FD.io VPP  v19.04-6-g6f05f72
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 
249 {
250  /**
251  * the RX interface
252  */
254  /**
255  * IP punt redirect configuration
256  */
259 
260 /**
261  * Add a punt redirect entry
262  */
263 extern void ip_punt_redirect_add (ip_punt_redirect_t * cfg,
264  u32 rx_sw_if_index,
265  ip_punt_redirect_rx_t * redirect,
266  fib_protocol_t fproto, vnet_link_t linkt);
267 extern void ip_punt_redirect_del (ip_punt_redirect_t * cfg,
268  u32 rx_sw_if_index);
269 extern u8 *format_ip_punt_redirect (u8 * s, va_list * args);
270 
271 extern u8 *format_ip_punt_redirect_trace (u8 * s, va_list * args);
272 
275 
278 {
279  ip_adjacency_t *adj = adj_get (ai);
280  u32 next0;
281 
282  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ai;
283 
284  switch (adj->lookup_next_index)
285  {
286  case IP_LOOKUP_NEXT_ARP:
288  break;
290  next0 = IP_PUNT_REDIRECT_NEXT_TX;
291  break;
292  default:
294  break;
295  }
296 
297  return (next0);
298 }
299 
302  vlib_node_runtime_t * node,
303  vlib_frame_t * frame,
304  u8 arc_index, ip_punt_redirect_t * redirect)
305 {
306  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
308  vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc_index];
309 
310  from = vlib_frame_vector_args (frame);
311  n_left_from = frame->n_vectors;
312  next_index = node->cached_next_index;
313 
314  while (n_left_from > 0)
315  {
316  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
317 
318  while (n_left_from > 0 && n_left_to_next > 0)
319  {
320  u32 rx_sw_if_index0;
321  ip_punt_redirect_rx_t *rrx0;
322  vlib_buffer_t *b0;
323  u32 next0;
324  u32 bi0;
325 
326  rrx0 = NULL;
327  next0 = 0;
328  bi0 = to_next[0] = from[0];
329 
330  from += 1;
331  n_left_from -= 1;
332  to_next += 1;
333  n_left_to_next -= 1;
334 
335  b0 = vlib_get_buffer (vm, bi0);
336 
338  &b0->current_config_index, &next0, 0);
339 
340  rx_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
341 
342  if (vec_len (redirect->redirect_by_rx_sw_if_index) >
343  rx_sw_if_index0)
344  {
345  rrx0 = &redirect->redirect_by_rx_sw_if_index[rx_sw_if_index0];
346  if (~0 != rrx0->tx_sw_if_index)
347  {
348  next0 = ip_punt_redirect_tx_via_adj (b0, rrx0->adj_index);
349  }
350  else if (~0 != redirect->any_rx_sw_if_index.tx_sw_if_index)
351  {
352  rrx0 = &redirect->any_rx_sw_if_index;
353  next0 = ip_punt_redirect_tx_via_adj (b0, rrx0->adj_index);
354  }
355  }
356  else if (~0 != redirect->any_rx_sw_if_index.tx_sw_if_index)
357  {
358  rrx0 = &redirect->any_rx_sw_if_index;
359  next0 = ip_punt_redirect_tx_via_adj (b0, rrx0->adj_index);
360  }
361 
362  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
363  {
365  vlib_add_trace (vm, node, b0, sizeof (*t));
366  t->next = next0;
367  if (rrx0)
368  t->redirect = *rrx0;
369  }
370 
371  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
372  n_left_to_next, bi0, next0);
373  }
374 
375  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
376  }
377 
378  return frame->n_vectors;
379 }
380 
383  vlib_node_runtime_t * node,
384  vlib_frame_t * frame, u8 arc_index)
385 {
386  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
387 
388  from = vlib_frame_vector_args (frame);
389  n_left_from = frame->n_vectors;
390  next_index = node->cached_next_index;
391 
392  while (n_left_from > 0)
393  {
394  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
395 
396  while (n_left_from >= 8 && n_left_to_next >= 4)
397  {
398  vlib_buffer_t *b0, *b1, *b2, *b3;
399  u32 next0, next1, next2, next3;
400  u32 bi0, bi1, bi2, bi3;
401 
402  next0 = next1 = next2 = next3 = 0;
403 
404  /* Prefetch next iteration. */
405  {
406  vlib_buffer_t *p4, *p5, *p6, *p7;
407 
408  p4 = vlib_get_buffer (vm, from[4]);
409  p5 = vlib_get_buffer (vm, from[5]);
410  p6 = vlib_get_buffer (vm, from[6]);
411  p7 = vlib_get_buffer (vm, from[7]);
412 
413  vlib_prefetch_buffer_header (p4, LOAD);
414  vlib_prefetch_buffer_header (p5, LOAD);
415  vlib_prefetch_buffer_header (p6, LOAD);
416  vlib_prefetch_buffer_header (p7, LOAD);
417  }
418 
419  bi0 = to_next[0] = from[0];
420  bi1 = to_next[1] = from[1];
421  bi2 = to_next[2] = from[2];
422  bi3 = to_next[3] = from[3];
423 
424  from += 4;
425  n_left_from -= 4;
426  to_next += 4;
427  n_left_to_next -= 4;
428 
429  b0 = vlib_get_buffer (vm, bi0);
430  b1 = vlib_get_buffer (vm, bi1);
431  b2 = vlib_get_buffer (vm, bi2);
432  b3 = vlib_get_buffer (vm, bi3);
433 
434  /* punt and drop features are not associated with a given interface
435  * so the special index 0 is used */
436  vnet_feature_arc_start (arc_index, 0, &next0, b0);
437  vnet_feature_arc_start (arc_index, 0, &next1, b1);
438  vnet_feature_arc_start (arc_index, 0, &next2, b2);
439  vnet_feature_arc_start (arc_index, 0, &next3, b3);
440 
441  vlib_validate_buffer_enqueue_x4 (vm, node, next_index,
442  to_next, n_left_to_next,
443  bi0, bi1, bi2, bi3,
444  next0, next1, next2, next3);
445  }
446 
447  while (n_left_from > 0 && n_left_to_next > 0)
448  {
449  vlib_buffer_t *b0;
450  u32 next0;
451  u32 bi0;
452 
453  next0 = 0;
454  bi0 = to_next[0] = from[0];
455 
456  from += 1;
457  n_left_from -= 1;
458  to_next += 1;
459  n_left_to_next -= 1;
460 
461  b0 = vlib_get_buffer (vm, bi0);
462 
463  vnet_feature_arc_start (arc_index, 0, &next0, b0);
464 
465  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
466  n_left_to_next, bi0, next0);
467  }
468  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
469  }
470 
471  return frame->n_vectors;
472 }
473 
474 #endif
475 
476 /*
477  * fd.io coding-style-patch-verification: ON
478  *
479  * Local Variables:
480  * eval: (c-set-style "gnu")
481  * End:
482  */
vnet_config_main_t config_main
Definition: feature.h:82
u32 sw_if_index
Definition: ipsec_gre.api:37
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 punt_redirect
IP punt redirect configuration.
Definition: ip_punt_drop.h:257
#define POLICER_TICKS_PER_PERIOD_SHIFT
Definition: police.h:57
unsigned long u64
Definition: types.h:89
u8 * format_ip_punt_policer_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:41
#define NULL
Definition: clib.h:58
ip_punt_redirect_detail_t * ip6_punt_redirect_entries(u32 sw_if_index)
IP unicast adjacency.
Definition: adj.h:221
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:75
#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:382
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:469
u8 * format_ip_punt_redirect(u8 *s, va_list *args)
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define fm
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:433
ip_punt_redirect_next_t_
IP punt redirect next nodes.
Definition: ip_punt_drop.h:231
#define always_inline
Definition: clib.h:98
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
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:94
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
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
ip_punt_redirect_rx_t redirect
Definition: ip_punt_drop.h:244
struct ip_punt_redirect_detail_t_ ip_punt_redirect_detail_t
static u32 ip_punt_redirect_tx_via_adj(vlib_buffer_t *b0, adj_index_t ai)
Definition: ip_punt_drop.h:277
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:111
#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:368
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:301
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:395
vlib_main_t * vm
Definition: buffer.c:312
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 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
Definition: buffer.h:147
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:465
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:514
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...
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:57
ip_punt_redirect_detail_t * ip4_punt_redirect_entries(u32 sw_if_index)
Definition: defs.h:47
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
ip_lookup_next_t lookup_next_index
Next hop after ip4-lookup.
Definition: adj.h:236
enum ip_punt_policer_next_t_ ip_punt_policer_next_t
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
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:274
u32 rx_sw_if_index
the RX interface
Definition: ip_punt_drop.h:253
#define vnet_buffer(b)
Definition: buffer.h:369
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:100
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:85
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:275