blob: eb04459f234707bd58f19289b2ed1d02de195349 [file] [log] [blame]
Matus Fabianf468e232016-12-02 06:00:53 -08001/*
2 *------------------------------------------------------------------
3 * l2_api.c - layer 2 forwarding api
4 *
5 * Copyright (c) 2016 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/l2/l2_input.h>
Pavel Kotucek0f971d82017-01-03 10:48:54 +010026#include <vnet/l2/l2_fib.h>
Pavel Kotucekadec5872017-01-25 08:50:53 +010027#include <vnet/l2/l2_vtr.h>
John Lo8d00fff2017-08-03 00:35:36 -040028#include <vnet/l2/l2_learn.h>
Neale Rannsb4743802018-09-05 09:13:57 -070029#include <vnet/l2/l2_bd.h>
Matus Fabianf468e232016-12-02 06:00:53 -080030
31#include <vnet/vnet_msg_enum.h>
32
33#define vl_typedefs /* define message structures */
34#include <vnet/vnet_all_api_h.h>
35#undef vl_typedefs
36
37#define vl_endianfun /* define message structures */
38#include <vnet/vnet_all_api_h.h>
39#undef vl_endianfun
40
Ole Troan01384fe2017-05-12 11:55:35 +020041#define vl_api_bridge_domain_details_t_endian vl_noop_handler
42#define vl_api_bridge_domain_details_t_print vl_noop_handler
43
Matus Fabianf468e232016-12-02 06:00:53 -080044/* instantiate all the print functions we know about */
45#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
46#define vl_printfun
47#include <vnet/vnet_all_api_h.h>
48#undef vl_printfun
49
50#include <vlibapi/api_helper_macros.h>
51
Pavel Kotucek0f971d82017-01-03 10:48:54 +010052#define foreach_vpe_api_msg \
53_(L2_XCONNECT_DUMP, l2_xconnect_dump) \
54_(L2_FIB_CLEAR_TABLE, l2_fib_clear_table) \
55_(L2_FIB_TABLE_DUMP, l2_fib_table_dump) \
Eyal Bari7537e712017-04-27 14:07:55 +030056_(L2FIB_FLUSH_ALL, l2fib_flush_all) \
Eyal Barif24991c2017-04-05 05:33:21 +030057_(L2FIB_FLUSH_INT, l2fib_flush_int) \
58_(L2FIB_FLUSH_BD, l2fib_flush_bd) \
Pavel Kotucek0f971d82017-01-03 10:48:54 +010059_(L2FIB_ADD_DEL, l2fib_add_del) \
John Lo8d00fff2017-08-03 00:35:36 -040060_(WANT_L2_MACS_EVENTS, want_l2_macs_events) \
Pavel Kotucek0f971d82017-01-03 10:48:54 +010061_(L2_FLAGS, l2_flags) \
Neale Rannsb8d44812017-11-10 06:53:54 -080062_(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
63_(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
64_(L2_PATCH_ADD_DEL, l2_patch_add_del) \
65_(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter) \
66_(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del) \
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +020067_(BD_IP_MAC_DUMP, bd_ip_mac_dump) \
Neale Rannsb8d44812017-11-10 06:53:54 -080068_(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del) \
69_(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \
70_(BRIDGE_FLAGS, bridge_flags) \
Pavel Kotucekadec5872017-01-25 08:50:53 +010071_(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite) \
Neale Rannsb8d44812017-11-10 06:53:54 -080072_(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \
73_(BRIDGE_DOMAIN_SET_MAC_AGE, bridge_domain_set_mac_age) \
74_(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath)
Matus Fabianf468e232016-12-02 06:00:53 -080075
76static void
Florin Coras6c4dae22018-01-09 06:39:23 -080077send_l2_xconnect_details (vl_api_registration_t * reg, u32 context,
Matus Fabianf468e232016-12-02 06:00:53 -080078 u32 rx_sw_if_index, u32 tx_sw_if_index)
79{
80 vl_api_l2_xconnect_details_t *mp;
81
82 mp = vl_msg_api_alloc (sizeof (*mp));
83 memset (mp, 0, sizeof (*mp));
84 mp->_vl_msg_id = ntohs (VL_API_L2_XCONNECT_DETAILS);
85 mp->context = context;
86 mp->rx_sw_if_index = htonl (rx_sw_if_index);
87 mp->tx_sw_if_index = htonl (tx_sw_if_index);
88
Florin Coras6c4dae22018-01-09 06:39:23 -080089 vl_api_send_msg (reg, (u8 *) mp);
Matus Fabianf468e232016-12-02 06:00:53 -080090}
91
92static void
93vl_api_l2_xconnect_dump_t_handler (vl_api_l2_xconnect_dump_t * mp)
94{
Florin Coras6c4dae22018-01-09 06:39:23 -080095 vl_api_registration_t *reg;
Matus Fabianf468e232016-12-02 06:00:53 -080096 vnet_main_t *vnm = vnet_get_main ();
97 vnet_interface_main_t *im = &vnm->interface_main;
98 l2input_main_t *l2im = &l2input_main;
99 vnet_sw_interface_t *swif;
100 l2_input_config_t *config;
101
Florin Coras6c4dae22018-01-09 06:39:23 -0800102 reg = vl_api_client_index_to_registration (mp->client_index);
103 if (!reg)
Matus Fabianf468e232016-12-02 06:00:53 -0800104 return;
105
106 /* *INDENT-OFF* */
107 pool_foreach (swif, im->sw_interfaces,
108 ({
109 config = vec_elt_at_index (l2im->configs, swif->sw_if_index);
110 if (config->xconnect)
Florin Coras6c4dae22018-01-09 06:39:23 -0800111 send_l2_xconnect_details (reg, mp->context, swif->sw_if_index,
Matus Fabianf468e232016-12-02 06:00:53 -0800112 config->output_sw_if_index);
113 }));
114 /* *INDENT-ON* */
115}
116
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100117static void
118vl_api_l2_fib_clear_table_t_handler (vl_api_l2_fib_clear_table_t * mp)
119{
120 int rv = 0;
121 vl_api_l2_fib_clear_table_reply_t *rmp;
122
Eyal Bari7537e712017-04-27 14:07:55 +0300123 /* Clear all MACs including static MACs */
124 l2fib_clear_table ();
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100125
126 REPLY_MACRO (VL_API_L2_FIB_CLEAR_TABLE_REPLY);
127}
128
129static void
130send_l2fib_table_entry (vpe_api_main_t * am,
Florin Coras6c4dae22018-01-09 06:39:23 -0800131 vl_api_registration_t * reg,
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100132 l2fib_entry_key_t * l2fe_key,
133 l2fib_entry_result_t * l2fe_res, u32 context)
134{
Ole Troan01384fe2017-05-12 11:55:35 +0200135 vl_api_l2_fib_table_details_t *mp;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100136
137 mp = vl_msg_api_alloc (sizeof (*mp));
138 memset (mp, 0, sizeof (*mp));
Ole Troan01384fe2017-05-12 11:55:35 +0200139 mp->_vl_msg_id = ntohs (VL_API_L2_FIB_TABLE_DETAILS);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100140
141 mp->bd_id =
142 ntohl (l2input_main.bd_configs[l2fe_key->fields.bd_index].bd_id);
143
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200144 clib_memcpy (mp->mac, l2fe_key->fields.mac, 6);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100145 mp->sw_if_index = ntohl (l2fe_res->fields.sw_if_index);
Neale Ranns7341b6d2018-09-19 04:07:02 -0700146 mp->static_mac = (l2fib_entry_result_is_set_STATIC (l2fe_res) ? 1 : 0);
147 mp->filter_mac = (l2fib_entry_result_is_set_FILTER (l2fe_res) ? 1 : 0);
148 mp->bvi_mac = (l2fib_entry_result_is_set_BVI (l2fe_res) ? 1 : 0);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100149 mp->context = context;
150
Florin Coras6c4dae22018-01-09 06:39:23 -0800151 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100152}
153
154static void
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100155vl_api_l2_fib_table_dump_t_handler (vl_api_l2_fib_table_dump_t * mp)
156{
157 vpe_api_main_t *am = &vpe_api_main;
158 bd_main_t *bdm = &bd_main;
159 l2fib_entry_key_t *l2fe_key = NULL;
160 l2fib_entry_result_t *l2fe_res = NULL;
161 u32 ni, bd_id = ntohl (mp->bd_id);
162 u32 bd_index;
Florin Coras6c4dae22018-01-09 06:39:23 -0800163 vl_api_registration_t *reg;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100164 uword *p;
165
Florin Coras6c4dae22018-01-09 06:39:23 -0800166 reg = vl_api_client_index_to_registration (mp->client_index);
167 if (!reg)
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100168 return;
169
170 /* see l2fib_table_dump: ~0 means "any" */
171 if (bd_id == ~0)
172 bd_index = ~0;
173 else
174 {
175 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
176 if (p == 0)
177 return;
178
179 bd_index = p[0];
180 }
181
182 l2fib_table_dump (bd_index, &l2fe_key, &l2fe_res);
183
184 vec_foreach_index (ni, l2fe_key)
185 {
Florin Coras6c4dae22018-01-09 06:39:23 -0800186 send_l2fib_table_entry (am, reg, vec_elt_at_index (l2fe_key, ni),
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100187 vec_elt_at_index (l2fe_res, ni), mp->context);
188 }
189 vec_free (l2fe_key);
190 vec_free (l2fe_res);
191}
192
193static void
194vl_api_l2fib_add_del_t_handler (vl_api_l2fib_add_del_t * mp)
195{
196 bd_main_t *bdm = &bd_main;
197 l2input_main_t *l2im = &l2input_main;
198 vl_api_l2fib_add_del_reply_t *rmp;
199 int rv = 0;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100200 u32 bd_id = ntohl (mp->bd_id);
Eyal Bari31a71ab2017-06-25 14:42:33 +0300201 uword *p = hash_get (bdm->bd_index_by_bd_id, bd_id);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100202
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100203 if (!p)
204 {
205 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
206 goto bad_sw_if_index;
207 }
Eyal Bari31a71ab2017-06-25 14:42:33 +0300208 u32 bd_index = p[0];
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100209
Mohsin Kazmi57938f62017-10-27 21:28:07 +0200210 u8 mac[6];
211
212 clib_memcpy (mac, mp->mac, 6);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100213 if (mp->is_add)
214 {
Eyal Bari31a71ab2017-06-25 14:42:33 +0300215 if (mp->filter_mac)
216 l2fib_add_filter_entry (mac, bd_index);
217 else
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100218 {
Neale Rannsb54d0812018-09-06 06:22:56 -0700219 l2fib_entry_result_flags_t flags = L2FIB_ENTRY_RESULT_FLAG_NONE;
Eyal Bari31a71ab2017-06-25 14:42:33 +0300220 u32 sw_if_index = ntohl (mp->sw_if_index);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100221 VALIDATE_SW_IF_INDEX (mp);
222 if (vec_len (l2im->configs) <= sw_if_index)
223 {
224 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
225 goto bad_sw_if_index;
226 }
227 else
228 {
229 l2_input_config_t *config;
230 config = vec_elt_at_index (l2im->configs, sw_if_index);
231 if (config->bridge == 0)
232 {
233 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
234 goto bad_sw_if_index;
235 }
236 }
Neale Rannsb54d0812018-09-06 06:22:56 -0700237 if (mp->static_mac)
238 flags |= L2FIB_ENTRY_RESULT_FLAG_STATIC;
239 if (mp->bvi_mac)
240 flags |= L2FIB_ENTRY_RESULT_FLAG_BVI;
241 l2fib_add_entry (mac, bd_index, sw_if_index, flags);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100242 }
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100243 }
244 else
245 {
John Lo7dbd7262018-05-31 10:25:18 -0400246 u32 sw_if_index = ntohl (mp->sw_if_index);
247 if (l2fib_del_entry (mac, bd_index, sw_if_index))
248 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100249 }
250
251 BAD_SW_IF_INDEX_LABEL;
252
253 REPLY_MACRO (VL_API_L2FIB_ADD_DEL_REPLY);
254}
255
256static void
John Lo8d00fff2017-08-03 00:35:36 -0400257vl_api_want_l2_macs_events_t_handler (vl_api_want_l2_macs_events_t * mp)
258{
259 int rv = 0;
260 vl_api_want_l2_macs_events_reply_t *rmp;
261 l2learn_main_t *lm = &l2learn_main;
262 l2fib_main_t *fm = &l2fib_main;
263 u32 pid = ntohl (mp->pid);
264 u32 learn_limit = ntohl (mp->learn_limit);
265
266 if (mp->enable_disable)
267 {
268 if (lm->client_pid == 0)
269 {
270 lm->client_pid = pid;
271 lm->client_index = mp->client_index;
272
273 if (mp->max_macs_in_event)
274 fm->max_macs_in_event = mp->max_macs_in_event * 10;
275 else
276 fm->max_macs_in_event = L2FIB_EVENT_MAX_MACS_DEFAULT;
277
278 if (mp->scan_delay)
279 fm->event_scan_delay = (f64) (mp->scan_delay) * 10e-3;
280 else
281 fm->event_scan_delay = L2FIB_EVENT_SCAN_DELAY_DEFAULT;
282
283 /* change learn limit and flush all learned MACs */
284 if (learn_limit && (learn_limit < L2LEARN_DEFAULT_LIMIT))
285 lm->global_learn_limit = learn_limit;
286 else
287 lm->global_learn_limit = L2FIB_EVENT_LEARN_LIMIT_DEFAULT;
288
289 l2fib_flush_all_mac (vlib_get_main ());
290 }
291 else if (lm->client_pid != pid)
292 {
293 rv = VNET_API_ERROR_L2_MACS_EVENT_CLINET_PRESENT;
294 goto exit;
295 }
296 }
297 else if (lm->client_pid)
298 {
299 lm->client_pid = 0;
300 lm->client_index = 0;
John Lodbfa5742017-09-02 08:27:36 -0400301 if (learn_limit && (learn_limit < L2LEARN_DEFAULT_LIMIT))
John Loe531f4c2017-08-22 09:16:50 -0400302 lm->global_learn_limit = learn_limit;
303 else
304 lm->global_learn_limit = L2LEARN_DEFAULT_LIMIT;
John Lo8d00fff2017-08-03 00:35:36 -0400305 }
306
307exit:
308 REPLY_MACRO (VL_API_WANT_L2_MACS_EVENTS_REPLY);
309}
310
311static void
Eyal Barif24991c2017-04-05 05:33:21 +0300312vl_api_l2fib_flush_int_t_handler (vl_api_l2fib_flush_int_t * mp)
313{
314 int rv = 0;
315 vlib_main_t *vm = vlib_get_main ();
316 vl_api_l2fib_flush_int_reply_t *rmp;
317
318 VALIDATE_SW_IF_INDEX (mp);
319
320 u32 sw_if_index = ntohl (mp->sw_if_index);
321 l2fib_flush_int_mac (vm, sw_if_index);
322
323 BAD_SW_IF_INDEX_LABEL;
324 REPLY_MACRO (VL_API_L2FIB_FLUSH_INT_REPLY);
325}
326
327static void
Eyal Bari7537e712017-04-27 14:07:55 +0300328vl_api_l2fib_flush_all_t_handler (vl_api_l2fib_flush_all_t * mp)
329{
330 int rv = 0;
331 vl_api_l2fib_flush_all_reply_t *rmp;
332
333 l2fib_flush_all_mac (vlib_get_main ());
334 REPLY_MACRO (VL_API_L2FIB_FLUSH_ALL_REPLY);
335}
336
337static void
Eyal Barif24991c2017-04-05 05:33:21 +0300338vl_api_l2fib_flush_bd_t_handler (vl_api_l2fib_flush_bd_t * mp)
339{
340 int rv = 0;
341 vlib_main_t *vm = vlib_get_main ();
342 bd_main_t *bdm = &bd_main;
343 vl_api_l2fib_flush_bd_reply_t *rmp;
344
345 u32 bd_id = ntohl (mp->bd_id);
346 uword *p = hash_get (bdm->bd_index_by_bd_id, bd_id);
347 if (p == 0)
348 {
349 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
350 goto out;
351 }
352 l2fib_flush_bd_mac (vm, *p);
353out:
354 REPLY_MACRO (VL_API_L2FIB_FLUSH_BD_REPLY);
355}
356
357static void
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100358vl_api_l2_flags_t_handler (vl_api_l2_flags_t * mp)
359{
360 vl_api_l2_flags_reply_t *rmp;
361 int rv = 0;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100362 u32 rbm = 0;
363
364 VALIDATE_SW_IF_INDEX (mp);
365
Eyal Barifead6702017-04-04 04:46:32 +0300366 u32 sw_if_index = ntohl (mp->sw_if_index);
John Lo8d00fff2017-08-03 00:35:36 -0400367 u32 flags = ntohl (mp->feature_bitmap);
368 u32 bitmap = 0;
369
370 if (flags & L2_LEARN)
371 bitmap |= L2INPUT_FEAT_LEARN;
372
373 if (flags & L2_FWD)
374 bitmap |= L2INPUT_FEAT_FWD;
375
376 if (flags & L2_FLOOD)
377 bitmap |= L2INPUT_FEAT_FLOOD;
378
379 if (flags & L2_UU_FLOOD)
380 bitmap |= L2INPUT_FEAT_UU_FLOOD;
381
382 if (flags & L2_ARP_TERM)
383 bitmap |= L2INPUT_FEAT_ARP_TERM;
384
385 rbm = l2input_intf_bitmap_enable (sw_if_index, bitmap, mp->is_set);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100386
387 BAD_SW_IF_INDEX_LABEL;
388
389 /* *INDENT-OFF* */
390 REPLY_MACRO2(VL_API_L2_FLAGS_REPLY,
391 ({
392 rmp->resulting_feature_bitmap = ntohl(rbm);
393 }));
394 /* *INDENT-ON* */
395}
396
397static void
Eyal Barifead6702017-04-04 04:46:32 +0300398vl_api_bridge_domain_set_mac_age_t_handler (vl_api_bridge_domain_set_mac_age_t
399 * mp)
400{
401 vlib_main_t *vm = vlib_get_main ();
402 bd_main_t *bdm = &bd_main;
403 vl_api_bridge_domain_set_mac_age_reply_t *rmp;
404 int rv = 0;
405 u32 bd_id = ntohl (mp->bd_id);
Jon Loeliger1c7d4852017-05-02 11:06:23 -0500406 uword *p;
407
408 if (bd_id == 0)
409 {
410 rv = VNET_API_ERROR_BD_NOT_MODIFIABLE;
411 goto out;
412 }
413
414 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
Eyal Barifead6702017-04-04 04:46:32 +0300415 if (p == 0)
416 {
417 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
418 goto out;
419 }
420 bd_set_mac_age (vm, *p, mp->mac_age);
421out:
422 REPLY_MACRO (VL_API_BRIDGE_DOMAIN_SET_MAC_AGE_REPLY);
423}
424
425static void
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100426vl_api_bridge_domain_add_del_t_handler (vl_api_bridge_domain_add_del_t * mp)
427{
Eyal Barib1352ed2017-04-07 23:14:17 +0300428 l2_bridge_domain_add_del_args_t a = {
429 .is_add = mp->is_add,
430 .flood = mp->flood,
431 .uu_flood = mp->uu_flood,
432 .forward = mp->forward,
433 .learn = mp->learn,
434 .arp_term = mp->arp_term,
435 .mac_age = mp->mac_age,
436 .bd_id = ntohl (mp->bd_id),
Jerome Tollet48304142017-09-05 12:13:22 +0100437 .bd_tag = mp->bd_tag
Eyal Barib1352ed2017-04-07 23:14:17 +0300438 };
439
440 int rv = bd_add_del (&a);
441
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100442 vl_api_bridge_domain_add_del_reply_t *rmp;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100443 REPLY_MACRO (VL_API_BRIDGE_DOMAIN_ADD_DEL_REPLY);
444}
445
446static void
Ole Troan01384fe2017-05-12 11:55:35 +0200447send_bridge_domain_details (l2input_main_t * l2im,
Florin Coras6c4dae22018-01-09 06:39:23 -0800448 vl_api_registration_t * reg,
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100449 l2_bridge_domain_t * bd_config,
450 u32 n_sw_ifs, u32 context)
451{
452 vl_api_bridge_domain_details_t *mp;
Ole Troan01384fe2017-05-12 11:55:35 +0200453 l2_flood_member_t *m;
454 vl_api_bridge_domain_sw_if_t *sw_ifs;
455 l2_input_config_t *input_cfg;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100456
Ole Troan01384fe2017-05-12 11:55:35 +0200457 mp = vl_msg_api_alloc (sizeof (*mp) +
458 (n_sw_ifs * sizeof (vl_api_bridge_domain_sw_if_t)));
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100459 memset (mp, 0, sizeof (*mp));
460 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_DETAILS);
461 mp->bd_id = ntohl (bd_config->bd_id);
462 mp->flood = bd_feature_flood (bd_config);
463 mp->uu_flood = bd_feature_uu_flood (bd_config);
464 mp->forward = bd_feature_forward (bd_config);
465 mp->learn = bd_feature_learn (bd_config);
466 mp->arp_term = bd_feature_arp_term (bd_config);
467 mp->bvi_sw_if_index = ntohl (bd_config->bvi_sw_if_index);
Neale Rannsb4743802018-09-05 09:13:57 -0700468 mp->uu_fwd_sw_if_index = ntohl (bd_config->uu_fwd_sw_if_index);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100469 mp->mac_age = bd_config->mac_age;
Jerome Tollet48304142017-09-05 12:13:22 +0100470 if (bd_config->bd_tag)
471 {
472 strncpy ((char *) mp->bd_tag, (char *) bd_config->bd_tag,
473 ARRAY_LEN (mp->bd_tag) - 1);
474 mp->bd_tag[ARRAY_LEN (mp->bd_tag) - 1] = 0;
475 }
476
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100477 mp->context = context;
478
Ole Troan01384fe2017-05-12 11:55:35 +0200479 sw_ifs = (vl_api_bridge_domain_sw_if_t *) mp->sw_if_details;
480 vec_foreach (m, bd_config->members)
481 {
482 sw_ifs->sw_if_index = ntohl (m->sw_if_index);
483 input_cfg = vec_elt_at_index (l2im->configs, m->sw_if_index);
484 sw_ifs->shg = input_cfg->shg;
485 sw_ifs++;
486 mp->n_sw_ifs++;
487 }
488 mp->n_sw_ifs = htonl (mp->n_sw_ifs);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100489
Florin Coras6c4dae22018-01-09 06:39:23 -0800490 vl_api_send_msg (reg, (u8 *) mp);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100491}
492
493static void
494vl_api_bridge_domain_dump_t_handler (vl_api_bridge_domain_dump_t * mp)
495{
496 bd_main_t *bdm = &bd_main;
497 l2input_main_t *l2im = &l2input_main;
Florin Coras6c4dae22018-01-09 06:39:23 -0800498 vl_api_registration_t *reg;
499 u32 bd_id, bd_index, end;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100500
Florin Coras6c4dae22018-01-09 06:39:23 -0800501 reg = vl_api_client_index_to_registration (mp->client_index);
502 if (!reg)
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100503 return;
504
Florin Coras6c4dae22018-01-09 06:39:23 -0800505 bd_id = ntohl (mp->bd_id);
Jon Loeliger1c7d4852017-05-02 11:06:23 -0500506 if (bd_id == 0)
507 return;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100508
Eyal Bari259fca72017-05-14 10:38:39 +0300509 if (bd_id == ~0)
510 bd_index = 0, end = vec_len (l2im->bd_configs);
511 else
512 {
513 bd_index = bd_find_index (bdm, bd_id);
514 if (bd_index == ~0)
515 return;
516
517 end = bd_index + 1;
518 }
Jon Loeliger1c7d4852017-05-02 11:06:23 -0500519
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100520 for (; bd_index < end; bd_index++)
521 {
Eyal Bari259fca72017-05-14 10:38:39 +0300522 l2_bridge_domain_t *bd_config =
523 l2input_bd_config_from_index (l2im, bd_index);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100524 /* skip dummy bd_id 0 */
525 if (bd_config && (bd_config->bd_id > 0))
Florin Coras6c4dae22018-01-09 06:39:23 -0800526 send_bridge_domain_details (l2im, reg, bd_config,
Ole Troan01384fe2017-05-12 11:55:35 +0200527 vec_len (bd_config->members),
528 mp->context);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100529 }
530}
531
Neale Rannsb4743802018-09-05 09:13:57 -0700532static bd_flags_t
533bd_flags_decode (vl_api_bd_flags_t v)
534{
535 bd_flags_t f = L2_NONE;
536
537 v = ntohl (v);
538
539 if (v & BRIDGE_API_FLAG_LEARN)
540 f |= L2_LEARN;
541 if (v & BRIDGE_API_FLAG_FWD)
542 f |= L2_FWD;
543 if (v & BRIDGE_API_FLAG_FLOOD)
544 f |= L2_FLOOD;
545 if (v & BRIDGE_API_FLAG_UU_FLOOD)
546 f |= L2_UU_FLOOD;
547 if (v & BRIDGE_API_FLAG_ARP_TERM)
548 f |= L2_ARP_TERM;
549
550 return (f);
551}
552
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100553static void
554vl_api_bridge_flags_t_handler (vl_api_bridge_flags_t * mp)
555{
556 vlib_main_t *vm = vlib_get_main ();
557 bd_main_t *bdm = &bd_main;
558 vl_api_bridge_flags_reply_t *rmp;
559 int rv = 0;
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100560
Neale Rannsb4743802018-09-05 09:13:57 -0700561 bd_flags_t flags = bd_flags_decode (mp->flags);
Eyal Bari259fca72017-05-14 10:38:39 +0300562 u32 bd_id = ntohl (mp->bd_id);
Jon Loeliger1c7d4852017-05-02 11:06:23 -0500563 if (bd_id == 0)
564 {
565 rv = VNET_API_ERROR_BD_NOT_MODIFIABLE;
566 goto out;
567 }
568
Eyal Bari259fca72017-05-14 10:38:39 +0300569 u32 bd_index = bd_find_index (bdm, bd_id);
570 if (bd_index == ~0)
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100571 {
572 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
573 goto out;
574 }
575
John Lo8d00fff2017-08-03 00:35:36 -0400576 u32 bitmap = bd_set_flags (vm, bd_index, flags, mp->is_set);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100577
578out:
579 /* *INDENT-OFF* */
580 REPLY_MACRO2(VL_API_BRIDGE_FLAGS_REPLY,
581 ({
John Lo8d00fff2017-08-03 00:35:36 -0400582 rmp->resulting_feature_bitmap = ntohl(bitmap);
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100583 }));
584 /* *INDENT-ON* */
585}
Matus Fabianf468e232016-12-02 06:00:53 -0800586
Pavel Kotucekadec5872017-01-25 08:50:53 +0100587static void
588 vl_api_l2_interface_vlan_tag_rewrite_t_handler
589 (vl_api_l2_interface_vlan_tag_rewrite_t * mp)
590{
591 int rv = 0;
592 vl_api_l2_interface_vlan_tag_rewrite_reply_t *rmp;
593 vnet_main_t *vnm = vnet_get_main ();
594 vlib_main_t *vm = vlib_get_main ();
595 u32 vtr_op;
596
597 VALIDATE_SW_IF_INDEX (mp);
598
599 vtr_op = ntohl (mp->vtr_op);
600
601 /* The L2 code is unsuspicious */
602 switch (vtr_op)
603 {
604 case L2_VTR_DISABLED:
605 case L2_VTR_PUSH_1:
606 case L2_VTR_PUSH_2:
607 case L2_VTR_POP_1:
608 case L2_VTR_POP_2:
609 case L2_VTR_TRANSLATE_1_1:
610 case L2_VTR_TRANSLATE_1_2:
611 case L2_VTR_TRANSLATE_2_1:
612 case L2_VTR_TRANSLATE_2_2:
613 break;
614
615 default:
616 rv = VNET_API_ERROR_INVALID_VALUE;
617 goto bad_sw_if_index;
618 }
619
620 rv = l2vtr_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
621 ntohl (mp->push_dot1q), ntohl (mp->tag1),
622 ntohl (mp->tag2));
623
624 BAD_SW_IF_INDEX_LABEL;
625
626 REPLY_MACRO (VL_API_L2_INTERFACE_VLAN_TAG_REWRITE_REPLY);
627}
628
629static void
630 vl_api_l2_interface_pbb_tag_rewrite_t_handler
631 (vl_api_l2_interface_pbb_tag_rewrite_t * mp)
632{
633 vl_api_l2_interface_pbb_tag_rewrite_reply_t *rmp;
634 vnet_main_t *vnm = vnet_get_main ();
635 vlib_main_t *vm = vlib_get_main ();
636 u32 vtr_op;
637 int rv = 0;
638
639 VALIDATE_SW_IF_INDEX (mp);
640
641 vtr_op = ntohl (mp->vtr_op);
642
643 switch (vtr_op)
644 {
645 case L2_VTR_DISABLED:
646 case L2_VTR_PUSH_2:
647 case L2_VTR_POP_2:
648 case L2_VTR_TRANSLATE_2_1:
649 break;
650
651 default:
652 rv = VNET_API_ERROR_INVALID_VALUE;
653 goto bad_sw_if_index;
654 }
655
656 rv = l2pbb_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
657 mp->b_dmac, mp->b_smac, ntohs (mp->b_vlanid),
658 ntohl (mp->i_sid), ntohs (mp->outer_tag));
659
660 BAD_SW_IF_INDEX_LABEL;
661
662 REPLY_MACRO (VL_API_L2_INTERFACE_PBB_TAG_REWRITE_REPLY);
663}
664
Neale Rannsb8d44812017-11-10 06:53:54 -0800665static void
666 vl_api_sw_interface_set_l2_xconnect_t_handler
667 (vl_api_sw_interface_set_l2_xconnect_t * mp)
668{
669 vl_api_sw_interface_set_l2_xconnect_reply_t *rmp;
670 int rv = 0;
671 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
672 u32 tx_sw_if_index = ntohl (mp->tx_sw_if_index);
673 vlib_main_t *vm = vlib_get_main ();
674 vnet_main_t *vnm = vnet_get_main ();
675
676 VALIDATE_RX_SW_IF_INDEX (mp);
677
678 if (mp->enable)
679 {
680 VALIDATE_TX_SW_IF_INDEX (mp);
681 rv = set_int_l2_mode (vm, vnm, MODE_L2_XC,
Neale Rannsb4743802018-09-05 09:13:57 -0700682 rx_sw_if_index, 0,
683 L2_BD_PORT_TYPE_NORMAL, 0, tx_sw_if_index);
Neale Rannsb8d44812017-11-10 06:53:54 -0800684 }
685 else
686 {
Neale Rannsb4743802018-09-05 09:13:57 -0700687 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0,
688 L2_BD_PORT_TYPE_NORMAL, 0, 0);
Neale Rannsb8d44812017-11-10 06:53:54 -0800689 }
690
Alexander Chernavine178b272018-09-24 05:42:01 -0400691 switch (rv)
692 {
693 case MODE_ERROR_ETH:
694 rv = VNET_API_ERROR_NON_ETHERNET;
695 break;
696 case MODE_ERROR_BVI_DEF:
697 rv = VNET_API_ERROR_BD_ALREADY_HAS_BVI;
698 break;
699 }
700
Neale Rannsb8d44812017-11-10 06:53:54 -0800701 BAD_RX_SW_IF_INDEX_LABEL;
702 BAD_TX_SW_IF_INDEX_LABEL;
703
704 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
705}
706
Neale Rannsb4743802018-09-05 09:13:57 -0700707static int
708l2_bd_port_type_decode (vl_api_l2_port_type_t v, l2_bd_port_type_t * l)
709{
710 v = clib_net_to_host_u32 (v);
711
712 switch (v)
713 {
714 case L2_API_PORT_TYPE_NORMAL:
715 *l = L2_BD_PORT_TYPE_NORMAL;
716 return 0;
717 case L2_API_PORT_TYPE_BVI:
718 *l = L2_BD_PORT_TYPE_BVI;
719 return 0;
720 case L2_API_PORT_TYPE_UU_FWD:
721 *l = L2_BD_PORT_TYPE_UU_FWD;
722 return 0;
723 }
724
725 return (VNET_API_ERROR_INVALID_VALUE);
726}
727
Neale Rannsb8d44812017-11-10 06:53:54 -0800728static void
729 vl_api_sw_interface_set_l2_bridge_t_handler
730 (vl_api_sw_interface_set_l2_bridge_t * mp)
731{
732 bd_main_t *bdm = &bd_main;
733 vl_api_sw_interface_set_l2_bridge_reply_t *rmp;
734 int rv = 0;
735 vlib_main_t *vm = vlib_get_main ();
736 vnet_main_t *vnm = vnet_get_main ();
Neale Rannsb4743802018-09-05 09:13:57 -0700737 l2_bd_port_type_t pt;
Neale Rannsb8d44812017-11-10 06:53:54 -0800738
739 VALIDATE_RX_SW_IF_INDEX (mp);
740 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
Neale Rannsb4743802018-09-05 09:13:57 -0700741 rv = l2_bd_port_type_decode (mp->port_type, &pt);
Neale Rannsb8d44812017-11-10 06:53:54 -0800742
Neale Rannsb4743802018-09-05 09:13:57 -0700743 if (0 != rv)
744 goto out;
Neale Rannsb8d44812017-11-10 06:53:54 -0800745 if (mp->enable)
746 {
747 VALIDATE_BD_ID (mp);
748 u32 bd_id = ntohl (mp->bd_id);
749 u32 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
Neale Rannsb4743802018-09-05 09:13:57 -0700750
Neale Rannsb8d44812017-11-10 06:53:54 -0800751 rv = set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE,
Neale Rannsb4743802018-09-05 09:13:57 -0700752 rx_sw_if_index, bd_index, pt, mp->shg, 0);
Neale Rannsb8d44812017-11-10 06:53:54 -0800753 }
754 else
755 {
Neale Rannsb4743802018-09-05 09:13:57 -0700756 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, pt, 0, 0);
Neale Rannsb8d44812017-11-10 06:53:54 -0800757 }
758
Alexander Chernavine178b272018-09-24 05:42:01 -0400759 switch (rv)
760 {
761 case MODE_ERROR_ETH:
762 rv = VNET_API_ERROR_NON_ETHERNET;
763 break;
764 case MODE_ERROR_BVI_DEF:
765 rv = VNET_API_ERROR_BD_ALREADY_HAS_BVI;
766 break;
767 }
768
Neale Rannsb8d44812017-11-10 06:53:54 -0800769 BAD_RX_SW_IF_INDEX_LABEL;
770 BAD_BD_ID_LABEL;
Neale Rannsb4743802018-09-05 09:13:57 -0700771out:
Neale Rannsb8d44812017-11-10 06:53:54 -0800772 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
773}
774
775static void
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +0200776send_bd_ip_mac_entry (vpe_api_main_t * am,
777 vl_api_registration_t * reg,
778 u32 bd_id, u8 is_ipv6,
779 u8 * ip_address, u8 * mac_address, u32 context)
780{
781 vl_api_bd_ip_mac_details_t *mp;
782
783 mp = vl_msg_api_alloc (sizeof (*mp));
784 memset (mp, 0, sizeof (*mp));
785 mp->_vl_msg_id = ntohs (VL_API_BD_IP_MAC_DETAILS);
786
787 mp->bd_id = ntohl (bd_id);
788
789 clib_memcpy (mp->mac_address, mac_address, 6);
790 mp->is_ipv6 = is_ipv6;
791 clib_memcpy (mp->ip_address, ip_address, (is_ipv6) ? 16 : 4);
792 mp->context = context;
793
794 vl_api_send_msg (reg, (u8 *) mp);
795}
796
797static void
798vl_api_bd_ip_mac_dump_t_handler (vl_api_bd_ip_mac_dump_t * mp)
799{
800 vpe_api_main_t *am = &vpe_api_main;
801 bd_main_t *bdm = &bd_main;
802 l2_bridge_domain_t *bd_config;
803 u32 bd_id = ntohl (mp->bd_id);
Mohsin Kazmib24dfec2018-08-23 12:24:19 +0200804 u32 bd_index, start, end;
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +0200805 vl_api_registration_t *reg;
806 uword *p;
807
808 reg = vl_api_client_index_to_registration (mp->client_index);
809 if (!reg)
810 return;
811
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +0200812 /* see bd_id: ~0 means "any" */
813 if (bd_id == ~0)
Mohsin Kazmib24dfec2018-08-23 12:24:19 +0200814 {
815 start = 1;
816 end = vec_len (l2input_main.bd_configs);
817 }
Mohsin Kazmi5d82d2f2018-08-13 19:17:54 +0200818 else
819 {
820 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
821 if (p == 0)
822 return;
823
824 bd_index = p[0];
825 vec_validate (l2input_main.bd_configs, bd_index);
826 start = bd_index;
827 end = start + 1;
828 }
829
830 for (bd_index = start; bd_index < end; bd_index++)
831 {
832 bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
833 if (bd_is_valid (bd_config))
834 {
835 ip4_address_t ip4_addr;
836 ip6_address_t *ip6_addr;
837 u64 mac_addr;
838 bd_id = bd_config->bd_id;
839
840 /* *INDENT-OFF* */
841 hash_foreach (ip4_addr.as_u32, mac_addr, bd_config->mac_by_ip4,
842 ({
843 send_bd_ip_mac_entry (am, reg, bd_id, 0, (u8 *) &(ip4_addr.as_u8), (u8 *) &mac_addr, mp->context);
844 }));
845
846 hash_foreach_mem (ip6_addr, mac_addr, bd_config->mac_by_ip6,
847 ({
848 send_bd_ip_mac_entry (am, reg, bd_id, 1, (u8 *) &(ip6_addr->as_u8), (u8 *) &mac_addr, mp->context);
849 }));
850 /* *INDENT-ON* */
851 }
852 }
853}
854
855static void
Neale Rannsb8d44812017-11-10 06:53:54 -0800856vl_api_bd_ip_mac_add_del_t_handler (vl_api_bd_ip_mac_add_del_t * mp)
857{
858 bd_main_t *bdm = &bd_main;
859 vl_api_bd_ip_mac_add_del_reply_t *rmp;
860 int rv = 0;
861 u32 bd_id = ntohl (mp->bd_id);
862 u32 bd_index;
863 uword *p;
864
865 if (bd_id == 0)
866 {
867 rv = VNET_API_ERROR_BD_NOT_MODIFIABLE;
868 goto out;
869 }
870
871 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
872 if (p == 0)
873 {
874 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
875 goto out;
876 }
877
878 bd_index = p[0];
879 if (bd_add_del_ip_mac (bd_index, mp->ip_address,
880 mp->mac_address, mp->is_ipv6, mp->is_add))
881 rv = VNET_API_ERROR_UNSPECIFIED;
882
883out:
884 REPLY_MACRO (VL_API_BD_IP_MAC_ADD_DEL_REPLY);
885}
886
887extern void l2_efp_filter_configure (vnet_main_t * vnet_main,
Neale Ranns6b9b41c2018-07-23 05:47:09 -0400888 u32 sw_if_index, u8 enable);
Neale Rannsb8d44812017-11-10 06:53:54 -0800889
890static void
891vl_api_l2_interface_efp_filter_t_handler (vl_api_l2_interface_efp_filter_t *
892 mp)
893{
894 int rv;
895 vl_api_l2_interface_efp_filter_reply_t *rmp;
896 vnet_main_t *vnm = vnet_get_main ();
897
Neale Ranns6b9b41c2018-07-23 05:47:09 -0400898 VALIDATE_SW_IF_INDEX (mp);
899
Neale Rannsb8d44812017-11-10 06:53:54 -0800900 // enable/disable the feature
Neale Ranns6b9b41c2018-07-23 05:47:09 -0400901 l2_efp_filter_configure (vnm, ntohl (mp->sw_if_index), mp->enable_disable);
Neale Rannsb8d44812017-11-10 06:53:54 -0800902 rv = vnm->api_errno;
903
Neale Ranns6b9b41c2018-07-23 05:47:09 -0400904 BAD_SW_IF_INDEX_LABEL;
Neale Rannsb8d44812017-11-10 06:53:54 -0800905 REPLY_MACRO (VL_API_L2_INTERFACE_EFP_FILTER_REPLY);
906}
907
908static void
909vl_api_l2_patch_add_del_t_handler (vl_api_l2_patch_add_del_t * mp)
910{
911 extern int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
912 int is_add);
913 vl_api_l2_patch_add_del_reply_t *rmp;
914 int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
915 int is_add);
916 int rv = 0;
917
918 VALIDATE_RX_SW_IF_INDEX (mp);
919 VALIDATE_TX_SW_IF_INDEX (mp);
920
921 rv = vnet_l2_patch_add_del (ntohl (mp->rx_sw_if_index),
922 ntohl (mp->tx_sw_if_index),
923 (int) (mp->is_add != 0));
924
925 BAD_RX_SW_IF_INDEX_LABEL;
926 BAD_TX_SW_IF_INDEX_LABEL;
927
928 REPLY_MACRO (VL_API_L2_PATCH_ADD_DEL_REPLY);
929}
930
931static void
932vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t * mp)
933{
934 vl_api_sw_interface_set_vpath_reply_t *rmp;
935 int rv = 0;
936 u32 sw_if_index = ntohl (mp->sw_if_index);
937
938 VALIDATE_SW_IF_INDEX (mp);
939
940 l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
941 vnet_feature_enable_disable ("ip4-unicast", "vpath-input-ip4",
942 sw_if_index, mp->enable, 0, 0);
943 vnet_feature_enable_disable ("ip4-multicast", "vpath-input-ip4",
944 sw_if_index, mp->enable, 0, 0);
945 vnet_feature_enable_disable ("ip6-unicast", "vpath-input-ip6",
946 sw_if_index, mp->enable, 0, 0);
947 vnet_feature_enable_disable ("ip6-multicast", "vpath-input-ip6",
948 sw_if_index, mp->enable, 0, 0);
949
950 BAD_SW_IF_INDEX_LABEL;
951
952 REPLY_MACRO (VL_API_SW_INTERFACE_SET_VPATH_REPLY);
953}
954
Matus Fabianf468e232016-12-02 06:00:53 -0800955/*
Pavel Kotucek0f971d82017-01-03 10:48:54 +0100956 * l2_api_hookup
Matus Fabianf468e232016-12-02 06:00:53 -0800957 * Add vpe's API message handlers to the table.
Paul Vinciguerrabdc0e6b2018-09-22 05:32:50 -0700958 * vlib has already mapped shared memory and
Matus Fabianf468e232016-12-02 06:00:53 -0800959 * added the client registration handlers.
960 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
961 */
962#define vl_msg_name_crc_list
963#include <vnet/vnet_all_api_h.h>
964#undef vl_msg_name_crc_list
965
966static void
967setup_message_id_table (api_main_t * am)
968{
969#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
970 foreach_vl_msg_name_crc_l2;
971#undef _
972}
973
974static clib_error_t *
975l2_api_hookup (vlib_main_t * vm)
976{
977 api_main_t *am = &api_main;
978
979#define _(N,n) \
980 vl_msg_api_set_handlers(VL_API_##N, #n, \
981 vl_api_##n##_t_handler, \
982 vl_noop_handler, \
983 vl_api_##n##_t_endian, \
984 vl_api_##n##_t_print, \
985 sizeof(vl_api_##n##_t), 1);
986 foreach_vpe_api_msg;
987#undef _
988
989 /*
990 * Set up the (msg_name, crc, message-id) table
991 */
992 setup_message_id_table (am);
993
994 return 0;
995}
996
997VLIB_API_INIT_FUNCTION (l2_api_hookup);
998
999/*
1000 * fd.io coding-style-patch-verification: ON
1001 *
1002 * Local Variables:
1003 * eval: (c-set-style "gnu")
1004 * End:
1005 */