FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
vxlan_gpe.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
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 /**
16  * @file
17  * @brief Common utility functions for IPv4 and IPv6 VXLAN GPE tunnels
18  *
19 */
21 #include <vnet/fib/fib.h>
22 #include <vnet/ip/format.h>
23 
25 
26 /**
27  * @brief Tracing function for VXLAN GPE tunnel packets
28  *
29  * @param *s formatting string
30  * @param *args
31  *
32  * @return *s formatted string
33  *
34  */
35 u8 * format_vxlan_gpe_tunnel (u8 * s, va_list * args)
36 {
37  vxlan_gpe_tunnel_t * t = va_arg (*args, vxlan_gpe_tunnel_t *);
39 
40  s = format (s, "[%d] local: %U remote: %U ",
41  t - gm->tunnels,
44 
45  s = format (s, " vxlan VNI %d ", t->vni);
46 
47  switch (t->protocol)
48  {
49  case VXLAN_GPE_PROTOCOL_IP4:
50  s = format (s, "next-protocol ip4");
51  break;
52  case VXLAN_GPE_PROTOCOL_IP6:
53  s = format (s, "next-protocol ip6");
54  break;
55  case VXLAN_GPE_PROTOCOL_ETHERNET:
56  s = format (s, "next-protocol ethernet");
57  break;
58  case VXLAN_GPE_PROTOCOL_NSH:
59  s = format (s, "next-protocol nsh");
60  break;
61  default:
62  s = format (s, "next-protocol unknown %d", t->protocol);
63  }
64 
65  s = format (s, " fibs: (encap %d, decap %d)",
66  t->encap_fib_index,
67  t->decap_fib_index);
68 
69  return s;
70 }
71 
72 /**
73  * @brief Naming for VXLAN GPE tunnel
74  *
75  * @param *s formatting string
76  * @param *args
77  *
78  * @return *s formatted string
79  *
80  */
81 static u8 * format_vxlan_gpe_name (u8 * s, va_list * args)
82 {
83  u32 dev_instance = va_arg (*args, u32);
84  return format (s, "vxlan_gpe_tunnel%d", dev_instance);
85 }
86 
88  vlib_node_runtime_t * node,
89  vlib_frame_t * frame)
90 {
91  clib_warning ("you shouldn't be here, leaking buffers...");
92  return frame->n_vectors;
93 }
94 
95 /**
96  * @brief CLI function for VXLAN GPE admin up/down
97  *
98  * @param *vnm
99  * @param hw_if_index
100  * @param flag
101  *
102  * @return *rc
103  *
104  */
105 static clib_error_t *
107 {
110  else
111  vnet_hw_interface_set_flags (vnm, hw_if_index, 0);
112 
113  return 0;
114 }
115 
116 VNET_DEVICE_CLASS (vxlan_gpe_device_class,static) = {
117  .name = "VXLAN_GPE",
118  .format_device_name = format_vxlan_gpe_name,
119  .format_tx_trace = format_vxlan_gpe_encap_trace,
120  .tx_function = dummy_interface_tx,
121  .admin_up_down_function = vxlan_gpe_interface_admin_up_down,
122 };
123 
124 
125 /**
126  * @brief Formatting function for tracing VXLAN GPE with length
127  *
128  * @param *s
129  * @param *args
130  *
131  * @return *s
132  *
133  */
134 static u8 * format_vxlan_gpe_header_with_length (u8 * s, va_list * args)
135 {
136  u32 dev_instance = va_arg (*args, u32);
137  s = format (s, "unimplemented dev %u", dev_instance);
138  return s;
139 }
140 
141 VNET_HW_INTERFACE_CLASS (vxlan_gpe_hw_class) = {
142  .name = "VXLAN_GPE",
143  .format_header = format_vxlan_gpe_header_with_length,
144  .build_rewrite = default_build_rewrite,
146 };
147 
148 
149 #define foreach_gpe_copy_field \
150 _(vni) \
151 _(protocol) \
152 _(encap_fib_index) \
153 _(decap_fib_index)
154 
155 #define foreach_copy_ipv4 { \
156  _(local.ip4.as_u32) \
157  _(remote.ip4.as_u32) \
158 }
159 
160 #define foreach_copy_ipv6 { \
161  _(local.ip6.as_u64[0]) \
162  _(local.ip6.as_u64[1]) \
163  _(remote.ip6.as_u64[0]) \
164  _(remote.ip6.as_u64[1]) \
165 }
166 
167 
168 /**
169  * @brief Calculate IPv4 VXLAN GPE rewrite header
170  *
171  * @param *t
172  *
173  * @return rc
174  *
175  */
176 int vxlan4_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size,
177  u8 protocol_override, uword encap_next_node)
178 {
179  u8 *rw = 0;
180  ip4_header_t * ip0;
181  ip4_vxlan_gpe_header_t * h0;
182  int len;
183 
184  len = sizeof (*h0) + extension_size;
185 
186  vec_free(t->rewrite);
188 
189  h0 = (ip4_vxlan_gpe_header_t *) rw;
190 
191  /* Fixed portion of the (outer) ip4 header */
192  ip0 = &h0->ip4;
193  ip0->ip_version_and_header_length = 0x45;
194  ip0->ttl = 254;
195  ip0->protocol = IP_PROTOCOL_UDP;
196 
197  /* we fix up the ip4 header length and checksum after-the-fact */
198  ip0->src_address.as_u32 = t->local.ip4.as_u32;
199  ip0->dst_address.as_u32 = t->remote.ip4.as_u32;
200  ip0->checksum = ip4_header_checksum (ip0);
201 
202  /* UDP header, randomize src port on something, maybe? */
203  h0->udp.src_port = clib_host_to_net_u16 (4790);
204  h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_vxlan_gpe);
205 
206  /* VXLAN header. Are we having fun yet? */
207  h0->vxlan.flags = VXLAN_GPE_FLAGS_I | VXLAN_GPE_FLAGS_P;
208  h0->vxlan.ver_res = VXLAN_GPE_VERSION;
209  if (protocol_override)
210  {
211  h0->vxlan.protocol = protocol_override;
212  }
213  else
214  {
215  h0->vxlan.protocol = t->protocol;
216  }
217  t->rewrite_size = sizeof(ip4_vxlan_gpe_header_t) + extension_size;
218  h0->vxlan.vni_res = clib_host_to_net_u32 (t->vni<<8);
219 
220  t->rewrite = rw;
221  t->encap_next_node = encap_next_node;
222  return (0);
223 }
224 
225 /**
226  * @brief Calculate IPv6 VXLAN GPE rewrite header
227  *
228  * @param *t
229  *
230  * @return rc
231  *
232  */
233 int vxlan6_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size,
234  u8 protocol_override, uword encap_next_node)
235 {
236  u8 *rw = 0;
237  ip6_header_t * ip0;
238  ip6_vxlan_gpe_header_t * h0;
239  int len;
240 
241  len = sizeof (*h0) + extension_size;
242 
243  vec_free(t->rewrite);
245 
246  h0 = (ip6_vxlan_gpe_header_t *) rw;
247 
248  /* Fixed portion of the (outer) ip4 header */
249  ip0 = &h0->ip6;
250  ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32(6 << 28);
251  ip0->hop_limit = 255;
252  ip0->protocol = IP_PROTOCOL_UDP;
253 
254  ip0->src_address.as_u64[0] = t->local.ip6.as_u64[0];
255  ip0->src_address.as_u64[1] = t->local.ip6.as_u64[1];
256  ip0->dst_address.as_u64[0] = t->remote.ip6.as_u64[0];
257  ip0->dst_address.as_u64[1] = t->remote.ip6.as_u64[1];
258 
259  /* UDP header, randomize src port on something, maybe? */
260  h0->udp.src_port = clib_host_to_net_u16 (4790);
261  h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_vxlan_gpe);
262 
263  /* VXLAN header. Are we having fun yet? */
264  h0->vxlan.flags = VXLAN_GPE_FLAGS_I | VXLAN_GPE_FLAGS_P;
265  h0->vxlan.ver_res = VXLAN_GPE_VERSION;
266  if (protocol_override)
267  {
268  h0->vxlan.protocol = t->protocol;
269  }
270  else
271  {
272  h0->vxlan.protocol = protocol_override;
273  }
274  t->rewrite_size = sizeof(ip4_vxlan_gpe_header_t) + extension_size;
275  h0->vxlan.vni_res = clib_host_to_net_u32 (t->vni<<8);
276 
277  t->rewrite = rw;
278  t->encap_next_node = encap_next_node;
279  return (0);
280 }
281 
282 /**
283  * @brief Add or Del a VXLAN GPE tunnel
284  *
285  * @param *a
286  * @param *sw_if_index
287  *
288  * @return rc
289  *
290  */
293 {
295  vxlan_gpe_tunnel_t *t = 0;
296  vnet_main_t * vnm = gm->vnet_main;
298  uword * p;
299  u32 hw_if_index = ~0;
300  u32 sw_if_index = ~0;
301  int rv;
302  vxlan4_gpe_tunnel_key_t key4, *key4_copy;
303  vxlan6_gpe_tunnel_key_t key6, *key6_copy;
304  hash_pair_t *hp;
305 
306  if (!a->is_ip6)
307  {
308  key4.local = a->local.ip4.as_u32;
309  key4.remote = a->remote.ip4.as_u32;
310  key4.vni = clib_host_to_net_u32 (a->vni << 8);
311  key4.pad = 0;
312 
313  p = hash_get_mem(gm->vxlan4_gpe_tunnel_by_key, &key4);
314  }
315  else
316  {
317  key6.local.as_u64[0] = a->local.ip6.as_u64[0];
318  key6.local.as_u64[1] = a->local.ip6.as_u64[1];
319  key6.remote.as_u64[0] = a->remote.ip6.as_u64[0];
320  key6.remote.as_u64[1] = a->remote.ip6.as_u64[1];
321  key6.vni = clib_host_to_net_u32 (a->vni << 8);
322 
323  p = hash_get_mem(gm->vxlan6_gpe_tunnel_by_key, &key6);
324  }
325 
326  if (a->is_add)
327  {
328  /* adding a tunnel: tunnel must not already exist */
329  if (p)
330  return VNET_API_ERROR_INVALID_VALUE;
331 
333  memset (t, 0, sizeof (*t));
334 
335  /* copy from arg structure */
336 #define _(x) t->x = a->x;
338  if (!a->is_ip6) foreach_copy_ipv4
339  else foreach_copy_ipv6
340 #undef _
341 
342  if (!a->is_ip6) t->flags |= VXLAN_GPE_TUNNEL_IS_IPV4;
343 
344  if (!a->is_ip6) {
346  } else {
348  }
349 
350  if (rv)
351  {
352  pool_put (gm->tunnels, t);
353  return rv;
354  }
355 
356  if (!a->is_ip6)
357  {
358  key4_copy = clib_mem_alloc (sizeof (*key4_copy));
359  clib_memcpy (key4_copy, &key4, sizeof (*key4_copy));
360  hash_set_mem (gm->vxlan4_gpe_tunnel_by_key, key4_copy,
361  t - gm->tunnels);
362  }
363  else
364  {
365  key6_copy = clib_mem_alloc (sizeof (*key6_copy));
366  clib_memcpy (key6_copy, &key6, sizeof (*key6_copy));
367  hash_set_mem (gm->vxlan6_gpe_tunnel_by_key, key6_copy,
368  t - gm->tunnels);
369  }
370 
372  {
373  hw_if_index = gm->free_vxlan_gpe_tunnel_hw_if_indices
375  _vec_len (gm->free_vxlan_gpe_tunnel_hw_if_indices) -= 1;
376 
377  hi = vnet_get_hw_interface (vnm, hw_if_index);
378  hi->dev_instance = t - gm->tunnels;
379  hi->hw_instance = hi->dev_instance;
380  }
381  else
382  {
383  hw_if_index = vnet_register_interface
384  (vnm, vxlan_gpe_device_class.index, t - gm->tunnels,
385  vxlan_gpe_hw_class.index, t - gm->tunnels);
386  hi = vnet_get_hw_interface (vnm, hw_if_index);
388  }
389 
390  t->hw_if_index = hw_if_index;
391  t->sw_if_index = sw_if_index = hi->sw_if_index;
393  gm->tunnel_index_by_sw_if_index[sw_if_index] = t - gm->tunnels;
394 
397  }
398  else
399  {
400  /* deleting a tunnel: tunnel must exist */
401  if (!p)
402  return VNET_API_ERROR_NO_SUCH_ENTRY;
403 
404  t = pool_elt_at_index (gm->tunnels, p[0]);
405 
406  vnet_sw_interface_set_flags (vnm, t->sw_if_index, 0 /* down */);
408 
410 
411  if (!a->is_ip6)
412  {
413  hp = hash_get_pair (gm->vxlan4_gpe_tunnel_by_key, &key4);
414  key4_copy = (void *)(hp->key);
416  clib_mem_free (key4_copy);
417  }
418  else
419  {
420  hp = hash_get_pair (gm->vxlan6_gpe_tunnel_by_key, &key6);
421  key6_copy = (void *)(hp->key);
423  clib_mem_free (key6_copy);
424  }
425 
426  vec_free (t->rewrite);
427  pool_put (gm->tunnels, t);
428  }
429 
430  if (sw_if_indexp)
431  *sw_if_indexp = sw_if_index;
432 
433  return 0;
434 }
435 
436 static clib_error_t *
438  unformat_input_t * input,
439  vlib_cli_command_t * cmd)
440 {
441  unformat_input_t _line_input, * line_input = &_line_input;
442  u8 is_add = 1;
443  ip46_address_t local, remote;
444  u8 local_set = 0;
445  u8 remote_set = 0;
446  u8 ipv4_set = 0;
447  u8 ipv6_set = 0;
448  u32 encap_fib_index = 0;
449  u32 decap_fib_index = 0;
450  u8 protocol = VXLAN_GPE_PROTOCOL_IP4;
451  u32 vni;
452  u8 vni_set = 0;
453  int rv;
454  u32 tmp;
456  u32 sw_if_index;
457  clib_error_t *error = NULL;
458 
459  /* Get a line of input. */
460  if (! unformat_user (input, unformat_line_input, line_input))
461  return 0;
462 
463  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
464  if (unformat (line_input, "del"))
465  is_add = 0;
466  else if (unformat (line_input, "local %U",
467  unformat_ip4_address, &local.ip4))
468  {
469  local_set = 1;
470  ipv4_set = 1;
471  }
472  else if (unformat (line_input, "remote %U",
473  unformat_ip4_address, &remote.ip4))
474  {
475  remote_set = 1;
476  ipv4_set = 1;
477  }
478  else if (unformat (line_input, "local %U",
479  unformat_ip6_address, &local.ip6))
480  {
481  local_set = 1;
482  ipv6_set = 1;
483  }
484  else if (unformat (line_input, "remote %U",
485  unformat_ip6_address, &remote.ip6))
486  {
487  remote_set = 1;
488  ipv6_set = 1;
489  }
490  else if (unformat (line_input, "encap-vrf-id %d", &tmp))
491  {
492  if (ipv6_set)
493  encap_fib_index = ip6_fib_index_from_table_id (tmp);
494  else
495  encap_fib_index = ip4_fib_index_from_table_id (tmp);
496 
497  if (encap_fib_index == ~0)
498  {
499  error = clib_error_return (0, "nonexistent encap fib id %d", tmp);
500  goto done;
501  }
502  }
503  else if (unformat (line_input, "decap-vrf-id %d", &tmp))
504  {
505  if (ipv6_set)
506  decap_fib_index = ip6_fib_index_from_table_id (tmp);
507  else
508  decap_fib_index = ip4_fib_index_from_table_id (tmp);
509 
510  if (decap_fib_index == ~0)
511  {
512  error = clib_error_return (0, "nonexistent decap fib id %d", tmp);
513  goto done;
514  }
515  }
516  else if (unformat (line_input, "vni %d", &vni))
517  vni_set = 1;
518  else if (unformat(line_input, "next-ip4"))
519  protocol = VXLAN_GPE_PROTOCOL_IP4;
520  else if (unformat(line_input, "next-ip6"))
521  protocol = VXLAN_GPE_PROTOCOL_IP6;
522  else if (unformat(line_input, "next-ethernet"))
523  protocol = VXLAN_GPE_PROTOCOL_ETHERNET;
524  else if (unformat(line_input, "next-nsh"))
525  protocol = VXLAN_GPE_PROTOCOL_NSH;
526  else
527  {
528  error = clib_error_return (0, "parse error: '%U'",
529  format_unformat_error, line_input);
530  goto done;
531  }
532  }
533 
534  if (local_set == 0)
535  {
536  error = clib_error_return (0, "tunnel local address not specified");
537  goto done;
538  }
539 
540  if (remote_set == 0)
541  {
542  error = clib_error_return (0, "tunnel remote address not specified");
543  goto done;
544  }
545 
546  if (ipv4_set && ipv6_set)
547  {
548  error = clib_error_return (0, "both IPv4 and IPv6 addresses specified");
549  goto done;
550  }
551 
552  if ((ipv4_set && memcmp(&local.ip4, &remote.ip4, sizeof(local.ip4)) == 0) ||
553  (ipv6_set && memcmp(&local.ip6, &remote.ip6, sizeof(local.ip6)) == 0))
554  {
555  error = clib_error_return (0, "src and dst addresses are identical");
556  goto done;
557  }
558 
559  if (vni_set == 0)
560  {
561  error = clib_error_return (0, "vni not specified");
562  goto done;
563  }
564 
565  memset (a, 0, sizeof (*a));
566 
567  a->is_add = is_add;
568  a->is_ip6 = ipv6_set;
569 
570 #define _(x) a->x = x;
572  if (ipv4_set) foreach_copy_ipv4
573  else foreach_copy_ipv6
574 #undef _
575 
576  rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index);
577 
578  switch(rv)
579  {
580  case 0:
581  vlib_cli_output(vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main(), sw_if_index);
582  break;
583  case VNET_API_ERROR_INVALID_DECAP_NEXT:
584  error = clib_error_return (0, "invalid decap-next...");
585  goto done;
586 
587  case VNET_API_ERROR_TUNNEL_EXIST:
588  error = clib_error_return (0, "tunnel already exists...");
589  goto done;
590 
591  case VNET_API_ERROR_NO_SUCH_ENTRY:
592  error = clib_error_return (0, "tunnel does not exist...");
593  goto done;
594 
595  default:
596  error = clib_error_return
597  (0, "vnet_vxlan_gpe_add_del_tunnel returned %d", rv);
598  goto done;
599  }
600 
601 done:
602  unformat_free (line_input);
603 
604  return error;
605 }
606 
607 VLIB_CLI_COMMAND (create_vxlan_gpe_tunnel_command, static) = {
608  .path = "create vxlan-gpe tunnel",
609  .short_help =
610  "create vxlan-gpe tunnel local <local-addr> remote <remote-addr>"
611  " vni <nn> [next-ip4][next-ip6][next-ethernet][next-nsh]"
612  " [encap-vrf-id <nn>] [decap-vrf-id <nn>]"
613  " [del]\n",
615 };
616 
617 /**
618  * @brief CLI function for showing VXLAN GPE tunnels
619  *
620  * @param *vm
621  * @param *input
622  * @param *cmd
623  *
624  * @return error
625  *
626  */
627 static clib_error_t *
629  unformat_input_t * input,
630  vlib_cli_command_t * cmd)
631 {
633  vxlan_gpe_tunnel_t * t;
634 
635  if (pool_elts (gm->tunnels) == 0)
636  vlib_cli_output (vm, "No vxlan-gpe tunnels configured.");
637 
638  pool_foreach (t, gm->tunnels,
639  ({
640  vlib_cli_output (vm, "%U", format_vxlan_gpe_tunnel, t);
641  }));
642 
643  return 0;
644 }
645 
646 VLIB_CLI_COMMAND (show_vxlan_gpe_tunnel_command, static) = {
647  .path = "show vxlan-gpe",
649 };
650 
651 /**
652  * @brief Feature init function for VXLAN GPE
653  *
654  * @param *vm
655  *
656  * @return error
657  *
658  */
660 {
662 
663  gm->vnet_main = vnet_get_main();
664  gm->vlib_main = vm;
665 
667  = hash_create_mem (0, sizeof(vxlan4_gpe_tunnel_key_t), sizeof (uword));
668 
670  = hash_create_mem (0, sizeof(vxlan6_gpe_tunnel_key_t), sizeof (uword));
671 
672 
673  udp_register_dst_port (vm, UDP_DST_PORT_vxlan_gpe,
674  vxlan4_gpe_input_node.index, 1 /* is_ip4 */);
675  udp_register_dst_port (vm, UDP_DST_PORT_vxlan6_gpe,
676  vxlan6_gpe_input_node.index, 0 /* is_ip4 */);
677 
678  /* Register the list of standard decap protocols supported */
679  vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IP4,
680  VXLAN_GPE_INPUT_NEXT_IP4_INPUT);
681  vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IP6,
682  VXLAN_GPE_INPUT_NEXT_IP6_INPUT);
683  vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_ETHERNET,
684  VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT);
685  return 0;
686 }
687 
689 
uword * vxlan6_gpe_tunnel_by_key
lookup IPv6 VXLAN GPE tunnel by key
Definition: vxlan_gpe.h:159
vmrglw vmrglh hi
u32 flags
flags
Definition: vxlan_gpe.h:116
clib_error_t * vxlan_gpe_init(vlib_main_t *vm)
Feature init function for VXLAN GPE.
Definition: vxlan_gpe.c:659
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:530
ip4_address_t src_address
Definition: ip4_packet.h:163
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vlib_node_registration_t vxlan4_gpe_input_node
(constructor) VLIB_REGISTER_NODE (vxlan4_gpe_input_node)
Definition: decap.c:689
static uword dummy_interface_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: vxlan_gpe.c:87
u64 as_u64[2]
Definition: ip6_packet.h:51
#define foreach_copy_ipv4
Definition: vxlan_gpe.c:155
#define NULL
Definition: clib.h:55
u32 * tunnel_index_by_sw_if_index
Mapping from sw_if_index to tunnel index.
Definition: vxlan_gpe.h:165
VXLAN GPE definitions.
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:522
int vxlan6_gpe_rewrite(vxlan_gpe_tunnel_t *t, u32 extension_size, u8 protocol_override, uword encap_next_node)
Calculate IPv6 VXLAN GPE rewrite header.
Definition: vxlan_gpe.c:233
vlib_node_registration_t vxlan6_gpe_input_node
(constructor) VLIB_REGISTER_NODE (vxlan6_gpe_input_node)
Definition: decap.c:712
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:982
format_function_t format_ip46_address
Definition: format.h:61
#define hash_set_mem(h, key, value)
Definition: hash.h:274
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:379
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:447
int vnet_vxlan_gpe_add_del_tunnel(vnet_vxlan_gpe_add_del_tunnel_args_t *a, u32 *sw_if_indexp)
Add or Del a VXLAN GPE tunnel.
Definition: vxlan_gpe.c:292
#define VXLAN_GPE_FLAGS_P
ip6_address_t src_address
Definition: ip6_packet.h:341
format_function_t format_vnet_sw_if_index_name
vnet_main_t * vnet_main
State convenience vnet_main_t.
Definition: vxlan_gpe.h:170
#define VXLAN_GPE_VERSION
#define VXLAN_GPE_FLAGS_I
#define foreach_gpe_copy_field
Definition: vxlan_gpe.c:149
u8 * format_vxlan_gpe_tunnel(u8 *s, va_list *args)
Tracing function for VXLAN GPE tunnel packets.
Definition: vxlan_gpe.c:35
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
unformat_function_t unformat_ip4_address
Definition: format.h:76
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
ip46_address_t local
tunnel local address
Definition: vxlan_gpe.h:98
static u8 * format_vxlan_gpe_header_with_length(u8 *s, va_list *args)
Formatting function for tracing VXLAN GPE with length.
Definition: vxlan_gpe.c:134
ip4_address_t dst_address
Definition: ip4_packet.h:163
u8 * format_vxlan_gpe_encap_trace(u8 *s, va_list *args)
Trace of packets encapsulated in VXLAN GPE.
Definition: encap.c:66
#define clib_error_return(e, args...)
Definition: error.h:111
#define hash_get_pair(h, key)
Definition: hash.h:251
void vxlan_gpe_register_decap_protocol(u8 protocol_id, uword next_node_index)
Definition: decap.c:645
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:681
u8 * rewrite
Rewrite string.
Definition: vxlan_gpe.h:92
unformat_function_t unformat_line_input
Definition: format.h:281
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:637
int vxlan4_gpe_rewrite(vxlan_gpe_tunnel_t *t, u32 extension_size, u8 protocol_override, uword encap_next_node)
Calculate IPv4 VXLAN GPE rewrite header.
Definition: vxlan_gpe.c:176
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
#define hash_unset_mem(h, key)
Definition: hash.h:280
Struct for VXLAN GPE tunnel.
Definition: vxlan_gpe.h:90
static u32 ip6_fib_index_from_table_id(u32 table_id)
Definition: ip6_fib.h:122
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
vxlan_gpe_main_t vxlan_gpe_main
Definition: vxlan_gpe.c:24
vlib_main_t * vlib_main
State convenience vlib_main_t.
Definition: vxlan_gpe.h:168
u8 protocol
encapsulated protocol
Definition: vxlan_gpe.h:95
ip46_address_t remote
tunnel remote address
Definition: vxlan_gpe.h:100
u32 vni
VXLAN GPE VNI in HOST byte order, shifted left 8 bits.
Definition: vxlan_gpe.h:108
unformat_function_t unformat_ip6_address
Definition: format.h:94
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
Definition: pool.h:169
Struct for VXLAN GPE add/del args.
Definition: vxlan_gpe.h:185
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
u16 n_vectors
Definition: node.h:344
vlib_main_t * vm
Definition: buffer.c:276
VNET_DEVICE_CLASS(vxlan_gpe_device_class, static)
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
#define clib_warning(format, args...)
Definition: error.h:59
#define clib_memcpy(a, b, c)
Definition: string.h:69
static u32 ip4_fib_index_from_table_id(u32 table_id)
Definition: ip4_fib.h:110
static u8 * format_vxlan_gpe_name(u8 *s, va_list *args)
Naming for VXLAN GPE tunnel.
Definition: vxlan_gpe.c:81
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:1386
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
static clib_error_t * vxlan_gpe_add_del_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: vxlan_gpe.c:437
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:536
unsigned int u32
Definition: types.h:88
VNET_HW_INTERFACE_CLASS(vxlan_gpe_hw_class)
static clib_error_t * vxlan_gpe_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
CLI function for VXLAN GPE admin up/down.
Definition: vxlan_gpe.c:106
u8 rewrite_size
rewrite size for dynamic plugins like iOAM
Definition: vxlan_gpe.h:119
Struct for VXLAN GPE node state.
Definition: vxlan_gpe.h:152
static void clib_mem_free(void *p)
Definition: mem.h:176
static void * clib_mem_alloc(uword size)
Definition: mem.h:109
vxlan_gpe_tunnel_t * tunnels
vector of encap tunnel instances
Definition: vxlan_gpe.h:154
u64 uword
Definition: types.h:112
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:328
uword * vxlan4_gpe_tunnel_by_key
lookup IPv4 VXLAN GPE tunnel by key
Definition: vxlan_gpe.h:157
u32 decap_fib_index
FIB indices - inner IP packet lookup here.
Definition: vxlan_gpe.h:105
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
static clib_error_t * show_vxlan_gpe_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI function for showing VXLAN GPE tunnels.
Definition: vxlan_gpe.c:628
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
a point 2 point interface
Definition: interface.h:274
u32 hw_if_index
vnet intfc hw_if_index
Definition: vxlan_gpe.h:111
#define hash_get_mem(h, key)
Definition: hash.h:268
u32 encap_fib_index
FIB indices - tunnel partner lookup here.
Definition: vxlan_gpe.h:103
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
uword encap_next_node
Next node after VxLAN-GPE encap.
Definition: vxlan_gpe.h:122
u32 sw_if_index
vnet intfc sw_if_index
Definition: vxlan_gpe.h:113
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:538
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:488
u8 ip_version_and_header_length
Definition: ip4_packet.h:131
vlib_node_registration_t vxlan_gpe_encap_node
(constructor) VLIB_REGISTER_NODE (vxlan_gpe_encap_node)
Definition: encap.c:370
u32 flags
Definition: vhost-user.h:78
#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:485
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
#define VXLAN_GPE_TUNNEL_IS_IPV4
Flags for vxlan_gpe_tunnel_t.
Definition: vxlan_gpe.h:126
#define foreach_copy_ipv6
Definition: vxlan_gpe.c:160
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:577
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:238
uword key
Definition: hash.h:161
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
ip6_address_t dst_address
Definition: ip6_packet.h:341
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u32 * free_vxlan_gpe_tunnel_hw_if_indices
Free vlib hw_if_indices.
Definition: vxlan_gpe.h:162
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109