blob: 3c839ffdd7456dad61601c51b142de3640febe09 [file] [log] [blame]
Neale Rannsd91c1db2017-07-31 02:30:50 -07001/*
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>
19#include <vnet/policer/police_inlines.h>
20
21/* *INDENT-OFF* */
22VNET_FEATURE_ARC_INIT (ip6_punt) =
23{
24 .arc_name = "ip6-punt",
25 .start_nodes = VNET_FEATURES ("ip6-punt"),
26};
27
28VNET_FEATURE_ARC_INIT (ip6_drop) =
29{
30 .arc_name = "ip6-drop",
Neale Ranns8269d3d2018-01-30 09:02:20 -080031 .start_nodes = VNET_FEATURES ("ip6-drop", "ip6-not-enabled"),
Neale Rannsd91c1db2017-07-31 02:30:50 -070032};
33/* *INDENT-ON* */
34
35ip_punt_policer_t ip6_punt_policer_cfg;
36
37static char *ip6_punt_policer_error_strings[] = {
38#define _(sym,string) string,
39 foreach_ip_punt_policer_error
40#undef _
41};
42
43static uword
44ip6_punt_policer (vlib_main_t * vm,
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
55VLIB_REGISTER_NODE (ip6_punt_policer_node, static) = {
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,
61 .n_errors = ARRAY_LEN(ip6_punt_policer_error_strings),
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
70VLIB_NODE_FUNCTION_MULTIARCH (ip6_punt_policer_node,
71 ip6_punt_policer);
72
73VNET_FEATURE_INIT (ip6_punt_policer_node, static) = {
74 .arc_name = "ip6-punt",
75 .node_name = "ip6-punt-policer",
76 .runs_before = VNET_FEATURES("ip6-punt-redirect")
77};
78/* *INDENT-ON* */
79
80static uword
81ip6_drop (vlib_main_t * vm, vlib_node_runtime_t * node, 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
91static uword
Neale Ranns8269d3d2018-01-30 09:02:20 -080092ip6_not_enabled (vlib_main_t * vm,
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
103static uword
Neale Rannsd91c1db2017-07-31 02:30:50 -0700104ip6_punt (vlib_main_t * vm, vlib_node_runtime_t * node, 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* */
114VLIB_REGISTER_NODE (ip6_drop_node, static) =
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
126VLIB_NODE_FUNCTION_MULTIARCH (ip6_drop_node, ip6_drop);
127
Neale Ranns8269d3d2018-01-30 09:02:20 -0800128VLIB_REGISTER_NODE (ip6_not_enabled_node, static) =
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
140VLIB_NODE_FUNCTION_MULTIARCH (ip6_not_enabled_node, ip6_not_enabled);
141
Neale Rannsd91c1db2017-07-31 02:30:50 -0700142VLIB_REGISTER_NODE (ip6_punt_node, static) =
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
154VLIB_NODE_FUNCTION_MULTIARCH (ip6_punt_node, ip6_punt);
155
156VNET_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
162VNET_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
169void
170ip6_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
178static clib_error_t *
179ip6_punt_police_cmd (vlib_main_t * vm,
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
219done:
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* */
230VLIB_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};
Swarup Nayak4112e382017-12-11 17:36:54 +0530236
Neale Rannsd91c1db2017-07-31 02:30:50 -0700237
238ip_punt_redirect_t ip6_punt_redirect_cfg = {
239 .any_rx_sw_if_index = {
Swarup Nayak4112e382017-12-11 17:36:54 +0530240 .tx_sw_if_index = ~0,
241 .adj_index = ADJ_INDEX_INVALID,
242 },
Neale Rannsd91c1db2017-07-31 02:30:50 -0700243};
Swarup Nayak4112e382017-12-11 17:36:54 +0530244/* *INDENT-ON* */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700245
246#define foreach_ip6_punt_redirect_error \
247_(DROP, "ip6 punt redirect drop")
248
249typedef enum
250{
251#define _(sym,str) IP6_PUNT_REDIRECT_ERROR_##sym,
252 foreach_ip6_punt_redirect_error
253#undef _
254 IP6_PUNT_REDIRECT_N_ERROR,
255} ip6_punt_redirect_error_t;
256
257static char *ip6_punt_redirect_error_strings[] = {
258#define _(sym,string) string,
259 foreach_ip6_punt_redirect_error
260#undef _
261};
262
263static uword
264ip6_punt_redirect (vlib_main_t * vm,
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* */
273VLIB_REGISTER_NODE (ip6_punt_redirect_node, static) = {
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,
279 .n_errors = ARRAY_LEN(ip6_punt_redirect_error_strings),
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
290VLIB_NODE_FUNCTION_MULTIARCH (ip6_punt_redirect_node,
291 ip6_punt_redirect);
292
293VNET_FEATURE_INIT (ip6_punt_redirect_node, static) = {
294 .arc_name = "ip6-punt",
295 .node_name = "ip6-punt-redirect",
296 .runs_before = VNET_FEATURES("error-punt")
297};
298/* *INDENT-ON* */
299
300void
301ip6_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
315void
316ip6_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
323static clib_error_t *
324ip6_punt_redirect_cmd (vlib_main_t * vm,
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;
Swarup Nayakecf844c2017-12-11 13:52:44 +0530330 u32 rx_sw_if_index = 0;
331 u32 tx_sw_if_index = 0;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700332 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",
354 unformat_ip6_address,
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))
Dave Barachb7b92992018-10-17 10:38:51 -0400360 clib_memset (&nh, 0, sizeof (nh));
Neale Rannsd91c1db2017-07-31 02:30:50 -0700361 else
362 {
363 error = unformat_parse_error (line_input);
364 goto done;
365 }
366 }
367
368 if (is_add)
Swarup Nayakecf844c2017-12-11 13:52:44 +0530369 {
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 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700375 else
Swarup Nayakecf844c2017-12-11 13:52:44 +0530376 {
377 if (rx_sw_if_index)
378 {
379 ip6_punt_redirect_del (rx_sw_if_index);
380 }
381 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700382
383done:
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* */
394VLIB_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
Pavel Kotucek609e1212018-11-27 09:59:44 +0100402ip_punt_redirect_detail_t *
403ip6_punt_redirect_entries (u32 sw_if_index)
404{
405 ip_punt_redirect_rx_t *pr;
406 ip_punt_redirect_detail_t *prs = 0;
407 u32 rx_sw_if_index;
408
409 vec_foreach_index (rx_sw_if_index,
410 ip6_punt_redirect_cfg.redirect_by_rx_sw_if_index)
411 {
412 if (sw_if_index == ~0 || sw_if_index == rx_sw_if_index)
413 {
414 pr =
415 &ip6_punt_redirect_cfg.redirect_by_rx_sw_if_index[rx_sw_if_index];
416 if (NULL != pr && ~0 != pr->tx_sw_if_index)
417 {
418 ip_punt_redirect_detail_t detail = {.rx_sw_if_index =
419 rx_sw_if_index,
420 .punt_redirect = *pr
421 };
422 vec_add1 (prs, detail);
423 }
424 }
425 }
426 if (~0 != ip6_punt_redirect_cfg.any_rx_sw_if_index.tx_sw_if_index)
427 {
428 pr = &ip6_punt_redirect_cfg.any_rx_sw_if_index;
429 if (NULL != pr)
430 {
431 ip_punt_redirect_detail_t detail = {.rx_sw_if_index =
432 rx_sw_if_index,
433 .punt_redirect = *pr
434 };
435 vec_add1 (prs, detail);
436 }
437 }
438
439 return prs;
440}
441
Neale Rannsd91c1db2017-07-31 02:30:50 -0700442static clib_error_t *
443ip6_punt_redirect_show_cmd (vlib_main_t * vm,
444 unformat_input_t * main_input,
445 vlib_cli_command_t * cmd)
446{
447 vlib_cli_output (vm, "%U", format_ip_punt_redirect, &ip6_punt_redirect_cfg);
448
449 return (NULL);
450}
451
452/*?
453 *
454 * @cliexpar
455 * @cliexcmd{set ip punt policer <INDEX>}
456 ?*/
457/* *INDENT-OFF* */
458VLIB_CLI_COMMAND (show_ip6_punt_redirect_command, static) =
459{
460 .path = "show ip6 punt redirect",
461 .function = ip6_punt_redirect_show_cmd,
Swarup Nayaka3611a72017-12-06 18:55:43 +0530462 .short_help = "show ip6 punt redirect",
Neale Rannsd91c1db2017-07-31 02:30:50 -0700463 .is_mp_safe = 1,
464};
465/* *INDENT-ON* */
466
467/*
468 * fd.io coding-style-patch-verification: ON
469 *
470 * Local Variables:
471 * eval: (c-set-style "gnu")
472 * End:
473 */