blob: aee84b4df52d359e44da64f8bb18f3d2d46f0267 [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
54static char *ip4_punt_policer_error_strings[] = {
55#define _(sym,string) string,
56 foreach_ip_punt_policer_error
57#undef _
58};
59
Filip Tehlar26ea14e2019-03-11 05:30:21 -070060VLIB_NODE_FN (ip4_punt_policer_node) (vlib_main_t * vm,
61 vlib_node_runtime_t * node,
62 vlib_frame_t * frame)
Neale Rannsd91c1db2017-07-31 02:30:50 -070063{
64 return (ip_punt_policer (vm, node, frame,
65 vnet_feat_arc_ip4_punt.feature_arc_index,
66 ip4_punt_policer_cfg.policer_index));
67}
68
69/* *INDENT-OFF* */
Filip Tehlar26ea14e2019-03-11 05:30:21 -070070VLIB_REGISTER_NODE (ip4_punt_policer_node) = {
Neale Rannsd91c1db2017-07-31 02:30:50 -070071 .name = "ip4-punt-policer",
72 .vector_size = sizeof (u32),
73 .n_next_nodes = IP_PUNT_POLICER_N_NEXT,
74 .format_trace = format_ip_punt_policer_trace,
75 .n_errors = ARRAY_LEN(ip4_punt_policer_error_strings),
76 .error_strings = ip4_punt_policer_error_strings,
77
78 .next_nodes = {
79 [IP_PUNT_POLICER_NEXT_DROP] = "ip4-drop",
80 },
81};
82
Filip Tehlar26ea14e2019-03-11 05:30:21 -070083VNET_FEATURE_INIT (ip4_punt_policer_node) = {
Neale Rannsd91c1db2017-07-31 02:30:50 -070084 .arc_name = "ip4-punt",
85 .node_name = "ip4-punt-policer",
86 .runs_before = VNET_FEATURES("ip4-punt-redirect"),
87};
88/* *INDENT-ON* */
89
Neale Rannsd91c1db2017-07-31 02:30:50 -070090
91#define foreach_ip4_punt_redirect_error \
92_(DROP, "ip4 punt redirect drop")
93
94typedef enum
95{
96#define _(sym,str) IP4_PUNT_REDIRECT_ERROR_##sym,
97 foreach_ip4_punt_redirect_error
98#undef _
99 IP4_PUNT_REDIRECT_N_ERROR,
100} ip4_punt_redirect_error_t;
101
102static char *ip4_punt_redirect_error_strings[] = {
103#define _(sym,string) string,
104 foreach_ip4_punt_redirect_error
105#undef _
106};
107
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700108VLIB_NODE_FN (ip4_punt_redirect_node) (vlib_main_t * vm,
109 vlib_node_runtime_t * node,
110 vlib_frame_t * frame)
Neale Rannsd91c1db2017-07-31 02:30:50 -0700111{
112 return (ip_punt_redirect (vm, node, frame,
113 vnet_feat_arc_ip4_punt.feature_arc_index,
Neale Ranns92207752019-06-03 13:21:40 +0000114 FIB_PROTOCOL_IP4));
Neale Rannsd91c1db2017-07-31 02:30:50 -0700115}
116
117/* *INDENT-OFF* */
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700118VLIB_REGISTER_NODE (ip4_punt_redirect_node) = {
Neale Rannsd91c1db2017-07-31 02:30:50 -0700119 .name = "ip4-punt-redirect",
120 .vector_size = sizeof (u32),
121 .n_next_nodes = IP_PUNT_REDIRECT_N_NEXT,
122 .format_trace = format_ip_punt_redirect_trace,
123 .n_errors = ARRAY_LEN(ip4_punt_redirect_error_strings),
124 .error_strings = ip4_punt_redirect_error_strings,
125
126 /* edit / add dispositions here */
127 .next_nodes = {
128 [IP_PUNT_REDIRECT_NEXT_DROP] = "ip4-drop",
129 [IP_PUNT_REDIRECT_NEXT_TX] = "ip4-rewrite",
130 [IP_PUNT_REDIRECT_NEXT_ARP] = "ip4-arp",
131 },
132};
133
Neale Rannsd91c1db2017-07-31 02:30:50 -0700134VNET_FEATURE_INIT (ip4_punt_redirect_node, static) = {
135 .arc_name = "ip4-punt",
136 .node_name = "ip4-punt-redirect",
137 .runs_before = VNET_FEATURES("error-punt"),
138};
139/* *INDENT-ON* */
140
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700141VLIB_NODE_FN (ip4_drop_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
142 vlib_frame_t * frame)
Neale Rannsd91c1db2017-07-31 02:30:50 -0700143{
144 if (node->flags & VLIB_NODE_FLAG_TRACE)
145 ip4_forward_next_trace (vm, node, frame, VLIB_TX);
146
147 return ip_drop_or_punt (vm, node, frame,
148 vnet_feat_arc_ip4_drop.feature_arc_index);
149
150}
151
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700152VLIB_NODE_FN (ip4_not_enabled_node) (vlib_main_t * vm,
153 vlib_node_runtime_t * node,
154 vlib_frame_t * frame)
Neale Ranns8269d3d2018-01-30 09:02:20 -0800155{
156 if (node->flags & VLIB_NODE_FLAG_TRACE)
157 ip4_forward_next_trace (vm, node, frame, VLIB_TX);
158
159 return ip_drop_or_punt (vm, node, frame,
160 vnet_feat_arc_ip4_drop.feature_arc_index);
161}
162
163static uword
Neale Rannsd91c1db2017-07-31 02:30:50 -0700164ip4_punt (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
165{
166 if (node->flags & VLIB_NODE_FLAG_TRACE)
167 ip4_forward_next_trace (vm, node, frame, VLIB_TX);
168
169 return ip_drop_or_punt (vm, node, frame,
170 vnet_feat_arc_ip4_punt.feature_arc_index);
171}
172
173/* *INDENT-OFF* */
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700174VLIB_REGISTER_NODE (ip4_drop_node) =
Neale Rannsd91c1db2017-07-31 02:30:50 -0700175{
Neale Rannsd91c1db2017-07-31 02:30:50 -0700176 .name = "ip4-drop",
177 .vector_size = sizeof (u32),
178 .format_trace = format_ip4_forward_next_trace,
179 .n_next_nodes = 1,
180 .next_nodes = {
181 [0] = "error-drop",
182 },
183};
184
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700185VLIB_REGISTER_NODE (ip4_not_enabled_node) =
Neale Ranns8269d3d2018-01-30 09:02:20 -0800186{
Neale Ranns8269d3d2018-01-30 09:02:20 -0800187 .name = "ip4-not-enabled",
188 .vector_size = sizeof (u32),
189 .format_trace = format_ip4_forward_next_trace,
Neale Ranns6bcc6a42019-10-15 15:47:55 +0000190 .sibling_of = "ip4-drop",
Neale Ranns8269d3d2018-01-30 09:02:20 -0800191};
192
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700193VLIB_REGISTER_NODE (ip4_punt_node) =
Neale Rannsd91c1db2017-07-31 02:30:50 -0700194{
195 .function = ip4_punt,
196 .name = "ip4-punt",
197 .vector_size = sizeof (u32),
198 .format_trace = format_ip4_forward_next_trace,
199 .n_next_nodes = 1,
200 .next_nodes = {
201 [0] = "error-punt",
202 },
203};
204
205VNET_FEATURE_INIT (ip4_punt_end_of_arc, static) = {
206 .arc_name = "ip4-punt",
207 .node_name = "error-punt",
208 .runs_before = 0, /* not before any other features */
209};
210
211VNET_FEATURE_INIT (ip4_drop_end_of_arc, static) = {
212 .arc_name = "ip4-drop",
213 .node_name = "error-drop",
214 .runs_before = 0, /* not before any other features */
215};
216/* *INDENT-ON */
217
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700218#ifndef CLIB_MARCH_VARIANT
Neale Rannsd91c1db2017-07-31 02:30:50 -0700219void
220ip4_punt_policer_add_del (u8 is_add, u32 policer_index)
221{
222 ip4_punt_policer_cfg.policer_index = policer_index;
223
224 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-policer",
225 0, is_add, 0, 0);
226}
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700227#endif /* CLIB_MARCH_VARIANT */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700228
229static clib_error_t *
230ip4_punt_police_cmd (vlib_main_t * vm,
231 unformat_input_t * main_input,
232 vlib_cli_command_t * cmd)
233{
234 unformat_input_t _line_input, *line_input = &_line_input;
235 clib_error_t *error = 0;
236 u32 policer_index;
237 u8 is_add = 1;
238
239 policer_index = ~0;
240
241 if (!unformat_user (main_input, unformat_line_input, line_input))
242 return 0;
243
244 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
245 {
246 if (unformat (line_input, "%d", &policer_index))
247 ;
248 else if (unformat (line_input, "del"))
249 is_add = 0;
250 else if (unformat (line_input, "add"))
251 is_add = 1;
252 else
253 {
254 error = unformat_parse_error (line_input);
255 goto done;
256 }
257 }
258
259 if (is_add && ~0 == policer_index)
260 {
261 error = clib_error_return (0, "expected policer index `%U'",
262 format_unformat_error, line_input);
263 goto done;
264 }
265 if (!is_add)
266 policer_index = ~0;
267
268 ip4_punt_policer_add_del(is_add, policer_index);
269
270done:
271 unformat_free (line_input);
272 return (error);
273}
274
275/*?
276 *
277 * @cliexpar
278 * @cliexcmd{set ip punt policer <INDEX>}
279 ?*/
280/* *INDENT-OFF* */
281VLIB_CLI_COMMAND (ip4_punt_policer_command, static) =
282{
283 .path = "ip punt policer",
284 .function = ip4_punt_police_cmd,
285 .short_help = "ip punt policer [add|del] <index>",
286};
287/* *INDENT-ON* */
288
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700289#ifndef CLIB_MARCH_VARIANT
Neale Rannsd91c1db2017-07-31 02:30:50 -0700290
291void
292ip4_punt_redirect_add (u32 rx_sw_if_index,
293 u32 tx_sw_if_index, ip46_address_t * nh)
294{
Neale Ranns92207752019-06-03 13:21:40 +0000295 /* *INDENT-OFF* */
296 fib_route_path_t *rpaths = NULL, rpath = {
297 .frp_proto = DPO_PROTO_IP4,
298 .frp_addr = *nh,
299 .frp_sw_if_index = tx_sw_if_index,
300 .frp_weight = 1,
301 .frp_fib_index = ~0,
Neale Rannsd91c1db2017-07-31 02:30:50 -0700302 };
Neale Ranns92207752019-06-03 13:21:40 +0000303 /* *INDENT-ON* */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700304
Neale Ranns92207752019-06-03 13:21:40 +0000305 vec_add1 (rpaths, rpath);
306
307 ip4_punt_redirect_add_paths (rx_sw_if_index, rpaths);
308
309 vec_free (rpaths);
310}
311
312void
313ip4_punt_redirect_add_paths (u32 rx_sw_if_index, fib_route_path_t * rpaths)
314{
315 ip_punt_redirect_add (FIB_PROTOCOL_IP4,
316 rx_sw_if_index,
317 FIB_FORW_CHAIN_TYPE_UNICAST_IP4, rpaths);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700318
319 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-redirect", 0, 1, 0, 0);
320}
321
322void
323ip4_punt_redirect_del (u32 rx_sw_if_index)
324{
325 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-redirect", 0, 0, 0, 0);
326
Neale Ranns92207752019-06-03 13:21:40 +0000327 ip_punt_redirect_del (FIB_PROTOCOL_IP4, rx_sw_if_index);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700328}
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700329#endif /* CLIB_MARCH_VARIANT */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700330
331static clib_error_t *
332ip4_punt_redirect_cmd (vlib_main_t * vm,
333 unformat_input_t * main_input,
334 vlib_cli_command_t * cmd)
335{
336 unformat_input_t _line_input, *line_input = &_line_input;
Neale Ranns92207752019-06-03 13:21:40 +0000337 fib_route_path_t *rpaths = NULL, rpath;
Neale Ranns5ca2a8a2019-07-29 12:59:45 +0000338 dpo_proto_t payload_proto;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700339 clib_error_t *error = 0;
Neale Ranns92207752019-06-03 13:21:40 +0000340 u32 rx_sw_if_index = ~0;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700341 vnet_main_t *vnm;
342 u8 is_add;
343
344 is_add = 1;
345 vnm = vnet_get_main ();
346
347 if (!unformat_user (main_input, unformat_line_input, line_input))
348 return 0;
349
350 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
351 {
352 if (unformat (line_input, "del"))
353 is_add = 0;
354 else if (unformat (line_input, "add"))
355 is_add = 1;
356 else if (unformat (line_input, "rx all"))
357 rx_sw_if_index = ~0;
358 else if (unformat (line_input, "rx %U",
359 unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
360 ;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700361 else if (unformat (line_input, "via %U",
Neale Ranns5ca2a8a2019-07-29 12:59:45 +0000362 unformat_fib_route_path, &rpath, &payload_proto))
Neale Ranns92207752019-06-03 13:21:40 +0000363 vec_add1 (rpaths, rpath);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700364 else
365 {
366 error = unformat_parse_error (line_input);
367 goto done;
368 }
369 }
370
Neale Ranns92207752019-06-03 13:21:40 +0000371 if (~0 == rx_sw_if_index)
372 {
373 error = unformat_parse_error (line_input);
374 goto done;
375 }
376
Neale Rannsd91c1db2017-07-31 02:30:50 -0700377 if (is_add)
Swarup Nayakecf844c2017-12-11 13:52:44 +0530378 {
Neale Ranns92207752019-06-03 13:21:40 +0000379 if (vec_len (rpaths))
380 ip4_punt_redirect_add_paths (rx_sw_if_index, rpaths);
Swarup Nayakecf844c2017-12-11 13:52:44 +0530381 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700382 else
Swarup Nayakecf844c2017-12-11 13:52:44 +0530383 {
Neale Ranns92207752019-06-03 13:21:40 +0000384 ip4_punt_redirect_del (rx_sw_if_index);
Swarup Nayakecf844c2017-12-11 13:52:44 +0530385 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700386
387done:
388 unformat_free (line_input);
389 return (error);
390}
391
392/*?
393 *
394 * @cliexpar
395 * @cliexcmd{set ip punt policer}
396 ?*/
397/* *INDENT-OFF* */
398VLIB_CLI_COMMAND (ip4_punt_redirect_command, static) =
399{
400 .path = "ip punt redirect",
401 .function = ip4_punt_redirect_cmd,
402 .short_help = "ip punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
403};
404/* *INDENT-ON* */
405
Neale Rannsd91c1db2017-07-31 02:30:50 -0700406static clib_error_t *
407ip4_punt_redirect_show_cmd (vlib_main_t * vm,
408 unformat_input_t * main_input,
409 vlib_cli_command_t * cmd)
410{
Neale Ranns92207752019-06-03 13:21:40 +0000411 vlib_cli_output (vm, "%U", format_ip_punt_redirect, FIB_PROTOCOL_IP4);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700412
413 return (NULL);
414}
415
416/*?
417 *
418 * @cliexpar
419 * @cliexcmd{set ip punt redierect}
420 ?*/
421/* *INDENT-OFF* */
422VLIB_CLI_COMMAND (show_ip4_punt_redirect_command, static) =
423{
424 .path = "show ip punt redirect",
425 .function = ip4_punt_redirect_show_cmd,
Swarup Nayaka3611a72017-12-06 18:55:43 +0530426 .short_help = "show ip punt redirect",
Neale Rannsd91c1db2017-07-31 02:30:50 -0700427 .is_mp_safe = 1,
428};
429/* *INDENT-ON* */
430
431/*
432 * fd.io coding-style-patch-verification: ON
433 *
434 * Local Variables:
435 * eval: (c-set-style "gnu")
436 * End:
437 */