blob: fc5a68fc66a0bbed8686c5c9d610e8ae879da176 [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,
190 .n_next_nodes = 1,
191 .next_nodes = {
192 [0] = "error-drop",
193 },
194};
195
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700196VLIB_REGISTER_NODE (ip4_punt_node) =
Neale Rannsd91c1db2017-07-31 02:30:50 -0700197{
198 .function = ip4_punt,
199 .name = "ip4-punt",
200 .vector_size = sizeof (u32),
201 .format_trace = format_ip4_forward_next_trace,
202 .n_next_nodes = 1,
203 .next_nodes = {
204 [0] = "error-punt",
205 },
206};
207
208VNET_FEATURE_INIT (ip4_punt_end_of_arc, static) = {
209 .arc_name = "ip4-punt",
210 .node_name = "error-punt",
211 .runs_before = 0, /* not before any other features */
212};
213
214VNET_FEATURE_INIT (ip4_drop_end_of_arc, static) = {
215 .arc_name = "ip4-drop",
216 .node_name = "error-drop",
217 .runs_before = 0, /* not before any other features */
218};
219/* *INDENT-ON */
220
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700221#ifndef CLIB_MARCH_VARIANT
Neale Rannsd91c1db2017-07-31 02:30:50 -0700222void
223ip4_punt_policer_add_del (u8 is_add, u32 policer_index)
224{
225 ip4_punt_policer_cfg.policer_index = policer_index;
226
227 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-policer",
228 0, is_add, 0, 0);
229}
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700230#endif /* CLIB_MARCH_VARIANT */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700231
232static clib_error_t *
233ip4_punt_police_cmd (vlib_main_t * vm,
234 unformat_input_t * main_input,
235 vlib_cli_command_t * cmd)
236{
237 unformat_input_t _line_input, *line_input = &_line_input;
238 clib_error_t *error = 0;
239 u32 policer_index;
240 u8 is_add = 1;
241
242 policer_index = ~0;
243
244 if (!unformat_user (main_input, unformat_line_input, line_input))
245 return 0;
246
247 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
248 {
249 if (unformat (line_input, "%d", &policer_index))
250 ;
251 else if (unformat (line_input, "del"))
252 is_add = 0;
253 else if (unformat (line_input, "add"))
254 is_add = 1;
255 else
256 {
257 error = unformat_parse_error (line_input);
258 goto done;
259 }
260 }
261
262 if (is_add && ~0 == policer_index)
263 {
264 error = clib_error_return (0, "expected policer index `%U'",
265 format_unformat_error, line_input);
266 goto done;
267 }
268 if (!is_add)
269 policer_index = ~0;
270
271 ip4_punt_policer_add_del(is_add, policer_index);
272
273done:
274 unformat_free (line_input);
275 return (error);
276}
277
278/*?
279 *
280 * @cliexpar
281 * @cliexcmd{set ip punt policer <INDEX>}
282 ?*/
283/* *INDENT-OFF* */
284VLIB_CLI_COMMAND (ip4_punt_policer_command, static) =
285{
286 .path = "ip punt policer",
287 .function = ip4_punt_police_cmd,
288 .short_help = "ip punt policer [add|del] <index>",
289};
290/* *INDENT-ON* */
291
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700292#ifndef CLIB_MARCH_VARIANT
Neale Rannsd91c1db2017-07-31 02:30:50 -0700293
294void
295ip4_punt_redirect_add (u32 rx_sw_if_index,
296 u32 tx_sw_if_index, ip46_address_t * nh)
297{
Neale Ranns92207752019-06-03 13:21:40 +0000298 /* *INDENT-OFF* */
299 fib_route_path_t *rpaths = NULL, rpath = {
300 .frp_proto = DPO_PROTO_IP4,
301 .frp_addr = *nh,
302 .frp_sw_if_index = tx_sw_if_index,
303 .frp_weight = 1,
304 .frp_fib_index = ~0,
Neale Rannsd91c1db2017-07-31 02:30:50 -0700305 };
Neale Ranns92207752019-06-03 13:21:40 +0000306 /* *INDENT-ON* */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700307
Neale Ranns92207752019-06-03 13:21:40 +0000308 vec_add1 (rpaths, rpath);
309
310 ip4_punt_redirect_add_paths (rx_sw_if_index, rpaths);
311
312 vec_free (rpaths);
313}
314
315void
316ip4_punt_redirect_add_paths (u32 rx_sw_if_index, fib_route_path_t * rpaths)
317{
318 ip_punt_redirect_add (FIB_PROTOCOL_IP4,
319 rx_sw_if_index,
320 FIB_FORW_CHAIN_TYPE_UNICAST_IP4, rpaths);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700321
322 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-redirect", 0, 1, 0, 0);
323}
324
325void
326ip4_punt_redirect_del (u32 rx_sw_if_index)
327{
328 vnet_feature_enable_disable ("ip4-punt", "ip4-punt-redirect", 0, 0, 0, 0);
329
Neale Ranns92207752019-06-03 13:21:40 +0000330 ip_punt_redirect_del (FIB_PROTOCOL_IP4, rx_sw_if_index);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700331}
Filip Tehlar26ea14e2019-03-11 05:30:21 -0700332#endif /* CLIB_MARCH_VARIANT */
Neale Rannsd91c1db2017-07-31 02:30:50 -0700333
334static clib_error_t *
335ip4_punt_redirect_cmd (vlib_main_t * vm,
336 unformat_input_t * main_input,
337 vlib_cli_command_t * cmd)
338{
339 unformat_input_t _line_input, *line_input = &_line_input;
Neale Ranns92207752019-06-03 13:21:40 +0000340 fib_route_path_t *rpaths = NULL, rpath;
Neale Ranns5ca2a8a2019-07-29 12:59:45 +0000341 dpo_proto_t payload_proto;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700342 clib_error_t *error = 0;
Neale Ranns92207752019-06-03 13:21:40 +0000343 u32 rx_sw_if_index = ~0;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700344 vnet_main_t *vnm;
345 u8 is_add;
346
347 is_add = 1;
348 vnm = vnet_get_main ();
349
350 if (!unformat_user (main_input, unformat_line_input, line_input))
351 return 0;
352
353 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
354 {
355 if (unformat (line_input, "del"))
356 is_add = 0;
357 else if (unformat (line_input, "add"))
358 is_add = 1;
359 else if (unformat (line_input, "rx all"))
360 rx_sw_if_index = ~0;
361 else if (unformat (line_input, "rx %U",
362 unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
363 ;
Neale Rannsd91c1db2017-07-31 02:30:50 -0700364 else if (unformat (line_input, "via %U",
Neale Ranns5ca2a8a2019-07-29 12:59:45 +0000365 unformat_fib_route_path, &rpath, &payload_proto))
Neale Ranns92207752019-06-03 13:21:40 +0000366 vec_add1 (rpaths, rpath);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700367 else
368 {
369 error = unformat_parse_error (line_input);
370 goto done;
371 }
372 }
373
Neale Ranns92207752019-06-03 13:21:40 +0000374 if (~0 == rx_sw_if_index)
375 {
376 error = unformat_parse_error (line_input);
377 goto done;
378 }
379
Neale Rannsd91c1db2017-07-31 02:30:50 -0700380 if (is_add)
Swarup Nayakecf844c2017-12-11 13:52:44 +0530381 {
Neale Ranns92207752019-06-03 13:21:40 +0000382 if (vec_len (rpaths))
383 ip4_punt_redirect_add_paths (rx_sw_if_index, rpaths);
Swarup Nayakecf844c2017-12-11 13:52:44 +0530384 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700385 else
Swarup Nayakecf844c2017-12-11 13:52:44 +0530386 {
Neale Ranns92207752019-06-03 13:21:40 +0000387 ip4_punt_redirect_del (rx_sw_if_index);
Swarup Nayakecf844c2017-12-11 13:52:44 +0530388 }
Neale Rannsd91c1db2017-07-31 02:30:50 -0700389
390done:
391 unformat_free (line_input);
392 return (error);
393}
394
395/*?
396 *
397 * @cliexpar
398 * @cliexcmd{set ip punt policer}
399 ?*/
400/* *INDENT-OFF* */
401VLIB_CLI_COMMAND (ip4_punt_redirect_command, static) =
402{
403 .path = "ip punt redirect",
404 .function = ip4_punt_redirect_cmd,
405 .short_help = "ip punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
406};
407/* *INDENT-ON* */
408
Neale Rannsd91c1db2017-07-31 02:30:50 -0700409static clib_error_t *
410ip4_punt_redirect_show_cmd (vlib_main_t * vm,
411 unformat_input_t * main_input,
412 vlib_cli_command_t * cmd)
413{
Neale Ranns92207752019-06-03 13:21:40 +0000414 vlib_cli_output (vm, "%U", format_ip_punt_redirect, FIB_PROTOCOL_IP4);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700415
416 return (NULL);
417}
418
419/*?
420 *
421 * @cliexpar
422 * @cliexcmd{set ip punt redierect}
423 ?*/
424/* *INDENT-OFF* */
425VLIB_CLI_COMMAND (show_ip4_punt_redirect_command, static) =
426{
427 .path = "show ip punt redirect",
428 .function = ip4_punt_redirect_show_cmd,
Swarup Nayaka3611a72017-12-06 18:55:43 +0530429 .short_help = "show ip punt redirect",
Neale Rannsd91c1db2017-07-31 02:30:50 -0700430 .is_mp_safe = 1,
431};
432/* *INDENT-ON* */
433
434/*
435 * fd.io coding-style-patch-verification: ON
436 *
437 * Local Variables:
438 * eval: (c-set-style "gnu")
439 * End:
440 */