FD.io VPP  v21.01.1
Vector Packet Processing
ip_punt_drop.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 #ifndef __IP_PUNT_DROP_H__
17 #define __IP_PUNT_DROP_H__
18 
19 #include <vnet/ip/ip.h>
20 #include <vnet/policer/policer.h>
22 
23 /**
24  * IP4 punt policer configuration
25  * we police the punt rate to prevent overloading the host
26  */
27 typedef struct ip_punt_policer_t_
28 {
31 
33 {
37 
39 {
43 
44 #define foreach_ip_punt_policer_error \
45 _(DROP, "ip punt policer drop")
46 
47 typedef enum
48 {
49 #define _(sym,str) IP_PUNT_POLICER_ERROR_##sym,
51 #undef _
54 
55 extern u8 *format_ip_punt_policer_trace (u8 * s, va_list * args);
56 
57 /**
58  * IP punt policing node function
59  */
63  vlib_frame_t * frame, u8 arc_index, u32 policer_index)
64 {
65  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
66  u64 time_in_policer_periods;
69 
70  time_in_policer_periods =
72 
73  from = vlib_frame_vector_args (frame);
74  n_left_from = frame->n_vectors;
75  next_index = node->cached_next_index;
76 
77  while (n_left_from > 0)
78  {
79  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
80 
81  while (n_left_from >= 4 && n_left_to_next >= 2)
82  {
83  vlib_buffer_t *b0, *b1;
84  u32 next0, next1;
85  u8 act0, act1;
86  u32 bi0, bi1;
87 
88  next0 = next1 = 0;
89  bi0 = to_next[0] = from[0];
90  bi1 = to_next[1] = from[1];
91 
92  from += 2;
93  n_left_from -= 2;
94  to_next += 2;
95  n_left_to_next -= 2;
96 
97  b0 = vlib_get_buffer (vm, bi0);
98  b1 = vlib_get_buffer (vm, bi1);
99 
101  &b0->current_config_index, &next0, 0);
103  &b1->current_config_index, &next1, 0);
104 
105  act0 = vnet_policer_police (vm, b0,
106  policer_index,
107  time_in_policer_periods,
109  act1 = vnet_policer_police (vm, b1,
110  policer_index,
111  time_in_policer_periods,
113 
114  if (PREDICT_FALSE (act0 == SSE2_QOS_ACTION_DROP))
115  {
117  b0->error = node->errors[IP_PUNT_POLICER_ERROR_DROP];
118  }
119  if (PREDICT_FALSE (act1 == SSE2_QOS_ACTION_DROP))
120  {
122  b1->error = node->errors[IP_PUNT_POLICER_ERROR_DROP];
123  }
124 
125  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
126  {
128  vlib_add_trace (vm, node, b0, sizeof (*t));
129  t->next = next0;
131  }
132  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
133  {
135  vlib_add_trace (vm, node, b1, sizeof (*t));
136  t->next = next1;
138  }
139  vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
140  n_left_to_next,
141  bi0, bi1, next0, next1);
142  }
143  while (n_left_from > 0 && n_left_to_next > 0)
144  {
145  vlib_buffer_t *b0;
146  u32 next0;
147  u32 bi0;
148  u8 act0;
149 
150  next0 = 0;
151  bi0 = to_next[0] = from[0];
152 
153  from += 1;
154  n_left_from -= 1;
155  to_next += 1;
156  n_left_to_next -= 1;
157 
158  b0 = vlib_get_buffer (vm, bi0);
159 
161  &b0->current_config_index, &next0, 0);
162 
163  act0 = vnet_policer_police (vm, b0,
164  policer_index,
165  time_in_policer_periods,
167  if (PREDICT_FALSE (act0 == SSE2_QOS_ACTION_DROP))
168  {
170  b0->error = node->errors[IP_PUNT_POLICER_ERROR_DROP];
171  }
172 
173  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
174  {
176  vlib_add_trace (vm, node, b0, sizeof (*t));
177  t->next = next0;
179  }
180 
181  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
182  n_left_to_next, bi0, next0);
183  }
184  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
185  }
186 
187  return frame->n_vectors;
188 }
189 
190 /**
191  * IP4 punt redirect per-rx interface configuration
192  * redirect punted traffic to another location.
193  */
195 {
196  /**
197  * Node linkage into the FIB graph
198  */
200 
205 
206  /**
207  * redirect forwarding
208  */
211 
212 /**
213  * IP punt redirect configuration
214  */
215 typedef struct ip_punt_redirect_t_
216 {
218 
219  /**
220  * per-RX interface configuration.
221  * sw_if_index = 0 (from which packets are never received) is used to
222  * indicate 'from-any'
223  */
224  index_t *redirect_by_rx_sw_if_index[FIB_PROTOCOL_IP_MAX];
226 
228 
229 /**
230  * IP punt redirect next nodes
231  */
233 {
239 
240 /**
241  * IP Punt redirect trace
242  */
244 {
248 
249 /**
250  * Add a punt redirect entry
251  */
252 extern void ip_punt_redirect_add (fib_protocol_t fproto,
253  u32 rx_sw_if_index,
255  fib_route_path_t * rpaths);
256 
257 extern void ip_punt_redirect_del (fib_protocol_t fproto, u32 rx_sw_if_index);
259  u32 rx_sw_if_index);
260 extern u8 *format_ip_punt_redirect (u8 * s, va_list * args);
261 
262 extern u8 *format_ip_punt_redirect_trace (u8 * s, va_list * args);
263 
264 typedef walk_rc_t (*ip_punt_redirect_walk_cb_t) (u32 rx_sw_if_index,
265  const ip_punt_redirect_rx_t *
266  redirect, void *arg);
267 extern void ip_punt_redirect_walk (fib_protocol_t fproto,
268  ip_punt_redirect_walk_cb_t cb, void *ctx);
269 
272 {
273  return (pool_elt_at_index (ip_punt_redirect_cfg.pool, rrxi));
274 }
275 
279  vlib_frame_t * frame, u8 arc_index, fib_protocol_t fproto)
280 {
281  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
284  index_t *redirects;
285 
286  from = vlib_frame_vector_args (frame);
287  n_left_from = frame->n_vectors;
288  next_index = node->cached_next_index;
289  redirects = ip_punt_redirect_cfg.redirect_by_rx_sw_if_index[fproto];
290 
291  while (n_left_from > 0)
292  {
293  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
294 
295  while (n_left_from > 0 && n_left_to_next > 0)
296  {
297  u32 rx_sw_if_index0, rrxi0;
298  ip_punt_redirect_rx_t *rrx0;
299  vlib_buffer_t *b0;
300  u32 next0;
301  u32 bi0;
302 
303  rrxi0 = INDEX_INVALID;
304  next0 = 0;
305  bi0 = to_next[0] = from[0];
306 
307  from += 1;
308  n_left_from -= 1;
309  to_next += 1;
310  n_left_to_next -= 1;
311 
312  b0 = vlib_get_buffer (vm, bi0);
313 
315  &b0->current_config_index, &next0, 0);
316 
317  rx_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
318 
319  /*
320  * If config exists for this particular RX interface use it,
321  * else use the default (at RX = 0)
322  */
323  if (vec_len (redirects) > rx_sw_if_index0)
324  {
325  rrxi0 = redirects[rx_sw_if_index0];
326  if (INDEX_INVALID == rrxi0)
327  rrxi0 = redirects[0];
328  }
329  else if (vec_len (redirects) >= 1)
330  rrxi0 = redirects[0];
331 
332  if (PREDICT_TRUE (INDEX_INVALID != rrxi0))
333  {
334  rrx0 = ip_punt_redirect_get (rrxi0);
335  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = rrx0->dpo.dpoi_index;
336  next0 = rrx0->dpo.dpoi_next_node;
337  }
338 
339  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
340  {
342  vlib_add_trace (vm, node, b0, sizeof (*t));
343  t->next = next0;
344  t->rrxi = rrxi0;
345  }
346 
347  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
348  n_left_to_next, bi0, next0);
349  }
350 
351  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
352  }
353 
354  return frame->n_vectors;
355 }
356 
360  vlib_frame_t * frame, u8 arc_index)
361 {
362  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
363 
364  from = vlib_frame_vector_args (frame);
365  n_left_from = frame->n_vectors;
366  next_index = node->cached_next_index;
367 
368  while (n_left_from > 0)
369  {
370  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
371 
372  while (n_left_from >= 8 && n_left_to_next >= 4)
373  {
374  vlib_buffer_t *b0, *b1, *b2, *b3;
375  u32 next0, next1, next2, next3;
376  u32 bi0, bi1, bi2, bi3;
377 
378  next0 = next1 = next2 = next3 = 0;
379 
380  /* Prefetch next iteration. */
381  {
382  vlib_buffer_t *p4, *p5, *p6, *p7;
383 
384  p4 = vlib_get_buffer (vm, from[4]);
385  p5 = vlib_get_buffer (vm, from[5]);
386  p6 = vlib_get_buffer (vm, from[6]);
387  p7 = vlib_get_buffer (vm, from[7]);
388 
389  vlib_prefetch_buffer_header (p4, LOAD);
390  vlib_prefetch_buffer_header (p5, LOAD);
391  vlib_prefetch_buffer_header (p6, LOAD);
392  vlib_prefetch_buffer_header (p7, LOAD);
393  }
394 
395  bi0 = to_next[0] = from[0];
396  bi1 = to_next[1] = from[1];
397  bi2 = to_next[2] = from[2];
398  bi3 = to_next[3] = from[3];
399 
400  from += 4;
401  n_left_from -= 4;
402  to_next += 4;
403  n_left_to_next -= 4;
404 
405  b0 = vlib_get_buffer (vm, bi0);
406  b1 = vlib_get_buffer (vm, bi1);
407  b2 = vlib_get_buffer (vm, bi2);
408  b3 = vlib_get_buffer (vm, bi3);
409 
410  /* punt and drop features are not associated with a given interface
411  * so the special index 0 is used */
412  vnet_feature_arc_start (arc_index, 0, &next0, b0);
413  vnet_feature_arc_start (arc_index, 0, &next1, b1);
414  vnet_feature_arc_start (arc_index, 0, &next2, b2);
415  vnet_feature_arc_start (arc_index, 0, &next3, b3);
416 
417  vlib_validate_buffer_enqueue_x4 (vm, node, next_index,
418  to_next, n_left_to_next,
419  bi0, bi1, bi2, bi3,
420  next0, next1, next2, next3);
421  }
422 
423  while (n_left_from > 0 && n_left_to_next > 0)
424  {
425  vlib_buffer_t *b0;
426  u32 next0;
427  u32 bi0;
428 
429  next0 = 0;
430  bi0 = to_next[0] = from[0];
431 
432  from += 1;
433  n_left_from -= 1;
434  to_next += 1;
435  n_left_to_next -= 1;
436 
437  b0 = vlib_get_buffer (vm, bi0);
438 
439  vnet_feature_arc_start (arc_index, 0, &next0, b0);
440 
441  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
442  n_left_to_next, bi0, next0);
443  }
444  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
445  }
446 
447  return frame->n_vectors;
448 }
449 
450 #endif
451 
452 /*
453  * fd.io coding-style-patch-verification: ON
454  *
455  * Local Variables:
456  * eval: (c-set-style "gnu")
457  * End:
458  */
vnet_config_main_t config_main
Definition: feature.h:82
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:124
ip_punt_redirect_rx_t * pool
Definition: ip_punt_drop.h:217
index_t ip_punt_redirect_find(fib_protocol_t fproto, u32 rx_sw_if_index)
Definition: ip_punt_drop.c:61
#define POLICER_TICKS_PER_PERIOD_SHIFT
Definition: police.h:57
A representation of a path as described by a route producer.
Definition: fib_types.h:500
fib_protocol_t fproto
Definition: ip_punt_drop.h:201
#define PREDICT_TRUE(x)
Definition: clib.h:122
unsigned long u64
Definition: types.h:89
u8 * format_ip_punt_policer_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:39
#define FIB_PROTOCOL_IP_MAX
Definition outside of enum so it does not need to be included in non-defaulted switch statements...
Definition: fib_types.h:57
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
static u64 clib_cpu_time_now(void)
Definition: time.h:81
#define vlib_validate_buffer_enqueue_x4(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, bi2, bi3, next0, next1, next2, next3)
Finish enqueueing four buffers forward in the graph.
Definition: buffer_node.h:140
static uword ip_drop_or_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 arc_index)
Definition: ip_punt_drop.h:358
vlib_main_t * vm
Definition: in2out_ed.c:1580
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:470
u8 * format_ip_punt_redirect(u8 *s, va_list *args)
Definition: ip_punt_drop.c:131
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define fm
enum walk_rc_t_ walk_rc_t
Walk return code.
struct ip_punt_policer_t_ ip_punt_policer_t
IP4 punt policer configuration we police the punt rate to prevent overloading the host...
#define static_always_inline
Definition: clib.h:109
ip_punt_redirect_next_t_
IP punt redirect next nodes.
Definition: ip_punt_drop.h:232
fib_forward_chain_type_t payload_type
Definition: ip_punt_drop.h:202
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:207
fib_node_index_t pl
Definition: ip_punt_drop.h:203
u8 * format_ip_punt_redirect_trace(u8 *s, va_list *args)
Definition: ip_punt_drop.c:25
struct ip4_punt_redirect_trace_t_ ip_punt_redirect_trace_t
IP Punt redirect trace.
unsigned int u32
Definition: types.h:88
#define foreach_ip_punt_policer_error
Definition: ip_punt_drop.h:44
IP punt redirect configuration.
Definition: ip_punt_drop.h:215
void ip_punt_redirect_del(fib_protocol_t fproto, u32 rx_sw_if_index)
Definition: ip_punt_drop.c:107
static uword ip_punt_policer(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 arc_index, u32 policer_index)
IP punt policing node function.
Definition: ip_punt_drop.h:61
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
fib_node_t node
Node linkage into the FIB graph.
Definition: ip_punt_drop.h:199
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
long ctx[MAX_CONNS]
Definition: main.c:144
void ip_punt_redirect_add(fib_protocol_t fproto, u32 rx_sw_if_index, fib_forward_chain_type_t ct, fib_route_path_t *rpaths)
Add a punt redirect entry.
Definition: ip_punt_drop.c:74
static void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
Definition: config.h:123
#define PREDICT_FALSE(x)
Definition: clib.h:121
#define always_inline
Definition: ipsec.h:28
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
#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:224
An node in the FIB graph.
Definition: fib_node.h:295
#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:391
IP Punt redirect trace.
Definition: ip_punt_drop.h:243
u16 n_vectors
Definition: node.h:397
static_always_inline ip_punt_redirect_rx_t * ip_punt_redirect_get(index_t rrxi)
Definition: ip_punt_drop.h:271
IP4 punt redirect per-rx interface configuration redirect punted traffic to another location...
Definition: ip_punt_drop.h:194
dpo_id_t dpo
redirect forwarding
Definition: ip_punt_drop.h:209
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
Definition: buffer.h:147
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:483
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
struct ip_punt_redirect_t_ ip_punt_redirect_cfg_t
IP punt redirect configuration.
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:511
IP4 punt policer configuration we police the punt rate to prevent overloading the host...
Definition: ip_punt_drop.h:27
enum fib_forward_chain_type_t_ fib_forward_chain_type_t
FIB output chain type.
walk_rc_t(* ip_punt_redirect_walk_cb_t)(u32 rx_sw_if_index, const ip_punt_redirect_rx_t *redirect, void *arg)
Definition: ip_punt_drop.h:264
static_always_inline u8 vnet_policer_police(vlib_main_t *vm, vlib_buffer_t *b, u32 policer_index, u64 time_in_policer_periods, policer_result_e packet_color)
struct ip_punt_policer_trace_t_ ip_punt_policer_trace_t
struct ip_punt_redirect_rx_t_ ip_punt_redirect_rx_t
IP4 punt redirect per-rx interface configuration redirect punted traffic to another location...
static uword ip_punt_redirect(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 arc_index, fib_protocol_t fproto)
Definition: ip_punt_drop.h:277
Definition: defs.h:47
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:188
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
enum ip_punt_policer_next_t_ ip_punt_policer_next_t
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1581
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:297
#define vnet_buffer(b)
Definition: buffer.h:417
index_t * redirect_by_rx_sw_if_index[FIB_PROTOCOL_IP_MAX]
per-RX interface configuration.
Definition: ip_punt_drop.h:224
ip_punt_policer_next_t_
Definition: ip_punt_drop.h:32
ip_punt_policer_error_t
Definition: ip_punt_drop.h:47
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:634
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:184
vnet_feature_config_main_t * feature_config_mains
feature config main objects
Definition: feature.h:100
vnet_feature_main_t feature_main
Definition: feature.c:18
enum ip_punt_redirect_next_t_ ip_punt_redirect_next_t
IP punt redirect next nodes.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
ip_punt_redirect_cfg_t ip_punt_redirect_cfg
Definition: ip_punt_drop.c:22
Definition: defs.h:46
void ip_punt_redirect_walk(fib_protocol_t fproto, ip_punt_redirect_walk_cb_t cb, void *ctx)
Definition: ip_punt_drop.c:160
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302