FD.io VPP  v21.01.1
Vector Packet Processing
ip6_mld.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 
20 #include <vnet/ip/ip.h>
22 
23 #include <vnet/ip/ip6_link.h>
24 #include <vnet/ip/ip6_ll_table.h>
25 
26 #include <vnet/ethernet/ethernet.h>
27 
28 /**
29  * @file
30  * @brief IPv6 Neighbor Adjacency and Neighbor Discovery.
31  *
32  * The files contains the API and CLI code for managing IPv6 neighbor
33  * adjacency tables and neighbor discovery logic.
34  */
35 
36 /* *INDENT-OFF*/
37 /* multicast listener report packet format for ethernet. */
38 typedef CLIB_PACKED (struct
39 {
40  ip6_hop_by_hop_ext_t ext_hdr;
41  ip6_router_alert_option_t alert;
42  ip6_padN_option_t pad;
43  icmp46_header_t icmp;
44  u16 rsvd;
45  u16 num_addr_records;
46  icmp6_multicast_address_record_t records[0];
47 }) icmp6_multicast_listener_report_header_t;
48 
49 typedef CLIB_PACKED (struct
50 {
52  icmp6_multicast_listener_report_header_t report_hdr;
54 /* *INDENT-ON*/
55 
56 typedef struct
57 {
58  /* group information */
61  ip6_address_t mcast_address;
62  ip6_address_t *mcast_source_address_pool;
64 
65 typedef struct ip6_nd_t_
66 {
67  /* local information */
70 
71  /* MLDP group information */
73 
74  /* Hash table mapping address to index in mldp address pool. */
76 
77 } ip6_mld_t;
78 
79 
82 
83 /////
84 
85 static inline ip6_mld_t *
87 {
88  index_t imi;
89 
90  imi = ip6_link_delegate_get (sw_if_index, ip6_mld_delegate_id);
91 
92  if (INDEX_INVALID != imi)
93  return (pool_elt_at_index (ip6_mld_pool, imi));
94 
95  return (NULL);
96 }
97 
98 /**
99  * @brief Add a multicast Address to the advertised MLD set
100  */
101 static void
103 {
104  ip6_mldp_group_t *mcast_group_info;
105  uword *p;
106 
107  /* lookup mldp info for this interface */
108  p = mhash_get (&imd->address_to_mldp_index, addr);
109  mcast_group_info = p ? pool_elt_at_index (imd->mldp_group_pool, p[0]) : 0;
110 
111  /* add address */
112  if (!mcast_group_info)
113  {
114  /* add */
115  u32 mi;
116  pool_get_zero (imd->mldp_group_pool, mcast_group_info);
117 
118  mi = mcast_group_info - imd->mldp_group_pool;
119  mhash_set (&imd->address_to_mldp_index, addr, mi, /* old_value */
120  0);
121 
122  mcast_group_info->type = 4;
123  mcast_group_info->mcast_source_address_pool = 0;
124  mcast_group_info->num_sources = 0;
125  clib_memcpy (&mcast_group_info->mcast_address, addr,
126  sizeof (ip6_address_t));
127  }
128 }
129 
130 /**
131  * @brief Delete a multicast Address from the advertised MLD set
132  */
133 static void
135 {
136  ip6_mldp_group_t *mcast_group_info;
137  uword *p;
138 
139  p = mhash_get (&imd->address_to_mldp_index, addr);
140  mcast_group_info = p ? pool_elt_at_index (imd->mldp_group_pool, p[0]) : 0;
141 
142  if (mcast_group_info)
143  {
144  mhash_unset (&imd->address_to_mldp_index, addr,
145  /* old_value */ 0);
146  pool_put (imd->mldp_group_pool, mcast_group_info);
147  }
148 }
149 
150 /**
151  * @brief Add a multicast Address to the advertised MLD set
152  */
153 static void
157 {
158  ip6_address_t addr;
159 
160  ip6_set_reserved_multicast_address (&addr, scope, group);
161 
162  ip6_neighbor_add_mld_prefix (a, &addr);
163 }
164 
165 static const ethernet_interface_t *
167 {
168  const vnet_sw_interface_t *sw;
169 
170  /* lookup radv container - ethernet interfaces only */
171  sw = vnet_get_sup_sw_interface (vnet_get_main (), sw_if_index);
174 
175  return (NULL);
176 }
177 
178 /**
179  * @brief create and initialize router advertisement parameters with default
180  * values for this intfc
181  */
182 static void
184 {
185  const ethernet_interface_t *eth;
186  ip6_mld_t *imd;
187 
188  eth = ip6_mld_get_eth_itf (sw_if_index);
189 
190  if (NULL == eth)
191  return;
192 
193  ASSERT (INDEX_INVALID == ip6_link_delegate_get (sw_if_index,
194  ip6_mld_delegate_id));
195 
196  pool_get_zero (ip6_mld_pool, imd);
197 
198  imd->sw_if_index = sw_if_index;
199 
200  mhash_init (&imd->address_to_mldp_index, sizeof (uword),
201  sizeof (ip6_address_t));
202 
203  /* add multicast groups we will always be reporting */
205  IP6_MULTICAST_SCOPE_link_local,
206  IP6_MULTICAST_GROUP_ID_all_hosts);
208  IP6_MULTICAST_SCOPE_link_local,
209  IP6_MULTICAST_GROUP_ID_all_routers);
211  IP6_MULTICAST_SCOPE_link_local,
212  IP6_MULTICAST_GROUP_ID_mldv2_routers);
213 
214  ip6_link_delegate_update (sw_if_index, ip6_mld_delegate_id,
215  imd - ip6_mld_pool);
216 }
217 
218 static void
220 {
221  ip6_mldp_group_t *m;
222  ip6_mld_t *imd;
223 
224  imd = pool_elt_at_index (ip6_mld_pool, imdi);
225 
226  /* clean MLD pools */
227  /* *INDENT-OFF* */
228  pool_flush (m, imd->mldp_group_pool,
229  ({
230  mhash_unset (&imd->address_to_mldp_index, &m->mcast_address, 0);
231  }));
232  /* *INDENT-ON* */
233 
234  pool_free (imd->mldp_group_pool);
235 
237 
238  pool_put (ip6_mld_pool, imd);
239 }
240 
241 /* send an mldpv2 report */
242 static void
244 {
245  vnet_main_t *vnm = vnet_get_main ();
246  vlib_main_t *vm = vnm->vlib_main;
247  int bogus_length;
248 
249  ip6_mld_t *imd;
250  u16 payload_length;
251  vlib_buffer_t *b0;
252  ip6_header_t *ip0;
253  u32 *to_next;
254  vlib_frame_t *f;
255  u32 bo0;
256  u32 n_to_alloc = 1;
257 
258  icmp6_multicast_listener_report_header_t *rh0;
260 
261  if (!vnet_sw_interface_is_admin_up (vnm, sw_if_index))
262  return;
263 
264  imd = ip6_mld_get_itf (sw_if_index);
265 
266  if (NULL == imd)
267  return;
268 
269  /* send report now - build a mldpv2 report packet */
270  if (0 == vlib_buffer_alloc (vm, &bo0, n_to_alloc))
271  {
272  alloc_fail:
273  clib_warning ("buffer allocation failure");
274  return;
275  }
276 
277  b0 = vlib_get_buffer (vm, bo0);
278 
279  /* adjust the sizeof the buffer to just include the ipv6 header */
281 
282  payload_length = sizeof (icmp6_multicast_listener_report_header_t);
283 
284  b0->error = ICMP6_ERROR_NONE;
285 
286  rp0 = vlib_buffer_get_current (b0);
287  ip0 = (ip6_header_t *) & rp0->ip;
288  rh0 = (icmp6_multicast_listener_report_header_t *) & rp0->report_hdr;
289 
291 
293  clib_host_to_net_u32 (0x6 << 28);
294 
295  ip0->protocol = IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS;
296  /* for DEBUG - vnet driver won't seem to emit router alerts */
297  /* ip0->protocol = IP_PROTOCOL_ICMP6; */
298  ip0->hop_limit = 1;
299 
300  rh0->icmp.type = ICMP6_multicast_listener_report_v2;
301 
302  /* source address MUST be the link-local address */
304  ip6_get_link_local_address (sw_if_index));
305 
306  /* destination is all mldpv2 routers */
308  IP6_MULTICAST_SCOPE_link_local,
309  IP6_MULTICAST_GROUP_ID_mldv2_routers);
310 
311  /* add reports here */
312  ip6_mldp_group_t *m;
313  int num_addr_records = 0;
314  icmp6_multicast_address_record_t rr;
315 
316  /* fill in the hop-by-hop extension header (router alert) info */
317  rh0->ext_hdr.next_hdr = IP_PROTOCOL_ICMP6;
318  rh0->ext_hdr.n_data_u64s = 0;
319 
320  rh0->alert.type = IP6_MLDP_ALERT_TYPE;
321  rh0->alert.len = 2;
322  rh0->alert.value = 0;
323 
324  rh0->pad.type = 1;
325  rh0->pad.len = 0;
326 
327  rh0->icmp.checksum = 0;
328 
329  /* *INDENT-OFF* */
330  pool_foreach (m, imd->mldp_group_pool)
331  {
332  rr.type = m->type;
333  rr.aux_data_len_u32s = 0;
334  rr.num_sources = clib_host_to_net_u16 (m->num_sources);
335  clib_memcpy(&rr.mcast_addr, &m->mcast_address, sizeof(ip6_address_t));
336 
337  num_addr_records++;
338 
339  if(vlib_buffer_add_data (vm, &bo0, (void *)&rr,
340  sizeof(icmp6_multicast_address_record_t)))
341  {
342  vlib_buffer_free (vm, &bo0, 1);
343  goto alloc_fail;
344  }
345 
346  payload_length += sizeof( icmp6_multicast_address_record_t);
347  }
348  /* *INDENT-ON* */
349 
350  rh0->rsvd = 0;
351  rh0->num_addr_records = clib_host_to_net_u16 (num_addr_records);
352 
353  /* update lengths */
354  ip0->payload_length = clib_host_to_net_u16 (payload_length);
355 
356  rh0->icmp.checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0,
357  &bogus_length);
358  ASSERT (bogus_length == 0);
359 
360  /*
361  * OK to override w/ no regard for actual FIB, because
362  * ip6-rewrite only looks at the adjacency.
363  */
364  vnet_buffer (b0)->sw_if_index[VLIB_RX] =
366 
367  vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
368  ip6_link_get_mcast_adj (sw_if_index);
369  b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
370 
371  vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "ip6-rewrite-mcast");
372 
373  f = vlib_get_frame_to_node (vm, node->index);
374  to_next = vlib_frame_vector_args (f);
375  to_next[0] = bo0;
376  f->n_vectors = 1;
377 
378  vlib_put_frame_to_node (vm, node->index, f);
379  return;
380 }
381 
382 /* send a RA or update the timer info etc.. */
383 static uword
386 {
387  vnet_main_t *vnm = vnet_get_main ();
388  ip6_mld_t *imd;
389 
390  /* Interface ip6 radv info list */
391  /* *INDENT-OFF* */
392  pool_foreach (imd, ip6_mld_pool)
393  {
395  {
396  imd->all_routers_mcast = 0;
397  continue;
398  }
399 
400  /* Make sure that we've joined the all-routers multicast group */
401  if (!imd->all_routers_mcast)
402  {
403  /* send MDLP_REPORT_EVENT message */
405  imd->all_routers_mcast = 1;
406  }
407  }
408  /* *INDENT-ON* */
409 
410  return 0;
411 }
412 
413 static uword
416 {
417  uword event_type;
418 
419  /* init code here */
420 
421  while (1)
422  {
423  vlib_process_wait_for_event_or_clock (vm, 1. /* seconds */ );
424 
425  if (!vlib_process_get_event_data (vm, &event_type))
426  {
427  /* No events found: timer expired. */
428  /* process interface list and send RAs as appropriate, update timer info */
429  ip6_mld_timer_event (vm, node, frame);
430  }
431  /* else; no events */
432  }
433  return frame->n_vectors;
434 }
435 
436 /* *INDENT-OFF* */
437 VLIB_REGISTER_NODE (ip6_mld_event_process_node) = {
438  .function = ip6_mld_event_process,
439  .name = "ip6-mld-process",
440  .type = VLIB_NODE_TYPE_PROCESS,
441 };
442 /* *INDENT-ON* */
443 
444 static u8 *
445 format_ip6_mld (u8 * s, va_list * args)
446 {
447  index_t imi = va_arg (*args, index_t);
448  u32 indent = va_arg (*args, u32);
449  ip6_mldp_group_t *m;
450  ip6_mld_t *imd;
451 
452  imd = pool_elt_at_index (ip6_mld_pool, imi);
453 
454  s = format (s, "%UJoined group address(es):\n", format_white_space, indent);
455 
456  /* *INDENT-OFF* */
457  pool_foreach (m, imd->mldp_group_pool)
458  {
459  s = format (s, "%U%U\n",
460  format_white_space, indent+2,
462  &m->mcast_address);
463  }
464  /* *INDENT-ON* */
465 
466  return (s);
467 }
468 
469 /**
470  * @brief callback when an interface address is added or deleted
471  */
472 static void
474  const ip6_address_t * address, u8 address_oength)
475 {
476  ip6_mld_t *imd;
477  ip6_address_t a;
478 
479  imd = pool_elt_at_index (ip6_mld_pool, imi);
480 
481  /* create solicited node multicast address for this interface address */
483 
484  a.as_u8[0xd] = address->as_u8[0xd];
485  a.as_u8[0xe] = address->as_u8[0xe];
486  a.as_u8[0xf] = address->as_u8[0xf];
487 
488  ip6_neighbor_add_mld_prefix (imd, &a);
489 }
490 
491 static void
493  const ip6_address_t * address, u8 address_oength)
494 {
495  ip6_mld_t *imd;
496  ip6_address_t a;
497 
498  imd = pool_elt_at_index (ip6_mld_pool, imi);
499 
500  /* create solicited node multicast address for this interface address */
502 
503  a.as_u8[0xd] = address->as_u8[0xd];
504  a.as_u8[0xe] = address->as_u8[0xe];
505  a.as_u8[0xf] = address->as_u8[0xf];
506 
507  ip6_neighbor_del_mld_prefix (imd, &a);
508 }
509 
510 /**
511  * VFT for registering as a delegate to an IP6 link
512  */
513 const static ip6_link_delegate_vft_t ip6_mld_delegate_vft = {
515  .ildv_enable = ip6_mld_link_enable,
516  .ildv_format = format_ip6_mld,
517  .ildv_addr_add = ip6_mld_address_add,
518  .ildv_addr_del = ip6_mld_address_del,
519 };
520 
521 static clib_error_t *
523 {
524  ip6_mld_delegate_id = ip6_link_delegate_register (&ip6_mld_delegate_vft);
525 
526  return (NULL);
527 }
528 
529 /* *INDENT-OFF* */
531 {
532  .runs_after = VLIB_INITS("icmp6_init"),
533 };
534 /* *INDENT-ON* */
535 
536 /*
537  * fd.io coding-style-patch-verification: ON
538  *
539  * Local Variables:
540  * eval: (c-set-style "gnu")
541  * End:
542  */
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
Definition: mhash.h:46
u8 pad[3]
log2 (size of the packing page block)
Definition: bihash_doc.h:61
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...
Definition: node_funcs.h:751
a
Definition: bitmap.h:544
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:937
static void ip6_neighbor_del_mld_prefix(ip6_mld_t *imd, ip6_address_t *addr)
Delete a multicast Address from the advertised MLD set.
Definition: ip6_mld.c:134
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
ip6_multicast_address_scope_t
Definition: ip6_packet.h:106
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:254
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index
Definition: node.h:280
struct ip6_nd_t_ ip6_mld_t
int vlib_buffer_add_data(vlib_main_t *vm, u32 *buffer_index, void *data, u32 n_data_bytes)
Definition: buffer.c:421
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
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:41
vlib_main_t * vm
Definition: in2out_ed.c:1580
vhost_vring_addr_t addr
Definition: vhost_user.h:111
ip6_address_t src_address
Definition: ip6_packet.h:310
unsigned char u8
Definition: types.h:56
#define clib_memcpy(d, s, n)
Definition: string.h:180
ethernet_main_t ethernet_main
Definition: init.c:45
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u32 local_interface_sw_if_index
Definition: vnet.h:63
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)
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:182
static uword ip6_mld_timer_event(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_mld.c:384
unsigned int u32
Definition: types.h:88
mhash_t address_to_mldp_index
Definition: ip6_mld.c:75
static const ethernet_interface_t * ip6_mld_get_eth_itf(u32 sw_if_index)
Definition: ip6_mld.c:166
static uword ip6_mld_event_process(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_mld.c:414
u32 sw_if_index
Definition: ip6_mld.c:68
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
#define pool_flush(VAR, POOL, BODY)
Remove all elements from a pool in a safe way.
Definition: pool.h:588
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
ip6_mldp_group_t * mldp_group_pool
Definition: ip6_mld.c:72
vlib_main_t * vlib_main
Definition: vnet.h:92
icmp
Definition: map.api:387
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer_funcs.h:677
unsigned short u16
Definition: types.h:57
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:216
#define IP6_MLDP_ALERT_TYPE
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:233
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
typedef CLIB_PACKED(struct { ip6_hop_by_hop_ext_t ext_hdr;ip6_router_alert_option_t alert;ip6_padN_option_t pad;icmp46_header_t icmp;u16 rsvd;u16 num_addr_records;icmp6_multicast_address_record_t records[0];})
Definition: ip6_mld.c:38
vnet_main_t vnet_main
Definition: misc.c:43
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
Definition: mhash.h:117
static ip6_link_delegate_id_t ip6_mld_delegate_id
Definition: ip6_mld.c:80
__clib_export void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
Definition: mhash.c:168
#define pool_free(p)
Free a pool.
Definition: pool.h:440
static void ip6_mld_link_enable(u32 sw_if_index)
create and initialize router advertisement parameters with default values for this intfc ...
Definition: ip6_mld.c:183
static void ip6_mld_address_add(u32 imi, const ip6_address_t *address, u8 address_oength)
callback when an interface address is added or deleted
Definition: ip6_mld.c:473
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:170
u16 n_vectors
Definition: node.h:397
format_function_t format_ip6_address
Definition: format.h:91
ip6_address_t mcast_address
Definition: ip6_mld.c:61
#define clib_warning(format, args...)
Definition: error.h:59
ip6_address_t * mcast_source_address_pool
Definition: ip6_mld.c:62
static void ip6_neighbor_send_mldpv2_report(u32 sw_if_index)
Definition: ip6_mld.c:243
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
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:1099
static void ip6_mld_delegate_disable(index_t imdi)
Definition: ip6_mld.c:219
#define ASSERT(truth)
manual_print typedef address
Definition: ip_types.api:96
static uword * mhash_get(mhash_t *h, const void *key)
Definition: mhash.h:110
static void mhash_free(mhash_t *h)
Definition: mhash.h:149
int all_routers_mcast
Definition: ip6_mld.c:69
ip6_multicast_link_local_group_id_t
Definition: ip6_packet.h:113
static void ip6_neighbor_add_mld_prefix(ip6_mld_t *imd, ip6_address_t *addr)
Add a multicast Address to the advertised MLD set.
Definition: ip6_mld.c:102
static clib_error_t * ip6_mld_init(vlib_main_t *vm)
Definition: ip6_mld.c:522
static uword vnet_sw_interface_is_admin_up(vnet_main_t *vnm, u32 sw_if_index)
static u8 * format_ip6_mld(u8 *s, va_list *args)
Definition: ip6_mld.c:445
__clib_export uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:346
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:297
Definition: defs.h:47
icmp6_multicast_listener_report_packet_t
Definition: ip6_mld.c:53
u16 payload_length
Definition: ip6_packet.h:301
static void * vlib_process_get_event_data(vlib_main_t *vm, uword *return_event_type_opaque)
Definition: node_funcs.h:526
vl_api_address_t ip
Definition: l2.api:501
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:982
static void ip6_set_solicited_node_multicast_address(ip6_address_t *a, u32 id)
Definition: ip6_packet.h:144
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1581
VLIB buffer representation.
Definition: buffer.h:102
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:297
static void ip6_address_copy(ip6_address_t *dst, const ip6_address_t *src)
Definition: ip6_packet.h:127
static ip6_mld_t * ip6_mld_pool
Definition: ip6_mld.c:81
#define vnet_buffer(b)
Definition: buffer.h:417
vnet_sw_interface_type_t type
Definition: interface.h:737
static ip6_mld_t * ip6_mld_get_itf(u32 sw_if_index)
Definition: ip6_mld.c:86
static void ip6_mld_address_del(u32 imi, const ip6_address_t *address, u8 address_oength)
Definition: ip6_mld.c:492
vl_api_gbp_scope_t scope
Definition: gbp.api:78
#define VLIB_INITS(...)
Definition: init.h:357
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
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
static void ip6_neighbor_add_mld_grp(ip6_mld_t *a, ip6_multicast_address_scope_t scope, ip6_multicast_link_local_group_id_t group)
Add a multicast Address to the advertised MLD set.
Definition: ip6_mld.c:154