FD.io VPP  v17.10-9-gd594711
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))
77  else if (unformat (input, "%d", label))
78  ;
79  else
80  return (0);
81 
82  return (1);
83 }
84 
85 u8 * format_mpls_eos_bit (u8 * s, va_list * args)
86 {
87  mpls_eos_bit_t eb = va_arg (*args, mpls_eos_bit_t);
88 
89  ASSERT(eb <= MPLS_EOS);
90 
91  s = format(s, "%s", mpls_eos_bit_names[eb]);
92 
93  return (s);
94 }
95 
96 u8 * format_mpls_header (u8 * s, va_list * args)
97 {
98  mpls_unicast_header_t hdr = va_arg (*args, mpls_unicast_header_t);
99 
100  return (format(s, "[%U:%d:%d:%U]",
107 }
108 
109 uword
110 unformat_mpls_header (unformat_input_t * input, va_list * args)
111 {
112  u8 ** result = va_arg (*args, u8 **);
113  mpls_unicast_header_t _h, * h = &_h;
114  u32 label, label_exp_s_ttl;
115 
116  if (! unformat (input, "MPLS %d", &label))
117  return 0;
118 
119  label_exp_s_ttl = (label<<12) | (1<<8) /* s-bit */ | 0xFF;
120  h->label_exp_s_ttl = clib_host_to_net_u32 (label_exp_s_ttl);
121 
122  /* Add gre, mpls headers to result. */
123  {
124  void * p;
125  u32 h_n_bytes = sizeof (h[0]);
126 
127  vec_add2 (*result, p, h_n_bytes);
128  clib_memcpy (p, h, h_n_bytes);
129  }
130 
131  return 1;
132 }
133 
134 uword
136  va_list * args)
137 {
138  u32 * result = va_arg (*args, u32 *);
139  u32 label;
140 
141  if (!unformat (input, "MPLS: label %d", &label))
142  return 0;
143 
144  label = (label<<12) | (1<<8) /* s-bit set */ | 0xFF /* ttl */;
145 
146  *result = clib_host_to_net_u32 (label);
147  return 1;
148 }
149 
151 {
152  mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *);
153  u32 label = h->label_exp_s_ttl;
154 
155  s = format (s, "label %d exp %d, s %d, ttl %d",
156  vnet_mpls_uc_get_label (label),
157  vnet_mpls_uc_get_exp (label),
158  vnet_mpls_uc_get_s (label),
159  vnet_mpls_uc_get_ttl (label));
160  return s;
161 }
162 
164 {
165  mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *);
166  mpls_unicast_header_t h_host;
167 
168  h_host.label_exp_s_ttl = clib_net_to_host_u32 (h->label_exp_s_ttl);
169 
171  &h_host);
172 }
173 
174 typedef struct {
181 
182 int
183 mpls_dest_cmp(void * a1, void * a2)
184 {
185  show_mpls_fib_t * r1 = a1;
186  show_mpls_fib_t * r2 = a2;
187 
188  return clib_net_to_host_u32(r1->dest) - clib_net_to_host_u32(r2->dest);
189 }
190 
191 int
192 mpls_fib_index_cmp(void * a1, void * a2)
193 {
194  show_mpls_fib_t * r1 = a1;
195  show_mpls_fib_t * r2 = a2;
196 
197  return r1->fib_index - r2->fib_index;
198 }
199 
200 int
201 mpls_label_cmp(void * a1, void * a2)
202 {
203  show_mpls_fib_t * r1 = a1;
204  show_mpls_fib_t * r2 = a2;
205 
206  return r1->label - r2->label;
207 }
208 
209 static clib_error_t *
211  unformat_input_t * input,
212  vlib_cli_command_t * cmd)
213 {
214  unformat_input_t _line_input, * line_input = &_line_input;
215  fib_route_path_t *rpaths = NULL, rpath;
216  u32 table_id, is_del, is_ip;
217  mpls_label_t local_label;
218  mpls_label_t out_label;
219  clib_error_t * error;
220  mpls_eos_bit_t eos;
221  vnet_main_t * vnm;
222  fib_prefix_t pfx;
223 
224  vnm = vnet_get_main();
225  error = NULL;
226  is_ip = 0;
227  table_id = 0;
228  eos = MPLS_EOS;
229  is_del = 0;
230  local_label = MPLS_LABEL_INVALID;
231  memset(&pfx, 0, sizeof(pfx));
232 
233  /* Get a line of input. */
234  if (! unformat_user (input, unformat_line_input, line_input))
235  return 0;
236 
237  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
238  {
239  memset(&rpath, 0, sizeof(rpath));
240 
241  if (unformat (line_input, "table %d", &table_id))
242  ;
243  else if (unformat (line_input, "del"))
244  is_del = 1;
245  else if (unformat (line_input, "add"))
246  is_del = 0;
247  else if (unformat (line_input, "eos"))
248  pfx.fp_eos = MPLS_EOS;
249  else if (unformat (line_input, "non-eos"))
250  pfx.fp_eos = MPLS_NON_EOS;
251  else if (unformat (line_input, "%U/%d",
253  &pfx.fp_addr.ip4,
254  &pfx.fp_len))
255  {
257  is_ip = 1;
258  }
259  else if (unformat (line_input, "%U/%d",
261  &pfx.fp_addr.ip6,
262  &pfx.fp_len))
263  {
265  is_ip = 1;
266  }
267  else if (unformat (line_input, "via %U %U weight %u",
269  &rpath.frp_addr.ip4,
271  &rpath.frp_sw_if_index,
272  &rpath.frp_weight))
273  {
274  rpath.frp_proto = DPO_PROTO_IP4;
275  vec_add1(rpaths, rpath);
276  }
277 
278  else if (unformat (line_input, "via %U %U weight %u",
280  &rpath.frp_addr.ip6,
282  &rpath.frp_sw_if_index,
283  &rpath.frp_weight))
284  {
285  rpath.frp_proto = DPO_PROTO_IP6;
286  vec_add1(rpaths, rpath);
287  }
288 
289  else if (unformat (line_input, "via %U %U",
291  &rpath.frp_addr.ip4,
293  &rpath.frp_sw_if_index))
294  {
295  rpath.frp_weight = 1;
296  rpath.frp_proto = DPO_PROTO_IP4;
297  vec_add1(rpaths, rpath);
298  }
299  else if (unformat (line_input, "rx-ip4 %U",
301  &rpath.frp_sw_if_index))
302  {
303  rpath.frp_weight = 1;
304  rpath.frp_proto = DPO_PROTO_IP4;
305  rpath.frp_flags = FIB_ROUTE_PATH_INTF_RX;
306  vec_add1(rpaths, rpath);
307  }
308  else if (unformat (line_input, "via %U %U",
310  &rpath.frp_addr.ip6,
312  &rpath.frp_sw_if_index))
313  {
314  rpath.frp_weight = 1;
315  rpath.frp_proto = DPO_PROTO_IP6;
316  vec_add1(rpaths, rpath);
317  }
318  else if (unformat (line_input, "via %U next-hop-table %d",
320  &rpath.frp_addr.ip4,
321  &rpath.frp_fib_index))
322  {
323  rpath.frp_weight = 1;
324  rpath.frp_sw_if_index = ~0;
325  rpath.frp_proto = DPO_PROTO_IP4;
326  vec_add1(rpaths, rpath);
327  }
328  else if (unformat (line_input, "via %U next-hop-table %d",
330  &rpath.frp_addr.ip6,
331  &rpath.frp_fib_index))
332  {
333  rpath.frp_weight = 1;
334  rpath.frp_sw_if_index = ~0;
335  rpath.frp_proto = DPO_PROTO_IP6;
336  vec_add1(rpaths, rpath);
337  }
338  else if (unformat (line_input, "via %U",
340  &rpath.frp_addr.ip4))
341  {
342  /*
343  * the recursive next-hops are by default in the same table
344  * as the prefix
345  */
346  rpath.frp_fib_index = table_id;
347  rpath.frp_weight = 1;
348  rpath.frp_sw_if_index = ~0;
349  rpath.frp_proto = DPO_PROTO_IP4;
350  vec_add1(rpaths, rpath);
351  }
352  else if (unformat (line_input, "via %U",
354  &rpath.frp_addr.ip6))
355  {
356  rpath.frp_fib_index = table_id;
357  rpath.frp_weight = 1;
358  rpath.frp_sw_if_index = ~0;
359  rpath.frp_proto = DPO_PROTO_IP6;
360  vec_add1(rpaths, rpath);
361  }
362  else if (unformat (line_input, "%d", &local_label))
363  ;
364  else if (unformat (line_input,
365  "ip4-lookup-in-table %d",
366  &rpath.frp_fib_index))
367  {
368  rpath.frp_proto = DPO_PROTO_IP4;
369  rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
371  vec_add1(rpaths, rpath);
372  }
373  else if (unformat (line_input,
374  "ip6-lookup-in-table %d",
375  &rpath.frp_fib_index))
376  {
377  rpath.frp_proto = DPO_PROTO_IP6;
378  rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
379  vec_add1(rpaths, rpath);
381  }
382  else if (unformat (line_input,
383  "mpls-lookup-in-table %d",
384  &rpath.frp_fib_index))
385  {
386  rpath.frp_proto = DPO_PROTO_MPLS;
387  rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
389  vec_add1(rpaths, rpath);
390  }
391  else if (unformat (line_input,
392  "l2-input-on %U",
394  &rpath.frp_sw_if_index))
395  {
396  rpath.frp_proto = DPO_PROTO_ETHERNET;
398  rpath.frp_flags = FIB_ROUTE_PATH_INTF_RX;
399  vec_add1(rpaths, rpath);
400  }
401  else if (unformat (line_input, "out-labels"))
402  {
403  if (vec_len (rpaths) == 0)
404  {
405  error = clib_error_return (0, "Paths then labels");
406  goto done;
407  }
408  else
409  {
410  while (unformat (line_input, "%U",
412  &out_label))
413  {
414  vec_add1 (rpaths[vec_len (rpaths) - 1].frp_label_stack,
415  out_label);
416  }
417  }
418  }
419  else
420  {
421  error = clib_error_return (0, "unkown input: %U",
422  format_unformat_error, line_input);
423  goto done;
424  }
425 
426  }
427 
428  if (MPLS_LABEL_INVALID == local_label)
429  {
430  error = clib_error_return (0, "local-label required: %U",
431  format_unformat_error, input);
432  goto done;
433  }
434 
435 
436  if (is_ip)
437  {
438  u32 fib_index = fib_table_find(pfx.fp_proto, table_id);
439 
440  if (FIB_NODE_INDEX_INVALID == fib_index)
441  {
442  error = clib_error_return (0, "%U table-id %d does not exist",
443  format_fib_protocol, pfx.fp_proto, table_id);
444  goto done;
445  }
446 
447  if (is_del)
448  {
449  fib_table_entry_local_label_remove(fib_index, &pfx, local_label);
450  }
451  else
452  {
453  fib_table_entry_local_label_add(fib_index, &pfx, local_label);
454  }
455  }
456  else
457  {
458  fib_node_index_t fib_index;
459  u32 fi;
460 
461  if (NULL == rpaths)
462  {
463  error = clib_error_return(0 , "no paths");
464  goto done;
465  }
466 
468  pfx.fp_len = 21;
469  pfx.fp_label = local_label;
470  pfx.fp_payload_proto = rpaths[0].frp_proto;
471 
472  /*
473  * the CLI parsing stored table Ids, swap to FIB indicies
474  */
475  if (FIB_NODE_INDEX_INVALID == rpath.frp_sw_if_index)
476  {
478  rpaths[0].frp_fib_index);
479 
480  if (~0 == fi)
481  {
482  error = clib_error_return(0 , "%U Via table %d does not exist",
484  rpaths[0].frp_fib_index);
485  goto done;
486  }
487  rpaths[0].frp_fib_index = fi;
488  }
489 
490  fib_index = mpls_fib_index_from_table_id(table_id);
491 
492  if (FIB_NODE_INDEX_INVALID == fib_index)
493  {
494  error = clib_error_return (0, "MPLS table-id %d does not exist",
495  table_id);
496  goto done;
497  }
498 
499  if (is_del)
500  {
502  &pfx,
504  rpaths);
505  }
506  else
507  {
508  fib_node_index_t lfe;
509 
510  lfe = fib_table_entry_path_add2(fib_index,
511  &pfx,
514  rpaths);
515 
516  if (FIB_NODE_INDEX_INVALID == lfe)
517  {
518  error = clib_error_return (0, "Failed to create %U-%U in MPLS table-id %d",
519  format_mpls_unicast_label, local_label,
520  format_mpls_eos_bit, eos,
521  table_id);
522  goto done;
523  }
524  }
525  }
526 
527 done:
528  unformat_free (line_input);
529 
530  return error;
531 }
532 
533 VLIB_CLI_COMMAND (mpls_local_label_command, static) = {
534  .path = "mpls local-label",
535  .function = vnet_mpls_local_label,
536  .short_help = "Create/Delete MPL local labels",
537 };
538 
539 clib_error_t *
541  unformat_input_t * main_input,
542  vlib_cli_command_t * cmdo)
543 {
544  unformat_input_t _line_input, *line_input = &_line_input;
545  clib_error_t *error = NULL;
546  u32 table_id, is_add;
547  u8 *name = NULL;
548 
549  is_add = 1;
550  table_id = ~0;
551 
552  /* Get a line of input. */
553  if (!unformat_user (main_input, unformat_line_input, line_input))
554  return 0;
555 
556  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
557  {
558  if (unformat (line_input, "%d", &table_id))
559  ;
560  else if (unformat (line_input, "del"))
561  is_add = 0;
562  else if (unformat (line_input, "add"))
563  is_add = 1;
564  else if (unformat (line_input, "name %s", &name))
565  ;
566  else
567  {
568  error = unformat_parse_error (line_input);
569  goto done;
570  }
571  }
572 
573  if (~0 == table_id)
574  {
575  error = clib_error_return (0, "No table id");
576  goto done;
577  }
578  else
579  {
580  if (is_add)
581  {
582  mpls_table_create (table_id, 0, name);
583  }
584  else
585  {
586  mpls_table_delete (table_id, 0);
587  }
588  }
589 
590  done:
591  unformat_free (line_input);
592  return error;
593 }
594 
595 /* *INDENT-ON* */
596 /*?
597  * This command is used to add or delete MPLS Tables. All
598  * Tables must be explicitly added before that can be used,
599  * Including the default table.
600  ?*/
601 /* *INDENT-OFF* */
602 VLIB_CLI_COMMAND (mpls_table_command, static) = {
603  .path = "mpls table",
604  .short_help = "mpls table [add|del] <table-id>",
605  .function = vnet_mpls_table_cmd,
606  .is_mp_safe = 1,
607 };
608 
609 int
611 {
612  // FIXME
613  return 0;
614 }
615 
616 static clib_error_t *
618 {
619  clib_error_t * error;
620 
621  if ((error = vlib_call_init_function (vm, ip_main_init)))
622  return error;
623 
625 }
626 
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:169
uword unformat_mpls_unicast_label(unformat_input_t *input, va_list *args)
Definition: mpls.c:57
A representation of a path as described by a route producer.
Definition: fib_types.h:336
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define NULL
Definition: clib.h:55
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, fib_route_path_t *rpath)
Add n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:538
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:24
#define MPLS_IETF_IMPLICIT_NULL_LABEL
Definition: mpls_types.h:30
From the CLI.
Definition: fib_entry.h:66
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
#define MPLS_IETF_ROUTER_ALERT_LABEL
Definition: mpls_types.h:28
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:557
u8 * format_mpls_unicast_label(u8 *s, va_list *args)
Definition: mpls.c:27
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
u8 * format_mpls_unicast_header_host_byte_order(u8 *s, va_list *args)
Definition: mpls.c:150
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:341
unformat_function_t unformat_vnet_sw_interface
int mpls_dest_cmp(void *a1, void *a2)
Definition: mpls.c:183
A path that result in received traffic being recieved/recirculated so that it appears to have arrived...
Definition: fib_types.h:301
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:897
#define MPLS_IETF_IPV4_EXPLICIT_NULL_BRIEF_STRING
Definition: mpls_types.h:36
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:193
unformat_function_t unformat_ip4_address
Definition: format.h:76
#define MPLS_IETF_ROUTER_ALERT_STRING
Definition: mpls_types.h:39
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
int mpls_fib_reset_labels(u32 fib_id)
Definition: mpls.c:610
Aggregrate type for a prefix.
Definition: fib_types.h:160
#define clib_error_return(e, args...)
Definition: error.h:99
static const char * mpls_eos_bit_names[]
Definition: mpls.c:23
#define MPLS_IETF_ROUTER_ALERT_BRIEF_STRING
Definition: mpls_types.h:40
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:1025
fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto)
Definition: fib_types.c:227
u16 fp_len
The mask length.
Definition: fib_types.h:164
#define vlib_call_init_function(vm, x)
Definition: init.h:162
#define MPLS_IETF_IPV6_EXPLICIT_NULL_BRIEF_STRING
Definition: mpls_types.h:42
Definition: fib_entry.h:228
unformat_function_t unformat_line_input
Definition: format.h:281
#define MPLS_IETF_GAL_STRING
Definition: mpls_types.h:45
void mpls_table_delete(u32 table_id, u8 is_api)
Definition: mpls_api.c:62
#define MPLS_IETF_ELI_LABEL
Definition: mpls_types.h:31
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:183
u32 entry_index
Definition: mpls.c:176
struct _unformat_input_t unformat_input_t
clib_error_t * vnet_mpls_table_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmdo)
Definition: mpls.c:540
void fib_table_entry_path_remove2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_route_path_t *rpath)
Remove n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:582
static u32 vnet_mpls_uc_get_label(mpls_label_t label_exp_s_ttl)
Definition: packet.h:77
uword unformat_mpls_header(unformat_input_t *input, va_list *args)
Definition: mpls.c:110
#define MPLS_IETF_IPV4_EXPLICIT_NULL_STRING
Definition: mpls_types.h:35
unformat_function_t unformat_ip6_address
Definition: format.h:94
clib_error_t * ip_main_init(vlib_main_t *vm)
Definition: ip_init.c:45
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
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:870
mpls_main_t mpls_main
Definition: mpls.c:25
vlib_main_t * vm
Definition: buffer.c:283
vec_header_t h
Definition: buffer.c:282
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:48
#define MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL
Definition: mpls_types.h:27
#define clib_memcpy(a, b, c)
Definition: string.h:69
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
#define MPLS_IETF_IMPLICIT_NULL_BRIEF_STRING
Definition: mpls_types.h:38
u32 mpls_fib_index_from_table_id(u32 table_id)
Definition: mpls_fib.c:73
mpls_label_t fp_label
Definition: fib_types.h:186
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
static clib_error_t * mpls_input_init(vlib_main_t *vm)
Definition: mpls_input.c:298
u32 fib_index
Definition: mpls.c:175
#define MPLS_IETF_IPV6_EXPLICIT_NULL_STRING
Definition: mpls_types.h:41
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
static clib_error_t * vnet_mpls_local_label(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mpls.c:210
#define MPLS_IETF_GAL_LABEL
Definition: mpls_types.h:32
void mpls_table_create(u32 table_id, u8 is_api, const u8 *name)
Definition: mpls_api.c:261
uword unformat_mpls_label_net_byte_order(unformat_input_t *input, va_list *args)
Definition: mpls.c:135
#define MPLS_IETF_ELI_STRING
Definition: mpls_types.h:43
mpls_label_t label_exp_s_ttl
Definition: packet.h:31
#define MPLS_IETF_IMPLICIT_NULL_STRING
Definition: mpls_types.h:37
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:617
#define unformat_parse_error(input)
Definition: format.h:267
u8 * format_mpls_unicast_header_net_byte_order(u8 *s, va_list *args)
Definition: mpls.c:163
#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
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
#define MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL
Definition: mpls_types.h:29
u8 * format_dpo_proto(u8 *s, va_list *args)
format a DPO protocol
Definition: dpo.c:171
u8 * format_mpls_eos_bit(u8 *s, va_list *args)
Definition: mpls.c:85
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
int mpls_label_cmp(void *a1, void *a2)
Definition: mpls.c:201
static u32 vnet_mpls_uc_get_exp(mpls_label_t label_exp_s_ttl)
Definition: packet.h:82
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:379
int mpls_fib_index_cmp(void *a1, void *a2)
Definition: mpls.c:192
u8 * format_mpls_header(u8 *s, va_list *args)
Definition: mpls.c:96
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
mpls_eos_bit_t fp_eos
Definition: fib_types.h:187
enum mpls_eos_bit_t_ mpls_eos_bit_t