FD.io VPP  v20.01-48-g3e0dafb74
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 static uword
296 vtep_addr_ref (ip46_address_t * ip)
297 {
298  uword *vtep = ip46_address_is_ip4 (ip) ?
299  hash_get (geneve_main.vtep4, ip->ip4.as_u32) :
300  hash_get_mem (geneve_main.vtep6, &ip->ip6);
301  if (vtep)
302  return ++(*vtep);
303  ip46_address_is_ip4 (ip) ?
304  hash_set (geneve_main.vtep4, ip->ip4.as_u32, 1) :
305  hash_set_mem_alloc (&geneve_main.vtep6, &ip->ip6, 1);
306  return 1;
307 }
308 
309 static uword
310 vtep_addr_unref (ip46_address_t * ip)
311 {
312  uword *vtep = ip46_address_is_ip4 (ip) ?
313  hash_get (geneve_main.vtep4, ip->ip4.as_u32) :
314  hash_get_mem (geneve_main.vtep6, &ip->ip6);
315  ASSERT (vtep);
316  if (--(*vtep) != 0)
317  return *vtep;
318  ip46_address_is_ip4 (ip) ?
319  hash_unset (geneve_main.vtep4, ip->ip4.as_u32) :
320  hash_unset_mem_free (&geneve_main.vtep6, &ip->ip6);
321  return 0;
322 }
323 
324 typedef union
325 {
326  struct
327  {
328  fib_node_index_t mfib_entry_index;
329  adj_index_t mcast_adj_index;
330  };
331  u64 as_u64;
332 } __clib_packed mcast_shared_t;
333 
334 static inline mcast_shared_t
335 mcast_shared_get (ip46_address_t * ip)
336 {
338  uword *p = hash_get_mem (geneve_main.mcast_shared, ip);
339  ASSERT (p);
340  return (mcast_shared_t)
341  {
342  .as_u64 = *p};
343 }
344 
345 static inline void
346 mcast_shared_add (ip46_address_t * remote,
347  fib_node_index_t mfei, adj_index_t ai)
348 {
349  mcast_shared_t new_ep = {
350  .mcast_adj_index = ai,
351  .mfib_entry_index = mfei,
352  };
353 
354  hash_set_mem_alloc (&geneve_main.mcast_shared, remote, new_ep.as_u64);
355 }
356 
357 static inline void
358 mcast_shared_remove (ip46_address_t * remote)
359 {
360  mcast_shared_t ep = mcast_shared_get (remote);
361 
362  adj_unlock (ep.mcast_adj_index);
363  mfib_table_entry_delete_index (ep.mfib_entry_index, MFIB_SOURCE_GENEVE);
364 
365  hash_unset_mem_free (&geneve_main.mcast_shared, remote);
366 }
367 
370 {
371  geneve_main_t *vxm = &geneve_main;
372  geneve_tunnel_t *t = 0;
373  vnet_main_t *vnm = vxm->vnet_main;
374  uword *p;
375  u32 hw_if_index = ~0;
376  u32 sw_if_index = ~0;
377  int rv;
378  geneve4_tunnel_key_t key4;
379  geneve6_tunnel_key_t key6;
380  u32 is_ip6 = a->is_ip6;
381 
382  if (!is_ip6)
383  {
384  key4.remote = a->remote.ip4.as_u32;
385  key4.vni = clib_host_to_net_u32 (a->vni << GENEVE_VNI_SHIFT);
386  p = hash_get (vxm->geneve4_tunnel_by_key, key4.as_u64);
387  }
388  else
389  {
390  key6.remote = a->remote.ip6;
391  key6.vni = clib_host_to_net_u32 (a->vni << GENEVE_VNI_SHIFT);
392  p = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6);
393  }
394 
395  if (a->is_add)
396  {
397  l2input_main_t *l2im = &l2input_main;
398 
399  /* adding a tunnel: tunnel must not already exist */
400  if (p)
401  return VNET_API_ERROR_TUNNEL_EXIST;
402 
403  /*if not set explicitly, default to l2 */
404  if (a->decap_next_index == ~0)
405  a->decap_next_index = GENEVE_INPUT_NEXT_L2_INPUT;
406  if (!geneve_decap_next_is_valid (vxm, is_ip6, a->decap_next_index))
407  return VNET_API_ERROR_INVALID_DECAP_NEXT;
408 
410  clib_memset (t, 0, sizeof (*t));
411 
412  /* copy from arg structure */
413 #define _(x) t->x = a->x;
415 #undef _
416 
417  rv = geneve_rewrite (t, is_ip6);
418  if (rv)
419  {
420  pool_put (vxm->tunnels, t);
421  return rv;
422  }
423 
424  /* copy the key */
425  if (is_ip6)
427  t - vxm->tunnels);
428  else
429  hash_set (vxm->geneve4_tunnel_by_key, key4.as_u64, t - vxm->tunnels);
430 
433  {
435  hw_if_index = vxm->free_geneve_tunnel_hw_if_indices
437  _vec_len (vxm->free_geneve_tunnel_hw_if_indices) -= 1;
438 
439  hi = vnet_get_hw_interface (vnm, hw_if_index);
440  hi->dev_instance = t - vxm->tunnels;
441  hi->hw_instance = hi->dev_instance;
442 
443  /* clear old stats of freed tunnel before reuse */
444  sw_if_index = hi->sw_if_index;
448  sw_if_index);
451  sw_if_index);
454  sw_if_index);
456  }
457  else
458  {
459  hw_if_index = vnet_register_interface
460  (vnm, geneve_device_class.index, t - vxm->tunnels,
461  geneve_hw_class.index, t - vxm->tunnels);
462  hi = vnet_get_hw_interface (vnm, hw_if_index);
463  }
464 
465  /* Set geneve tunnel output node */
466  u32 encap_index = !is_ip6 ?
468  vnet_set_interface_output_node (vnm, hw_if_index, encap_index);
469 
470  t->hw_if_index = hw_if_index;
471  t->sw_if_index = sw_if_index = hi->sw_if_index;
472 
474  ~0);
476 
477  /* setup l2 input config with l2 feature and bd 0 to drop packet */
478  vec_validate (l2im->configs, sw_if_index);
479  l2im->configs[sw_if_index].feature_bitmap = L2INPUT_FEAT_DROP;
480  l2im->configs[sw_if_index].bd_index = 0;
481 
482  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
484  vnet_sw_interface_set_flags (vnm, sw_if_index,
486 
488  fib_prefix_t tun_remote_pfx;
490 
491  fib_prefix_from_ip46_addr (&t->remote, &tun_remote_pfx);
493  {
494  /* Unicast tunnel -
495  * source the FIB entry for the tunnel's destination
496  * and become a child thereof. The tunnel will then get poked
497  * when the forwarding for the entry updates, and the tunnel can
498  * re-stack accordingly
499  */
500  vtep_addr_ref (&t->local);
502  &tun_remote_pfx,
504  t - vxm->tunnels,
505  &t->sibling_index);
507  }
508  else
509  {
510  /* Multicast tunnel -
511  * as the same mcast group can be used for mutiple mcast tunnels
512  * with different VNIs, create the output fib adjecency only if
513  * it does not already exist
514  */
515  fib_protocol_t fp = fib_ip_proto (is_ip6);
516 
517  if (vtep_addr_ref (&t->remote) == 1)
518  {
519  fib_node_index_t mfei;
520  adj_index_t ai;
522  .frp_proto = fib_proto_to_dpo (fp),
523  .frp_addr = zero_addr,
524  .frp_sw_if_index = 0xffffffff,
525  .frp_fib_index = ~0,
526  .frp_weight = 1,
527  .frp_flags = FIB_ROUTE_PATH_LOCAL,
528  .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
529  };
530  const mfib_prefix_t mpfx = {
531  .fp_proto = fp,
532  .fp_len = (is_ip6 ? 128 : 32),
533  .fp_grp_addr = tun_remote_pfx.fp_addr,
534  };
535 
536  /*
537  * Setup the (*,G) to receive traffic on the mcast group
538  * - the forwarding interface is for-us
539  * - the accepting interface is that from the API
540  */
542  &mpfx, MFIB_SOURCE_GENEVE, &path);
543 
548  &mpfx,
549  MFIB_SOURCE_GENEVE, &path);
550 
551  /*
552  * Create the mcast adjacency to send traffic to the group
553  */
554  ai = adj_mcast_add_or_lock (fp,
555  fib_proto_to_link (fp),
556  a->mcast_sw_if_index);
557 
558  /*
559  * create a new end-point
560  */
561  mcast_shared_add (&t->remote, mfei, ai);
562  }
563 
564  dpo_id_t dpo = DPO_INVALID;
565  mcast_shared_t ep = mcast_shared_get (&t->remote);
566 
567  /* Stack shared mcast remote mac addr rewrite on encap */
569  fib_proto_to_dpo (fp), ep.mcast_adj_index);
570 
571  dpo_stack_from_node (encap_index, &t->next_dpo, &dpo);
572  dpo_reset (&dpo);
573  flood_class = VNET_FLOOD_CLASS_TUNNEL_MASTER;
574  }
575 
576  vnet_get_sw_interface (vnet_get_main (), sw_if_index)->flood_class =
577  flood_class;
578  }
579  else
580  {
581  /* deleting a tunnel: tunnel must exist */
582  if (!p)
583  return VNET_API_ERROR_NO_SUCH_ENTRY;
584 
585  t = pool_elt_at_index (vxm->tunnels, p[0]);
586 
587  sw_if_index = t->sw_if_index;
588  vnet_sw_interface_set_flags (vnm, t->sw_if_index, 0 /* down */ );
591 
592  /* make sure tunnel is removed from l2 bd or xconnect */
593  set_int_l2_mode (vxm->vlib_main, vnm, MODE_L3, t->sw_if_index, 0,
594  L2_BD_PORT_TYPE_NORMAL, 0, 0);
596 
598 
599  if (!is_ip6)
600  hash_unset (vxm->geneve4_tunnel_by_key, key4.as_u64);
601  else
603 
605  {
606  vtep_addr_unref (&t->local);
608  }
609  else if (vtep_addr_unref (&t->remote) == 0)
610  {
612  }
613 
614  fib_node_deinit (&t->node);
615  vec_free (t->rewrite);
616  pool_put (vxm->tunnels, t);
617  }
618 
619  if (sw_if_indexp)
620  *sw_if_indexp = sw_if_index;
621 
622  if (a->is_add)
623  {
624  /* register udp ports */
625  if (!is_ip6 && !udp_is_valid_dst_port (UDP_DST_PORT_geneve, 1))
626  udp_register_dst_port (vxm->vlib_main, UDP_DST_PORT_geneve,
627  geneve4_input_node.index, 1);
628  if (is_ip6 && !udp_is_valid_dst_port (UDP_DST_PORT_geneve6, 0))
629  udp_register_dst_port (vxm->vlib_main, UDP_DST_PORT_geneve6,
630  geneve6_input_node.index, 0);
631  }
632 
633  return 0;
634 }
635 
636 static uword
637 get_decap_next_for_node (u32 node_index, u32 ipv4_set)
638 {
639  geneve_main_t *vxm = &geneve_main;
640  vlib_main_t *vm = vxm->vlib_main;
641  uword input_node = (ipv4_set) ? geneve4_input_node.index :
642  geneve6_input_node.index;
643 
644  return vlib_node_add_next (vm, input_node, node_index);
645 }
646 
647 static uword
648 unformat_decap_next (unformat_input_t * input, va_list * args)
649 {
650  u32 *result = va_arg (*args, u32 *);
651  u32 ipv4_set = va_arg (*args, int);
652  geneve_main_t *vxm = &geneve_main;
653  vlib_main_t *vm = vxm->vlib_main;
654  u32 node_index;
655  u32 tmp;
656 
657  if (unformat (input, "l2"))
658  *result = GENEVE_INPUT_NEXT_L2_INPUT;
659  else if (unformat (input, "node %U", unformat_vlib_node, vm, &node_index))
660  *result = get_decap_next_for_node (node_index, ipv4_set);
661  else if (unformat (input, "%d", &tmp))
662  *result = tmp;
663  else
664  return 0;
665  return 1;
666 }
667 
668 static clib_error_t *
670  unformat_input_t * input,
671  vlib_cli_command_t * cmd)
672 {
673  unformat_input_t _line_input, *line_input = &_line_input;
674  ip46_address_t local, remote;
675  u8 is_add = 1;
676  u8 local_set = 0;
677  u8 remote_set = 0;
678  u8 grp_set = 0;
679  u8 ipv4_set = 0;
680  u8 ipv6_set = 0;
681  u32 encap_fib_index = 0;
682  u32 mcast_sw_if_index = ~0;
683  u32 decap_next_index = GENEVE_INPUT_NEXT_L2_INPUT;
684  u32 vni = 0;
685  u32 tmp;
686  int rv;
688  u32 tunnel_sw_if_index;
689  clib_error_t *error = NULL;
690 
691  /* Cant "universally zero init" (={0}) due to GCC bug 53119 */
692  clib_memset (&local, 0, sizeof local);
693  clib_memset (&remote, 0, sizeof remote);
694 
695  /* Get a line of input. */
696  if (!unformat_user (input, unformat_line_input, line_input))
697  return 0;
698 
699  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
700  {
701  if (unformat (line_input, "del"))
702  {
703  is_add = 0;
704  }
705  else if (unformat (line_input, "local %U",
706  unformat_ip4_address, &local.ip4))
707  {
708  local_set = 1;
709  ipv4_set = 1;
710  }
711  else if (unformat (line_input, "remote %U",
712  unformat_ip4_address, &remote.ip4))
713  {
714  remote_set = 1;
715  ipv4_set = 1;
716  }
717  else if (unformat (line_input, "local %U",
718  unformat_ip6_address, &local.ip6))
719  {
720  local_set = 1;
721  ipv6_set = 1;
722  }
723  else if (unformat (line_input, "remote %U",
724  unformat_ip6_address, &remote.ip6))
725  {
726  remote_set = 1;
727  ipv6_set = 1;
728  }
729  else if (unformat (line_input, "group %U %U",
730  unformat_ip4_address, &remote.ip4,
732  vnet_get_main (), &mcast_sw_if_index))
733  {
734  grp_set = remote_set = 1;
735  ipv4_set = 1;
736  }
737  else if (unformat (line_input, "group %U %U",
738  unformat_ip6_address, &remote.ip6,
740  vnet_get_main (), &mcast_sw_if_index))
741  {
742  grp_set = remote_set = 1;
743  ipv6_set = 1;
744  }
745  else if (unformat (line_input, "encap-vrf-id %d", &tmp))
746  {
747  encap_fib_index = fib_table_find (fib_ip_proto (ipv6_set), tmp);
748  if (encap_fib_index == ~0)
749  {
750  error =
751  clib_error_return (0, "nonexistent encap-vrf-id %d", tmp);
752  goto done;
753  }
754  }
755  else if (unformat (line_input, "decap-next %U", unformat_decap_next,
756  &decap_next_index, ipv4_set))
757  ;
758  else if (unformat (line_input, "vni %d", &vni))
759  {
760  if (vni >> 24)
761  {
762  error = clib_error_return (0, "vni %d out of range", vni);
763  goto done;
764  }
765  }
766  else
767  {
768  error = clib_error_return (0, "parse error: '%U'",
769  format_unformat_error, line_input);
770  goto done;
771  }
772  }
773 
774  if (local_set == 0)
775  {
776  error = clib_error_return (0, "tunnel local address not specified");
777  goto done;
778  }
779 
780  if (remote_set == 0)
781  {
782  error = clib_error_return (0, "tunnel remote address not specified");
783  goto done;
784  }
785 
786  if (grp_set && !ip46_address_is_multicast (&remote))
787  {
788  error = clib_error_return (0, "tunnel group address not multicast");
789  goto done;
790  }
791 
792  if (grp_set == 0 && ip46_address_is_multicast (&remote))
793  {
794  error = clib_error_return (0, "remote address must be unicast");
795  goto done;
796  }
797 
798  if (grp_set && mcast_sw_if_index == ~0)
799  {
800  error = clib_error_return (0, "tunnel nonexistent multicast device");
801  goto done;
802  }
803 
804  if (ipv4_set && ipv6_set)
805  {
806  error = clib_error_return (0, "both IPv4 and IPv6 addresses specified");
807  goto done;
808  }
809 
810  if (ip46_address_cmp (&local, &remote) == 0)
811  {
812  error =
813  clib_error_return (0, "local and remote addresses are identical");
814  goto done;
815  }
816 
817  if (decap_next_index == ~0)
818  {
819  error = clib_error_return (0, "next node not found");
820  goto done;
821  }
822 
823  if (vni == 0)
824  {
825  error = clib_error_return (0, "vni not specified");
826  goto done;
827  }
828 
829  clib_memset (a, 0, sizeof (*a));
830 
831  a->is_add = is_add;
832  a->is_ip6 = ipv6_set;
833 
834 #define _(x) a->x = x;
836 #undef _
837 
838  rv = vnet_geneve_add_del_tunnel (a, &tunnel_sw_if_index);
839 
840  switch (rv)
841  {
842  case 0:
843  if (is_add)
845  vnet_get_main (), tunnel_sw_if_index);
846  break;
847 
848  case VNET_API_ERROR_TUNNEL_EXIST:
849  error = clib_error_return (0, "tunnel already exists...");
850  goto done;
851 
852  case VNET_API_ERROR_NO_SUCH_ENTRY:
853  error = clib_error_return (0, "tunnel does not exist...");
854  goto done;
855 
856  default:
857  error = clib_error_return
858  (0, "vnet_geneve_add_del_tunnel returned %d", rv);
859  goto done;
860  }
861 
862 done:
863  unformat_free (line_input);
864 
865  return error;
866 }
867 
868 /*?
869  * Add or delete a GENEVE Tunnel.
870  *
871  * GENEVE provides the features needed to allow L2 bridge domains (BDs)
872  * to span multiple servers. This is done by building an L2 overlay on
873  * top of an L3 network underlay using GENEVE tunnels.
874  *
875  * This makes it possible for servers to be co-located in the same data
876  * center or be separated geographically as long as they are reachable
877  * through the underlay L3 network.
878  *
879  * You can refer to this kind of L2 overlay bridge domain as a GENEVE
880  * segment.
881  *
882  * @cliexpar
883  * Example of how to create a GENEVE Tunnel:
884  * @cliexcmd{create geneve tunnel local 10.0.3.1 remote 10.0.3.3 vni 13 encap-vrf-id 7}
885  * Example of how to delete a GENEVE Tunnel:
886  * @cliexcmd{create geneve tunnel local 10.0.3.1 remote 10.0.3.3 vni 13 del}
887  ?*/
888 /* *INDENT-OFF* */
889 VLIB_CLI_COMMAND (create_geneve_tunnel_command, static) = {
890  .path = "create geneve tunnel",
891  .short_help =
892  "create geneve tunnel local <local-vtep-addr>"
893  " {remote <remote-vtep-addr>|group <mcast-vtep-addr> <intf-name>} vni <nn>"
894  " [encap-vrf-id <nn>] [decap-next [l2|node <name>]] [del]",
896 };
897 /* *INDENT-ON* */
898 
899 static clib_error_t *
901  unformat_input_t * input,
902  vlib_cli_command_t * cmd)
903 {
904  geneve_main_t *vxm = &geneve_main;
905  geneve_tunnel_t *t;
906 
907  if (pool_elts (vxm->tunnels) == 0)
908  vlib_cli_output (vm, "No geneve tunnels configured...");
909 
910  pool_foreach (t, vxm->tunnels, (
911  {
912  vlib_cli_output (vm, "%U",
913  format_geneve_tunnel, t);
914  }
915  ));
916 
917  return 0;
918 }
919 
920 /*?
921  * Display all the GENEVE Tunnel entries.
922  *
923  * @cliexpar
924  * Example of how to display the GENEVE Tunnel entries:
925  * @cliexstart{show geneve tunnel}
926  * [0] local 10.0.3.1 remote 10.0.3.3 vni 13 encap_fib_index 0 sw_if_index 5 decap_next l2
927  * @cliexend
928  ?*/
929 /* *INDENT-OFF* */
930 VLIB_CLI_COMMAND (show_geneve_tunnel_command, static) = {
931  .path = "show geneve tunnel",
932  .short_help = "show geneve tunnel",
933  .function = show_geneve_tunnel_command_fn,
934 };
935 /* *INDENT-ON* */
936 
937 
938 void
940 {
941  if (is_ip6)
942  vnet_feature_enable_disable ("ip6-unicast", "ip6-geneve-bypass",
943  sw_if_index, is_enable, 0, 0);
944  else
945  vnet_feature_enable_disable ("ip4-unicast", "ip4-geneve-bypass",
946  sw_if_index, is_enable, 0, 0);
947 }
948 
949 
950 static clib_error_t *
952  unformat_input_t * input, vlib_cli_command_t * cmd)
953 {
954  unformat_input_t _line_input, *line_input = &_line_input;
955  vnet_main_t *vnm = vnet_get_main ();
956  clib_error_t *error = 0;
957  u32 sw_if_index, is_enable;
958 
959  sw_if_index = ~0;
960  is_enable = 1;
961 
962  if (!unformat_user (input, unformat_line_input, line_input))
963  return 0;
964 
965  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
966  {
967  if (unformat_user
968  (line_input, unformat_vnet_sw_interface, vnm, &sw_if_index))
969  ;
970  else if (unformat (line_input, "del"))
971  is_enable = 0;
972  else
973  {
974  error = unformat_parse_error (line_input);
975  goto done;
976  }
977  }
978 
979  if (~0 == sw_if_index)
980  {
981  error = clib_error_return (0, "unknown interface `%U'",
982  format_unformat_error, line_input);
983  goto done;
984  }
985 
986  vnet_int_geneve_bypass_mode (sw_if_index, is_ip6, is_enable);
987 
988 done:
989  unformat_free (line_input);
990 
991  return error;
992 }
993 
994 static clib_error_t *
996  unformat_input_t * input, vlib_cli_command_t * cmd)
997 {
998  return set_ip_geneve_bypass (0, input, cmd);
999 }
1000 
1001 /*?
1002  * This command adds the 'ip4-geneve-bypass' graph node for a given interface.
1003  * By adding the IPv4 geneve-bypass graph node to an interface, the node checks
1004  * for and validate input geneve packet and bypass ip4-lookup, ip4-local,
1005  * ip4-udp-lookup nodes to speedup geneve packet forwarding. This node will
1006  * cause extra overhead to for non-geneve packets which is kept at a minimum.
1007  *
1008  * @cliexpar
1009  * @parblock
1010  * Example of graph node before ip4-geneve-bypass is enabled:
1011  * @cliexstart{show vlib graph ip4-geneve-bypass}
1012  * Name Next Previous
1013  * ip4-geneve-bypass error-drop [0]
1014  * geneve4-input [1]
1015  * ip4-lookup [2]
1016  * @cliexend
1017  *
1018  * Example of how to enable ip4-geneve-bypass on an interface:
1019  * @cliexcmd{set interface ip geneve-bypass GigabitEthernet2/0/0}
1020  *
1021  * Example of graph node after ip4-geneve-bypass is enabled:
1022  * @cliexstart{show vlib graph ip4-geneve-bypass}
1023  * Name Next Previous
1024  * ip4-geneve-bypass error-drop [0] ip4-input
1025  * geneve4-input [1] ip4-input-no-checksum
1026  * ip4-lookup [2]
1027  * @cliexend
1028  *
1029  * Example of how to display the feature enabed on an interface:
1030  * @cliexstart{show ip interface features GigabitEthernet2/0/0}
1031  * IP feature paths configured on GigabitEthernet2/0/0...
1032  * ...
1033  * ipv4 unicast:
1034  * ip4-geneve-bypass
1035  * ip4-lookup
1036  * ...
1037  * @cliexend
1038  *
1039  * Example of how to disable ip4-geneve-bypass on an interface:
1040  * @cliexcmd{set interface ip geneve-bypass GigabitEthernet2/0/0 del}
1041  * @endparblock
1042 ?*/
1043 /* *INDENT-OFF* */
1044 VLIB_CLI_COMMAND (set_interface_ip_geneve_bypass_command, static) = {
1045  .path = "set interface ip geneve-bypass",
1046  .function = set_ip4_geneve_bypass,
1047  .short_help = "set interface ip geneve-bypass <interface> [del]",
1048 };
1049 /* *INDENT-ON* */
1050 
1051 static clib_error_t *
1053  unformat_input_t * input, vlib_cli_command_t * cmd)
1054 {
1055  return set_ip_geneve_bypass (1, input, cmd);
1056 }
1057 
1058 /*?
1059  * This command adds the 'ip6-geneve-bypass' graph node for a given interface.
1060  * By adding the IPv6 geneve-bypass graph node to an interface, the node checks
1061  * for and validate input geneve packet and bypass ip6-lookup, ip6-local,
1062  * ip6-udp-lookup nodes to speedup geneve packet forwarding. This node will
1063  * cause extra overhead to for non-geneve packets which is kept at a minimum.
1064  *
1065  * @cliexpar
1066  * @parblock
1067  * Example of graph node before ip6-geneve-bypass is enabled:
1068  * @cliexstart{show vlib graph ip6-geneve-bypass}
1069  * Name Next Previous
1070  * ip6-geneve-bypass error-drop [0]
1071  * geneve6-input [1]
1072  * ip6-lookup [2]
1073  * @cliexend
1074  *
1075  * Example of how to enable ip6-geneve-bypass on an interface:
1076  * @cliexcmd{set interface ip6 geneve-bypass GigabitEthernet2/0/0}
1077  *
1078  * Example of graph node after ip6-geneve-bypass is enabled:
1079  * @cliexstart{show vlib graph ip6-geneve-bypass}
1080  * Name Next Previous
1081  * ip6-geneve-bypass error-drop [0] ip6-input
1082  * geneve6-input [1] ip4-input-no-checksum
1083  * ip6-lookup [2]
1084  * @cliexend
1085  *
1086  * Example of how to display the feature enabed on an interface:
1087  * @cliexstart{show ip interface features GigabitEthernet2/0/0}
1088  * IP feature paths configured on GigabitEthernet2/0/0...
1089  * ...
1090  * ipv6 unicast:
1091  * ip6-geneve-bypass
1092  * ip6-lookup
1093  * ...
1094  * @cliexend
1095  *
1096  * Example of how to disable ip6-geneve-bypass on an interface:
1097  * @cliexcmd{set interface ip6 geneve-bypass GigabitEthernet2/0/0 del}
1098  * @endparblock
1099 ?*/
1100 /* *INDENT-OFF* */
1101 VLIB_CLI_COMMAND (set_interface_ip6_geneve_bypass_command, static) = {
1102  .path = "set interface ip6 geneve-bypass",
1103  .function = set_ip6_geneve_bypass,
1104  .short_help = "set interface ip6 geneve-bypass <interface> [del]",
1105 };
1106 /* *INDENT-ON* */
1107 
1108 clib_error_t *
1110 {
1111  geneve_main_t *vxm = &geneve_main;
1112 
1113  vxm->vnet_main = vnet_get_main ();
1114  vxm->vlib_main = vm;
1115 
1116  /* initialize the ip6 hash */
1118  sizeof (geneve6_tunnel_key_t),
1119  sizeof (uword));
1120  vxm->vtep6 = hash_create_mem (0, sizeof (ip6_address_t), sizeof (uword));
1121  vxm->mcast_shared = hash_create_mem (0,
1122  sizeof (ip46_address_t),
1123  sizeof (mcast_shared_t));
1124 
1126 
1127  return 0;
1128 }
1129 
1131 
1132 /*
1133  * fd.io coding-style-patch-verification: ON
1134  *
1135  * Local Variables:
1136  * eval: (c-set-style "gnu")
1137  * End:
1138  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:440
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:1052
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:82
u32 hw_if_index
Definition: geneve.h:116
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:485
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:346
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:554
static mcast_shared_t mcast_shared_get(ip46_address_t *ip)
Definition: geneve.c:335
unsigned long u64
Definition: types.h:89
#define NULL
Definition: clib.h:58
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 decap_next_index
Definition: geneve.h:109
fib_node_t node
Linkage into the FIB object graph.
Definition: geneve.h:121
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:523
#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:106
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:669
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:65
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)
uword * vtep6
Definition: geneve.h:171
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
dpo_id_t next_dpo
Definition: geneve.h:91
unformat_function_t unformat_vnet_sw_interface
static uword vtep_addr_ref(ip46_address_t *ip)
Definition: geneve.c:296
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:451
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:369
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:558
u8 * format_geneve_encap_trace(u8 *s, va_list *args)
Definition: geneve.c:42
ip6_address_t src_address
Definition: ip6_packet.h:307
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:162
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:900
VNET_HW_INTERFACE_CLASS(geneve_hw_class)
vnet_flood_class_t flood_class
Definition: interface.h:745
clib_error_t * geneve_init(vlib_main_t *vm)
Definition: geneve.c:1109
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
unformat_function_t unformat_ip4_address
Definition: format.h:68
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:525
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:59
#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:88
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:863
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)
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:324
static clib_error_t * set_ip_geneve_bypass(u32 is_ip6, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: geneve.c:951
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:762
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:519
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
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:112
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:995
struct _unformat_input_t unformat_input_t
u32 vni
Definition: lisp_gpe.api:129
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:287
#define PREDICT_FALSE(x)
Definition: clib.h:111
static void vnet_set_geneve_version(geneve_header_t *h, u8 version)
vnet_sw_interface_flags_t flags
Definition: interface.h:720
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:862
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:1810
u8 len
Definition: ip_types.api:91
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:231
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
uword * vtep4
Definition: geneve.h:170
u32 flags
Definition: vhost_user.h:141
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
ip46_address_t local
Definition: geneve.h:102
vnet_flood_class_t
Definition: interface.h:661
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:893
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:165
Aggregate type for a prefix.
Definition: mfib_types.h:24
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1810
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:1629
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:886
VNET_DEVICE_CLASS(geneve_device_class, static)
u32 sw_if_index
Definition: geneve.h:115
#define ASSERT(truth)
void fib_entry_untrack(fib_node_index_t fei, u32 sibling)
Stop tracking a FIB entry.
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:595
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:136
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:260
static int geneve_rewrite(geneve_tunnel_t *t, bool is_ip6)
Definition: geneve.c:213
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:294
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:103
vl_api_address_t ip
Definition: l2.api:490
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:532
#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:492
u64 uword
Definition: types.h:112
uword * geneve6_tunnel_by_key
Definition: geneve.h:166
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
fib_node_index_t fib_entry_index
Definition: geneve.h:127
#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:637
static void mcast_shared_remove(ip46_address_t *remote)
Definition: geneve.c:358
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:501
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:648
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:545
vnet_link_t fib_proto_to_link(fib_protocol_t proto)
Convert from a protocol to a link type.
Definition: fib_types.c:294
static uword vtep_addr_unref(ip46_address_t *ip)
Definition: geneve.c:310
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:471
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:487
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:247
const ip46_address_t zero_addr
Definition: lookup.c:307
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:307
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:939
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128