18 #define foreach_rd_cp_msg \ 19 _(IP6_ND_ADDRESS_AUTOCONFIG, ip6_nd_address_autoconfig) 21 #define foreach_client_rd_cp_msg \ 22 _(IP6_RA_EVENT, ip6_ra_event) \ 23 _(IP6ND_SEND_ROUTER_SOLICITATION_REPLY, ip6nd_send_router_solicitation_reply) \ 24 _(WANT_IP6_RA_EVENTS_REPLY, want_ip6_ra_events_reply) \ 25 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, sw_interface_add_del_address_reply) \ 26 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \ 27 _(SW_INTERFACE_GET_MAC_ADDRESS_REPLY, sw_interface_get_mac_address_reply) \ 28 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, sw_interface_ip6_enable_disable_reply) 64 void (**msg_handlers) (
void *);
89 #define vl_api_ip6_nd_address_autoconfig_t_print vl_noop_handler 100 (
"BUG: re-registering 'vl_api_%s_t_handler'." 101 "Handler was %llx, replaced by %llx",
113 memset (c, 0,
sizeof (*c));
136 u16 id = ntohs (*((
u16 *) msgp));
137 u8 *(*handler) (
void *);
142 (*handler) ((
void *) msgp);
146 if (
id != VL_API_MEMCLNT_KEEPALIVE)
200 memset (mp, 0,
sizeof (*mp));
201 mp->_vl_msg_id = htons (VL_API_IP6ND_SEND_ROUTER_SOLICITATION);
207 mp->
mrt = htonl (120);
219 (vl_api_ip6nd_send_router_solicitation_reply_t * mp)
235 memset (mp, 0,
sizeof (*mp));
236 mp->_vl_msg_id = htons (VL_API_WANT_IP6_RA_EVENTS);
239 mp->
pid = htonl (getpid ());
274 slaac_address->
address = *address;
278 memset (mp, 0,
sizeof (*mp));
279 mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS);
294 (vl_api_sw_interface_add_del_address_reply_t * mp)
318 memset (mp, 0,
sizeof (*mp));
319 mp->_vl_msg_id = htons (VL_API_IP_ADD_DEL_ROUTE);
348 memset (mp, 0,
sizeof (*mp));
349 mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS);
371 memset (mp, 0,
sizeof (*mp));
372 mp->_vl_msg_id = htons (VL_API_IP_ADD_DEL_ROUTE);
395 memset (mp, 0,
sizeof (*mp));
396 mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_GET_MAC_ADDRESS);
429 memset (mp, 0,
sizeof (*mp));
430 mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE);
442 (vl_api_sw_interface_ip6_enable_disable_reply_t * mp)
459 return prefix1->
as_u64[1] >> (128 - len) ==
460 prefix2->
as_u64[1] >> (128 - len);
462 return prefix1->
as_u64[0] >> (64 - len) == prefix2->
as_u64[0] >> (64 - len);
465 #define PREFIX_FLAG_A (1 << 6) 466 #define PREFIX_FLAG_L (1 << 7) 477 u16 router_lifetime_in_sec;
493 u8 route_already_present = 0;
497 if (default_route->sw_if_index != sw_if_index)
499 else if (0 != memcmp (&default_route->router_address,
500 mp->router_address, 16))
504 route_already_present = 1;
505 goto default_route_pool_foreach_out;
509 default_route_pool_foreach_out:
511 if (!route_already_present)
513 if (router_lifetime_in_sec != 0)
515 current_time + router_lifetime_in_sec);
519 if (router_lifetime_in_sec != 0)
520 default_route->
due_time = current_time + router_lifetime_in_sec;
532 if (!if_config->enabled)
535 n_prefixes = ntohl (mp->n_prefixes);
536 for (
i = 0;
i < n_prefixes;
i++)
544 prefix = &mp->prefixes[
i];
550 prefix_length = prefix->dst_address_length;
555 valid_time = ntohl (prefix->valid_time);
556 preferred_time = ntohl (prefix->preferred_time);
558 if (preferred_time > valid_time)
561 if (prefix_length != 64)
564 u8 address_already_present = 0;
568 if (slaac_address->sw_if_index != sw_if_index)
570 else if (slaac_address->address_length != prefix_length)
572 else if (!ip6_prefixes_equal (&slaac_address->address, dst_address,
577 address_already_present = 1;
578 goto slaac_address_pool_foreach_out;
582 slaac_address_pool_foreach_out:
584 if (address_already_present)
586 f64 remaining_life_time = slaac_address->due_time - current_time;
587 if (valid_time > 2 * 60 * 60 || valid_time > remaining_life_time)
588 slaac_address->due_time = current_time + valid_time;
589 else if (remaining_life_time > 2 * 60 * 60)
590 slaac_address->due_time = current_time + 2 * 60 * 60;
597 due_time = current_time + valid_time;
600 addr.
as_u64[0] = dst_address->as_u64[0];
602 addr.
as_u8[8] = mac[0] ^ (1 << 1);
603 addr.
as_u8[9] = mac[1];
604 addr.
as_u8[10] = mac[2];
605 addr.
as_u8[11] = 0xFF;
606 addr.
as_u8[12] = 0xFE;
607 addr.
as_u8[13] = mac[3];
608 addr.
as_u8[14] = mac[4];
609 addr.
as_u8[15] = mac[5];
621 uword *event_data = 0;
625 f64 sleep_time = 1e9;
626 const f64 micro_sleep_time = 1e-5;
650 due_time = current_time + 1e9;
654 if (slaac_address->due_time > current_time)
656 if (slaac_address->due_time < due_time)
657 due_time = slaac_address->due_time;
661 remove_slaac_address (vm, slaac_address);
663 ip6_enable (slaac_address->sw_if_index);
668 if (default_route->due_time > current_time)
670 if (default_route->due_time < due_time)
671 due_time = default_route->due_time;
679 while (due_time < current_time);
681 sleep_time = due_time - current_time;
691 .name =
"rd-cp-process",
714 pthread_mutex_lock (&svm->
mutex);
717 pthread_mutex_unlock (&svm->
mutex);
740 install_default_routes = 0;
762 if (!if_config->
enabled && enable)
765 if ((!if_config->
enabled && enable)
768 else if (if_config->
enabled && !enable)
771 if (if_config->
enabled && !enable)
776 remove_slaac_address (vm, slaac_address);
785 remove_default_route (vm, default_route);
803 u32 sw_if_index = ~0;
805 u8 default_route = 0;
812 if (
unformat (input,
"default-route"))
820 if (sw_if_index != ~0)
848 .path =
"ip6 nd address autoconfig",
849 .short_help =
"ip6 nd address autoconfig <interface> [default-route|disable]",
858 vl_api_ip6_nd_address_autoconfig_reply_t *rmp;
875 #define vl_msg_name_crc_list 876 #include <vnet/ip/rd_cp.api.h> 877 #undef vl_msg_name_crc_list 882 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); 883 foreach_vl_msg_name_crc_rd_cp;
899 vl_msg_api_set_handlers(VL_API_##N, #n, \ 900 vl_api_##n##_t_handler, \ 902 vl_api_##n##_t_endian, \ 903 vl_api_##n##_t_print, \ 904 sizeof(vl_api_##n##_t), 0); 909 set_handler(VL_API_##N, #n, vl_api_##n##_t_handler); #define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static void vl_api_sw_interface_ip6_enable_disable_reply_t_handler(vl_api_sw_interface_ip6_enable_disable_reply_t *mp)
static u8 ip6_prefixes_equal(ip6_address_t *prefix1, ip6_address_t *prefix2, u8 len)
static int add_slaac_address(vlib_main_t *vm, u32 sw_if_index, u8 address_length, ip6_address_t *address, f64 due_time)
Register for ip6 router advertisement events.
u32 vl_api_memclnt_create_internal(char *name, svm_queue_t *q)
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
static void vl_api_ip6_ra_event_t_handler(vl_api_ip6_ra_event_t *mp)
Get interface's MAC address.
vnet_main_t * vnet_get_main(void)
u16 router_lifetime_in_sec
slaac_address_t * slaac_address_pool
static int router_solicitation_start_stop(u32 sw_if_index, u8 start)
static f64 vlib_time_now(vlib_main_t *vm)
int svm_queue_sub2(svm_queue_t *q, u8 *elem)
Message configuration definition.
static void vl_api_ip6_nd_address_autoconfig_t_handler(vl_api_ip6_nd_address_autoconfig_t *mp)
#define foreach_rd_cp_msg
u8 install_default_routes
static void vl_api_ip_add_del_route_reply_t_handler(vl_api_ip_add_del_route_reply_t *mp)
static int add_default_route(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *next_hop_address, f64 due_time)
unformat_function_t unformat_vnet_sw_interface
ip6_address_t router_address
static u32 ip6_enable(u32 sw_if_index)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
void * vl_msg_api_alloc(int nbytes)
static void msg_api_config(vl_msg_api_msg_config_t *c)
static clib_error_t * rd_cp_init(vlib_main_t *vm)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void setup_message_id_table(api_main_t *am)
svm_queue_t * svm_queue_init(int nels, int elsize, int consumer_pid, int signal_when_queue_non_empty)
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
#define static_always_inline
svm_queue_t * vl_input_queue
static void vl_api_want_ip6_ra_events_reply_t_handler(vl_api_want_ip6_ra_events_reply_t *mp)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
static int create_api_loopback(void)
#define VLIB_INIT_FUNCTION(x)
Start / stop sending router solicitation.
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
#define clib_error_return(e, args...)
svm_region_t * vlib_rp
Current binary api segment descriptor.
Enable/disable IPv6 ND address autoconfiguration and setting up default routes.
IPv6 interface enable / disable request.
static_always_inline void check_queue(void)
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
static_always_inline void send_msg(void *msg)
struct rd_cp_main_t::@222 api_reply
static uword rd_cp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
int message_bounce
do not free message after processing
#define pool_put(P, E)
Free an object E in pool P.
Set or delete one or all ip addresses on a specified interface.
API main structure, used by both vpp and binary API clients.
u8 install_default_routes
#define BAD_SW_IF_INDEX_LABEL
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
#define VLIB_REGISTER_NODE(x,...)
#define clib_warning(format, args...)
#define clib_memcpy(a, b, c)
static void vl_api_sw_interface_get_mac_address_reply_t_handler(vl_api_sw_interface_get_mac_address_reply_t *mp)
vlib_node_registration_t rd_cp_process_node
(constructor) VLIB_REGISTER_NODE (rd_cp_process_node)
svm_queue_t * vl_input_queue
#define VLIB_CLI_COMMAND(x,...)
int replay
is this message to be replayed?
interface_config_t * config_by_sw_if_index
Tell client about a router advertisement event.
Reply for get interface's MAC address request.
default_route_t * default_route_pool
static_always_inline int wait_for_reply(void)
static int remove_default_route(vlib_main_t *vm, default_route_t *default_route)
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
#define foreach_client_rd_cp_msg
static uword vnet_sw_interface_is_api_valid(vnet_main_t *vnm, u32 sw_if_index)
static_always_inline int send_msg_and_wait_for_reply(void *msg)
Struct representing RA prefix info.
static int remove_slaac_address(vlib_main_t *vm, slaac_address_t *slaac_address)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static int ip6_ra_events_enable_disable(int enable)
static void interrupt_process(void)
static void vl_api_sw_interface_add_del_address_reply_t_handler(vl_api_sw_interface_add_del_address_reply_t *mp)
struct _svm_queue svm_queue_t
static u32 get_interface_mac_address(u32 sw_if_index, u8 mac[])
static void vl_api_ip6nd_send_router_solicitation_reply_t_handler(vl_api_ip6nd_send_router_solicitation_reply_t *mp)
static int set_address_autoconfig(u32 sw_if_index, u8 enable, u8 install_default_routes)
int is_mp_safe
worker thread barrier required?
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
static clib_error_t * ip6_nd_address_autoconfig(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
char * name
the message name
static void set_handler(int id, char *name, void *handler)
void * handler
the message handler
#define VALIDATE_SW_IF_INDEX(mp)
void(** msg_handlers)(void *)