FD.io VPP  v19.04.1-1-ge4a0f9f
Vector Packet Processing
ip6_punt_drop.c
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 #include <vnet/ip/ip.h>
17 #include <vnet/ip/ip_punt_drop.h>
18 #include <vnet/policer/policer.h>
20 
21 /* *INDENT-OFF* */
22 VNET_FEATURE_ARC_INIT (ip6_punt) =
23 {
24  .arc_name = "ip6-punt",
25  .start_nodes = VNET_FEATURES ("ip6-punt"),
26 };
27 
28 VNET_FEATURE_ARC_INIT (ip6_drop) =
29 {
30  .arc_name = "ip6-drop",
31  .start_nodes = VNET_FEATURES ("ip6-drop", "ip6-not-enabled"),
32 };
33 /* *INDENT-ON* */
34 
36 
37 #ifndef CLIB_MARCH_VARIANT
39 #endif /* CLIB_MARCH_VARIANT */
40 
42 #define _(sym,string) string,
44 #undef _
45 };
46 
48  vlib_node_runtime_t * node,
49  vlib_frame_t * frame)
50 {
51  return (ip_punt_policer (vm, node, frame,
52  vnet_feat_arc_ip6_punt.feature_arc_index,
53  ip6_punt_policer_cfg.policer_index));
54 }
55 
56 
57 /* *INDENT-OFF* */
58 
60  .name = "ip6-punt-policer",
61  .vector_size = sizeof (u32),
62  .n_next_nodes = IP_PUNT_POLICER_N_NEXT,
63  .format_trace = format_ip_punt_policer_trace,
65  .error_strings = ip6_punt_policer_error_strings,
66 
67  /* edit / add dispositions here */
68  .next_nodes = {
69  [IP_PUNT_POLICER_NEXT_DROP] = "ip6-drop",
70  },
71 };
72 
74  .arc_name = "ip6-punt",
75  .node_name = "ip6-punt-policer",
76  .runs_before = VNET_FEATURES("ip6-punt-redirect")
77 };
78 /* *INDENT-ON* */
79 
81  vlib_frame_t * frame)
82 {
83  if (node->flags & VLIB_NODE_FLAG_TRACE)
84  ip6_forward_next_trace (vm, node, frame, VLIB_TX);
85 
86  return ip_drop_or_punt (vm, node, frame,
87  vnet_feat_arc_ip6_drop.feature_arc_index);
88 
89 }
90 
92  vlib_node_runtime_t * node,
93  vlib_frame_t * frame)
94 {
95  if (node->flags & VLIB_NODE_FLAG_TRACE)
96  ip6_forward_next_trace (vm, node, frame, VLIB_TX);
97 
98  return ip_drop_or_punt (vm, node, frame,
99  vnet_feat_arc_ip6_drop.feature_arc_index);
100 
101 }
102 
104  vlib_frame_t * frame)
105 {
106  if (node->flags & VLIB_NODE_FLAG_TRACE)
107  ip6_forward_next_trace (vm, node, frame, VLIB_TX);
108 
109  return ip_drop_or_punt (vm, node, frame,
110  vnet_feat_arc_ip6_punt.feature_arc_index);
111 }
112 
113 /* *INDENT-OFF* */
115 {
116  .name = "ip6-drop",
117  .vector_size = sizeof (u32),
118  .format_trace = format_ip6_forward_next_trace,
119  .n_next_nodes = 1,
120  .next_nodes = {
121  [0] = "error-drop",
122  },
123 };
124 
126 {
127  .name = "ip6-not-enabled",
128  .vector_size = sizeof (u32),
129  .format_trace = format_ip6_forward_next_trace,
130  .n_next_nodes = 1,
131  .next_nodes = {
132  [0] = "error-drop",
133  },
134 };
135 
137 {
138  .name = "ip6-punt",
139  .vector_size = sizeof (u32),
140  .format_trace = format_ip6_forward_next_trace,
141  .n_next_nodes = 1,
142  .next_nodes = {
143  [0] = "error-punt",
144  },
145 };
146 
147 VNET_FEATURE_INIT (ip6_punt_end_of_arc, static) = {
148  .arc_name = "ip6-punt",
149  .node_name = "error-punt",
150  .runs_before = 0, /* not before any other features */
151 };
152 
153 VNET_FEATURE_INIT (ip6_drop_end_of_arc, static) = {
154  .arc_name = "ip6-drop",
155  .node_name = "error-drop",
156  .runs_before = 0, /* not before any other features */
157 };
158 /* *INDENT-ON */
159 
160 #ifndef CLIB_MARCH_VARIANT
161 void
163 {
164  ip6_punt_policer_cfg.policer_index = policer_index;
165 
166  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-policer",
167  0, is_add, 0, 0);
168 }
169 #endif /* CLIB_MARCH_VARIANT */
170 
171 static clib_error_t *
173  unformat_input_t * main_input,
174  vlib_cli_command_t * cmd)
175 {
176  unformat_input_t _line_input, *line_input = &_line_input;
177  clib_error_t *error = 0;
178  u32 policer_index;
179  u8 is_add = 1;
180 
181  policer_index = ~0;
182 
183  if (!unformat_user (main_input, unformat_line_input, line_input))
184  return 0;
185 
186  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
187  {
188  if (unformat (line_input, "%d", &policer_index))
189  ;
190  else if (unformat (line_input, "del"))
191  is_add = 0;
192  else if (unformat (line_input, "add"))
193  is_add = 1;
194  else
195  {
196  error = unformat_parse_error (line_input);
197  goto done;
198  }
199  }
200 
201  if (is_add && ~0 == policer_index)
202  {
203  error = clib_error_return (0, "expected policer index `%U'",
204  format_unformat_error, line_input);
205  goto done;
206  }
207  if (!is_add)
208  policer_index = ~0;
209 
210  ip6_punt_policer_add_del(is_add, policer_index);
211 
212 done:
213  unformat_free (line_input);
214  return (error);
215 }
216 
217 /*?
218  *
219  * @cliexpar
220  * @cliexcmd{set ip punt policer <INDEX>}
221  ?*/
222 /* *INDENT-OFF* */
223 VLIB_CLI_COMMAND (ip6_punt_policer_command, static) =
224 {
225  .path = "ip6 punt policer",
226  .function = ip6_punt_police_cmd,
227  .short_help = "ip6 punt policer [add|del] <index>",
228 };
229 
231 
232 #ifndef CLIB_MARCH_VARIANT
233 ip_punt_redirect_t ip6_punt_redirect_cfg = {
234  .any_rx_sw_if_index = {
235  .tx_sw_if_index = ~0,
236  .adj_index = ADJ_INDEX_INVALID,
237  },
238 };
239 #endif /* CLIB_MARCH_VARIANT */
240 /* *INDENT-ON* */
241 
242 #define foreach_ip6_punt_redirect_error \
243 _(DROP, "ip6 punt redirect drop")
244 
245 typedef enum
246 {
247 #define _(sym,str) IP6_PUNT_REDIRECT_ERROR_##sym,
249 #undef _
252 
254 #define _(sym,string) string,
256 #undef _
257 };
258 
260  vlib_node_runtime_t * node,
261  vlib_frame_t * frame)
262 {
263  return (ip_punt_redirect (vm, node, frame,
264  vnet_feat_arc_ip6_punt.feature_arc_index,
265  &ip6_punt_redirect_cfg));
266 }
267 
268 /* *INDENT-OFF* */
270  .name = "ip6-punt-redirect",
271  .vector_size = sizeof (u32),
272  .n_next_nodes = IP_PUNT_REDIRECT_N_NEXT,
273  .format_trace = format_ip_punt_redirect_trace,
275  .error_strings = ip6_punt_redirect_error_strings,
276 
277  /* edit / add dispositions here */
278  .next_nodes = {
279  [IP_PUNT_REDIRECT_NEXT_DROP] = "ip6-drop",
280  [IP_PUNT_REDIRECT_NEXT_TX] = "ip6-rewrite",
281  [IP_PUNT_REDIRECT_NEXT_ARP] = "ip6-discover-neighbor",
282  },
283 };
284 
286  .arc_name = "ip6-punt",
287  .node_name = "ip6-punt-redirect",
288  .runs_before = VNET_FEATURES("error-punt")
289 };
290 /* *INDENT-ON* */
291 
292 #ifndef CLIB_MARCH_VARIANT
293 void
294 ip6_punt_redirect_add (u32 rx_sw_if_index,
295  u32 tx_sw_if_index, ip46_address_t * nh)
296 {
297  ip_punt_redirect_rx_t rx = {
298  .tx_sw_if_index = tx_sw_if_index,
299  .nh = *nh,
300  };
301 
302  ip_punt_redirect_add (&ip6_punt_redirect_cfg,
303  rx_sw_if_index, &rx, FIB_PROTOCOL_IP6, VNET_LINK_IP6);
304 
305  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 1, 0, 0);
306 }
307 
308 void
309 ip6_punt_redirect_del (u32 rx_sw_if_index)
310 {
311  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 0, 0, 0);
312 
313  ip_punt_redirect_del (&ip6_punt_redirect_cfg, rx_sw_if_index);
314 }
315 #endif /* CLIB_MARCH_VARIANT */
316 
317 static clib_error_t *
319  unformat_input_t * main_input,
320  vlib_cli_command_t * cmd)
321 {
322  unformat_input_t _line_input, *line_input = &_line_input;
323  clib_error_t *error = 0;
324  u32 rx_sw_if_index = 0;
325  u32 tx_sw_if_index = 0;
326  ip46_address_t nh;
327  vnet_main_t *vnm;
328  u8 is_add;
329 
330  is_add = 1;
331  vnm = vnet_get_main ();
332 
333  if (!unformat_user (main_input, unformat_line_input, line_input))
334  return 0;
335 
336  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
337  {
338  if (unformat (line_input, "del"))
339  is_add = 0;
340  else if (unformat (line_input, "add"))
341  is_add = 1;
342  else if (unformat (line_input, "rx all"))
343  rx_sw_if_index = ~0;
344  else if (unformat (line_input, "rx %U",
345  unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
346  ;
347  else if (unformat (line_input, "via %U %U",
349  &nh.ip6,
350  unformat_vnet_sw_interface, vnm, &tx_sw_if_index))
351  ;
352  else if (unformat (line_input, "via %U",
353  unformat_vnet_sw_interface, vnm, &tx_sw_if_index))
354  clib_memset (&nh, 0, sizeof (nh));
355  else
356  {
357  error = unformat_parse_error (line_input);
358  goto done;
359  }
360  }
361 
362  if (is_add)
363  {
364  if (rx_sw_if_index && tx_sw_if_index)
365  {
366  ip6_punt_redirect_add (rx_sw_if_index, tx_sw_if_index, &nh);
367  }
368  }
369  else
370  {
371  if (rx_sw_if_index)
372  {
373  ip6_punt_redirect_del (rx_sw_if_index);
374  }
375  }
376 
377 done:
378  unformat_free (line_input);
379  return (error);
380 }
381 
382 /*?
383  *
384  * @cliexpar
385  * @cliexcmd{set ip punt policer <INDEX>}
386  ?*/
387 /* *INDENT-OFF* */
388 VLIB_CLI_COMMAND (ip6_punt_redirect_command, static) =
389 {
390  .path = "ip6 punt redirect",
391  .function = ip6_punt_redirect_cmd,
392  .short_help = "ip6 punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
393 };
394 /* *INDENT-ON* */
395 
396 #ifndef CLIB_MARCH_VARIANT
399 {
401  ip_punt_redirect_detail_t *prs = 0;
402  u32 rx_sw_if_index;
403 
404  vec_foreach_index (rx_sw_if_index,
405  ip6_punt_redirect_cfg.redirect_by_rx_sw_if_index)
406  {
407  if (sw_if_index == ~0 || sw_if_index == rx_sw_if_index)
408  {
409  pr =
410  &ip6_punt_redirect_cfg.redirect_by_rx_sw_if_index[rx_sw_if_index];
411  if (NULL != pr && ~0 != pr->tx_sw_if_index)
412  {
414  rx_sw_if_index,
415  .punt_redirect = *pr
416  };
417  vec_add1 (prs, detail);
418  }
419  }
420  }
421  if (~0 != ip6_punt_redirect_cfg.any_rx_sw_if_index.tx_sw_if_index)
422  {
423  pr = &ip6_punt_redirect_cfg.any_rx_sw_if_index;
424  if (NULL != pr)
425  {
427  rx_sw_if_index,
428  .punt_redirect = *pr
429  };
430  vec_add1 (prs, detail);
431  }
432  }
433 
434  return prs;
435 }
436 #endif /* CLIB_MARCH_VARIANT */
437 
438 static clib_error_t *
440  unformat_input_t * main_input,
441  vlib_cli_command_t * cmd)
442 {
443  vlib_cli_output (vm, "%U", format_ip_punt_redirect, &ip6_punt_redirect_cfg);
444 
445  return (NULL);
446 }
447 
448 /*?
449  *
450  * @cliexpar
451  * @cliexcmd{set ip punt policer <INDEX>}
452  ?*/
453 /* *INDENT-OFF* */
454 VLIB_CLI_COMMAND (show_ip6_punt_redirect_command, static) =
455 {
456  .path = "show ip6 punt redirect",
457  .function = ip6_punt_redirect_show_cmd,
458  .short_help = "show ip6 punt redirect",
459  .is_mp_safe = 1,
460 };
461 /* *INDENT-ON* */
462 
463 /*
464  * fd.io coding-style-patch-verification: ON
465  *
466  * Local Variables:
467  * eval: (c-set-style "gnu")
468  * End:
469  */
u32 sw_if_index
Definition: ipsec_gre.api:37
#define vec_foreach_index(var, v)
Iterate over vector indices.
ip6_punt_redirect_error_t
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
vlib_node_registration_t ip6_punt_redirect_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_redirect_node)
static clib_error_t * ip6_punt_redirect_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
#define NULL
Definition: clib.h:58
vlib_node_registration_t ip6_not_enabled_node
(constructor) VLIB_REGISTER_NODE (ip6_not_enabled_node)
ip_punt_redirect_rx_t * redirect_by_rx_sw_if_index
per-RX interface configuration
Definition: ip_punt_drop.h:225
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
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)
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
unformat_function_t unformat_vnet_sw_interface
#define VLIB_NODE_FN(node)
Definition: node.h:201
unsigned char u8
Definition: types.h:56
void ip6_punt_redirect_del(u32 rx_sw_if_index)
u8 * format_ip_punt_redirect_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:94
void ip6_punt_policer_add_del(u8 is_add, u32 policer_index)
vlib_node_registration_t ip6_drop_node
(constructor) VLIB_REGISTER_NODE (ip6_drop_node)
void ip6_punt_redirect_add(u32 rx_sw_if_index, u32 tx_sw_if_index, ip46_address_t *nh)
static char * ip6_punt_policer_error_strings[]
Definition: ip6_punt_drop.c:41
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
#define foreach_ip_punt_policer_error
Definition: ip_punt_drop.h:44
ip_punt_policer_t ip6_punt_policer_cfg
Definition: ip6_punt_drop.c:38
IP punt redirect configuration.
Definition: ip_punt_drop.h:215
ip_punt_redirect_detail_t * ip6_punt_redirect_entries(u32 sw_if_index)
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_node_registration_t ip6_punt_policer_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_policer_node)
Definition: ip6_punt_drop.c:59
unformat_function_t unformat_line_input
Definition: format.h:282
u8 * format_ip_punt_policer_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:41
#define ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
Definition: adj_types.h:36
struct _unformat_input_t unformat_input_t
static clib_error_t * ip6_punt_redirect_show_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
vlib_node_registration_t ip6_punt_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_node)
unformat_function_t unformat_ip6_address
Definition: format.h:91
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
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
ip_punt_redirect_rx_t any_rx_sw_if_index
any RX interface redirect
Definition: ip_punt_drop.h:220
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
#define ARRAY_LEN(x)
Definition: clib.h:62
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
VNET_FEATURE_INIT(ip6_punt_policer_node, static)
u8 is_add
Definition: ipsec_gre.api:36
#define foreach_ip6_punt_redirect_error
IP4 punt policer configuration we police the punt rate to prevent overloading the host...
Definition: ip_punt_drop.h:27
static char * ip6_punt_redirect_error_strings[]
#define VNET_FEATURES(...)
Definition: feature.h:435
#define unformat_parse_error(input)
Definition: format.h:268
Definition: defs.h:47
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 unformat_free(unformat_input_t *i)
Definition: format.h:162
u32 rx_sw_if_index
the RX interface
Definition: ip_punt_drop.h:253
VNET_FEATURE_ARC_INIT(ip6_punt)
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void ip6_forward_next_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, vlib_rx_or_tx_t which_adj_index)
Definition: ip6_forward.c:855
u8 * format_ip_punt_redirect(u8 *s, va_list *args)
ip_punt_redirect_t ip6_punt_redirect_cfg
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:301
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:274
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
static clib_error_t * ip6_punt_police_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
u8 * format_ip6_forward_next_trace(u8 *s, va_list *args)
Definition: ip6_forward.c:803