aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/lacp/lacp_test.c
blob: 3a5e63516936b6b248721fa7b889e643be211f37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * lacp VAT support
 *
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <inttypes.h>

#include <vat/vat.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>

#include <vppinfra/error.h>
#include <lacp/node.h>

#define __plugin_msg_base lacp_test_main.msg_id_base
#include <vlibapi/vat_helper_macros.h>

/* declare message IDs */
#include <vnet/format_fns.h>
#include <lacp/lacp.api_enum.h>
#include <lacp/lacp.api_types.h>
#include <vpp/api/vpe.api_types.h>

typedef struct
{
  /* API message ID base */
  u16 msg_id_base;
  u32 ping_id;
  vat_main_t *vat_main;
} lacp_test_main_t;

lacp_test_main_t lacp_test_main;

/* lacp-dump API */
static void vl_api_sw_interface_lacp_details_t_handler
  (vl_api_sw_interface_lacp_details_t * mp)
{
  vat_main_t *vam = &vat_main;

  fformat (vam->ofp,
	   "%-25s %-12d %-16s %3x %3x %3x %3x %3x %3x %3x %3x "
	   "%4x %3x %3x %3x %3x %3x %3x %3x\n",
	   mp->interface_name, ntohl (mp->sw_if_index),
	   mp->bond_interface_name,
	   lacp_bit_test (mp->actor_state, 7),
	   lacp_bit_test (mp->actor_state, 6),
	   lacp_bit_test (mp->actor_state, 5),
	   lacp_bit_test (mp->actor_state, 4),
	   lacp_bit_test (mp->actor_state, 3),
	   lacp_bit_test (mp->actor_state, 2),
	   lacp_bit_test (mp->actor_state, 1),
	   lacp_bit_test (mp->actor_state, 0),
	   lacp_bit_test (mp->partner_state, 7),
	   lacp_bit_test (mp->partner_state, 6),
	   lacp_bit_test (mp->partner_state, 5),
	   lacp_bit_test (mp->partner_state, 4),
	   lacp_bit_test (mp->partner_state, 3),
	   lacp_bit_test (mp->partner_state, 2),
	   lacp_bit_test (mp->partner_state, 1),
	   lacp_bit_test (mp->partner_state, 0));
  fformat (vam->ofp,
	   "  LAG ID: [(%04x,%02x-%02x-%02x-%02x-%02x-%02x,%04x,%04x,%04x), "
	   "(%04x,%02x-%02x-%02x-%02x-%02x-%02x,%04x,%04x,%04x)]\n",
	   ntohs (mp->actor_system_priority), mp->actor_system[0],
	   mp->actor_system[1], mp->actor_system[2], mp->actor_system[3],
	   mp->actor_system[4], mp->actor_system[5], ntohs (mp->actor_key),
	   ntohs (mp->actor_port_priority), ntohs (mp->actor_port_number),
	   ntohs (mp->partner_system_priority), mp->partner_system[0],
	   mp->partner_system[1], mp->partner_system[2],
	   mp->partner_system[3], mp->partner_system[4],
	   mp->partner_system[5], ntohs (mp->partner_key),
	   ntohs (mp->partner_port_priority),
	   ntohs (mp->partner_port_number));
  fformat (vam->ofp,
	   "  RX-state: %U, TX-state: %U, MUX-state: %U, PTX-state: %U\n",
	   format_rx_sm_state, ntohl (mp->rx_state), format_tx_sm_state,
	   ntohl (mp->tx_state), format_mux_sm_state, ntohl (mp->mux_state),
	   format_ptx_sm_state, ntohl (mp->ptx_state));
}

static int
api_sw_interface_lacp_dump (vat_main_t * vam)
{
  lacp_test_main_t *lm = &lacp_test_main;
  vl_api_sw_interface_lacp_dump_t *mp;
  vl_api_control_ping_t *mp_ping;
  int ret;

  if (vam->json_output)
    {
      clib_warning ("JSON output not supported for sw_interface_lacp_dump");
      return -99;
    }

  fformat (vam->ofp, "%-55s %-32s %-32s\n", " ", "actor state",
	   "partner state");
  fformat (vam->ofp, "%-25s %-12s %-16s %-31s  %-31s\n", "interface name",
	   "sw_if_index", "bond interface", "exp/def/dis/col/syn/agg/tim/act",
	   "exp/def/dis/col/syn/agg/tim/act");

  /* Get list of lacp interfaces */
  M (SW_INTERFACE_LACP_DUMP, mp);
  S (mp);

  /* Use a control ping for synchronization */
  if (!lm->ping_id)
    lm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
  mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
  mp_ping->_vl_msg_id = htons (lm->ping_id);
  mp_ping->client_index = vam->my_client_index;

  fformat (vam->ofp, "Sending ping id=%d\n", lm->ping_id);

  vam->result_ready = 0;
  S (mp_ping);

  W (ret);
  return ret;
}

