FD.io VPP  v18.01-8-g0eacf49
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"),
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 {
94  if (node->flags & VLIB_NODE_FLAG_TRACE)
95  ip6_forward_next_trace (vm, node, frame, VLIB_TX);
96 
97  return ip_drop_or_punt (vm, node, frame,
98  vnet_feat_arc_ip6_punt.feature_arc_index);
99 }
100 
101 /* *INDENT-OFF* */
103 {
104  .function = ip6_drop,
105  .name = "ip6-drop",
106  .vector_size = sizeof (u32),
107  .format_trace = format_ip6_forward_next_trace,
108  .n_next_nodes = 1,
109  .next_nodes = {
110  [0] = "error-drop",
111  },
112 };
113 
115 
117 {
118  .function = ip6_punt,
119  .name = "ip6-punt",
120  .vector_size = sizeof (u32),
121  .format_trace = format_ip6_forward_next_trace,
122  .n_next_nodes = 1,
123  .next_nodes = {
124  [0] = "error-punt",
125  },
126 };
127 
129 
130 VNET_FEATURE_INIT (ip6_punt_end_of_arc, static) = {
131  .arc_name = "ip6-punt",
132  .node_name = "error-punt",
133  .runs_before = 0, /* not before any other features */
134 };
135 
136 VNET_FEATURE_INIT (ip6_drop_end_of_arc, static) = {
137  .arc_name = "ip6-drop",
138  .node_name = "error-drop",
139  .runs_before = 0, /* not before any other features */
140 };
141 /* *INDENT-ON */
142 
143 void
144 ip6_punt_policer_add_del (u8 is_add, u32 policer_index)
145 {
146  ip6_punt_policer_cfg.policer_index = policer_index;
147 
148  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-policer",
149  0, is_add, 0, 0);
150 }
151 
152 static clib_error_t *
154  unformat_input_t * main_input,
155  vlib_cli_command_t * cmd)
156 {
157  unformat_input_t _line_input, *line_input = &_line_input;
158  clib_error_t *error = 0;
159  u32 policer_index;
160  u8 is_add = 1;
161 
162  policer_index = ~0;
163 
164  if (!unformat_user (main_input, unformat_line_input, line_input))
165  return 0;
166 
167  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
168  {
169  if (unformat (line_input, "%d", &policer_index))
170  ;
171  else if (unformat (line_input, "del"))
172  is_add = 0;
173  else if (unformat (line_input, "add"))
174  is_add = 1;
175  else
176  {
177  error = unformat_parse_error (line_input);
178  goto done;
179  }
180  }
181 
182  if (is_add && ~0 == policer_index)
183  {
184  error = clib_error_return (0, "expected policer index `%U'",
185  format_unformat_error, line_input);
186  goto done;
187  }
188  if (!is_add)
189  policer_index = ~0;
190 
191  ip6_punt_policer_add_del(is_add, policer_index);
192 
193 done:
194  unformat_free (line_input);
195  return (error);
196 }
197 
198 /*?
199  *
200  * @cliexpar
201  * @cliexcmd{set ip punt policer <INDEX>}
202  ?*/
203 /* *INDENT-OFF* */
204 VLIB_CLI_COMMAND (ip6_punt_policer_command, static) =
205 {
206  .path = "ip6 punt policer",
207  .function = ip6_punt_police_cmd,
208  .short_help = "ip6 punt policer [add|del] <index>",
209 };
210 
211 
212 ip_punt_redirect_t ip6_punt_redirect_cfg = {
213  .any_rx_sw_if_index = {
214  .tx_sw_if_index = ~0,
215  .adj_index = ADJ_INDEX_INVALID,
216  },
217 };
218 /* *INDENT-ON* */
219 
220 #define foreach_ip6_punt_redirect_error \
221 _(DROP, "ip6 punt redirect drop")
222 
223 typedef enum
224 {
225 #define _(sym,str) IP6_PUNT_REDIRECT_ERROR_##sym,
227 #undef _
230 
232 #define _(sym,string) string,
234 #undef _
235 };
236 
237 static uword
239  vlib_node_runtime_t * node, vlib_frame_t * frame)
240 {
241  return (ip_punt_redirect (vm, node, frame,
242  vnet_feat_arc_ip6_punt.feature_arc_index,
243  &ip6_punt_redirect_cfg));
244 }
245 
246 /* *INDENT-OFF* */
248  .function = ip6_punt_redirect,
249  .name = "ip6-punt-redirect",
250  .vector_size = sizeof (u32),
251  .n_next_nodes = IP_PUNT_REDIRECT_N_NEXT,
252  .format_trace = format_ip_punt_redirect_trace,
254  .error_strings = ip6_punt_redirect_error_strings,
255 
256  /* edit / add dispositions here */
257  .next_nodes = {
258  [IP_PUNT_REDIRECT_NEXT_DROP] = "ip6-drop",
259  [IP_PUNT_REDIRECT_NEXT_TX] = "ip6-rewrite",
260  [IP_PUNT_REDIRECT_NEXT_ARP] = "ip6-discover-neighbor",
261  },
262 };
263 
266 
268  .arc_name = "ip6-punt",
269  .node_name = "ip6-punt-redirect",
270  .runs_before = VNET_FEATURES("error-punt")
271 };
272 /* *INDENT-ON* */
273 
274 void
275 ip6_punt_redirect_add (u32 rx_sw_if_index,
276  u32 tx_sw_if_index, ip46_address_t * nh)
277 {
278  ip_punt_redirect_rx_t rx = {
279  .tx_sw_if_index = tx_sw_if_index,
280  .nh = *nh,
281  };
282 
283  ip_punt_redirect_add (&ip6_punt_redirect_cfg,
284  rx_sw_if_index, &rx, FIB_PROTOCOL_IP6, VNET_LINK_IP6);
285 
286  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 1, 0, 0);
287 }
288 
289 void
290 ip6_punt_redirect_del (u32 rx_sw_if_index)
291 {
292  vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 0, 0, 0);
293 
294  ip_punt_redirect_del (&ip6_punt_redirect_cfg, rx_sw_if_index);
295 }
296 
297 static clib_error_t *
299  unformat_input_t * main_input,
300  vlib_cli_command_t * cmd)
301 {
302  unformat_input_t _line_input, *line_input = &_line_input;
303  clib_error_t *error = 0;
304  u32 rx_sw_if_index = 0;
305  u32 tx_sw_if_index = 0;
306  ip46_address_t nh;
307  vnet_main_t *vnm;
308  u8 is_add;
309 
310  is_add = 1;
311  vnm = vnet_get_main ();
312 
313  if (!unformat_user (main_input, unformat_line_input, line_input))
314  return 0;
315 
316  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
317  {
318  if (unformat (line_input, "del"))
319  is_add = 0;
320  else if (unformat (line_input, "add"))
321  is_add = 1;
322  else if (unformat (line_input, "rx all"))
323  rx_sw_if_index = ~0;
324  else if (unformat (line_input, "rx %U",
325  unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
326  ;
327  else if (unformat (line_input, "via %U %U",
329  &nh.ip6,
330  unformat_vnet_sw_interface, vnm, &tx_sw_if_index))
331  ;
332  else if (unformat (line_input, "via %U",
333  unformat_vnet_sw_interface, vnm, &tx_sw_if_index))
334  memset (&nh, 0, sizeof (nh));
335  else
336  {
337  error = unformat_parse_error (line_input);
338  goto done;
339  }
340  }
341 
342  if (is_add)
343  {
344  if (rx_sw_if_index && tx_sw_if_index)
345  {
346  ip6_punt_redirect_add (rx_sw_if_index, tx_sw_if_index, &nh);
347  }
348  }
349  else
350  {
351  if (rx_sw_if_index)
352  {
353  ip6_punt_redirect_del (rx_sw_if_index);
354  }
355  }
356 
357 done:
358  unformat_free (line_input);
359  return (error);
360 }
361 
362 /*?
363  *
364  * @cliexpar
365  * @cliexcmd{set ip punt policer <INDEX>}
366  ?*/
367 /* *INDENT-OFF* */
368 VLIB_CLI_COMMAND (ip6_punt_redirect_command, static) =
369 {
370  .path = "ip6 punt redirect",
371  .function = ip6_punt_redirect_cmd,
372  .short_help = "ip6 punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
373 };
374 /* *INDENT-ON* */
375 
376 static clib_error_t *
378  unformat_input_t * main_input,
379  vlib_cli_command_t * cmd)
380 {
381  vlib_cli_output (vm, "%U", format_ip_punt_redirect, &ip6_punt_redirect_cfg);
382 
383  return (NULL);
384 }
385 
386 /*?
387  *
388  * @cliexpar
389  * @cliexcmd{set ip punt policer <INDEX>}
390  ?*/
391 /* *INDENT-OFF* */
392 VLIB_CLI_COMMAND (show_ip6_punt_redirect_command, static) =
393 {
394  .path = "show ip6 punt redirect",
395  .function = ip6_punt_redirect_show_cmd,
396  .short_help = "show ip6 punt redirect",
397  .is_mp_safe = 1,
398 };
399 /* *INDENT-ON* */
400 
401 /*
402  * fd.io coding-style-patch-verification: ON
403  *
404  * Local Variables:
405  * eval: (c-set-style "gnu")
406  * End:
407  */
static uword ip6_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_punt_drop.c:92
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 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)
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 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:283
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
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:259
static char * ip6_punt_redirect_error_strings[]
#define VNET_FEATURES(...)
Definition: feature.h:368
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
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
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:1041
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
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:229
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:991