FD.io VPP  v18.04-17-g3a0d853
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* */
23 {
24  .arc_name = "ip6-punt",
25  .start_nodes = VNET_FEATURES ("ip6-punt"),
26 };
27 
29 {
30  .arc_name = "ip6-drop",
31  .start_nodes = VNET_FEATURES ("ip6-drop", "ip6-not-enabled"),
32 };
33 /* *INDENT-ON* */
34 
36 
38 #define _(sym,string) string,
40 #undef _
41 };
42 
43 static uword
45  vlib_node_runtime_t * node, vlib_frame_t * frame)
46 {
47  return (ip_punt_policer (vm, node, frame,
48  vnet_feat_arc_ip6_punt.feature_arc_index,
49  ip6_punt_policer_cfg.policer_index));
50 }
51 
52 
53 /* *INDENT-OFF* */
54 
56  .function = ip6_punt_policer,
57  .name = "ip6-punt-policer",
58  .vector_size = sizeof (u32),
59  .n_next_nodes = IP_PUNT_POLICER_N_NEXT,
60  .format_trace = format_ip_punt_policer_trace,
62  .error_strings = ip6_punt_policer_error_strings,
63 
64  /* edit / add dispositions here */
65  .next_nodes = {
66  [IP_PUNT_POLICER_NEXT_DROP] = "ip6-drop",
67  },
68 };
69 
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 
80 static uword
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 
91 static uword
93  vlib_node_runtime_t * node, 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 
103 static uword
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  .function = ip6_drop,
117  .name = "ip6-drop",
118  .vector_size = sizeof (u32),
119  .format_trace = format_ip6_forward_next_trace,
120  .n_next_nodes = 1,
121  .next_nodes = {
122  [0] = "error-drop",
123  },
124 };
125 
127 
129 {
130  .function = ip6_not_enabled,
131  .name = "ip6-not-enabled",
132  .vector_size = sizeof (u32),
133  .format_trace = format_ip6_forward_next_trace,
134  .n_next_nodes = 1,
135  .next_nodes = {
136  [0] = "error-drop",
137  },
138 };
139 
141 
143 {
144  .function = ip6_punt,
145  .name = "ip6-punt",
146  .vector_size = sizeof (u32),
147  .format_trace = format_ip6_forward_next_trace,
148  .n_next_nodes = 1,
149  .next_nodes = {
150  [0] = "error-punt",
151  },
152 };
153 
155 
156 VNET_FEATURE_INIT (ip6_punt_end_of_arc, static) = {
157  .arc_name = "ip6-punt",
158  .node_name = "error-punt",
159  .runs_before = 0, /* not before any other features */
160 };
161 
162 VNET_FEATURE_INIT (ip6_drop_end_of_arc, static) = {
163  .arc_name = "ip6-drop",
164  .node_name = "error-drop",
165  .runs_before = 0, /* not before any other features */
166 };
167 /* *INDENT-ON */
168 
169 void
170 ip6_punt_policer_add_del (u8 is_add, u32 policer_index)
171 {
172  ip6_punt_policer_cfg.policer_index = policer_index;
173 
174  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-policer",
175  0, is_add, 0, 0);
176 }
177 
178 static clib_error_t *
180  unformat_input_t * main_input,
181  vlib_cli_command_t * cmd)
182 {
183  unformat_input_t _line_input, *line_input = &_line_input;
184  clib_error_t *error = 0;
185  u32 policer_index;
186  u8 is_add = 1;
187 
188  policer_index = ~0;
189 
190  if (!unformat_user (main_input, unformat_line_input, line_input))
191  return 0;
192 
193  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
194  {
195  if (unformat (line_input, "%d", &policer_index))
196  ;
197  else if (unformat (line_input, "del"))
198  is_add = 0;
199  else if (unformat (line_input, "add"))
200  is_add = 1;
201  else
202  {
203  error = unformat_parse_error (line_input);
204  goto done;
205  }
206  }
207 
208  if (is_add && ~0 == policer_index)
209  {
210  error = clib_error_return (0, "expected policer index `%U'",
211  format_unformat_error, line_input);
212  goto done;
213  }
214  if (!is_add)
215  policer_index = ~0;
216 
217  ip6_punt_policer_add_del(is_add, policer_index);
218 
219 done:
220  unformat_free (line_input);
221  return (error);
222 }
223 
224 /*?
225  *
226  * @cliexpar
227  * @cliexcmd{set ip punt policer <INDEX>}
228  ?*/
229 /* *INDENT-OFF* */
230 VLIB_CLI_COMMAND (ip6_punt_policer_command, static) =
231 {
232  .path = "ip6 punt policer",
233  .function = ip6_punt_police_cmd,
234  .short_help = "ip6 punt policer [add|del] <index>",
235 };
236 
237 
238 ip_punt_redirect_t ip6_punt_redirect_cfg = {
239  .any_rx_sw_if_index = {
240  .tx_sw_if_index = ~0,
241  .adj_index = ADJ_INDEX_INVALID,
242  },
243 };
244 /* *INDENT-ON* */
245 
246 #define foreach_ip6_punt_redirect_error \
247 _(DROP, "ip6 punt redirect drop")
248 
249 typedef enum
250 {
251 #define _(sym,str) IP6_PUNT_REDIRECT_ERROR_##sym,
253 #undef _
256 
258 #define _(sym,string) string,
260 #undef _
261 };
262 
263 static uword
265  vlib_node_runtime_t * node, vlib_frame_t * frame)
266 {
267  return (ip_punt_redirect (vm, node, frame,
268  vnet_feat_arc_ip6_punt.feature_arc_index,
269  &ip6_punt_redirect_cfg));
270 }
271 
272 /* *INDENT-OFF* */
274  .function = ip6_punt_redirect,
275  .name = "ip6-punt-redirect",
276  .vector_size = sizeof (u32),
277  .n_next_nodes = IP_PUNT_REDIRECT_N_NEXT,
278  .format_trace = format_ip_punt_redirect_trace,
280  .error_strings = ip6_punt_redirect_error_strings,
281 
282  /* edit / add dispositions here */
283  .next_nodes = {
284  [IP_PUNT_REDIRECT_NEXT_DROP] = "ip6-drop",
285  [IP_PUNT_REDIRECT_NEXT_TX] = "ip6-rewrite",
286  [IP_PUNT_REDIRECT_NEXT_ARP] = "ip6-discover-neighbor",
287  },
288 };
289 
292 
294  .arc_name = "ip6-punt",
295  .node_name = "ip6-punt-redirect",
296  .runs_before = VNET_FEATURES("error-punt")
297 };
298 /* *INDENT-ON* */
299 
300 void
301 ip6_punt_redirect_add (u32 rx_sw_if_index,
302  u32 tx_sw_if_index, ip46_address_t * nh)
303 {
304  ip_punt_redirect_rx_t rx = {
305  .tx_sw_if_index = tx_sw_if_index,
306  .nh = *nh,
307  };
308 
309  ip_punt_redirect_add (&ip6_punt_redirect_cfg,
310  rx_sw_if_index, &rx, FIB_PROTOCOL_IP6, VNET_LINK_IP6);
311 
312  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 1, 0, 0);
313 }
314 
315 void
316 ip6_punt_redirect_del (u32 rx_sw_if_index)
317 {
318  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 0, 0, 0);
319 
320  ip_punt_redirect_del (&ip6_punt_redirect_cfg, rx_sw_if_index);
321 }
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  clib_error_t *error = 0;
330  u32 rx_sw_if_index = 0;
331  u32 tx_sw_if_index = 0;
332  ip46_address_t nh;
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 %U",
355  &nh.ip6,
356  unformat_vnet_sw_interface, vnm, &tx_sw_if_index))
357  ;
358  else if (unformat (line_input, "via %U",
359  unformat_vnet_sw_interface, vnm, &tx_sw_if_index))
360  memset (&nh, 0, sizeof (nh));
361  else
362  {
363  error = unformat_parse_error (line_input);
364  goto done;
365  }
366  }
367 
368  if (is_add)
369  {
370  if (rx_sw_if_index && tx_sw_if_index)
371  {
372  ip6_punt_redirect_add (rx_sw_if_index, tx_sw_if_index, &nh);
373  }
374  }
375  else
376  {
377  if (rx_sw_if_index)
378  {
379  ip6_punt_redirect_del (rx_sw_if_index);
380  }
381  }
382 
383 done:
384  unformat_free (line_input);
385  return (error);
386 }
387 
388 /*?
389  *
390  * @cliexpar
391  * @cliexcmd{set ip punt policer <INDEX>}
392  ?*/
393 /* *INDENT-OFF* */
394 VLIB_CLI_COMMAND (ip6_punt_redirect_command, static) =
395 {
396  .path = "ip6 punt redirect",
397  .function = ip6_punt_redirect_cmd,
398  .short_help = "ip6 punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
399 };
400 /* *INDENT-ON* */
401 
402 static clib_error_t *
404  unformat_input_t * main_input,
405  vlib_cli_command_t * cmd)
406 {
407  vlib_cli_output (vm, "%U", format_ip_punt_redirect, &ip6_punt_redirect_cfg);
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  */
static uword ip6_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
ip6_punt_redirect_error_t
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static 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:55
static vlib_node_registration_t ip6_not_enabled_node
(constructor) VLIB_REGISTER_NODE (ip6_not_enabled_node)
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)
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
unformat_function_t unformat_vnet_sw_interface
static uword ip6_punt_policer(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_punt_drop.c:44
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:91
void ip6_punt_policer_add_del(u8 is_add, u32 policer_index)
static 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:37
#define clib_error_return(e, args...)
Definition: error.h:99
#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:35
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
static vlib_node_registration_t ip6_punt_policer_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_policer_node)
Definition: ip6_punt_drop.c:55
unformat_function_t unformat_line_input
Definition: format.h:281
u8 * format_ip_punt_policer_trace(u8 *s, va_list *args)
Definition: ip4_punt_drop.c:36
#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)
static vlib_node_registration_t ip6_punt_node
(constructor) VLIB_REGISTER_NODE (ip6_punt_node)
static uword ip6_punt_redirect(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static uword ip6_not_enabled(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_punt_drop.c:92
unformat_function_t unformat_ip6_address
Definition: format.h:94
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
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
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: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
#define ARRAY_LEN(x)
Definition: clib.h:59
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
unsigned int u32
Definition: types.h:88
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:375
u64 uword
Definition: types.h:112
#define unformat_parse_error(input)
Definition: format.h:267
Definition: defs.h:47
unsigned char u8
Definition: types.h:56
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:161
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:773
u8 * format_ip_punt_redirect(u8 *s, va_list *args)
u16 flags
Copy of main node flags.
Definition: node.h:450
static uword ip6_drop(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_punt_drop.c:81
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:259
VLIB_NODE_FUNCTION_MULTIARCH(ip6_punt_policer_node, ip6_punt_policer)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
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:233
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
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:723