#include <lacp/lacp.api_test.c>

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
ne u8 bd_feature_learn (l2_bridge_domain_t * bd_config) { return ((bd_config->feature_bitmap & L2INPUT_FEAT_LEARN) == L2INPUT_FEAT_LEARN); } static_always_inline u8 bd_feature_arp_term (l2_bridge_domain_t * bd_config) { return ((bd_config->feature_bitmap & L2INPUT_FEAT_ARP_TERM) == L2INPUT_FEAT_ARP_TERM); } static_always_inline u8 bd_feature_arp_ufwd (l2_bridge_domain_t * bd_config) { return ((bd_config->feature_bitmap & L2INPUT_FEAT_ARP_UFWD) == L2INPUT_FEAT_ARP_UFWD); } /** Masks for eliminating features that do not apply to a packet */ /** Get a pointer to the config for the given interface */ l2_input_config_t *l2input_intf_config (u32 sw_if_index); /* Enable (or disable) the feature in the bitmap for the given interface */ u32 l2input_intf_bitmap_enable (u32 sw_if_index, l2input_feat_masks_t feature_bitmap, u32 enable); /* Sets modifies flags from a bridge domain */ u32 l2input_set_bridge_features (u32 bd_index, u32 feat_mask, u32 feat_value); void l2input_interface_mac_change (u32 sw_if_index, const u8 * old_address, const u8 * new_address); #define MODE_L3 0 #define MODE_L2_BRIDGE 1 #define MODE_L2_XC 2 #define MODE_L2_CLASSIFY 3 #define MODE_ERROR_ETH 1 #define MODE_ERROR_BVI_DEF 2 u32 set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, u32 mode, u32 sw_if_index, u32 bd_index, l2_bd_port_type_t port_type, u32 shg, u32 xc_sw_if_index); static inline void vnet_update_l2_len (vlib_buffer_t * b) { ethernet_header_t *eth; u16 ethertype; u8 vlan_count = 0; /* point at current l2 hdr */ eth = vlib_buffer_get_current (b); /* * l2-output pays no attention to this * but the tag push/pop code on an l2 subif needs it. * * Determine l2 header len, check for up to 2 vlans */ vnet_buffer (b)->l2.l2_len = sizeof (ethernet_header_t); ethertype = clib_net_to_host_u16 (eth->type); if (ethernet_frame_is_tagged (ethertype)) { ethernet_vlan_header_t *vlan; vnet_buffer (b)->l2.l2_len += sizeof (*vlan); vlan_count = 1; vlan = (void *) (eth + 1); ethertype = clib_net_to_host_u16 (vlan->type); if (ethertype == ETHERNET_TYPE_VLAN) { vnet_buffer (b)->l2.l2_len += sizeof (*vlan); vlan_count = 2; } } ethernet_buffer_set_vlan_count (b, vlan_count); } /* * Compute flow hash of an ethernet packet, use 5-tuple hash if L3 packet * is ip4 or ip6. Otherwise hash on smac/dmac/etype. * The vlib buffer current pointer is expected to be at ethernet header * and vnet l2.l2_len is expected to be setup already. */ static inline u32 vnet_l2_compute_flow_hash (vlib_buffer_t * b) { ethernet_header_t *eh = vlib_buffer_get_current (b); u8 *l3h = (u8 *) eh + vnet_buffer (b)->l2.l2_len; u16 ethertype = clib_net_to_host_u16 (*(u16 *) (l3h - 2)); if (ethertype == ETHERNET_TYPE_IP4) return ip4_compute_flow_hash ((ip4_header_t *) l3h, IP_FLOW_HASH_DEFAULT); else if (ethertype == ETHERNET_TYPE_IP6) return ip6_compute_flow_hash ((ip6_header_t *) l3h, IP_FLOW_HASH_DEFAULT); else { u32 a, b, c; u32 *ap = (u32 *) & eh->dst_address[2]; u32 *bp = (u32 *) & eh->src_address[2]; a = *ap; b = *bp; c = ethertype; hash_v3_mix32 (a, b, c); hash_v3_finalize32 (a, b, c); return c; } } #endif /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */