FD.io VPP  v18.04-17-g3a0d853
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  */
62  vlib_node_runtime_t * node,
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  * The next-hop to send redirected packets to
198  */
199  ip46_address_t nh;
200 
201  /**
202  * the TX interface to send redirected packets
203  */
205 
206  /**
207  * redirect forwarding adjacency
208  */
211 
212 /**
213  * IP punt redirect configuration
214  */
215 typedef struct ip_punt_redirect_t_
216 {
217  /**
218  * any RX interface redirect
219  */
221 
222  /**
223  * per-RX interface configuration
224  */
227 
228 /**
229  * IP punt redirect next nodes
230  */
232 {
238 
239 /**
240  * IP Punt redirect trace
241  */
243 {
247 
248 /**
249  * Add a punt redirect entry
250  */
251 extern void ip_punt_redirect_add (ip_punt_redirect_t * cfg,
252  u32 rx_sw_if_index,
253  ip_punt_redirect_rx_t * redirect,
254  fib_protocol_t fproto, vnet_link_t linkt);
255 extern void ip_punt_redirect_del (ip_punt_redirect_t * cfg,
256  u32 rx_sw_if_index);
257 extern u8 *format_ip_punt_redirect (u8 * s, va_list * args);
258 
259 extern u8 *format_ip_punt_redirect_trace (u8 * s, va_list * args);
260 
263 {
264  ip_adjacency_t *adj = adj_get (ai);
265  u32 next0;
266 
267  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ai;
268 
269  switch (adj->lookup_next_index)
270  {
271  case IP_LOOKUP_NEXT_ARP:
273  break;
275  next0 = IP_PUNT_REDIRECT_NEXT_TX;
276  break;
277  default:
279  break;
280  }
281 
282  return (next0);
283 }
284 
287  vlib_node_runtime_t * node,
288  vlib_frame_t * frame,
289  u8 arc_index, ip_punt_redirect_t * redirect)
290 {
291  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
293  vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc_index];
294 
295  from = vlib_frame_vector_args (frame);
296  n_left_from = frame->n_vectors;
297  next_index = node->cached_next_index;
298 
299  while (n_left_from > 0)
300  {
301  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
302 
303  while (n_left_from > 0 && n_left_to_next > 0)
304  {
305  u32 rx_sw_if_index0;
306  ip_punt_redirect_rx_t *rrx0;
307  vlib_buffer_t *b0;
308  u32 next0;
309  u32 bi0;
310 
311  rrx0 = NULL;
312  next0 = 0;
313  bi0 = to_next[0] = from[0];
314 
315  from += 1;
316  n_left_from -= 1;
317  to_next += 1;
318  n_left_to_next -= 1;
319 
320  b0 = vlib_get_buffer (vm, bi0);
321 
323  &b0->current_config_index, &next0, 0);
324 
325  rx_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
326 
327  if (vec_len (redirect->redirect_by_rx_sw_if_index) >
328  rx_sw_if_index0)
329  {
330  rrx0 = &redirect->redirect_by_rx_sw_if_index[rx_sw_if_index0];
331  if (~0 != rrx0->tx_sw_if_index)
332  {
333  next0 = ip_punt_redirect_tx_via_adj (b0, rrx0->adj_index);
334  }
335  else if (~0 != redirect->any_rx_sw_if_index.tx_sw_if_index)
336  {
337  rrx0 = &redirect->any_rx_sw_if_index;
338  next0 = ip_punt_redirect_tx_via_adj (b0, rrx0->adj_index);
339  }
340  }
341  else if (~0 != redirect->any_rx_sw_if_index.tx_sw_if_index)
342  {
343  rrx0 = &redirect->any_rx_sw_if_index;
344  next0 = ip_punt_redirect_tx_via_adj (b0, rrx0->adj_index);
345  }
346 
347  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
348  {
350  vlib_add_trace (vm, node, b0, sizeof (*t));
351  t->next = next0;
352  if (rrx0)
353  t->redirect = *rrx0;
354  }
355 
356  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
357  n_left_to_next, bi0, next0);
358  }
359 
360  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
361  }
362 
363  return frame->n_vectors;
364 }
365 
368  vlib_node_runtime_t * node,
369  vlib_frame_t * frame, u8 arc_index)
370 {
371  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
372 
373  from = vlib_frame_vector_args (frame);
374  n_left_from = frame->n_vectors;
375  next_index = node->cached_next_index;
376 
377  while (n_left_from > 0)
378  {
379  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
380 
381  while (n_left_from >= 8 && n_left_to_next >= 4)
382  {
383  vlib_buffer_t *b0, *b1, *b2, *b3;
384  u32 next0, next1, next2, next3;
385  u32 bi0, bi1, bi2, bi3;
386 
387  next0 = next1 = next2 = next3 = 0;
388 
389  /* Prefetch next iteration. */
390  {
391  vlib_buffer_t *p4, *p5, *p6, *p7;
392 
393  p4 = vlib_get_buffer (vm, from[4]);
394  p5 = vlib_get_buffer (vm, from[5]);
395  p6 = vlib_get_buffer (vm, from[6]);
396  p7 = vlib_get_buffer (vm, from[7]);
397 
398  vlib_prefetch_buffer_header (p4, LOAD);
399  vlib_prefetch_buffer_header (p5, LOAD);
400  vlib_prefetch_buffer_header (p6, LOAD);
401  vlib_prefetch_buffer_header (p7, LOAD);
402  }
403 
404  bi0 = to_next[0] = from[0];
405  bi1 = to_next[1] = from[1];
406  bi2 = to_next[2] = from[2];
407  bi3 = to_next[3] = from[3];
408 
409  from += 4;
410  n_left_from -= 4;
411  to_next += 4;
412  n_left_to_next -= 4;
413 
414  b0 = vlib_get_buffer (vm, bi0);
415  b1 = vlib_get_buffer (vm, bi1);
416  b2 = vlib_get_buffer (vm, bi2);
417  b3 = vlib_get_buffer (vm, bi3);
418 
419  /* punt and drop features are not associated with a given interface
420  * so the special index 0 is used */
421  vnet_feature_arc_start (arc_index, 0, &next0, b0);
422  vnet_feature_arc_start (arc_index, 0, &next1, b1);
423  vnet_feature_arc_start (arc_index, 0, &next2, b2);
424  vnet_feature_arc_start (arc_index, 0, &next3, b3);
425 
426  vlib_validate_buffer_enqueue_x4 (vm, node, next_index,
427  to_next, n_left_to_next,
428  bi0, bi1, bi2, bi3,
429  next0, next1, next2, next3);
430  }
431 
432  while (n_left_from > 0 && n_left_to_next > 0)
433  {
434  vlib_buffer_t *b0;
435  u32 next0;
436  u32 bi0;
437 
438  next0 = 0;
439  bi0 = to_next[0] = from[0];
440 
441  from += 1;
442  n_left_from -= 1;
443  to_next += 1;
444  n_left_to_next -= 1;
445 
446  b0 = vlib_get_buffer (vm, bi0);
447 
448  vnet_feature_arc_start (arc_index, 0, &next0, b0);
449 
450  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
451  n_left_to_next, bi0, next0);
452  }
453  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
454  }
455 
456  return frame->n_vectors;
457 }
458 
459 #endif
460 
461 /*
462  * fd.io coding-style-patch-verification: ON
463  *
464  * Local Variables:
465  * eval: (c-set-style "gnu")
466  * End:
467  */
vnet_config_main_t config_main
Definition: feature.h:65
#define POLICER_TICKS_PER_PERIOD_SHIFT
Definition: police.h:57
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
Definition: buffer.h:133
u8 * format_ip_punt_policer_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:36
#define NULL
Definition: clib.h:55
IP unicast adjacency.
Definition: adj.h:175
ip_punt_redirect_rx_t * redirect_by_rx_sw_if_index
per-RX interface configuration
Definition: ip_punt_drop.h:225
This packet is to be rewritten and forwarded to the next processing node.
Definition: adj.h:73
static u64 clib_cpu_time_now(void)
Definition: time.h:73
#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:138
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:367
void ip_punt_redirect_del(ip_punt_redirect_t *cfg, u32 rx_sw_if_index)
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:415
u8 * format_ip_punt_redirect(u8 *s, va_list *args)
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
struct ip_punt_policer_t_ ip_punt_policer_t
IP4 punt policer configuration we police the punt rate to prevent overloading the host...
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:376
ip_punt_redirect_next_t_
IP punt redirect next nodes.
Definition: ip_punt_drop.h:231
#define always_inline
Definition: clib.h:92
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:191
unsigned long u64
Definition: types.h:89
ip46_address_t nh
The next-hop to send redirected packets to.
Definition: ip_punt_drop.h:199
u8 * format_ip_punt_redirect_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:91
struct ip4_punt_redirect_trace_t_ ip_punt_redirect_trace_t
IP Punt redirect trace.
#define foreach_ip_punt_policer_error
Definition: ip_punt_drop.h:44
IP punt redirect configuration.
Definition: ip_punt_drop.h:215
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
ip_punt_redirect_rx_t redirect
Definition: ip_punt_drop.h:244
static u32 ip_punt_redirect_tx_via_adj(vlib_buffer_t *b0, adj_index_t ai)
Definition: ip_punt_drop.h:262
static void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
Definition: config.h:122
#define PREDICT_FALSE(x)
Definition: clib.h:105
#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: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
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:130
static uword ip_punt_redirect(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 arc_index, ip_punt_redirect_t *redirect)
Definition: ip_punt_drop.h:286
IP Punt redirect trace.
Definition: ip_punt_drop.h:242
This packet matches an "incomplete adjacency" and packets need to be passed to ARP to find rewrite st...
Definition: adj.h:63
ip_punt_redirect_rx_t any_rx_sw_if_index
any RX interface redirect
Definition: ip_punt_drop.h:220
u16 n_vectors
Definition: node.h:344
vlib_main_t * vm
Definition: buffer.c:294
IP4 punt redirect per-rx interface configuration redirect punted traffic to another location...
Definition: ip_punt_drop.h:194
u32 tx_sw_if_index
the TX interface to send redirected packets
Definition: ip_punt_drop.h:204
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
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
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:456
unsigned int u32
Definition: types.h:88
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
IP4 punt policer configuration we police the punt rate to prevent overloading the host...
Definition: ip_punt_drop.h:27
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...
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
Definition: defs.h:47
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
ip_lookup_next_t lookup_next_index
Next hop after ip4-lookup.
Definition: adj.h:190
enum ip_punt_policer_next_t_ ip_punt_policer_next_t
void ip_punt_redirect_add(ip_punt_redirect_t *cfg, u32 rx_sw_if_index, ip_punt_redirect_rx_t *redirect, fib_protocol_t fproto, vnet_link_t linkt)
Add a punt redirect entry.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
#define vnet_buffer(b)
Definition: buffer.h:372
ip_punt_policer_next_t_
Definition: ip_punt_drop.h:32
ip_punt_policer_error_t
Definition: ip_punt_drop.h:47
vnet_feature_config_main_t * feature_config_mains
feature config main objects
Definition: feature.h:81
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:111
vnet_feature_main_t feature_main
Definition: feature.c:19
adj_index_t adj_index
redirect forwarding adjacency
Definition: ip_punt_drop.h:209
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:57
struct ip_punt_redirect_t_ ip_punt_redirect_t
IP punt redirect configuration.
Definition: defs.h:46
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:201