blob: d999ed46fad9e971fb299303be57df6391ea92e6 [file] [log] [blame]
Juraj Slobodac0374232018-02-01 15:18:49 +01001#include <vnet/vnet.h>
2#include <vlibmemory/api.h>
3#include <vnet/vnet_msg_enum.h>
4#include <vnet/ip/ip6.h>
Juraj Sloboda52574522018-05-03 10:03:50 +02005#include <vnet/ethernet/ethernet.h>
6#include <vnet/ip/ip6_neighbor.h>
Juraj Slobodac0374232018-02-01 15:18:49 +01007#include <signal.h>
8#include <math.h>
9
10#define vl_typedefs /* define message structures */
11#include <vnet/vnet_all_api_h.h>
12#undef vl_typedefs
13
14#define vl_endianfun /* define message structures */
15#include <vnet/vnet_all_api_h.h>
16#undef vl_endianfun
17
18#include <vlibapi/api_helper_macros.h>
19
20#define foreach_rd_cp_msg \
21_(IP6_ND_ADDRESS_AUTOCONFIG, ip6_nd_address_autoconfig)
22
Juraj Slobodac0374232018-02-01 15:18:49 +010023typedef struct
24{
25 u32 sw_if_index;
26 u8 address_length;
27 ip6_address_t address;
28 f64 due_time;
29} slaac_address_t;
30
31typedef struct
32{
33 u32 sw_if_index;
34 ip6_address_t router_address;
35 f64 due_time;
36} default_route_t;
37
38typedef struct
39{
40 u8 enabled;
41 u8 install_default_routes;
42} interface_config_t;
43
44typedef struct
45{
46 u8 enabled;
47 u8 events_on;
48
49 interface_config_t *config_by_sw_if_index;
50 slaac_address_t *slaac_address_pool;
51 default_route_t *default_route_pool;
52
53 /* binary API client */
54 u8 api_connected;
55 svm_queue_t *vl_input_queue;
56 u32 my_client_index;
Juraj Slobodac0374232018-02-01 15:18:49 +010057
58 /* convenience */
59 vlib_main_t *vlib_main;
60 vnet_main_t *vnet_main;
61 api_main_t *api_main;
62 u32 node_index;
63} rd_cp_main_t;
64
65rd_cp_main_t rd_cp_main;
66
67enum
68{
69 RD_CP_EVENT_INTERRUPT,
70};
71
72#define vl_api_ip6_nd_address_autoconfig_t_print vl_noop_handler
73
74static void
Juraj Slobodac0374232018-02-01 15:18:49 +010075router_solicitation_start_stop (u32 sw_if_index, u8 start)
76{
77 rd_cp_main_t *rm = &rd_cp_main;
Juraj Sloboda52574522018-05-03 10:03:50 +020078 icmp6_send_router_solicitation_params_t params = { 0, };
Juraj Slobodac0374232018-02-01 15:18:49 +010079
Juraj Slobodac0374232018-02-01 15:18:49 +010080 if (start)
81 {
Juraj Sloboda52574522018-05-03 10:03:50 +020082 params.irt = 1;
83 params.mrt = 120;
Juraj Slobodac0374232018-02-01 15:18:49 +010084 }
Juraj Slobodac0374232018-02-01 15:18:49 +010085
Juraj Sloboda52574522018-05-03 10:03:50 +020086 icmp6_send_router_solicitation (rm->vlib_main, sw_if_index, !start,
87 &params);
Juraj Slobodac0374232018-02-01 15:18:49 +010088}
89
90static void interrupt_process (void);
91
92static int
93add_slaac_address (vlib_main_t * vm, u32 sw_if_index, u8 address_length,
94 ip6_address_t * address, f64 due_time)
95{
96 rd_cp_main_t *rm = &rd_cp_main;
97 slaac_address_t *slaac_address;
Juraj Sloboda52574522018-05-03 10:03:50 +020098 clib_error_t *rv = 0;
Juraj Slobodac0374232018-02-01 15:18:49 +010099
100 pool_get (rm->slaac_address_pool, slaac_address);
101
102 slaac_address->sw_if_index = sw_if_index;
103 slaac_address->address_length = address_length;
104 slaac_address->address = *address;
105 slaac_address->due_time = due_time;
106
Juraj Sloboda52574522018-05-03 10:03:50 +0200107 rv =
108 ip6_add_del_interface_address (vm, sw_if_index, &slaac_address->address,
109 address_length, 0);
Juraj Slobodac0374232018-02-01 15:18:49 +0100110
Juraj Sloboda52574522018-05-03 10:03:50 +0200111 return rv != 0;
Juraj Slobodac0374232018-02-01 15:18:49 +0100112}
113
Juraj Sloboda52574522018-05-03 10:03:50 +0200114int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
Juraj Slobodac0374232018-02-01 15:18:49 +0100115
116static int
117add_default_route (vlib_main_t * vm, u32 sw_if_index,
118 ip6_address_t * next_hop_address, f64 due_time)
119{
120 rd_cp_main_t *rm = &rd_cp_main;
121 default_route_t *default_route;
Juraj Sloboda52574522018-05-03 10:03:50 +0200122 vl_api_ip_add_del_route_t mp = { 0, };
Juraj Slobodac0374232018-02-01 15:18:49 +0100123 int rv;
124
125 pool_get (rm->default_route_pool, default_route);
126
127 default_route->sw_if_index = sw_if_index;
128 default_route->router_address = *next_hop_address;
129 default_route->due_time = due_time;
130
Juraj Sloboda52574522018-05-03 10:03:50 +0200131 mp.is_add = 1;
132 mp.is_ipv6 = 1;
133 mp.dst_address_length = 0;
134 mp.next_hop_sw_if_index = htonl (default_route->sw_if_index);
135 clib_memcpy (mp.next_hop_address, default_route->router_address.as_u8, 16);
Juraj Slobodac0374232018-02-01 15:18:49 +0100136
Juraj Sloboda52574522018-05-03 10:03:50 +0200137 rv = ip6_add_del_route_t_handler (&mp);
Juraj Slobodac0374232018-02-01 15:18:49 +0100138
139 return rv;
140}
141
Juraj Slobodac0374232018-02-01 15:18:49 +0100142static int
143remove_slaac_address (vlib_main_t * vm, slaac_address_t * slaac_address)
144{
Juraj Sloboda52574522018-05-03 10:03:50 +0200145 clib_error_t *rv = 0;
Juraj Slobodac0374232018-02-01 15:18:49 +0100146
Juraj Sloboda52574522018-05-03 10:03:50 +0200147 rv = ip6_add_del_interface_address (vm, slaac_address->sw_if_index,
148 &slaac_address->address,
149 slaac_address->address_length, 1);
Juraj Slobodac0374232018-02-01 15:18:49 +0100150
Juraj Sloboda52574522018-05-03 10:03:50 +0200151 return rv != 0;
Juraj Slobodac0374232018-02-01 15:18:49 +0100152}
153
154static int
155remove_default_route (vlib_main_t * vm, default_route_t * default_route)
156{
157 rd_cp_main_t *rm = &rd_cp_main;
Juraj Sloboda52574522018-05-03 10:03:50 +0200158 vl_api_ip_add_del_route_t mp = { 0, };
159 int rv;
Juraj Slobodac0374232018-02-01 15:18:49 +0100160
Juraj Sloboda52574522018-05-03 10:03:50 +0200161 mp.is_add = 0;
162 mp.is_ipv6 = 1;
163 mp.dst_address_length = 0;
164 mp.next_hop_sw_if_index = htonl (default_route->sw_if_index);
165 clib_memcpy (mp.next_hop_address, default_route->router_address.as_u8, 16);
Juraj Slobodac0374232018-02-01 15:18:49 +0100166
Juraj Sloboda52574522018-05-03 10:03:50 +0200167 rv = ip6_add_del_route_t_handler (&mp);
Juraj Slobodac0374232018-02-01 15:18:49 +0100168
Juraj Sloboda52574522018-05-03 10:03:50 +0200169 if (!rv)
170 pool_put (rm->default_route_pool, default_route);
Juraj Slobodac0374232018-02-01 15:18:49 +0100171
Juraj Sloboda52574522018-05-03 10:03:50 +0200172 return rv;
Juraj Slobodac0374232018-02-01 15:18:49 +0100173}
174
175static u32
176get_interface_mac_address (u32 sw_if_index, u8 mac[])
177{
178 rd_cp_main_t *rm = &rd_cp_main;
Juraj Sloboda52574522018-05-03 10:03:50 +0200179 vnet_sw_interface_t *si;
180 ethernet_interface_t *eth_if = 0;
Juraj Slobodac0374232018-02-01 15:18:49 +0100181
Juraj Sloboda52574522018-05-03 10:03:50 +0200182 if (!vnet_sw_interface_is_api_valid (rm->vnet_main, sw_if_index))
183 {
184 clib_warning ("Invalid sw_if_index");
185 return 1;
186 }
Juraj Slobodac0374232018-02-01 15:18:49 +0100187
Juraj Sloboda52574522018-05-03 10:03:50 +0200188 si = vnet_get_sup_sw_interface (rm->vnet_main, sw_if_index);
189 if (si->type == VNET_SW_INTERFACE_TYPE_HARDWARE)
190 eth_if = ethernet_get_interface (&ethernet_main, si->hw_if_index);
Juraj Slobodac0374232018-02-01 15:18:49 +0100191
Juraj Sloboda52574522018-05-03 10:03:50 +0200192 clib_memcpy (mac, eth_if->address, 6);
Juraj Slobodac0374232018-02-01 15:18:49 +0100193
Juraj Sloboda52574522018-05-03 10:03:50 +0200194 return 0;
Juraj Slobodac0374232018-02-01 15:18:49 +0100195}
196
197static u32
198ip6_enable (u32 sw_if_index)
199{
200 rd_cp_main_t *rm = &rd_cp_main;
Juraj Sloboda52574522018-05-03 10:03:50 +0200201 clib_error_t *rv;
Juraj Slobodac0374232018-02-01 15:18:49 +0100202
Juraj Sloboda52574522018-05-03 10:03:50 +0200203 rv = enable_ip6_interface (rm->vlib_main, sw_if_index);
Juraj Slobodac0374232018-02-01 15:18:49 +0100204
Juraj Sloboda52574522018-05-03 10:03:50 +0200205 return rv != 0;
Juraj Slobodac0374232018-02-01 15:18:49 +0100206}
207
208static u8
209ip6_prefixes_equal (ip6_address_t * prefix1, ip6_address_t * prefix2, u8 len)
210{
211 if (len >= 64)
212 {
213 if (prefix1->as_u64[0] != prefix2->as_u64[0])
214 return 0;
215 if (len == 64)
216 return 1;
217 return prefix1->as_u64[1] >> (128 - len) ==
218 prefix2->as_u64[1] >> (128 - len);
219 }
220 return prefix1->as_u64[0] >> (64 - len) == prefix2->as_u64[0] >> (64 - len);
221}
222
223#define PREFIX_FLAG_A (1 << 6)
224#define PREFIX_FLAG_L (1 << 7)
225
Juraj Sloboda52574522018-05-03 10:03:50 +0200226static clib_error_t *
227ip6_ra_report_handler (void *data)
Juraj Slobodac0374232018-02-01 15:18:49 +0100228{
229 rd_cp_main_t *rm = &rd_cp_main;
230 vlib_main_t *vm = rm->vlib_main;
Juraj Sloboda52574522018-05-03 10:03:50 +0200231 clib_error_t *error = 0;
232 ra_report_t *r = data;
Juraj Slobodac0374232018-02-01 15:18:49 +0100233 interface_config_t *if_config;
234 default_route_t *default_route;
235 slaac_address_t *slaac_address;
236 u32 sw_if_index;
237 u16 router_lifetime_in_sec;
238 u32 n_prefixes;
Juraj Sloboda52574522018-05-03 10:03:50 +0200239 ra_report_prefix_info_t *prefix;
Juraj Slobodac0374232018-02-01 15:18:49 +0100240 u8 mac[6];
241 f64 current_time;
242 u32 i;
243
244 current_time = vlib_time_now (vm);
245
Juraj Sloboda52574522018-05-03 10:03:50 +0200246 sw_if_index = r->sw_if_index;
Juraj Slobodac0374232018-02-01 15:18:49 +0100247
Juraj Sloboda52574522018-05-03 10:03:50 +0200248 if (sw_if_index >= vec_len (rm->config_by_sw_if_index))
249 return 0;
Juraj Slobodac0374232018-02-01 15:18:49 +0100250 if_config = &rm->config_by_sw_if_index[sw_if_index];
251
252 if (if_config->install_default_routes)
253 {
Juraj Sloboda52574522018-05-03 10:03:50 +0200254 router_lifetime_in_sec = r->router_lifetime_in_sec;
Juraj Slobodac0374232018-02-01 15:18:49 +0100255 u8 route_already_present = 0;
256 /* *INDENT-OFF* */
257 pool_foreach (default_route, rm->default_route_pool,
258 ({
259 if (default_route->sw_if_index != sw_if_index)
260 ;
261 else if (0 != memcmp (&default_route->router_address,
Juraj Sloboda52574522018-05-03 10:03:50 +0200262 r->router_address, 16))
Juraj Slobodac0374232018-02-01 15:18:49 +0100263 ;
264 else
265 {
266 route_already_present = 1;
267 goto default_route_pool_foreach_out;
268 }
269 }));
270 /* *INDENT-ON* */
271 default_route_pool_foreach_out:
272
273 if (!route_already_present)
274 {
275 if (router_lifetime_in_sec != 0)
Juraj Sloboda52574522018-05-03 10:03:50 +0200276 add_default_route (vm, sw_if_index, (void *) r->router_address,
Juraj Slobodac0374232018-02-01 15:18:49 +0100277 current_time + router_lifetime_in_sec);
278 }
279 else
280 {
281 if (router_lifetime_in_sec != 0)
282 default_route->due_time = current_time + router_lifetime_in_sec;
283 else
284 remove_default_route (vm, default_route);
285 }
286 }
287
288 if (get_interface_mac_address (sw_if_index, mac) != 0)
289 {
290 clib_warning ("Error getting MAC address");
Juraj Sloboda52574522018-05-03 10:03:50 +0200291 return clib_error_return (0, "Error getting MAC address");
Juraj Slobodac0374232018-02-01 15:18:49 +0100292 }
293
294 if (!if_config->enabled)
Juraj Sloboda52574522018-05-03 10:03:50 +0200295 return 0;
Juraj Slobodac0374232018-02-01 15:18:49 +0100296
Juraj Sloboda52574522018-05-03 10:03:50 +0200297 n_prefixes = vec_len (r->prefixes);
Juraj Slobodac0374232018-02-01 15:18:49 +0100298 for (i = 0; i < n_prefixes; i++)
299 {
300 ip6_address_t *dst_address;
301 u8 prefix_length;
302 u32 valid_time;
303 u32 preferred_time;
304 f64 due_time;
305
Juraj Sloboda52574522018-05-03 10:03:50 +0200306 prefix = &r->prefixes[i];
Juraj Slobodac0374232018-02-01 15:18:49 +0100307
308 if (!(prefix->flags & PREFIX_FLAG_A))
309 continue;
310
Juraj Sloboda52574522018-05-03 10:03:50 +0200311 dst_address = &prefix->dst_address;
Juraj Slobodac0374232018-02-01 15:18:49 +0100312 prefix_length = prefix->dst_address_length;
313
314 if (ip6_address_is_link_local_unicast (dst_address))
315 continue;
316
Juraj Sloboda52574522018-05-03 10:03:50 +0200317 valid_time = prefix->valid_time;
318 preferred_time = prefix->preferred_time;
Juraj Slobodac0374232018-02-01 15:18:49 +0100319
320 if (preferred_time > valid_time)
321 continue;
322
323 if (prefix_length != 64)
324 continue;
325
326 u8 address_already_present = 0;
327 /* *INDENT-OFF* */
328 pool_foreach (slaac_address, rm->slaac_address_pool,
329 ({
330 if (slaac_address->sw_if_index != sw_if_index)
331 ;
332 else if (slaac_address->address_length != prefix_length)
333 ;
334 else if (!ip6_prefixes_equal (&slaac_address->address, dst_address,
335 prefix_length))
336 ;
337 else
338 {
339 address_already_present = 1;
340 goto slaac_address_pool_foreach_out;
341 }
342 }));
343 /* *INDENT-ON* */
344 slaac_address_pool_foreach_out:
345
346 if (address_already_present)
347 {
348 f64 remaining_life_time = slaac_address->due_time - current_time;
349 if (valid_time > 2 * 60 * 60 || valid_time > remaining_life_time)
350 slaac_address->due_time = current_time + valid_time;
351 else if (remaining_life_time > 2 * 60 * 60)
352 slaac_address->due_time = current_time + 2 * 60 * 60;
353 continue;
354 }
355
356 if (valid_time == 0)
357 continue;
358
359 due_time = current_time + valid_time;
360
361 ip6_address_t addr;
362 addr.as_u64[0] = dst_address->as_u64[0];
363 /* Invert the "u" bit */
364 addr.as_u8[8] = mac[0] ^ (1 << 1);
365 addr.as_u8[9] = mac[1];
366 addr.as_u8[10] = mac[2];
367 addr.as_u8[11] = 0xFF;
368 addr.as_u8[12] = 0xFE;
369 addr.as_u8[13] = mac[3];
370 addr.as_u8[14] = mac[4];
371 addr.as_u8[15] = mac[5];
372
373 add_slaac_address (vm, sw_if_index, prefix_length, &addr, due_time);
374 }
375
376 interrupt_process ();
Juraj Sloboda52574522018-05-03 10:03:50 +0200377
378 return error;
Juraj Slobodac0374232018-02-01 15:18:49 +0100379}
380
Juraj Sloboda52574522018-05-03 10:03:50 +0200381VNET_IP6_NEIGHBOR_RA_FUNCTION (ip6_ra_report_handler);
382
Juraj Slobodac0374232018-02-01 15:18:49 +0100383static uword
384rd_cp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
385{
Juraj Slobodac0374232018-02-01 15:18:49 +0100386 uword *event_data = 0;
387 rd_cp_main_t *rm = &rd_cp_main;
388 slaac_address_t *slaac_address;
389 default_route_t *default_route;
390 f64 sleep_time = 1e9;
Juraj Slobodac0374232018-02-01 15:18:49 +0100391 f64 current_time;
392 f64 due_time;
393
394 while (1)
395 {
Juraj Sloboda52574522018-05-03 10:03:50 +0200396 vlib_process_wait_for_event_or_clock (vm, sleep_time);
397 vlib_process_get_events (vm, &event_data);
Juraj Slobodac0374232018-02-01 15:18:49 +0100398
399 vec_reset_length (event_data);
400
401 current_time = vlib_time_now (vm);
402 do
403 {
404 due_time = current_time + 1e9;
405 /* *INDENT-OFF* */
406 pool_foreach (slaac_address, rm->slaac_address_pool,
407 ({
408 if (slaac_address->due_time > current_time)
409 {
410 if (slaac_address->due_time < due_time)
411 due_time = slaac_address->due_time;
412 }
413 else
414 {
415 remove_slaac_address (vm, slaac_address);
416 /* make sure ip6 stays enabled */
417 ip6_enable (slaac_address->sw_if_index);
418 }
419 }));
420 pool_foreach (default_route, rm->default_route_pool,
421 ({
422 if (default_route->due_time > current_time)
423 {
424 if (default_route->due_time < due_time)
425 due_time = default_route->due_time;
426 }
427 else
428 remove_default_route (vm, default_route);
429 }));
430 /* *INDENT-ON* */
431 current_time = vlib_time_now (vm);
432 }
433 while (due_time < current_time);
434
435 sleep_time = due_time - current_time;
436 }
437
438 return 0;
439}
440
441/* *INDENT-OFF* */
442VLIB_REGISTER_NODE (rd_cp_process_node) = {
443 .function = rd_cp_process,
444 .type = VLIB_NODE_TYPE_PROCESS,
445 .name = "rd-cp-process",
446};
447/* *INDENT-ON* */
448
449static void
450interrupt_process (void)
451{
452 rd_cp_main_t *rm = &rd_cp_main;
453 vlib_main_t *vm = rm->vlib_main;
454
455 vlib_process_signal_event (vm, rd_cp_process_node.index,
456 RD_CP_EVENT_INTERRUPT, 0);
457}
458
459static int
Juraj Slobodac0374232018-02-01 15:18:49 +0100460set_address_autoconfig (u32 sw_if_index, u8 enable, u8 install_default_routes)
461{
462 rd_cp_main_t *rm = &rd_cp_main;
463 vlib_main_t *vm = rm->vlib_main;
464 vnet_main_t *vnm = rm->vnet_main;
465 interface_config_t *if_config;
466 interface_config_t empty_config = { 0, 0 };
467 slaac_address_t *slaac_address;
468 default_route_t *default_route;
469
470 if (!enable)
471 install_default_routes = 0;
472
Juraj Slobodac0374232018-02-01 15:18:49 +0100473 if (!vnet_sw_interface_is_api_valid (vnm, sw_if_index))
474 {
475 clib_warning ("Invalid sw_if_index");
476 return 1;
477 }
478
479 if (!rm->enabled)
480 {
Juraj Slobodac0374232018-02-01 15:18:49 +0100481 /* process kickoff */
482 interrupt_process ();
Juraj Slobodac0374232018-02-01 15:18:49 +0100483 rm->enabled = 1;
484 }
485
486 vec_validate_init_empty (rm->config_by_sw_if_index, sw_if_index,
487 empty_config);
488 if_config = &rm->config_by_sw_if_index[sw_if_index];
489
490 if (!if_config->enabled && enable)
491 ip6_enable (sw_if_index);
492
493 if ((!if_config->enabled && enable)
494 || (!if_config->install_default_routes && install_default_routes))
495 router_solicitation_start_stop (sw_if_index, 1);
496 else if (if_config->enabled && !enable)
497 router_solicitation_start_stop (sw_if_index, 0);
498
499 if (if_config->enabled && !enable)
500 {
501 /* *INDENT-OFF* */
502 pool_foreach (slaac_address, rm->slaac_address_pool,
503 ({
504 remove_slaac_address (vm, slaac_address);
505 }));
506 /* *INDENT-ON* */
507 }
508 if (if_config->install_default_routes && !install_default_routes)
509 {
510 /* *INDENT-OFF* */
511 pool_foreach (default_route, rm->default_route_pool,
512 ({
513 remove_default_route (vm, default_route);
514 }));
515 /* *INDENT-ON* */
516 }
517
518 if_config->enabled = enable;
519 if_config->install_default_routes = install_default_routes;
520
521 return 0;
522}
523
524static clib_error_t *
525ip6_nd_address_autoconfig (vlib_main_t * vm,
526 unformat_input_t * input, vlib_cli_command_t * cmd)
527{
528 rd_cp_main_t *rm = &rd_cp_main;
529 vnet_main_t *vnm = rm->vnet_main;
530 clib_error_t *error = 0;
531 u32 sw_if_index = ~0;
532 u8 enable = 1;
533 u8 default_route = 0;
534
535 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
536 {
537 if (unformat
538 (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
539 ;
540 if (unformat (input, "default-route"))
541 default_route = 1;
542 if (unformat (input, "disable"))
543 enable = 0;
544 else
545 break;
546 }
547
548 if (sw_if_index != ~0)
549 {
550 if (set_address_autoconfig (sw_if_index, enable, default_route) != 0)
551 error = clib_error_return (0, "Invalid sw_if_index");
552 }
553 else
554 error = clib_error_return (0, "Missing sw_if_index");
555
556 return error;
557}
558
559/*?
560 * This command is used to enable ND address autoconfiguration
561 * on particular interface including setting up default routes.
562 *
563 * @cliexpar
564 * @parblock
565 * Example of how to enable ND address autoconfiguration:
566 * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0}
567 * Example of how to enable ND address autoconfiguration
568 * with setting up default routes:
569 * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0 default-route}
570 * Example of how to disable ND address autoconfiguration:
571 * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0 disable}
572 * @endparblock
573?*/
574/* *INDENT-OFF* */
575VLIB_CLI_COMMAND (ip6_nd_address_autoconfig_command, static) = {
576 .path = "ip6 nd address autoconfig",
577 .short_help = "ip6 nd address autoconfig <interface> [default-route|disable]",
578 .function = ip6_nd_address_autoconfig,
579};
580/* *INDENT-ON* */
581
582static void
583vl_api_ip6_nd_address_autoconfig_t_handler (vl_api_ip6_nd_address_autoconfig_t
584 * mp)
585{
586 vl_api_ip6_nd_address_autoconfig_reply_t *rmp;
587 u32 sw_if_index;
588 int rv = 0;
589
590 VALIDATE_SW_IF_INDEX (mp);
591
592 sw_if_index = ntohl (mp->sw_if_index);
593
594 rv =
595 set_address_autoconfig (sw_if_index, mp->enable,
596 mp->install_default_routes);
597
598 BAD_SW_IF_INDEX_LABEL;
599
600 REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
601}
602
603#define vl_msg_name_crc_list
604#include <vnet/ip/rd_cp.api.h>
605#undef vl_msg_name_crc_list
606
607static void
608setup_message_id_table (api_main_t * am)
609{
610#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
611 foreach_vl_msg_name_crc_rd_cp;
612#undef _
613}
614
615static clib_error_t *
616rd_cp_init (vlib_main_t * vm)
617{
618 rd_cp_main_t *rm = &rd_cp_main;
619 api_main_t *am = &api_main;
620
621 rm->vlib_main = vm;
622 rm->vnet_main = vnet_get_main ();
623 rm->api_main = am;
624 rm->node_index = rd_cp_process_node.index;
625
626#define _(N,n) \
627 vl_msg_api_set_handlers(VL_API_##N, #n, \
628 vl_api_##n##_t_handler, \
629 vl_noop_handler, \
630 vl_api_##n##_t_endian, \
631 vl_api_##n##_t_print, \
632 sizeof(vl_api_##n##_t), 0/* do NOT trace! */);
633 foreach_rd_cp_msg;
634#undef _
635
Juraj Slobodac0374232018-02-01 15:18:49 +0100636 /*
637 * Set up the (msg_name, crc, message-id) table
638 */
639 setup_message_id_table (am);
640
641 return 0;
642}
643
644VLIB_INIT_FUNCTION (rd_cp_init);
645
646/*
647 * fd.io coding-style-patch-verification: ON
648 *
649 * Local Variables:
650 * eval: (c-set-style "gnu")
651 * End:
652 */