FD.io VPP  v20.09-64-g4f7b92f0a
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  s = format (s, "l3-mode %u ", t->l3_mode);
85 
87  s = format (s, "mcast-sw-if-idx %d ", t->mcast_sw_if_index);
88 
89  return s;
90 }
91 
92 static u8 *
93 format_geneve_name (u8 * s, va_list * args)
94 {
95  u32 dev_instance = va_arg (*args, u32);
96  return format (s, "geneve_tunnel%d", dev_instance);
97 }
98 
99 static clib_error_t *
101 {
102  u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
104  vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
105 
106  return /* no error */ 0;
107 }
108 
109 static clib_error_t *
111  const u8 * old_address, const u8 * mac_address)
112 {
113  l2input_interface_mac_change (hi->sw_if_index, old_address, mac_address);
114  return (NULL);
115 }
116 
117 /* *INDENT-OFF* */
118 VNET_DEVICE_CLASS (geneve_device_class, static) = {
119  .name = "GENEVE",
120  .format_device_name = format_geneve_name,
121  .format_tx_trace = format_geneve_encap_trace,
122  .admin_up_down_function = geneve_interface_admin_up_down,
123  .mac_addr_change_function = geneve_mac_change,
124 };
125 /* *INDENT-ON* */
126 
127 static u8 *
129 {
130  u32 dev_instance = va_arg (*args, u32);
131  s = format (s, "unimplemented dev %u", dev_instance);
132  return s;
133 }
134 
135 /* *INDENT-OFF* */
136 VNET_HW_INTERFACE_CLASS (geneve_hw_class) = {
137  .name = "GENEVE",
138  .format_header = format_geneve_header_with_length,
139  .build_rewrite = default_build_rewrite,
140 };
141 /* *INDENT-ON* */
142 
143 static void
145 {
146  dpo_id_t dpo = DPO_INVALID;
147  u32 encap_index = ip46_address_is_ip4 (&t->remote) ?
151 
152  fib_entry_contribute_forwarding (t->fib_entry_index, forw_type, &dpo);
153  dpo_stack_from_node (encap_index, &t->next_dpo, &dpo);
154  dpo_reset (&dpo);
155 }
156 
157 static geneve_tunnel_t *
159 {
161  return ((geneve_tunnel_t *) (((char *) node) -
163 }
164 
165 /**
166  * Function definition to backwalk a FIB node -
167  * Here we will restack the new dpo of GENEVE DIP to encap node.
168  */
171 {
174 }
175 
176 /**
177  * Function definition to get a FIB node from its index
178  */
179 static fib_node_t *
181 {
182  geneve_tunnel_t *t;
183  geneve_main_t *vxm = &geneve_main;
184 
185  t = pool_elt_at_index (vxm->tunnels, index);
186 
187  return (&t->node);
188 }
189 
190 /**
191  * Function definition to inform the FIB node that its last lock has gone.
192  */
193 static void
195 {
196  /*
197  * The GENEVE tunnel is a root of the graph. As such
198  * it never has children and thus is never locked.
199  */
200  ASSERT (0);
201 }
202 
203 /*
204  * Virtual function table registered by GENEVE tunnels
205  * for participation in the FIB object graph.
206  */
207 const static fib_node_vft_t geneve_vft = {
209  .fnv_last_lock = geneve_tunnel_last_lock_gone,
210  .fnv_back_walk = geneve_tunnel_back_walk,
211 };
212 
213 
214 #define foreach_copy_field \
215 _(vni) \
216 _(mcast_sw_if_index) \
217 _(encap_fib_index) \
218 _(decap_next_index) \
219 _(local) \
220 _(remote) \
221 _(l3_mode)
222 
223 static int
225 {
226  union
227  {
228  ip4_geneve_header_t *h4;
229  ip6_geneve_header_t *h6;
230  u8 *rw;
231  } r =
232  {
233  .rw = 0};
234  int len = is_ip6 ? sizeof *r.h6 : sizeof *r.h4;
235 #if SUPPORT_OPTIONS_HEADER==1
236  len += t->options_len;
237 #endif
238 
240 
241  udp_header_t *udp;
242  geneve_header_t *geneve;
243  /* Fixed portion of the (outer) ip header */
244  if (!is_ip6)
245  {
246  ip4_header_t *ip = &r.h4->ip4;
247  udp = &r.h4->udp, geneve = &r.h4->geneve;
248  ip->ip_version_and_header_length = 0x45;
249  ip->ttl = 254;
250  ip->protocol = IP_PROTOCOL_UDP;
251 
252  ip->src_address = t->local.ip4;
253  ip->dst_address = t->remote.ip4;
254 
255  /* we fix up the ip4 header length and checksum after-the-fact */
256  ip->checksum = ip4_header_checksum (ip);
257  }
258  else
259  {
260  ip6_header_t *ip = &r.h6->ip6;
261  udp = &r.h6->udp, geneve = &r.h6->geneve;
263  clib_host_to_net_u32 (6 << 28);
264  ip->hop_limit = 255;
265  ip->protocol = IP_PROTOCOL_UDP;
266 
267  ip->src_address = t->local.ip6;
268  ip->dst_address = t->remote.ip6;
269  }
270 
271  /* UDP header, randomize local port on something, maybe? */
272  udp->src_port = clib_host_to_net_u16 (5251);
273  udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_geneve);
274 
275  /* GENEVE header */
277 #if SUPPORT_OPTIONS_HEADER==1
278  vnet_set_geneve_options_len (geneve, t->options_len);
279 #else
280  vnet_set_geneve_options_len (geneve, 0);
281 #endif
282  vnet_set_geneve_oamframe_bit (geneve, 0);
283  vnet_set_geneve_critical_bit (geneve, 0);
285 
287 
288  vnet_set_geneve_vni (geneve, t->vni);
289 
290  t->rewrite = r.rw;
291  return (0);
292 }
293 
294 static bool
296  u32 decap_next_index)
297 {
298  vlib_main_t *vm = vxm->vlib_main;
299  u32 input_idx =
300  (!is_ip6) ? geneve4_input_node.index : geneve6_input_node.index;
301  vlib_node_runtime_t *r = vlib_node_get_runtime (vm, input_idx);
302 
303  return decap_next_index < r->n_next_nodes;
304 }
305 
306 typedef union
307 {
308  struct
309  {
310  fib_node_index_t mfib_entry_index;
311  adj_index_t mcast_adj_index;
312  };
313  u64 as_u64;
314 } __clib_packed mcast_shared_t;
315 
316 static inline mcast_shared_t
317 mcast_shared_get (ip46_address_t * ip)
318 {
320  uword *p = hash_get_mem (geneve_main.mcast_shared, ip);
321  ALWAYS_ASSERT (p);
322  return (mcast_shared_t)
323  {
324  .as_u64 = *p};
325 }
326 
327 static inline void
328 mcast_shared_add (ip46_address_t * remote,
329  fib_node_index_t mfei, adj_index_t ai)
330 {
331  mcast_shared_t new_ep = {
332  .mcast_adj_index = ai,
333  .mfib_entry_index = mfei,
334  };
335 
336  hash_set_mem_alloc (&geneve_main.mcast_shared, remote, new_ep.as_u64);
337 }
338 
339 static inline void
340 mcast_shared_remove (ip46_address_t * remote)
341 {
342  mcast_shared_t ep = mcast_shared_get (remote);
343 
344  adj_unlock (ep.mcast_adj_index);
345  mfib_table_entry_delete_index (ep.mfib_entry_index, MFIB_SOURCE_GENEVE);
346 
347  hash_unset_mem_free (&geneve_main.mcast_shared, remote);
348 }
349 
352 {
353  geneve_main_t *vxm = &geneve_main;
354  geneve_tunnel_t *t = 0;
355  vnet_main_t *vnm = vxm->vnet_main;
356  uword *p;
357  u32 hw_if_index = ~0;
358  u32 sw_if_index = ~0;
359  int rv;
360  geneve4_tunnel_key_t key4;
361  geneve6_tunnel_key_t key6;
362  u32 is_ip6 = a->is_ip6;
363 
364  if (!is_ip6)
365  {
366  key4.remote = a->remote.ip4.as_u32;
367  key4.vni = clib_host_to_net_u32 (a->vni << GENEVE_VNI_SHIFT);
368  p = hash_get (vxm->geneve4_tunnel_by_key, key4.as_u64);
369  }
370  else
371  {
372  key6.remote = a->remote.ip6;
373  key6.vni = clib_host_to_net_u32 (a->vni << GENEVE_VNI_SHIFT);
374  p = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6);
375  }
376 
377  if (a->is_add)
378  {
379  l2input_main_t *l2im = &l2input_main;
380 
381  /* adding a tunnel: tunnel must not already exist */
382  if (p)
383  return VNET_API_ERROR_TUNNEL_EXIST;
384 
385  /*if not set explicitly, default to l2 */
386  if (a->decap_next_index == ~0)
387  a->decap_next_index = GENEVE_INPUT_NEXT_L2_INPUT;
388  if (!geneve_decap_next_is_valid (vxm, is_ip6, a->decap_next_index))
389  return VNET_API_ERROR_INVALID_DECAP_NEXT;
390 
392  clib_memset (t, 0, sizeof (*t));
393 
394  /* copy from arg structure */
395 #define _(x) t->x = a->x;
397 #undef _
398 
399  rv = geneve_rewrite (t, is_ip6);
400  if (rv)
401  {
402  pool_put (vxm->tunnels, t);
403  return rv;
404  }
405 
406  /* copy the key */
407  if (is_ip6)
409  t - vxm->tunnels);
410  else
411  hash_set (vxm->geneve4_tunnel_by_key, key4.as_u64, t - vxm->tunnels);
412 
414  if (a->l3_mode)
415  {
416  u32 t_idx = t - vxm->tunnels;
417  u8 address[6] =
418  { 0xd0, 0x0b, 0xee, 0xd0, (u8) (t_idx >> 8), (u8) t_idx };
419  clib_error_t *error =
420  ethernet_register_interface (vnm, geneve_device_class.index,
421  t_idx,
422  address, &hw_if_index, 0);
423  if (error)
424  {
425  clib_error_report (error);
426  return VNET_API_ERROR_INVALID_REGISTRATION;
427  }
428  }
429  else
430  {
431  hw_if_index = vnet_register_interface
432  (vnm, geneve_device_class.index, t - vxm->tunnels,
433  geneve_hw_class.index, t - vxm->tunnels);
434  }
435 
436  hi = vnet_get_hw_interface (vnm, hw_if_index);
437 
438  /* Set geneve tunnel output node */
439  u32 encap_index = !is_ip6 ?
441  vnet_set_interface_output_node (vnm, hw_if_index, encap_index);
442 
443  t->hw_if_index = hw_if_index;
444  t->sw_if_index = sw_if_index = hi->sw_if_index;
445 
447  ~0);
449 
450  /* setup l2 input config with l2 feature and bd 0 to drop packet */
451  vec_validate (l2im->configs, sw_if_index);
452  l2im->configs[sw_if_index].feature_bitmap = L2INPUT_FEAT_DROP;
453  l2im->configs[sw_if_index].bd_index = 0;
454 
455  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
457  vnet_sw_interface_set_flags (vnm, sw_if_index,
459 
461  fib_prefix_t tun_remote_pfx;
463 
464  fib_prefix_from_ip46_addr (&t->remote, &tun_remote_pfx);
466  {
467  /* Unicast tunnel -
468  * source the FIB entry for the tunnel's destination
469  * and become a child thereof. The tunnel will then get poked
470  * when the forwarding for the entry updates, and the tunnel can
471  * re-stack accordingly
472  */
475  &tun_remote_pfx,
477  t - vxm->tunnels,
478  &t->sibling_index);
480  }
481  else
482  {
483  /* Multicast tunnel -
484  * as the same mcast group can be used for mutiple mcast tunnels
485  * with different VNIs, create the output fib adjecency only if
486  * it does not already exist
487  */
488  fib_protocol_t fp = fib_ip_proto (is_ip6);
489 
490  if (vtep_addr_ref (&vxm->vtep_table,
491  t->encap_fib_index, &t->remote) == 1)
492  {
493  fib_node_index_t mfei;
494  adj_index_t ai;
496  .frp_proto = fib_proto_to_dpo (fp),
497  .frp_addr = zero_addr,
498  .frp_sw_if_index = 0xffffffff,
499  .frp_fib_index = ~0,
500  .frp_weight = 1,
501  .frp_flags = FIB_ROUTE_PATH_LOCAL,
502  .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
503  };
504  const mfib_prefix_t mpfx = {
505  .fp_proto = fp,
506  .fp_len = (is_ip6 ? 128 : 32),
507  .fp_grp_addr = tun_remote_pfx.fp_addr,
508  };
509 
510  /*
511  * Setup the (*,G) to receive traffic on the mcast group
512  * - the forwarding interface is for-us
513  * - the accepting interface is that from the API
514  */
516  &mpfx, MFIB_SOURCE_GENEVE, &path);
517 
522  &mpfx,
523  MFIB_SOURCE_GENEVE, &path);
524 
525  /*
526  * Create the mcast adjacency to send traffic to the group
527  */
528  ai = adj_mcast_add_or_lock (fp,
529  fib_proto_to_link (fp),
530  a->mcast_sw_if_index);
531 
532  /*
533  * create a new end-point
534  */
535  mcast_shared_add (&t->remote, mfei, ai);
536  }
537 
538  dpo_id_t dpo = DPO_INVALID;
539  mcast_shared_t ep = mcast_shared_get (&t->remote);
540 
541  /* Stack shared mcast remote mac addr rewrite on encap */
543  fib_proto_to_dpo (fp), ep.mcast_adj_index);
544 
545  dpo_stack_from_node (encap_index, &t->next_dpo, &dpo);
546  dpo_reset (&dpo);
547  flood_class = VNET_FLOOD_CLASS_TUNNEL_MASTER;
548  }
549 
550  vnet_get_sw_interface (vnet_get_main (), sw_if_index)->flood_class =
551  flood_class;
552  }
553  else
554  {
555  /* deleting a tunnel: tunnel must exist */
556  if (!p)
557  return VNET_API_ERROR_NO_SUCH_ENTRY;
558 
559  t = pool_elt_at_index (vxm->tunnels, p[0]);
560 
561  sw_if_index = t->sw_if_index;
562  vnet_sw_interface_set_flags (vnm, t->sw_if_index, 0 /* down */ );
565 
566  /* make sure tunnel is removed from l2 bd or xconnect */
567  set_int_l2_mode (vxm->vlib_main, vnm, MODE_L3, t->sw_if_index, 0,
568  L2_BD_PORT_TYPE_NORMAL, 0, 0);
569 
570  if (t->l3_mode)
572  else
574 
576 
577  if (!is_ip6)
578  hash_unset (vxm->geneve4_tunnel_by_key, key4.as_u64);
579  else
581 
583  {
586  }
587  else if (vtep_addr_unref (&vxm->vtep_table,
588  t->encap_fib_index, &t->remote) == 0)
589  {
591  }
592 
593  fib_node_deinit (&t->node);
594  vec_free (t->rewrite);
595  pool_put (vxm->tunnels, t);
596  }
597 
598  if (sw_if_indexp)
599  *sw_if_indexp = sw_if_index;
600 
601  if (a->is_add)
602  {
603  /* register udp ports */
604  if (!is_ip6 && !udp_is_valid_dst_port (UDP_DST_PORT_geneve, 1))
605  udp_register_dst_port (vxm->vlib_main, UDP_DST_PORT_geneve,
606  geneve4_input_node.index, 1);
607  if (is_ip6 && !udp_is_valid_dst_port (UDP_DST_PORT_geneve6, 0))
608  udp_register_dst_port (vxm->vlib_main, UDP_DST_PORT_geneve6,
609  geneve6_input_node.index, 0);
610  }
611 
612  return 0;
613 }
614 
615 static uword
616 get_decap_next_for_node (u32 node_index, u32 ipv4_set)
617 {
618  geneve_main_t *vxm = &geneve_main;
619  vlib_main_t *vm = vxm->vlib_main;
620  uword input_node = (ipv4_set) ? geneve4_input_node.index :
621  geneve6_input_node.index;
622 
623  return vlib_node_add_next (vm, input_node, node_index);
624 }
625 
626 static uword
627 unformat_decap_next (unformat_input_t * input, va_list * args)
628 {
629  u32 *result = va_arg (*args, u32 *);
630  u32 ipv4_set = va_arg (*args, int);
631  geneve_main_t *vxm = &geneve_main;
632  vlib_main_t *vm = vxm->vlib_main;
633  u32 node_index;
634  u32 tmp;
635 
636  if (unformat (input, "l2"))
637  *result = GENEVE_INPUT_NEXT_L2_INPUT;
638  else if (unformat (input, "node %U", unformat_vlib_node, vm, &node_index))
639  *result = get_decap_next_for_node (node_index, ipv4_set);
640  else if (unformat (input, "%d", &tmp))
641  *result = tmp;
642  else
643  return 0;
644  return 1;
645 }
646 
647 static clib_error_t *
649  unformat_input_t * input,
650  vlib_cli_command_t * cmd)
651 {
652  unformat_input_t _line_input, *line_input = &_line_input;
653  ip46_address_t local, remote;
654  u8 is_add = 1;
655  u8 local_set = 0;
656  u8 remote_set = 0;
657  u8 grp_set = 0;
658  u8 ipv4_set = 0;
659  u8 ipv6_set = 0;
660  u8 l3_mode = 0;
661  u32 encap_fib_index = 0;
662  u32 mcast_sw_if_index = ~0;
663  u32 decap_next_index = GENEVE_INPUT_NEXT_L2_INPUT;
664  u32 vni = 0;
665  u32 tmp;
666  int rv;
668  u32 tunnel_sw_if_index;
669  clib_error_t *error = NULL;
670 
671  /* Cant "universally zero init" (={0}) due to GCC bug 53119 */
672  clib_memset (&local, 0, sizeof local);
673  clib_memset (&remote, 0, sizeof remote);
674 
675  /* Get a line of input. */
676  if (!unformat_user (input, unformat_line_input, line_input))
677  return 0;
678 
679  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
680  {
681  if (unformat (line_input, "del"))
682  {
683  is_add = 0;
684  }
685  else if (unformat (line_input, "local %U",
686  unformat_ip4_address, &local.ip4))
687  {
688  local_set = 1;
689  ipv4_set = 1;
690  }
691  else if (unformat (line_input, "remote %U",
692  unformat_ip4_address, &remote.ip4))
693  {
694  remote_set = 1;
695  ipv4_set = 1;
696  }
697  else if (unformat (line_input, "local %U",
698  unformat_ip6_address, &local.ip6))
699  {
700  local_set = 1;
701  ipv6_set = 1;
702  }
703  else if (unformat (line_input, "remote %U",
704  unformat_ip6_address, &remote.ip6))
705  {
706  remote_set = 1;
707  ipv6_set = 1;
708  }
709  else if (unformat (line_input, "group %U %U",
710  unformat_ip4_address, &remote.ip4,
712  vnet_get_main (), &mcast_sw_if_index))
713  {
714  grp_set = remote_set = 1;
715  ipv4_set = 1;
716  }
717  else if (unformat (line_input, "group %U %U",
718  unformat_ip6_address, &remote.ip6,
720  vnet_get_main (), &mcast_sw_if_index))
721  {
722  grp_set = remote_set = 1;
723  ipv6_set = 1;
724  }
725  else if (unformat (line_input, "encap-vrf-id %d", &tmp))
726  {
727  encap_fib_index = fib_table_find (fib_ip_proto (ipv6_set), tmp);
728  if (encap_fib_index == ~0)
729  {
730  error =
731  clib_error_return (0, "nonexistent encap-vrf-id %d", tmp);
732  goto done;
733  }
734  }
735  else if (unformat (line_input, "decap-next %U", unformat_decap_next,
736  &decap_next_index, ipv4_set))
737  ;
738  else if (unformat (line_input, "vni %d", &vni))
739  {
740  if (vni >> 24)
741  {
742  error = clib_error_return (0, "vni %d out of range", vni);
743  goto done;
744  }
745  }
746  else if (unformat (line_input, "l3-mode"))
747  {
748  l3_mode = 1;
749  }
750  else
751  {
752  error = clib_error_return (0, "parse error: '%U'",
753  format_unformat_error, line_input);
754  goto done;
755  }
756  }
757 
758  if (local_set == 0)
759  {
760  error = clib_error_return (0, "tunnel local address not specified");
761  goto done;
762  }
763 
764  if (remote_set == 0)
765  {
766  error = clib_error_return (0, "tunnel remote address not specified");
767  goto done;
768  }
769 
770  if (grp_set && !ip46_address_is_multicast (&remote))
771  {
772  error = clib_error_return (0, "tunnel group address not multicast");
773  goto done;
774  }
775 
776  if (grp_set == 0 && ip46_address_is_multicast (&remote))
777  {
778  error = clib_error_return (0, "remote address must be unicast");
779  goto done;
780  }
781 
782  if (grp_set && mcast_sw_if_index == ~0)
783  {
784  error = clib_error_return (0, "tunnel nonexistent multicast device");
785  goto done;
786  }
787 
788  if (ipv4_set && ipv6_set)
789  {
790  error = clib_error_return (0, "both IPv4 and IPv6 addresses specified");
791  goto done;
792  }
793 
794  if (ip46_address_cmp (&local, &remote) == 0)
795  {
796  error =
797  clib_error_return (0, "local and remote addresses are identical");
798  goto done;
799  }
800 
801  if (decap_next_index == ~0)
802  {
803  error = clib_error_return (0, "next node not found");
804  goto done;
805  }
806 
807  if (vni == 0)
808  {
809  error = clib_error_return (0, "vni not specified");
810  goto done;
811  }
812 
813  clib_memset (a, 0, sizeof (*a));
814 
815  a->is_add = is_add;
816  a->is_ip6 = ipv6_set;
817 
818 #define _(x) a->x = x;
820 #undef _
821 
822  rv = vnet_geneve_add_del_tunnel (a, &tunnel_sw_if_index);
823 
824  switch (rv)
825  {
826  case 0:
827  if (is_add)
829  vnet_get_main (), tunnel_sw_if_index);
830  break;
831 
832  case VNET_API_ERROR_TUNNEL_EXIST:
833  error = clib_error_return (0, "tunnel already exists...");
834  goto done;
835 
836  case VNET_API_ERROR_NO_SUCH_ENTRY:
837  error = clib_error_return (0, "tunnel does not exist...");
838  goto done;
839 
840  default:
841  error = clib_error_return
842  (0, "vnet_geneve_add_del_tunnel returned %d", rv);
843  goto done;
844  }
845 
846 done:
847  unformat_free (line_input);
848 
849  return error;
850 }
851 
852 /*?
853  * Add or delete a GENEVE Tunnel.
854  *
855  * GENEVE provides the features needed to allow L2 bridge domains (BDs)
856  * to span multiple servers. This is done by building an L2 overlay on
857  * top of an L3 network underlay using GENEVE tunnels.
858  *
859  * This makes it possible for servers to be co-located in the same data
860  * center or be separated geographically as long as they are reachable
861  * through the underlay L3 network.
862  *
863  * You can refer to this kind of L2 overlay bridge domain as a GENEVE
864  * segment.
865  *
866  * @cliexpar
867  * Example of how to create a GENEVE Tunnel:
868  * @cliexcmd{create geneve tunnel local 10.0.3.1 remote 10.0.3.3 vni 13 encap-vrf-id 7}
869  * Example of how to delete a GENEVE Tunnel:
870  * @cliexcmd{create geneve tunnel local 10.0.3.1 remote 10.0.3.3 vni 13 del}
871  ?*/
872 /* *INDENT-OFF* */
873 VLIB_CLI_COMMAND (create_geneve_tunnel_command, static) = {
874  .path = "create geneve tunnel",
875  .short_help =
876  "create geneve tunnel local <local-vtep-addr>"
877  " {remote <remote-vtep-addr>|group <mcast-vtep-addr> <intf-name>} vni <nn>"
878  " [encap-vrf-id <nn>] [decap-next [l2|node <name>]] [l3-mode] [del]",
880 };
881 /* *INDENT-ON* */
882 
883 static clib_error_t *
885  unformat_input_t * input,
886  vlib_cli_command_t * cmd)
887 {
888  geneve_main_t *vxm = &geneve_main;
889  geneve_tunnel_t *t;
890 
891  if (pool_elts (vxm->tunnels) == 0)
892  vlib_cli_output (vm, "No geneve tunnels configured...");
893 
894  pool_foreach (t, vxm->tunnels, (
895  {
896  vlib_cli_output (vm, "%U",
897  format_geneve_tunnel, t);
898  }
899  ));
900 
901  return 0;
902 }
903 
904 /*?
905  * Display all the GENEVE Tunnel entries.
906  *
907  * @cliexpar
908  * Example of how to display the GENEVE Tunnel entries:
909  * @cliexstart{show geneve tunnel}
910  * [0] local 10.0.3.1 remote 10.0.3.3 vni 13 encap_fib_index 0 sw_if_index 5 decap_next l2
911  * @cliexend
912  ?*/
913 /* *INDENT-OFF* */
914 VLIB_CLI_COMMAND (show_geneve_tunnel_command, static) = {
915  .path = "show geneve tunnel",
916  .short_help = "show geneve tunnel",
917  .function = show_geneve_tunnel_command_fn,
918 };
919 /* *INDENT-ON* */
920 
921 
922 void
924 {
925  if (is_ip6)
926  vnet_feature_enable_disable ("ip6-unicast", "ip6-geneve-bypass",
927  sw_if_index, is_enable, 0, 0);
928  else
929  vnet_feature_enable_disable ("ip4-unicast", "ip4-geneve-bypass",
930  sw_if_index, is_enable, 0, 0);
931 }
932 
933 
934 static clib_error_t *
936  unformat_input_t * input, vlib_cli_command_t * cmd)
937 {
938  unformat_input_t _line_input, *line_input = &_line_input;
939  vnet_main_t *vnm = vnet_get_main ();
940  clib_error_t *error = 0;
941  u32 sw_if_index, is_enable;
942 
943  sw_if_index = ~0;
944  is_enable = 1;
945 
946  if (!unformat_user (input, unformat_line_input, line_input))
947  return 0;
948 
949  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
950  {
951  if (unformat_user
952  (line_input, unformat_vnet_sw_interface, vnm, &sw_if_index))
953  ;
954  else if (unformat (line_input, "del"))
955  is_enable = 0;
956  else
957  {
958  error = unformat_parse_error (line_input);
959  goto done;
960  }
961  }
962 
963  if (~0 == sw_if_index)
964  {
965  error = clib_error_return (0, "unknown interface `%U'",
966  format_unformat_error, line_input);
967  goto done;
968  }
969 
970  vnet_int_geneve_bypass_mode (sw_if_index, is_ip6, is_enable);
971 
972 done:
973  unformat_free (line_input);
974 
975  return error;
976 }
977 
978 static clib_error_t *
980  unformat_input_t * input, vlib_cli_command_t * cmd)
981 {
982  return set_ip_geneve_bypass (0, input, cmd);
983 }
984 
985 /*?
986  * This command adds the 'ip4-geneve-bypass' graph node for a given interface.
987  * By adding the IPv4 geneve-bypass graph node to an interface, the node checks
988  * for and validate input geneve packet and bypass ip4-lookup, ip4-local,
989  * ip4-udp-lookup nodes to speedup geneve packet forwarding. This node will
990  * cause extra overhead to for non-geneve packets which is kept at a minimum.
991  *
992  * @cliexpar
993  * @parblock
994  * Example of graph node before ip4-geneve-bypass is enabled:
995  * @cliexstart{show vlib graph ip4-geneve-bypass}
996  * Name Next Previous
997  * ip4-geneve-bypass error-drop [0]
998  * geneve4-input [1]
999  * ip4-lookup [2]
1000  * @cliexend
1001  *
1002  * Example of how to enable ip4-geneve-bypass on an interface:
1003  * @cliexcmd{set interface ip geneve-bypass GigabitEthernet2/0/0}
1004  *
1005  * Example of graph node after ip4-geneve-bypass is enabled:
1006  * @cliexstart{show vlib graph ip4-geneve-bypass}
1007  * Name Next Previous
1008  * ip4-geneve-bypass error-drop [0] ip4-input
1009  * geneve4-input [1] ip4-input-no-checksum
1010  * ip4-lookup [2]
1011  * @cliexend
1012  *
1013  * Example of how to display the feature enabed on an interface:
1014  * @cliexstart{show ip interface features GigabitEthernet2/0/0}
1015  * IP feature paths configured on GigabitEthernet2/0/0...
1016  * ...
1017  * ipv4 unicast:
1018  * ip4-geneve-bypass
1019  * ip4-lookup
1020  * ...
1021  * @cliexend
1022  *
1023  * Example of how to disable ip4-geneve-bypass on an interface:
1024  * @cliexcmd{set interface ip geneve-bypass GigabitEthernet2/0/0 del}
1025  * @endparblock
1026 ?*/
1027 /* *INDENT-OFF* */
1028 VLIB_CLI_COMMAND (set_interface_ip_geneve_bypass_command, static) = {
1029  .path = "set interface ip geneve-bypass",
1030  .function = set_ip4_geneve_bypass,
1031  .short_help = "set interface ip geneve-bypass <interface> [del]",
1032 };
1033 /* *INDENT-ON* */
1034 
1035 static clib_error_t *
1037  unformat_input_t * input, vlib_cli_command_t * cmd)
1038 {
1039  return set_ip_geneve_bypass (1, input, cmd);
1040 }
1041 
1042 /*?
1043  * This command adds the 'ip6-geneve-bypass' graph node for a given interface.
1044  * By adding the IPv6 geneve-bypass graph node to an interface, the node checks
1045  * for and validate input geneve packet and bypass ip6-lookup, ip6-local,
1046  * ip6-udp-lookup nodes to speedup geneve packet forwarding. This node will
1047  * cause extra overhead to for non-geneve packets which is kept at a minimum.
1048  *
1049  * @cliexpar
1050  * @parblock
1051  * Example of graph node before ip6-geneve-bypass is enabled:
1052  * @cliexstart{show vlib graph ip6-geneve-bypass}
1053  * Name Next Previous
1054  * ip6-geneve-bypass error-drop [0]
1055  * geneve6-input [1]
1056  * ip6-lookup [2]
1057  * @cliexend
1058  *
1059  * Example of how to enable ip6-geneve-bypass on an interface:
1060  * @cliexcmd{set interface ip6 geneve-bypass GigabitEthernet2/0/0}
1061  *
1062  * Example of graph node after ip6-geneve-bypass is enabled:
1063  * @cliexstart{show vlib graph ip6-geneve-bypass}
1064  * Name Next Previous
1065  * ip6-geneve-bypass error-drop [0] ip6-input
1066  * geneve6-input [1] ip4-input-no-checksum
1067  * ip6-lookup [2]
1068  * @cliexend
1069  *
1070  * Example of how to display the feature enabed on an interface:
1071  * @cliexstart{show ip interface features GigabitEthernet2/0/0}
1072  * IP feature paths configured on GigabitEthernet2/0/0...
1073  * ...
1074  * ipv6 unicast:
1075  * ip6-geneve-bypass
1076  * ip6-lookup
1077  * ...
1078  * @cliexend
1079  *
1080  * Example of how to disable ip6-geneve-bypass on an interface:
1081  * @cliexcmd{set interface ip6 geneve-bypass GigabitEthernet2/0/0 del}
1082  * @endparblock
1083 ?*/
1084 /* *INDENT-OFF* */
1085 VLIB_CLI_COMMAND (set_interface_ip6_geneve_bypass_command, static) = {
1086  .path = "set interface ip6 geneve-bypass",
1087  .function = set_ip6_geneve_bypass,
1088  .short_help = "set interface ip6 geneve-bypass <interface> [del]",
1089 };
1090 /* *INDENT-ON* */
1091 
1092 clib_error_t *
1094 {
1095  geneve_main_t *vxm = &geneve_main;
1096 
1097  vxm->vnet_main = vnet_get_main ();
1098  vxm->vlib_main = vm;
1099 
1100  /* initialize the ip6 hash */
1102  sizeof (geneve6_tunnel_key_t),
1103  sizeof (uword));
1104  vxm->vtep_table = vtep_table_create ();
1105  vxm->mcast_shared = hash_create_mem (0,
1106  sizeof (ip46_address_t),
1107  sizeof (mcast_shared_t));
1108 
1110 
1111  return 0;
1112 }
1113 
1115 
1116 /*
1117  * fd.io coding-style-patch-verification: ON
1118  *
1119  * Local Variables:
1120  * eval: (c-set-style "gnu")
1121  * End:
1122  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
vlib_main_t * vlib_main
Definition: geneve.h:182
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:1036
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
u16 vni
Definition: flow_types.api:160
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:128
#define CLIB_UNUSED(x)
Definition: clib.h:87
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
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:103
A representation of a path as described by a route producer.
Definition: fib_types.h:490
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:378
ip4_address_t src_address
Definition: ip4_packet.h:125
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:328
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
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:317
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 foreach_copy_field
Definition: geneve.c:214
static geneve_tunnel_t * geneve_tunnel_from_fib_node(fib_node_t *node)
Definition: geneve.c:158
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:648
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:70
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)
vlib_main_t * vm
Definition: in2out_ed.c:1582
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:520
uword * mcast_shared
Definition: geneve.h:176
int vnet_geneve_add_del_tunnel(vnet_geneve_add_del_tunnel_args_t *a, u32 *sw_if_indexp)
Definition: geneve.c:351
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:179
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:1173
unsigned char u8
Definition: types.h:56
geneve_tunnel_t * tunnels
Definition: geneve.h:165
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:884
VNET_HW_INTERFACE_CLASS(geneve_hw_class)
vnet_flood_class_t flood_class
Definition: interface.h:763
clib_error_t * geneve_init(vlib_main_t *vm)
Definition: geneve.c:1093
#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:170
#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:125
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:173
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:348
#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:935
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
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:979
struct _unformat_input_t unformat_input_t
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:120
static void vnet_set_geneve_version(geneve_header_t *h, u8 version)
vnet_sw_interface_flags_t flags
Definition: interface.h:738
static u8 * format_geneve_name(u8 *s, va_list *args)
Definition: geneve.c:93
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:194
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
#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:679
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:115
fib_node_get_t fnv_get
Definition: fib_node.h:283
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:168
Aggregate type for a prefix.
Definition: mfib_types.h:24
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 placeholder) rewrite.
Definition: interface.c:1639
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
Context passed between object during a back walk.
Definition: fib_node.h:208
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
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:696
manual_print typedef address
Definition: ip_types.api:85
static clib_error_t * geneve_mac_change(vnet_hw_interface_t *hi, const u8 *old_address, const u8 *mac_address)
Definition: geneve.c:110
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:580
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:180
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:144
#define clib_error_report(e)
Definition: error.h:113
static void hash_unset_mem_free(uword **h, const void *key)
Definition: hash.h:295
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:224
static vtep_table_t vtep_table_create()
Definition: vtep.h:70
vl_api_ip4_address_t hi
Definition: arp.api:37
void vnet_delete_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:984
static void vnet_set_geneve_critical_bit(geneve_header_t *h, u8 critical_opts)
vnet_main_t * vnet_main
Definition: geneve.h:183
static clib_error_t * geneve_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: geneve.c:100
#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:127
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 GENEVE_VNI_SHIFT
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:331
static fib_protocol_t fib_ip_proto(bool is_ip6)
Convert from boolean is_ip6 to FIB protocol.
Definition: fib_types.h:80
void l2input_interface_mac_change(u32 sw_if_index, const u8 *old_address, const u8 *new_address)
Definition: l2_input.c:551
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:169
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
u32 index
Definition: flow_types.api:221
static uword get_decap_next_for_node(u32 node_index, u32 ipv4_set)
Definition: geneve.c:616
static void mcast_shared_remove(ip46_address_t *remote)
Definition: geneve.c:340
unformat_function_t unformat_vlib_node
Definition: node_funcs.h:1228
#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:295
static uword unformat_decap_next(unformat_input_t *input, va_list *args)
Definition: geneve.c:627
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:93
manual_print typedef u8 mac_address[6]
#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:556
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:314
const ip46_address_t zero_addr
Definition: lookup.c:181
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
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:303
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:923
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128