X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fdhcp%2Fdhcp6_pd_client_cp.c;h=1c0b286bd307f2e00796baa3a3f89a0935220323;hb=d1586962a5f8f14fb81c930174d12d0453adaab8;hp=6f151430e5844c99bf5a9119c7d641ba9f79b0f2;hpb=02bfd641b69aab83397e217b9ca4e35a6aab05c8;p=vpp.git diff --git a/src/plugins/dhcp/dhcp6_pd_client_cp.c b/src/plugins/dhcp/dhcp6_pd_client_cp.c index 6f151430e58..1c0b286bd30 100644 --- a/src/plugins/dhcp/dhcp6_pd_client_cp.c +++ b/src/plugins/dhcp/dhcp6_pd_client_cp.c @@ -19,9 +19,12 @@ #include #include #include +#include +#include #include #include #include +#include typedef struct { @@ -67,6 +70,8 @@ typedef struct { prefix_info_t *prefix_pool; const u8 **prefix_group_name_by_index; + /* vector of active prefix pool indicies, prep-H for pool_foreach(..) */ + u32 *indices; } ip6_prefix_main_t; static ip6_prefix_main_t ip6_prefix_main; @@ -241,17 +246,6 @@ send_client_message_start_stop (u32 sw_if_index, u32 server_index, static void interrupt_process (void); -static u32 -ip6_enable (u32 sw_if_index) -{ - dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main; - clib_error_t *rv; - - rv = enable_ip6_interface (rm->vlib_main, sw_if_index); - - return rv != 0; -} - static u8 ip6_prefixes_equal (ip6_address_t * prefix1, ip6_address_t * prefix2, u8 len) { @@ -285,6 +279,7 @@ dhcp6_pd_reply_event_handler (vl_api_dhcp6_pd_reply_event_t * mp) f64 current_time; clib_error_t *error = 0; u32 i; + prefix_info_t *prefix_info; current_time = vlib_time_now (vm); @@ -371,13 +366,26 @@ dhcp6_pd_reply_event_handler (vl_api_dhcp6_pd_reply_event_t * mp) send_client_message_start_stop (sw_if_index, server_index, mp->msg_type, 0, 0); + vec_reset_length (pm->indices); + /* + * We're going to loop through the pool multiple times, + * so collect active indices. + */ + /* *INDENT-OFF* */ + pool_foreach (prefix_info, pm->prefix_pool, + ({ + vec_add1 (pm->indices, prefix_info - pm->prefix_pool); + })); + /* *INDENT-ON* */ + for (i = 0; i < n_prefixes; i++) { - prefix_info_t *prefix_info = 0; u8 prefix_length; u32 valid_time; u32 preferred_time; + int j; + prefix_info = 0; api_prefix = &mp->prefixes[i]; prefix = (ip6_address_t *) api_prefix->prefix.address; @@ -394,28 +402,40 @@ dhcp6_pd_reply_event_handler (vl_api_dhcp6_pd_reply_event_t * mp) continue; u8 address_prefix_present = 0; - /* *INDENT-OFF* */ - pool_foreach (prefix_info, pm->prefix_pool, - ({ - if (is_dhcpv6_pd_prefix (prefix_info) && - prefix_info->opaque_data == sw_if_index && - prefix_info->prefix_length == prefix_length && - ip6_prefixes_equal (&prefix_info->prefix, prefix, prefix_length)) - { - address_prefix_present = 1; - goto prefix_pool_foreach_out; - } - })); - /* *INDENT-ON* */ - prefix_pool_foreach_out: + + /* Look for a matching prefix_info */ + for (j = 0; j < vec_len (pm->indices); j++) + { + prefix_info = pool_elt_at_index (pm->prefix_pool, pm->indices[j]); + + if (is_dhcpv6_pd_prefix (prefix_info) && + prefix_info->opaque_data == sw_if_index && + prefix_info->prefix_length == prefix_length && + ip6_prefixes_equal (&prefix_info->prefix, prefix, + prefix_length)) + { + address_prefix_present = 1; + break; + } + } if (address_prefix_present) { + /* Found the (primary) prefix, update prefix timers */ prefix_info->preferred_lt = preferred_time; prefix_info->valid_lt = valid_time; prefix_info->due_time = current_time + valid_time; if (prefix_info->due_time > rm->max_valid_due_time) rm->max_valid_due_time = prefix_info->due_time; + + /* + * Tell the RA code to update any secondary per-interface + * timers that it might be hoarding. + */ + ip6_ra_update_secondary_radv_info + (prefix, prefix_length, + prefix_info->opaque_data /* sw_if_index */ , + valid_time, preferred_time); continue; } @@ -423,6 +443,7 @@ dhcp6_pd_reply_event_handler (vl_api_dhcp6_pd_reply_event_t * mp) continue; pool_get (pm->prefix_pool, prefix_info); + vec_add1 (pm->indices, prefix_info - pm->prefix_pool); prefix_info->prefix_group_index = client_state->prefix_group_index; set_is_dhcpv6_pd_prefix (prefix_info, 1); prefix_info->opaque_data = sw_if_index; @@ -684,7 +705,16 @@ cp_ip6_address_add_del_now (ip6_address_info_t * address_info, u8 is_add) clib_warning ("Failed adding IPv6 address: %U", format_clib_error, error); else - address_info->configured_in_data_plane = 1; + { + if (CLIB_DEBUG > 0) + clib_warning ("Add address %U on %U", + format_ip6_address_and_length, + &addr, address_info->prefix_length, + format_vnet_sw_if_index_name, + vnet_get_main (), address_info->sw_if_index); + + address_info->configured_in_data_plane = 1; + } } else { @@ -699,7 +729,17 @@ cp_ip6_address_add_del_now (ip6_address_info_t * address_info, u8 is_add) clib_warning ("Failed adding IPv6 address: %U", format_clib_error, error); else - address_info->configured_in_data_plane = 1; + { + if (CLIB_DEBUG > 0) + clib_warning ("Add address %U on %U", + format_ip6_address_and_length, + &addr, address_info->prefix_length, + format_vnet_sw_if_index_name, + vnet_get_main (), + address_info->sw_if_index); + + address_info->configured_in_data_plane = 1; + } } } } @@ -758,6 +798,53 @@ cp_ip6_address_find_new_active_prefix (u32 prefix_group_index, return ~0; } +static void +cp_ip6_advertise_prefix (prefix_info_t * prefix_info, + ip6_address_info_t * address_info, int enable) +{ + vlib_main_t *vm = vlib_get_main (); + ip6_main_t *im = &ip6_main; + u32 prefix_index; + ip6_address_t addr; + int rv; + + prefix_index = + active_prefix_index_by_prefix_group_index_get + (address_info->prefix_group_index); + + if (cp_ip6_construct_address (address_info, prefix_index, &addr) != 0) + { + clib_warning ("address construction FAIL"); + return; + } + + /* The RA code assumes that host bits are zero, so clear them */ + addr.as_u64[0] &= im->fib_masks[address_info->prefix_length].as_u64[0]; + addr.as_u64[1] &= im->fib_masks[address_info->prefix_length].as_u64[1]; + + rv = ip6_ra_prefix (vm, address_info->sw_if_index, + &addr, address_info->prefix_length, + 0 /* use_default */ , + prefix_info->valid_lt, + prefix_info->preferred_lt, 0 /* no_advertise */ , + 0 /* off_link */ , + 0 /* no_autoconfig */ , + 0 /* no_onlink */ , + enable == 0 /* is_no */ ); + if (rv != 0) + { + clib_warning ("ip6_neighbor_ra_prefix returned %d", rv); + return; + } + + if (CLIB_DEBUG > 0) + clib_warning ("Advertise prefix %U valid lt %u preferred lt %u", + format_ip6_address_and_length, &addr, + address_info->prefix_length, prefix_info->valid_lt, + prefix_info->preferred_lt); +} + + static void cp_ip6_address_prefix_add_del_handler (u32 prefix_index, u8 is_add) { @@ -783,7 +870,13 @@ cp_ip6_address_prefix_add_del_handler (u32 prefix_index, u8 is_add) { address_info = &apm->addresses[i]; if (address_info->prefix_group_index == prefix_group_index) - cp_ip6_address_add_del_now (address_info, 1 /* add */ ); + { + /* Add the prefix to the interface */ + cp_ip6_address_add_del_now (address_info, 1 /* add */ ); + /* And advertise the prefix on the interface */ + cp_ip6_advertise_prefix (prefix, address_info, + 1 /* enable */ ); + } } } } @@ -796,7 +889,11 @@ cp_ip6_address_prefix_add_del_handler (u32 prefix_index, u8 is_add) { address_info = &apm->addresses[i]; if (address_info->prefix_group_index == prefix_group_index) - cp_ip6_address_add_del_now (address_info, 0 /* del */ ); + { + cp_ip6_advertise_prefix (prefix, address_info, + 0 /* enable */ ); + cp_ip6_address_add_del_now (address_info, 0 /* del */ ); + } } active_prefix_index_by_prefix_group_index_set (prefix_group_index, ~0); @@ -811,7 +908,11 @@ cp_ip6_address_prefix_add_del_handler (u32 prefix_index, u8 is_add) { address_info = &apm->addresses[i]; if (address_info->prefix_group_index == prefix_group_index) - cp_ip6_address_add_del_now (address_info, 1 /* add */ ); + { + cp_ip6_address_add_del_now (address_info, 1 /* add */ ); + cp_ip6_advertise_prefix (prefix, address_info, + 1 /* enable */ ); + } } } } @@ -1181,7 +1282,7 @@ dhcp6_pd_client_enable_disable (u32 sw_if_index, dhcp6_clients_enable_disable (1); } - ip6_enable (sw_if_index); + ip6_link_enable (sw_if_index); send_client_message_start_stop (sw_if_index, ~0, DHCPV6_MSG_SOLICIT, 0, 1); } @@ -1300,6 +1401,8 @@ VLIB_CLI_COMMAND (dhcp6_pd_client_enable_disable_command, static) = { }; /* *INDENT-ON* */ +#include + static clib_error_t * dhcp_pd_client_cp_init (vlib_main_t * vm) { @@ -1307,7 +1410,7 @@ dhcp_pd_client_cp_init (vlib_main_t * vm) rm->vlib_main = vm; rm->vnet_main = vnet_get_main (); - rm->api_main = &api_main; + rm->api_main = vlibapi_get_main (); rm->node_index = dhcp6_pd_client_cp_process_node.index; return (NULL);