bond: Add bonding driver and LACP protocol
[vpp.git] / src / plugins / lacp / lacp_test.c
1 /*
2  * lacp VAT support
3  *
4  * Copyright (c) 2017 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <inttypes.h>
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23
24 #include <vppinfra/error.h>
25 #include <lacp/node.h>
26
27 #define __plugin_msg_base lacp_test_main.msg_id_base
28 #include <vlibapi/vat_helper_macros.h>
29
30 /* declare message IDs */
31 #include <lacp/lacp_msg_enum.h>
32
33 /* Get CRC codes of the messages defined outside of this plugin */
34 #define vl_msg_name_crc_list
35 #include <vpp/api/vpe_all_api_h.h>
36 #undef vl_msg_name_crc_list
37
38 /* define message structures */
39 #define vl_typedefs
40 #include <vpp/api/vpe_all_api_h.h>
41 #include <lacp/lacp_all_api_h.h>
42 #undef vl_typedefs
43
44 /* declare message handlers for each api */
45
46 #define vl_endianfun            /* define message structures */
47 #include <lacp/lacp_all_api_h.h>
48 #undef vl_endianfun
49
50 /* instantiate all the print functions we know about */
51 #define vl_print(handle, ...)
52 #define vl_printfun
53 #include <lacp/lacp_all_api_h.h>
54 #undef vl_printfun
55
56 /* Get the API version number. */
57 #define vl_api_version(n,v) static u32 api_version=(v);
58 #include <lacp/lacp_all_api_h.h>
59 #undef vl_api_version
60
61 typedef struct
62 {
63   /* API message ID base */
64   u16 msg_id_base;
65   u32 ping_id;
66   vat_main_t *vat_main;
67 } lacp_test_main_t;
68
69 lacp_test_main_t lacp_test_main;
70
71 /*
72  * Table of message reply handlers, must include boilerplate handlers
73  * we just generated
74  */
75 #define foreach_vpe_api_reply_msg                       \
76 _(SW_INTERFACE_LACP_DETAILS, sw_interface_lacp_details)
77
78 /* lacp-dump API */
79 static void vl_api_sw_interface_lacp_details_t_handler
80   (vl_api_sw_interface_lacp_details_t * mp)
81 {
82   vat_main_t *vam = &vat_main;
83
84   fformat (vam->ofp,
85            "%-25s %-12d %-16s %3x %3x %3x %3x %3x %3x %3x %3x "
86            "%4x %3x %3x %3x %3x %3x %3x %3x\n",
87            mp->interface_name, ntohl (mp->sw_if_index),
88            mp->bond_interface_name,
89            lacp_bit_test (mp->actor_state, 7),
90            lacp_bit_test (mp->actor_state, 6),
91            lacp_bit_test (mp->actor_state, 5),
92            lacp_bit_test (mp->actor_state, 4),
93            lacp_bit_test (mp->actor_state, 3),
94            lacp_bit_test (mp->actor_state, 2),
95            lacp_bit_test (mp->actor_state, 1),
96            lacp_bit_test (mp->actor_state, 0),
97            lacp_bit_test (mp->partner_state, 7),
98            lacp_bit_test (mp->partner_state, 6),
99            lacp_bit_test (mp->partner_state, 5),
100            lacp_bit_test (mp->partner_state, 4),
101            lacp_bit_test (mp->partner_state, 3),
102            lacp_bit_test (mp->partner_state, 2),
103            lacp_bit_test (mp->partner_state, 1),
104            lacp_bit_test (mp->partner_state, 0));
105   fformat (vam->ofp,
106            "  LAG ID: [(%04x,%02x-%02x-%02x-%02x-%02x-%02x,%04x,%04x,%04x), "
107            "(%04x,%02x-%02x-%02x-%02x-%02x-%02x,%04x,%04x,%04x)]\n",
108            ntohs (mp->actor_system_priority), mp->actor_system[0],
109            mp->actor_system[1], mp->actor_system[2], mp->actor_system[3],
110            mp->actor_system[4], mp->actor_system[5], ntohs (mp->actor_key),
111            ntohs (mp->actor_port_priority), ntohs (mp->actor_port_number),
112            ntohs (mp->partner_system_priority), mp->partner_system[0],
113            mp->partner_system[1], mp->partner_system[2],
114            mp->partner_system[3], mp->partner_system[4],
115            mp->partner_system[5], ntohs (mp->partner_key),
116            ntohs (mp->partner_port_priority),
117            ntohs (mp->partner_port_number));
118   fformat (vam->ofp,
119            "  RX-state: %U, TX-state: %U, MUX-state: %U, PTX-state: %U\n",
120            format_rx_sm_state, ntohl (mp->rx_state), format_tx_sm_state,
121            ntohl (mp->tx_state), format_mux_sm_state, ntohl (mp->mux_state),
122            format_ptx_sm_state, ntohl (mp->ptx_state));
123 }
124
125 static int
126 api_sw_interface_lacp_dump (vat_main_t * vam)
127 {
128   lacp_test_main_t *lm = &lacp_test_main;
129   vl_api_sw_interface_lacp_dump_t *mp;
130   vl_api_control_ping_t *mp_ping;
131   int ret;
132
133   if (vam->json_output)
134     {
135       clib_warning ("JSON output not supported for sw_interface_lacp_dump");
136       return -99;
137     }
138
139   fformat (vam->ofp, "%-55s %-32s %-32s\n", " ", "actor state",
140            "partner state");
141   fformat (vam->ofp, "%-25s %-12s %-16s %-31s  %-31s\n", "interface name",
142            "sw_if_index", "bond interface", "exp/def/dis/col/syn/agg/tim/act",
143            "exp/def/dis/col/syn/agg/tim/act");
144
145   /* Get list of lacp interfaces */
146   M (SW_INTERFACE_LACP_DUMP, mp);
147   S (mp);
148
149   /* Use a control ping for synchronization */
150   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
151   mp_ping->_vl_msg_id = htons (lm->ping_id);
152   mp_ping->client_index = vam->my_client_index;
153
154   fformat (vam->ofp, "Sending ping id=%d\n", lm->ping_id);
155
156   vam->result_ready = 0;
157   S (mp_ping);
158
159   W (ret);
160   return ret;
161 }
162
163 /*
164  * List of messages that the api test plugin sends,
165  * and that the data plane plugin processes
166  */
167 #define foreach_vpe_api_msg                                       \
168 _(sw_interface_lacp_dump, "")
169
170 static void
171 lacp_vat_api_hookup (vat_main_t * vam)
172 {
173   lacp_test_main_t *lm __attribute__ ((unused)) = &lacp_test_main;
174   /* Hook up handlers for replies from the data plane plug-in */
175 #define _(N,n)                                                  \
176   vl_msg_api_set_handlers((VL_API_##N + lm->msg_id_base),       \
177                           #n,                                   \
178                           vl_api_##n##_t_handler,               \
179                           vl_noop_handler,                      \
180                           vl_api_##n##_t_endian,                \
181                           vl_api_##n##_t_print,                 \
182                           sizeof(vl_api_##n##_t), 1);
183   foreach_vpe_api_reply_msg;
184 #undef _
185
186   /* API messages we can send */
187 #define _(n,h)                                          \
188   hash_set_mem (vam->function_by_name, #n, api_##n);
189   foreach_vpe_api_msg;
190 #undef _
191
192   /* Help strings */
193 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
194   foreach_vpe_api_msg;
195 #undef _
196 }
197
198 clib_error_t *
199 vat_plugin_register (vat_main_t * vam)
200 {
201   lacp_test_main_t *lm = &lacp_test_main;
202   u8 *name;
203
204   lm->vat_main = vam;
205
206   /* Ask the vpp engine for the first assigned message-id */
207   name = format (0, "lacp_%08x%c", api_version, 0);
208   lm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
209
210   /* Get the control ping ID */
211 #define _(id,n,crc) \
212   const char *id ## _CRC __attribute__ ((unused)) = #n "_" #crc;
213   foreach_vl_msg_name_crc_vpe;
214 #undef _
215   lm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
216
217   if (lm->msg_id_base != (u16) ~ 0)
218     lacp_vat_api_hookup (vam);
219
220   vec_free (name);
221
222   return 0;
223 }
224
225 /*
226  * fd.io coding-style-patch-verification: ON
227  *
228  * Local Variables:
229  * eval: (c-set-style "gnu")
230  * End:
231  */