blob: f2985a244aaffdd564a6c0f60d7dc073088021e3 [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
Neale Ranns80af13d2022-03-25 08:51:58 +0000315static u32 ip4_punt_redirect_enable_counts;
316
Neale Rannsd91c1db2017-07-31 02:30:50 -0700317void
Nathan Skrzypczak2a1783f2021-08-10 15:05:29 +0200318ip4_punt_redirect_add_paths (u32 rx_sw_if_index,
319 const fib_route_path_t *rpaths)
Neale Ranns92207752019-06-03 13:21:40 +0000320{
321 ip_punt_redirect_add (FIB_PROTOCOL_IP4,
322 rx_sw_if_index,
323 FIB_FORW_CHAIN_TYPE_UNICAST_IP4, rpaths);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700324
Neale Ranns80af13d2022-03-25 08:51:58 +0000325 if (1 == ++ip4_punt_redirect_enable_counts)
326 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-redirect", 0, 1, 0, 0);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700327}
328
329void
330ip4_punt_redirect_del (u32 rx_sw_if_index)
331{
Neale Ranns80af13d2022-03-25 08:51:58 +0000332 ASSERT (ip4_punt_redirect_enable_counts);
333 if (0 == --ip4_punt_redirect_enable_counts)
334 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-redirect", 0, 0, 0, 0);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700335
Neale Ranns92207752019-06-03 13:21:40 +0000336 ip_punt_redirect_del (FIB_PROTOCOL_IP4, rx_sw_if_index);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700337}
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700338#endif /* CLIB_MARCH_VARIANT */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700339
340static clib_error_t *
341ip4_punt_redirect_cmd (vlib_main_t * vm,
342 unformat_input_t * main_input,
343 vlib_cli_command_t * cmd)
344{
345 unformat_input_t _line_input, *line_input = &_line_input;
Benoît Ganne41a54f62021-08-05 15:06:36 +0200346 fib_route_path_t *rpaths = NULL, rpath;
347 dpo_proto_t payload_proto = DPO_PROTO_IP4;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700348 clib_error_t *error = 0;
Neale Ranns92207752019-06-03 13:21:40 +0000349 u32 rx_sw_if_index = ~0;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700350 vnet_main_t *vnm;
351 u8 is_add;
352
353 is_add = 1;
354 vnm = vnet_get_main ();
355
356 if (!unformat_user (main_input, unformat_line_input, line_input))
357 return 0;
358
359 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
360 {
361 if (unformat (line_input, "del"))
362 is_add = 0;
363 else if (unformat (line_input, "add"))
364 is_add = 1;
365 else if (unformat (line_input, "rx all"))
Benoît Ganne41a54f62021-08-05 15:06:36 +0200366 rx_sw_if_index = 0;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700367 else if (unformat (line_input, "rx %U",
368 unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
369 ;
Benoît Ganne41a54f62021-08-05 15:06:36 +0200370 else if (unformat (line_input, "via %U", unformat_fib_route_path, &rpath,
371 &payload_proto))
372 vec_add1 (rpaths, rpath);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700373 else
374 {
375 error = unformat_parse_error (line_input);
376 goto done;
377 }
378 }
379
Neale Ranns92207752019-06-03 13:21:40 +0000380 if (~0 == rx_sw_if_index)
381 {
382 error = unformat_parse_error (line_input);
383 goto done;
384 }
385
Neale Rannsd91c1db2017-07-31 02:30:50 -0700386 if (is_add)
Swarup Nayakecf844c2017-12-11 13:52:44 +0530387 {
Benoît Ganne41a54f62021-08-05 15:06:36 +0200388 if (vec_len (rpaths))
389 ip4_punt_redirect_add_paths (rx_sw_if_index, rpaths);
Swarup Nayakecf844c2017-12-11 13:52:44 +0530390 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700391 else
Swarup Nayakecf844c2017-12-11 13:52:44 +0530392 {
Neale Ranns92207752019-06-03 13:21:40 +0000393 ip4_punt_redirect_del (rx_sw_if_index);
Swarup Nayakecf844c2017-12-11 13:52:44 +0530394 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700395
396done:
Benoît Ganne41a54f62021-08-05 15:06:36 +0200397 vec_free (rpaths);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700398 unformat_free (line_input);
399 return (error);
400}
401
402/*?
403 *
404 * @cliexpar
405 * @cliexcmd{set ip punt policer}
406 ?*/
407/* *INDENT-OFF* */
408VLIB_CLI_COMMAND (ip4_punt_redirect_command, static) =
409{
410 .path = "ip punt redirect",
411 .function = ip4_punt_redirect_cmd,
412 .short_help = "ip punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
413};
414/* *INDENT-ON* */
415
Neale Rannsd91c1db2017-07-31 02:30:50 -0700416static clib_error_t *
417ip4_punt_redirect_show_cmd (vlib_main_t * vm,
418 unformat_input_t * main_input,
419 vlib_cli_command_t * cmd)
420{
Neale Ranns92207752019-06-03 13:21:40 +0000421 vlib_cli_output (vm, "%U", format_ip_punt_redirect, FIB_PROTOCOL_IP4);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700422
423 return (NULL);
424}
425
426/*?
427 *
428 * @cliexpar
429 * @cliexcmd{set ip punt redierect}
430 ?*/
431/* *INDENT-OFF* */
432VLIB_CLI_COMMAND (show_ip4_punt_redirect_command, static) =
433{
434 .path = "show ip punt redirect",
435 .function = ip4_punt_redirect_show_cmd,
Swarup Nayaka3611a72017-12-06 18:55:43 +0530436 .short_help = "show ip punt redirect",
Neale Rannsd91c1db2017-07-31 02:30:50 -0700437 .is_mp_safe = 1,
438};
439/* *INDENT-ON* */
440
441/*
442 * fd.io coding-style-patch-verification: ON
443 *
444 * Local Variables:
445 * eval: (c-set-style "gnu")
446 * End:
447 */