diff options
Diffstat (limited to 'src/vnet/ip6-nd/ip6_ra.c')
-rw-r--r-- | src/vnet/ip6-nd/ip6_ra.c | 233 |
1 files changed, 73 insertions, 160 deletions
diff --git a/src/vnet/ip6-nd/ip6_ra.c b/src/vnet/ip6-nd/ip6_ra.c index 895f3092820..ffc02e813e2 100644 --- a/src/vnet/ip6-nd/ip6_ra.c +++ b/src/vnet/ip6-nd/ip6_ra.c @@ -30,7 +30,6 @@ * The files contains the API and CLI code for managing IPv6 RAs */ -/* *INDENT-OFF* */ /* Router solicitation packet format for ethernet. */ typedef CLIB_PACKED (struct { @@ -51,7 +50,6 @@ typedef CLIB_PACKED (struct icmp6_neighbor_discovery_prefix_information_option_t prefix[0]; }) icmp6_router_advertisement_packet_t; -/* *INDENT-ON* */ #define DEF_MAX_RADV_INTERVAL 200 #define DEF_MIN_RADV_INTERVAL .75 * DEF_MAX_RADV_INTERVAL @@ -65,95 +63,6 @@ typedef CLIB_PACKED (struct #define MAX_DELAY_BETWEEN_RAS 1800 /* seconds */ #define MAX_RA_DELAY_TIME .5 /* seconds */ -/* advertised prefix option */ -typedef struct -{ - /* basic advertised information */ - ip6_address_t prefix; - u8 prefix_len; - int adv_on_link_flag; - int adv_autonomous_flag; - u32 adv_valid_lifetime_in_secs; - u32 adv_pref_lifetime_in_secs; - - /* advertised values are computed from these times if decrementing */ - f64 valid_lifetime_expires; - f64 pref_lifetime_expires; - - /* local information */ - int enabled; - int deprecated_prefix_flag; - int decrement_lifetime_flag; - -#define MIN_ADV_VALID_LIFETIME 7203 /* seconds */ -#define DEF_ADV_VALID_LIFETIME 2592000 -#define DEF_ADV_PREF_LIFETIME 604800 - - /* extensions are added here, mobile, DNS etc.. */ -} ip6_radv_prefix_t; - -typedef struct ip6_ra_t_ -{ - /* advertised config information, zero means unspecified */ - u8 curr_hop_limit; - int adv_managed_flag; - int adv_other_flag; - u16 adv_router_lifetime_in_sec; - u32 adv_neighbor_reachable_time_in_msec; - u32 adv_time_in_msec_between_retransmitted_neighbor_solicitations; - - /* mtu option */ - u32 adv_link_mtu; - - /* local information */ - u32 sw_if_index; - int send_radv; /* radv on/off on this interface - set by config */ - int cease_radv; /* we are ceasing to send - set byf config */ - int send_unicast; - int adv_link_layer_address; - int prefix_option; - int failed_device_check; - int ref_count; - - /* prefix option */ - ip6_radv_prefix_t *adv_prefixes_pool; - - /* Hash table mapping address to index in interface advertised prefix pool. */ - mhash_t address_to_prefix_index; - - f64 max_radv_interval; - f64 min_radv_interval; - f64 min_delay_between_radv; - f64 max_delay_between_radv; - f64 max_rtr_default_lifetime; - - f64 last_radv_time; - f64 last_multicast_time; - f64 next_multicast_time; - - - u32 initial_adverts_count; - f64 initial_adverts_interval; - u32 initial_adverts_sent; - - /* stats */ - u32 n_advertisements_sent; - u32 n_solicitations_rcvd; - u32 n_solicitations_dropped; - - /* router solicitations sending state */ - u8 keep_sending_rs; /* when true then next fields are valid */ - icmp6_send_router_solicitation_params_t params; - f64 sleep_interval; - f64 due_time; - u32 n_left; - f64 start_time; - vlib_buffer_t *buffer; - - u32 seed; - -} ip6_ra_t; - static ip6_link_delegate_id_t ip6_ra_delegate_id; static ip6_ra_t *ip6_ra_pool; @@ -191,7 +100,7 @@ ip6_ra_report_unregister (ip6_ra_report_notify_t fn) } } -static inline ip6_ra_t * +ip6_ra_t * ip6_ra_get_itf (u32 sw_if_index) { index_t rai; @@ -204,6 +113,28 @@ ip6_ra_get_itf (u32 sw_if_index) return (NULL); } +u8 +ip6_ra_adv_enabled (u32 sw_if_index) +{ + ip6_ra_t *ra; + + ra = ip6_ra_get_itf (sw_if_index); + + return ((ra != NULL) && (ra->send_radv != 0)); +} + +void +ip6_ra_itf_walk (ip6_ra_itf_walk_fn_t fn, void *ctx) +{ + ip6_ra_t *radv_info; + + pool_foreach (radv_info, ip6_ra_pool) + { + if (WALK_STOP == fn (radv_info->sw_if_index, ctx)) + break; + } +} + /* for "syslogging" - use elog for now */ #define foreach_log_level \ _ (DEBUG, "DEBUG") \ @@ -372,7 +303,6 @@ icmp6_router_solicitation (vlib_main_t * vm, if (PREDICT_TRUE (error0 == ICMP6_ERROR_NONE && o0 != 0 && !is_unspecified && !is_link_local)) { - /* *INDENT-OFF* */ ip_neighbor_learn_t learn = { .sw_if_index = sw_if_index0, .ip = { @@ -380,7 +310,6 @@ icmp6_router_solicitation (vlib_main_t * vm, .version = AF_IP6, }, }; - /* *INDENT-ON* */ memcpy (&learn.mac, o0->ethernet_address, sizeof (learn.mac)); ip_neighbor_learn_dp (&learn); } @@ -413,12 +342,9 @@ icmp6_router_solicitation (vlib_main_t * vm, radv_info = ip6_ra_get_itf (sw_if_index0); - error0 = ((!radv_info) ? - ICMP6_ERROR_ROUTER_SOLICITATION_RADV_NOT_CONFIG : - error0); - error0 = radv_info->send_radv == 0 ? - ICMP6_ERROR_ROUTER_SOLICITATION_RADV_NOT_CONFIG : - error0; + error0 = ((!radv_info || 0 == radv_info->send_radv) ? + ICMP6_ERROR_ROUTER_SOLICITATION_RADV_NOT_CONFIG : + error0); if (error0 == ICMP6_ERROR_NONE) { f64 now = vlib_time_now (vm); @@ -530,7 +456,6 @@ icmp6_router_solicitation (vlib_main_t * vm, /* add advertised prefix options */ ip6_radv_prefix_t *pr_info; - /* *INDENT-OFF* */ pool_foreach (pr_info, radv_info->adv_prefixes_pool) { if(pr_info->enabled && @@ -596,7 +521,6 @@ icmp6_router_solicitation (vlib_main_t * vm, } } - /* *INDENT-ON* */ /* add additional options before here */ @@ -640,6 +564,8 @@ icmp6_router_solicitation (vlib_main_t * vm, /* Reuse current MAC header, copy SMAC to DMAC and * interface MAC to SMAC */ vlib_buffer_reset (p0); + vlib_buffer_advance ( + p0, vnet_buffer (p0)->l2_hdr_offset); eth0 = vlib_buffer_get_current (p0); clib_memcpy (eth0->dst_address, eth0->src_address, 6); @@ -702,7 +628,6 @@ icmp6_router_solicitation (vlib_main_t * vm, return frame->n_vectors; } -/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_icmp_router_solicitation_node,static) = { .function = icmp6_router_solicitation, @@ -719,7 +644,6 @@ VLIB_REGISTER_NODE (ip6_icmp_router_solicitation_node,static) = [ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_TX] = "interface-output", }, }; -/* *INDENT-ON* */ /* validate advertised info for consistancy (see RFC-4861 section 6.2.7) - log any inconsistencies, packet will always be dropped */ static_always_inline uword @@ -1012,7 +936,6 @@ icmp6_router_advertisement (vlib_main_t * vm, prefix->prefix.fp_proto = FIB_PROTOCOL_IP6; /* look for matching prefix - if we our advertising it, it better be consistant */ - /* *INDENT-OFF* */ pool_foreach (pr_info, radv_info->adv_prefixes_pool) { @@ -1043,7 +966,6 @@ icmp6_router_advertisement (vlib_main_t * vm, } break; } - /* *INDENT-ON* */ break; } default: @@ -1077,7 +999,6 @@ icmp6_router_advertisement (vlib_main_t * vm, return frame->n_vectors; } -/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_icmp_router_advertisement_node,static) = { .function = icmp6_router_advertisement, @@ -1092,7 +1013,6 @@ VLIB_REGISTER_NODE (ip6_icmp_router_advertisement_node,static) = [0] = "ip6-drop", }, }; -/* *INDENT-ON* */ static inline f64 random_f64_from_to (f64 from, f64 to) @@ -1282,14 +1202,12 @@ send_rs_process (vlib_main_t * vm, vlib_node_runtime_t * rt, do { due_time = current_time + 1e9; - /* *INDENT-OFF* */ pool_foreach (radv_info, ip6_ra_pool) { if (check_send_rs (vm, radv_info, current_time, &dt) && (dt < due_time)) due_time = dt; } - /* *INDENT-ON* */ current_time = vlib_time_now (vm); } while (due_time < current_time); @@ -1300,13 +1218,11 @@ send_rs_process (vlib_main_t * vm, vlib_node_runtime_t * rt, return 0; } -/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_rs_process_node) = { .function = send_rs_process, .type = VLIB_NODE_TYPE_PROCESS, .name = "ip6-rs-process", }; -/* *INDENT-ON* */ void icmp6_send_router_solicitation (vlib_main_t * vm, u32 sw_if_index, u8 stop, @@ -1394,9 +1310,6 @@ ip6_ra_link_enable (u32 sw_if_index) radv_info->initial_adverts_sent = radv_info->initial_adverts_count - 1; radv_info->initial_adverts_interval = MAX_INITIAL_RTR_ADVERT_INTERVAL; - /* deafult is to send */ - radv_info->send_radv = 1; - /* fill in delegate for this interface that will be needed later */ radv_info->adv_link_mtu = vnet_sw_interface_get_mtu (vnet_get_main (), sw_if_index, VNET_MTU_IP6); @@ -1417,12 +1330,10 @@ ip6_ra_delegate_disable (index_t rai) radv_info = pool_elt_at_index (ip6_ra_pool, rai); /* clean up prefix and MDP pools */ - /* *INDENT-OFF* */ pool_flush(p, radv_info->adv_prefixes_pool, ({ mhash_unset (&radv_info->address_to_prefix_index, &p->prefix, 0); })); - /* *INDENT-ON* */ pool_free (radv_info->adv_prefixes_pool); @@ -1444,12 +1355,10 @@ ip6_ra_update_secondary_radv_info (ip6_address_t * address, u8 prefix_len, ip6_address_mask_from_width (&mask, prefix_len); vec_reset_length (radv_indices); - /* *INDENT-OFF* */ pool_foreach (radv_info, ip6_ra_pool) { vec_add1 (radv_indices, radv_info - ip6_ra_pool); } - /* *INDENT-ON* */ /* * If we have another customer for this prefix, @@ -1464,7 +1373,6 @@ ip6_ra_update_secondary_radv_info (ip6_address_t * address, u8 prefix_len, if (radv_info->sw_if_index == primary_sw_if_index) continue; - /* *INDENT-OFF* */ pool_foreach (this_prefix, radv_info->adv_prefixes_pool) { if (this_prefix->prefix_len == prefix_len @@ -1487,7 +1395,6 @@ ip6_ra_update_secondary_radv_info (ip6_address_t * address, u8 prefix_len, clib_warning ("ip6_neighbor_ra_prefix returned %d", rv); } } - /* *INDENT-ON*/ } } @@ -1508,7 +1415,6 @@ ip6_ra_process_timer_event (vlib_main_t * vm, f64 now = vlib_time_now (vm); /* Interface ip6 radv info list */ - /* *INDENT-OFF* */ pool_foreach (radv_info, ip6_ra_pool) { if( !vnet_sw_interface_is_admin_up (vnm, radv_info->sw_if_index)) @@ -1598,7 +1504,6 @@ ip6_ra_process_timer_event (vlib_main_t * vm, } } } - /* *INDENT-ON* */ if (f) { @@ -1655,14 +1560,12 @@ ip6_ra_event_process (vlib_main_t * vm, return frame->n_vectors; } -/* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_ra_process_node) = { .function = ip6_ra_event_process, .name = "ip6-ra-process", .type = VLIB_NODE_TYPE_PROCESS, }; -/* *INDENT-ON* */ static void ip6_ra_signal_report (ip6_ra_report_t * r) @@ -1704,6 +1607,9 @@ ip6_ra_config (vlib_main_t * vm, u32 sw_if_index, if (!radv_info) return (VNET_API_ERROR_IP6_NOT_ENABLED); + /* Start off believing that we're going to send radv's */ + radv_info->send_radv = 1; + if ((max_interval != 0) && (min_interval == 0)) min_interval = .75 * max_interval; @@ -2029,8 +1935,7 @@ ip6_ra_cmd (vlib_main_t * vm, } else { - error = unformat_parse_error (line_input); - goto done; + break; } } @@ -2122,14 +2027,12 @@ format_ip6_ra (u8 * s, va_list * args) indent += 2; - /* *INDENT-OFF* */ pool_foreach (p, radv_info->adv_prefixes_pool) { s = format (s, "%Uprefix %U, length %d\n", format_white_space, indent+2, format_ip6_address, &p->prefix, p->prefix_len); } - /* *INDENT-ON* */ s = format (s, "%UMTU is %d\n", format_white_space, indent, radv_info->adv_link_mtu); @@ -2175,7 +2078,6 @@ format_ip6_ra (u8 * s, va_list * args) return (s); } - /*? * This command is used to configure the neighbor discovery * parameters on a given interface. Use the '<em>show ip6 interface</em>' @@ -2183,9 +2085,16 @@ format_ip6_ra (u8 * s, va_list * args) * on a given interface. This command has three formats: * * - * <b>Format 1 - Router Advertisement Options:</b> (Only one can be entered in a single command) + * <b>Format 1 - Router Advertisement Options:</b> (Only one can be entered in + * a single command) * - * '<em><b>ip6 nd <interface> [no] [ra-managed-config-flag] | [ra-other-config-flag] | [ra-suppress] | [ra-suppress-link-layer] | [ra-send-unicast] | [ra-lifetime <lifetime>] | [ra-initial <cnt> <interval>] | [ra-interval <max-interval> [<min-interval>]] | [ra-cease]</b></em>' + * @clistart + * ip6 nd <interface> [no] [ra-managed-config-flag] | + * [ra-other-config-flag] | [ra-suppress] | [ra-suppress-link-layer] | + * [ra-send-unicast] | [ra-lifetime <lifetime>] | + * [ra-initial <cnt> <interval>] | + * [ra-interval <max-interval> [<min-interval>]] | [ra-cease] + * @cliend * * Where: * @@ -2211,7 +2120,7 @@ format_ip6_ra (u8 * s, va_list * args) * and the '<em>no</em>' option returns it to this default state. * * <em>[no] ra-send-unicast</em> - Use the source address of the - * router-solicitation message if availiable. The default is to use + * router-solicitation message if available. The default is to use * multicast address of all nodes, and the '<em>no</em>' option returns * it to this default state. * @@ -2242,63 +2151,69 @@ format_ip6_ra (u8 * s, va_list * args) * * <b>Format 2 - Prefix Options:</b> * - * '<em><b>ip6 nd <interface> [no] prefix <ip6-address>/<width> [<valid-lifetime> <pref-lifetime> | infinite] [no-advertise] [off-link] [no-autoconfig] [no-onlink]</b></em>' + * @clistart + * ip6 nd <interface> [no] prefix <ip6-address>/<width> + * [<valid-lifetime> <pref-lifetime> | infinite] [no-advertise] [off-link] + * [no-autoconfig] [no-onlink] + * @cliend * * Where: * * <em>no</em> - All additional flags are ignored and the prefix is deleted. * - * <em><valid-lifetime> <pref-lifetime></em> - '<em><valid-lifetime></em>' is the - * length of time in seconds during what the prefix is valid for the purpose of - * on-link determination. Range is 7203 to 2592000 seconds and default is 2592000 - * seconds (30 days). '<em><pref-lifetime></em>' is the prefered-lifetime and is the - * length of time in seconds during what addresses generated from the prefix remain - * preferred. Range is 0 to 604800 seconds and default is 604800 seconds (7 days). + * <em><valid-lifetime> <pref-lifetime></em> - '<em><valid-lifetime></em>' is + * the length of time in seconds during what the prefix is valid for the + * purpose of on-link determination. Range is 7203 to 2592000 seconds and + * default is 2592000 seconds (30 days). '<em><pref-lifetime></em>' is the + * preferred-lifetime and is the length of time in seconds during what + * addresses generated from the prefix remain preferred. Range is 0 to 604800 + * seconds and default is 604800 seconds (7 days). * - * <em>infinite</em> - Both '<em><valid-lifetime></em>' and '<em><<pref-lifetime></em>' - * are inifinte, no timeout. + * <em>infinite</em> - Both '<em><valid-lifetime></em>' and + * '<em><pref-lifetime></em>' are infinite, no timeout. * * <em>no-advertise</em> - Do not send full router address in prefix * advertisement. Default is to advertise (i.e. - This flag is off by default). * - * <em>off-link</em> - Prefix is off-link, clear L-bit in packet. Default is on-link - * (i.e. - This flag is off and L-bit in packet is set by default and this prefix can - * be used for on-link determination). '<em>no-onlink</em>' also controls the L-bit. + * <em>off-link</em> - Prefix is off-link, clear L-bit in packet. Default is + * on-link (i.e. - This flag is off and L-bit in packet is set by default + * and this prefix can be used for on-link determination). '<em>no-onlink</em>' + * also controls the L-bit. * - * <em>no-autoconfig</em> - Do not use prefix for autoconfiguration, clear A-bit in packet. - * Default is autoconfig (i.e. - This flag is off and A-bit in packet is set by default. + * <em>no-autoconfig</em> - Do not use prefix for autoconfiguration, clear + * A-bit in packet. Default is autoconfig (i.e. - This flag is off and A-bit + * in packet is set by default. * - * <em>no-onlink</em> - Do not use prefix for onlink determination, clear L-bit in packet. - * Default is on-link (i.e. - This flag is off and L-bit in packet is set by default and - * this prefix can be used for on-link determination). '<em>off-link</em>' also controls - * the L-bit. + * <em>no-onlink</em> - Do not use prefix for onlink determination, clear L-bit + * in packet. Default is on-link (i.e. - This flag is off and L-bit in packet + * is set by default and this prefix can be used for on-link determination). + * '<em>off-link</em>' also controls the L-bit. * * * <b>Format 3: - Default of Prefix:</b> * - * '<em><b>ip6 nd <interface> [no] prefix <ip6-address>/<width> default</b></em>' + * @cliexcmd{ip6 nd <interface> [no] prefix <ip6-address>/<width> default} * - * When a new prefix is added (or existing one is being overwritten) <em>default</em> - * uses default values for the prefix. If <em>no</em> is used, the <em>default</em> - * is ignored and the prefix is deleted. + * When a new prefix is added (or existing one is being overwritten) + * <em>default</em> uses default values for the prefix. If <em>no</em> is + * used, the <em>default</em> is ignored and the prefix is deleted. * * * @cliexpar * Example of how set a router advertisement option: * @cliexcmd{ip6 nd GigabitEthernet2/0/0 ra-interval 100 20} * Example of how to add a prefix: - * @cliexcmd{ip6 nd GigabitEthernet2/0/0 prefix fe80::fe:28ff:fe9c:75b3/64 infinite no-advertise} + * @cliexcmd{ip6 nd GigabitEthernet2/0/0 prefix fe80::fe:28ff:fe9c:75b3/64 + * infinite no-advertise} * Example of how to delete a prefix: * @cliexcmd{ip6 nd GigabitEthernet2/0/0 no prefix fe80::fe:28ff:fe9c:75b3/64} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ip6_nd_command, static) = { .path = "ip6 nd", .short_help = "ip6 nd <interface> ...", .function = ip6_ra_cmd, }; -/* *INDENT-ON* */ /** * VFT for registering as a delegate to an IP6 link @@ -2324,12 +2239,10 @@ ip6_ra_init (vlib_main_t * vm) return (NULL); } -/* *INDENT-OFF* */ VLIB_INIT_FUNCTION (ip6_ra_init) = { .runs_after = VLIB_INITS("icmp6_init"), }; -/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON |