FD.io VPP  v16.06
Vector Packet Processing
interface.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 #include <vppinfra/error.h>
17 #include <vppinfra/hash.h>
18 #include <vnet/vnet.h>
19 #include <vnet/ip/ip.h>
20 #include <vnet/ip/udp.h>
21 #include <vnet/ethernet/ethernet.h>
22 #include <vnet/lisp-gpe/lisp_gpe.h>
23 
24 #define foreach_lisp_gpe_tx_next \
25  _(DROP, "error-drop") \
26  _(IP4_LOOKUP, "ip4-lookup") \
27  _(IP6_LOOKUP, "ip6-lookup")
28 
29 typedef enum
30 {
31 #define _(sym,str) LISP_GPE_TX_NEXT_##sym,
33 #undef _
36 
37 typedef struct
38 {
41 
42 u8 *
43 format_lisp_gpe_tx_trace (u8 * s, va_list * args)
44 {
45  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
46  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
47  lisp_gpe_tx_trace_t * t = va_arg (*args, lisp_gpe_tx_trace_t *);
48 
49  s = format (s, "LISP-GPE-TX: tunnel %d", t->tunnel_index);
50  return s;
51 }
52 
53 always_inline void
55  lisp_gpe_tunnel_t ** t0, u8 is_v4)
56 {
57  u32 adj_index0, tunnel_index0;
58  ip_adjacency_t * adj0;
59 
60  /* Get adjacency and from it the tunnel_index */
61  adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
62 
63  if (is_v4)
64  adj0 = ip_get_adjacency (lgm->lm4, adj_index0);
65  else
66  adj0 = ip_get_adjacency (lgm->lm6, adj_index0);
67 
68  tunnel_index0 = adj0->rewrite_header.node_index;
69  t0[0] = pool_elt_at_index(lgm->tunnels, tunnel_index0);
70 
71  ASSERT(t0[0] != 0);
72 }
73 
74 always_inline void
76  lisp_gpe_tunnel_t * t0, u32 * next0, u8 is_v4)
77 {
78  ASSERT(sizeof(ip4_udp_lisp_gpe_header_t) == 36);
79  ASSERT(sizeof(ip6_udp_lisp_gpe_header_t) == 56);
80 
81  if (is_v4)
82  {
83  ip_udp_encap_one (lgm->vlib_main, b0, t0->rewrite, 36, 1);
84  next0[0] = LISP_GPE_TX_NEXT_IP4_LOOKUP;
85 
86  }
87  else
88  {
89  ip_udp_encap_one (lgm->vlib_main, b0, t0->rewrite, 56, 0);
90  next0[0] = LISP_GPE_TX_NEXT_IP6_LOOKUP;
91  }
92 }
93 
94 always_inline void
96  vlib_buffer_t * b1, lisp_gpe_tunnel_t ** t0,
97  lisp_gpe_tunnel_t ** t1, u8 is_v4)
98 {
99  u32 adj_index0, adj_index1, tunnel_index0, tunnel_index1;
100  ip_adjacency_t * adj0, * adj1;
101 
102  /* Get adjacency and from it the tunnel_index */
103  adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
104  adj_index1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
105 
106  if (is_v4)
107  {
108  adj0 = ip_get_adjacency (lgm->lm4, adj_index0);
109  adj1 = ip_get_adjacency (lgm->lm4, adj_index1);
110  }
111  else
112  {
113  adj0 = ip_get_adjacency (lgm->lm6, adj_index0);
114  adj1 = ip_get_adjacency (lgm->lm6, adj_index1);
115  }
116 
117  tunnel_index0 = adj0->rewrite_header.node_index;
118  tunnel_index1 = adj1->rewrite_header.node_index;
119 
120  t0[0] = pool_elt_at_index(lgm->tunnels, tunnel_index0);
121  t1[0] = pool_elt_at_index(lgm->tunnels, tunnel_index1);
122 
123  ASSERT(t0[0] != 0);
124  ASSERT(t1[0] != 0);
125 }
126 
127 always_inline void
129  lisp_gpe_tunnel_t * t0, lisp_gpe_tunnel_t * t1, u32 * next0,
130  u32 * next1, u8 is_v4)
131 {
132  ASSERT(sizeof(ip4_udp_lisp_gpe_header_t) == 36);
133  ASSERT(sizeof(ip6_udp_lisp_gpe_header_t) == 56);
134 
135  if (is_v4)
136  {
137  ip_udp_encap_one (lgm->vlib_main, b0, t0->rewrite, 36, 1);
138  ip_udp_encap_one (lgm->vlib_main, b1, t1->rewrite, 36, 1);
139  next0[0] = next1[0] = LISP_GPE_TX_NEXT_IP4_LOOKUP;
140  }
141  else
142  {
143  ip_udp_encap_one (lgm->vlib_main, b0, t0->rewrite, 56, 0);
144  ip_udp_encap_one (lgm->vlib_main, b1, t1->rewrite, 56, 0);
145  next0[0] = next1[0] = LISP_GPE_TX_NEXT_IP6_LOOKUP;
146  }
147 }
148 
149 #define is_v4_packet(_h) ((*(u8*) _h) & 0xF0) == 0x40
150 
151 static uword
153  vlib_frame_t * from_frame)
154 {
155  u32 n_left_from, next_index, * from, * to_next;
157  u32 pkts_encapsulated = 0;
158 
159  from = vlib_frame_vector_args (from_frame);
160  n_left_from = from_frame->n_vectors;
161 
162  next_index = node->cached_next_index;
163 
164  while (n_left_from > 0)
165  {
166  u32 n_left_to_next;
167 
168  vlib_get_next_frame (vm, node, next_index,
169  to_next, n_left_to_next);
170 
171  while (n_left_from >= 4 && n_left_to_next >= 2)
172  {
173  u32 bi0, bi1;
174  vlib_buffer_t * b0, * b1;
175  u32 next0, next1;
176  lisp_gpe_tunnel_t * t0 = 0, * t1 = 0;
177  u8 is_v4_eid0, is_v4_eid1;
178 
179  next0 = next1 = LISP_GPE_TX_NEXT_IP4_LOOKUP;
180 
181  /* Prefetch next iteration. */
182  {
183  vlib_buffer_t * p2, *p3;
184 
185  p2 = vlib_get_buffer (vm, from[2]);
186  p3 = vlib_get_buffer (vm, from[3]);
187 
188  vlib_prefetch_buffer_header(p2, LOAD);
189  vlib_prefetch_buffer_header(p3, LOAD);
190 
193  }
194 
195  bi0 = from[0];
196  bi1 = from[1];
197  to_next[0] = bi0;
198  to_next[1] = bi1;
199  from += 2;
200  to_next += 2;
201  n_left_to_next -= 2;
202  n_left_from -= 2;
203 
204  b0 = vlib_get_buffer (vm, bi0);
205  b1 = vlib_get_buffer (vm, bi1);
206 
207  is_v4_eid0 = is_v4_packet(vlib_buffer_get_current (b0));
208  is_v4_eid1 = is_v4_packet(vlib_buffer_get_current (b1));
209 
210  if (PREDICT_TRUE(is_v4_eid0 == is_v4_eid1))
211  {
212  get_two_tunnels_inline (lgm, b0, b1, &t0, &t1,
213  is_v4_eid0 ? 1 : 0);
214  }
215  else
216  {
217  get_one_tunnel_inline (lgm, b0, &t0, is_v4_eid0 ? 1 : 0);
218  get_one_tunnel_inline (lgm, b1, &t1, is_v4_eid1 ? 1 : 0);
219  }
220 
221  if (PREDICT_TRUE(
222  ip_addr_version(&t0->dst) == ip_addr_version(&t1->dst)))
223  {
224  encap_two_inline (lgm, b0, b1, t0, t1, &next0, &next1,
225  ip_addr_version(&t0->dst) == IP4 ? 1 : 0);
226  }
227  else
228  {
229  encap_one_inline (lgm, b0, t0, &next0,
230  ip_addr_version(&t0->dst) == IP4 ? 1 : 0);
231  encap_one_inline (lgm, b1, t1, &next1,
232  ip_addr_version(&t1->dst) == IP4 ? 1 : 0);
233  }
234 
235  /* Reset to look up tunnel partner in the configured FIB */
236  vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->encap_fib_index;
237  vnet_buffer(b1)->sw_if_index[VLIB_TX] = t1->encap_fib_index;
238 
240  {
241  lisp_gpe_tx_trace_t *tr = vlib_add_trace (vm, node, b0,
242  sizeof(*tr));
243  tr->tunnel_index = t0 - lgm->tunnels;
244  }
246  {
247  lisp_gpe_tx_trace_t *tr = vlib_add_trace (vm, node, b1,
248  sizeof(*tr));
249  tr->tunnel_index = t1 - lgm->tunnels;
250  }
251 
252  pkts_encapsulated += 2;
253 
254  vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
255  n_left_to_next, bi0, bi1, next0,
256  next1);
257  }
258 
259  while (n_left_from > 0 && n_left_to_next > 0)
260  {
261  vlib_buffer_t * b0;
262  u32 bi0, next0 = LISP_GPE_TX_NEXT_IP4_LOOKUP;
263  lisp_gpe_tunnel_t * t0 = 0;
264  u8 is_v4_0;
265 
266  bi0 = from[0];
267  to_next[0] = bi0;
268  from += 1;
269  to_next += 1;
270  n_left_from -= 1;
271  n_left_to_next -= 1;
272 
273  b0 = vlib_get_buffer (vm, bi0);
274 
275  is_v4_0 = is_v4_packet(vlib_buffer_get_current (b0));
276  get_one_tunnel_inline (lgm, b0, &t0, is_v4_0 ? 1 : 0);
277 
278  encap_one_inline (lgm, b0, t0, &next0,
279  ip_addr_version(&t0->dst) == IP4 ? 1 : 0);
280 
281  /* Reset to look up tunnel partner in the configured FIB */
282  vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->encap_fib_index;
283 
284  pkts_encapsulated++;
285 
287  {
288  lisp_gpe_tx_trace_t *tr = vlib_add_trace (vm, node, b0,
289  sizeof(*tr));
290  tr->tunnel_index = t0 - lgm->tunnels;
291  }
292  vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
293  n_left_to_next, bi0, next0);
294  }
295 
296  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
297  }
299  LISP_GPE_ERROR_ENCAPSULATED, pkts_encapsulated);
300  return from_frame->n_vectors;
301 }
302 
303 static u8 *
304 format_lisp_gpe_name (u8 * s, va_list * args)
305 {
306  u32 dev_instance = va_arg (*args, u32);
307  return format (s, "lisp_gpe%d", dev_instance);
308 }
309 
310 VNET_DEVICE_CLASS (lisp_gpe_device_class,static) = {
311  .name = "LISP_GPE",
312  .format_device_name = format_lisp_gpe_name,
313  .format_tx_trace = format_lisp_gpe_tx_trace,
314  .tx_function = lisp_gpe_interface_tx,
315  .no_flatten_output_chains = 1,
316 };
317 
318 static uword
319 dummy_set_rewrite (vnet_main_t * vnm, u32 sw_if_index, u32 l3_type,
320  void * dst_address, void * rewrite, uword max_rewrite_bytes)
321 {
322  return 0;
323 }
324 
325 u8 *
327 {
328  lisp_gpe_header_t * h = va_arg (*args, lisp_gpe_header_t *);
329  u32 max_header_bytes = va_arg (*args, u32);
330  u32 header_bytes;
331 
332  header_bytes = sizeof (h[0]);
333  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
334  return format (s, "lisp-gpe header truncated");
335 
336  s = format (s, "flags: ");
337 #define _(n,v) if (h->flags & v) s = format (s, "%s ", #n);
339 #undef _
340 
341  s = format (s, "\n ver_res %d res %d next_protocol %d iid %d(%x)",
342  h->ver_res, h->res, h->next_protocol,
343  clib_net_to_host_u32 (h->iid),
344  clib_net_to_host_u32 (h->iid));
345  return s;
346 }
347 
348 VNET_HW_INTERFACE_CLASS (lisp_gpe_hw_class) = {
349  .name = "LISP_GPE",
350  .format_header = format_lisp_gpe_header_with_length,
351  .set_rewrite = dummy_set_rewrite,
352 };
353 
354 int
355 add_del_ip_prefix_route (ip_prefix_t * dst_prefix, u32 table_id,
356  ip_adjacency_t * add_adj, u8 is_add, u32 * adj_index)
357 {
358  uword * p;
359 
360  if (ip_prefix_version(dst_prefix) == IP4)
361  {
362  ip4_main_t * im4 = &ip4_main;
364  ip4_address_t addr = ip_prefix_v4(dst_prefix);
365 
366  memset(&a, 0, sizeof(a));
368  a.table_index_or_table_id = table_id;
369  a.adj_index = ~0;
370  a.dst_address_length = ip_prefix_len(dst_prefix);
371  a.dst_address = addr;
373  a.add_adj = add_adj;
374  a.n_add_adj = is_add ? 1 : 0;
375 
376  ip4_add_del_route (im4, &a);
377 
378  if (is_add)
379  {
380  p = ip4_get_route (im4, table_id, 0, addr.as_u8,
381  ip_prefix_len(dst_prefix));
382  if (p == 0)
383  {
384  clib_warning("Failed to insert route for eid %U!",
386  ip_prefix_len(dst_prefix));
387  return -1;
388  }
389  adj_index[0] = p[0];
390  }
391  }
392  else
393  {
394  ip6_main_t * im6 = &ip6_main;
396  ip6_address_t addr = ip_prefix_v6(dst_prefix);
397 
398  memset(&a, 0, sizeof(a));
400  a.table_index_or_table_id = table_id;
401  a.adj_index = ~0;
402  a.dst_address_length = ip_prefix_len(dst_prefix);
403  a.dst_address = addr;
405  a.add_adj = add_adj;
406  a.n_add_adj = is_add ? 1 : 0;
407 
408  ip6_add_del_route (im6, &a);
409 
410  if (is_add)
411  {
412  adj_index[0] = ip6_get_route (im6, table_id, 0, &addr,
413  ip_prefix_len(dst_prefix));
414  if (adj_index[0] == 0)
415  {
416  clib_warning("Failed to insert route for eid %U!",
418  ip_prefix_len(dst_prefix));
419  return -1;
420  }
421  }
422  }
423  return 0;
424 }
425 
426 static void
427 add_del_lisp_gpe_default_route (u32 table_id, u8 is_v4, u8 is_add)
428 {
430  ip_adjacency_t adj;
431  ip_prefix_t prefix;
432  u32 adj_index = 0;
433 
434  /* setup adjacency */
435  memset (&adj, 0, sizeof(adj));
436 
437  adj.n_adj = 1;
438  adj.explicit_fib_index = ~0;
441  /* default route has tunnel_index ~0 */
442  adj.rewrite_header.sw_if_index = ~0;
443 
444  /* set prefix to 0/0 */
445  memset(&prefix, 0, sizeof(prefix));
446  ip_prefix_version(&prefix) = is_v4 ? IP4 : IP6;
447 
448  /* add/delete route for prefix */
449  add_del_ip_prefix_route (&prefix, table_id, &adj, is_add, &adj_index);
450 }
451 
452 static void
453 lisp_gpe_iface_set_table (u32 sw_if_index, u32 table_id, u8 is_ip4)
454 {
455  if (is_ip4)
456  {
457  ip4_main_t * im4 = &ip4_main;
458  ip4_fib_t * fib;
459  fib = find_ip4_fib_by_table_index_or_id (im4, table_id,
461 
462  /* fib's created if it doesn't exist */
463  ASSERT(fib != 0);
464 
465  vec_validate(im4->fib_index_by_sw_if_index, sw_if_index);
466  im4->fib_index_by_sw_if_index[sw_if_index] = fib->index;
467  }
468  else
469  {
470  ip6_main_t * im6 = &ip6_main;
471  ip6_fib_t * fib;
472  fib = find_ip6_fib_by_table_index_or_id (im6, table_id,
474 
475  /* fib's created if it doesn't exist */
476  ASSERT(fib != 0);
477 
478  vec_validate(im6->fib_index_by_sw_if_index, sw_if_index);
479  im6->fib_index_by_sw_if_index[sw_if_index] = fib->index;
480  }
481 }
482 
483 void
485  u32 * hw_if_indexp)
486 {
488  vnet_main_t * vnm = lgm->vnet_main;
490  u32 hw_if_index = ~0, lookup_next_index4, lookup_next_index6, flen;
491  uword * hip, * vni;
492 
494 
495  if (a->is_add)
496  {
497  if (hip)
498  {
499  clib_warning ("Interface for vrf %d already exists", a->table_id);
500  return;
501  }
502 
503  /* create hw lisp_gpeX iface if needed, otherwise reuse existing */
505  if (flen > 0)
506  {
507  hw_if_index = lgm->free_lisp_gpe_tunnel_hw_if_indices[flen - 1];
508  _vec_len(lgm->free_lisp_gpe_tunnel_hw_if_indices) -= 1;
509  }
510  else
511  {
512  hw_if_index = vnet_register_interface (vnm,
513  lisp_gpe_device_class.index,
514  a->table_id,
515  lisp_gpe_hw_class.index, 0);
516  }
517 
518  hi = vnet_get_hw_interface (vnm, hw_if_index);
519  hash_set(lgm->lisp_gpe_hw_if_index_by_table_id, a->table_id, hw_if_index);
520 
521  /* set tunnel termination: post decap, packets are tagged as having been
522  * originated by lisp-gpe interface */
525 
526  /* set ingress arc from lgpe_ipX_lookup */
527  lookup_next_index4 = vlib_node_add_next (lgm->vlib_main,
528  lgpe_ip4_lookup_node.index,
529  hi->output_node_index);
530  lookup_next_index6 = vlib_node_add_next (lgm->vlib_main,
531  lgpe_ip6_lookup_node.index,
532  hi->output_node_index);
534  lookup_next_index4);
536  lookup_next_index6);
537 
538  /* insert default routes that point to lgpe-ipx-lookup */
539  add_del_lisp_gpe_default_route (a->table_id, /* is_v4 */1, 1);
540  add_del_lisp_gpe_default_route (a->table_id, /* is_v4 */0, 1);
541 
542  /* set egress arcs */
543 #define _(sym,str) vlib_node_add_named_next_with_slot (vnm->vlib_main, \
544  hi->tx_node_index, str, LISP_GPE_TX_NEXT_##sym);
546 #undef _
547 
548  /* set interface in appropriate v4 and v6 FIBs */
551 
552  /* enable interface */
557  }
558  else
559  {
560  if (hip == 0)
561  {
562  clib_warning("The interface for vrf %d doesn't exist", a->table_id);
563  return;
564  }
565  hi = vnet_get_hw_interface (vnm, hip[0]);
566 
567  /* disable interface */
568  vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0/* down */);
569  vnet_hw_interface_set_flags (vnm, hi->hw_if_index, 0/* down */);
572 
573  /* clean tunnel termination and vni to sw_if_index binding */
577 
578  /* unset default routes */
579  add_del_lisp_gpe_default_route (a->table_id, /* is_v4 */1, 0);
580  add_del_lisp_gpe_default_route (a->table_id, /* is_v4 */0, 0);
581  }
582 }
583 
584 static clib_error_t *
586  vlib_cli_command_t * cmd)
587 {
588  unformat_input_t _line_input, * line_input = &_line_input;
589  u8 is_add = 1;
590  u32 table_id;
591 
593 
594  /* Get a line of input. */
595  if (! unformat_user (input, unformat_line_input, line_input))
596  return 0;
597 
598  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
599  {
600  if (unformat (line_input, "add"))
601  is_add = 1;
602  else if (unformat (line_input, "del"))
603  is_add = 0;
604  else if (unformat (line_input, "vrf %d", &table_id))
605  ;
606  else
607  {
608  return clib_error_return (0, "parse error: '%U'",
609  format_unformat_error, line_input);
610  }
611  }
612 
613  a->is_add = is_add;
614  a->table_id = table_id;
616  return 0;
617 }
618 
619 VLIB_CLI_COMMAND (add_del_lisp_gpe_iface_command, static) = {
620  .path = "lisp gpe iface",
621  .short_help = "lisp gpe iface add/del table-index <table_index> vrf <vrf>",
623 };
#define ip_prefix_v4(_a)
Definition: lisp_types.h:56
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Definition: main.c:459
#define is_v4_packet(_h)
Definition: interface.c:149
ip4_fib_t * find_ip4_fib_by_table_index_or_id(ip4_main_t *im, u32 table_index_or_id, u32 flags)
Get or create an IPv4 fib.
Definition: ip4_forward.c:98
vmrglw vmrglh hi
static void add_del_lisp_gpe_default_route(u32 table_id, u8 is_v4, u8 is_add)
Definition: interface.c:427
#define hash_set(h, key, value)
Definition: hash.h:237
#define CLIB_UNUSED(x)
Definition: clib.h:79
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
u32 ip4_lookup_next_lgpe_ip4_lookup
Definition: lisp_gpe.h:151
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:454
#define hash_unset(h, key)
Definition: hash.h:243
a
Definition: bitmap.h:393
#define foreach_lisp_gpe_tx_next
Definition: interface.c:24
uword * tunnel_term_sw_if_index_by_vni
Definition: lisp_gpe.h:137
ip_lookup_next_t lookup_next_index
Definition: lookup.h:163
#define PREDICT_TRUE(x)
Definition: clib.h:98
u8 as_u8[16]
Definition: ip6_packet.h:47
#define UNFORMAT_END_OF_INPUT
Definition: format.h:142
lisp_gpe_tunnel_t * tunnels
Definition: lisp_gpe.h:131
#define ip_prefix_len(_a)
Definition: lisp_types.h:55
static clib_error_t * lisp_gpe_add_del_iface_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: interface.c:585
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:480
static u8 * format_lisp_gpe_name(u8 *s, va_list *args)
Definition: interface.c:304
u32 * fib_index_by_sw_if_index
Definition: ip4.h:137
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:241
uword * lgpe_ip6_lookup_next_index_by_table_id
Definition: lisp_gpe.h:148
always_inline void get_one_tunnel_inline(lisp_gpe_main_t *lgm, vlib_buffer_t *b0, lisp_gpe_tunnel_t **t0, u8 is_v4)
Definition: interface.c:54
#define ip_prefix_version(_a)
Definition: lisp_types.h:54
always_inline void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:184
u8 * format_lisp_gpe_tx_trace(u8 *s, va_list *args)
Definition: interface.c:43
u32 index
Definition: ip4.h:61
vlib_main_t * vlib_main
Definition: lisp_gpe.h:155
always_inline uword unformat_check_input(unformat_input_t *i)
Definition: format.h:168
#define always_inline
Definition: clib.h:84
ip6_fib_t * find_ip6_fib_by_table_index_or_id(ip6_main_t *im, u32 table_index_or_id, u32 flags)
Get or create an IPv6 fib.
Definition: ip6_forward.c:185
#define clib_warning(format, args...)
Definition: error.h:59
u32 table_index_or_table_id
Definition: ip6.h:343
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:953
void vnet_lisp_gpe_add_del_iface(vnet_lisp_gpe_add_del_iface_args_t *a, u32 *hw_if_indexp)
Definition: interface.c:484
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:583
u8 * format_lisp_gpe_header_with_length(u8 *s, va_list *args)
Definition: interface.c:326
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
Definition: node_funcs.h:202
void ip6_add_del_route(ip6_main_t *im, ip6_add_del_route_args_t *args)
Definition: ip6_forward.c:208
#define ip_addr_version(_a)
Definition: lisp_types.h:51
u32 * free_lisp_gpe_tunnel_hw_if_indices
Definition: lisp_gpe.h:141
static void lisp_gpe_iface_set_table(u32 sw_if_index, u32 table_id, u8 is_ip4)
Definition: interface.c:453
ip6_address_t dst_address
Definition: ip6.h:346
#define hash_get(h, key)
Definition: hash.h:231
#define pool_elt_at_index(p, i)
Definition: pool.h:346
uword * lisp_gpe_hw_if_index_by_table_id
Definition: lisp_gpe.h:144
void * ip4_get_route(ip4_main_t *im, u32 fib_index_or_table_id, u32 flags, u8 *address, u32 address_length)
Definition: ip4_forward.c:469
#define ip_prefix_v6(_a)
Definition: lisp_types.h:57
ip_adjacency_t * add_adj
Definition: ip6.h:355
u32 ip6_lookup_next_lgpe_ip6_lookup
Definition: lisp_gpe.h:152
#define PREDICT_FALSE(x)
Definition: clib.h:97
static uword dummy_set_rewrite(vnet_main_t *vnm, u32 sw_if_index, u32 l3_type, void *dst_address, void *rewrite, uword max_rewrite_bytes)
Definition: interface.c:319
u32 index
Definition: ip6.h:67
u32 ip6_get_route(ip6_main_t *im, u32 fib_index_or_table_id, u32 flags, ip6_address_t *address, u32 address_length)
Definition: ip6_forward.c:523
always_inline void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:970
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Definition: buffer_node.h:43
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Definition: buffer_node.h:83
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Definition: node_funcs.h:265
uword * vni_by_tunnel_term_sw_if_index
Definition: lisp_gpe.h:138
ip_adjacency_t * add_adj
Definition: ip4.h:293
VNET_HW_INTERFACE_CLASS(ethernet_hw_interface_class)
u16 n_vectors
Definition: node.h:307
vlib_node_registration_t lgpe_ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (lgpe_ip4_lookup_node)
Definition: ip_forward.c:912
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:82
Definition: ip6.h:62
vnet_main_t * vnet_main
Definition: lisp_gpe.h:156
Definition: ip4.h:47
always_inline void get_two_tunnels_inline(lisp_gpe_main_t *lgm, vlib_buffer_t *b0, vlib_buffer_t *b1, lisp_gpe_tunnel_t **t0, lisp_gpe_tunnel_t **t1, u8 is_v4)
Definition: interface.c:95
#define IP6_ROUTE_FLAG_DEL
Definition: ip6.h:328
always_inline vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
lisp_gpe_main_t lisp_gpe_main
Definition: lisp_gpe.c:18
#define IP4_ROUTE_FLAG_DEL
Definition: ip4.h:265
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:150
u16 cached_next_index
Definition: node.h:422
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:373
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:87
ip4_address_t dst_address
Definition: ip4.h:284
#define vnet_buffer(b)
Definition: buffer.h:300
#define IP4_ROUTE_FLAG_ADD
Definition: ip4.h:264
ip6_main_t ip6_main
Definition: ip6_forward.c:2490
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
vlib_node_registration_t lgpe_ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (lgpe_ip6_lookup_node)
Definition: ip_forward.c:1129
int add_del_ip_prefix_route(ip_prefix_t *dst_prefix, u32 table_id, ip_adjacency_t *add_adj, u8 is_add, u32 *adj_index)
Definition: interface.c:355
always_inline uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:919
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:91
always_inline ip_adjacency_t * ip_get_adjacency(ip_lookup_main_t *lm, u32 adj_index)
Definition: lookup.h:423
u64 uword
Definition: types.h:112
Definition: defs.h:46
format_function_t format_ip6_address_and_length
Definition: format.h:88
ip_lookup_main_t * lm4
Definition: lisp_gpe.h:159
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
u32 table_index_or_table_id
Definition: ip4.h:281
Definition: lisp_types.h:24
always_inline void encap_one_inline(lisp_gpe_main_t *lgm, vlib_buffer_t *b0, lisp_gpe_tunnel_t *t0, u32 *next0, u8 is_v4)
Definition: interface.c:75
always_inline void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:162
static uword lisp_gpe_interface_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: interface.c:152
ip4_main_t ip4_main
Definition: ip4_forward.c:1394
#define IP4_ROUTE_FLAG_TABLE_ID
Definition: ip4.h:266
u8 data[0]
Packet data.
Definition: buffer.h:150
#define IP6_ROUTE_FLAG_ADD
Definition: ip6.h:327
i16 explicit_fib_index
Definition: lookup.h:168
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:462
vhost_vring_addr_t addr
Definition: vhost-user.h:78
#define clib_error_return(e, args...)
Definition: error.h:112
VNET_DEVICE_CLASS(ethernet_simulated_device_class)
#define IP6_ROUTE_FLAG_TABLE_ID
Definition: ip6.h:329
struct _unformat_input_t unformat_input_t
void ip4_add_del_route(ip4_main_t *im, ip4_add_del_route_args_t *args)
Definition: ip4_forward.c:196
ip_lookup_main_t * lm6
Definition: lisp_gpe.h:160
always_inline void ip_udp_encap_one(vlib_main_t *vm, vlib_buffer_t *b0, u8 *ec0, word ec_len, u8 is_ip4)
Definition: udp.h:117
Definition: lisp_types.h:25
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
format_function_t format_ip4_address_and_length
Definition: format.h:72
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:84
lisp_gpe_tx_next_t
Definition: interface.c:29
unformat_function_t unformat_line_input
Definition: format.h:279
u32 * fib_index_by_sw_if_index
Definition: ip6.h:148
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:69
uword * lgpe_ip4_lookup_next_index_by_table_id
Definition: lisp_gpe.h:147
ip_address_t dst
Definition: lisp_gpe.h:66
always_inline void encap_two_inline(lisp_gpe_main_t *lgm, vlib_buffer_t *b0, vlib_buffer_t *b1, lisp_gpe_tunnel_t *t0, lisp_gpe_tunnel_t *t1, u32 *next0, u32 *next1, u8 is_v4)
Definition: interface.c:128