FD.io VPP  v18.01-8-g0eacf49
Vector Packet Processing
bier_bift_table.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 
17 #include <vnet/dpo/drop_dpo.h>
18 #include <vnet/udp/udp.h>
19 
20 typedef enum {
21 #define bier_error(n,s) BIER_INPUT_ERROR_##n,
23 #undef bier_error
26 
27 static char * bier_error_strings[] = {
28 #define bier_error(n,s) s,
30 #undef bier_error
31 };
32 
33 /**
34  * Global BIFT table
35  */
37 
38 /**
39  * Forward declare the node
40  */
42 
43 void
45  const dpo_id_t *dpo)
46 {
47  if (NULL == bier_bift_table)
48  {
49  u32 ii;
50 
51  /*
52  * allocate the table and
53  * set each of the entries therein to a BIER drop
54  */
55  bier_bift_table = clib_mem_alloc_aligned(sizeof(*bier_bift_table),
57  memset(bier_bift_table, 0, sizeof(*bier_bift_table));
58 
59  for (ii = 0; ii < BIER_BIFT_N_ENTRIES; ii++)
60  {
62  &bier_bift_table->bblt_dpos[ii],
64  }
65 
66  /*
67  * register to handle packets that arrive on the assigned
68  * UDP port
69  */
71  UDP_DST_PORT_BIER,
73  0);
75  UDP_DST_PORT_BIER,
77  1);
78  }
79 
81  &bier_bift_table->bblt_dpos[id],
82  dpo);
83 
84  bier_bift_table->bblt_n_entries++;
85 }
86 
87 void
89 {
90  ASSERT(NULL != bier_bift_table);
91 
92  dpo_reset(&bier_bift_table->bblt_dpos[id]);
93 
94  bier_bift_table->bblt_n_entries--;
95 
96  if (0 == bier_bift_table->bblt_n_entries)
97  {
99  UDP_DST_PORT_BIER,
100  0);
102  UDP_DST_PORT_BIER,
103  1);
104 
105  clib_mem_free(bier_bift_table);
106  bier_bift_table = NULL;
107  }
108 }
109 
110 /**
111  * @brief Packet trace record for BIER input
112  */
114 {
117 
118 static uword
120  vlib_node_runtime_t * node,
121  vlib_frame_t * from_frame)
122 {
123  u32 n_left_from, next_index, * from, * to_next;
124 
125  from = vlib_frame_vector_args (from_frame);
126  n_left_from = from_frame->n_vectors;
127  next_index = node->cached_next_index;
128 
129  while (n_left_from > 0)
130  {
131  u32 n_left_to_next;
132 
133  vlib_get_next_frame (vm, node, next_index,
134  to_next, n_left_to_next);
135 
136  while (n_left_from > 0 && n_left_to_next > 0)
137  {
138  bier_bift_id_t *biftp0, bift0;
139  const dpo_id_t *dpo0;
140  vlib_buffer_t * b0;
141  u32 bi0, next0;
142 
143  bi0 = from[0];
144  to_next[0] = bi0;
145  from += 1;
146  to_next += 1;
147  n_left_from -= 1;
148  n_left_to_next -= 1;
149 
150  b0 = vlib_get_buffer (vm, bi0);
151  biftp0 = vlib_buffer_get_current (b0);
152  vlib_buffer_advance(b0, sizeof(bift0));
153  bift0 = clib_net_to_host_u32(*biftp0);
154 
155  /*
156  * Do the lookup based on the first 20 bits, i.e. the
157  * encoding of the set, sub-domain and BSL
158  */
159  dpo0 = bier_bift_dp_lookup(bift0);
160 
161  /*
162  * save the TTL for later during egress
163  */
164  vnet_buffer(b0)->mpls.ttl = vnet_mpls_uc_get_ttl(bift0);
165 
166  next0 = dpo0->dpoi_next_node;
167  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
168 
170  {
172 
173  tr = vlib_add_trace(vm, node, b0, sizeof (*tr));
174  tr->bift_id = bift0;
175  }
176 
177  vlib_validate_buffer_enqueue_x1(vm, node, next_index,
178  to_next, n_left_to_next,
179  bi0, next0);
180  }
181 
182  vlib_put_next_frame(vm, node, next_index, n_left_to_next);
183  }
184 
186  BIER_INPUT_ERROR_PKTS_VALID,
187  from_frame->n_vectors);
188  return (from_frame->n_vectors);
189 }
190 
191 static u8 *
192 format_bier_bift_input_trace (u8 * s, va_list * args)
193 {
194  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
195  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
196  bier_bift_input_trace_t * t = va_arg (*args, bier_bift_input_trace_t *);
197 
198  s = format (s, "BIFT-ID:[%U]", format_bier_bift_id,
200  return s;
201 }
202 
204  .function = bier_bift_input,
205  .name = "bier-bift-input",
206  /* Takes a vector of packets. */
207  .vector_size = sizeof (u32),
208  .n_errors = BIER_INPUT_N_ERROR,
209  .error_strings = bier_error_strings,
210  .n_next_nodes = 0,
211  .format_trace = format_bier_bift_input_trace,
212 };
213 
214 clib_error_t *
216  unformat_input_t * input,
217  vlib_cli_command_t * cmd)
218 {
219  clib_error_t * error = NULL;
220  u32 hdr_len, set, sub_domain;
221 
222  set = hdr_len = sub_domain = ~0;
223 
224  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
225  if (unformat (input, "sd %d", &sub_domain)) {
226  ;
227  } else if (unformat (input, "set %d", &set)) {
228  ;
229  } else if (unformat (input, "bsl %d", &hdr_len)) {
230  ;
231  }
232  else
233  {
234  error = unformat_parse_error (input);
235  goto done;
236  }
237  }
238 
239  if (NULL == bier_bift_table)
240  {
241  vlib_cli_output(vm, "no BIFT entries");
242  goto done;
243  }
244 
245  if (~0 == set)
246  {
247  u32 ii;
248 
249  for (ii = 0; ii < BIER_BIFT_N_ENTRIES; ii++)
250  {
251  if (!dpo_is_drop(&bier_bift_table->bblt_dpos[ii]))
252  {
253  bier_hdr_len_id_t bsl;
254 
255  bier_bift_id_decode(ii, &set, &sub_domain, &bsl);
256 
257  vlib_cli_output(vm, "set: %d, sub-domain:%d, BSL:%U",
258  set, sub_domain,
260  vlib_cli_output(vm, " %U",
262  &bier_bift_table->bblt_dpos[ii], 0);
263  }
264  }
265  }
266  else
267  {
268  bier_bift_id_t id;
269 
270  id = bier_bift_id_encode(set, sub_domain,
271  bier_hdr_bit_len_to_id(hdr_len));
272 
273  if (!dpo_is_drop(&bier_bift_table->bblt_dpos[id]))
274  {
275  vlib_cli_output(vm, "set: %d, sub-domain:%d, BSL:%U",
276  set, sub_domain,
277  format_bier_hdr_len_id, hdr_len);
278  vlib_cli_output(vm, " %U",
280  &bier_bift_table->bblt_dpos[id], 0);
281  }
282  }
283 done:
284  return (error);
285 }
286 
287 VLIB_CLI_COMMAND (show_bier_bift_command, static) = {
288  .path = "show bier bift",
289  .short_help = "show bier bift [set <value> sd <value> bsl <value>]",
290  .function = show_bier_bift_cmd,
291 };
Packet trace record for BIER input.
void dpo_stack_from_node(u32 child_node_index, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child parent relationship.
Definition: dpo.c:485
bier_bfit_table_t * bier_bift_table
Global BIFT table.
#define CLIB_UNUSED(x)
Definition: clib.h:79
struct bier_bift_input_trace_t_ bier_bift_input_trace_t
Packet trace record for BIER input.
#define NULL
Definition: clib.h:55
u8 * format_bier_bift_id(u8 *s, va_list *ap)
Definition: bier_types.c:222
struct _vlib_node_registration vlib_node_registration_t
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
void bier_bift_table_entry_add(bier_bift_id_t id, const dpo_id_t *dpo)
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
static char * bier_error_strings[]
bier_bift_id_t bier_bift_id_encode(bier_table_set_id_t set, bier_table_sub_domain_id_t sd, bier_hdr_len_id_t bsl)
Encode a BIFT-ID as per draft-wijnandsxu-bier-non-mpls-bift-encoding-00.txt.
Definition: bier_types.c:164
static u32 vnet_mpls_uc_get_ttl(mpls_label_t label_exp_s_ttl)
Definition: packet.h:92
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:166
static const dpo_id_t * bier_bift_dp_lookup(bier_bift_id_t key_host_order)
struct _unformat_input_t unformat_input_t
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:195
#define PREDICT_FALSE(x)
Definition: clib.h:105
static u32 vnet_mpls_uc_get_label(mpls_label_t label_exp_s_ttl)
Definition: packet.h:77
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:218
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:364
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1158
vlib_node_registration_t bier_bift_input_node
Forward declare the node.
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static uword bier_bift_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
u16 n_vectors
Definition: node.h:344
vlib_main_t * vm
Definition: buffer.c:283
#define BIER_BIFT_N_ENTRIES
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:530
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:93
enum bier_hdr_len_id_t_ bier_hdr_len_id_t
bier_hdr_len_id_t enumerator
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:454
u32 bier_bift_id_t
The BIER universal &#39;label&#39;.
Definition: bier_types.h:510
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:456
void bier_bift_id_decode(bier_bift_id_t id, bier_table_set_id_t *set, bier_table_sub_domain_id_t *sd, bier_hdr_len_id_t *bsl)
Definition: bier_types.c:180
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
static void clib_mem_free(void *p)
Definition: mem.h:179
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:208
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:146
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u64 uword
Definition: types.h:112
static 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 unformat_parse_error(input)
Definition: format.h:267
Definition: defs.h:47
u8 * format_bier_hdr_len_id(u8 *s, va_list *ap)
Format the header length field.
Definition: bier_types.c:96
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:182
dpo_id_t bblt_dpos[BIER_BIFT_N_ENTRIES]
Forwarding information for each BIFT ID.
unsigned char u8
Definition: types.h:56
static u8 * format_bier_bift_input_trace(u8 *s, va_list *args)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:120
static bier_hdr_len_id_t bier_hdr_bit_len_to_id(u32 bytes)
Definition: bier_types.h:137
#define vnet_buffer(b)
Definition: buffer.h:326
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
int dpo_is_drop(const dpo_id_t *dpo)
The Drop DPO will drop all packets, no questions asked.
Definition: drop_dpo.c:33
void bier_bift_table_entry_remove(bier_bift_id_t id)
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:228
u32 bblt_n_entries
The number of entries in the table.
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:178
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:492
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:75
bier_input_error_t
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
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
clib_error_t * show_bier_bift_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)