FD.io VPP  v16.12-rc0-308-g931be3a
Vector Packet Processing
mpls.c
Go to the documentation of this file.
1 /*
2  * mpls.c: mpls
3  *
4  * Copyright (c) 2012 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/vnet.h>
19 #include <vnet/mpls/mpls.h>
20 #include <vnet/fib/ip4_fib.h>
21 #include <vnet/fib/mpls_fib.h>
22 
23 const static char* mpls_eos_bit_names[] = MPLS_EOS_BITS;
24 
26 
27 u8 * format_mpls_unicast_label (u8 * s, va_list * args)
28 {
29  mpls_label_t label = va_arg (*args, mpls_label_t);
30 
31  switch (label) {
34  break;
37  break;
40  break;
43  break;
45  s = format (s, "%s", MPLS_IETF_ELI_STRING);
46  break;
48  s = format (s, "%s", MPLS_IETF_GAL_STRING);
49  break;
50  default:
51  s = format (s, "%d", label);
52  break;
53  }
54  return s;
55 }
56 
58 {
59  mpls_label_t *label = va_arg (*args, mpls_label_t*);
60 
65  else if (unformat (input, MPLS_IETF_ROUTER_ALERT_STRING))
67  else if (unformat (input, MPLS_IETF_IMPLICIT_NULL_STRING))
69  else if (unformat (input, "%d", label))
70  ;
71 
72  return (1);
73 }
74 
75 u8 * format_mpls_eos_bit (u8 * s, va_list * args)
76 {
77  mpls_eos_bit_t eb = va_arg (*args, mpls_eos_bit_t);
78 
79  ASSERT(eb <= MPLS_EOS);
80 
81  s = format(s, "%s", mpls_eos_bit_names[eb]);
82 
83  return (s);
84 }
85 
86 u8 * format_mpls_header (u8 * s, va_list * args)
87 {
88  mpls_unicast_header_t hdr = va_arg (*args, mpls_unicast_header_t);
89 
90  return (format(s, "[%U:%d:%d:%U]",
97 }
98 
99 uword
100 unformat_mpls_header (unformat_input_t * input, va_list * args)
101 {
102  u8 ** result = va_arg (*args, u8 **);
103  mpls_unicast_header_t _h, * h = &_h;
104  u32 label, label_exp_s_ttl;
105 
106  if (! unformat (input, "MPLS %d", &label))
107  return 0;
108 
109  label_exp_s_ttl = (label<<12) | (1<<8) /* s-bit */ | 0xFF;
110  h->label_exp_s_ttl = clib_host_to_net_u32 (label_exp_s_ttl);
111 
112  /* Add gre, mpls headers to result. */
113  {
114  void * p;
115  u32 h_n_bytes = sizeof (h[0]);
116 
117  vec_add2 (*result, p, h_n_bytes);
118  clib_memcpy (p, h, h_n_bytes);
119  }
120 
121  return 1;
122 }
123 
124 u8 * format_mpls_eth_tx_trace (u8 * s, va_list * args)
125 {
126  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
127  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
128  mpls_eth_tx_trace_t * t = va_arg (*args, mpls_eth_tx_trace_t *);
129  mpls_main_t * mm = &mpls_main;
130 
131  if (t->lookup_miss)
132  s = format (s, "MPLS: lookup miss");
133  else
134  {
135  s = format (s, "MPLS: tunnel %d labels %U len %d tx_sw_index %d dst %U",
136  t->tunnel_id,
138  clib_net_to_host_u16 (t->length),
139  t->tx_sw_if_index,
141  }
142  return s;
143 }
144 
145 u8 * format_mpls_eth_header_with_length (u8 * s, va_list * args)
146 {
147  ethernet_header_t * h = va_arg (*args, ethernet_header_t *);
149  u32 max_header_bytes = va_arg (*args, u32);
150  uword header_bytes;
151 
152  header_bytes = sizeof (h[0]);
153  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
154  return format (s, "ethernet header truncated");
155 
156  s = format
157  (s, "ETHERNET-MPLS label %d",
158  vnet_mpls_uc_get_label (clib_net_to_host_u32 (m->label_exp_s_ttl)));
159 
160  return s;
161 }
162 
163 uword
165  va_list * args)
166 {
167  u32 * result = va_arg (*args, u32 *);
168  u32 label;
169 
170  if (!unformat (input, "MPLS: label %d", &label))
171  return 0;
172 
173  label = (label<<12) | (1<<8) /* s-bit set */ | 0xFF /* ttl */;
174 
175  *result = clib_host_to_net_u32 (label);
176  return 1;
177 }
178 
179 mpls_encap_t *
180 mpls_encap_by_fib_and_dest (mpls_main_t * mm, u32 rx_fib, u32 dst_address)
181 {
182  uword * p;
183  mpls_encap_t * e;
184  u64 key;
185 
186  key = ((u64)rx_fib<<32) | ((u64) dst_address);
187  p = hash_get (mm->mpls_encap_by_fib_and_dest, key);
188 
189  if (!p)
190  return 0;
191 
192  e = pool_elt_at_index (mm->encaps, p[0]);
193  return e;
194 }
195 
197  u32 *labels_host_byte_order,
198  u32 policy_tunnel_index,
199  int no_dst_hash, u32 * indexp, int is_add)
200 {
201  mpls_main_t * mm = &mpls_main;
202  ip4_main_t * im = &ip4_main;
203  mpls_encap_t * e;
204  u32 label_net_byte_order, label_host_byte_order;
205  u32 fib_index;
206  u64 key;
207  uword *p;
208  int i;
209 
210  p = hash_get (im->fib_index_by_table_id, fib_id);
211  if (! p)
212  return VNET_API_ERROR_NO_SUCH_FIB;
213 
214  fib_index = p[0];
215 
216  key = ((u64)fib_index<<32) | ((u64) dest->as_u32);
217 
218  if (is_add)
219  {
220  pool_get (mm->encaps, e);
221  memset (e, 0, sizeof (*e));
222 
223  for (i = 0; i < vec_len (labels_host_byte_order); i++)
224  {
226  label_host_byte_order = labels_host_byte_order[i];
227 
228  /* Reformat label into mpls_unicast_header_t */
229  label_host_byte_order <<= 12;
230  // FIXME NEOS AND EOS
231  //if (i == vec_len(labels_host_byte_order) - 1)
232  // label_host_byte_order |= 1<<8; /* S=1 */
233  label_host_byte_order |= 0xff; /* TTL=FF */
234  label_net_byte_order = clib_host_to_net_u32 (label_host_byte_order);
235  h.label_exp_s_ttl = label_net_byte_order;
236  vec_add1 (e->labels, h);
237  }
238  if (no_dst_hash == 0)
239  hash_set (mm->mpls_encap_by_fib_and_dest, key, e - mm->encaps);
240  if (indexp)
241  *indexp = e - mm->encaps;
242  if (policy_tunnel_index != ~0)
243  return vnet_mpls_policy_tunnel_add_rewrite (mm, e, policy_tunnel_index);
244  }
245  else
246  {
247  p = hash_get (mm->mpls_encap_by_fib_and_dest, key);
248  if (!p)
249  return VNET_API_ERROR_NO_SUCH_LABEL;
250 
251  e = pool_elt_at_index (mm->encaps, p[0]);
252 
253  vec_free (e->labels);
254  vec_free (e->rewrite);
255  pool_put(mm->encaps, e);
256 
257  if (no_dst_hash == 0)
259  }
260  return 0;
261 }
262 
263 static clib_error_t *
265  unformat_input_t * input,
266  vlib_cli_command_t * cmd)
267 {
268  u32 fib_id;
269  u32 *labels = 0;
270  u32 this_label;
271  ip4_address_t dest;
272  u32 policy_tunnel_index = ~0;
273  int no_dst_hash = 0;
274  int rv;
275  int fib_set = 0;
276  int dest_set = 0;
277 
279  {
280  if (unformat (input, "fib %d", &fib_id))
281  fib_set = 1;
282  else if (unformat (input, "dest %U", unformat_ip4_address, &dest))
283  dest_set = 1;
284  else if (unformat (input, "no-dst-hash"))
285  no_dst_hash = 1;
286  else if (unformat (input, "label %d", &this_label))
287  vec_add1 (labels, this_label);
288  else if (unformat (input, "policy-tunnel %d", &policy_tunnel_index))
289  ;
290  else
291  break;
292  }
293 
294  if (fib_set == 0)
295  return clib_error_return (0, "fib-id missing");
296  if (dest_set == 0)
297  return clib_error_return (0, "destination IP address missing");
298  if (vec_len (labels) == 0)
299  return clib_error_return (0, "label stack missing");
300 
301  rv = vnet_mpls_add_del_encap (&dest, fib_id, labels,
302  policy_tunnel_index,
303  no_dst_hash, 0 /* indexp */,
304  1 /* is_add */);
305  vec_free (labels);
306 
307  switch (rv)
308  {
309  case 0:
310  break;
311 
312  case VNET_API_ERROR_NO_SUCH_FIB:
313  return clib_error_return (0, "fib id %d unknown", fib_id);
314 
315  default:
316  return clib_error_return (0, "vnet_mpls_add_del_encap returned %d",
317  rv);
318  }
319 
320  return 0;
321 }
322 
323 VLIB_CLI_COMMAND (mpls_add_encap_command, static) = {
324  .path = "mpls encap add",
325  .short_help =
326  "mpls encap add label <label> ... fib <id> dest <ip4-address>",
327  .function = mpls_add_encap_command_fn,
328 };
329 
331 {
332  mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *);
333  u32 label = h->label_exp_s_ttl;
334 
335  s = format (s, "label %d exp %d, s %d, ttl %d",
336  vnet_mpls_uc_get_label (label),
337  vnet_mpls_uc_get_exp (label),
338  vnet_mpls_uc_get_s (label),
339  vnet_mpls_uc_get_ttl (label));
340  return s;
341 }
342 
344 {
345  mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *);
346  mpls_unicast_header_t h_host;
347 
348  h_host.label_exp_s_ttl = clib_net_to_host_u32 (h->label_exp_s_ttl);
349 
351  &h_host);
352 }
353 
354 static clib_error_t *
356  unformat_input_t * input,
357  vlib_cli_command_t * cmd)
358 {
359  u32 fib_id;
360  ip4_address_t dest;
361  int rv;
362 
363  if (unformat (input, "fib %d dest %U", &fib_id,
364  unformat_ip4_address, &dest))
365  {
366  rv = vnet_mpls_add_del_encap (&dest, fib_id, 0 /* labels */,
367  ~0 /* policy_tunnel_index */,
368  0 /* no_dst_hash */,
369  0 /* indexp */,
370  0 /* is_add */);
371  switch (rv)
372  {
373  case VNET_API_ERROR_NO_SUCH_FIB:
374  return clib_error_return (0, "fib id %d unknown", fib_id);
375  case VNET_API_ERROR_NO_SUCH_ENTRY:
376  return clib_error_return (0, "dest %U not in fib %d",
377  format_ip4_address, &dest, fib_id);
378  default:
379  break;
380  }
381  return 0;
382  }
383  else
384  return clib_error_return (0, "unknown input `%U'",
385  format_unformat_error, input);
386 }
387 
388 VLIB_CLI_COMMAND (mpls_del_encap_command, static) = {
389  .path = "mpls encap delete",
390  .short_help = "mpls encap delete fib <id> dest <ip4-address>",
391  .function = mpls_del_encap_command_fn,
392 };
393 
394 int
395 mpls_dest_cmp(void * a1, void * a2)
396 {
397  show_mpls_fib_t * r1 = a1;
398  show_mpls_fib_t * r2 = a2;
399 
400  return clib_net_to_host_u32(r1->dest) - clib_net_to_host_u32(r2->dest);
401 }
402 
403 int
404 mpls_fib_index_cmp(void * a1, void * a2)
405 {
406  show_mpls_fib_t * r1 = a1;
407  show_mpls_fib_t * r2 = a2;
408 
409  return r1->fib_index - r2->fib_index;
410 }
411 
412 int
413 mpls_label_cmp(void * a1, void * a2)
414 {
415  show_mpls_fib_t * r1 = a1;
416  show_mpls_fib_t * r2 = a2;
417 
418  return r1->label - r2->label;
419 }
420 
421 static clib_error_t *
423  unformat_input_t * input,
424  vlib_cli_command_t * cmd)
425 {
426  u64 key;
427  u32 value;
428  show_mpls_fib_t *records = 0;
429  show_mpls_fib_t *s;
430  mpls_main_t * mm = &mpls_main;
431  ip4_fib_t * rx_fib;
432 
433  hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest,
434  ({
435  vec_add2 (records, s, 1);
436  s->fib_index = (u32)(key>>32);
437  s->dest = (u32)(key & 0xFFFFFFFF);
438  s->entry_index = (u32) value;
439  }));
440 
441  if (!vec_len(records))
442  {
443  vlib_cli_output (vm, "MPLS encap table empty");
444  }
445  /* sort output by dst address within fib */
448  vlib_cli_output (vm, "MPLS encap table");
449  vlib_cli_output (vm, "%=6s%=16s%=16s", "Table", "Dest address", "Labels");
450  vec_foreach (s, records)
451  {
452  rx_fib = ip4_fib_get (s->fib_index);
453  vlib_cli_output (vm, "%=6d%=16U%=16U", rx_fib->table_id,
456  }
457 
458  vec_free(records);
459  return 0;
460 }
461 
462 VLIB_CLI_COMMAND (show_mpls_fib_command, static) = {
463  .path = "show mpls encap",
464  .short_help = "show mpls encap",
465  .function = show_mpls_fib_command_fn,
466 };
467 
468 static clib_error_t *
470  unformat_input_t * input,
471  vlib_cli_command_t * cmd)
472 {
473  unformat_input_t _line_input, * line_input = &_line_input;
474  fib_route_path_t *rpaths = NULL, rpath;
475  clib_error_t * error = 0;
476  u32 table_id, is_del, is_ip;
477  fib_prefix_t pfx;
478  mpls_label_t local_label;
479  mpls_eos_bit_t eos;
480 
481  is_ip = 0;
482  table_id = 0;
483  eos = MPLS_EOS;
484  is_del = 0;
485  local_label = MPLS_LABEL_INVALID;
486  memset(&pfx, 0, sizeof(pfx));
487 
488  /* Get a line of input. */
489  if (! unformat_user (input, unformat_line_input, line_input))
490  return 0;
491 
492  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
493  {
494  memset(&rpath, 0, sizeof(rpath));
495 
496  if (unformat (line_input, "table %d", &table_id))
497  ;
498  else if (unformat (line_input, "del"))
499  is_del = 1;
500  else if (unformat (line_input, "add"))
501  is_del = 0;
502  else if (unformat (line_input, "eos"))
503  pfx.fp_eos = MPLS_EOS;
504  else if (unformat (line_input, "non-eos"))
505  pfx.fp_eos = MPLS_NON_EOS;
506  else if (unformat (line_input, "%U/%d",
508  &pfx.fp_addr.ip4,
509  &pfx.fp_len))
510  {
512  is_ip = 1;
513  }
514  else if (unformat (line_input, "%U/%d",
516  &pfx.fp_addr.ip6,
517  &pfx.fp_len))
518  {
520  is_ip = 1;
521  }
522  else if (unformat (line_input, "%d", &local_label))
523  ;
524  else if (unformat (line_input,
525  "ip4-lookup-in-table %d",
526  &rpath.frp_fib_index))
527  {
528  rpath.frp_label = MPLS_LABEL_INVALID;
529  rpath.frp_proto = FIB_PROTOCOL_IP4;
530  rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
532  vec_add1(rpaths, rpath);
533  }
534  else if (unformat (line_input,
535  "ip6-lookup-in-table %d",
536  &rpath.frp_fib_index))
537  {
538  rpath.frp_label = MPLS_LABEL_INVALID;
539  rpath.frp_proto = FIB_PROTOCOL_IP6;
540  rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
541  vec_add1(rpaths, rpath);
543  }
544  else if (unformat (line_input,
545  "mpls-lookup-in-table %d",
546  &rpath.frp_fib_index))
547  {
548  rpath.frp_label = MPLS_LABEL_INVALID;
549  rpath.frp_proto = FIB_PROTOCOL_MPLS;
550  rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
552  vec_add1(rpaths, rpath);
553  }
554  else
555  {
556  error = clib_error_return (0, "unkown input: %U",
557  format_unformat_error, input);
558  goto done;
559  }
560 
561  }
562 
563  if (MPLS_LABEL_INVALID == local_label)
564  {
565  error = clib_error_return (0, "local-label required: %U",
566  format_unformat_error, input);
567  goto done;
568  }
569 
570 
571  if (is_ip)
572  {
573  u32 fib_index = fib_table_find(pfx.fp_proto, table_id);
574 
575  if (FIB_NODE_INDEX_INVALID == fib_index)
576  {
577  error = clib_error_return (0, "%U table-id %d does not exist",
578  format_fib_protocol, pfx.fp_proto, table_id);
579  goto done;
580  }
581 
582  if (is_del)
583  {
584  fib_table_entry_local_label_remove(fib_index, &pfx, local_label);
585  }
586  else
587  {
588  fib_table_entry_local_label_add(fib_index, &pfx, local_label);
589  }
590  }
591  else
592  {
593  fib_node_index_t lfe, fib_index;
594  u32 fi;
595 
597  pfx.fp_len = 21;
598  pfx.fp_label = local_label;
599 
600  if (NULL == rpaths)
601  {
602  error = clib_error_return(0 , "no paths");
603  goto done;
604  }
605 
606  /*
607  * the CLI parsing stored table Ids, swap to FIB indicies
608  */
610  rpaths[0].frp_fib_index);
611 
612  if (~0 == fi)
613  {
614  error = clib_error_return(0 , "%U Via table %d does not exist",
616  rpaths[0].frp_fib_index);
617  goto done;
618  }
619  rpaths[0].frp_fib_index = fi;
620 
621  fib_index = mpls_fib_index_from_table_id(table_id);
622 
623  if (FIB_NODE_INDEX_INVALID == fib_index)
624  {
625  error = clib_error_return (0, "MPLS table-id %d does not exist",
626  table_id);
627  goto done;
628  }
629 
630  lfe = fib_table_entry_path_add2(fib_index,
631  &pfx,
634  rpaths);
635 
636  if (FIB_NODE_INDEX_INVALID == lfe)
637  {
638  error = clib_error_return (0, "Failed to create %U-%U in MPLS table-id %d",
639  format_mpls_unicast_label, local_label,
640  format_mpls_eos_bit, eos,
641  table_id);
642  goto done;
643  }
644  }
645 
646 done:
647  return error;
648 }
649 
650 VLIB_CLI_COMMAND (mpls_local_label_command, static) = {
651  .path = "mpls local-label",
652  .function = vnet_mpls_local_label,
653  .short_help = "Create/Delete MPL local labels",
654 };
655 
657 {
658  u64 key;
659  u32 value;
660  show_mpls_fib_t *records = 0;
661  show_mpls_fib_t *s;
662  mpls_main_t * mm = &mpls_main;
663  ip4_main_t * im = &ip4_main;
664  u32 fib_index;
665  uword *p;
666 
667  p = hash_get (im->fib_index_by_table_id, fib_id);
668  if (! p)
669  return VNET_API_ERROR_NO_SUCH_FIB;
670 
671  fib_index = p[0];
672 
673  hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest,
674  ({
675  if (fib_index == (u32)(key>>32)) {
676  vec_add2 (records, s, 1);
677  s->dest = (u32)(key & 0xFFFFFFFF);
678  s->entry_index = (u32) value;
679  }
680  }));
681 
682  vec_foreach (s, records)
683  {
684  key = ((u64)fib_index<<32) | ((u64) s->dest);
685  hash_unset (mm->mpls_encap_by_fib_and_dest, key);
686  pool_put_index (mm->encaps, s->entry_index);
687  }
688 
689  vec_free(records);
690  return 0;
691 }
692 
694 {
695  mpls_main_t * mm = &mpls_main;
696  clib_error_t * error;
697 
698  mm->vlib_main = vm;
699  mm->vnet_main = vnet_get_main();
700 
701  if ((error = vlib_call_init_function (vm, ip_main_init)))
702  return error;
703 
704  mm->mpls_encap_by_fib_and_dest = hash_create (0, sizeof (uword));
705 
707 }
708 
710 
712 {
714  return &mpls_main;
715 }
716 
u32 fib_table_id_find_fib_index(fib_protocol_t proto, u32 table_id)
Definition: lookup.c:316
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:158
uword unformat_mpls_unicast_label(unformat_input_t *input, va_list *args)
Definition: mpls.c:57
#define hash_set(h, key, value)
Definition: hash.h:254
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
#define CLIB_UNUSED(x)
Definition: clib.h:79
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
#define hash_unset(h, key)
Definition: hash.h:260
A representation of a path as described by a route producer.
Definition: fib_types.h:283
u32 table_id
Definition: ip4.h:56
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
#define NULL
Definition: clib.h:55
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:24
#define MPLS_IETF_IMPLICIT_NULL_LABEL
Definition: mpls_types.h:16
From the CLI.
Definition: fib_entry.h:61
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:482
#define MPLS_IETF_ROUTER_ALERT_LABEL
Definition: mpls_types.h:14
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:521
u8 * format_mpls_unicast_label(u8 *s, va_list *args)
Definition: mpls.c:27
u8 * format_mpls_unicast_header_host_byte_order(u8 *s, va_list *args)
Definition: mpls.c:330
int mpls_dest_cmp(void *a1, void *a2)
Definition: mpls.c:395
uword * mpls_encap_by_fib_and_dest
Definition: mpls.h:111
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
static clib_error_t * mpls_input_init(vlib_main_t *vm)
Definition: node.c:211
format_function_t format_ip4_address
Definition: format.h:78
void fib_table_entry_local_label_remove(u32 fib_index, const fib_prefix_t *prefix, mpls_label_t label)
remove a MPLS local label for the prefix/route.
Definition: fib_table.c:855
static clib_error_t * mpls_add_encap_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mpls.c:264
dpo_proto_t fp_payload_proto
This protocol determines the payload protocol of packets that will be forwarded by this entry once th...
Definition: fib_types.h:182
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
u8 * format_mpls_eth_tx_trace(u8 *s, va_list *args)
Definition: mpls.c:124
u8 * format_ethernet_address(u8 *s, va_list *args)
Definition: format.c:44
#define MPLS_IETF_ROUTER_ALERT_STRING
Definition: mpls_types.h:24
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
int mpls_fib_reset_labels(u32 fib_id)
Definition: mpls.c:656
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:418
Aggregrate type for a prefix.
Definition: fib_types.h:149
unsigned long u64
Definition: types.h:89
static clib_error_t * show_mpls_fib_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mpls.c:422
static const char * mpls_eos_bit_names[]
Definition: mpls.c:23
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:977
int vnet_mpls_policy_tunnel_add_rewrite(mpls_main_t *mm, mpls_encap_t *e, u32 policy_tunnel_index)
Definition: interface.c:754
static u32 vnet_mpls_uc_get_ttl(mpls_label_t label_exp_s_ttl)
Definition: packet.h:92
#define MPLS_EOS_BITS
Definition: packet.h:40
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:933
fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto)
Definition: fib_types.c:238
u16 fp_len
The mask length.
Definition: fib_types.h:153
#define vlib_call_init_function(vm, x)
Definition: init.h:161
Definition: fib_entry.h:215
unformat_function_t unformat_ip4_address
Definition: format.h:75
#define MPLS_IETF_GAL_STRING
Definition: mpls_types.h:30
#define hash_get(h, key)
Definition: hash.h:248
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
#define MPLS_IETF_ELI_LABEL
Definition: mpls_types.h:17
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
Definition: ip4.h:111
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:172
u32 entry_index
Definition: mpls.h:269
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:214
static u32 vnet_mpls_uc_get_label(mpls_label_t label_exp_s_ttl)
Definition: packet.h:77
vnet_main_t * vnet_main
Definition: mpls.h:128
uword unformat_mpls_header(unformat_input_t *input, va_list *args)
Definition: mpls.c:100
#define MPLS_IETF_IPV4_EXPLICIT_NULL_STRING
Definition: mpls_types.h:20
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
unformat_function_t unformat_ip6_address
Definition: format.h:93
clib_error_t * ip_main_init(vlib_main_t *vm)
Definition: ip_init.c:45
u8 * rewrite
Definition: mpls.h:53
fib_node_index_t fib_table_entry_local_label_add(u32 fib_index, const fib_prefix_t *prefix, mpls_label_t label)
Add a MPLS local label for the prefix/route.
Definition: fib_table.c:828
mpls_main_t mpls_main
Definition: mpls.c:25
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:33
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
Definition: ip4_fib.h:71
Definition: ip4.h:48
#define MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL
Definition: mpls_types.h:13
#define clib_memcpy(a, b, c)
Definition: string.h:64
int vnet_mpls_add_del_encap(ip4_address_t *dest, u32 fib_id, u32 *labels_host_byte_order, u32 policy_tunnel_index, int no_dst_hash, u32 *indexp, int is_add)
Definition: mpls.c:196
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
u32 mpls_fib_index_from_table_id(u32 table_id)
Definition: mpls_fib.c:77
mpls_label_t fp_label
Definition: fib_types.h:175
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
u32 mpls_encap_index
Definition: mpls.h:257
u32 fib_index
Definition: mpls.h:268
#define hash_create(elts, value_bytes)
Definition: hash.h:658
#define MPLS_IETF_IPV6_EXPLICIT_NULL_STRING
Definition: mpls_types.h:26
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:228
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
fib_node_index_t fib_table_entry_path_add2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *rpath)
Add n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:522
static clib_error_t * vnet_mpls_local_label(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mpls.c:469
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define MPLS_IETF_GAL_LABEL
Definition: mpls_types.h:18
IPv4 main type.
Definition: ip4.h:95
uword unformat_mpls_label_net_byte_order(unformat_input_t *input, va_list *args)
Definition: mpls.c:164
#define MPLS_IETF_ELI_STRING
Definition: mpls_types.h:28
mpls_label_t label_exp_s_ttl
Definition: packet.h:31
u8 * format_mpls_eth_header_with_length(u8 *s, va_list *args)
Definition: mpls.c:145
#define MPLS_IETF_IMPLICIT_NULL_STRING
Definition: mpls_types.h:22
mpls_encap_t * mpls_encap_by_fib_and_dest(mpls_main_t *mm, u32 rx_fib, u32 dst_address)
Definition: mpls.c:180
u8 * format_fib_protocol(u8 *s, va_list ap)
Definition: fib_types.c:30
u64 uword
Definition: types.h:112
static clib_error_t * mpls_init(vlib_main_t *vm)
Definition: mpls.c:693
u8 * format_mpls_unicast_header_net_byte_order(u8 *s, va_list *args)
Definition: mpls.c:343
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:29
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static u32 vnet_mpls_uc_get_s(mpls_label_t label_exp_s_ttl)
Definition: packet.h:87
unsigned char u8
Definition: types.h:56
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:920
#define MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL
Definition: mpls_types.h:15
vlib_main_t * vlib_main
Definition: mpls.h:127
u8 * format_mpls_eos_bit(u8 *s, va_list *args)
Definition: mpls.c:75
mpls_main_t * mpls_get_main(vlib_main_t *vm)
Definition: mpls.c:711
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1060
int mpls_label_cmp(void *a1, void *a2)
Definition: mpls.c:413
#define vec_foreach(var, vec)
Vector iterator.
static u32 vnet_mpls_uc_get_exp(mpls_label_t label_exp_s_ttl)
Definition: packet.h:82
format_function_t format_mpls_encap_index
Definition: mpls.h:161
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
u32 tx_sw_if_index
Definition: mpls.h:254
unformat_function_t unformat_line_input
Definition: format.h:281
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:305
int mpls_fib_index_cmp(void *a1, void *a2)
Definition: mpls.c:404
static clib_error_t * mpls_del_encap_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mpls.c:355
u8 * format_mpls_header(u8 *s, va_list *args)
Definition: mpls.c:86
mpls_unicast_header_t * labels
Definition: mpls.h:51
mpls_encap_t * encaps
Definition: mpls.h:110
mpls_eos_bit_t fp_eos
Definition: fib_types.h:176
enum mpls_eos_bit_t_ mpls_eos_bit_t