FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
drop.c
Go to the documentation of this file.
1 /*
2  * drop.c - Punt and drop nodes
3  *
4  * Copyright (c) 2015 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 <vlib/vlib.h>
19 
20 typedef enum
21 {
26 
27 static u8 *
29 {
31  uword code = vlib_error_get_code (&vm->node_main, e[0]);
32  vlib_node_t *n;
33 
35  return format (0, "[%d], node index out of range 0x%x, error 0x%x",
36  index, node_index, e[0]);
37 
39  if (code >= n->n_errors)
40  return format (0, "[%d], code %d out of range for node %v",
41  index, code, n->name);
42 
43  return 0;
44 }
45 
46 static u8 *
49 {
50  u32 *buffers = vlib_frame_vector_args (f);
52  u8 *msg = 0;
53  uword i;
54 
55  for (i = 0; i < f->n_vectors; i++)
56  {
57  b = vlib_get_buffer (vm, buffers[i]);
58  msg = validate_error (vm, &b->error, i);
59  if (msg)
60  return msg;
61  }
62 
63  return msg;
64 }
65 
68 {
69  vlib_node_t *n;
70  u32 ci, ni;
71 
72  ni = vlib_error_get_node (&vm->node_main, e);
73  n = vlib_get_node (vm, ni);
74 
75  ci = vlib_error_get_code (&vm->node_main, e);
76  ASSERT (ci < n->n_errors);
77 
78  ci += n->error_heap_index;
79 
80  return ci;
81 }
82 
83 static u8 *
84 format_error_trace (u8 * s, va_list * va)
85 {
86  vlib_main_t *vm = va_arg (*va, vlib_main_t *);
87  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
88  vlib_error_t *e = va_arg (*va, vlib_error_t *);
89  vlib_node_t *error_node;
91  u32 i;
92 
93  error_node = vlib_get_node (vm, vlib_error_get_node (&vm->node_main, e[0]));
95  error_node->error_heap_index;
96  s = format (s, "%v: %s", error_node->name, em->counters_heap[i].name);
97 
98  return s;
99 }
100 
101 static void
104 {
105  u32 n_left, *buffers;
106 
107  buffers = vlib_frame_vector_args (frame);
108  n_left = frame->n_vectors;
109 
110  while (n_left >= 4)
111  {
112  u32 bi0, bi1;
113  vlib_buffer_t *b0, *b1;
114  vlib_error_t *t0, *t1;
115 
116  /* Prefetch next iteration. */
117  vlib_prefetch_buffer_with_index (vm, buffers[2], LOAD);
118  vlib_prefetch_buffer_with_index (vm, buffers[3], LOAD);
119 
120  bi0 = buffers[0];
121  bi1 = buffers[1];
122 
123  b0 = vlib_get_buffer (vm, bi0);
124  b1 = vlib_get_buffer (vm, bi1);
125 
126  if (b0->flags & VLIB_BUFFER_IS_TRACED)
127  {
128  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
129  t0[0] = b0->error;
130  }
131  if (b1->flags & VLIB_BUFFER_IS_TRACED)
132  {
133  t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
134  t1[0] = b1->error;
135  }
136  buffers += 2;
137  n_left -= 2;
138  }
139 
140  while (n_left >= 1)
141  {
142  u32 bi0;
143  vlib_buffer_t *b0;
144  vlib_error_t *t0;
145 
146  bi0 = buffers[0];
147 
148  b0 = vlib_get_buffer (vm, bi0);
149 
150  if (b0->flags & VLIB_BUFFER_IS_TRACED)
151  {
152  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
153  t0[0] = b0->error;
154  }
155  buffers += 1;
156  n_left -= 1;
157  }
158 }
159 
163  vlib_frame_t * frame, error_disposition_t disposition)
164 {
165  u32 errors[VLIB_FRAME_SIZE], *error, *from, n_left;
168 
170  n_left = frame->n_vectors;
171  b = bufs;
172  error = errors;
173 
175 
176  if (node->flags & VLIB_NODE_FLAG_TRACE)
178 
179  /* collect the array of error first ... */
180  while (n_left >= 4)
181  {
182  if (n_left >= 12)
183  {
184  /* Prefetch 8 ahead - there's not much going on in each iteration */
185  vlib_prefetch_buffer_header (b[4], LOAD);
186  vlib_prefetch_buffer_header (b[5], LOAD);
187  vlib_prefetch_buffer_header (b[6], LOAD);
188  vlib_prefetch_buffer_header (b[7], LOAD);
189  }
190  error[0] = b[0]->error;
191  error[1] = b[1]->error;
192  error[2] = b[2]->error;
193  error[3] = b[3]->error;
194 
195  error += 4;
196  n_left -= 4;
197  b += 4;
198  }
199  while (n_left)
200  {
201  error[0] = b[0]->error;
202 
203  error += 1;
204  n_left -= 1;
205  b += 1;
206  }
207 
208  /* ... then count against them in blocks */
209  n_left = frame->n_vectors;
210 
211  while (n_left)
212  {
213  u16 off, count;
214  u32 c_index;
215 
216  off = frame->n_vectors - n_left;
217 
218  error = errors + off;
219 
221  n_left -= count;
222 
223  c_index = counter_index (vm, error[0]);
224  em->counters[c_index] += count;
225 
226  vlib_error_elog_count (vm, c_index, count);
227  }
228 
229  if (disposition == ERROR_DISPOSITION_DROP || !vm->os_punt_frame)
230  {
231  vlib_buffer_free (vm, from, frame->n_vectors);
232 
233  /* If there is no punt function, free the frame as well. */
234  if (disposition == ERROR_DISPOSITION_PUNT && !vm->os_punt_frame)
236  }
237  else
239 
240  return frame->n_vectors;
241 }
242 
246 {
248 }
249 
253 {
255 }
256 
257 /* *INDENT-OFF* */
259  .name = "drop",
260  .flags = VLIB_NODE_FLAG_IS_DROP,
261  .vector_size = sizeof (u32),
262  .format_trace = format_error_trace,
263  .validate_frame = validate_error_frame,
264 };
265 /* *INDENT-ON* */
266 
267 /* *INDENT-OFF* */
269  .name = "punt",
272  .vector_size = sizeof (u32),
273  .format_trace = format_error_trace,
274  .validate_frame = validate_error_frame,
275 };
276 /* *INDENT-ON* */
277 
278 /*
279  * fd.io coding-style-patch-verification: ON
280  *
281  * Local Variables:
282  * eval: (c-set-style "gnu")
283  * End:
284  */
vlib.h
vlib_error_main_t
Definition: error.h:61
vlib_frame_t::n_vectors
u16 n_vectors
Definition: node.h:387
vlib_buffer_free
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:979
bufs
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
Definition: nat44_ei_out2in.c:717
vlib_prefetch_buffer_header
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:231
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
vlib_error_get_node
static u32 vlib_error_get_node(vlib_node_main_t *nm, vlib_error_t e)
Definition: node.h:748
error_punt_node
vlib_node_registration_t error_punt_node
(constructor) VLIB_REGISTER_NODE (error_punt_node)
Definition: drop.c:268
vlib_error_main_t::counters_heap
vlib_error_desc_t * counters_heap
Definition: error.h:71
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
f
vlib_frame_t * f
Definition: interface_output.c:1098
VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH
#define VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH
Definition: node.h:282
vlib_get_buffers
vlib_get_buffers(vm, from, b, n_left_from)
error_drop_node
vlib_node_registration_t error_drop_node
(constructor) VLIB_REGISTER_NODE (error_drop_node)
Definition: drop.c:258
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
ERROR_DISPOSITION_PUNT
@ ERROR_DISPOSITION_PUNT
Definition: drop.c:23
vlib_main_t::error_main
vlib_error_main_t error_main
Definition: main.h:179
u16
unsigned short u16
Definition: types.h:57
vlib_main_t::node_main
vlib_node_main_t node_main
Definition: main.h:173
vlib_error_get_code
static u32 vlib_error_get_code(vlib_node_main_t *nm, vlib_error_t e)
Definition: node.h:754
vlib_error_elog_count
static void vlib_error_elog_count(vlib_main_t *vm, uword counter, uword increment)
Definition: error_funcs.h:46
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
counter_index
static u32 counter_index(vlib_main_t *vm, vlib_error_t e)
Definition: drop.c:67
node_index
node node_index
Definition: interface_output.c:440
validate_error_frame
static u8 * validate_error_frame(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f)
Definition: drop.c:47
vlib_frame_t
Definition: node.h:372
vlib_error_desc_t::name
char * name
Definition: error.h:56
error
Definition: cJSON.c:88
process_drop_punt
static_always_inline uword process_drop_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, error_disposition_t disposition)
Definition: drop.c:161
count
u8 count
Definition: dhcp.api:208
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
vlib_error_main_t::counters
u64 * counters
Definition: error.h:64
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
trace_errors
static void trace_errors(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: drop.c:102
static_always_inline
#define static_always_inline
Definition: clib.h:112
vlib_prefetch_buffer_with_index
#define vlib_prefetch_buffer_with_index(vm, bi, type)
Prefetch buffer metadata by buffer index The first 64 bytes of buffer contains most header informatio...
Definition: buffer_funcs.h:507
uword
u64 uword
Definition: types.h:112
vlib_get_node
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:86
vlib_main_t::os_punt_frame
void(* os_punt_frame)(struct vlib_main_t *vm, struct vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: main.h:183
clib_count_equal_u32
static_always_inline uword clib_count_equal_u32(u32 *data, uword max_count)
Definition: string.h:535
VLIB_NODE_FLAG_IS_DROP
#define VLIB_NODE_FLAG_IS_DROP
Definition: node.h:286
vlib_node_t::n_errors
u16 n_errors
Definition: node.h:308
VLIB_NODE_FLAG_IS_PUNT
#define VLIB_NODE_FLAG_IS_PUNT
Definition: node.h:287
format_error_trace
static u8 * format_error_trace(u8 *s, va_list *va)
Definition: drop.c:84
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vlib_frame_free
void vlib_frame_free(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_frame_t *f)
Definition: main.c:242
ERROR_N_DISPOSITION
@ ERROR_N_DISPOSITION
Definition: drop.c:24
index
u32 index
Definition: flow_types.api:221
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
ERROR_DISPOSITION_DROP
@ ERROR_DISPOSITION_DROP
Definition: drop.c:22
off
u32 off
Definition: interface_output.c:1096
u32
unsigned int u32
Definition: types.h:88
n_left
u32 n_left
Definition: interface_output.c:1096
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
validate_error
static u8 * validate_error(vlib_main_t *vm, vlib_error_t *e, u32 index)
Definition: drop.c:28
i
int i
Definition: flowhash_template.h:376
vlib_node_t::error_heap_index
u32 error_heap_index
Definition: node.h:315
error_disposition_t
error_disposition_t
Definition: drop.c:20
vlib_error_t
u16 vlib_error_t
Definition: error.h:45
vlib_node_runtime_t
Definition: node.h:454
vlib_node_main_t::nodes
vlib_node_t ** nodes
Definition: node.h:668
from
from
Definition: nat44_ei_hairpinning.c:415
vlib_node_t::name
u8 * name
Definition: node.h:253
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169