blob: 3fd73d7995f416a426bdcf1fabe230a244a270ab [file] [log] [blame]
Steven9cd2d7a2017-12-20 12:43:01 -08001/*
2 *------------------------------------------------------------------
3 * bond_api.c - vnet bonding device driver API support
4 *
5 * Copyright (c) 2017 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <vnet/vnet.h>
21#include <vlibmemory/api.h>
22
23#include <vnet/interface.h>
24#include <vnet/api_errno.h>
25#include <vnet/ethernet/ethernet.h>
Jakub Grajciar3d1ef872019-08-26 12:55:15 +020026#include <vnet/ethernet/ethernet_types_api.h>
Steven9cd2d7a2017-12-20 12:43:01 -080027#include <vnet/bonding/node.h>
28
Filip Tehlar116a1e52021-06-22 09:24:06 +000029#include <vnet/format_fns.h>
30#include <vnet/bonding/bond.api_enum.h>
31#include <vnet/bonding/bond.api_types.h>
32
33#define REPLY_MSG_ID_BASE msg_id_base
34#include <vlibapi/api_helper_macros.h>
35
36static u16 msg_id_base;
Steven9cd2d7a2017-12-20 12:43:01 -080037
38static void
Steven9cd2d7a2017-12-20 12:43:01 -080039vl_api_bond_delete_t_handler (vl_api_bond_delete_t * mp)
40{
41 vlib_main_t *vm = vlib_get_main ();
42 int rv;
Steven9cd2d7a2017-12-20 12:43:01 -080043 vl_api_bond_delete_reply_t *rmp;
Steven9cd2d7a2017-12-20 12:43:01 -080044 u32 sw_if_index = ntohl (mp->sw_if_index);
45
46 rv = bond_delete_if (vm, sw_if_index);
47
Ole Troan2e1c8962019-04-10 09:44:23 +020048 REPLY_MACRO (VL_API_BOND_DELETE_REPLY);
Steven9cd2d7a2017-12-20 12:43:01 -080049}
50
51static void
52vl_api_bond_create_t_handler (vl_api_bond_create_t * mp)
53{
54 vlib_main_t *vm = vlib_get_main ();
55 vl_api_bond_create_reply_t *rmp;
Steven9cd2d7a2017-12-20 12:43:01 -080056 bond_create_if_args_t _a, *ap = &_a;
57
Dave Barachb7b92992018-10-17 10:38:51 -040058 clib_memset (ap, 0, sizeof (*ap));
Steven9cd2d7a2017-12-20 12:43:01 -080059
Alexander Chernavinad9d5282018-12-13 09:08:09 -050060 ap->id = ntohl (mp->id);
61
Steven9cd2d7a2017-12-20 12:43:01 -080062 if (mp->use_custom_mac)
63 {
Jakub Grajciar3d1ef872019-08-26 12:55:15 +020064 mac_address_decode (mp->mac_address, (mac_address_t *) ap->hw_addr);
Steven9cd2d7a2017-12-20 12:43:01 -080065 ap->hw_addr_set = 1;
66 }
67
Jakub Grajciar3d1ef872019-08-26 12:55:15 +020068 ap->mode = ntohl (mp->mode);
69 ap->lb = ntohl (mp->lb);
Zhiyong Yang751e3f32019-06-26 05:49:14 -040070 ap->numa_only = mp->numa_only;
Steven9cd2d7a2017-12-20 12:43:01 -080071 bond_create_if (vm, ap);
72
Ole Troan2e1c8962019-04-10 09:44:23 +020073 int rv = ap->rv;
Steven9cd2d7a2017-12-20 12:43:01 -080074
Ole Troan2e1c8962019-04-10 09:44:23 +020075 /* *INDENT-OFF* */
76 REPLY_MACRO2(VL_API_BOND_CREATE_REPLY,
77 ({
78 rmp->sw_if_index = ntohl (ap->sw_if_index);
79 }));
80 /* *INDENT-ON* */
Steven9cd2d7a2017-12-20 12:43:01 -080081}
82
83static void
Steven Luongea717862020-07-30 07:31:40 -070084vl_api_bond_create2_t_handler (vl_api_bond_create2_t * mp)
85{
86 vlib_main_t *vm = vlib_get_main ();
87 vl_api_bond_create2_reply_t *rmp;
88 bond_create_if_args_t _a, *ap = &_a;
89
90 clib_memset (ap, 0, sizeof (*ap));
91
92 ap->id = ntohl (mp->id);
93
94 if (mp->use_custom_mac)
95 {
96 mac_address_decode (mp->mac_address, (mac_address_t *) ap->hw_addr);
97 ap->hw_addr_set = 1;
98 }
99
100 ap->mode = ntohl (mp->mode);
101 ap->lb = ntohl (mp->lb);
102 ap->numa_only = mp->numa_only;
103 ap->gso = mp->enable_gso;
104 bond_create_if (vm, ap);
105
106 int rv = ap->rv;
107
108 /* *INDENT-OFF* */
109 REPLY_MACRO2(VL_API_BOND_CREATE2_REPLY,
110 ({
111 rmp->sw_if_index = ntohl (ap->sw_if_index);
112 }));
113 /* *INDENT-ON* */
114}
115
116static void
Steven Luong4c4223e2020-07-15 08:44:54 -0700117vl_api_bond_add_member_t_handler (vl_api_bond_add_member_t * mp)
Steven9cd2d7a2017-12-20 12:43:01 -0800118{
119 vlib_main_t *vm = vlib_get_main ();
Steven Luong4c4223e2020-07-15 08:44:54 -0700120 vl_api_bond_add_member_reply_t *rmp;
121 bond_add_member_args_t _a, *ap = &_a;
Ole Troan2e1c8962019-04-10 09:44:23 +0200122 int rv = 0;
Steven9cd2d7a2017-12-20 12:43:01 -0800123
Dave Barachb7b92992018-10-17 10:38:51 -0400124 clib_memset (ap, 0, sizeof (*ap));
Steven9cd2d7a2017-12-20 12:43:01 -0800125
126 ap->group = ntohl (mp->bond_sw_if_index);
Steven Luong3f54d962020-08-10 09:34:07 -0700127 VALIDATE_SW_IF_INDEX (mp);
Steven Luong4c4223e2020-07-15 08:44:54 -0700128 ap->member = ntohl (mp->sw_if_index);
Steven9cd2d7a2017-12-20 12:43:01 -0800129 ap->is_passive = mp->is_passive;
130 ap->is_long_timeout = mp->is_long_timeout;
131
Steven Luong4c4223e2020-07-15 08:44:54 -0700132 bond_add_member (vm, ap);
Steven Luong3f54d962020-08-10 09:34:07 -0700133 rv = ap->rv;
Steven Luong4c4223e2020-07-15 08:44:54 -0700134
Steven Luong3f54d962020-08-10 09:34:07 -0700135 BAD_SW_IF_INDEX_LABEL;
Steven Luong4c4223e2020-07-15 08:44:54 -0700136 REPLY_MACRO (VL_API_BOND_ADD_MEMBER_REPLY);
137}
138
139static void
140vl_api_bond_enslave_t_handler (vl_api_bond_enslave_t * mp)
141{
142 vlib_main_t *vm = vlib_get_main ();
143 vl_api_bond_enslave_reply_t *rmp;
144 bond_add_member_args_t _a, *ap = &_a;
145 int rv = 0;
146
147 clib_memset (ap, 0, sizeof (*ap));
148
149 ap->group = ntohl (mp->bond_sw_if_index);
Steven Luong3f54d962020-08-10 09:34:07 -0700150 VALIDATE_SW_IF_INDEX (mp);
Steven Luong4c4223e2020-07-15 08:44:54 -0700151 ap->member = ntohl (mp->sw_if_index);
152 ap->is_passive = mp->is_passive;
153 ap->is_long_timeout = mp->is_long_timeout;
154
155 bond_add_member (vm, ap);
Steven Luong3f54d962020-08-10 09:34:07 -0700156 rv = ap->rv;
Steven9cd2d7a2017-12-20 12:43:01 -0800157
Steven Luong3f54d962020-08-10 09:34:07 -0700158 BAD_SW_IF_INDEX_LABEL;
Ole Troan2e1c8962019-04-10 09:44:23 +0200159 REPLY_MACRO (VL_API_BOND_ENSLAVE_REPLY);
Steven9cd2d7a2017-12-20 12:43:01 -0800160}
161
162static void
Steven Luonga1876b82019-08-20 16:58:00 -0700163 vl_api_sw_interface_set_bond_weight_t_handler
164 (vl_api_sw_interface_set_bond_weight_t * mp)
165{
166 vlib_main_t *vm = vlib_get_main ();
167 bond_set_intf_weight_args_t _a, *ap = &_a;
168 vl_api_sw_interface_set_bond_weight_reply_t *rmp;
169 int rv = 0;
170
171 clib_memset (ap, 0, sizeof (*ap));
172
173 ap->sw_if_index = ntohl (mp->sw_if_index);
174 ap->weight = ntohl (mp->weight);
175
176 bond_set_intf_weight (vm, ap);
Steven Luong3f54d962020-08-10 09:34:07 -0700177 rv = ap->rv;
Steven Luonga1876b82019-08-20 16:58:00 -0700178
179 REPLY_MACRO (VL_API_SW_INTERFACE_SET_BOND_WEIGHT_REPLY);
180}
181
182static void
Steven9cd2d7a2017-12-20 12:43:01 -0800183vl_api_bond_detach_slave_t_handler (vl_api_bond_detach_slave_t * mp)
184{
185 vlib_main_t *vm = vlib_get_main ();
186 vl_api_bond_detach_slave_reply_t *rmp;
Steven Luong4c4223e2020-07-15 08:44:54 -0700187 bond_detach_member_args_t _a, *ap = &_a;
Ole Troan2e1c8962019-04-10 09:44:23 +0200188 int rv = 0;
Steven9cd2d7a2017-12-20 12:43:01 -0800189
Dave Barachb7b92992018-10-17 10:38:51 -0400190 clib_memset (ap, 0, sizeof (*ap));
Steven9cd2d7a2017-12-20 12:43:01 -0800191
Steven Luong4c4223e2020-07-15 08:44:54 -0700192 ap->member = ntohl (mp->sw_if_index);
193 bond_detach_member (vm, ap);
Steven Luong3f54d962020-08-10 09:34:07 -0700194 rv = ap->rv;
Steven9cd2d7a2017-12-20 12:43:01 -0800195
Ole Troan2e1c8962019-04-10 09:44:23 +0200196 REPLY_MACRO (VL_API_BOND_DETACH_SLAVE_REPLY);
Steven9cd2d7a2017-12-20 12:43:01 -0800197}
198
199static void
Steven Luong4c4223e2020-07-15 08:44:54 -0700200vl_api_bond_detach_member_t_handler (vl_api_bond_detach_member_t * mp)
201{
202 vlib_main_t *vm = vlib_get_main ();
203 vl_api_bond_detach_member_reply_t *rmp;
204 bond_detach_member_args_t _a, *ap = &_a;
205 int rv = 0;
206
207 clib_memset (ap, 0, sizeof (*ap));
208
209 ap->member = ntohl (mp->sw_if_index);
210 bond_detach_member (vm, ap);
Steven Luong3f54d962020-08-10 09:34:07 -0700211 rv = ap->rv;
Steven Luong4c4223e2020-07-15 08:44:54 -0700212
213 REPLY_MACRO (VL_API_BOND_DETACH_MEMBER_REPLY);
214}
215
216static void
Steven9cd2d7a2017-12-20 12:43:01 -0800217bond_send_sw_interface_details (vpe_api_main_t * am,
218 vl_api_registration_t * reg,
219 bond_interface_details_t * bond_if,
220 u32 context)
221{
222 vl_api_sw_interface_bond_details_t *mp;
223
224 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400225 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlar116a1e52021-06-22 09:24:06 +0000226 mp->_vl_msg_id =
227 htons (REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_BOND_DETAILS);
Steven9cd2d7a2017-12-20 12:43:01 -0800228 mp->sw_if_index = htonl (bond_if->sw_if_index);
Alexander Chernavinad9d5282018-12-13 09:08:09 -0500229 mp->id = htonl (bond_if->id);
Steven9cd2d7a2017-12-20 12:43:01 -0800230 clib_memcpy (mp->interface_name, bond_if->interface_name,
231 MIN (ARRAY_LEN (mp->interface_name) - 1,
232 strlen ((const char *) bond_if->interface_name)));
Jakub Grajciar3d1ef872019-08-26 12:55:15 +0200233 mp->mode = htonl (bond_if->mode);
234 mp->lb = htonl (bond_if->lb);
Zhiyong Yang751e3f32019-06-26 05:49:14 -0400235 mp->numa_only = bond_if->numa_only;
Steven Luong4c4223e2020-07-15 08:44:54 -0700236 mp->active_slaves = htonl (bond_if->active_members);
237 mp->slaves = htonl (bond_if->members);
Steven9cd2d7a2017-12-20 12:43:01 -0800238
239 mp->context = context;
240 vl_api_send_msg (reg, (u8 *) mp);
241}
242
243static void
244vl_api_sw_interface_bond_dump_t_handler (vl_api_sw_interface_bond_dump_t * mp)
245{
246 int rv;
247 vpe_api_main_t *am = &vpe_api_main;
248 vl_api_registration_t *reg;
249 bond_interface_details_t *bondifs = NULL;
250 bond_interface_details_t *bond_if = NULL;
251
252 reg = vl_api_client_index_to_registration (mp->client_index);
253 if (!reg)
254 return;
255
256 rv = bond_dump_ifs (&bondifs);
257 if (rv)
258 return;
259
260 vec_foreach (bond_if, bondifs)
261 {
262 bond_send_sw_interface_details (am, reg, bond_if, mp->context);
263 }
264
265 vec_free (bondifs);
266}
267
268static void
Steven Luong4c4223e2020-07-15 08:44:54 -0700269bond_send_sw_bond_interface_details (vpe_api_main_t * am,
270 vl_api_registration_t * reg,
271 bond_interface_details_t * bond_if,
272 u32 context)
273{
274 vl_api_sw_bond_interface_details_t *mp;
275
276 mp = vl_msg_api_alloc (sizeof (*mp));
277 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlar116a1e52021-06-22 09:24:06 +0000278 mp->_vl_msg_id =
279 htons (REPLY_MSG_ID_BASE + VL_API_SW_BOND_INTERFACE_DETAILS);
Steven Luong4c4223e2020-07-15 08:44:54 -0700280 mp->sw_if_index = htonl (bond_if->sw_if_index);
281 mp->id = htonl (bond_if->id);
282 clib_memcpy (mp->interface_name, bond_if->interface_name,
283 MIN (ARRAY_LEN (mp->interface_name) - 1,
284 strlen ((const char *) bond_if->interface_name)));
285 mp->mode = htonl (bond_if->mode);
286 mp->lb = htonl (bond_if->lb);
287 mp->numa_only = bond_if->numa_only;
288 mp->active_members = htonl (bond_if->active_members);
289 mp->members = htonl (bond_if->members);
290
291 mp->context = context;
292 vl_api_send_msg (reg, (u8 *) mp);
293}
294
295static void
296vl_api_sw_bond_interface_dump_t_handler (vl_api_sw_bond_interface_dump_t * mp)
297{
298 int rv;
299 vpe_api_main_t *am = &vpe_api_main;
300 vl_api_registration_t *reg;
301 bond_interface_details_t *bondifs = NULL;
302 bond_interface_details_t *bond_if = NULL;
303 u32 filter_sw_if_index;
304
305 reg = vl_api_client_index_to_registration (mp->client_index);
306 if (!reg)
307 return;
308
309 filter_sw_if_index = htonl (mp->sw_if_index);
310 if (filter_sw_if_index != ~0)
311 VALIDATE_SW_IF_INDEX (mp);
312
313 rv = bond_dump_ifs (&bondifs);
314 if (rv)
315 return;
316
317 vec_foreach (bond_if, bondifs)
318 {
319 if ((filter_sw_if_index == ~0) ||
320 (bond_if->sw_if_index == filter_sw_if_index))
321 bond_send_sw_bond_interface_details (am, reg, bond_if, mp->context);
322 }
323
324 BAD_SW_IF_INDEX_LABEL;
325 vec_free (bondifs);
326}
327
328static void
329bond_send_sw_member_interface_details (vpe_api_main_t * am,
330 vl_api_registration_t * reg,
331 member_interface_details_t * member_if,
332 u32 context)
Steven9cd2d7a2017-12-20 12:43:01 -0800333{
334 vl_api_sw_interface_slave_details_t *mp;
335
336 mp = vl_msg_api_alloc (sizeof (*mp));
Dave Barachb7b92992018-10-17 10:38:51 -0400337 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlar116a1e52021-06-22 09:24:06 +0000338 mp->_vl_msg_id =
339 htons (REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_SLAVE_DETAILS);
Steven Luong4c4223e2020-07-15 08:44:54 -0700340 mp->sw_if_index = htonl (member_if->sw_if_index);
341 clib_memcpy (mp->interface_name, member_if->interface_name,
Steven9cd2d7a2017-12-20 12:43:01 -0800342 MIN (ARRAY_LEN (mp->interface_name) - 1,
Steven Luong4c4223e2020-07-15 08:44:54 -0700343 strlen ((const char *) member_if->interface_name)));
344 mp->is_passive = member_if->is_passive;
345 mp->is_long_timeout = member_if->is_long_timeout;
346 mp->is_local_numa = member_if->is_local_numa;
347 mp->weight = htonl (member_if->weight);
Steven9cd2d7a2017-12-20 12:43:01 -0800348
349 mp->context = context;
350 vl_api_send_msg (reg, (u8 *) mp);
351}
352
353static void
354vl_api_sw_interface_slave_dump_t_handler (vl_api_sw_interface_slave_dump_t *
355 mp)
356{
357 int rv;
358 vpe_api_main_t *am = &vpe_api_main;
359 vl_api_registration_t *reg;
Steven Luong4c4223e2020-07-15 08:44:54 -0700360 member_interface_details_t *memberifs = NULL;
361 member_interface_details_t *member_if = NULL;
Steven9cd2d7a2017-12-20 12:43:01 -0800362
363 reg = vl_api_client_index_to_registration (mp->client_index);
364 if (!reg)
365 return;
366
Steven Luong4c4223e2020-07-15 08:44:54 -0700367 rv = bond_dump_member_ifs (&memberifs, ntohl (mp->sw_if_index));
Steven9cd2d7a2017-12-20 12:43:01 -0800368 if (rv)
369 return;
370
Steven Luong4c4223e2020-07-15 08:44:54 -0700371 vec_foreach (member_if, memberifs)
Steven9cd2d7a2017-12-20 12:43:01 -0800372 {
Steven Luong4c4223e2020-07-15 08:44:54 -0700373 bond_send_sw_member_interface_details (am, reg, member_if, mp->context);
Steven9cd2d7a2017-12-20 12:43:01 -0800374 }
375
Steven Luong4c4223e2020-07-15 08:44:54 -0700376 vec_free (memberifs);
377}
378
379static void
380bond_send_member_interface_details (vpe_api_main_t * am,
381 vl_api_registration_t * reg,
382 member_interface_details_t * member_if,
383 u32 context)
384{
385 vl_api_sw_member_interface_details_t *mp;
386
387 mp = vl_msg_api_alloc (sizeof (*mp));
388 clib_memset (mp, 0, sizeof (*mp));
Filip Tehlar116a1e52021-06-22 09:24:06 +0000389 mp->_vl_msg_id =
390 htons (REPLY_MSG_ID_BASE + VL_API_SW_MEMBER_INTERFACE_DETAILS);
Steven Luong4c4223e2020-07-15 08:44:54 -0700391 mp->sw_if_index = htonl (member_if->sw_if_index);
392 clib_memcpy (mp->interface_name, member_if->interface_name,
393 MIN (ARRAY_LEN (mp->interface_name) - 1,
394 strlen ((const char *) member_if->interface_name)));
395 mp->is_passive = member_if->is_passive;
396 mp->is_long_timeout = member_if->is_long_timeout;
397 mp->is_local_numa = member_if->is_local_numa;
398 mp->weight = htonl (member_if->weight);
399
400 mp->context = context;
401 vl_api_send_msg (reg, (u8 *) mp);
402}
403
404static void
405vl_api_sw_member_interface_dump_t_handler (vl_api_sw_member_interface_dump_t *
406 mp)
407{
408 int rv;
409 vpe_api_main_t *am = &vpe_api_main;
410 vl_api_registration_t *reg;
411 member_interface_details_t *memberifs = NULL;
412 member_interface_details_t *member_if = NULL;
413
414 reg = vl_api_client_index_to_registration (mp->client_index);
415 if (!reg)
416 return;
417
418 rv = bond_dump_member_ifs (&memberifs, ntohl (mp->sw_if_index));
419 if (rv)
420 return;
421
422 vec_foreach (member_if, memberifs)
423 {
424 bond_send_member_interface_details (am, reg, member_if, mp->context);
425 }
426
427 vec_free (memberifs);
Steven9cd2d7a2017-12-20 12:43:01 -0800428}
429
Filip Tehlar116a1e52021-06-22 09:24:06 +0000430#include <vnet/bonding/bond.api.c>
Steven9cd2d7a2017-12-20 12:43:01 -0800431static clib_error_t *
432bond_api_hookup (vlib_main_t * vm)
433{
Steven9cd2d7a2017-12-20 12:43:01 -0800434 /*
435 * Set up the (msg_name, crc, message-id) table
436 */
Filip Tehlar116a1e52021-06-22 09:24:06 +0000437 REPLY_MSG_ID_BASE = setup_message_id_table ();
Steven9cd2d7a2017-12-20 12:43:01 -0800438
439 return 0;
440}
441
442VLIB_API_INIT_FUNCTION (bond_api_hookup);
443
444/*
445 * fd.io coding-style-patch-verification: ON
446 *
447 * Local Variables:
448 * eval: (c-set-style "gnu")
449 * End:
450 */