35 #define DEF_MAX_RADV_INTERVAL 200 36 #define DEF_MIN_RADV_INTERVAL .75 * DEF_MAX_RADV_INTERVAL 63 uword is_solicitation)
69 u32 n_left_from, n_left_to_next, next_index, n_advertisements_sent;
76 n_left_from = n_packets;
86 ? ICMP6_NEIGHBOR_DISCOVERY_OPTION_source_link_layer_address
87 : ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address);
88 n_advertisements_sent = 0;
90 while (n_left_from > 0)
94 while (n_left_from > 0 && n_left_to_next > 0)
98 icmp6_neighbor_solicitation_or_advertisement_header_t *h0;
99 icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *o0;
100 u32 bi0, options_len0, sw_if_index0, next0, error0;
101 u32 ip6_sadd_link_local, ip6_sadd_unspecified;
105 bi0 = to_next[0] = from[0];
118 error0 = ICMP6_ERROR_NONE;
120 ip6_sadd_link_local =
122 ip6_sadd_unspecified =
126 if (!ip6_sadd_unspecified && !ip6_sadd_link_local)
139 error0 = ((adj0->rewrite_header.sw_if_index != sw_if_index0
142 ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_NOT_ON_LINK
148 ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_NOT_ON_LINK;
152 o0 = (
void *) (h0 + 1);
153 o0 = ((options_len0 == 8 && o0->header.type == option_type
154 && o0->header.n_data_u64s == 1) ? o0 : 0);
157 if (
PREDICT_TRUE (error0 == ICMP6_ERROR_NONE && o0 != 0 &&
158 !ip6_sadd_unspecified))
163 .ip.ip6 = (is_solicitation ?
166 memcpy (&learn.
mac, o0->ethernet_address, sizeof (learn.
mac));
170 if (is_solicitation && error0 == ICMP6_ERROR_NONE)
181 error0 = ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
189 &h0->target_address, 128);
202 ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
225 ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
232 next0 = (error0 != ICMP6_ERROR_NONE
238 error0 = error0 == ICMP6_ERROR_NONE ?
239 ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_RX : error0;
242 if (is_solicitation && error0 == ICMP6_ERROR_NONE)
249 if (!ip6_sadd_unspecified)
253 IP6_MULTICAST_SCOPE_link_local,
254 IP6_MULTICAST_GROUP_ID_all_hosts);
258 h0->icmp.type = ICMP6_neighbor_advertisement;
268 ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
271 h0->advertisement_flags = clib_host_to_net_u32
275 h0->icmp.checksum = 0;
279 ASSERT (bogus_length == 0);
295 n_advertisements_sent++;
301 to_next, n_left_to_next,
310 ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_TX,
311 n_advertisements_sent);
389 .name =
"icmp6-neighbor-solicitation",
391 .vector_size =
sizeof (
u32),
405 .name =
"icmp6-neighbor-advertisement",
407 .vector_size =
sizeof (
u32),
422 u32 indent = va_arg (*args,
u32);
424 s =
format (s,
"%UNeighbor Discovery: enabled\n",
427 s =
format (s,
"%UICMP redirects are disabled\n",
429 s =
format (s,
"%UICMP unreachables are not sent\n",
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
static vlib_node_registration_t ip6_icmp_neighbor_advertisement_node
(constructor) VLIB_REGISTER_NODE (ip6_icmp_neighbor_advertisement_node)
Route added as a result of interface configuration.
vnet_main_t * vnet_get_main(void)
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
static uword icmp6_neighbor_advertisement(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
void ip_neighbor_learn_dp(const ip_neighbor_learn_t *l)
APIs invoked by neighbor implementation (i.s.
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
#define ethernet_buffer_header_size(b)
Determine the size of the Ethernet headers of the current frame in the buffer.
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
static void ip6_nd_delegate_disable(index_t indi)
vlib_error_t * errors
Vector of errors for this node.
static ip6_nd_t * ip6_nd_pool
#define clib_memcpy(d, s, n)
ethernet_main_t ethernet_main
int ip6_nd_proxy_add(u32 sw_if_index, const ip6_address_t *addr)
fib_node_index_t ip6_fib_table_lookup_exact_match(u32 fib_index, const ip6_address_t *addr, u32 len)
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
#define static_always_inline
#define VLIB_INIT_FUNCTION(x)
u32 local_interface_sw_if_index
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
icmp6_neighbor_solicitation_or_advertisement_next_t
static u32 ip6_src_lookup_for_packet(ip6_main_t *im, vlib_buffer_t *b, ip6_header_t *i)
return the DPO that the LB stacks on.
static_always_inline uword icmp6_neighbor_solicitation_or_advertisement(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, uword is_solicitation)
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
ip6_neighbor_proxy_cfg_t inv_proxy6_add
static vlib_node_registration_t ip6_icmp_neighbor_solicitation_node
(constructor) VLIB_REGISTER_NODE (ip6_icmp_neighbor_solicitation_node)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
struct ip6_nd_t_ ip6_nd_t
static u8 * format_ip6_nd(u8 *s, va_list *args)
#define ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
void ip_neighbor_register(ip46_type_t type, const ip_neighbor_vft_t *vft)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
u32 ip6_ll_fib_get(u32 sw_if_index)
For use in the data plane.
#define pool_put(P, E)
Free an object E in pool P.
enum icmp6_neighbor_discovery_option_type icmp6_neighbor_discovery_option_type_t
u32 node_index
Node index.
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
ip6_link_delegate_id_t ip6_link_delegate_register(const ip6_link_delegate_vft_t *vft)
vlib_node_registration_t ip6_icmp_input_node
(constructor) VLIB_REGISTER_NODE (ip6_icmp_input_node)
static clib_error_t * ip6_nd_init(vlib_main_t *vm)
This packet matches an "incomplete adjacency" and packets need to be passed to ARP to find rewrite st...
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
#define VLIB_REGISTER_NODE(x,...)
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Virtual function Table for neighbor protocol implementations to register.
u32 fib_node_index_t
A typedef of a node index.
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
index_t ip6_link_delegate_get(u32 sw_if_index, ip6_link_delegate_id_t id)
static void * ip6_next_header(ip6_header_t *i)
vlib_main_t vlib_node_runtime_t * node
static ip6_link_delegate_id_t ip6_nd_delegate_id
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
u32 ip6_link_delegate_id_t
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
IPv6 ND (seen in the link-local tables)
ip6_link_disable_fn_t ildv_disable
fib_entry_flag_t fib_entry_get_flags_for_source(fib_node_index_t fib_entry_index, fib_source_t source)
u32 n_solicitations_dropped
void vlib_trace_frame_buffers_only(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, uword n_buffers, uword next_buffer_stride, uword n_buffer_data_bytes_in_trace)
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
int ip6_nd_proxy_del(u32 sw_if_index, const ip6_address_t *addr)
#define FIB_NODE_INDEX_INVALID
void icmp6_register_type(vlib_main_t *vm, icmp6_type_t type, u32 node_index)
ip_lookup_next_t lookup_next_index
Next hop after ip4-lookup.
static uword icmp6_neighbor_solicitation(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static uword ip6_address_is_unspecified(const ip6_address_t *a)
vnet_sw_interface_type_t type
static const ethernet_interface_t * ip6_nd_get_eth_itf(u32 sw_if_index)
u16 flags
Copy of main node flags.
#define VLIB_NODE_FLAG_TRACE
static void ip6_nd_link_enable(u32 sw_if_index)
called when IP6 is enabled on a link.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
bool ip6_link_delegate_update(u32 sw_if_index, ip6_link_delegate_id_t id, index_t ii)
static void ip6_set_reserved_multicast_address(ip6_address_t *a, ip6_multicast_address_scope_t scope, u16 id)
format_function_t format_icmp6_input_trace