LCOV - code coverage report
Current view: top level - vnet/ip - ip6_punt_drop.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 53 113 46.9 %
Date: 2023-10-26 01:39:38 Functions: 63 84 75.0 %

          Line data    Source code
       1             : /*
       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* */
      22        1151 : VNET_FEATURE_ARC_INIT (ip6_punt) =
      23             : {
      24             :   .arc_name  = "ip6-punt",
      25             :   .start_nodes = VNET_FEATURES ("ip6-punt"),
      26             : };
      27             : 
      28        1151 : VNET_FEATURE_ARC_INIT (ip6_drop) =
      29             : {
      30             :   .arc_name  = "ip6-drop",
      31             :   .start_nodes = VNET_FEATURES ("ip6-drop", "ip6-not-enabled"),
      32             : };
      33             : /* *INDENT-ON* */
      34             : 
      35             : extern ip_punt_policer_t ip6_punt_policer_cfg;
      36             : 
      37             : #ifndef CLIB_MARCH_VARIANT
      38             : ip_punt_policer_t ip6_punt_policer_cfg;
      39             : #endif /* CLIB_MARCH_VARIANT */
      40             : 
      41             : static char *ip6_punt_policer_handoff_error_strings[] = { "congestion drop" };
      42             : 
      43        2303 : VLIB_NODE_FN (ip6_punt_policer_handoff_node)
      44             : (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
      45             : {
      46           3 :   return policer_handoff (vm, node, frame, ip6_punt_policer_cfg.fq_index,
      47             :                           ip6_punt_policer_cfg.policer_index);
      48             : }
      49             : 
      50      183788 : VLIB_REGISTER_NODE (ip6_punt_policer_handoff_node) = {
      51             :   .name = "ip6-punt-policer-handoff",
      52             :   .vector_size = sizeof (u32),
      53             :   .format_trace = format_policer_handoff_trace,
      54             :   .type = VLIB_NODE_TYPE_INTERNAL,
      55             :   .n_errors = ARRAY_LEN(ip6_punt_policer_handoff_error_strings),
      56             :   .error_strings = ip6_punt_policer_handoff_error_strings,
      57             : 
      58             :   .n_next_nodes = 1,
      59             :   .next_nodes = {
      60             :     [0] = "error-drop",
      61             :   },
      62             : };
      63             : 
      64             : static char *ip6_punt_policer_error_strings[] = {
      65             : #define _(sym,string) string,
      66             :   foreach_ip_punt_policer_error
      67             : #undef _
      68             : };
      69             : 
      70        2319 : VLIB_NODE_FN (ip6_punt_policer_node) (vlib_main_t * vm,
      71             :                                       vlib_node_runtime_t * node,
      72             :                                       vlib_frame_t * frame)
      73             : {
      74          38 :   return (ip_punt_policer (vm, node, frame,
      75          19 :                            vnet_feat_arc_ip6_punt.feature_arc_index,
      76             :                            ip6_punt_policer_cfg.policer_index));
      77             : }
      78             : 
      79             : 
      80             : /* *INDENT-OFF* */
      81             : 
      82      183788 : VLIB_REGISTER_NODE (ip6_punt_policer_node) = {
      83             :   .name = "ip6-punt-policer",
      84             :   .vector_size = sizeof (u32),
      85             :   .n_next_nodes = IP_PUNT_POLICER_N_NEXT,
      86             :   .format_trace = format_ip_punt_policer_trace,
      87             :   .n_errors = ARRAY_LEN(ip6_punt_policer_error_strings),
      88             :   .error_strings = ip6_punt_policer_error_strings,
      89             : 
      90             :   /* edit / add dispositions here */
      91             :   .next_nodes = {
      92             :     [IP_PUNT_POLICER_NEXT_DROP] = "ip6-drop",
      93             :     [IP_PUNT_POLICER_NEXT_HANDOFF] = "ip6-punt-policer-handoff",
      94             :   },
      95             : };
      96             : 
      97       76635 : VNET_FEATURE_INIT (ip6_punt_policer_node, static) = {
      98             :   .arc_name = "ip6-punt",
      99             :   .node_name = "ip6-punt-policer",
     100             :   .runs_before = VNET_FEATURES("ip6-punt-redirect")
     101             : };
     102             : /* *INDENT-ON* */
     103             : 
     104        2871 : VLIB_NODE_FN (ip6_drop_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
     105             :                               vlib_frame_t * frame)
     106             : {
     107         571 :   if (node->flags & VLIB_NODE_FLAG_TRACE)
     108         186 :     ip6_forward_next_trace (vm, node, frame, VLIB_TX);
     109             : 
     110        1142 :   return ip_drop_or_punt (vm, node, frame,
     111         571 :                           vnet_feat_arc_ip6_drop.feature_arc_index);
     112             : 
     113             : }
     114             : 
     115        3067 : VLIB_NODE_FN (ip6_not_enabled_node) (vlib_main_t * vm,
     116             :                                      vlib_node_runtime_t * node,
     117             :                                      vlib_frame_t * frame)
     118             : {
     119         767 :   if (node->flags & VLIB_NODE_FLAG_TRACE)
     120          20 :     ip6_forward_next_trace (vm, node, frame, VLIB_TX);
     121             : 
     122        1534 :   return ip_drop_or_punt (vm, node, frame,
     123         767 :                           vnet_feat_arc_ip6_drop.feature_arc_index);
     124             : 
     125             : }
     126             : 
     127        2400 : VLIB_NODE_FN (ip6_punt_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
     128             :                               vlib_frame_t * frame)
     129             : {
     130         100 :   if (node->flags & VLIB_NODE_FLAG_TRACE)
     131          60 :     ip6_forward_next_trace (vm, node, frame, VLIB_TX);
     132             : 
     133         200 :   return ip_drop_or_punt (vm, node, frame,
     134         100 :                           vnet_feat_arc_ip6_punt.feature_arc_index);
     135             : }
     136             : 
     137             : /* *INDENT-OFF* */
     138      183788 : VLIB_REGISTER_NODE (ip6_drop_node) =
     139             : {
     140             :   .name = "ip6-drop",
     141             :   .vector_size = sizeof (u32),
     142             :   .format_trace = format_ip6_forward_next_trace,
     143             :   .n_next_nodes = 1,
     144             :   .next_nodes = {
     145             :     [0] = "error-drop",
     146             :   },
     147             : };
     148             : 
     149      183788 : VLIB_REGISTER_NODE (ip6_not_enabled_node) = {
     150             :   .name = "ip6-not-enabled",
     151             :   .vector_size = sizeof (u32),
     152             :   .format_trace = format_ip6_forward_next_trace,
     153             :   .sibling_of = "ip6-drop",
     154             : };
     155             : 
     156      183788 : VLIB_REGISTER_NODE (ip6_punt_node) =
     157             : {
     158             :   .name = "ip6-punt",
     159             :   .vector_size = sizeof (u32),
     160             :   .format_trace = format_ip6_forward_next_trace,
     161             :   .n_next_nodes = 1,
     162             :   .next_nodes = {
     163             :     [0] = "error-punt",
     164             :   },
     165             : };
     166             : 
     167       76635 : VNET_FEATURE_INIT (ip6_punt_end_of_arc, static) = {
     168             :   .arc_name = "ip6-punt",
     169             :   .node_name = "error-punt",
     170             :   .runs_before = 0, /* not before any other features */
     171             : };
     172             : 
     173       76635 : VNET_FEATURE_INIT (ip6_drop_end_of_arc, static) = {
     174             :   .arc_name = "ip6-drop",
     175             :   .node_name = "error-drop",
     176             :   .runs_before = 0, /* not before any other features */
     177             : };
     178             : /* *INDENT-ON */
     179             : 
     180             : #ifndef CLIB_MARCH_VARIANT
     181             : void
     182           6 : ip6_punt_policer_add_del (u8 is_add, u32 policer_index)
     183             : {
     184           6 :   ip6_punt_policer_cfg.policer_index = policer_index;
     185             : 
     186           6 :   vnet_feature_enable_disable ("ip6-punt", "ip6-punt-policer",
     187             :                                0, is_add, 0, 0);
     188           6 : }
     189             : #endif /* CLIB_MARCH_VARIANT */
     190             : 
     191             : static clib_error_t *
     192           0 : ip6_punt_police_cmd (vlib_main_t * vm,
     193             :                      unformat_input_t * main_input,
     194             :                      vlib_cli_command_t * cmd)
     195             : {
     196           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     197           0 :   clib_error_t *error = 0;
     198             :   u32 policer_index;
     199           0 :   u8 is_add = 1;
     200             : 
     201           0 :   policer_index = ~0;
     202             : 
     203           0 :   if (!unformat_user (main_input, unformat_line_input, line_input))
     204           0 :     return 0;
     205             : 
     206           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     207             :     {
     208           0 :       if (unformat (line_input, "%d", &policer_index))
     209             :         ;
     210           0 :       else if (unformat (line_input, "del"))
     211           0 :         is_add = 0;
     212           0 :       else if (unformat (line_input, "add"))
     213           0 :         is_add = 1;
     214             :       else
     215             :         {
     216           0 :           error = unformat_parse_error (line_input);
     217           0 :           goto done;
     218             :         }
     219             :     }
     220             : 
     221           0 :   if (is_add && ~0 == policer_index)
     222             :   {
     223           0 :       error = clib_error_return (0, "expected policer index `%U'",
     224             :                                  format_unformat_error, line_input);
     225           0 :       goto done;
     226             :   }
     227           0 :   if (!is_add)
     228           0 :       policer_index = ~0;
     229             : 
     230           0 :   ip6_punt_policer_add_del(is_add, policer_index);
     231             : 
     232           0 : done:
     233           0 :   unformat_free (line_input);
     234           0 :   return (error);
     235             : }
     236             : 
     237             : /*?
     238             :  *
     239             :  * @cliexpar
     240             :  * @cliexcmd{set ip punt policer <INDEX>}
     241             :  ?*/
     242             : /* *INDENT-OFF* */
     243      285289 : VLIB_CLI_COMMAND (ip6_punt_policer_command, static) =
     244             : {
     245             :   .path = "ip6 punt policer",
     246             :   .function = ip6_punt_police_cmd,
     247             :   .short_help = "ip6 punt policer [add|del] <index>",
     248             : };
     249             : 
     250             : /* *INDENT-ON* */
     251             : 
     252             : #define foreach_ip6_punt_redirect_error         \
     253             : _(DROP, "ip6 punt redirect drop")
     254             : 
     255             : typedef enum
     256             : {
     257             : #define _(sym,str) IP6_PUNT_REDIRECT_ERROR_##sym,
     258             :   foreach_ip6_punt_redirect_error
     259             : #undef _
     260             :     IP6_PUNT_REDIRECT_N_ERROR,
     261             : } ip6_punt_redirect_error_t;
     262             : 
     263             : static char *ip6_punt_redirect_error_strings[] = {
     264             : #define _(sym,string) string,
     265             :   foreach_ip6_punt_redirect_error
     266             : #undef _
     267             : };
     268             : 
     269        2351 : VLIB_NODE_FN (ip6_punt_redirect_node) (vlib_main_t * vm,
     270             :                                        vlib_node_runtime_t * node,
     271             :                                        vlib_frame_t * frame)
     272             : {
     273         102 :   return (ip_punt_redirect (vm, node, frame,
     274          51 :                             vnet_feat_arc_ip6_punt.feature_arc_index,
     275             :                             FIB_PROTOCOL_IP6));
     276             : }
     277             : 
     278             : /* *INDENT-OFF* */
     279      183788 : VLIB_REGISTER_NODE (ip6_punt_redirect_node) = {
     280             :   .name = "ip6-punt-redirect",
     281             :   .vector_size = sizeof (u32),
     282             :   .n_next_nodes = IP_PUNT_REDIRECT_N_NEXT,
     283             :   .format_trace = format_ip_punt_redirect_trace,
     284             :   .n_errors = ARRAY_LEN(ip6_punt_redirect_error_strings),
     285             :   .error_strings = ip6_punt_redirect_error_strings,
     286             : 
     287             :   /* edit / add dispositions here */
     288             :   .next_nodes = {
     289             :     [IP_PUNT_REDIRECT_NEXT_DROP] = "ip6-drop",
     290             :     [IP_PUNT_REDIRECT_NEXT_TX] = "ip6-rewrite",
     291             :     [IP_PUNT_REDIRECT_NEXT_ARP] = "ip6-discover-neighbor",
     292             :   },
     293             : };
     294             : 
     295       76635 : VNET_FEATURE_INIT (ip6_punt_redirect_node, static) = {
     296             :   .arc_name = "ip6-punt",
     297             :   .node_name = "ip6-punt-redirect",
     298             :   .runs_before = VNET_FEATURES("error-punt")
     299             : };
     300             : /* *INDENT-ON* */
     301             : 
     302             : #ifndef CLIB_MARCH_VARIANT
     303             : 
     304             : static u32 ip6_punt_redirect_enable_counts;
     305             : 
     306             : void
     307          21 : ip6_punt_redirect_add_paths (u32 rx_sw_if_index,
     308             :                              const fib_route_path_t *rpaths)
     309             : {
     310          21 :   ip_punt_redirect_add (FIB_PROTOCOL_IP6,
     311             :                         rx_sw_if_index,
     312             :                         FIB_FORW_CHAIN_TYPE_UNICAST_IP6, rpaths);
     313             : 
     314          21 :   if (1 == ++ip6_punt_redirect_enable_counts)
     315          12 :     vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 1, 0, 0);
     316          21 : }
     317             : 
     318             : void
     319          21 : ip6_punt_redirect_del (u32 rx_sw_if_index)
     320             : {
     321          21 :   ASSERT (ip6_punt_redirect_enable_counts);
     322          21 :   if (0 == --ip6_punt_redirect_enable_counts)
     323          12 :     vnet_feature_enable_disable ("ip6-punt", "ip6-punt-redirect", 0, 0, 0, 0);
     324             : 
     325          21 :   ip_punt_redirect_del (FIB_PROTOCOL_IP6, rx_sw_if_index);
     326          21 : }
     327             : #endif /* CLIB_MARCH_VARIANT */
     328             : 
     329             : static clib_error_t *
     330           0 : ip6_punt_redirect_cmd (vlib_main_t * vm,
     331             :                        unformat_input_t * main_input,
     332             :                        vlib_cli_command_t * cmd)
     333             : {
     334           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     335           0 :   fib_route_path_t *rpaths = NULL, rpath;
     336           0 :   dpo_proto_t payload_proto = DPO_PROTO_IP6;
     337           0 :   clib_error_t *error = 0;
     338           0 :   u32 rx_sw_if_index = ~0;
     339             :   vnet_main_t *vnm;
     340             :   u8 is_add;
     341             : 
     342           0 :   is_add = 1;
     343           0 :   vnm = vnet_get_main ();
     344             : 
     345           0 :   if (!unformat_user (main_input, unformat_line_input, line_input))
     346           0 :     return 0;
     347             : 
     348           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     349             :     {
     350           0 :       if (unformat (line_input, "del"))
     351           0 :         is_add = 0;
     352           0 :       else if (unformat (line_input, "add"))
     353           0 :         is_add = 1;
     354           0 :       else if (unformat (line_input, "rx all"))
     355           0 :         rx_sw_if_index = 0;
     356           0 :       else if (unformat (line_input, "rx %U",
     357             :                          unformat_vnet_sw_interface, vnm, &rx_sw_if_index))
     358             :         ;
     359           0 :       else if (unformat (line_input, "via %U",
     360             :                          unformat_fib_route_path, &rpath, &payload_proto))
     361           0 :         vec_add1 (rpaths, rpath);
     362             :       else
     363             :         {
     364           0 :           error = unformat_parse_error (line_input);
     365           0 :           goto done;
     366             :         }
     367             :     }
     368             : 
     369           0 :   if (~0 == rx_sw_if_index)
     370             :     {
     371           0 :       error = unformat_parse_error (line_input);
     372           0 :       goto done;
     373             :     }
     374             : 
     375           0 :   if (is_add)
     376             :     {
     377           0 :       if (vec_len (rpaths))
     378           0 :         ip6_punt_redirect_add_paths (rx_sw_if_index, rpaths);
     379             :     }
     380             :   else
     381             :     {
     382           0 :       ip6_punt_redirect_del (rx_sw_if_index);
     383             :     }
     384             : 
     385           0 : done:
     386           0 :   vec_free (rpaths);
     387           0 :   unformat_free (line_input);
     388           0 :   return (error);
     389             : }
     390             : 
     391             : /*?
     392             :  *
     393             :  * @cliexpar
     394             :  * @cliexcmd{set ip punt policer <INDEX>}
     395             :  ?*/
     396             : /* *INDENT-OFF* */
     397      285289 : VLIB_CLI_COMMAND (ip6_punt_redirect_command, static) =
     398             : {
     399             :   .path = "ip6 punt redirect",
     400             :   .function = ip6_punt_redirect_cmd,
     401             :   .short_help = "ip6 punt redirect [add|del] rx [<interface>|all] via [<nh>] <tx_interface>",
     402             : };
     403             : /* *INDENT-ON* */
     404             : 
     405             : #ifndef CLIB_MARCH_VARIANT
     406             : 
     407             : #endif /* CLIB_MARCH_VARIANT */
     408             : 
     409             : static clib_error_t *
     410           0 : ip6_punt_redirect_show_cmd (vlib_main_t * vm,
     411             :                             unformat_input_t * main_input,
     412             :                             vlib_cli_command_t * cmd)
     413             : {
     414           0 :   vlib_cli_output (vm, "%U", format_ip_punt_redirect, FIB_PROTOCOL_IP6);
     415             : 
     416           0 :   return (NULL);
     417             : }
     418             : 
     419             : /*?
     420             :  *
     421             :  * @cliexpar
     422             :  * @cliexcmd{set ip punt policer <INDEX>}
     423             :  ?*/
     424             : /* *INDENT-OFF* */
     425      285289 : VLIB_CLI_COMMAND (show_ip6_punt_redirect_command, static) =
     426             : {
     427             :   .path = "show ip6 punt redirect",
     428             :   .function = ip6_punt_redirect_show_cmd,
     429             :   .short_help = "show ip6 punt redirect",
     430             :   .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             :  */

Generated by: LCOV version 1.14