FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
vrrp_packet.c
Go to the documentation of this file.
1 /*
2  * vrrp.c - vrrp plugin action functions
3  *
4  * Copyright 2019-2020 Rubicon Communications, LLC (Netgate)
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  */
9 
10 #include <vnet/vnet.h>
11 #include <vnet/plugin/plugin.h>
12 #include <vnet/mfib/mfib_entry.h>
13 #include <vnet/mfib/mfib_table.h>
14 #include <vnet/adj/adj.h>
15 #include <vnet/adj/adj_mcast.h>
16 #include <vnet/fib/fib_table.h>
17 #include <vnet/fib/fib_sas.h>
18 #include <vnet/ip/igmp_packet.h>
19 #include <vnet/ip/ip6_link.h>
21 
22 #include <vrrp/vrrp.h>
23 #include <vrrp/vrrp_packet.h>
24 
25 #include <vpp/app/version.h>
26 
27 static const u8 vrrp4_dst_mac[6] = { 0x1, 0x0, 0x5e, 0x0, 0x0, 0x12 };
28 static const u8 vrrp6_dst_mac[6] = { 0x33, 0x33, 0x0, 0x0, 0x0, 0x12 };
29 static const u8 vrrp_src_mac_prefix[4] = { 0x0, 0x0, 0x5e, 0x0 };
30 
31 static int
33 {
34  vnet_main_t *vnm = vnet_get_main ();
35  vnet_link_t link_type;
36  ethernet_header_t *eth;
37  int n_bytes = 0;
38  const void *dst_mac;
39  u8 mac_byte_ipver;
40  u8 *rewrite;
41 
42  eth = vlib_buffer_get_current (b);
43 
44  if (vrrp_vr_is_ipv6 (vr))
45  {
46  dst_mac = vrrp6_dst_mac;
47  link_type = VNET_LINK_IP6;
48  mac_byte_ipver = 0x2;
49  }
50  else
51  {
52  dst_mac = vrrp4_dst_mac;
53  link_type = VNET_LINK_IP4;
54  mac_byte_ipver = 0x1;
55  }
56 
57  rewrite = ethernet_build_rewrite (vnm, vr->config.sw_if_index, link_type,
58  dst_mac);
60 
61  /* change the source mac from the HW addr to the VRRP virtual MAC */
64  eth->src_address[4] = mac_byte_ipver;
65  eth->src_address[5] = vr->config.vr_id;
66 
67  n_bytes += vec_len (rewrite);
68 
71 
72  vec_free (rewrite);
73 
74  return n_bytes;
75 }
76 
77 #define VRRP4_MCAST_ADDR_AS_U8 { 224, 0, 0, 18 }
78 #define VRRP6_MCAST_ADDR_AS_U8 \
79 { 0xff, 0x2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x12 }
80 
81 static const ip46_address_t vrrp4_mcast_addr = {
82  .ip4 = {.as_u8 = VRRP4_MCAST_ADDR_AS_U8,},
83 };
84 
85 static const ip46_address_t vrrp6_mcast_addr = {
86  .ip6 = {.as_u8 = VRRP6_MCAST_ADDR_AS_U8,},
87 };
88 
89 /* size of static parts of header + (# addrs * addr length) */
92 {
93  u16 addr_len = vrrp_vr_is_ipv6 (vr) ? 16 : 4;
94 
95  return sizeof (vrrp_header_t) + (vec_len (vr->config.vr_addrs) * addr_len);
96 }
97 
98 static int
100  const ip46_address_t * dst)
101 {
102  if (!vrrp_vr_is_ipv6 (vr)) /* IPv4 */
103  {
105  ip4_address_t *src4;
106 
107  clib_memset (ip4, 0, sizeof (*ip4));
108  ip4->ip_version_and_header_length = 0x45;
109  ip4->ttl = 255;
110  ip4->protocol = IP_PROTOCOL_VRRP;
111  clib_memcpy (&ip4->dst_address, &dst->ip4, sizeof (dst->ip4));
112 
113  /* RFC 5798 Section 5.1.1.1 - Source Address "is the primary IPv4
114  * address of the interface the packet is being sent from". Assume
115  * this is the first address on the interface.
116  */
118  ip4->src_address.as_u32 = src4->as_u32;
119  ip4->length = clib_host_to_net_u16 (sizeof (*ip4) +
120  vrrp_adv_payload_len (vr));
121  ip4->checksum = ip4_header_checksum (ip4);
122 
124  vlib_buffer_advance (b, sizeof (*ip4));
125 
126  return sizeof (*ip4);
127  }
128  else
129  {
131 
132  clib_memset (ip6, 0, sizeof (*ip6));
133  ip6->ip_version_traffic_class_and_flow_label = 0x00000060;
134  ip6->hop_limit = 255;
135  ip6->protocol = IP_PROTOCOL_VRRP;
136  clib_memcpy (&ip6->dst_address, &dst->ip6, sizeof (dst->ip6));
137  ip6_address_copy (&ip6->src_address,
139  ip6->payload_length = clib_host_to_net_u16 (vrrp_adv_payload_len (vr));
140 
142  vlib_buffer_advance (b, sizeof (*ip6));
143 
144  return sizeof (*ip6);
145  }
146 }
147 
148 
149 u16
150 vrrp_adv_csum (void *l3_hdr, void *payload, u8 is_ipv6, u16 len)
151 {
152  ip_csum_t csum = 0;
153  u8 proto = IP_PROTOCOL_VRRP;
154  int addr_len;
155  int word_size = sizeof (uword);
156  void *src_addr;
157  int i;
158 
159  if (is_ipv6)
160  {
161  addr_len = 16;
162  src_addr = &(((ip6_header_t *) l3_hdr)->src_address);
163  }
164  else
165  {
166  addr_len = 4;
167  src_addr = &(((ip4_header_t *) l3_hdr)->src_address);
168  }
169 
170  for (i = 0; i < (2 * addr_len); i += word_size)
171  {
172  if (word_size == sizeof (u64))
173  csum =
175  else
176  csum =
178  }
179 
180  csum = ip_csum_with_carry (csum,
181  clib_host_to_net_u32 (len + (proto << 16)));
182 
183  /* now do the payload */
184  csum = ip_incremental_checksum (csum, payload, len);
185 
186  csum = ~ip_csum_fold (csum);
187 
188  return (u16) csum;
189 }
190 
191 static int
193 {
194  vrrp_header_t *vrrp = vlib_buffer_get_current (b);
195  void *l3_hdr;
196  ip46_address_t *vr_addr;
197  void *hdr_addr;
198  u8 is_ipv6;
199  u8 n_addrs;
200  int len;
201 
202  n_addrs = vec_len (vr->config.vr_addrs);
203  is_ipv6 = vrrp_vr_is_ipv6 (vr);
204 
205  if (is_ipv6)
206  {
207  ip6_header_t *ip6;
208 
209  len = sizeof (*vrrp) + n_addrs * sizeof (ip6_address_t);;
210  l3_hdr = vlib_buffer_get_current (b) - sizeof (ip6_header_t);
211  ip6 = l3_hdr;
212  ip6->payload_length = clib_host_to_net_u16 (len);
213  }
214  else
215  {
216  len = sizeof (*vrrp) + n_addrs * sizeof (ip4_address_t);
217  l3_hdr = vlib_buffer_get_current (b) - sizeof (ip4_header_t);
218  }
219 
220  vrrp->vrrp_version_and_type = 0x31;
221  vrrp->vr_id = vr->config.vr_id;
222  vrrp->priority = (shutdown) ? 0 : vrrp_vr_priority (vr);
223  vrrp->n_addrs = vec_len (vr->config.vr_addrs);
224  vrrp->rsvd_and_max_adv_int = clib_host_to_net_u16 (vr->config.adv_interval);
225  vrrp->checksum = 0;
226 
227  hdr_addr = (void *) (vrrp + 1);
228 
229  vec_foreach (vr_addr, vr->config.vr_addrs)
230  {
231  if (is_ipv6)
232  {
233  clib_memcpy (hdr_addr, &vr_addr->ip6, 16);
234  hdr_addr += 16;
235  }
236  else
237  {
238  clib_memcpy (hdr_addr, &vr_addr->ip4, 4);
239  hdr_addr += 4;
240  }
241  }
242 
244 
245  vrrp->checksum =
246  vrrp_adv_csum (l3_hdr, vrrp, is_ipv6, vrrp_adv_payload_len (vr));
247 
248  return len;
249 }
250 
253 {
254  if (vrrp_vr_is_unicast (vr))
255  {
256  if (vrrp_vr_is_ipv6 (vr))
257  return ip6_lookup_node.index;
258  else
259  return ip4_lookup_node.index;
260  }
261  else
262  {
263  vrrp_main_t *vmp = &vrrp_main;
264 
265  return vmp->intf_output_node_idx;
266  }
267 }
268 
269 static_always_inline const ip46_address_t *
271 {
272  if (vrrp_vr_is_ipv6 (vr))
273  return &vrrp6_mcast_addr;
274 
275  return &vrrp4_mcast_addr;
276 }
277 
278 int
279 vrrp_adv_send (vrrp_vr_t * vr, int shutdown)
280 {
282  vlib_frame_t *to_frame;
283  int i, n_buffers = 1;
284  u32 node_index, *to_next, *bi = 0;
285  u8 is_unicast = vrrp_vr_is_unicast (vr);
286 
288 
289  if (is_unicast)
291 
292  if (n_buffers < 1)
293  {
294  /* A unicast VR will not start without peers added so this should
295  * not happen. Just avoiding a crash if it happened somehow.
296  */
297  clib_warning ("Unicast VR configuration corrupted for %U",
298  format_vrrp_vr_key, vr);
299  return -1;
300  }
301 
302  vec_validate (bi, n_buffers - 1);
303  if (vlib_buffer_alloc (vm, bi, n_buffers) != n_buffers)
304  {
305  clib_warning ("Buffer allocation failed for %U", format_vrrp_vr_key,
306  vr);
307  vec_free (bi);
308  return -1;
309  }
310 
311  to_frame = vlib_get_frame_to_node (vm, node_index);
312  to_next = vlib_frame_vector_args (to_frame);
313 
314  for (i = 0; i < n_buffers; i++)
315  {
316  vlib_buffer_t *b;
317  u32 bi0;
318  const ip46_address_t *dst = vrrp_adv_mcast_addr (vr);
319 
320  bi0 = vec_elt (bi, i);
321  b = vlib_get_buffer (vm, bi0);
322 
323  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
324  vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
325  vnet_buffer (b)->sw_if_index[VLIB_TX] = vr->config.sw_if_index;
326 
327  if (is_unicast)
328  {
330  vnet_buffer (b)->sw_if_index[VLIB_TX] = ~0;
331  }
332  else
334 
335  vrrp_adv_l3_build (vr, b, dst);
336  vrrp_adv_payload_build (vr, b, shutdown);
337 
339 
340  to_next[i] = bi0;
341  }
342 
343  to_frame->n_vectors = n_buffers;
344 
345  vlib_put_frame_to_node (vm, node_index, to_frame);
346 
347  vec_free (bi);
348 
349  return 0;
350 }
351 
352 static void
353 vrrp6_na_pkt_build (vrrp_vr_t * vr, vlib_buffer_t * b, ip6_address_t * addr6)
354 {
355  vnet_main_t *vnm = vnet_get_main ();
357  ethernet_header_t *eth;
358  ip6_header_t *ip6;
359  icmp6_neighbor_solicitation_or_advertisement_header_t *na;
360  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *ll_opt;
361  int payload_length, bogus_length;
362  int rewrite_bytes = 0;
363  u8 *rewrite;
364  u8 dst_mac[6];
365 
366  /* L2 headers */
367  eth = vlib_buffer_get_current (b);
368 
369  ip6_multicast_ethernet_address (dst_mac, IP6_MULTICAST_GROUP_ID_all_hosts);
370  rewrite =
372  dst_mac);
373  rewrite_bytes += vec_len (rewrite);
375  vec_free (rewrite);
376 
377  b->current_length += rewrite_bytes;
378  vlib_buffer_advance (b, rewrite_bytes);
379 
380  /* IPv6 */
382 
383  b->current_length += sizeof (*ip6);
384  clib_memset (ip6, 0, sizeof (*ip6));
385 
386  ip6->ip_version_traffic_class_and_flow_label = 0x00000060;
387  ip6->protocol = IP_PROTOCOL_ICMP6;
388  ip6->hop_limit = 255;
390  IP6_MULTICAST_SCOPE_link_local,
391  IP6_MULTICAST_GROUP_ID_all_hosts);
392  ip6_address_copy (&ip6->src_address,
394 
395 
396  /* ICMPv6 */
397  na = (icmp6_neighbor_solicitation_or_advertisement_header_t *) (ip6 + 1);
398  ll_opt =
399  (icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *) (na +
400  1);
401 
402  payload_length = sizeof (*na) + sizeof (*ll_opt);
403  b->current_length += payload_length;
404  clib_memset (na, 0, payload_length);
405 
406  na->icmp.type = ICMP6_neighbor_advertisement; /* icmp code, csum are 0 */
407  na->target_address = *addr6;
408  na->advertisement_flags = clib_host_to_net_u32
411 
412  ll_opt->header.type =
413  ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
414  ll_opt->header.n_data_u64s = 1;
415  clib_memcpy (ll_opt->ethernet_address, vr->runtime.mac.bytes,
416  sizeof (vr->runtime.mac));
417 
418  ip6->payload_length = clib_host_to_net_u16 (payload_length);
419  na->icmp.checksum =
420  ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus_length);
421 }
422 
424  .bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,},
425 };
426 
427 static void
429 {
430  vnet_main_t *vnm = vnet_get_main ();
431  ethernet_header_t *eth;
433  int rewrite_bytes;
434  u8 *rewrite;
435 
436  eth = vlib_buffer_get_current (b);
437 
438  rewrite =
441  rewrite_bytes = vec_len (rewrite);
442  clib_memcpy (eth, rewrite, rewrite_bytes);
443  vec_free (rewrite);
444 
445  b->current_length += rewrite_bytes;
446  vlib_buffer_advance (b, rewrite_bytes);
447 
448  arp = vlib_buffer_get_current (b);
449  b->current_length += sizeof (*arp);
450 
451  clib_memset (arp, 0, sizeof (*arp));
452 
453  arp->l2_type = clib_host_to_net_u16 (ETHERNET_ARP_HARDWARE_TYPE_ethernet);
454  arp->l3_type = clib_host_to_net_u16 (ETHERNET_TYPE_IP4);
455  arp->n_l2_address_bytes = 6;
456  arp->n_l3_address_bytes = 4;
457  arp->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request);
458  arp->ip4_over_ethernet[0].mac = vr->runtime.mac;
459  arp->ip4_over_ethernet[0].ip4 = *ip4;
460  arp->ip4_over_ethernet[1].mac = broadcast_mac;
461  arp->ip4_over_ethernet[1].ip4 = *ip4;
462 }
463 
464 int
466 {
468  vrrp_main_t *vmp = &vrrp_main;
469  vlib_frame_t *to_frame;
470  u32 *bi = 0;
471  u32 n_buffers;
472  u32 *to_next;
473  int i;
474 
475  if (vec_len (vr->config.peer_addrs))
476  return 0; /* unicast is used in routed environments - don't garp */
477 
479  if (!n_buffers)
480  {
481  clib_warning ("Unable to send gratuitous ARP for VR %U - no addresses",
482  format_vrrp_vr_key, vr);
483  return -1;
484  }
485 
486  /* need to send a packet for each VR address */
487  vec_validate (bi, n_buffers - 1);
488 
489  if (vlib_buffer_alloc (vm, bi, n_buffers) != n_buffers)
490  {
491  clib_warning ("Buffer allocation failed for %U", format_vrrp_vr_key,
492  vr);
493  vec_free (bi);
494  return -1;
495  }
496 
498  to_frame->n_vectors = 0;
499  to_next = vlib_frame_vector_args (to_frame);
500 
501  for (i = 0; i < n_buffers; i++)
502  {
503  vlib_buffer_t *b;
504  ip46_address_t *addr;
505 
507  b = vlib_get_buffer (vm, bi[i]);
508 
509  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
510  vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
511  vnet_buffer (b)->sw_if_index[VLIB_TX] = vr->config.sw_if_index;
512 
513  if (vrrp_vr_is_ipv6 (vr))
514  vrrp6_na_pkt_build (vr, b, &addr->ip6);
515  else
516  vrrp4_garp_pkt_build (vr, b, &addr->ip4);
517 
519 
520  to_next[i] = bi[i];
521  to_frame->n_vectors++;
522  }
523 
525 
526  return 0;
527 }
528 
529 #define IGMP4_MCAST_ADDR_AS_U8 { 224, 0, 0, 22 }
530 
531 static const ip4_header_t igmp_ip4_mcast = {
532  .ip_version_and_header_length = 0x46, /* there's options! */
533  .ttl = 1,
534  .protocol = IP_PROTOCOL_IGMP,
535  .tos = 0xc0,
536  .dst_address = {.as_u8 = IGMP4_MCAST_ADDR_AS_U8,},
537 };
538 
539 static void
541 {
542  ip4_header_t *ip4;
543  u8 *ip4_options;
546  ip4_address_t *src4;
547 
549  clib_memcpy (ip4, &igmp_ip4_mcast, sizeof (*ip4));
550 
551  /* Use the source address advertisements will use to join mcast group */
553  ip4->src_address.as_u32 = src4->as_u32;
554 
556  vlib_buffer_advance (b, sizeof (*ip4));
557 
558  ip4_options = (u8 *) (ip4 + 1);
559  ip4_options[0] = 0x94; /* 10010100 == the router alert option */
560  ip4_options[1] = 0x04; /* length == 4 bytes */
561  ip4_options[2] = 0x0; /* value == Router shall examine packet */
562  ip4_options[3] = 0x0; /* reserved */
563 
565  vlib_buffer_advance (b, 4);
566 
567  report = vlib_buffer_get_current (b);
568 
569  report->header.type = IGMP_TYPE_membership_report_v3;
570  report->header.code = 0;
571  report->header.checksum = 0;
572  report->unused = 0;
573  report->n_groups = clib_host_to_net_u16 (1);
574 
575  vlib_buffer_chain_increase_length (b, b, sizeof (*report));
576  vlib_buffer_advance (b, sizeof (*report));
577 
578  group = vlib_buffer_get_current (b);
579  group->type = IGMP_MEMBERSHIP_GROUP_change_to_exclude;
580  group->n_aux_u32s = 0;
581  group->n_src_addresses = 0;
582  group->group_address.as_u32 = clib_host_to_net_u32 (0xe0000012);
583 
584  vlib_buffer_chain_increase_length (b, b, sizeof (*group));
585  vlib_buffer_advance (b, sizeof (*group));
586 
587  ip4->length = clib_host_to_net_u16 (b->current_data);
588  ip4->checksum = ip4_header_checksum (ip4);
589 
590  int payload_len = vlib_buffer_get_current (b) - ((void *) report);
591  report->header.checksum =
592  ~ip_csum_fold (ip_incremental_checksum (0, report, payload_len));
593 
595 }
596 
597 /* multicast listener report packet format for ethernet. */
598 typedef CLIB_PACKED (struct
599  {
600  ip6_hop_by_hop_ext_t ext_hdr;
601  ip6_router_alert_option_t alert;
602  ip6_padN_option_t pad;
603  icmp46_header_t icmp;
604  u16 rsvd;
605  u16 num_addr_records;
606  icmp6_multicast_address_record_t records[0];
607  }) icmp6_multicast_listener_report_header_t;
608 
609 static void
610 vrrp_icmp6_mlr_pkt_build (vrrp_vr_t * vr, vlib_buffer_t * b)
611 {
613  ip6_header_t *ip6;
614  icmp6_multicast_listener_report_header_t *rh;
615  icmp6_multicast_address_record_t *rr;
616  ip46_address_t *vr_addr;
617  int bogus_length, n_addrs;
618  u16 payload_length;
619 
620  n_addrs = vec_len (vr->config.vr_addrs) + 1;
621  payload_length = sizeof (*rh) + (n_addrs * sizeof (*rr));
622  b->current_length = sizeof (*ip6) + payload_length;
623  b->error = ICMP6_ERROR_NONE;
624 
626  rh = (icmp6_multicast_listener_report_header_t *) (ip6 + 1);
627  rr = (icmp6_multicast_address_record_t *) (rh + 1);
628 
629  /* IP header */
631  ip6->ip_version_traffic_class_and_flow_label =
632  clib_host_to_net_u32 (0x60000000);
633  ip6->hop_limit = 1;
634  ip6->protocol = IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS;
636  IP6_MULTICAST_SCOPE_link_local,
637  IP6_MULTICAST_GROUP_ID_mldv2_routers);
638  ip6_address_copy (&ip6->src_address,
640 
641  clib_memset (rh, 0, sizeof (*rh));
642 
643  /* v6 hop by hop extension header */
644  rh->ext_hdr.next_hdr = IP_PROTOCOL_ICMP6;
645  rh->ext_hdr.n_data_u64s = 0;
646 
647  rh->alert.type = IP6_MLDP_ALERT_TYPE;
648  rh->alert.len = 2;
649  rh->alert.value = 0;
650 
651  rh->pad.type = 1;
652  rh->pad.len = 0;
653 
654  /* icmp6 header */
655  rh->icmp.type = ICMP6_multicast_listener_report_v2;
656  rh->icmp.checksum = 0;
657 
658  rh->rsvd = 0;
659  rh->num_addr_records = clib_host_to_net_u16 (n_addrs);
660 
661  /* group addresses */
662 
663  /* All VRRP routers group */
664  rr->type = 4;
665  rr->aux_data_len_u32s = 0;
666  rr->num_sources = 0;
668  (&rr->mcast_addr, &vrrp6_mcast_addr.ip6, sizeof (ip6_address_t));
669 
670  /* solicited node multicast addresses for VR addrs */
671  vec_foreach (vr_addr, vr->config.vr_addrs)
672  {
673  u32 id;
674 
675  rr++;
676  rr->type = 4;
677  rr->aux_data_len_u32s = 0;
678  rr->num_sources = 0;
679 
680  id = clib_net_to_host_u32 (vr_addr->ip6.as_u32[3]) & 0x00ffffff;
681  ip6_set_solicited_node_multicast_address (&rr->mcast_addr, id);
682  }
683 
684  ip6->payload_length = clib_host_to_net_u16 (payload_length);
685  rh->icmp.checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6,
686  &bogus_length);
687 }
688 
689 int
691 {
693  vlib_buffer_t *b;
694  vlib_frame_t *f;
695  vnet_main_t *vnm = vnet_get_main ();
696  vrrp_intf_t *intf;
697  u32 bi = 0, *to_next;
698  int n_buffers = 1;
699  u8 is_ipv6;
700  u32 node_index;
701 
703  return 0;
704 
705  is_ipv6 = vrrp_vr_is_ipv6 (vr);
706 
707  if (is_ipv6 && ip6_link_is_enabled (vr->config.sw_if_index) == 0)
708  return 0;
709 
710  if (vlib_buffer_alloc (vm, &bi, n_buffers) != n_buffers)
711  {
712  clib_warning ("Buffer allocation failed for %U", format_vrrp_vr_key,
713  vr);
714  return -1;
715  }
716 
717  b = vlib_get_buffer (vm, bi);
718 
719  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
720 
721  vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
722  vnet_buffer (b)->sw_if_index[VLIB_TX] = vr->config.sw_if_index;
723 
724  intf = vrrp_intf_get (vr->config.sw_if_index);
725  vnet_buffer (b)->ip.adj_index[VLIB_TX] = intf->mcast_adj_index[is_ipv6];
726 
727  if (is_ipv6)
728  {
729  vrrp_icmp6_mlr_pkt_build (vr, b);
731  }
732  else
733  {
734  vrrp_igmp_pkt_build (vr, b);
736  }
737 
739  to_next = vlib_frame_vector_args (f);
740  to_next[0] = bi;
741  f->n_vectors = 1;
742 
744 
745  return f->n_vectors;
746 }
747 
748 
749 /*
750  * fd.io coding-style-patch-verification: ON
751  *
752  * Local Variables:
753  * eval: (c-set-style "gnu")
754  * End:
755  */
ip4_lookup_node
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:105
vlib_frame_t::n_vectors
u16 n_vectors
Definition: node.h:387
adj.h
ethernet_arp_header_t::opcode
u16 opcode
Definition: arp_packet.h:139
vrrp_vr
Definition: vrrp.h:106
vrrp_vr::config
vrrp_vr_config_t config
Definition: vrrp.h:108
IGMP4_MCAST_ADDR_AS_U8
#define IGMP4_MCAST_ADDR_AS_U8
Definition: vrrp_packet.c:529
ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
ip6_multicast_ethernet_address
static void ip6_multicast_ethernet_address(u8 *ethernet_address, u32 group_id)
Definition: ip6_packet.h:156
ethernet_build_rewrite
u8 * ethernet_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
build a rewrite string to use for sending packets of type 'link_type' to 'dst_address'
Definition: interface.c:83
n_buffers
u32 n_buffers
Definition: interface_output.c:421
is_ipv6
bool is_ipv6
Definition: dhcp.api:202
igmp_membership_group_v3_t::type
igmp_membership_group_v3_type_t type
Definition: igmp_packet.h:149
vlib_buffer_chain_increase_length
static void vlib_buffer_chain_increase_length(vlib_buffer_t *first, vlib_buffer_t *last, i32 len)
Definition: buffer_funcs.h:1391
vrrp_vr_config::vr_addrs
ip46_address_t * vr_addrs
Definition: vrrp.h:76
igmp_ip4_mcast
static const ip4_header_t igmp_ip4_mcast
Definition: vrrp_packet.c:531
igmp_header_t::code
u8 code
Definition: igmp_packet.h:72
VRRP6_MCAST_ADDR_AS_U8
#define VRRP6_MCAST_ADDR_AS_U8
Definition: vrrp_packet.c:78
ip6_tcp_udp_icmp_compute_checksum
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:1096
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
ip4
vl_api_ip4_address_t ip4
Definition: one.api:376
vrrp_vr_config::peer_addrs
ip46_address_t * peer_addrs
Definition: vrrp.h:77
vlib_get_buffer
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
f
vlib_frame_t * f
Definition: interface_output.c:1098
format_vrrp_vr_key
u8 * format_vrrp_vr_key(u8 *s, va_list *args)
Definition: vrrp_format.c:65
ethernet_header_t::src_address
u8 src_address[6]
Definition: packet.h:56
igmp_header_t::type
igmp_type_t type
Definition: igmp_packet.h:70
broadcast_mac
const mac_address_t broadcast_mac
Definition: vrrp_packet.c:423
adj_mcast.h
ip4_address_t::as_u32
u32 as_u32
Definition: ip4_packet.h:57
mfib_entry.h
ethernet_arp_header_t::ip4_over_ethernet
ethernet_arp_ip4_over_ethernet_address_t ip4_over_ethernet[2]
Definition: arp_packet.h:142
igmp_packet.h
fib_table.h
u16
unsigned short u16
Definition: types.h:57
igmp_header_t::checksum
u16 checksum
Definition: igmp_packet.h:74
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
vrrp_vr::runtime
vrrp_vr_runtime_t runtime
Definition: vrrp.h:109
node_index
node node_index
Definition: interface_output.c:440
vrrp_vr_is_ipv6
static u8 vrrp_vr_is_ipv6(vrrp_vr_t *vr)
Definition: vrrp.h:312
VNET_LINK_ARP
@ VNET_LINK_ARP
Definition: interface.h:351
igmp_membership_report_v3_t
Definition: igmp_packet.h:179
igmp_membership_report_v3_t::n_groups
u16 n_groups
Definition: igmp_packet.h:187
igmp_membership_group_v3_t::n_src_addresses
u16 n_src_addresses
Definition: igmp_packet.h:155
vrrp_adv_l2_build_multicast
static int vrrp_adv_l2_build_multicast(vrrp_vr_t *vr, vlib_buffer_t *b)
Definition: vrrp_packet.c:32
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
vlib_frame_t
Definition: node.h:372
vlib_get_frame_to_node
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:184
vrrp_adv_mcast_addr
const static_always_inline ip46_address_t * vrrp_adv_mcast_addr(vrrp_vr_t *vr)
Definition: vrrp_packet.c:270
vrrp_adv_csum
u16 vrrp_adv_csum(void *l3_hdr, void *payload, u8 is_ipv6, u16 len)
Definition: vrrp_packet.c:150
ip4_rewrite_mcast_node
vlib_node_registration_t ip4_rewrite_mcast_node
(constructor) VLIB_REGISTER_NODE (ip4_rewrite_mcast_node)
Definition: ip4_forward.c:2619
ip6_lookup_node
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
Definition: ip6_forward.c:739
vrrp4_garp_pkt_build
static void vrrp4_garp_pkt_build(vrrp_vr_t *vr, vlib_buffer_t *b, ip4_address_t *ip4)
Definition: vrrp_packet.c:428
vrrp_vr_is_unicast
static u8 vrrp_vr_is_unicast(vrrp_vr_t *vr)
Definition: vrrp.h:318
ip4_header_t
Definition: ip4_packet.h:87
vec_elt
#define vec_elt(v, i)
Get vector value at index i.
Definition: vec_bootstrap.h:210
vrrp_adv_send
int vrrp_adv_send(vrrp_vr_t *vr, int shutdown)
Definition: vrrp_packet.c:279
ethernet_arp_header_t
Definition: arp_packet.h:133
vlib_buffer_t::current_data
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
vlib_put_frame_to_node
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:218
vrrp_intf_t
Definition: vrrp.h:127
vlib_buffer_advance
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:276
ip_interface_get_first_ip
void * ip_interface_get_first_ip(u32 sw_if_index, u8 is_ip4)
Definition: ip_interface.c:174
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
len
u8 len
Definition: ip_types.api:103
VNET_LINK_IP4
@ VNET_LINK_IP4
Definition: interface.h:344
vrrp_packet.h
vlib_buffer_alloc
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:702
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
src_addr
vl_api_mac_address_t src_addr
Definition: flow_types.api:64
ip6_set_solicited_node_multicast_address
static void ip6_set_solicited_node_multicast_address(ip6_address_t *a, u32 id)
Definition: ip6_packet.h:144
ip_incremental_checksum
static ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
Definition: ip_packet.h:319
igmp_membership_report_v3_t::unused
u16 unused
Definition: igmp_packet.h:184
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
vrrp6_dst_mac
static const u8 vrrp6_dst_mac[6]
Definition: vrrp_packet.c:28
static_always_inline
#define static_always_inline
Definition: clib.h:112
ip6_rewrite_mcast_node
vlib_node_registration_t ip6_rewrite_mcast_node
(constructor) VLIB_REGISTER_NODE (ip6_rewrite_mcast_node)
Definition: ip6_forward.c:2227
vrrp.h
uword
u64 uword
Definition: types.h:112
vrrp_adv_l3_build
static int vrrp_adv_l3_build(vrrp_vr_t *vr, vlib_buffer_t *b, const ip46_address_t *dst)
Definition: vrrp_packet.c:99
ethernet_header_t
Definition: packet.h:52
clib_mem_unaligned
#define clib_mem_unaligned(pointer, type)
Definition: types.h:155
vrrp_vr_multicast_group_join
int vrrp_vr_multicast_group_join(vrrp_vr_t *vr)
Definition: vrrp_packet.c:690
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
mac_address_t_::bytes
u8 bytes[6]
Definition: mac_address.h:25
vrrp_main_t
Definition: vrrp.h:145
ip4_address_t
Definition: ip4_packet.h:50
ip6_address_copy
static void ip6_address_copy(ip6_address_t *dst, const ip6_address_t *src)
Definition: ip6_packet.h:127
mfib_table.h
igmp_membership_group_v3_t::n_aux_u32s
u8 n_aux_u32s
Definition: igmp_packet.h:152
vlib_buffer_t::current_length
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
VRRP4_MCAST_ADDR_AS_U8
#define VRRP4_MCAST_ADDR_AS_U8
Definition: vrrp_packet.c:77
ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER
vrrp_vr_runtime::mac
mac_address_t mac
Definition: vrrp.h:100
plugin.h
ip6_set_reserved_multicast_address
static void ip6_set_reserved_multicast_address(ip6_address_t *a, ip6_multicast_address_scope_t scope, u16 id)
Definition: ip6_packet.h:134
id
u8 id[64]
Definition: dhcp.api:160
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
ethernet_arp_header_t::n_l2_address_bytes
u8 n_l2_address_bytes
Definition: arp_packet.h:137
fib_sas.h
icmp
icmp
Definition: map.api:387
vrrp_vr_config::vr_id
u8 vr_id
Definition: vrrp.h:72
vrrp_src_mac_prefix
static const u8 vrrp_src_mac_prefix[4]
Definition: vrrp_packet.c:29
vrrp6_na_pkt_build
static void vrrp6_na_pkt_build(vrrp_vr_t *vr, vlib_buffer_t *b, ip6_address_t *addr6)
Definition: vrrp_packet.c:353
igmp_membership_group_v3_t
Definition: igmp_packet.h:147
u64
unsigned long u64
Definition: types.h:89
ip_csum_with_carry
static ip_csum_t ip_csum_with_carry(ip_csum_t sum, ip_csum_t x)
Definition: ip_packet.h:248
u32
unsigned int u32
Definition: types.h:88
ip6
vl_api_ip6_address_t ip6
Definition: one.api:424
vrrp4_dst_mac
static const u8 vrrp4_dst_mac[6]
Definition: vrrp_packet.c:27
n_bytes
u32 n_bytes
Definition: interface_output.c:421
vrrp4_mcast_addr
static const ip46_address_t vrrp4_mcast_addr
Definition: vrrp_packet.c:81
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
vrrp_vr_config::adv_interval
u16 adv_interval
Definition: vrrp.h:74
IP6_MLDP_ALERT_TYPE
#define IP6_MLDP_ALERT_TYPE
ip6_header_t
Definition: ip6_packet.h:294
ethernet_arp_header_t::l3_type
u16 l3_type
Definition: arp_packet.h:136
mac_address_t_
Definition: mac_address.h:21
ethernet_arp_header_t::l2_type
u16 l2_type
Definition: arp_packet.h:135
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
ip4_header_t::ip_version_and_header_length
u8 ip_version_and_header_length
Definition: ip4_packet.h:93
vnet_link_t
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
vrrp_igmp_pkt_build
static void vrrp_igmp_pkt_build(vrrp_vr_t *vr, vlib_buffer_t *b)
Definition: vrrp_packet.c:540
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
VNET_LINK_IP6
@ VNET_LINK_IP6
Definition: interface.h:348
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
ip4_header_checksum
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:314
ip_csum_t
uword ip_csum_t
Definition: ip_packet.h:245
arp_packet.h
i
int i
Definition: flowhash_template.h:376
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
vnet_sw_interface_is_up
static uword vnet_sw_interface_is_up(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:339
pad
u8 pad[3]
log2 (size of the packing page block)
Definition: bihash_doc.h:61
vrrp_vr_config::sw_if_index
u32 sw_if_index
Definition: vrrp.h:71
vrrp_main_t::intf_output_node_idx
u32 intf_output_node_idx
Definition: vrrp.h:175
vnet.h
proto
vl_api_ip_proto_t proto
Definition: acl_types.api:51
vlib_buffer_reset
static void vlib_buffer_reset(vlib_buffer_t *b)
Reset current header & length to state they were in when packet was received.
Definition: buffer.h:305
igmp_membership_report_v3_t::header
igmp_header_t header
Definition: igmp_packet.h:182
rewrite
rewrite
Definition: pnat.api:158
vrrp_garp_or_na_send
int vrrp_garp_or_na_send(vrrp_vr_t *vr)
Definition: vrrp_packet.c:465
ip_csum_fold
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:301
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
vrrp_vr_priority
static u8 vrrp_vr_priority(vrrp_vr_t *vr)
Definition: vrrp.h:356
vrrp_intf_get
static vrrp_intf_t * vrrp_intf_get(u32 sw_if_index)
Definition: vrrp.h:289
vrrp_main
vrrp_main_t vrrp_main
Definition: vrrp.c:25
vrrp_adv_payload_build
static int vrrp_adv_payload_build(vrrp_vr_t *vr, vlib_buffer_t *b, int shutdown)
Definition: vrrp_packet.c:192
vrrp_adv_payload_len
static u16 vrrp_adv_payload_len(vrrp_vr_t *vr)
Definition: vrrp_packet.c:91
vrrp_adv_next_node
static_always_inline u32 vrrp_adv_next_node(vrrp_vr_t *vr)
Definition: vrrp_packet.c:252
CLIB_PACKED
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: vrrp_packet.c:598
vrrp_intf_t::mcast_adj_index
adj_index_t mcast_adj_index[2]
Definition: vrrp.h:138
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vrrp6_mcast_addr
static const ip46_address_t vrrp6_mcast_addr
Definition: vrrp_packet.c:85
ethernet_arp_header_t::n_l3_address_bytes
u8 n_l3_address_bytes
Definition: arp_packet.h:138
igmp_membership_group_v3_t::group_address
ip4_address_t group_address
Definition: igmp_packet.h:158
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111