FD.io VPP  v19.08-27-gf4dcae4
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
162 ip6_punt_policer_add_del (u8 is_add, u32 policer_index)
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 
230 /* *INDENT-ON* */
231 
232 #define foreach_ip6_punt_redirect_error \
233 _(DROP, "ip6 punt redirect drop")
234 
235 typedef enum
236 {
237 #define _(sym,str) IP6_PUNT_REDIRECT_ERROR_##sym,
239 #undef _
242 
244 #define _(sym,string) string,
246 #undef _
247 };
248 
250  vlib_node_runtime_t * node,
251  vlib_frame_t * frame)
252 {
253  return (ip_punt_redirect (vm, node, frame,
254  vnet_feat_arc_ip6_punt.feature_arc_index,
256 }
257 
258 /* *INDENT-OFF* */
260  .name = "ip6-punt-redirect",
261  .vector_size = sizeof (u32),
262  .n_next_nodes = IP_PUNT_REDIRECT_N_NEXT,
263  .format_trace = format_ip_punt_redirect_trace,
265  .error_strings = ip6_punt_redirect_error_strings,
266 
267  /* edit / add dispositions here */
268  .next_nodes = {
269  [IP_PUNT_REDIRECT_NEXT_DROP] = "ip6-drop",
270  [IP_PUNT_REDIRECT_NEXT_TX] = "ip6-rewrite",
271  [IP_PUNT_REDIRECT_NEXT_ARP] = "ip6-discover-neighbor",
272  },
273 };
274 
276  .arc_name = "ip6-punt",
277  .node_name = "ip6-punt-redirect",
278  .runs_before = VNET_FEATURES("error-punt")
279 };
280 /* *INDENT-ON* */
281 
282 #ifndef CLIB_MARCH_VARIANT
283 
284 void
285 ip6_punt_redirect_add (u32 rx_sw_if_index,
286  u32 tx_sw_if_index, ip46_address_t * nh)
287 {
288  /* *INDENT-OFF* */
289  fib_route_path_t *rpaths = NULL, rpath = {
290  .frp_proto = DPO_PROTO_IP6,
291  .frp_addr = *nh,
292  .frp_sw_if_index = tx_sw_if_index,
293  .frp_weight = 1,
294  .frp_fib_index = ~0,
295  };
296  /* *INDENT-ON* */
297  vec_add1 (rpaths, rpath);
298 
299  ip6_punt_redirect_add_paths (rx_sw_if_index, rpaths);
300 
301  vec_free (rpaths);
302 }
303 
304 void
306 {
308  rx_sw_if_index,
310 
311  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 1, 0, 0);
312 }
313 
314 void
315 ip6_punt_redirect_del (u32 rx_sw_if_index)
316 {
317  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 0, 0, 0);
318 
319  ip_punt_redirect_del (FIB_PROTOCOL_IP6, rx_sw_if_index);
320 }
321 #endif /* CLIB_MARCH_VARIANT */
322 
323 static clib_error_t *
325  unformat_input_t * main_input,
326  vlib_cli_command_t * cmd)
327 {
328  unformat_input_t _line_input, *line_input = &_line_input;
329  fib_route_path_t *rpaths = NULL, rpath;
330  dpo_proto_t payload_proto;
331  clib_error_t *error = 0;
332  u32 rx_sw_if_index = ~0;
333  vnet_main_t *vnm;
334  u8 is_add;
335 
336  is_add = 1;
337  vnm = vnet_get_main ();
338 
339  if (!unformat_user (main_input, unformat_line_input, line_input))
340  return 0;
341 
342  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
343  {
344  if (unformat (line_input, "del"))
345  is_add = 0;
346  else if (unformat (line_input, "add"))
347  is_add = 1;
348  else if (unformat (line_input, "rx all"))
349  rx_sw_if_index = ~0;
350  else if (unformat (line_input, "rx %U",
351  unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
352  ;
353  else if (unformat (line_input, "via %U",
354  unformat_fib_route_path, &rpath, &payload_proto))
355  vec_add1 (rpaths, rpath);
356  else
357  {
358  error = unformat_parse_error (line_input);
359  goto done;
360  }
361  }
362 
363  if (~0 == rx_sw_if_index)
364  {
365  error = unformat_parse_error (line_input);
366  goto done;
367  }
368 
369  if (is_add)
370  {
371  if (vec_len (rpaths))
372  ip6_punt_redirect_add_paths (rx_sw_if_index, rpaths);
373  }
374  else
375  {
376  ip6_punt_redirect_del (rx_sw_if_index);
377  }
378 
379 done:
380  unformat_free (line_input);
381  return (error);
382 }
383 
384 /*?
385  *
386  * @cliexpar
387  * @cliexcmd{set ip punt policer <INDEX>}
388  ?*/
389 /* *INDENT-OFF* */
390 VLIB_CLI_COMMAND (ip6_punt_redirect_command, static) =
391 {
392  .path = "ip6 punt redirect",
393  .function = ip6_punt_redirect_cmd,
394  .short_help = "ip6 punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
395 };
396 /* *INDENT-ON* */
397 
398 #ifndef CLIB_MARCH_VARIANT
399 
400 #endif /* CLIB_MARCH_VARIANT */
401 
402 static clib_error_t *
404  unformat_input_t * main_input,
405  vlib_cli_command_t * cmd)
406 {
408 
409  return (NULL);
410 }
411 
412 /*?
413  *
414  * @cliexpar
415  * @cliexcmd{set ip punt policer <INDEX>}
416  ?*/
417 /* *INDENT-OFF* */
418 VLIB_CLI_COMMAND (show_ip6_punt_redirect_command, static) =
419 {
420  .path = "show ip6 punt redirect",
421  .function = ip6_punt_redirect_show_cmd,
422  .short_help = "show ip6 punt redirect",
423  .is_mp_safe = 1,
424 };
425 /* *INDENT-ON* */
426 
427 /*
428  * fd.io coding-style-patch-verification: ON
429  *
430  * Local Variables:
431  * eval: (c-set-style "gnu")
432  * End:
433  */
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:113
ip6_punt_redirect_error_t
A representation of a path as described by a route producer.
Definition: fib_types.h:479
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
uword unformat_fib_route_path(unformat_input_t *input, va_list *args)
Unformat a fib_route_path_t from CLI input.
Definition: fib_types.c:434
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
u8 * format_ip_punt_redirect_trace(u8 *s, va_list *args)
Definition: ip_punt_drop.c:25
vlib_node_registration_t ip6_not_enabled_node
(constructor) VLIB_REGISTER_NODE (ip6_not_enabled_node)
#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:358
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
unformat_function_t unformat_vnet_sw_interface
#define VLIB_NODE_FN(node)
Definition: node.h:201
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
unsigned char u8
Definition: types.h:56
void ip6_punt_redirect_del(u32 rx_sw_if_index)
u8 * format_ip_punt_redirect(u8 *s, va_list *args)
Definition: ip_punt_drop.c:131
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
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
ip_punt_policer_t ip6_punt_policer_cfg
Definition: ip6_punt_drop.c:38
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:283
u8 * format_ip_punt_policer_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:39
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)
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
vlib_main_t * vm
Definition: buffer.c:312
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
#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)
#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
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
#define unformat_parse_error(input)
Definition: format.h:269
Definition: defs.h:47
void ip_punt_redirect_del(fib_protocol_t fproto, u32 rx_sw_if_index)
Definition: ip_punt_drop.c:107
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
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:814
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:301
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:768
void ip6_punt_redirect_add_paths(u32 rx_sw_if_index, fib_route_path_t *rpaths)
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
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:171
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:762