blob: 20430adb2f32c3e3ad98808bd69ab35c1f43ee23 [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 (ip4_punt) =
23{
24 .arc_name = "ip4-punt",
25 .start_nodes = VNET_FEATURES ("ip4-punt"),
26};
27
28VNET_FEATURE_ARC_INIT (ip4_drop) =
29{
30 .arc_name = "ip4-drop",
Neale Ranns8269d3d2018-01-30 09:02:20 -080031 .start_nodes = VNET_FEATURES ("ip4-drop", "ip4-not-enabled"),
Neale Rannsd91c1db2017-07-31 02:30:50 -070032};
33/* *INDENT-ON* */
34
Filip Tehlar26ea14e2019-03-11 05:30:21 -070035extern ip_punt_policer_t ip4_punt_policer_cfg;
Filip Tehlar26ea14e2019-03-11 05:30:21 -070036
37#ifndef CLIB_MARCH_VARIANT
Neale Rannsd91c1db2017-07-31 02:30:50 -070038u8 *
39format_ip_punt_policer_trace (u8 * s, va_list * args)
40{
41 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
42 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
43 ip_punt_policer_trace_t *t = va_arg (*args, ip_punt_policer_trace_t *);
44
45 s = format (s, "policer_index %d next %d", t->policer_index, t->next);
46 return s;
47}
48
49ip_punt_policer_t ip4_punt_policer_cfg = {
50 .policer_index = ~0,
51};
Filip Tehlar26ea14e2019-03-11 05:30:21 -070052#endif /* CLIB_MARCH_VARIANT */
Neale Rannsd91c1db2017-07-31 02:30:50 -070053
Brian Russell1b2e16a2021-01-21 14:44:09 +000054static char *ip4_punt_policer_handoff_error_strings[] = { "congestion drop" };
55
56VLIB_NODE_FN (ip4_punt_policer_handoff_node)
57(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
58{
59 return policer_handoff (vm, node, frame, ip4_punt_policer_cfg.fq_index,
60 ip4_punt_policer_cfg.policer_index);
61}
62
63VLIB_REGISTER_NODE (ip4_punt_policer_handoff_node) = {
64 .name = "ip4-punt-policer-handoff",
65 .vector_size = sizeof (u32),
66 .format_trace = format_policer_handoff_trace,
67 .type = VLIB_NODE_TYPE_INTERNAL,
68 .n_errors = ARRAY_LEN(ip4_punt_policer_handoff_error_strings),
69 .error_strings = ip4_punt_policer_handoff_error_strings,
70
71 .n_next_nodes = 1,
72 .next_nodes = {
73 [0] = "error-drop",
74 },
75};
76
Neale Rannsd91c1db2017-07-31 02:30:50 -070077static char *ip4_punt_policer_error_strings[] = {
78#define _(sym,string) string,
79 foreach_ip_punt_policer_error
80#undef _
81};
82
Filip Tehlar26ea14e2019-03-11 05:30:21 -070083VLIB_NODE_FN (ip4_punt_policer_node) (vlib_main_t * vm,
84 vlib_node_runtime_t * node,
85 vlib_frame_t * frame)
Neale Rannsd91c1db2017-07-31 02:30:50 -070086{
87 return (ip_punt_policer (vm, node, frame,
88 vnet_feat_arc_ip4_punt.feature_arc_index,
89 ip4_punt_policer_cfg.policer_index));
90}
91
92/* *INDENT-OFF* */
Filip Tehlar26ea14e2019-03-11 05:30:21 -070093VLIB_REGISTER_NODE (ip4_punt_policer_node) = {
Neale Rannsd91c1db2017-07-31 02:30:50 -070094 .name = "ip4-punt-policer",
95 .vector_size = sizeof (u32),
96 .n_next_nodes = IP_PUNT_POLICER_N_NEXT,
97 .format_trace = format_ip_punt_policer_trace,
98 .n_errors = ARRAY_LEN(ip4_punt_policer_error_strings),
99 .error_strings = ip4_punt_policer_error_strings,
100
101 .next_nodes = {
102 [IP_PUNT_POLICER_NEXT_DROP] = "ip4-drop",
Brian Russell1b2e16a2021-01-21 14:44:09 +0000103 [IP_PUNT_POLICER_NEXT_HANDOFF] = "ip4-punt-policer-handoff",
Neale Rannsd91c1db2017-07-31 02:30:50 -0700104 },
105};
106
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700107VNET_FEATURE_INIT (ip4_punt_policer_node) = {
Neale Rannsd91c1db2017-07-31 02:30:50 -0700108 .arc_name = "ip4-punt",
109 .node_name = "ip4-punt-policer",
110 .runs_before = VNET_FEATURES("ip4-punt-redirect"),
111};
112/* *INDENT-ON* */
113
Neale Rannsd91c1db2017-07-31 02:30:50 -0700114
115#define foreach_ip4_punt_redirect_error \
116_(DROP, "ip4 punt redirect drop")
117
118typedef enum
119{
120#define _(sym,str) IP4_PUNT_REDIRECT_ERROR_##sym,
121 foreach_ip4_punt_redirect_error
122#undef _
123 IP4_PUNT_REDIRECT_N_ERROR,
124} ip4_punt_redirect_error_t;
125
126static char *ip4_punt_redirect_error_strings[] = {
127#define _(sym,string) string,
128 foreach_ip4_punt_redirect_error
129#undef _
130};
131
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700132VLIB_NODE_FN (ip4_punt_redirect_node) (vlib_main_t * vm,
133 vlib_node_runtime_t * node,
134 vlib_frame_t * frame)
Neale Rannsd91c1db2017-07-31 02:30:50 -0700135{
136 return (ip_punt_redirect (vm, node, frame,
137 vnet_feat_arc_ip4_punt.feature_arc_index,
Neale Ranns92207752019-06-03 13:21:40 +0000138 FIB_PROTOCOL_IP4));
Neale Rannsd91c1db2017-07-31 02:30:50 -0700139}
140
141/* *INDENT-OFF* */
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700142VLIB_REGISTER_NODE (ip4_punt_redirect_node) = {
Neale Rannsd91c1db2017-07-31 02:30:50 -0700143 .name = "ip4-punt-redirect",
144 .vector_size = sizeof (u32),
145 .n_next_nodes = IP_PUNT_REDIRECT_N_NEXT,
146 .format_trace = format_ip_punt_redirect_trace,
147 .n_errors = ARRAY_LEN(ip4_punt_redirect_error_strings),
148 .error_strings = ip4_punt_redirect_error_strings,
149
150 /* edit / add dispositions here */
151 .next_nodes = {
152 [IP_PUNT_REDIRECT_NEXT_DROP] = "ip4-drop",
153 [IP_PUNT_REDIRECT_NEXT_TX] = "ip4-rewrite",
154 [IP_PUNT_REDIRECT_NEXT_ARP] = "ip4-arp",
155 },
156};
157
Neale Rannsd91c1db2017-07-31 02:30:50 -0700158VNET_FEATURE_INIT (ip4_punt_redirect_node, static) = {
159 .arc_name = "ip4-punt",
160 .node_name = "ip4-punt-redirect",
161 .runs_before = VNET_FEATURES("error-punt"),
162};
163/* *INDENT-ON* */
164
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700165VLIB_NODE_FN (ip4_drop_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
166 vlib_frame_t * frame)
Neale Rannsd91c1db2017-07-31 02:30:50 -0700167{
168 if (node->flags & VLIB_NODE_FLAG_TRACE)
169 ip4_forward_next_trace (vm, node, frame, VLIB_TX);
170
171 return ip_drop_or_punt (vm, node, frame,
172 vnet_feat_arc_ip4_drop.feature_arc_index);
173
174}
175
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700176VLIB_NODE_FN (ip4_not_enabled_node) (vlib_main_t * vm,
177 vlib_node_runtime_t * node,
178 vlib_frame_t * frame)
Neale Ranns8269d3d2018-01-30 09:02:20 -0800179{
180 if (node->flags & VLIB_NODE_FLAG_TRACE)
181 ip4_forward_next_trace (vm, node, frame, VLIB_TX);
182
183 return ip_drop_or_punt (vm, node, frame,
184 vnet_feat_arc_ip4_drop.feature_arc_index);
185}
186
187static uword
Neale Rannsd91c1db2017-07-31 02:30:50 -0700188ip4_punt (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
189{
190 if (node->flags & VLIB_NODE_FLAG_TRACE)
191 ip4_forward_next_trace (vm, node, frame, VLIB_TX);
192
193 return ip_drop_or_punt (vm, node, frame,
194 vnet_feat_arc_ip4_punt.feature_arc_index);
195}
196
197/* *INDENT-OFF* */
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700198VLIB_REGISTER_NODE (ip4_drop_node) =
Neale Rannsd91c1db2017-07-31 02:30:50 -0700199{
Neale Rannsd91c1db2017-07-31 02:30:50 -0700200 .name = "ip4-drop",
201 .vector_size = sizeof (u32),
202 .format_trace = format_ip4_forward_next_trace,
203 .n_next_nodes = 1,
204 .next_nodes = {
205 [0] = "error-drop",
206 },
207};
208
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700209VLIB_REGISTER_NODE (ip4_not_enabled_node) =
Neale Ranns8269d3d2018-01-30 09:02:20 -0800210{
Neale Ranns8269d3d2018-01-30 09:02:20 -0800211 .name = "ip4-not-enabled",
212 .vector_size = sizeof (u32),
213 .format_trace = format_ip4_forward_next_trace,
Neale Ranns6bcc6a42019-10-15 15:47:55 +0000214 .sibling_of = "ip4-drop",
Neale Ranns8269d3d2018-01-30 09:02:20 -0800215};
216
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700217VLIB_REGISTER_NODE (ip4_punt_node) =
Neale Rannsd91c1db2017-07-31 02:30:50 -0700218{
219 .function = ip4_punt,
220 .name = "ip4-punt",
221 .vector_size = sizeof (u32),
222 .format_trace = format_ip4_forward_next_trace,
223 .n_next_nodes = 1,
224 .next_nodes = {
225 [0] = "error-punt",
226 },
227};
228
229VNET_FEATURE_INIT (ip4_punt_end_of_arc, static) = {
230 .arc_name = "ip4-punt",
231 .node_name = "error-punt",
232 .runs_before = 0, /* not before any other features */
233};
234
235VNET_FEATURE_INIT (ip4_drop_end_of_arc, static) = {
236 .arc_name = "ip4-drop",
237 .node_name = "error-drop",
238 .runs_before = 0, /* not before any other features */
239};
240/* *INDENT-ON */
241
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700242#ifndef CLIB_MARCH_VARIANT
Neale Rannsd91c1db2017-07-31 02:30:50 -0700243void
244ip4_punt_policer_add_del (u8 is_add, u32 policer_index)
245{
246 ip4_punt_policer_cfg.policer_index = policer_index;
247
248 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-policer",
249 0, is_add, 0, 0);
250}
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700251#endif /* CLIB_MARCH_VARIANT */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700252
253static clib_error_t *
254ip4_punt_police_cmd (vlib_main_t * vm,
255 unformat_input_t * main_input,
256 vlib_cli_command_t * cmd)
257{
258 unformat_input_t _line_input, *line_input = &_line_input;
259 clib_error_t *error = 0;
260 u32 policer_index;
261 u8 is_add = 1;
262
263 policer_index = ~0;
264
265 if (!unformat_user (main_input, unformat_line_input, line_input))
266 return 0;
267
268 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
269 {
270 if (unformat (line_input, "%d", &policer_index))
271 ;
272 else if (unformat (line_input, "del"))
273 is_add = 0;
274 else if (unformat (line_input, "add"))
275 is_add = 1;
276 else
277 {
278 error = unformat_parse_error (line_input);
279 goto done;
280 }
281 }
282
283 if (is_add && ~0 == policer_index)
284 {
285 error = clib_error_return (0, "expected policer index `%U'",
286 format_unformat_error, line_input);
287 goto done;
288 }
289 if (!is_add)
290 policer_index = ~0;
291
292 ip4_punt_policer_add_del(is_add, policer_index);
293
294done:
295 unformat_free (line_input);
296 return (error);
297}
298
299/*?
300 *
301 * @cliexpar
302 * @cliexcmd{set ip punt policer <INDEX>}
303 ?*/
304/* *INDENT-OFF* */
305VLIB_CLI_COMMAND (ip4_punt_policer_command, static) =
306{
307 .path = "ip punt policer",
308 .function = ip4_punt_police_cmd,
309 .short_help = "ip punt policer [add|del] <index>",
310};
311/* *INDENT-ON* */
312
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700313#ifndef CLIB_MARCH_VARIANT
Neale Rannsd91c1db2017-07-31 02:30:50 -0700314
315void
316ip4_punt_redirect_add (u32 rx_sw_if_index,
317 u32 tx_sw_if_index, ip46_address_t * nh)
318{
Neale Ranns92207752019-06-03 13:21:40 +0000319 /* *INDENT-OFF* */
320 fib_route_path_t *rpaths = NULL, rpath = {
321 .frp_proto = DPO_PROTO_IP4,
322 .frp_addr = *nh,
323 .frp_sw_if_index = tx_sw_if_index,
324 .frp_weight = 1,
325 .frp_fib_index = ~0,
Neale Rannsd91c1db2017-07-31 02:30:50 -0700326 };
Neale Ranns92207752019-06-03 13:21:40 +0000327 /* *INDENT-ON* */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700328
Neale Ranns92207752019-06-03 13:21:40 +0000329 vec_add1 (rpaths, rpath);
330
331 ip4_punt_redirect_add_paths (rx_sw_if_index, rpaths);
332
333 vec_free (rpaths);
334}
335
336void
337ip4_punt_redirect_add_paths (u32 rx_sw_if_index, fib_route_path_t * rpaths)
338{
339 ip_punt_redirect_add (FIB_PROTOCOL_IP4,
340 rx_sw_if_index,
341 FIB_FORW_CHAIN_TYPE_UNICAST_IP4, rpaths);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700342
343 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-redirect", 0, 1, 0, 0);
344}
345
346void
347ip4_punt_redirect_del (u32 rx_sw_if_index)
348{
349 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-redirect", 0, 0, 0, 0);
350
Neale Ranns92207752019-06-03 13:21:40 +0000351 ip_punt_redirect_del (FIB_PROTOCOL_IP4, rx_sw_if_index);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700352}
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700353#endif /* CLIB_MARCH_VARIANT */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700354
355static clib_error_t *
356ip4_punt_redirect_cmd (vlib_main_t * vm,
357 unformat_input_t * main_input,
358 vlib_cli_command_t * cmd)
359{
360 unformat_input_t _line_input, *line_input = &_line_input;
Mohsin Kazmia84cb712020-06-25 13:43:52 +0200361 ip46_address_t nh = { 0 };
Neale Rannsd91c1db2017-07-31 02:30:50 -0700362 clib_error_t *error = 0;
Neale Ranns92207752019-06-03 13:21:40 +0000363 u32 rx_sw_if_index = ~0;
Mohsin Kazmia84cb712020-06-25 13:43:52 +0200364 u32 tx_sw_if_index = ~0;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700365 vnet_main_t *vnm;
366 u8 is_add;
367
368 is_add = 1;
369 vnm = vnet_get_main ();
370
371 if (!unformat_user (main_input, unformat_line_input, line_input))
372 return 0;
373
374 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
375 {
376 if (unformat (line_input, "del"))
377 is_add = 0;
378 else if (unformat (line_input, "add"))
379 is_add = 1;
380 else if (unformat (line_input, "rx all"))
381 rx_sw_if_index = ~0;
382 else if (unformat (line_input, "rx %U",
383 unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
384 ;
Mohsin Kazmia84cb712020-06-25 13:43:52 +0200385 else if (unformat (line_input, "via %U %U",
Mohsin Kazmic6eae9c2020-07-02 10:56:57 +0200386 unformat_ip4_address, &nh.ip4,
387 unformat_vnet_sw_interface, vnm, &tx_sw_if_index))
Mohsin Kazmia84cb712020-06-25 13:43:52 +0200388 ;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700389 else if (unformat (line_input, "via %U",
Mohsin Kazmia84cb712020-06-25 13:43:52 +0200390 unformat_vnet_sw_interface, vnm, &tx_sw_if_index))
391 ;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700392 else
393 {
394 error = unformat_parse_error (line_input);
395 goto done;
396 }
397 }
398
Neale Ranns92207752019-06-03 13:21:40 +0000399 if (~0 == rx_sw_if_index)
400 {
401 error = unformat_parse_error (line_input);
402 goto done;
403 }
404
Neale Rannsd91c1db2017-07-31 02:30:50 -0700405 if (is_add)
Swarup Nayakecf844c2017-12-11 13:52:44 +0530406 {
Mohsin Kazmia84cb712020-06-25 13:43:52 +0200407 ip4_punt_redirect_add (rx_sw_if_index, tx_sw_if_index, &nh);
Swarup Nayakecf844c2017-12-11 13:52:44 +0530408 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700409 else
Swarup Nayakecf844c2017-12-11 13:52:44 +0530410 {
Neale Ranns92207752019-06-03 13:21:40 +0000411 ip4_punt_redirect_del (rx_sw_if_index);
Swarup Nayakecf844c2017-12-11 13:52:44 +0530412 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700413
414done:
415 unformat_free (line_input);
416 return (error);
417}
418
419/*?
420 *
421 * @cliexpar
422 * @cliexcmd{set ip punt policer}
423 ?*/
424/* *INDENT-OFF* */
425VLIB_CLI_COMMAND (ip4_punt_redirect_command, static) =
426{
427 .path = "ip punt redirect",
428 .function = ip4_punt_redirect_cmd,
429 .short_help = "ip punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
430};
431/* *INDENT-ON* */
432
Neale Rannsd91c1db2017-07-31 02:30:50 -0700433static clib_error_t *
434ip4_punt_redirect_show_cmd (vlib_main_t * vm,
435 unformat_input_t * main_input,
436 vlib_cli_command_t * cmd)
437{
Neale Ranns92207752019-06-03 13:21:40 +0000438 vlib_cli_output (vm, "%U", format_ip_punt_redirect, FIB_PROTOCOL_IP4);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700439
440 return (NULL);
441}
442
443/*?
444 *
445 * @cliexpar
446 * @cliexcmd{set ip punt redierect}
447 ?*/
448/* *INDENT-OFF* */
449VLIB_CLI_COMMAND (show_ip4_punt_redirect_command, static) =
450{
451 .path = "show ip punt redirect",
452 .function = ip4_punt_redirect_show_cmd,
Swarup Nayaka3611a72017-12-06 18:55:43 +0530453 .short_help = "show ip punt redirect",
Neale Rannsd91c1db2017-07-31 02:30:50 -0700454 .is_mp_safe = 1,
455};
456/* *INDENT-ON* */
457
458/*
459 * fd.io coding-style-patch-verification: ON
460 *
461 * Local Variables:
462 * eval: (c-set-style "gnu")
463 * End:
464 */