FD.io VPP  v21.06
Vector Packet Processing
ip6_nd.c
Go to the documentation of this file.
1 /*
2  * ip/ip6_neighbor.c: IP6 neighbor handling
3  *
4  * Copyright (c) 2010 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/ip6-nd/ip6_nd.h>
19 
22 
23 #include <vnet/fib/ip6_fib.h>
24 #include <vnet/ip/ip6_link.h>
25 #include <vnet/ip/ip6_ll_table.h>
26 
27 /**
28  * @file
29  * @brief IPv6 Neighbor Adjacency and Neighbor Discovery.
30  *
31  * The files contains the API and CLI code for managing IPv6 neighbor
32  * adjacency tables and neighbor discovery logic.
33  */
34 
35 #define DEF_MAX_RADV_INTERVAL 200
36 #define DEF_MIN_RADV_INTERVAL .75 * DEF_MAX_RADV_INTERVAL
37 
38 typedef struct ip6_nd_t_
39 {
40  /* local information */
42 
43  /* stats */
46 } ip6_nd_t;
47 
50 
51 
52 typedef enum
53 {
58 
63  uword is_solicitation)
64 {
65  vnet_main_t *vnm = vnet_get_main ();
67  uword n_packets = frame->n_vectors;
68  u32 *from, *to_next;
69  u32 n_left_from, n_left_to_next, next_index, n_advertisements_sent;
71  vlib_node_runtime_t *error_node =
73  int bogus_length;
74 
75  from = vlib_frame_vector_args (frame);
76  n_left_from = n_packets;
77  next_index = node->cached_next_index;
78 
79  if (node->flags & VLIB_NODE_FLAG_TRACE)
80  vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
81  /* stride */ 1,
82  sizeof (icmp6_input_trace_t));
83 
84  option_type =
85  (is_solicitation
86  ? ICMP6_NEIGHBOR_DISCOVERY_OPTION_source_link_layer_address
87  : ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address);
88  n_advertisements_sent = 0;
89 
90  while (n_left_from > 0)
91  {
92  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
93 
94  while (n_left_from > 0 && n_left_to_next > 0)
95  {
96  vlib_buffer_t *p0;
97  ip6_header_t *ip0;
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;
102  int is_rewrite0;
103  u32 ni0;
104 
105  bi0 = to_next[0] = from[0];
106 
107  from += 1;
108  to_next += 1;
109  n_left_from -= 1;
110  n_left_to_next -= 1;
111 
112  p0 = vlib_get_buffer (vm, bi0);
113  ip0 = vlib_buffer_get_current (p0);
114  h0 = ip6_next_header (ip0);
115  options_len0 =
116  clib_net_to_host_u16 (ip0->payload_length) - sizeof (h0[0]);
117 
118  error0 = ICMP6_ERROR_NONE;
119  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
120  ip6_sadd_link_local =
122  ip6_sadd_unspecified =
124 
125  /* Check that source address is unspecified, link-local or else on-link. */
126  if (!ip6_sadd_unspecified && !ip6_sadd_link_local)
127  {
128  u32 src_adj_index0 = ip6_src_lookup_for_packet (im, p0, ip0);
129 
130  if (ADJ_INDEX_INVALID != src_adj_index0)
131  {
132  ip_adjacency_t *adj0 = adj_get (src_adj_index0);
133 
134  /* Allow all realistic-looking rewrite adjacencies to pass */
135  ni0 = adj0->lookup_next_index;
136  is_rewrite0 = (ni0 >= IP_LOOKUP_NEXT_ARP) &&
137  (ni0 < IP6_LOOKUP_N_NEXT);
138 
139  error0 = ((adj0->rewrite_header.sw_if_index != sw_if_index0
140  || !is_rewrite0)
141  ?
142  ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_NOT_ON_LINK
143  : error0);
144  }
145  else
146  {
147  error0 =
148  ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_NOT_ON_LINK;
149  }
150  }
151 
152  o0 = (void *) (h0 + 1);
153  o0 = ((options_len0 == 8 && o0->header.type == option_type
154  && o0->header.n_data_u64s == 1) ? o0 : 0);
155 
156  /* If src address unspecified or link local, donot learn neighbor MAC */
157  if (PREDICT_TRUE (error0 == ICMP6_ERROR_NONE && o0 != 0 &&
158  !ip6_sadd_unspecified))
159  {
160  /* *INDENT-OFF* */
161  ip_neighbor_learn_t learn = {
162  .sw_if_index = sw_if_index0,
163  .ip = {
164  .version = AF_IP6,
165  .ip.ip6 = (is_solicitation ?
166  ip0->src_address :
167  h0->target_address),
168  }
169  };
170  /* *INDENT-ON* */
171  memcpy (&learn.mac, o0->ethernet_address, sizeof (learn.mac));
172  ip_neighbor_learn_dp (&learn);
173  }
174 
175  if (is_solicitation && error0 == ICMP6_ERROR_NONE)
176  {
177  /* Check that target address is local to this router. */
178  fib_node_index_t fei;
179  u32 fib_index;
180 
181  fib_index =
183 
184  if (~0 == fib_index)
185  {
186  error0 = ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
187  }
188  else
189  {
190  if (ip6_address_is_link_local_unicast (&h0->target_address))
191  {
193  (ip6_ll_fib_get (sw_if_index0),
194  &h0->target_address, 128);
195  }
196  else
197  {
198  fei = ip6_fib_table_lookup_exact_match (fib_index,
199  &h0->target_address,
200  128);
201  }
202 
203  if (FIB_NODE_INDEX_INVALID == fei)
204  {
205  /* The target address is not in the FIB */
206  error0 =
207  ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
208  }
209  else
210  {
214  {
215  /* It's an address that belongs to one of our interfaces
216  * that's good. */
217  }
218  else if (FIB_ENTRY_FLAG_LOCAL &
220  fei, FIB_SOURCE_IP6_ND))
221  {
222  /* It's one of our link local addresses
223  * that's good. */
224  }
225  else if (fib_entry_is_sourced (fei,
227  {
228  /* The address was added by IPv6 Proxy ND config.
229  * We should only respond to these if the NS arrived on
230  * the link that has a matching covering prefix */
231  }
232  else
233  {
234  error0 =
235  ICMP6_ERROR_NEIGHBOR_SOLICITATION_SOURCE_UNKNOWN;
236  }
237  }
238  }
239  }
240 
241  if (is_solicitation)
242  next0 = (error0 != ICMP6_ERROR_NONE
245  else
246  {
247  next0 = 0;
248  error0 = error0 == ICMP6_ERROR_NONE ?
249  ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_RX : error0;
250  }
251 
252  if (is_solicitation && error0 == ICMP6_ERROR_NONE)
253  {
254  vnet_sw_interface_t *sw_if0;
255  ethernet_interface_t *eth_if0;
256  ethernet_header_t *eth0;
257 
258  /* dst address is either source address or the all-nodes mcast addr */
259  if (!ip6_sadd_unspecified)
260  ip0->dst_address = ip0->src_address;
261  else
263  IP6_MULTICAST_SCOPE_link_local,
264  IP6_MULTICAST_GROUP_ID_all_hosts);
265 
266  ip0->src_address = h0->target_address;
267  ip0->hop_limit = 255;
268  h0->icmp.type = ICMP6_neighbor_advertisement;
269 
270  sw_if0 = vnet_get_sup_sw_interface (vnm, sw_if_index0);
272  eth_if0 =
274  if (eth_if0 && o0)
275  {
276  clib_memcpy (o0->ethernet_address, &eth_if0->address, 6);
277  o0->header.type =
278  ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
279  }
280 
281  h0->advertisement_flags = clib_host_to_net_u32
284 
285  h0->icmp.checksum = 0;
286  h0->icmp.checksum =
288  &bogus_length);
289  ASSERT (bogus_length == 0);
290 
291  /* Reuse current MAC header, copy SMAC to DMAC and
292  * interface MAC to SMAC */
294  eth0 = vlib_buffer_get_current (p0);
295  clib_memcpy (eth0->dst_address, eth0->src_address, 6);
296  if (eth_if0)
297  clib_memcpy (eth0->src_address, &eth_if0->address, 6);
298 
299  /* Setup input and output sw_if_index for packet */
300  ASSERT (vnet_buffer (p0)->sw_if_index[VLIB_RX] == sw_if_index0);
301  vnet_buffer (p0)->sw_if_index[VLIB_TX] = sw_if_index0;
302  vnet_buffer (p0)->sw_if_index[VLIB_RX] =
304 
305  n_advertisements_sent++;
306  }
307 
308  p0->error = error_node->errors[error0];
309 
310  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
311  to_next, n_left_to_next,
312  bi0, next0);
313  }
314 
315  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
316  }
317 
318  /* Account for advertisements sent. */
319  vlib_error_count (vm, error_node->node_index,
320  ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_TX,
321  n_advertisements_sent);
322 
323  return frame->n_vectors;
324 }
325 
326 static const ethernet_interface_t *
328 {
329  const vnet_sw_interface_t *sw;
330 
331  /* lookup radv container - ethernet interfaces only */
332  sw = vnet_get_sup_sw_interface (vnet_get_main (), sw_if_index);
335 
336  return (NULL);
337 }
338 
339 /**
340  * @brief called when IP6 is enabled on a link.
341  * create and initialize router advertisement parameters with default
342  * values for this intfc
343  */
344 static void
346 {
347  const ethernet_interface_t *eth;
348  ip6_nd_t *ind;
349 
350  eth = ip6_nd_get_eth_itf (sw_if_index);
351 
352  if (NULL == eth)
353  return;
354 
355  ASSERT (INDEX_INVALID == ip6_link_delegate_get (sw_if_index,
357 
358  pool_get_zero (ip6_nd_pool, ind);
359 
360  ind->sw_if_index = sw_if_index;
361 
363  ind - ip6_nd_pool);
364 }
365 
366 static void
368 {
369  ip6_nd_t *ind;
370 
371  ind = pool_elt_at_index (ip6_nd_pool, indi);
372 
373  pool_put (ip6_nd_pool, ind);
374 }
375 
376 static uword
379 {
380  return icmp6_neighbor_solicitation_or_advertisement (vm, node, frame,
381  /* is_solicitation */
382  1);
383 }
384 
385 static uword
389 {
390  return icmp6_neighbor_solicitation_or_advertisement (vm, node, frame,
391  /* is_solicitation */
392  0);
393 }
394 
395 /* *INDENT-OFF* */
397 {
398  .function = icmp6_neighbor_solicitation,
399  .name = "icmp6-neighbor-solicitation",
400 
401  .vector_size = sizeof (u32),
402 
403  .format_trace = format_icmp6_input_trace,
404 
405  .n_next_nodes = ICMP6_NEIGHBOR_SOLICITATION_N_NEXT,
406  .next_nodes = {
408  [ICMP6_NEIGHBOR_SOLICITATION_NEXT_REPLY] = "interface-output",
409  },
410 };
411 
413 {
414  .function = icmp6_neighbor_advertisement,
415  .name = "icmp6-neighbor-advertisement",
416 
417  .vector_size = sizeof (u32),
418 
419  .format_trace = format_icmp6_input_trace,
420 
421  .n_next_nodes = 1,
422  .next_nodes = {
423  [0] = "ip6-punt",
424  },
425 };
426 /* *INDENT-ON* */
427 
428 static u8 *
429 format_ip6_nd (u8 * s, va_list * args)
430 {
431  CLIB_UNUSED (index_t indi) = va_arg (*args, index_t);
432  u32 indent = va_arg (*args, u32);
433 
434  s = format (s, "%UNeighbor Discovery: enabled\n",
435  format_white_space, indent);
436 
437  s = format (s, "%UICMP redirects are disabled\n",
438  format_white_space, indent + 2);
439  s = format (s, "%UICMP unreachables are not sent\n",
440  format_white_space, indent + 2);
441  s = format (s, "%UND DAD is disabled\n", format_white_space, indent + 2);
442  //s = format (s, "%UND reachable time is %d milliseconds\n",);
443 
444  return (s);
445 }
446 
447 /**
448  * VFT to act as an implementation of a neighbour protocol
449  */
450 const static ip_neighbor_vft_t ip6_nd_impl_vft = {
452  .inv_proxy6_del = ip6_nd_proxy_del,
453 };
454 
455 /**
456  * VFT for registering as a delegate to an IP6 link
457  */
458 const static ip6_link_delegate_vft_t ip6_nd_delegate_vft = {
460  .ildv_enable = ip6_nd_link_enable,
461  .ildv_format = format_ip6_nd,
462 };
463 
464 static clib_error_t *
466 {
467  icmp6_register_type (vm, ICMP6_neighbor_solicitation,
469  icmp6_register_type (vm, ICMP6_neighbor_advertisement,
471 
472  ip_neighbor_register (AF_IP6, &ip6_nd_impl_vft);
473 
474  ip6_nd_delegate_id = ip6_link_delegate_register (&ip6_nd_delegate_vft);
475 
476  return 0;
477 }
478 
479 /* *INDENT-OFF* */
481 {
482  .runs_after = VLIB_INITS("icmp6_init"),
483 };
484 /* *INDENT-ON* */
485 
486 /*
487  * fd.io coding-style-patch-verification: ON
488  *
489  * Local Variables:
490  * eval: (c-set-style "gnu")
491  * End:
492  */
#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)
Definition: ip6_nd.c:412
#define CLIB_UNUSED(x)
Definition: clib.h:90
Route added as a result of interface configuration.
Definition: fib_source.h:59
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:258
static uword icmp6_neighbor_advertisement(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_nd.c:386
#define PREDICT_TRUE(x)
Definition: clib.h:125
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)
Definition: error_funcs.h:57
IP unicast adjacency.
Definition: adj.h:235
#define ethernet_buffer_header_size(b)
Determine the size of the Ethernet headers of the current frame in the buffer.
Definition: ethernet.h:463
u8 src_address[6]
Definition: packet.h:56
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:43
static void ip6_nd_delegate_disable(index_t indi)
Definition: ip6_nd.c:367
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:461
ip6_address_t src_address
Definition: ip6_packet.h:310
unsigned char u8
Definition: types.h:56
static ip6_nd_t * ip6_nd_pool
Definition: ip6_nd.c:49
unsigned int u32
Definition: types.h:88
#define clib_memcpy(d, s, n)
Definition: string.h:197
ethernet_main_t ethernet_main
Definition: init.c:45
int ip6_nd_proxy_add(u32 sw_if_index, const ip6_address_t *addr)
Definition: ip6_nd_proxy.c:76
fib_node_index_t ip6_fib_table_lookup_exact_match(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:229
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:470
#define static_always_inline
Definition: clib.h:112
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
u32 local_interface_sw_if_index
Definition: vnet.h:79
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
u8 dst_address[6]
Definition: packet.h:55
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
description fragment has unexpected format
Definition: map.api:433
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
Definition: ip6_nd.c:52
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.
Definition: ip6_fib.h:166
vnet_main_t * vnet_get_main(void)
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)
Definition: ip6_nd.c:60
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_fib.c:353
ip6_neighbor_proxy_cfg_t inv_proxy6_add
Definition: ip_neighbor.h:107
u32 sw_if_index
Definition: ip6_mld.c:68
static vlib_node_registration_t ip6_icmp_neighbor_solicitation_node
(constructor) VLIB_REGISTER_NODE (ip6_icmp_neighbor_solicitation_node)
Definition: ip6_nd.c:396
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
struct ip6_nd_t_ ip6_nd_t
Definition: fib_entry.h:117
static u8 * format_ip6_nd(u8 *s, va_list *args)
Definition: ip6_nd.c:429
#define ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
Definition: adj_types.h:36
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
u32 ip6_ll_fib_get(u32 sw_if_index)
For use in the data plane.
Definition: ip6_ll_table.c:28
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
enum icmp6_neighbor_discovery_option_type icmp6_neighbor_discovery_option_type_t
ethernet_interface_address_t address
Definition: ethernet.h:174
vnet_main_t vnet_main
Definition: misc.c:43
ip6_main_t ip6_main
Definition: ip6_forward.c:2787
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
u32 node_index
Node index.
Definition: node.h:479
#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.
Definition: buffer_node.h:224
#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).
Definition: node_funcs.h:395
vlib_node_registration_t ip6_icmp_input_node
(constructor) VLIB_REGISTER_NODE (ip6_icmp_input_node)
Definition: icmp6.c:240
static clib_error_t * ip6_nd_init(vlib_main_t *vm)
Definition: ip6_nd.c:465
This packet matches an "incomplete adjacency" and packets need to be passed to ARP to find rewrite st...
Definition: adj.h:63
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:388
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:116
vnet_interface_main_t * im
Virtual function Table for neighbor protocol implementations to register.
Definition: ip_neighbor.h:101
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:407
static ip6_link_delegate_id_t ip6_nd_delegate_id
Definition: ip6_nd.c:48
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
Definition: ip6_forward.c:1098
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:498
#define ASSERT(truth)
u32 n_solicitations_rcvd
Definition: ip6_nd.c:44
vlib_put_next_frame(vm, node, next_index, 0)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:276
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
Definition: ip6_packet.h:253
IPv6 ND (seen in the link-local tables)
Definition: fib_source.h:99
nat44_ei_hairpin_src_next_t next_index
IPv6 Proxy ND.
Definition: fib_source.h:95
fib_entry_flag_t fib_entry_get_flags_for_source(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: defs.h:47
u32 n_solicitations_dropped
Definition: ip6_nd.c:45
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)
Definition: trace.c:48
u16 payload_length
Definition: ip6_packet.h:301
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:982
int ip6_nd_proxy_del(u32 sw_if_index, const ip6_address_t *addr)
Definition: ip6_nd_proxy.c:82
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
void icmp6_register_type(vlib_main_t *vm, icmp6_type_t type, u32 node_index)
Definition: icmp6.c:750
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
ip_lookup_next_t lookup_next_index
Next hop after ip4-lookup.
Definition: adj.h:337
static uword icmp6_neighbor_solicitation(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_nd.c:377
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
VLIB buffer representation.
Definition: buffer.h:111
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
static uword ip6_address_is_unspecified(const ip6_address_t *a)
Definition: ip6_packet.h:237
#define vnet_buffer(b)
Definition: buffer.h:437
vnet_sw_interface_type_t type
Definition: interface.h:870
static const ethernet_interface_t * ip6_nd_get_eth_itf(u32 sw_if_index)
Definition: ip6_nd.c:327
u16 flags
Copy of main node flags.
Definition: node.h:492
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:292
static void ip6_nd_link_enable(u32 sw_if_index)
called when IP6 is enabled on a link.
Definition: ip6_nd.c:345
#define VLIB_INITS(...)
Definition: init.h:352
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
void ip_neighbor_register(ip_address_family_t af, const ip_neighbor_vft_t *vft)
Definition: ip_neighbor.c:1009
Definition: defs.h:46
ip6_address_t dst_address
Definition: ip6_packet.h:310
static void ip6_set_reserved_multicast_address(ip6_address_t *a, ip6_multicast_address_scope_t scope, u16 id)
Definition: ip6_packet.h:134
format_function_t format_icmp6_input_trace
Definition: icmp6.h:67