FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  * node.c - vrrp packet handling node definitions
3  *
4  * Copyright 2019-2020 Rubicon Communications, LLC (Netgate)
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  */
9 #include <vlib/vlib.h>
10 #include <vlibmemory/api.h>
11 #include <vnet/vnet.h>
12 #include <vnet/ip/ip4_packet.h>
13 #include <vnet/ip/ip6_link.h>
15 #include <vnet/fib/fib_sas.h>
16 #include <vppinfra/error.h>
17 #include <vrrp/vrrp.h>
18 #include <vrrp/vrrp_packet.h>
19 
20 typedef struct
21 {
24  vrrp_header_t vrrp;
25  u8 addrs[256]; /* print up to 64 IPv4 or 16 IPv6 addresses */
26 } vrrp_trace_t;
27 
28 /* packet trace format function */
29 static u8 *
30 format_vrrp_trace (u8 * s, va_list * args)
31 {
32  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
33  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
34  vrrp_trace_t *t = va_arg (*args, vrrp_trace_t *);
35  int i;
36 
37  s = format (s, "VRRP: sw_if_index %d IPv%d\n",
38  t->sw_if_index, (t->is_ipv6) ? 6 : 4);
39  s = format (s, " %U\n", format_vrrp_packet_hdr, &t->vrrp);
40  s = format (s, " addresses: ");
41 
42  for (i = 0; i < t->vrrp.n_addrs; i++)
43  {
44  if (t->is_ipv6)
45  s = format (s, "%U ", format_ip6_address,
46  (ip6_address_t *) (t->addrs + i * 16));
47  else
48  s = format (s, "%U ", format_ip4_address,
49  (ip4_address_t *) (t->addrs + i * 4));
50  }
51 
52  return s;
53 }
54 
59 
60 #define foreach_vrrp_error \
61 _(RECEIVED, "VRRP packets processed") \
62 _(BAD_TTL, "VRRP advertisement TTL is not 255") \
63 _(NOT_VERSION_3, "VRRP version is not 3") \
64 _(INCOMPLETE_PKT, "VRRP packet has wrong size") \
65 _(BAD_CHECKSUM, "VRRP checksum is invalid") \
66 _(UNKNOWN_VR, "VRRP message does not match known VRs") \
67 _(ADDR_MISMATCH, "VR addrs do not match configuration")
68 
69 typedef enum
70 {
71 #define _(sym,str) VRRP_ERROR_##sym,
73 #undef _
75 } vrrp_error_t;
76 
77 static char *vrrp_error_strings[] = {
78 #define _(sym,string) string,
80 #undef _
81 };
82 
83 typedef enum
84 {
87 } vrrp_next_t;
88 
90 {
92  vrrp_header_t *pkt;
94 
95 /* Given a VR and a pointer to the VRRP header of an incoming packet,
96  * compare the local src address to the peers. Return < 0 if the local
97  * address < the peer address, 0 if they're equal, > 0 if
98  * the local address > the peer address
99  */
100 static int
101 vrrp_vr_addr_cmp (vrrp_vr_t * vr, vrrp_header_t * pkt)
102 {
103  vrrp_vr_config_t *vrc = &vr->config;
104  void *peer_addr, *local_addr;
105  ip46_address_t addr;
106  int addr_size;
107 
108  clib_memset (&addr, 0, sizeof (addr));
109 
110  if (vrrp_vr_is_ipv6 (vr))
111  {
112  peer_addr = &(((ip6_header_t *) pkt) - 1)->src_address;
113  local_addr = &addr.ip6;
114  addr_size = 16;
115  ip6_address_copy (local_addr,
117  }
118  else
119  {
120  peer_addr = &(((ip4_header_t *) pkt) - 1)->src_address;
121  local_addr = &addr.ip4;
122  addr_size = 4;
123  fib_sas4_get (vrc->sw_if_index, NULL, local_addr);
124  }
125 
126  return memcmp (local_addr, peer_addr, addr_size);
127 }
128 
129 static void
130 vrrp_input_process_master (vrrp_vr_t * vr, vrrp_header_t * pkt)
131 {
132  /* received priority 0, another VR is shutting down. send an adv and
133  * remain in the master state
134  */
135  if (pkt->priority == 0)
136  {
137  clib_warning ("Received shutdown message from a peer on VR %U",
138  format_vrrp_vr_key, vr);
139  vrrp_adv_send (vr, 0);
141  return;
142  }
143 
144  /* if either:
145  * - received priority > adjusted priority, or
146  * - received priority == adjusted priority and peer addr > local addr
147  * allow the local VR to be preempted by the peer
148  */
149  if ((pkt->priority > vrrp_vr_priority (vr)) ||
150  ((pkt->priority == vrrp_vr_priority (vr)) &&
151  (vrrp_vr_addr_cmp (vr, pkt) < 0)))
152  {
153  vrrp_vr_transition (vr, VRRP_VR_STATE_BACKUP, pkt);
154 
155  return;
156  }
157 
158  /* if we made it this far, eiher received prority < adjusted priority or
159  * received == adjusted and local addr > peer addr. Ignore.
160  */
161  return;
162 }
163 
164 /* RFC 5798 section 6.4.2 */
165 static void
166 vrrp_input_process_backup (vrrp_vr_t * vr, vrrp_header_t * pkt)
167 {
168  vrrp_vr_config_t *vrc = &vr->config;
169  vrrp_vr_runtime_t *vrt = &vr->runtime;
170 
171  /* master shutting down, ready for election */
172  if (pkt->priority == 0)
173  {
174  clib_warning ("Master for VR %U is shutting down", format_vrrp_vr_key,
175  vr);
176  vrt->master_down_int = vrt->skew;
178  return;
179  }
180 
181  /* no preempt set or adv from a higher priority router, update timers */
182  if (!(vrc->flags & VRRP_VR_PREEMPT) ||
183  (pkt->priority >= vrrp_vr_priority (vr)))
184  {
185  vrt->master_adv_int = clib_net_to_host_u16 (pkt->rsvd_and_max_adv_int);
186  vrt->master_adv_int &= ((u16) 0x0fff); /* ignore rsvd bits */
187 
191  return;
192  }
193 
194  /* preempt set or our priority > received, continue to wait on master down */
195  return;
196 }
197 
198 always_inline void
200 {
201  vrrp_vr_t *vr;
202 
203  vr = vrrp_vr_lookup_index (args->vr_index);
204 
205  if (!vr)
206  {
207  clib_warning ("Error retrieving VR with index %u", args->vr_index);
208  return;
209  }
210 
211  switch (vr->runtime.state)
212  {
213  case VRRP_VR_STATE_INIT:
214  return;
215  case VRRP_VR_STATE_BACKUP:
216  /* this is usually the only state an advertisement should be received */
217  vrrp_input_process_backup (vr, args->pkt);
218  break;
219  case VRRP_VR_STATE_MASTER:
220  /* might be getting preempted. or have a misbehaving peer */
221  clib_warning ("Received advertisement for master VR %U",
222  format_vrrp_vr_key, vr);
223  vrrp_input_process_master (vr, args->pkt);
224  break;
225  default:
226  clib_warning ("Received advertisement for VR %U in unknown state %d",
227  format_vrrp_vr_key, vr, vr->runtime.state);
228  break;
229  }
230 
231  return;
232 }
233 
234 typedef struct
235 {
236  ip46_address_t ip;
241 
242 
243 static u8 *
245 {
246  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
247  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
248  vrrp_arp_nd_trace_t *t = va_arg (*va, vrrp_arp_nd_trace_t *);
249 
250  s = format (s, "address %U",
252  (t->is_ipv6) ? (void *) &t->ip.ip6 : (void *) &t->ip.ip4);
253 
254  if (t->vr_index != ~0)
255  s = format (s, ": vr_index %u vr_id %u", t->vr_index, t->vr_id);
256 
257  return s;
258 }
259 
260 typedef enum
261 {
266 
267 typedef enum
268 {
273 
276  u8 is_ipv6)
277 {
278  vnet_main_t *vnm = vnet_get_main ();
280  ethernet_header_t *eth, *eth_new;
281  void *lookup_addr = 0;
282  vrrp_vr_t *vr;
284  vnet_link_t link_type;
285  u8 *rewrite, rewrite_len;
286  int bogus_length;
287  /* ND vars */
288  ip6_header_t *ip6 = 0;
289  icmp6_neighbor_solicitation_or_advertisement_header_t *sol_adv = 0;
290  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *lladdr = 0;
291  /* ARP vars */
293  ip4_address_t ip4_addr;
294 
295  if (is_ipv6)
296  {
298 
299  /* we only care about about ICMP6 neighbor solicitiations */
300  if (ip6->protocol != IP_PROTOCOL_ICMP6)
301  return;
302 
303  sol_adv = ip6_next_header (ip6);
304  lladdr = (void *) (sol_adv + 1);
305 
306  /* skip anything other than neighbor solicitations */
307  if (sol_adv->icmp.type != ICMP6_neighbor_solicitation)
308  return;
309 
310  lookup_addr = &sol_adv->target_address;
311  link_type = VNET_LINK_IP6;
312  }
313  else
314  {
315  arp = vlib_buffer_get_current (b);
316 
317  /* skip non-request packets */
318  if (arp->opcode != clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request))
319  return;
320 
321  lookup_addr = &arp->ip4_over_ethernet[1].ip4;
322  link_type = VNET_LINK_ARP;
323  }
324 
325  sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
326 
327  /* Don't bother with a hash lookup if no VRs configured on this interface */
329  return;
330 
331  /* skip requests that are not for VRRP addresses */
332  *vr_index = vrrp_vr_lookup_address (sw_if_index, is_ipv6, lookup_addr);
333  if (*vr_index == ~0)
334  return;
335 
336  vr = vrrp_vr_lookup_index (*vr_index);
337  if (!vr || vr->runtime.state != VRRP_VR_STATE_MASTER)
338  {
339  /* RFC 5798 - section 6.4.2 - Backup "MUST NOT respond" to ARP/ND.
340  * So we must drop the request rather than allowing it to continue
341  * on the feature arc.
342  */
344  return;
345  }
346 
347  /* RFC 5798 section 6.4.3: Master "MUST respond" to ARP/ND. */
349  rewrite = ethernet_build_rewrite (vnm, sw_if_index, link_type,
350  eth->src_address);
351  rewrite_len = vec_len (rewrite);
352  if (rewrite_len == 0)
353  return;
354 
355  /* send the reply out the incoming interface */
357  vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
358 
359  /* the outbound ethernet & vlan headers may have a different length than
360  * the received header, so get a pointer to the new start of the packet
361  * and write the header there.
362  */
363  vlib_buffer_advance (b, -rewrite_len);
364  eth_new = vlib_buffer_get_current (b);
365  clib_memcpy_fast (eth_new, rewrite, rewrite_len);
366  vec_free (rewrite);
367 
368  if (is_ipv6)
369  {
370  if (ip6_address_is_unspecified (&ip6->src_address))
372  IP6_MULTICAST_SCOPE_link_local,
373  IP6_MULTICAST_GROUP_ID_all_hosts);
374  else
375  ip6->dst_address = ip6->src_address;
376 
377  ip6->src_address = sol_adv->target_address;
378  ip6->hop_limit = 255;
379  sol_adv->icmp.type = ICMP6_neighbor_advertisement;
380  sol_adv->icmp.checksum = 0;
381  sol_adv->advertisement_flags =
382  clib_host_to_net_u32 (ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER
385 
386  clib_memcpy (lladdr->ethernet_address, vr->runtime.mac.bytes,
387  sizeof (mac_address_t));
388  lladdr->header.type =
389  ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
390 
391  sol_adv->icmp.checksum =
392  ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus_length);
393 
394  }
395  else
396  {
397  ip4_addr = arp->ip4_over_ethernet[1].ip4;
398 
399  arp->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
400  arp->ip4_over_ethernet[1] = arp->ip4_over_ethernet[0];
401 
402  arp->ip4_over_ethernet[0].mac = vr->runtime.mac;
403  arp->ip4_over_ethernet[0].ip4 = ip4_addr;
404  }
405 }
406 
410 {
411  u32 n_left_from, *from, next_index, *to_next;
412 
414  n_left_from = frame->n_vectors;
415  next_index = node->cached_next_index;
416 
417  while (n_left_from > 0)
418  {
419  u32 n_left_to_next;
420 
421  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
422 
423  while (n_left_from > 0 && n_left_to_next > 0)
424  {
425 
426  vlib_buffer_t *b0;
427  u32 bi0;
428  u32 next0;
429  u32 vr_index = ~0;
430 
431  bi0 = from[0];
432  to_next[0] = bi0;
433  from += 1;
434  to_next += 1;
435  n_left_from -= 1;
436  n_left_to_next -= 1;
437 
438  b0 = vlib_get_buffer (vm, bi0);
439 
440  vnet_feature_next (&next0, b0);
441  vrrp_arp_nd_next (b0, &next0, &vr_index, is_ipv6);
442 
443  if (b0->flags & VLIB_BUFFER_IS_TRACED)
444  {
446  vlib_add_trace (vm, node, b0, sizeof (*t));
447  vrrp_vr_t *vr;
448 
449  if (is_ipv6)
450  {
451  ip6_header_t *ip0;
452  icmp6_neighbor_solicitation_or_advertisement_header_t
453  * sol_adv0;
454 
455  ip0 = vlib_buffer_get_current (b0);
456  sol_adv0 = ip6_next_header (ip0);
457  t->ip.ip6 = sol_adv0->target_address;
458  }
459  else
460  {
461  ethernet_arp_header_t *arp0;
462 
463  arp0 = vlib_buffer_get_current (b0);
464  t->ip.ip4 = arp0->ip4_over_ethernet[0].ip4;
465  }
466 
467  vr = vrrp_vr_lookup_index (vr_index);
468  if (vr)
469  t->vr_id = vr->config.vr_id;
470 
471  t->vr_index = vr_index;
472  t->is_ipv6 = is_ipv6;
473  }
474 
476  n_left_to_next, bi0, next0);
477  }
478 
479  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
480  }
481 
482  return frame->n_vectors;
483 }
484 
488 {
489  return vrrp_arp_nd_input_inline (vm, node, frame, 0 /* is_ipv6 */ );
490 }
491 
492 /* *INDENT-OFF* */
494 {
495  .name = "vrrp4-arp-input",
496  .vector_size = sizeof (u32),
497  .format_trace = format_vrrp_arp_nd_input_trace,
499 
500  .n_errors = ARRAY_LEN(vrrp_error_strings),
501  .error_strings = vrrp_error_strings,
502 
503  .n_next_nodes = VRRP_ARP_N_NEXT,
504 
505  .next_nodes = {
506  [VRRP_ARP_INPUT_NEXT_DROP] = "error-drop",
507  [VRRP_ARP_INPUT_NEXT_REPLY_TX] = "interface-output",
508  },
509 };
510 
511 VNET_FEATURE_INIT (vrrp4_arp_feat_node, static) =
512 {
513  .arc_name = "arp",
514  .node_name = "vrrp4-arp-input",
515  .runs_before = VNET_FEATURES ("arp-reply"),
516 };
517 
521 {
522  return vrrp_arp_nd_input_inline (vm, node, frame, 1 /* is_ipv6 */);
523 }
524 
525 /* *INDENT-OFF* */
527 {
528  .name = "vrrp6-nd-input",
529  .vector_size = sizeof (u32),
530  .format_trace = format_vrrp_arp_nd_input_trace,
532 
533  .n_errors = ARRAY_LEN(vrrp_error_strings),
534  .error_strings = vrrp_error_strings,
535 
536  .n_next_nodes = VRRP_ND_N_NEXT,
537 
538  .next_nodes = {
539  [VRRP_ND_INPUT_NEXT_DROP] = "error-drop",
540  [VRRP_ND_INPUT_NEXT_REPLY_TX] = "interface-output",
541  },
542 };
543 
544 VNET_FEATURE_INIT (vrrp6_nd_feat_node, static) =
545 {
546  .arc_name = "ip6-local",
547  .node_name = "vrrp6-nd-input",
548  .runs_before = VNET_FEATURES ("ip6-local-end-of-arc"),
549 };
550 
554 {
555  u32 n_left_from, *from;
556  vrrp_main_t *vmp = &vrrp_main;
557 
559  n_left_from = frame->n_vectors;
560 
561  while (n_left_from > 0)
562  {
563  u32 bi0;
564  vlib_buffer_t *b0;
565  u32 next0, error0;
566  void *ip0;
567  vrrp_header_t *vrrp0;
568  vrrp_vr_t *vr0;
570  u8 *ttl0;
571  u16 rx_csum0;
572  u16 payload_len0;
573  int addr_len;
574 
575  bi0 = from[0];
576  b0 = vlib_get_buffer (vm, bi0);
577 
578  ip0 = vlib_buffer_get_current (b0);
579 
580  if (is_ipv6)
581  {
582  ip6_header_t *ip6 = ip0;
583 
584  vrrp0 = (vrrp_header_t *) (ip6 + 1);
585  ttl0 = &ip6->hop_limit;
586  addr_len = 16;
587  payload_len0 = clib_net_to_host_u16 (ip6->payload_length);
588  vlib_buffer_advance (b0, sizeof (*ip6));
589  }
590  else
591  {
592  ip4_header_t *ip4 = ip0;
593 
594  vrrp0 = (vrrp_header_t *) (ip4 + 1);
595  ttl0 = &ip4->ttl;
596  addr_len = 4;
597  payload_len0 = clib_net_to_host_u16 (ip4->length) - sizeof(*ip4);
598  vlib_buffer_advance (b0, sizeof (*ip4));
599  }
600 
601  next0 = VRRP_INPUT_NEXT_DROP;
602 
603  error0 = VRRP_ERROR_RECEIVED;
604 
605  /* Validation from RFC 5798 sec 7.1 */
606 
607  /* checksum set to 0 for calculation, save original value */
608  rx_csum0 = vrrp0->checksum;
609  vrrp0->checksum = 0;
610 
611  /* Mandatory - TTL/hop limit must be 255 */
612  if (*ttl0 != 255)
613  {
614  error0 = VRRP_ERROR_BAD_TTL;
615  goto trace;
616  }
617 
618  /* Mandatory - VRRP version must be 3 */
619  if ((vrrp0->vrrp_version_and_type >> 4) != 3)
620  {
621  error0 = VRRP_ERROR_NOT_VERSION_3;
622  goto trace;
623  }
624 
625  /* Mandatory - packet must be complete */
626  if (b0->current_length < sizeof (*vrrp0) +
627  ((u32) vrrp0->n_addrs) * addr_len)
628  {
629  error0 = VRRP_ERROR_INCOMPLETE_PKT;
630  goto trace;
631  }
632 
633  /* Mandatory - checksum must be correct */
634  if (rx_csum0 != vrrp_adv_csum (ip0, vrrp0, is_ipv6, payload_len0))
635  {
636  error0 = VRRP_ERROR_BAD_CHECKSUM;
637  goto trace;
638  }
639 
640  /* Mandatory - VR must be configured on the interface adv received on */
641  if (!(vr0 =
643  vrrp0->vr_id, is_ipv6)))
644  {
645  error0 = VRRP_ERROR_UNKNOWN_VR;
646  goto trace;
647  }
648 
649  /* Optional - count of addresses should match configuration */
650  /* Could also check that addresses match, but likely to be O(n^2) */
651  if (vrrp0->n_addrs != vec_len (vr0->config.vr_addrs))
652  {
653  error0 = VRRP_ERROR_ADDR_MISMATCH;
654  goto trace;
655  }
656 
657  /* signal main thread to process contents of packet */
658  args0.vr_index = vr0 - vmp->vrs;
659  args0.pkt = vrrp0;
660 
662  sizeof (args0));
663 
664  trace:
665  vrrp0->checksum = rx_csum0; /* restore csum for correct trace output */
666  b0->error = node->errors[error0];
667 
668  if (b0->flags & VLIB_BUFFER_IS_TRACED)
669  {
670  vrrp_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
671  size_t addr_len = (is_ipv6 ? 16 : 4);
672 
673  t->sw_if_index = vnet_buffer(b0)->sw_if_index[VLIB_RX];
674  t->is_ipv6 = is_ipv6;
675  clib_memcpy_fast (&t->vrrp, vrrp0, sizeof (*vrrp0));
676  clib_memcpy_fast (t->addrs, (void *) (vrrp0 + 1),
677  (size_t) vrrp0->n_addrs * addr_len);
678  }
679 
680  /* always drop, never forward or reply here */
681  vlib_set_next_frame_buffer (vm, node, next0, bi0);
682 
683  from += 1;
684  n_left_from -= 1;
685  }
686 
687  return frame->n_vectors;
688 }
689 
692 {
693  return vrrp_input_inline (vm, node, frame, 0);
694 }
695 
696 /* *INDENT-OFF* */
698 {
699  .name = "vrrp4-input",
700  .vector_size = sizeof (u32),
701  .format_trace = format_vrrp_trace,
703 
704  .n_errors = ARRAY_LEN(vrrp_error_strings),
705  .error_strings = vrrp_error_strings,
706 
707  .n_next_nodes = VRRP_INPUT_N_NEXT,
708 
709  .next_nodes = {
710  [VRRP_INPUT_NEXT_DROP] = "error-drop",
711  },
712 };
713 
716 {
717  return vrrp_input_inline (vm, node, frame, 1);
718 }
719 
721 {
722  .name = "vrrp6-input",
723  .vector_size = sizeof (u32),
724  .format_trace = format_vrrp_trace,
726 
727  .n_errors = ARRAY_LEN(vrrp_error_strings),
728  .error_strings = vrrp_error_strings,
729 
730  .n_next_nodes = VRRP_INPUT_N_NEXT,
731 
732  .next_nodes = {
733  [VRRP_INPUT_NEXT_DROP] = "error-drop",
734  },
735 };
736 
737 typedef struct
738 {
741  ip46_address_t src, dst;
743 
744 /* packet trace format function */
745 static u8 *
746 format_vrrp_accept_owner_trace (u8 * s, va_list * args)
747 {
748  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
749  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
751  int ip_ver = 4, ip_type = IP46_TYPE_IP4;
752 
753  if (t->is_ipv6)
754  {
755  ip_ver = 6;
756  ip_type = IP46_TYPE_IP6;
757  }
758 
759  s = format (s, "IPv%d sw_if_index %d %U -> %U",
760  ip_ver, t->sw_if_index,
761  format_ip46_address, &t->src, ip_type,
762  format_ip46_address, &t->dst, ip_type);
763 
764  return s;
765 }
766 
767 #define foreach_vrrp_accept_owner_error \
768 _(RECEIVED, "VRRP owner accept packets received") \
769 _(PROCESSED, "VRRP owner accept advertisements processed")
770 
771 typedef enum
772 {
773 #define _(sym,str) VRRP_ACCEPT_OWNER_ERROR_##sym,
775 #undef _
778 
780 #define _(sym,string) string,
782 #undef _
783 };
784 
785 typedef enum
786 {
790 
793  u32 *next_index, u32 *error)
794 {
796 
797  if (vr && (vr->runtime.state == VRRP_VR_STATE_MASTER) &&
798  (vr->config.flags & VRRP_VR_ACCEPT))
799  {
801  *error = VRRP_ACCEPT_OWNER_ERROR_PROCESSED;
802  }
803 }
804 
808 {
809  u32 n_left_from, *from, *to_next;
810  u32 next_index = node->cached_next_index;
811 
813  n_left_from = frame->n_vectors;
814 
815  while (n_left_from > 0)
816  {
817  u32 n_left_to_next;
818 
819  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
820 
821  while (n_left_from >= 2 && n_left_to_next >= 2)
822  {
823  u32 bi0, bi1;
824  vlib_buffer_t *b0, *b1;
825  u32 next0, next1;
826  u32 error0, error1;
827  vrrp_header_t *vrrp0, *vrrp1;
828  ip4_header_t *ip40, *ip41;
829  ip6_header_t *ip60, *ip61;
830  u32 sw_if_index0, sw_if_index1;
831 
832  bi0 = from[0];
833  bi1 = from[1];
834 
835  to_next[0] = bi0;
836  to_next[1] = bi1;
837 
838  b0 = vlib_get_buffer (vm, bi0);
839  b1 = vlib_get_buffer (vm, bi1);
840 
841  /* most packets will follow feature arc */
842  vnet_feature_next (&next0, b0);
843  vnet_feature_next (&next1, b1);
844 
845  error0 = error1 = VRRP_ACCEPT_OWNER_ERROR_RECEIVED;
846 
847  sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
848  sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_RX];
849 
850  /* find VRRP advertisements which should be sent to VRRP node */
851  if (is_ipv6)
852  {
853  ip60 = vlib_buffer_get_current (b0);
854  ip61 = vlib_buffer_get_current (b1);
855 
856  if (PREDICT_FALSE (ip60->protocol == IP_PROTOCOL_VRRP))
857  {
858  vrrp0 = (vrrp_header_t *) (ip60 + 1);
859  vrrp_accept_owner_next_node (sw_if_index0, vrrp0->vr_id,
860  is_ipv6, &next0, &error0);
861  }
862  if (PREDICT_FALSE (ip61->protocol == IP_PROTOCOL_VRRP))
863  {
864  vrrp1 = (vrrp_header_t *) (ip61 + 1);
865  vrrp_accept_owner_next_node (sw_if_index1, vrrp1->vr_id,
866  is_ipv6, &next1, &error1);
867  }
868  }
869  else
870  {
871  ip40 = vlib_buffer_get_current (b0);
872  ip41 = vlib_buffer_get_current (b1);
873 
874  if (PREDICT_FALSE (ip40->protocol == IP_PROTOCOL_VRRP))
875  {
876  vrrp0 = (vrrp_header_t *) (ip40 + 1);
877  vrrp_accept_owner_next_node (sw_if_index0, vrrp0->vr_id,
878  is_ipv6, &next0, &error0);
879  }
880  if (PREDICT_FALSE (ip41->protocol == IP_PROTOCOL_VRRP))
881  {
882  vrrp1 = (vrrp_header_t *) (ip41 + 1);
883  vrrp_accept_owner_next_node (sw_if_index1, vrrp1->vr_id,
884  is_ipv6, &next1, &error1);
885  }
886  }
887 
888  b0->error = node->errors[error0];
889  b1->error = node->errors[error1];
890 
891  if (b0->flags & VLIB_BUFFER_IS_TRACED)
892  {
894  vlib_add_trace (vm, node, b0, sizeof (*t));
895 
896  t->sw_if_index = sw_if_index0;
897  t->is_ipv6 = is_ipv6;
898  if (is_ipv6)
899  {
900  ip6_address_copy (&t->src.ip6, &ip60->src_address);
901  ip6_address_copy (&t->dst.ip6, &ip60->dst_address);
902  }
903  else
904  {
905  t->src.ip4.as_u32 = ip40->src_address.as_u32;
906  t->dst.ip4.as_u32 = ip40->dst_address.as_u32;
907  }
908  }
909 
910  if (b1->flags & VLIB_BUFFER_IS_TRACED)
911  {
913  vlib_add_trace (vm, node, b1, sizeof (*t));
914 
915  t->sw_if_index = sw_if_index1;
916  t->is_ipv6 = is_ipv6;
917  if (is_ipv6)
918  {
919  ip6_address_copy (&t->src.ip6, &ip61->src_address);
920  ip6_address_copy (&t->dst.ip6, &ip61->dst_address);
921  }
922  else
923  {
924  t->src.ip4.as_u32 = ip41->src_address.as_u32;
925  t->dst.ip4.as_u32 = ip41->dst_address.as_u32;
926  }
927  }
928 
929  from += 2;
930  n_left_from -= 2;
931  to_next += 2;
932  n_left_to_next -= 2;
933 
935  to_next, n_left_to_next,
936  bi0, bi1, next0, next1);
937  }
938 
939  while (n_left_from > 0 && n_left_to_next > 0)
940  {
941  u32 bi0;
942  vlib_buffer_t *b0;
943  u32 next0;
944  u32 error0;
945  vrrp_header_t *vrrp0;
946  ip4_header_t *ip4;
947  ip6_header_t *ip6;
948  u32 sw_if_index0;
949 
950  bi0 = from[0];
951  to_next[0] = bi0;
952 
953  b0 = vlib_get_buffer (vm, bi0);
954 
955  /* most packets will follow feature arc */
956  vnet_feature_next (&next0, b0);
957 
958  error0 = VRRP_ACCEPT_OWNER_ERROR_RECEIVED;
959 
960  sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
961 
962  /* find VRRP advertisements which should be sent to VRRP node */
963  if (is_ipv6)
964  {
966 
967  if (PREDICT_FALSE (ip6->protocol == IP_PROTOCOL_VRRP))
968  {
969  vrrp0 = (vrrp_header_t *) (ip6 + 1);
970  vrrp_accept_owner_next_node (sw_if_index0, vrrp0->vr_id,
971  is_ipv6, &next0, &error0);
972  }
973  }
974  else
975  {
977 
978  if (PREDICT_FALSE (ip4->protocol == IP_PROTOCOL_VRRP))
979  {
980  vrrp0 = (vrrp_header_t *) (ip4 + 1);
981  vrrp_accept_owner_next_node (sw_if_index0, vrrp0->vr_id,
982  is_ipv6, &next0, &error0);
983  }
984  }
985 
986  b0->error = node->errors[error0];
987 
988  if (b0->flags & VLIB_BUFFER_IS_TRACED)
989  {
991  vlib_add_trace (vm, node, b0, sizeof (*t));
992 
993  t->sw_if_index = sw_if_index0;
994  t->is_ipv6 = is_ipv6;
995  if (is_ipv6)
996  {
997  ip6_address_copy (&t->src.ip6, &ip6->src_address);
998  ip6_address_copy (&t->dst.ip6, &ip6->dst_address);
999  }
1000  else
1001  {
1002  t->src.ip4.as_u32 = ip4->src_address.as_u32;
1003  t->dst.ip4.as_u32 = ip4->dst_address.as_u32;
1004  }
1005  }
1006 
1007  from += 1;
1008  n_left_from -= 1;
1009  to_next += 1;
1010  n_left_to_next -= 1;
1011 
1013  to_next, n_left_to_next,
1014  bi0, next0);
1015  }
1016 
1017  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1018  }
1019 
1020  return frame->n_vectors;
1021 }
1022 
1025  vlib_frame_t * frame)
1026 {
1028 }
1029 
1031 {
1032  .name = "vrrp4-accept-owner-input",
1033  .vector_size = sizeof (u32),
1034  .format_trace = format_vrrp_accept_owner_trace,
1036 
1038  .error_strings = vrrp_accept_owner_error_strings,
1039 
1040  .n_next_nodes = VRRP_ACCEPT_OWNER_N_NEXT,
1041 
1042  .next_nodes = {
1043  [VRRP_ACCEPT_OWNER_NEXT_PROCESS] = "vrrp4-input",
1044  },
1045 };
1046 
1047 VNET_FEATURE_INIT (vrrp4_accept_owner_mc, static) =
1048 {
1049  .arc_name = "ip4-multicast",
1050  .node_name = "vrrp4-accept-owner-input",
1051  .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
1052 };
1053 
1056  vlib_frame_t * frame)
1057 {
1059 }
1060 
1062 {
1063  .name = "vrrp6-accept-owner-input",
1064  .vector_size = sizeof (u32),
1065  .format_trace = format_vrrp_accept_owner_trace,
1067 
1069  .error_strings = vrrp_accept_owner_error_strings,
1070 
1071  .n_next_nodes = VRRP_ACCEPT_OWNER_N_NEXT,
1072 
1073  .next_nodes = {
1074  [VRRP_ACCEPT_OWNER_NEXT_PROCESS] = "vrrp6-input",
1075  },
1076 };
1077 
1078 VNET_FEATURE_INIT (vrrp6_accept_owner_mc, static) =
1079 {
1080  .arc_name = "ip6-multicast",
1081  .node_name = "vrrp6-accept-owner-input",
1082  .runs_before = VNET_FEATURES ("ip6-mfib-forward-lookup"),
1083 };
1084 
1085 static clib_error_t *
1087 {
1089 
1091  return error;
1092 
1093  ip4_register_protocol (IP_PROTOCOL_VRRP, vrrp4_input_node.index);
1094  ip6_register_protocol (IP_PROTOCOL_VRRP, vrrp6_input_node.index);
1095 
1096  return 0;
1097 }
1098 
1100 
1101 /* *INDENT-ON* */
1102 
1103 /*
1104  * fd.io coding-style-patch-verification: ON
1105  *
1106  * Local Variables:
1107  * eval: (c-set-style "gnu")
1108  * End:
1109  */
vlib.h
vrrp4_accept_owner_input_node
vlib_node_registration_t vrrp4_accept_owner_input_node
(constructor) VLIB_REGISTER_NODE (vrrp4_accept_owner_input_node)
Definition: node.c:1030
vrrp6_accept_owner_input_node
vlib_node_registration_t vrrp6_accept_owner_input_node
(constructor) VLIB_REGISTER_NODE (vrrp6_accept_owner_input_node)
Definition: node.c:1061
trace
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
Definition: vlib_api_cli.c:899
api.h
vrrp_vr_config
Definition: vrrp.h:69
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
vrrp_input_process_master
static void vrrp_input_process_master(vrrp_vr_t *vr, vrrp_header_t *pkt)
Definition: node.c:130
vrrp_trace_t::sw_if_index
u32 sw_if_index
Definition: node.c:22
vrrp4_input_node
vlib_node_registration_t vrrp4_input_node
(constructor) VLIB_REGISTER_NODE (vrrp4_input_node)
Definition: node.c:697
ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
format_vrrp_trace
static u8 * format_vrrp_trace(u8 *s, va_list *args)
Definition: node.c:30
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
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
is_ipv6
bool is_ipv6
Definition: dhcp.api:202
vrrp_vr_config::vr_addrs
ip46_address_t * vr_addrs
Definition: vrrp.h:76
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:1098
format_ip4_address
format_function_t format_ip4_address
Definition: format.h:73
vrrp6_nd_input_node
vlib_node_registration_t vrrp6_nd_input_node
(constructor) VLIB_REGISTER_NODE (vrrp6_nd_input_node)
Definition: node.c:526
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
vrrp_adv_send
int vrrp_adv_send(vrrp_vr_t *vr, int shutdown)
Definition: vrrp_packet.c:272
ip4
vl_api_ip4_address_t ip4
Definition: one.api:376
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
format_vrrp_packet_hdr
u8 * format_vrrp_packet_hdr(u8 *s, va_list *args)
Definition: vrrp_format.c:124
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
vrrp_vr_runtime::master_down_int
u16 master_down_int
Definition: vrrp.h:99
VRRP_ND_N_NEXT
@ VRRP_ND_N_NEXT
Definition: node.c:271
format_vrrp_vr_key
u8 * format_vrrp_vr_key(u8 *s, va_list *args)
Definition: vrrp_format.c:65
ip6_header_t::protocol
u8 protocol
Definition: ip6_packet.h:304
ethernet_header_t::src_address
u8 src_address[6]
Definition: packet.h:56
VLIB_NODE_TYPE_INTERNAL
@ VLIB_NODE_TYPE_INTERNAL
Definition: node.h:72
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
IP46_TYPE_IP4
@ IP46_TYPE_IP4
Definition: ip46_address.h:26
ip4_address_t::as_u32
u32 as_u32
Definition: ip4_packet.h:57
ethernet_arp_header_t::ip4_over_ethernet
ethernet_arp_ip4_over_ethernet_address_t ip4_over_ethernet[2]
Definition: arp_packet.h:142
vrrp_vr_skew_compute
static void vrrp_vr_skew_compute(vrrp_vr_t *vr)
Definition: vrrp.h:214
u16
unsigned short u16
Definition: types.h:57
vrrp_input_process_args::vr_index
u32 vr_index
Definition: node.c:91
vrrp_arp_nd_trace_t::ip
ip46_address_t ip
Definition: node.c:236
vrrp_vr_config::flags
vrrp_vr_flags_t flags
Definition: vrrp.h:75
vlib_call_init_function
#define vlib_call_init_function(vm, x)
Definition: init.h:259
vrrp_input_process_args::pkt
vrrp_header_t * pkt
Definition: node.c:92
VRRP_VR_ACCEPT
@ VRRP_VR_ACCEPT
Definition: vrrp.h:24
vrrp_next_t
vrrp_next_t
Definition: node.c:83
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
vrrp_vr_is_ipv6
static u8 vrrp_vr_is_ipv6(vrrp_vr_t *vr)
Definition: vrrp.h:312
vrrp_vr_master_down_compute
static void vrrp_vr_master_down_compute(vrrp_vr_t *vr)
Definition: vrrp.h:223
VNET_LINK_ARP
@ VNET_LINK_ARP
Definition: interface.h:351
ip6_address_is_unspecified
static uword ip6_address_is_unspecified(const ip6_address_t *a)
Definition: ip6_packet.h:237
vrrp_error_strings
static char * vrrp_error_strings[]
Definition: node.c:77
foreach_vrrp_error
#define foreach_vrrp_error
Definition: node.c:60
vrrp_vr_transition
void vrrp_vr_transition(vrrp_vr_t *vr, vrrp_vr_state_t new_state, void *data)
Definition: vrrp.c:282
ip4_register_protocol
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1895
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
ip6_next_header
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:407
vlib_frame_t
Definition: node.h:372
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
vrrp_arp_nd_next
static_always_inline void vrrp_arp_nd_next(vlib_buffer_t *b, u32 *next_index, u32 *vr_index, u8 is_ipv6)
Definition: node.c:275
ip4_header_t
Definition: ip4_packet.h:87
error
Definition: cJSON.c:88
vrrp_accept_owner_next_t
vrrp_accept_owner_next_t
Definition: node.c:785
vrrp_error_t
vrrp_error_t
Definition: node.c:69
vrrp_vr_timer_set
void vrrp_vr_timer_set(vrrp_vr_t *vr, vrrp_vr_timer_type_t type)
Definition: vrrp_periodic.c:89
vr_id
u8 vr_id
Definition: vrrp.api:17
ethernet_arp_header_t
Definition: arp_packet.h:133
VRRP_ACCEPT_OWNER_NEXT_PROCESS
@ VRRP_ACCEPT_OWNER_NEXT_PROCESS
Definition: node.c:787
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
vrrp_nd_next_t
vrrp_nd_next_t
Definition: node.c:267
vrrp_trace_t::is_ipv6
u8 is_ipv6
Definition: node.c:23
VRRP_ARP_INPUT_NEXT_DROP
@ VRRP_ARP_INPUT_NEXT_DROP
Definition: node.c:262
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
error.h
vrrp_accept_owner_trace_t::src
ip46_address_t src
Definition: node.c:741
vrrp_packet.h
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
VNET_FEATURE_INIT
VNET_FEATURE_INIT(lb_nat4_in2out_node_fn, static)
vrrp_input_process
static void vrrp_input_process(vrrp_input_process_args_t *args)
Definition: node.c:199
vrrp_accept_owner_trace_t::sw_if_index
u32 sw_if_index
Definition: node.c:739
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
vrrp_accept_owner_input_inline
static_always_inline uword vrrp_accept_owner_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_ipv6)
Definition: node.c:806
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
vrrp_trace_t::addrs
u8 addrs[256]
Definition: node.c:25
vrrp_accept_owner_error_t
vrrp_accept_owner_error_t
Definition: node.c:771
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
vnet_feature_next
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:322
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
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
static_always_inline
#define static_always_inline
Definition: clib.h:112
vrrp.h
vrrp_vr_runtime::master_adv_int
u16 master_adv_int
Definition: vrrp.h:97
vrrp_arp_next_t
vrrp_arp_next_t
Definition: node.c:260
uword
u64 uword
Definition: types.h:112
vrrp6_input_node
vlib_node_registration_t vrrp6_input_node
(constructor) VLIB_REGISTER_NODE (vrrp6_input_node)
Definition: node.c:720
ethernet_header_t
Definition: packet.h:52
foreach_vrrp_accept_owner_error
#define foreach_vrrp_accept_owner_error
Definition: node.c:767
vrrp_accept_owner_trace_t::is_ipv6
u8 is_ipv6
Definition: node.c:740
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
ip6_header_t::dst_address
ip6_address_t dst_address
Definition: ip6_packet.h:310
ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
mac_address_t_::bytes
u8 bytes[6]
Definition: mac_address.h:25
vrrp_vr_addr_cmp
static int vrrp_vr_addr_cmp(vrrp_vr_t *vr, vrrp_header_t *pkt)
Definition: node.c:101
vrrp_arp_nd_trace_t
Definition: node.c:234
vrrp_vr_lookup_index
static vrrp_vr_t * vrrp_vr_lookup_index(u32 vr_index)
Definition: vrrp.h:251
vrrp_intf_num_vrs
static int vrrp_intf_num_vrs(u32 sw_if_index, u8 is_ipv6)
Definition: vrrp.h:301
vrrp_main_t
Definition: vrrp.h:145
vrrp_arp_nd_input_inline
static_always_inline uword vrrp_arp_nd_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_ipv6)
Definition: node.c:408
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
IP46_TYPE_IP6
@ IP46_TYPE_IP6
Definition: ip46_address.h:27
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
VRRP_ACCEPT_OWNER_N_NEXT
@ VRRP_ACCEPT_OWNER_N_NEXT
Definition: node.c:788
ip4_header_t::dst_address
ip4_address_t dst_address
Definition: ip4_packet.h:125
vrrp_input_process_args
Definition: node.c:89
vlib_buffer_t::current_length
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
vrrp_vr_lookup
static vrrp_vr_t * vrrp_vr_lookup(u32 sw_if_index, u8 vr_id, u8 is_ipv6)
Definition: vrrp.h:231
vrrp_vr_runtime::state
vrrp_vr_state_t state
Definition: vrrp.h:96
vrrp_vr_lookup_address
static u32 vrrp_vr_lookup_address(u32 sw_if_index, u8 is_ipv6, void *addr)
Definition: vrrp.h:262
vrrp_arp_nd_trace_t::vr_index
u32 vr_index
Definition: node.c:237
ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER
vrrp_vr_runtime::mac
mac_address_t mac
Definition: vrrp.h:100
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
ip4_packet.h
vrrp_arp_nd_trace_t::vr_id
u8 vr_id
Definition: node.c:238
VRRP_ARP_N_NEXT
@ VRRP_ARP_N_NEXT
Definition: node.c:264
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
vlib_validate_buffer_enqueue_x1
#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
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
fib_sas.h
ip4_header_t::src_address
ip4_address_t src_address
Definition: ip4_packet.h:125
vrrp_vr_config::vr_id
u8 vr_id
Definition: vrrp.h:72
fib_sas4_get
bool fib_sas4_get(u32 sw_if_index, const ip4_address_t *dst, ip4_address_t *src)
Get an IPv4 Source address to use in a packet being sent out an interface.
Definition: fib_sas.c:50
VRRP_ND_INPUT_NEXT_DROP
@ VRRP_ND_INPUT_NEXT_DROP
Definition: node.c:269
vrrp_accept_owner_error_strings
static char * vrrp_accept_owner_error_strings[]
Definition: node.c:779
vrrp_adv_csum
u16 vrrp_adv_csum(void *l3_hdr, void *payload, u8 is_ipv6, u16 len)
Definition: vrrp_packet.c:143
format
description fragment has unexpected format
Definition: map.api:433
vrrp_accept_owner_trace_t::dst
ip46_address_t dst
Definition: node.c:741
VRRP_ARP_INPUT_NEXT_REPLY_TX
@ VRRP_ARP_INPUT_NEXT_REPLY_TX
Definition: node.c:263
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
format_ip46_address
format_function_t format_ip46_address
Definition: ip46_address.h:50
vrrp_arp_nd_trace_t::is_ipv6
u8 is_ipv6
Definition: node.c:239
vrrp_init
static clib_error_t * vrrp_init(vlib_main_t *vm)
Definition: vrrp.c:1233
vlib_set_next_frame_buffer
static void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
Definition: node_funcs.h:428
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
ip6
vl_api_ip6_address_t ip6
Definition: one.api:424
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
vl_api_rpc_call_main_thread
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: vlib_api.c:620
VRRP_N_ERROR
@ VRRP_N_ERROR
Definition: node.c:74
ip6_header_t
Definition: ip6_packet.h:294
mac_address_t_
Definition: mac_address.h:21
format_vrrp_arp_nd_input_trace
static u8 * format_vrrp_arp_nd_input_trace(u8 *s, va_list *va)
Definition: node.c:244
ip6_header_t::src_address
ip6_address_t src_address
Definition: ip6_packet.h:310
vrrp_trace_t
Definition: node.c:20
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
vrrp_vr_runtime
Definition: vrrp.h:94
vnet_link_t
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
vlib_node_t
Definition: node.h:247
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
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
VNET_FEATURES
#define VNET_FEATURES(...)
Definition: feature.h:470
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
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
format_vrrp_accept_owner_trace
static u8 * format_vrrp_accept_owner_trace(u8 *s, va_list *args)
Definition: node.c:746
VRRP_INPUT_N_NEXT
@ VRRP_INPUT_N_NEXT
Definition: node.c:86
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
arp_packet.h
format_ip6_address
format_function_t format_ip6_address
Definition: format.h:91
VRRP_VR_TIMER_MASTER_DOWN
@ VRRP_VR_TIMER_MASTER_DOWN
Definition: vrrp.h:117
vrrp_vr_runtime::skew
u16 skew
Definition: vrrp.h:98
vrrp_accept_owner_trace_t
Definition: node.c:737
ethernet_buffer_get_header
static ethernet_header_t * ethernet_buffer_get_header(vlib_buffer_t *b)
Definition: ethernet.h:419
vrrp_input_inline
static_always_inline uword vrrp_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_ipv6)
Definition: node.c:552
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
ip6_register_protocol
void ip6_register_protocol(u32 protocol, u32 node_index)
Definition: ip6_forward.c:1679
vrrp_main_t::vrs
vrrp_vr_t * vrs
Definition: vrrp.h:151
vlib_validate_buffer_enqueue_x2
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
vrrp_accept_owner_next_node
static_always_inline void vrrp_accept_owner_next_node(u32 sw_if_index, u8 vr_id, u8 is_ipv6, u32 *next_index, u32 *error)
Definition: node.c:792
vrrp_vr_config::sw_if_index
u32 sw_if_index
Definition: vrrp.h:71
VRRP_ACCEPT_OWNER_N_ERROR
@ VRRP_ACCEPT_OWNER_N_ERROR
Definition: node.c:776
vnet.h
vlib_node_runtime_t
Definition: node.h:454
vrrp_input_init
static clib_error_t * vrrp_input_init(vlib_main_t *vm)
Definition: node.c:1086
src_address
vl_api_address_union_t src_address
Definition: ip_types.api:122
from
from
Definition: nat44_ei_hairpinning.c:415
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
rewrite
rewrite
Definition: pnat.api:158
vlib_get_next_frame
#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
vrrp_trace_t::vrrp
vrrp_header_t vrrp
Definition: node.c:24
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
vrrp_vr_priority
static u8 vrrp_vr_priority(vrrp_vr_t *vr)
Definition: vrrp.h:356
vrrp4_arp_input_node
vlib_node_registration_t vrrp4_arp_input_node
(constructor) VLIB_REGISTER_NODE (vrrp4_arp_input_node)
Definition: node.c:493
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
vrrp_main
vrrp_main_t vrrp_main
Definition: vrrp.c:25
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
VRRP_VR_TIMER_ADV
@ VRRP_VR_TIMER_ADV
Definition: vrrp.h:116
VRRP_VR_PREEMPT
@ VRRP_VR_PREEMPT
Definition: vrrp.h:23
ip4_header_t::protocol
u8 protocol
Definition: ip4_packet.h:115
VRRP_INPUT_NEXT_DROP
@ VRRP_INPUT_NEXT_DROP
Definition: node.c:85
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
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
VRRP_ND_INPUT_NEXT_REPLY_TX
@ VRRP_ND_INPUT_NEXT_REPLY_TX
Definition: node.c:270
vrrp_input_process_backup
static void vrrp_input_process_backup(vrrp_vr_t *vr, vrrp_header_t *pkt)
Definition: node.c:166
vrrp_input_process_args_t
struct vrrp_input_process_args vrrp_input_process_args_t