FD.io VPP  v20.05-21-gb1500e9ff
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/pg/pg.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;
124  vrc->sw_if_index, local_addr);
125  }
126 
127  return memcmp (local_addr, peer_addr, addr_size);
128 }
129 
130 static void
131 vrrp_input_process_master (vrrp_vr_t * vr, vrrp_header_t * pkt)
132 {
133  /* received priority 0, another VR is shutting down. send an adv and
134  * remain in the master state
135  */
136  if (pkt->priority == 0)
137  {
138  clib_warning ("Received shutdown message from a peer on VR %U",
139  format_vrrp_vr_key, vr);
140  vrrp_adv_send (vr, 0);
142  return;
143  }
144 
145  /* if either:
146  * - received priority > adjusted priority, or
147  * - received priority == adjusted priority and peer addr > local addr
148  * allow the local VR to be preempted by the peer
149  */
150  if ((pkt->priority > vrrp_vr_priority (vr)) ||
151  ((pkt->priority == vrrp_vr_priority (vr)) &&
152  (vrrp_vr_addr_cmp (vr, pkt) < 0)))
153  {
154  vrrp_vr_transition (vr, VRRP_VR_STATE_BACKUP, pkt);
155 
156  return;
157  }
158 
159  /* if we made it this far, eiher received prority < adjusted priority or
160  * received == adjusted and local addr > peer addr. Ignore.
161  */
162  return;
163 }
164 
165 /* RFC 5798 section 6.4.2 */
166 static void
167 vrrp_input_process_backup (vrrp_vr_t * vr, vrrp_header_t * pkt)
168 {
169  vrrp_vr_config_t *vrc = &vr->config;
170  vrrp_vr_runtime_t *vrt = &vr->runtime;
171 
172  /* master shutting down, ready for election */
173  if (pkt->priority == 0)
174  {
175  clib_warning ("Master for VR %U is shutting down", format_vrrp_vr_key,
176  vr);
177  vrt->master_down_int = vrt->skew;
179  return;
180  }
181 
182  /* no preempt set or adv from a higher priority router, update timers */
183  if (!(vrc->flags & VRRP_VR_PREEMPT) ||
184  (pkt->priority >= vrrp_vr_priority (vr)))
185  {
186  vrt->master_adv_int = clib_net_to_host_u16 (pkt->rsvd_and_max_adv_int);
187  vrt->master_adv_int &= ((u16) 0x0fff); /* ignore rsvd bits */
188 
192  return;
193  }
194 
195  /* preempt set or our priority > received, continue to wait on master down */
196  return;
197 }
198 
199 always_inline void
201 {
202  vrrp_vr_t *vr;
203 
204  vr = vrrp_vr_lookup_index (args->vr_index);
205 
206  if (!vr)
207  {
208  clib_warning ("Error retrieving VR with index %u", args->vr_index);
209  return;
210  }
211 
212  switch (vr->runtime.state)
213  {
214  case VRRP_VR_STATE_INIT:
215  return;
216  case VRRP_VR_STATE_BACKUP:
217  /* this is usually the only state an advertisement should be received */
218  vrrp_input_process_backup (vr, args->pkt);
219  break;
220  case VRRP_VR_STATE_MASTER:
221  /* might be getting preempted. or have a misbehaving peer */
222  clib_warning ("Received advertisement for master VR %U",
223  format_vrrp_vr_key, vr);
224  vrrp_input_process_master (vr, args->pkt);
225  break;
226  default:
227  clib_warning ("Received advertisement for VR %U in unknown state %d",
228  format_vrrp_vr_key, vr, vr->runtime.state);
229  break;
230  }
231 
232  return;
233 }
234 
235 typedef struct
236 {
237  ip46_address_t ip;
242 
243 
244 static u8 *
246 {
247  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
248  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
249  vrrp_arp_nd_trace_t *t = va_arg (*va, vrrp_arp_nd_trace_t *);
250 
251  s = format (s, "address %U",
253  (t->is_ipv6) ? (void *) &t->ip.ip6 : (void *) &t->ip.ip4);
254 
255  if (t->vr_index != ~0)
256  s = format (s, ": vr_index %u vr_id %u", t->vr_index, t->vr_id);
257 
258  return s;
259 }
260 
261 typedef enum
262 {
267 
268 typedef enum
269 {
274 
277  u8 is_ipv6)
278 {
279  vnet_main_t *vnm = vnet_get_main ();
280  vlib_main_t *vm = vlib_get_main ();
281  ethernet_header_t *eth, *eth_new;
282  void *lookup_addr = 0;
283  vrrp_vr_t *vr;
285  vnet_link_t link_type;
286  u8 *rewrite, rewrite_len;
287  int bogus_length;
288  /* ND vars */
289  ip6_header_t *ip6 = 0;
290  icmp6_neighbor_solicitation_or_advertisement_header_t *sol_adv = 0;
291  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *lladdr = 0;
292  /* ARP vars */
294  ip4_address_t ip4_addr;
295 
296  if (is_ipv6)
297  {
298  ip6 = vlib_buffer_get_current (b);
299 
300  /* we only care about about ICMP6 neighbor solicitiations */
301  if (ip6->protocol != IP_PROTOCOL_ICMP6)
302  return;
303 
304  sol_adv = ip6_next_header (ip6);
305  lladdr = (void *) (sol_adv + 1);
306 
307  /* skip anything other than neighbor solicitations */
308  if (sol_adv->icmp.type != ICMP6_neighbor_solicitation)
309  return;
310 
311  lookup_addr = &sol_adv->target_address;
312  link_type = VNET_LINK_IP6;
313  }
314  else
315  {
316  arp = vlib_buffer_get_current (b);
317 
318  /* skip non-request packets */
319  if (arp->opcode != clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request))
320  return;
321 
322  lookup_addr = &arp->ip4_over_ethernet[1].ip4;
323  link_type = VNET_LINK_ARP;
324  }
325 
326  sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
327 
328  /* Don't bother with a hash lookup if no VRs configured on this interface */
329  if (!vrrp_intf_num_vrs (sw_if_index, is_ipv6))
330  return;
331 
332  /* skip requests that are not for VRRP addresses */
333  *vr_index = vrrp_vr_lookup_address (sw_if_index, is_ipv6, lookup_addr);
334  if (*vr_index == ~0)
335  return;
336 
337  /* only reply if the VR is in the master state */
338  vr = vrrp_vr_lookup_index (*vr_index);
339  if (!vr || vr->runtime.state != VRRP_VR_STATE_MASTER)
340  return;
341 
342  eth = ethernet_buffer_get_header (b);
343  rewrite = ethernet_build_rewrite (vnm, sw_if_index, link_type,
344  eth->src_address);
345  rewrite_len = vec_len (rewrite);
346  if (rewrite_len == 0)
347  return;
348 
349  /* send the reply out the incoming interface */
350  *next_index = VRRP_ARP_INPUT_NEXT_REPLY_TX;
351  vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
352 
353  /* the outbound ethernet & vlan headers may have a different length than
354  * the received header, so get a pointer to the new start of the packet
355  * and write the header there.
356  */
357  vlib_buffer_advance (b, -rewrite_len);
358  eth_new = vlib_buffer_get_current (b);
359  clib_memcpy_fast (eth_new, rewrite, rewrite_len);
360  vec_free (rewrite);
361 
362  if (is_ipv6)
363  {
366  IP6_MULTICAST_SCOPE_link_local,
367  IP6_MULTICAST_GROUP_ID_all_hosts);
368  else
369  ip6->dst_address = ip6->src_address;
370 
371  ip6->src_address = sol_adv->target_address;
372  ip6->hop_limit = 255;
373  sol_adv->icmp.type = ICMP6_neighbor_advertisement;
374  sol_adv->icmp.checksum = 0;
375  sol_adv->advertisement_flags =
376  clib_host_to_net_u32 (ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER
379 
380  clib_memcpy (lladdr->ethernet_address, vr->runtime.mac.bytes,
381  sizeof (mac_address_t));
382  lladdr->header.type =
383  ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
384 
385  sol_adv->icmp.checksum =
386  ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus_length);
387 
388  }
389  else
390  {
391  ip4_addr = arp->ip4_over_ethernet[1].ip4;
392 
393  arp->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
394  arp->ip4_over_ethernet[1] = arp->ip4_over_ethernet[0];
395 
396  arp->ip4_over_ethernet[0].mac = vr->runtime.mac;
397  arp->ip4_over_ethernet[0].ip4 = ip4_addr;
398  }
399 }
400 
404 {
405  u32 n_left_from, *from, next_index, *to_next;
406 
407  from = vlib_frame_vector_args (frame);
408  n_left_from = frame->n_vectors;
409  next_index = node->cached_next_index;
410 
411  while (n_left_from > 0)
412  {
413  u32 n_left_to_next;
414 
415  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
416 
417  while (n_left_from > 0 && n_left_to_next > 0)
418  {
419 
420  vlib_buffer_t *b0;
421  u32 bi0;
422  u32 next0;
423  u32 vr_index = ~0;
424 
425  bi0 = from[0];
426  to_next[0] = bi0;
427  from += 1;
428  to_next += 1;
429  n_left_from -= 1;
430  n_left_to_next -= 1;
431 
432  b0 = vlib_get_buffer (vm, bi0);
433 
434  vnet_feature_next (&next0, b0);
435  vrrp_arp_nd_next (b0, &next0, &vr_index, is_ipv6);
436 
437  if (b0->flags & VLIB_BUFFER_IS_TRACED)
438  {
440  vlib_add_trace (vm, node, b0, sizeof (*t));
441  vrrp_vr_t *vr;
442 
443  if (is_ipv6)
444  {
445  ip6_header_t *ip0;
446  icmp6_neighbor_solicitation_or_advertisement_header_t
447  * sol_adv0;
448 
449  ip0 = vlib_buffer_get_current (b0);
450  sol_adv0 = ip6_next_header (ip0);
451  t->ip.ip6 = sol_adv0->target_address;
452  }
453  else
454  {
455  ethernet_arp_header_t *arp0;
456 
457  arp0 = vlib_buffer_get_current (b0);
458  t->ip.ip4 = arp0->ip4_over_ethernet[0].ip4;
459  }
460 
461  vr = vrrp_vr_lookup_index (vr_index);
462  if (vr)
463  t->vr_id = vr->config.vr_id;
464 
465  t->vr_index = vr_index;
466  t->is_ipv6 = is_ipv6;
467  }
468 
469  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
470  n_left_to_next, bi0, next0);
471  }
472 
473  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
474  }
475 
476  return frame->n_vectors;
477 }
478 
482 {
483  return vrrp_arp_nd_input_inline (vm, node, frame, 0 /* is_ipv6 */ );
484 }
485 
486 /* *INDENT-OFF* */
488 {
489  .name = "vrrp4-arp-input",
490  .vector_size = sizeof (u32),
491  .format_trace = format_vrrp_arp_nd_input_trace,
493 
494  .n_errors = ARRAY_LEN(vrrp_error_strings),
495  .error_strings = vrrp_error_strings,
496 
497  .n_next_nodes = VRRP_ARP_N_NEXT,
498 
499  .next_nodes = {
500  [VRRP_ARP_INPUT_NEXT_DROP] = "error-drop",
501  [VRRP_ARP_INPUT_NEXT_REPLY_TX] = "interface-output",
502  },
503 };
504 
505 VNET_FEATURE_INIT (vrrp4_arp_feat_node, static) =
506 {
507  .arc_name = "arp",
508  .node_name = "vrrp4-arp-input",
509  .runs_before = VNET_FEATURES ("arp-reply"),
510 };
511 
515 {
516  return vrrp_arp_nd_input_inline (vm, node, frame, 1 /* is_ipv6 */);
517 }
518 
519 /* *INDENT-OFF* */
521 {
522  .name = "vrrp6-nd-input",
523  .vector_size = sizeof (u32),
524  .format_trace = format_vrrp_arp_nd_input_trace,
526 
527  .n_errors = ARRAY_LEN(vrrp_error_strings),
528  .error_strings = vrrp_error_strings,
529 
530  .n_next_nodes = VRRP_ND_N_NEXT,
531 
532  .next_nodes = {
533  [VRRP_ND_INPUT_NEXT_DROP] = "error-drop",
534  [VRRP_ND_INPUT_NEXT_REPLY_TX] = "interface-output",
535  },
536 };
537 
538 VNET_FEATURE_INIT (vrrp6_nd_feat_node, static) =
539 {
540  .arc_name = "ip6-local",
541  .node_name = "vrrp6-nd-input",
542  .runs_before = VNET_FEATURES ("ip6-local-end-of-arc"),
543 };
544 
548 {
549  u32 n_left_from, *from;
550  vrrp_main_t *vmp = &vrrp_main;
551 
552  from = vlib_frame_vector_args (frame);
553  n_left_from = frame->n_vectors;
554 
555  while (n_left_from > 0)
556  {
557  u32 bi0;
558  vlib_buffer_t *b0;
559  u32 next0, error0;
560  void *ip0;
561  vrrp_header_t *vrrp0;
562  vrrp_vr_t *vr0;
564  u8 *ttl0;
565  u16 rx_csum0;
566  u16 payload_len0;
567  int addr_len;
568 
569  bi0 = from[0];
570  b0 = vlib_get_buffer (vm, bi0);
571 
572  ip0 = vlib_buffer_get_current (b0);
573 
574  if (is_ipv6)
575  {
576  ip6_header_t *ip6 = ip0;
577 
578  vrrp0 = (vrrp_header_t *) (ip6 + 1);
579  ttl0 = &ip6->hop_limit;
580  addr_len = 16;
581  payload_len0 = clib_net_to_host_u16 (ip6->payload_length);
582  vlib_buffer_advance (b0, sizeof (*ip6));
583  }
584  else
585  {
586  ip4_header_t *ip4 = ip0;
587 
588  vrrp0 = (vrrp_header_t *) (ip4 + 1);
589  ttl0 = &ip4->ttl;
590  addr_len = 4;
591  payload_len0 = clib_net_to_host_u16 (ip4->length) - sizeof(*ip4);
592  vlib_buffer_advance (b0, sizeof (*ip4));
593  }
594 
595  next0 = VRRP_INPUT_NEXT_DROP;
596 
597  error0 = VRRP_ERROR_RECEIVED;
598 
599  /* Validation from RFC 5798 sec 7.1 */
600 
601  /* checksum set to 0 for calculation, save original value */
602  rx_csum0 = vrrp0->checksum;
603  vrrp0->checksum = 0;
604 
605  /* Mandatory - TTL/hop limit must be 255 */
606  if (*ttl0 != 255)
607  {
608  error0 = VRRP_ERROR_BAD_TTL;
609  goto trace;
610  }
611 
612  /* Mandatory - VRRP version must be 3 */
613  if ((vrrp0->vrrp_version_and_type >> 4) != 3)
614  {
615  error0 = VRRP_ERROR_NOT_VERSION_3;
616  goto trace;
617  }
618 
619  /* Mandatory - packet must be complete */
620  if (b0->current_length < sizeof (*vrrp0) +
621  ((u32) vrrp0->n_addrs) * addr_len)
622  {
623  error0 = VRRP_ERROR_INCOMPLETE_PKT;
624  goto trace;
625  }
626 
627  /* Mandatory - checksum must be correct */
628  if (rx_csum0 != vrrp_adv_csum (ip0, vrrp0, is_ipv6, payload_len0))
629  {
630  error0 = VRRP_ERROR_BAD_CHECKSUM;
631  goto trace;
632  }
633 
634  /* Mandatory - VR must be configured on the interface adv received on */
635  if (!(vr0 =
637  vrrp0->vr_id, is_ipv6)))
638  {
639  error0 = VRRP_ERROR_UNKNOWN_VR;
640  goto trace;
641  }
642 
643  /* Optional - count of addresses should match configuration */
644  /* Could also check that addresses match, but likely to be O(n^2) */
645  if (vrrp0->n_addrs != vec_len (vr0->config.vr_addrs))
646  {
647  error0 = VRRP_ERROR_ADDR_MISMATCH;
648  goto trace;
649  }
650 
651  /* signal main thread to process contents of packet */
652  args0.vr_index = vr0 - vmp->vrs;
653  args0.pkt = vrrp0;
654 
656  sizeof (args0));
657 
658  trace:
659  vrrp0->checksum = rx_csum0; /* restore csum for correct trace output */
660  b0->error = node->errors[error0];
661 
662  if (b0->flags & VLIB_BUFFER_IS_TRACED)
663  {
664  vrrp_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
665  size_t addr_len = (is_ipv6 ? 16 : 4);
666 
667  t->sw_if_index = vnet_buffer(b0)->sw_if_index[VLIB_RX];
668  t->is_ipv6 = is_ipv6;
669  clib_memcpy_fast (&t->vrrp, vrrp0, sizeof (*vrrp0));
670  clib_memcpy_fast (t->addrs, (void *) (vrrp0 + 1),
671  (size_t) vrrp0->n_addrs * addr_len);
672  }
673 
674  /* always drop, never forward or reply here */
675  vlib_set_next_frame_buffer (vm, node, next0, bi0);
676 
677  from += 1;
678  n_left_from -= 1;
679  }
680 
681  return frame->n_vectors;
682 }
683 
686 {
687  return vrrp_input_inline (vm, node, frame, 0);
688 }
689 
690 /* *INDENT-OFF* */
692 {
693  .name = "vrrp4-input",
694  .vector_size = sizeof (u32),
695  .format_trace = format_vrrp_trace,
697 
698  .n_errors = ARRAY_LEN(vrrp_error_strings),
699  .error_strings = vrrp_error_strings,
700 
701  .n_next_nodes = VRRP_INPUT_N_NEXT,
702 
703  .next_nodes = {
704  [VRRP_INPUT_NEXT_DROP] = "error-drop",
705  },
706 };
707 
710 {
711  return vrrp_input_inline (vm, node, frame, 1);
712 }
713 
715 {
716  .name = "vrrp6-input",
717  .vector_size = sizeof (u32),
718  .format_trace = format_vrrp_trace,
720 
721  .n_errors = ARRAY_LEN(vrrp_error_strings),
722  .error_strings = vrrp_error_strings,
723 
724  .n_next_nodes = VRRP_INPUT_N_NEXT,
725 
726  .next_nodes = {
727  [VRRP_INPUT_NEXT_DROP] = "error-drop",
728  },
729 };
730 
731 static clib_error_t *
733 {
734  clib_error_t *error;
735 
736  if ((error = vlib_call_init_function (vm, vrrp_init)))
737  return error;
738 
739  ip4_register_protocol (IP_PROTOCOL_VRRP, vrrp4_input_node.index);
740  ip6_register_protocol (IP_PROTOCOL_VRRP, vrrp6_input_node.index);
741 
742  return 0;
743 }
744 
746 
747 /* *INDENT-ON* */
748 
749 /*
750  * fd.io coding-style-patch-verification: ON
751  *
752  * Local Variables:
753  * eval: (c-set-style "gnu")
754  * End:
755  */
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
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
static void vrrp_input_process_master(vrrp_vr_t *vr, vrrp_header_t *pkt)
Definition: node.c:131
vrrp_error_t
Definition: node.c:69
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
Definition: vlib_api_cli.c:899
vlib_node_registration_t vrrp6_nd_input_node
(constructor) VLIB_REGISTER_NODE (vrrp6_nd_input_node)
Definition: node.c:520
#define CLIB_UNUSED(x)
Definition: clib.h:86
u32 sw_if_index
Definition: vrrp.h:71
vlib_node_registration_t vrrp4_arp_input_node
(constructor) VLIB_REGISTER_NODE (vrrp4_arp_input_node)
Definition: node.c:487
void ip6_register_protocol(u32 protocol, u32 node_index)
Definition: ip6_forward.c:1664
static clib_error_t * vrrp_init(vlib_main_t *vm)
Definition: vrrp.c:1184
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:371
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
Definition: vrrp.h:106
vrrp_arp_next_t
Definition: node.c:261
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u8 src_address[6]
Definition: packet.h:56
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
static int vrrp_vr_addr_cmp(vrrp_vr_t *vr, vrrp_header_t *pkt)
Definition: node.c:101
vrrp_vr_t * vrs
Definition: vrrp.h:151
ip_lookup_main_t lookup_main
Definition: ip4.h:108
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
vrrp_vr_state_t state
Definition: vrrp.h:96
#define VLIB_NODE_FN(node)
Definition: node.h:202
struct vrrp_input_process_args vrrp_input_process_args_t
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1933
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:472
vhost_vring_addr_t addr
Definition: vhost_user.h:254
ip6_address_t src_address
Definition: ip6_packet.h:310
unsigned char u8
Definition: types.h:56
static vrrp_vr_t * vrrp_vr_lookup_index(u32 vr_index)
Definition: vrrp.h:248
#define clib_memcpy(d, s, n)
Definition: string.h:180
format_function_t format_ip4_address
Definition: format.h:73
u16 master_adv_int
Definition: vrrp.h:97
#define static_always_inline
Definition: clib.h:106
vl_api_interface_index_t sw_if_index
Definition: gre.api:53
ethernet_arp_ip4_over_ethernet_address_t ip4_over_ethernet[2]
Definition: arp_packet.h:142
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
vl_api_ip6_address_t ip6
Definition: one.api:424
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
vrrp_vr_config_t config
Definition: vrrp.h:108
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: vlib_api.c:608
static void vrrp_input_process_backup(vrrp_vr_t *vr, vrrp_header_t *pkt)
Definition: node.c:167
unsigned int u32
Definition: types.h:88
u16 skew
Definition: vrrp.h:98
#define vlib_call_init_function(vm, x)
Definition: init.h:270
ip46_address_t ip
Definition: node.c:237
u16 master_down_int
Definition: vrrp.h:99
u16 vrrp_adv_csum(void *l3_hdr, void *payload, u8 is_ipv6, u16 len)
Definition: vrrp_packet.c:143
u8 is_ipv6
Definition: node.c:23
mac_address_t mac
Definition: vrrp.h:100
u8 * format_vrrp_packet_hdr(u8 *s, va_list *args)
Definition: vrrp_format.c:124
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
vlib_node_registration_t vrrp4_input_node
(constructor) VLIB_REGISTER_NODE (vrrp4_input_node)
Definition: node.c:691
static ethernet_header_t * ethernet_buffer_get_header(vlib_buffer_t *b)
Definition: ethernet.h:408
u8 * format_vrrp_vr_key(u8 *s, va_list *args)
Definition: vrrp_format.c:65
vrrp_vr_flags_t flags
Definition: vrrp.h:75
unsigned short u16
Definition: types.h:57
vrrp_header_t vrrp
Definition: node.c:24
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
u8 vr_id
Definition: vrrp.h:72
vrrp_nd_next_t
Definition: node.c:268
#define always_inline
Definition: ipsec.h:28
vl_api_ip4_address_t ip4
Definition: one.api:376
vrrp_vr_runtime_t runtime
Definition: vrrp.h:109
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:546
static void vrrp_vr_master_down_compute(vrrp_vr_t *vr)
Definition: vrrp.h:222
vl_api_address_union_t src_address
Definition: ip_types.api:99
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:224
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:338
static char * vrrp_error_strings[]
Definition: node.c:77
vlib_main_t * vm
Definition: in2out_ed.c:1599
static u8 vrrp_vr_is_ipv6(vrrp_vr_t *vr)
Definition: vrrp.h:309
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:399
format_function_t format_ip6_address
Definition: format.h:91
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:322
#define clib_warning(format, args...)
Definition: error.h:59
vlib_node_registration_t vrrp6_input_node
(constructor) VLIB_REGISTER_NODE (vrrp6_input_node)
Definition: node.c:714
#define foreach_vrrp_error
Definition: node.c:60
#define ARRAY_LEN(x)
Definition: clib.h:66
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:483
static u8 vrrp_vr_priority(vrrp_vr_t *vr)
Definition: vrrp.h:353
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1599
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:371
static void vrrp_input_process(vrrp_input_process_args_t *args)
Definition: node.c:200
vrrp_main_t vrrp_main
Definition: vrrp.c:25
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:1095
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:517
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
int vrrp_adv_send(vrrp_vr_t *vr, int shutdown)
Definition: vrrp_packet.c:272
void vrrp_vr_timer_set(vrrp_vr_t *vr, vrrp_vr_timer_type_t type)
Definition: vrrp_periodic.c:89
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
#define VNET_FEATURES(...)
Definition: feature.h:470
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u32 sw_if_index
Definition: node.c:22
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
struct _vlib_node_registration vlib_node_registration_t
Definition: defs.h:47
u16 payload_length
Definition: ip6_packet.h:301
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static u8 * format_vrrp_trace(u8 *s, va_list *args)
Definition: node.c:30
static u8 * format_vrrp_arp_nd_input_trace(u8 *s, va_list *va)
Definition: node.c:245
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:244
static int vrrp_intf_num_vrs(u32 sw_if_index, u8 is_ipv6)
Definition: vrrp.h:298
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 &#39;link_type&#39; to &#39;dst_address&#39; ...
Definition: interface.c:83
static vrrp_vr_t * vrrp_vr_lookup(u32 sw_if_index, u8 vr_id, u8 is_ipv6)
Definition: vrrp.h:230
static void ip6_address_copy(ip6_address_t *dst, const ip6_address_t *src)
Definition: ip6_packet.h:127
vrrp_header_t * pkt
Definition: node.c:92
static uword ip6_address_is_unspecified(const ip6_address_t *a)
Definition: ip6_packet.h:237
#define vnet_buffer(b)
Definition: buffer.h:417
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1144
static clib_error_t * vrrp_input_init(vlib_main_t *vm)
Definition: node.c:732
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1600
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:402
ip46_address_t * vr_addrs
Definition: vrrp.h:76
bool is_ipv6
Definition: dhcp.api:202
static_always_inline void vrrp_arp_nd_next(vlib_buffer_t *b, u32 *next_index, u32 *vr_index, u8 is_ipv6)
Definition: node.c:276
static int ip4_src_address_for_packet(ip_lookup_main_t *lm, u32 sw_if_index, ip4_address_t *src)
Definition: ip4.h:214
static void vrrp_vr_skew_compute(vrrp_vr_t *vr)
Definition: vrrp.h:213
u8 addrs[256]
Definition: node.c:25
vrrp_next_t
Definition: node.c:83
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
VNET_FEATURE_INIT(lb_nat4_in2out_node_fn, static)
static u32 vrrp_vr_lookup_address(u32 sw_if_index, u8 is_ipv6, void *addr)
Definition: vrrp.h:259
void vrrp_vr_transition(vrrp_vr_t *vr, vrrp_vr_state_t new_state, void *data)
Definition: vrrp.c:247