FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
geneve.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 SUSE LLC.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vnet/geneve/geneve.h>
16 #include <vnet/ip/format.h>
17 #include <vnet/fib/fib_entry.h>
18 #include <vnet/fib/fib_table.h>
20 #include <vnet/mfib/mfib_table.h>
21 #include <vnet/adj/adj_mcast.h>
22 #include <vnet/interface.h>
23 #include <vlib/vlib.h>
24 
25 /**
26  * @file
27  * @brief GENEVE.
28  *
29  * GENEVE provides the features needed to allow L2 bridge domains (BDs)
30  * to span multiple servers. This is done by building an L2 overlay on
31  * top of an L3 network underlay using GENEVE tunnels.
32  *
33  * This makes it possible for servers to be co-located in the same data
34  * center or be separated geographically as long as they are reachable
35  * through the underlay L3 network.
36  */
37 
38 
40 
41 u8 *
42 format_geneve_encap_trace (u8 * s, va_list * args)
43 {
44  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
45  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
46  geneve_encap_trace_t *t = va_arg (*args, geneve_encap_trace_t *);
47 
48  s = format (s, "GENEVE encap to geneve_tunnel%d vni %d",
49  t->tunnel_index, t->vni);
50  return s;
51 }
52 
53 static u8 *
54 format_decap_next (u8 * s, va_list * args)
55 {
56  u32 next_index = va_arg (*args, u32);
57 
58  switch (next_index)
59  {
60  case GENEVE_INPUT_NEXT_DROP:
61  return format (s, "drop");
62  case GENEVE_INPUT_NEXT_L2_INPUT:
63  return format (s, "l2");
64  default:
65  return format (s, "index %d", next_index);
66  }
67  return s;
68 }
69 
70 u8 *
71 format_geneve_tunnel (u8 * s, va_list * args)
72 {
73  geneve_tunnel_t *t = va_arg (*args, geneve_tunnel_t *);
74  geneve_main_t *ngm = &geneve_main;
75 
76  s = format (s, "[%d] lcl %U rmt %U vni %d fib-idx %d sw-if-idx %d ",
77  t - ngm->tunnels,
80  t->vni, t->encap_fib_index, t->sw_if_index);
81 
82  s = format (s, "encap-dpo-idx %d ", t->next_dpo.dpoi_index);
83  s = format (s, "decap-next-%U ", format_decap_next, t->decap_next_index);
84 
86  s = format (s, "mcast-sw-if-idx %d ", t->mcast_sw_if_index);
87 
88  return s;
89 }
90 
91 static u8 *
92 format_geneve_name (u8 * s, va_list * args)
93 {
94  u32 dev_instance = va_arg (*args, u32);
95  return format (s, "geneve_tunnel%d", dev_instance);
96 }
97 
98 static clib_error_t *
100 {
101  u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
103  vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
104 
105  return /* no error */ 0;
106 }
107 
108 /* *INDENT-OFF* */
109 VNET_DEVICE_CLASS (geneve_device_class, static) = {
110  .name = "GENEVE",
111  .format_device_name = format_geneve_name,
112  .format_tx_trace = format_geneve_encap_trace,
113  .admin_up_down_function = geneve_interface_admin_up_down,
114 };
115 /* *INDENT-ON* */
116 
117 static u8 *
119 {
120  u32 dev_instance = va_arg (*args, u32);
121  s = format (s, "unimplemented dev %u", dev_instance);
122  return s;
123 }
124 
125 /* *INDENT-OFF* */
126 VNET_HW_INTERFACE_CLASS (geneve_hw_class) = {
127  .name = "GENEVE",
128  .format_header = format_geneve_header_with_length,
129  .build_rewrite = default_build_rewrite,
130 };
131 /* *INDENT-ON* */
132 
133 static void
135 {
136  dpo_id_t dpo = DPO_INVALID;
137  u32 encap_index = ip46_address_is_ip4 (&t->remote) ?
141 
142  fib_entry_contribute_forwarding (t->fib_entry_index, forw_type, &dpo);
143  dpo_stack_from_node (encap_index, &t->next_dpo, &dpo);
144  dpo_reset (&dpo);
145 }
146 
147 static geneve_tunnel_t *
149 {
151  return ((geneve_tunnel_t *) (((char *) node) -
153 }
154 
155 /**
156  * Function definition to backwalk a FIB node -
157  * Here we will restack the new dpo of GENEVE DIP to encap node.
158  */
161 {
164 }
165 
166 /**
167  * Function definition to get a FIB node from its index
168  */
169 static fib_node_t *
171 {
172  geneve_tunnel_t *t;
173  geneve_main_t *vxm = &geneve_main;
174 
175  t = pool_elt_at_index (vxm->tunnels, index);
176 
177  return (&t->node);
178 }
179 
180 /**
181  * Function definition to inform the FIB node that its last lock has gone.
182  */
183 static void
185 {
186  /*
187  * The GENEVE tunnel is a root of the graph. As such
188  * it never has children and thus is never locked.
189  */
190  ASSERT (0);
191 }
192 
193 /*
194  * Virtual function table registered by GENEVE tunnels
195  * for participation in the FIB object graph.
196  */
197 const static fib_node_vft_t geneve_vft = {
199  .fnv_last_lock = geneve_tunnel_last_lock_gone,
200  .fnv_back_walk = geneve_tunnel_back_walk,
201 };
202 
203 
204 #define foreach_copy_field \
205 _(vni) \
206 _(mcast_sw_if_index) \
207 _(encap_fib_index) \
208 _(decap_next_index) \
209 _(local) \
210 _(remote)
211 
212 static int
214 {
215  union
216  {
217  ip4_geneve_header_t *h4;
218  ip6_geneve_header_t *h6;
219  u8 *rw;
220  } r =
221  {
222  .rw = 0};
223  int len = is_ip6 ? sizeof *r.h6 : sizeof *r.h4;
224 #if SUPPORT_OPTIONS_HEADER==1
225  len += t->options_len;
226 #endif
227 
229 
230  udp_header_t *udp;
231  geneve_header_t *geneve;
232  /* Fixed portion of the (outer) ip header */
233  if (!is_ip6)
234  {
235  ip4_header_t *ip = &r.h4->ip4;
236  udp = &r.h4->udp, geneve = &r.h4->geneve;
237  ip->ip_version_and_header_length = 0x45;
238  ip->ttl = 254;
239  ip->protocol = IP_PROTOCOL_UDP;
240 
241  ip->src_address = t->local.ip4;
242  ip->dst_address = t->remote.ip4;
243 
244  /* we fix up the ip4 header length and checksum after-the-fact */
245  ip->checksum = ip4_header_checksum (ip);
246  }
247  else
248  {
249  ip6_header_t *ip = &r.h6->ip6;
250  udp = &r.h6->udp, geneve = &r.h6->geneve;
252  clib_host_to_net_u32 (6 << 28);
253  ip->hop_limit = 255;
254  ip->protocol = IP_PROTOCOL_UDP;
255 
256  ip->src_address = t->local.ip6;
257  ip->dst_address = t->remote.ip6;
258  }
259 
260  /* UDP header, randomize local port on something, maybe? */
261  udp->src_port = clib_host_to_net_u16 (5251);
262  udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_geneve);
263 
264  /* GENEVE header */
266 #if SUPPORT_OPTIONS_HEADER==1
267  vnet_set_geneve_options_len (geneve, t->options_len);
268 #else
269  vnet_set_geneve_options_len (geneve, 0);
270 #endif
271  vnet_set_geneve_oamframe_bit (geneve, 0);
272  vnet_set_geneve_critical_bit (geneve, 0);
274 
276 
277  vnet_set_geneve_vni (geneve, t->vni);
278 
279  t->rewrite = r.rw;
280  return (0);
281 }
282 
283 static bool
285  u32 decap_next_index)
286 {
287  vlib_main_t *vm = vxm->vlib_main;
288  u32 input_idx =
289  (!is_ip6) ? geneve4_input_node.index : geneve6_input_node.index;
290  vlib_node_runtime_t *r = vlib_node_get_runtime (vm, input_idx);
291 
292  return decap_next_index < r->n_next_nodes;
293 }
294 
295 typedef union
296 {
297  struct
298  {
299  fib_node_index_t mfib_entry_index;
300  adj_index_t mcast_adj_index;
301  };
302  u64 as_u64;
303 } __clib_packed mcast_shared_t;
304 
305 static inline mcast_shared_t
306 mcast_shared_get (ip46_address_t * ip)
307 {
309  uword *p = hash_get_mem (geneve_main.mcast_shared, ip);
310  ALWAYS_ASSERT (p);
311  return (mcast_shared_t)
312  {
313  .as_u64 = *p};
314 }
315 
316 static inline void
317 mcast_shared_add (ip46_address_t * remote,
318  fib_node_index_t mfei, adj_index_t ai)
319 {
320  mcast_shared_t new_ep = {
321  .mcast_adj_index = ai,
322  .mfib_entry_index = mfei,
323  };
324 
325  hash_set_mem_alloc (&geneve_main.mcast_shared, remote, new_ep.as_u64);
326 }
327 
328 static inline void
329 mcast_shared_remove (ip46_address_t * remote)
330 {
331  mcast_shared_t ep = mcast_shared_get (remote);
332 
333  adj_unlock (ep.mcast_adj_index);
334  mfib_table_entry_delete_index (ep.mfib_entry_index, MFIB_SOURCE_GENEVE);
335 
336  hash_unset_mem_free (&geneve_main.mcast_shared, remote);
337 }
338 
341 {
342  geneve_main_t *vxm = &geneve_main;
343  geneve_tunnel_t *t = 0;
344  vnet_main_t *vnm = vxm->vnet_main;
345  uword *p;
346  u32 hw_if_index = ~0;
347  u32 sw_if_index = ~0;
348  int rv;
349  geneve4_tunnel_key_t key4;
350  geneve6_tunnel_key_t key6;
351  u32 is_ip6 = a->is_ip6;
352 
353  if (!is_ip6)
354  {
355  key4.remote = a->remote.ip4.as_u32;
356  key4.vni = clib_host_to_net_u32 (a->vni << GENEVE_VNI_SHIFT);
357  p = hash_get (vxm->geneve4_tunnel_by_key, key4.as_u64);
358  }
359  else
360  {
361  key6.remote = a->remote.ip6;
362  key6.vni = clib_host_to_net_u32 (a->vni << GENEVE_VNI_SHIFT);
363  p = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6);
364  }
365 
366  if (a->is_add)
367  {
368  l2input_main_t *l2im = &l2input_main;
369 
370  /* adding a tunnel: tunnel must not already exist */
371  if (p)
372  return VNET_API_ERROR_TUNNEL_EXIST;
373 
374  /*if not set explicitly, default to l2 */
375  if (a->decap_next_index == ~0)
376  a->decap_next_index = GENEVE_INPUT_NEXT_L2_INPUT;
377  if (!geneve_decap_next_is_valid (vxm, is_ip6, a->decap_next_index))
378  return VNET_API_ERROR_INVALID_DECAP_NEXT;
379 
381  clib_memset (t, 0, sizeof (*t));
382 
383  /* copy from arg structure */
384 #define _(x) t->x = a->x;
386 #undef _
387 
388  rv = geneve_rewrite (t, is_ip6);
389  if (rv)
390  {
391  pool_put (vxm->tunnels, t);
392  return rv;
393  }
394 
395  /* copy the key */
396  if (is_ip6)
398  t - vxm->tunnels);
399  else
400  hash_set (vxm->geneve4_tunnel_by_key, key4.as_u64, t - vxm->tunnels);
401 
404  {
406  hw_if_index = vxm->free_geneve_tunnel_hw_if_indices
408  _vec_len (vxm->free_geneve_tunnel_hw_if_indices) -= 1;
409 
410  hi = vnet_get_hw_interface (vnm, hw_if_index);
411  hi->dev_instance = t - vxm->tunnels;
412  hi->hw_instance = hi->dev_instance;
413 
414  /* clear old stats of freed tunnel before reuse */
415  sw_if_index = hi->sw_if_index;
419  sw_if_index);
422  sw_if_index);
425  sw_if_index);
427  }
428  else
429  {
430  hw_if_index = vnet_register_interface
431  (vnm, geneve_device_class.index, t - vxm->tunnels,
432  geneve_hw_class.index, t - vxm->tunnels);
433  hi = vnet_get_hw_interface (vnm, hw_if_index);
434  }
435 
436  /* Set geneve tunnel output node */
437  u32 encap_index = !is_ip6 ?
439  vnet_set_interface_output_node (vnm, hw_if_index, encap_index);
440 
441  t->hw_if_index = hw_if_index;
442  t->sw_if_index = sw_if_index = hi->sw_if_index;
443 
445  ~0);
447 
448  /* setup l2 input config with l2 feature and bd 0 to drop packet */
449  vec_validate (l2im->configs, sw_if_index);
450  l2im->configs[sw_if_index].feature_bitmap = L2INPUT_FEAT_DROP;
451  l2im->configs[sw_if_index].bd_index = 0;
452 
453  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
455  vnet_sw_interface_set_flags (vnm, sw_if_index,
457 
459  fib_prefix_t tun_remote_pfx;
461 
462  fib_prefix_from_ip46_addr (&t->remote, &tun_remote_pfx);
464  {
465  /* Unicast tunnel -
466  * source the FIB entry for the tunnel's destination
467  * and become a child thereof. The tunnel will then get poked
468  * when the forwarding for the entry updates, and the tunnel can
469  * re-stack accordingly
470  */
473  &tun_remote_pfx,
475  t - vxm->tunnels,
476  &t->sibling_index);
478  }
479  else
480  {
481  /* Multicast tunnel -
482  * as the same mcast group can be used for mutiple mcast tunnels
483  * with different VNIs, create the output fib adjecency only if
484  * it does not already exist
485  */
486  fib_protocol_t fp = fib_ip_proto (is_ip6);
487 
488  if (vtep_addr_ref (&vxm->vtep_table,
489  t->encap_fib_index, &t->remote) == 1)
490  {
491  fib_node_index_t mfei;
492  adj_index_t ai;
494  .frp_proto = fib_proto_to_dpo (fp),
495  .frp_addr = zero_addr,
496  .frp_sw_if_index = 0xffffffff,
497  .frp_fib_index = ~0,
498  .frp_weight = 1,
499  .frp_flags = FIB_ROUTE_PATH_LOCAL,
500  .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
501  };
502  const mfib_prefix_t mpfx = {
503  .fp_proto = fp,
504  .fp_len = (is_ip6 ? 128 : 32),
505  .fp_grp_addr = tun_remote_pfx.fp_addr,
506  };
507 
508  /*
509  * Setup the (*,G) to receive traffic on the mcast group
510  * - the forwarding interface is for-us
511  * - the accepting interface is that from the API
512  */
514  &mpfx, MFIB_SOURCE_GENEVE, &path);
515 
520  &mpfx,
521  MFIB_SOURCE_GENEVE, &path);
522 
523  /*
524  * Create the mcast adjacency to send traffic to the group
525  */
526  ai = adj_mcast_add_or_lock (fp,
527  fib_proto_to_link (fp),
528  a->mcast_sw_if_index);
529 
530  /*
531  * create a new end-point
532  */
533  mcast_shared_add (&t->remote, mfei, ai);
534  }
535 
536  dpo_id_t dpo = DPO_INVALID;
537  mcast_shared_t ep = mcast_shared_get (&t->remote);
538 
539  /* Stack shared mcast remote mac addr rewrite on encap */
541  fib_proto_to_dpo (fp), ep.mcast_adj_index);
542 
543  dpo_stack_from_node (encap_index, &t->next_dpo, &dpo);
544  dpo_reset (&dpo);
545  flood_class = VNET_FLOOD_CLASS_TUNNEL_MASTER;
546  }
547 
548  vnet_get_sw_interface (vnet_get_main (), sw_if_index)->flood_class =
549  flood_class;
550  }
551  else
552  {
553  /* deleting a tunnel: tunnel must exist */
554  if (!p)
555  return VNET_API_ERROR_NO_SUCH_ENTRY;
556 
557  t = pool_elt_at_index (vxm->tunnels, p[0]);
558 
559  sw_if_index = t->sw_if_index;
560  vnet_sw_interface_set_flags (vnm, t->sw_if_index, 0 /* down */ );
563 
564  /* make sure tunnel is removed from l2 bd or xconnect */
565  set_int_l2_mode (vxm->vlib_main, vnm, MODE_L3, t->sw_if_index, 0,
566  L2_BD_PORT_TYPE_NORMAL, 0, 0);
568 
570 
571  if (!is_ip6)
572  hash_unset (vxm->geneve4_tunnel_by_key, key4.as_u64);
573  else
575 
577  {
580  }
581  else if (vtep_addr_unref (&vxm->vtep_table,
582  t->encap_fib_index, &t->remote) == 0)
583  {
585  }
586 
587  fib_node_deinit (&t->node);
588  vec_free (t->rewrite);
589  pool_put (vxm->tunnels, t);
590  }
591 
592  if (sw_if_indexp)
593  *sw_if_indexp = sw_if_index;
594 
595  if (a->is_add)
596  {
597  /* register udp ports */
598  if (!is_ip6 && !udp_is_valid_dst_port (UDP_DST_PORT_geneve, 1))
599  udp_register_dst_port (vxm->vlib_main, UDP_DST_PORT_geneve,
600  geneve4_input_node.index, 1);
601  if (is_ip6 && !udp_is_valid_dst_port (UDP_DST_PORT_geneve6, 0))
602  udp_register_dst_port (vxm->vlib_main, UDP_DST_PORT_geneve6,
603  geneve6_input_node.index, 0);
604  }
605 
606  return 0;
607 }
608 
609 static uword
610 get_decap_next_for_node (u32 node_index, u32 ipv4_set)
611 {
612  geneve_main_t *vxm = &geneve_main;
613  vlib_main_t *vm = vxm->vlib_main;
614  uword input_node = (ipv4_set) ? geneve4_input_node.index :
615  geneve6_input_node.index;
616 
617  return vlib_node_add_next (vm, input_node, node_index);
618 }
619 
620 static uword
621 unformat_decap_next (unformat_input_t * input, va_list * args)
622 {
623  u32 *result = va_arg (*args, u32 *);
624  u32 ipv4_set = va_arg (*args, int);
625  geneve_main_t *vxm = &geneve_main;
626  vlib_main_t *vm = vxm->vlib_main;
627  u32 node_index;
628  u32 tmp;
629 
630  if (unformat (input, "l2"))
631  *result = GENEVE_INPUT_NEXT_L2_INPUT;
632  else if (unformat (input, "node %U", unformat_vlib_node, vm, &node_index))
633  *result = get_decap_next_for_node (node_index, ipv4_set);
634  else if (unformat (input, "%d", &tmp))
635  *result = tmp;
636  else
637  return 0;
638  return 1;
639 }
640 
641 static clib_error_t *
643  unformat_input_t * input,
644  vlib_cli_command_t * cmd)
645 {
646  unformat_input_t _line_input, *line_input = &_line_input;
647  ip46_address_t local, remote;
648  u8 is_add = 1;
649  u8 local_set = 0;
650  u8 remote_set = 0;
651  u8 grp_set = 0;
652  u8 ipv4_set = 0;
653  u8 ipv6_set = 0;
654  u32 encap_fib_index = 0;
655  u32 mcast_sw_if_index = ~0;
656  u32 decap_next_index = GENEVE_INPUT_NEXT_L2_INPUT;
657  u32 vni = 0;
658  u32 tmp;
659  int rv;
661  u32 tunnel_sw_if_index;
662  clib_error_t *error = NULL;
663 
664  /* Cant "universally zero init" (={0}) due to GCC bug 53119 */
665  clib_memset (&local, 0, sizeof local);
666  clib_memset (&remote, 0, sizeof remote);
667 
668  /* Get a line of input. */
669  if (!unformat_user (input, unformat_line_input, line_input))
670  return 0;
671 
672  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
673  {
674  if (unformat (line_input, "del"))
675  {
676  is_add = 0;
677  }
678  else if (unformat (line_input, "local %U",
679  unformat_ip4_address, &local.ip4))
680  {
681  local_set = 1;
682  ipv4_set = 1;
683  }
684  else if (unformat (line_input, "remote %U",
685  unformat_ip4_address, &remote.ip4))
686  {
687  remote_set = 1;
688  ipv4_set = 1;
689  }
690  else if (unformat (line_input, "local %U",
691  unformat_ip6_address, &local.ip6))
692  {
693  local_set = 1;
694  ipv6_set = 1;
695  }
696  else if (unformat (line_input, "remote %U",
697  unformat_ip6_address, &remote.ip6))
698  {
699  remote_set = 1;
700  ipv6_set = 1;
701  }
702  else if (unformat (line_input, "group %U %U",
703  unformat_ip4_address, &remote.ip4,
705  vnet_get_main (), &mcast_sw_if_index))
706  {
707  grp_set = remote_set = 1;
708  ipv4_set = 1;
709  }
710  else if (unformat (line_input, "group %U %U",
711  unformat_ip6_address, &remote.ip6,
713  vnet_get_main (), &mcast_sw_if_index))
714  {
715  grp_set = remote_set = 1;
716  ipv6_set = 1;
717  }
718  else if (unformat (line_input, "encap-vrf-id %d", &tmp))
719  {
720  encap_fib_index = fib_table_find (fib_ip_proto (ipv6_set), tmp);
721  if (encap_fib_index == ~0)
722  {
723  error =
724  clib_error_return (0, "nonexistent encap-vrf-id %d", tmp);
725  goto done;
726  }
727  }
728  else if (unformat (line_input, "decap-next %U", unformat_decap_next,
729  &decap_next_index, ipv4_set))
730  ;
731  else if (unformat (line_input, "vni %d", &vni))
732  {
733  if (vni >> 24)
734  {
735  error = clib_error_return (0, "vni %d out of range", vni);
736  goto done;
737  }
738  }
739  else
740  {
741  error = clib_error_return (0, "parse error: '%U'",
742  format_unformat_error, line_input);
743  goto done;
744  }
745  }
746 
747  if (local_set == 0)
748  {
749  error = clib_error_return (0, "tunnel local address not specified");
750  goto done;
751  }
752 
753  if (remote_set == 0)
754  {
755  error = clib_error_return (0, "tunnel remote address not specified");
756  goto done;
757  }
758 
759  if (grp_set && !ip46_address_is_multicast (&remote))
760  {
761  error = clib_error_return (0, "tunnel group address not multicast");
762  goto done;
763  }
764 
765  if (grp_set == 0 && ip46_address_is_multicast (&remote))
766  {
767  error = clib_error_return (0, "remote address must be unicast");
768  goto done;
769  }
770 
771  if (grp_set && mcast_sw_if_index == ~0)
772  {
773  error = clib_error_return (0, "tunnel nonexistent multicast device");
774  goto done;
775  }
776 
777  if (ipv4_set && ipv6_set)
778  {
779  error = clib_error_return (0, "both IPv4 and IPv6 addresses specified");
780  goto done;
781  }
782 
783  if (ip46_address_cmp (&local, &remote) == 0)
784  {
785  error =
786  clib_error_return (0, "local and remote addresses are identical");
787  goto done;
788  }
789 
790  if (decap_next_index == ~0)
791  {
792  error = clib_error_return (0, "next node not found");
793  goto done;
794  }
795 
796  if (vni == 0)
797  {
798  error = clib_error_return (0, "vni not specified");
799  goto done;
800  }
801 
802  clib_memset (a, 0, sizeof (*a));
803 
804  a->is_add = is_add;
805  a->is_ip6 = ipv6_set;
806 
807 #define _(x) a->x = x;
809 #undef _
810 
811  rv = vnet_geneve_add_del_tunnel (a, &tunnel_sw_if_index);
812 
813  switch (rv)
814  {
815  case 0:
816  if (is_add)
818  vnet_get_main (), tunnel_sw_if_index);
819  break;
820 
821  case VNET_API_ERROR_TUNNEL_EXIST:
822  error = clib_error_return (0, "tunnel already exists...");
823  goto done;
824 
825  case VNET_API_ERROR_NO_SUCH_ENTRY:
826  error = clib_error_return (0, "tunnel does not exist...");
827  goto done;
828 
829  default:
830  error = clib_error_return
831  (0, "vnet_geneve_add_del_tunnel returned %d", rv);
832  goto done;
833  }
834 
835 done:
836  unformat_free (line_input);
837 
838  return error;
839 }
840 
841 /*?
842  * Add or delete a GENEVE Tunnel.
843  *
844  * GENEVE provides the features needed to allow L2 bridge domains (BDs)
845  * to span multiple servers. This is done by building an L2 overlay on
846  * top of an L3 network underlay using GENEVE tunnels.
847  *
848  * This makes it possible for servers to be co-located in the same data
849  * center or be separated geographically as long as they are reachable
850  * through the underlay L3 network.
851  *
852  * You can refer to this kind of L2 overlay bridge domain as a GENEVE
853  * segment.
854  *
855  * @cliexpar
856  * Example of how to create a GENEVE Tunnel:
857  * @cliexcmd{create geneve tunnel local 10.0.3.1 remote 10.0.3.3 vni 13 encap-vrf-id 7}
858  * Example of how to delete a GENEVE Tunnel:
859  * @cliexcmd{create geneve tunnel local 10.0.3.1 remote 10.0.3.3 vni 13 del}
860  ?*/
861 /* *INDENT-OFF* */
862 VLIB_CLI_COMMAND (create_geneve_tunnel_command, static) = {
863  .path = "create geneve tunnel",
864  .short_help =
865  "create geneve tunnel local <local-vtep-addr>"
866  " {remote <remote-vtep-addr>|group <mcast-vtep-addr> <intf-name>} vni <nn>"
867  " [encap-vrf-id <nn>] [decap-next [l2|node <name>]] [del]",
869 };
870 /* *INDENT-ON* */
871 
872 static clib_error_t *
874  unformat_input_t * input,
875  vlib_cli_command_t * cmd)
876 {
877  geneve_main_t *vxm = &geneve_main;
878  geneve_tunnel_t *t;
879 
880  if (pool_elts (vxm->tunnels) == 0)
881  vlib_cli_output (vm, "No geneve tunnels configured...");
882 
883  pool_foreach (t, vxm->tunnels, (
884  {
885  vlib_cli_output (vm, "%U",
886  format_geneve_tunnel, t);
887  }
888  ));
889 
890  return 0;
891 }
892 
893 /*?
894  * Display all the GENEVE Tunnel entries.
895  *
896  * @cliexpar
897  * Example of how to display the GENEVE Tunnel entries:
898  * @cliexstart{show geneve tunnel}
899  * [0] local 10.0.3.1 remote 10.0.3.3 vni 13 encap_fib_index 0 sw_if_index 5 decap_next l2
900  * @cliexend
901  ?*/
902 /* *INDENT-OFF* */
903 VLIB_CLI_COMMAND (show_geneve_tunnel_command, static) = {
904  .path = "show geneve tunnel",
905  .short_help = "show geneve tunnel",
906  .function = show_geneve_tunnel_command_fn,
907 };
908 /* *INDENT-ON* */
909 
910 
911 void
913 {
914  if (is_ip6)
915  vnet_feature_enable_disable ("ip6-unicast", "ip6-geneve-bypass",
916  sw_if_index, is_enable, 0, 0);
917  else
918  vnet_feature_enable_disable ("ip4-unicast", "ip4-geneve-bypass",
919  sw_if_index, is_enable, 0, 0);
920 }
921 
922 
923 static clib_error_t *
925  unformat_input_t * input, vlib_cli_command_t * cmd)
926 {
927  unformat_input_t _line_input, *line_input = &_line_input;
928  vnet_main_t *vnm = vnet_get_main ();
929  clib_error_t *error = 0;
930  u32 sw_if_index, is_enable;
931 
932  sw_if_index = ~0;
933  is_enable = 1;
934 
935  if (!unformat_user (input, unformat_line_input, line_input))
936  return 0;
937 
938  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
939  {
940  if (unformat_user
941  (line_input, unformat_vnet_sw_interface, vnm, &sw_if_index))
942  ;
943  else if (unformat (line_input, "del"))
944  is_enable = 0;
945  else
946  {
947  error = unformat_parse_error (line_input);
948  goto done;
949  }
950  }
951 
952  if (~0 == sw_if_index)
953  {
954  error = clib_error_return (0, "unknown interface `%U'",
955  format_unformat_error, line_input);
956  goto done;
957  }
958 
959  vnet_int_geneve_bypass_mode (sw_if_index, is_ip6, is_enable);
960 
961 done:
962  unformat_free (line_input);
963 
964  return error;
965 }
966 
967 static clib_error_t *
969  unformat_input_t * input, vlib_cli_command_t * cmd)
970 {
971  return set_ip_geneve_bypass (0, input, cmd);
972 }
973 
974 /*?
975  * This command adds the 'ip4-geneve-bypass' graph node for a given interface.
976  * By adding the IPv4 geneve-bypass graph node to an interface, the node checks
977  * for and validate input geneve packet and bypass ip4-lookup, ip4-local,
978  * ip4-udp-lookup nodes to speedup geneve packet forwarding. This node will
979  * cause extra overhead to for non-geneve packets which is kept at a minimum.
980  *
981  * @cliexpar
982  * @parblock
983  * Example of graph node before ip4-geneve-bypass is enabled:
984  * @cliexstart{show vlib graph ip4-geneve-bypass}
985  * Name Next Previous
986  * ip4-geneve-bypass error-drop [0]
987  * geneve4-input [1]
988  * ip4-lookup [2]
989  * @cliexend
990  *
991  * Example of how to enable ip4-geneve-bypass on an interface:
992  * @cliexcmd{set interface ip geneve-bypass GigabitEthernet2/0/0}
993  *
994  * Example of graph node after ip4-geneve-bypass is enabled:
995  * @cliexstart{show vlib graph ip4-geneve-bypass}
996  * Name Next Previous
997  * ip4-geneve-bypass error-drop [0] ip4-input
998  * geneve4-input [1] ip4-input-no-checksum
999  * ip4-lookup [2]
1000  * @cliexend
1001  *
1002  * Example of how to display the feature enabed on an interface:
1003  * @cliexstart{show ip interface features GigabitEthernet2/0/0}
1004  * IP feature paths configured on GigabitEthernet2/0/0...
1005  * ...
1006  * ipv4 unicast:
1007  * ip4-geneve-bypass
1008  * ip4-lookup
1009  * ...
1010  * @cliexend
1011  *
1012  * Example of how to disable ip4-geneve-bypass on an interface:
1013  * @cliexcmd{set interface ip geneve-bypass GigabitEthernet2/0/0 del}
1014  * @endparblock
1015 ?*/
1016 /* *INDENT-OFF* */
1017 VLIB_CLI_COMMAND (set_interface_ip_geneve_bypass_command, static) = {
1018  .path = "set interface ip geneve-bypass",
1019  .function = set_ip4_geneve_bypass,
1020  .short_help = "set interface ip geneve-bypass <interface> [del]",
1021 };
1022 /* *INDENT-ON* */
1023 
1024 static clib_error_t *
1026  unformat_input_t * input, vlib_cli_command_t * cmd)
1027 {
1028  return set_ip_geneve_bypass (1, input, cmd);
1029 }
1030 
1031 /*?
1032  * This command adds the 'ip6-geneve-bypass' graph node for a given interface.
1033  * By adding the IPv6 geneve-bypass graph node to an interface, the node checks
1034  * for and validate input geneve packet and bypass ip6-lookup, ip6-local,
1035  * ip6-udp-lookup nodes to speedup geneve packet forwarding. This node will
1036  * cause extra overhead to for non-geneve packets which is kept at a minimum.
1037  *
1038  * @cliexpar
1039  * @parblock
1040  * Example of graph node before ip6-geneve-bypass is enabled:
1041  * @cliexstart{show vlib graph ip6-geneve-bypass}
1042  * Name Next Previous
1043  * ip6-geneve-bypass error-drop [0]
1044  * geneve6-input [1]
1045  * ip6-lookup [2]
1046  * @cliexend
1047  *
1048  * Example of how to enable ip6-geneve-bypass on an interface:
1049  * @cliexcmd{set interface ip6 geneve-bypass GigabitEthernet2/0/0}
1050  *
1051  * Example of graph node after ip6-geneve-bypass is enabled:
1052  * @cliexstart{show vlib graph ip6-geneve-bypass}
1053  * Name Next Previous
1054  * ip6-geneve-bypass error-drop [0] ip6-input
1055  * geneve6-input [1] ip4-input-no-checksum
1056  * ip6-lookup [2]
1057  * @cliexend
1058  *
1059  * Example of how to display the feature enabed on an interface:
1060  * @cliexstart{show ip interface features GigabitEthernet2/0/0}
1061  * IP feature paths configured on GigabitEthernet2/0/0...
1062  * ...
1063  * ipv6 unicast:
1064  * ip6-geneve-bypass
1065  * ip6-lookup
1066  * ...
1067  * @cliexend
1068  *
1069  * Example of how to disable ip6-geneve-bypass on an interface:
1070  * @cliexcmd{set interface ip6 geneve-bypass GigabitEthernet2/0/0 del}
1071  * @endparblock
1072 ?*/
1073 /* *INDENT-OFF* */
1074 VLIB_CLI_COMMAND (set_interface_ip6_geneve_bypass_command, static) = {
1075  .path = "set interface ip6 geneve-bypass",
1076  .function = set_ip6_geneve_bypass,
1077  .short_help = "set interface ip6 geneve-bypass <interface> [del]",
1078 };
1079 /* *INDENT-ON* */
1080 
1081 clib_error_t *
1083 {
1084  geneve_main_t *vxm = &geneve_main;
1085 
1086  vxm->vnet_main = vnet_get_main ();
1087  vxm->vlib_main = vm;
1088 
1089  /* initialize the ip6 hash */
1091  sizeof (geneve6_tunnel_key_t),
1092  sizeof (uword));
1093  vxm->vtep_table = vtep_table_create ();
1094  vxm->mcast_shared = hash_create_mem (0,
1095  sizeof (ip46_address_t),
1096  sizeof (mcast_shared_t));
1097 
1099 
1100  return 0;
1101 }
1102 
1104 
1105 /*
1106  * fd.io coding-style-patch-verification: ON
1107  *
1108  * Local Variables:
1109  * eval: (c-set-style "gnu")
1110  * End:
1111  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:507
vlib_main_t * vlib_main
Definition: geneve.h:183
void vnet_set_interface_output_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Set interface output node - for interface registered without its output/tx nodes created because its ...
static void vnet_geneve_hdr_1word_hton(geneve_header_t *h)
static clib_error_t * set_ip6_geneve_bypass(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: geneve.c:1025
void dpo_stack_from_node(u32 child_node_index, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child parent relationship.
Definition: dpo.c:531
fib_node_index_t fib_entry_track(u32 fib_index, const fib_prefix_t *prefix, fib_node_type_t child_type, index_t child_index, u32 *sibling)
Trackers are used on FIB entries by objects that which to track the changing state of the entry...
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:113
#define hash_set(h, key, value)
Definition: hash.h:255
l2_input_config_t * configs
Definition: l2_input.h:62
static u8 * format_geneve_header_with_length(u8 *s, va_list *args)
Definition: geneve.c:118
#define CLIB_UNUSED(x)
Definition: clib.h:86
uword vtep_addr_ref(vtep_table_t *t, u32 fib_index, ip46_address_t *ip)
Definition: vtep.c:19
u32 hw_if_index
Definition: geneve.h:117
static uword ip46_address_is_multicast(const ip46_address_t *a)
Definition: ip46_address.h:154
#define hash_unset(h, key)
Definition: hash.h:261
A representation of a path as described by a route producer.
Definition: fib_types.h:490
ip4_address_t src_address
Definition: ip4_packet.h:170
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static void mcast_shared_add(ip46_address_t *remote, fib_node_index_t mfei, adj_index_t ai)
Definition: geneve.c:317
vnet_interface_main_t interface_main
Definition: vnet.h:56
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:185
u64 as_u64
Definition: bihash_doc.h:63
u32 * free_geneve_tunnel_hw_if_indices
Definition: geneve.h:177
fib_node_index_t mfib_table_entry_path_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath)
Add n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:325
u32 frp_mitf_flags
MFIB interface flags.
Definition: fib_types.h:559
static mcast_shared_t mcast_shared_get(ip46_address_t *ip)
Definition: geneve.c:306
unsigned long u64
Definition: types.h:89
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 decap_next_index
Definition: geneve.h:110
fib_node_t node
Linkage into the FIB object graph.
Definition: geneve.h:122
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
void fib_entry_contribute_forwarding(fib_node_index_t fib_entry_index, fib_forward_chain_type_t fct, dpo_id_t *dpo)
Definition: fib_entry.c:437
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:590
#define foreach_copy_field
Definition: geneve.c:204
static geneve_tunnel_t * geneve_tunnel_from_fib_node(fib_node_t *node)
Definition: geneve.c:148
u32 mcast_sw_if_index
Definition: geneve.h:107
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:109
static clib_error_t * geneve_add_del_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: geneve.c:642
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:69
void fib_node_deinit(fib_node_t *node)
Definition: fib_node.c:197
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
dpo_id_t next_dpo
Definition: geneve.h:92
unformat_function_t unformat_vnet_sw_interface
vl_api_fib_path_t path
Definition: mfib_types.api:34
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:518
uword * mcast_shared
Definition: geneve.h:174
int vnet_geneve_add_del_tunnel(vnet_geneve_add_del_tunnel_args_t *a, u32 *sw_if_indexp)
Definition: geneve.c:340
static u8 ip46_address_is_ip4(const ip46_address_t *ip46)
Definition: ip46_address.h:55
u32 * tunnel_index_by_sw_if_index
Definition: geneve.h:180
vlib_node_registration_t geneve6_encap_node
(constructor) VLIB_REGISTER_NODE (geneve6_encap_node)
Definition: encap.c:561
u8 * format_geneve_encap_trace(u8 *s, va_list *args)
Definition: geneve.c:42
ip6_address_t src_address
Definition: ip6_packet.h:310
format_function_t format_vnet_sw_if_index_name
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1092
unsigned char u8
Definition: types.h:56
geneve_tunnel_t * tunnels
Definition: geneve.h:163
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
void fib_node_register_type(fib_node_type_t type, const fib_node_vft_t *vft)
fib_node_register_type
Definition: fib_node.c:60
static clib_error_t * show_geneve_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: geneve.c:873
VNET_HW_INTERFACE_CLASS(geneve_hw_class)
vnet_flood_class_t flood_class
Definition: interface.h:749
clib_error_t * geneve_init(vlib_main_t *vm)
Definition: geneve.c:1082
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
unformat_function_t unformat_ip4_address
Definition: format.h:68
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:530
static fib_node_back_walk_rc_t geneve_tunnel_back_walk(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
Function definition to backwalk a FIB node - Here we will restack the new dpo of GENEVE DIP to encap ...
Definition: geneve.c:160
vl_api_interface_index_t sw_if_index
Definition: gre.api:53
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static void vnet_set_geneve_oamframe_bit(geneve_header_t *h, u8 oam)
u8 * rewrite
Definition: geneve.h:89
void mfib_table_entry_delete_index(fib_node_index_t mfib_entry_index, mfib_source_t source)
Delete a FIB entry.
Definition: mfib_table.c:517
ip4_address_t dst_address
Definition: ip4_packet.h:170
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:867
static int ip46_address_cmp(const ip46_address_t *ip46_1, const ip46_address_t *ip46_2)
Definition: ip46_address.h:80
vl_api_interface_index_t mcast_sw_if_index
Definition: vxlan_gbp.api:41
Aggregate type for a prefix.
Definition: fib_types.h:203
#define clib_error_return(e, args...)
Definition: error.h:99
static void vnet_set_geneve_options_len(geneve_header_t *h, u8 len)
vtep_table_t vtep_table
Definition: geneve.h:171
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:325
#define ALWAYS_ASSERT(truth)
static clib_error_t * set_ip_geneve_bypass(u32 is_ip6, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: geneve.c:924
unsigned int u32
Definition: types.h:88
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1097
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
Definition: interface.c:768
bool is_ip6
Definition: ip.api:43
unformat_function_t unformat_line_input
Definition: format.h:283
static void vnet_set_geneve_vni(geneve_header_t *h, u32 vni)
#define GENEVE_ETH_PROTOCOL
Definition: geneve_packet.h:99
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:661
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread counters.
Definition: counter.h:285
uword vtep_addr_unref(vtep_table_t *t, u32 fib_index, ip46_address_t *ip)
Definition: vtep.c:34
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
u32 encap_fib_index
Definition: geneve.h:113
long ctx[MAX_CONNS]
Definition: main.c:144
static clib_error_t * set_ip4_geneve_bypass(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: geneve.c:968
struct _unformat_input_t unformat_input_t
u32 vni
Definition: lisp_gpe.api:119
u8 * format_geneve_tunnel(u8 *s, va_list *args)
Definition: geneve.c:71
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
#define PREDICT_FALSE(x)
Definition: clib.h:118
static void vnet_set_geneve_version(geneve_header_t *h, u8 version)
vnet_sw_interface_flags_t flags
Definition: interface.h:724
static u8 * format_geneve_name(u8 *s, va_list *args)
Definition: geneve.c:92
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:866
static void vnet_set_geneve_protocol(geneve_header_t *h, u16 protocol)
fib_node_type_t fn_type
The node&#39;s type.
Definition: fib_node.h:299
An node in the FIB graph.
Definition: fib_node.h:295
static void geneve_tunnel_last_lock_gone(fib_node_t *node)
Function definition to inform the FIB node that its last lock has gone.
Definition: geneve.c:184
vlib_main_t * vm
Definition: in2out_ed.c:1599
u8 len
Definition: ip_types.api:92
format_function_t format_ip46_address
Definition: ip46_address.h:50
unformat_function_t unformat_ip6_address
Definition: format.h:89
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:246
vlib_node_registration_t geneve4_input_node
(constructor) VLIB_REGISTER_NODE (geneve4_input_node)
Definition: decap.c:816
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
u32 flags
Definition: vhost_user.h:248
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
ip46_address_t local
Definition: geneve.h:103
vnet_flood_class_t
Definition: interface.h:665
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:89
fib_node_get_t fnv_get
Definition: fib_node.h:283
static void vnet_interface_counter_unlock(vnet_interface_main_t *im)
Definition: interface.h:897
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
void fib_prefix_from_ip46_addr(const ip46_address_t *addr, fib_prefix_t *pfx)
Host prefix from ip.
Definition: fib_types.c:81
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:186
uword * geneve4_tunnel_by_key
Definition: geneve.h:166
Aggregate type for a prefix.
Definition: mfib_types.h:24
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1599
u8 * default_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
Return a complete, zero-length (aka dummy) rewrite.
Definition: interface.c:1635
Context passed between object during a back walk.
Definition: fib_node.h:208
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
static void vnet_interface_counter_lock(vnet_interface_main_t *im)
Definition: interface.h:890
VNET_DEVICE_CLASS(geneve_device_class, static)
u32 sw_if_index
Definition: geneve.h:116
#define ASSERT(truth)
void fib_entry_untrack(fib_node_index_t fei, u32 sibling)
Stop tracking a FIB entry.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
u32 set_int_l2_mode(vlib_main_t *vm, vnet_main_t *vnet_main, u32 mode, u32 sw_if_index, u32 bd_index, l2_bd_port_type_t port_type, u32 shg, u32 xc_sw_if_index)
Set the subinterface to run in l2 or l3 mode.
Definition: l2_input.c:591
enum fib_forward_chain_type_t_ fib_forward_chain_type_t
FIB output chain type.
static fib_node_t * geneve_tunnel_fib_node_get(fib_node_index_t index)
Function definition to get a FIB node from its index.
Definition: geneve.c:170
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:600
static void geneve_tunnel_restack_dpo(geneve_tunnel_t *t)
Definition: geneve.c:134
static void hash_unset_mem_free(uword **h, const void *key)
Definition: hash.h:295
static void vlib_zero_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
Clear a simple counter Clears the set of per-thread u16 counters, and the u64 counter.
Definition: counter.h:139
u32 sibling_index
The tunnel is a child of the FIB entry for its desintion.
Definition: geneve.h:137
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:324
static int geneve_rewrite(geneve_tunnel_t *t, bool is_ip6)
Definition: geneve.c:213
static vtep_table_t vtep_table_create()
Definition: vtep.h:70
vl_api_ip4_address_t hi
Definition: arp.api:37
static void vnet_set_geneve_critical_bit(geneve_header_t *h, u8 critical_opts)
vnet_main_t * vnet_main
Definition: geneve.h:184
static clib_error_t * geneve_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: geneve.c:99
#define unformat_parse_error(input)
Definition: format.h:269
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:297
fib_protocol_t fp_proto
protocol type
Definition: mfib_types.h:33
l2input_main_t l2input_main
Definition: l2_input.c:128
ip46_address_t remote
Definition: geneve.h:104
vl_api_address_t ip
Definition: l2.api:501
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:186
A for-us/local path.
Definition: fib_types.h:338
bool udp_is_valid_dst_port(udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:529
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define GENEVE_VNI_SHIFT
static fib_protocol_t fib_ip_proto(bool is_ip6)
Convert from boolean is_ip6 to FIB protocol.
Definition: fib_types.h:80
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
Definition: interface.c:498
u64 uword
Definition: types.h:112
uword * geneve6_tunnel_by_key
Definition: geneve.h:167
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
fib_node_index_t fib_entry_index
Definition: geneve.h:128
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
#define GENEVE_VERSION
Definition: geneve_packet.h:98
static uword get_decap_next_for_node(u32 node_index, u32 ipv4_set)
Definition: geneve.c:610
static void mcast_shared_remove(ip46_address_t *remote)
Definition: geneve.c:329
unformat_function_t unformat_vlib_node
Definition: node_funcs.h:1147
#define hash_get_mem(h, key)
Definition: hash.h:269
A FIB graph nodes virtual function table.
Definition: fib_node.h:282
vlib_node_registration_t geneve6_input_node
(constructor) VLIB_REGISTER_NODE (geneve6_input_node)
Definition: decap.c:834
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static u8 * format_decap_next(u8 *s, va_list *args)
Definition: geneve.c:54
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
Definition: interface.c:507
geneve_main_t geneve_main
Definition: geneve.c:39
adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto, vnet_link_t link_type, u32 sw_if_index)
Mcast Adjacency.
Definition: adj_mcast.c:51
static bool geneve_decap_next_is_valid(geneve_main_t *vxm, u32 is_ip6, u32 decap_next_index)
Definition: geneve.c:284
static uword unformat_decap_next(unformat_input_t *input, va_list *args)
Definition: geneve.c:621
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
vlib_node_registration_t geneve4_encap_node
(constructor) VLIB_REGISTER_NODE (geneve4_encap_node)
Definition: encap.c:548
vnet_link_t fib_proto_to_link(fib_protocol_t proto)
Convert from a protocol to a link type.
Definition: fib_types.c:358
static void hash_set_mem_alloc(uword **h, const void *key, uword v)
Definition: hash.h:279
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
Definition: udp_local.c:468
u8 si
Definition: lisp_types.api:47
u8 ip_version_and_header_length
Definition: ip4_packet.h:138
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:554
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:247
const ip46_address_t zero_addr
Definition: lookup.c:181
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:304
ip6_address_t dst_address
Definition: ip6_packet.h:310
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
#define MODE_L3
Definition: l2_input.h:220
void vnet_int_geneve_bypass_mode(u32 sw_if_index, u8 is_ip6, u8 is_enable)
Definition: geneve.c:912
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128