LCOV - code coverage report
Current view: top level - vnet/srv6 - sr_steering.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 119 227 52.4 %
Date: 2023-10-26 01:39:38 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /*
       2             :  * sr_steering.c: ipv6 segment routing steering into SR policy
       3             :  *
       4             :  * Copyright (c) 2016 Cisco and/or its affiliates.
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at:
       8             :  *
       9             :  *     http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : 
      18             : /**
      19             :  * @file
      20             :  * @brief Packet steering into SR Policies
      21             :  *
      22             :  * This file is in charge of handling the FIB appropiatly to steer packets
      23             :  * through SR Policies as defined in 'sr_policy_rewrite.c'. Notice that here
      24             :  * we are only doing steering. SR policy application is done in
      25             :  * sr_policy_rewrite.c
      26             :  *
      27             :  * Supports:
      28             :  *  - Steering of IPv6 traffic Destination Address based
      29             :  *  - Steering of IPv4 traffic Destination Address based
      30             :  *  - Steering of L2 frames, interface based (sw interface)
      31             :  */
      32             : 
      33             : #include <vlib/vlib.h>
      34             : #include <vnet/vnet.h>
      35             : #include <vnet/srv6/sr.h>
      36             : #include <vnet/ip/ip.h>
      37             : #include <vnet/srv6/sr_packet.h>
      38             : #include <vnet/ip/ip6_packet.h>
      39             : #include <vnet/fib/ip6_fib.h>
      40             : #include <vnet/dpo/dpo.h>
      41             : 
      42             : #include <vppinfra/error.h>
      43             : #include <vppinfra/elog.h>
      44             : 
      45             : /**
      46             :  * @brief Steer traffic L2 and L3 traffic through a given SR policy
      47             :  *
      48             :  * @param is_del
      49             :  * @param bsid is the bindingSID of the SR Policy (alt to sr_policy_index)
      50             :  * @param sr_policy is the index of the SR Policy (alt to bsid)
      51             :  * @param table_id is the VRF where to install the FIB entry for the BSID
      52             :  * @param prefix is the IPv4/v6 address for L3 traffic type
      53             :  * @param mask_width is the mask for L3 traffic type
      54             :  * @param sw_if_index is the incoming interface for L2 traffic
      55             :  * @param traffic_type describes the type of traffic
      56             :  *
      57             :  * @return 0 if correct, else error
      58             :  */
      59             : int
      60           3 : sr_steering_policy (int is_del, ip6_address_t * bsid, u32 sr_policy_index,
      61             :                     u32 table_id, ip46_address_t * prefix, u32 mask_width,
      62             :                     u32 sw_if_index, u8 traffic_type)
      63             : {
      64           3 :   ip6_sr_main_t *sm = &sr_main;
      65             :   sr_steering_key_t key;
      66             :   ip6_sr_steering_policy_t *steer_pl;
      67           3 :   fib_prefix_t pfx = { 0 };
      68             : 
      69           3 :   ip6_sr_policy_t *sr_policy = 0;
      70           3 :   uword *p = 0;
      71             : 
      72           3 :   clib_memset (&key, 0, sizeof (sr_steering_key_t));
      73             : 
      74             :   /* Compute the steer policy key */
      75           3 :   if (traffic_type == SR_STEER_IPV4 || traffic_type == SR_STEER_IPV6)
      76             :     {
      77           3 :       key.l3.prefix.as_u64[0] = prefix->as_u64[0];
      78           3 :       key.l3.prefix.as_u64[1] = prefix->as_u64[1];
      79           3 :       key.l3.mask_width = mask_width;
      80           3 :       key.l3.fib_table = (table_id != (u32) ~ 0 ? table_id : 0);
      81             :     }
      82           0 :   else if (traffic_type == SR_STEER_L2)
      83             :     {
      84           0 :       key.l2.sw_if_index = sw_if_index;
      85             : 
      86             :       /* Sanitise the SW_IF_INDEX */
      87           0 :       if (pool_is_free_index (sm->vnet_main->interface_main.sw_interfaces,
      88             :                               sw_if_index))
      89           0 :         return -3;
      90             : 
      91             :       vnet_sw_interface_t *sw =
      92           0 :         vnet_get_sw_interface (sm->vnet_main, sw_if_index);
      93           0 :       if (sw->type != VNET_SW_INTERFACE_TYPE_HARDWARE)
      94           0 :         return -3;
      95             :     }
      96             :   else
      97           0 :     return -1;
      98             : 
      99           3 :   key.traffic_type = traffic_type;
     100             : 
     101             :   /* Search for the item */
     102           3 :   p = mhash_get (&sm->sr_steer_policies_hash, &key);
     103             : 
     104           3 :   if (p)
     105             :     {
     106             :       /* Retrieve Steer Policy function */
     107           1 :       steer_pl = pool_elt_at_index (sm->steer_policies, p[0]);
     108             : 
     109           1 :       if (is_del)
     110             :         {
     111           1 :           if (steer_pl->classify.traffic_type == SR_STEER_IPV6)
     112             :             {
     113             :               /* Remove FIB entry */
     114           1 :               pfx.fp_proto = FIB_PROTOCOL_IP6;
     115           1 :               pfx.fp_len = steer_pl->classify.l3.mask_width;
     116           1 :               pfx.fp_addr.ip6 = steer_pl->classify.l3.prefix.ip6;
     117             : 
     118           1 :               fib_table_entry_delete (fib_table_find
     119             :                                       (FIB_PROTOCOL_IP6,
     120           1 :                                        steer_pl->classify.l3.fib_table),
     121             :                                       &pfx, FIB_SOURCE_SR);
     122             :             }
     123           0 :           else if (steer_pl->classify.traffic_type == SR_STEER_IPV4)
     124             :             {
     125             :               /* Remove FIB entry */
     126           0 :               pfx.fp_proto = FIB_PROTOCOL_IP4;
     127           0 :               pfx.fp_len = steer_pl->classify.l3.mask_width;
     128           0 :               pfx.fp_addr.ip4 = steer_pl->classify.l3.prefix.ip4;
     129             : 
     130           0 :               fib_table_entry_delete (fib_table_find
     131             :                                       (FIB_PROTOCOL_IP4,
     132           0 :                                        steer_pl->classify.l3.fib_table), &pfx,
     133             :                                       FIB_SOURCE_SR);
     134             :             }
     135           0 :           else if (steer_pl->classify.traffic_type == SR_STEER_L2)
     136             :             {
     137             :               /* Remove HW redirection */
     138           0 :               int ret = vnet_feature_enable_disable ("device-input",
     139             :                                                      "sr-pl-rewrite-encaps-l2",
     140             :                                                      sw_if_index, 0, 0, 0);
     141             : 
     142           0 :               if (ret != 0)
     143           0 :                 return -1;
     144             : 
     145           0 :               sm->sw_iface_sr_policies[sw_if_index] = ~(u32) 0;
     146             : 
     147             :               /* Remove promiscous mode from interface */
     148           0 :               vnet_main_t *vnm = vnet_get_main ();
     149             :               vnet_hw_interface_t *hi =
     150           0 :                 vnet_get_sup_hw_interface (vnm, sw_if_index);
     151             :               /* Make sure it is main interface */
     152           0 :               if (hi->sw_if_index == sw_if_index)
     153           0 :                 ethernet_set_flags (vnm, hi->hw_if_index, 0);
     154             :             }
     155             : 
     156             :           /* Delete SR steering policy entry */
     157           1 :           pool_put (sm->steer_policies, steer_pl);
     158           1 :           mhash_unset (&sm->sr_steer_policies_hash, &key, NULL);
     159             : 
     160             :           /* If no more SR policies or steering policies */
     161           1 :           if (!pool_elts (sm->sr_policies) && !pool_elts (sm->steer_policies))
     162             :             {
     163           0 :               fib_table_unlock (sm->fib_table_ip6,
     164             :                                 FIB_PROTOCOL_IP6, FIB_SOURCE_SR);
     165           0 :               fib_table_unlock (sm->fib_table_ip4,
     166             :                                 FIB_PROTOCOL_IP6, FIB_SOURCE_SR);
     167           0 :               sm->fib_table_ip6 = (u32) ~ 0;
     168           0 :               sm->fib_table_ip4 = (u32) ~ 0;
     169             :             }
     170             : 
     171           1 :           return 0;
     172             :         }
     173             :       else                      /* It means user requested to update an existing SR steering policy */
     174             :         {
     175             :           /* Retrieve SR steering policy */
     176           0 :           if (bsid)
     177             :             {
     178           0 :               p = mhash_get (&sm->sr_policies_index_hash, bsid);
     179           0 :               if (p)
     180           0 :                 sr_policy = pool_elt_at_index (sm->sr_policies, p[0]);
     181             :               else
     182           0 :                 return -2;
     183             :             }
     184             :           else
     185           0 :             sr_policy = pool_elt_at_index (sm->sr_policies, sr_policy_index);
     186             : 
     187           0 :           steer_pl->sr_policy = sr_policy - sm->sr_policies;
     188             : 
     189             :           /* Remove old FIB/hw redirection and create a new one */
     190           0 :           if (steer_pl->classify.traffic_type == SR_STEER_IPV6)
     191             :             {
     192             :               /* Remove FIB entry */
     193           0 :               pfx.fp_proto = FIB_PROTOCOL_IP6;
     194           0 :               pfx.fp_len = steer_pl->classify.l3.mask_width;
     195           0 :               pfx.fp_addr.ip6 = steer_pl->classify.l3.prefix.ip6;
     196             : 
     197           0 :               fib_table_entry_delete (fib_table_find
     198             :                                       (FIB_PROTOCOL_IP6,
     199           0 :                                        steer_pl->classify.l3.fib_table),
     200             :                                       &pfx, FIB_SOURCE_SR);
     201             : 
     202             :               /* Create a new one */
     203           0 :               goto update_fib;
     204             :             }
     205           0 :           else if (steer_pl->classify.traffic_type == SR_STEER_IPV4)
     206             :             {
     207             :               /* Remove FIB entry */
     208           0 :               pfx.fp_proto = FIB_PROTOCOL_IP4;
     209           0 :               pfx.fp_len = steer_pl->classify.l3.mask_width;
     210           0 :               pfx.fp_addr.ip4 = steer_pl->classify.l3.prefix.ip4;
     211             : 
     212           0 :               fib_table_entry_delete (fib_table_find
     213             :                                       (FIB_PROTOCOL_IP4,
     214           0 :                                        steer_pl->classify.l3.fib_table),
     215             :                                       &pfx, FIB_SOURCE_SR);
     216             : 
     217             :               /* Create a new one */
     218           0 :               goto update_fib;
     219             :             }
     220           0 :           else if (steer_pl->classify.traffic_type == SR_STEER_L2)
     221             :             {
     222             :               /* Update L2-HW redirection */
     223           0 :               goto update_fib;
     224             :             }
     225             :         }
     226             :     }
     227             :   else
     228             :     /* delete; steering policy does not exist; complain */
     229           2 :   if (is_del)
     230           0 :     return -4;
     231             : 
     232             :   /* Retrieve SR policy */
     233           2 :   if (bsid)
     234             :     {
     235           2 :       p = mhash_get (&sm->sr_policies_index_hash, bsid);
     236           2 :       if (p)
     237           2 :         sr_policy = pool_elt_at_index (sm->sr_policies, p[0]);
     238             :       else
     239           0 :         return -2;
     240             :     }
     241             :   else
     242           0 :     sr_policy = pool_elt_at_index (sm->sr_policies, sr_policy_index);
     243             : 
     244             :   /* Create a new steering policy */
     245           2 :   pool_get (sm->steer_policies, steer_pl);
     246           2 :   clib_memset (steer_pl, 0, sizeof (*steer_pl));
     247             : 
     248           2 :   if (traffic_type == SR_STEER_IPV4 || traffic_type == SR_STEER_IPV6)
     249             :     {
     250           2 :       clib_memcpy_fast (&steer_pl->classify.l3.prefix, prefix,
     251             :                         sizeof (ip46_address_t));
     252           2 :       steer_pl->classify.l3.mask_width = mask_width;
     253           2 :       steer_pl->classify.l3.fib_table =
     254           2 :         (table_id != (u32) ~ 0 ? table_id : 0);
     255           2 :       steer_pl->classify.traffic_type = traffic_type;
     256             :     }
     257           0 :   else if (traffic_type == SR_STEER_L2)
     258             :     {
     259           0 :       steer_pl->classify.l2.sw_if_index = sw_if_index;
     260           0 :       steer_pl->classify.traffic_type = traffic_type;
     261             :     }
     262             :   else
     263             :     {
     264             :       /* Incorrect API usage. Should never get here */
     265           0 :       pool_put (sm->steer_policies, steer_pl);
     266           0 :       mhash_unset (&sm->sr_steer_policies_hash, &key, NULL);
     267           0 :       return -1;
     268             :     }
     269           2 :   steer_pl->sr_policy = sr_policy - sm->sr_policies;
     270             : 
     271             :   /* Create and store key */
     272           2 :   mhash_set (&sm->sr_steer_policies_hash, &key, steer_pl - sm->steer_policies,
     273             :              NULL);
     274             : 
     275           2 :   if (traffic_type == SR_STEER_L2)
     276             :     {
     277           0 :       if (!sr_policy->is_encap)
     278           0 :         goto cleanup_error_encap;
     279             : 
     280           0 :       if (vnet_feature_enable_disable
     281             :           ("device-input", "sr-pl-rewrite-encaps-l2", sw_if_index, 1, 0, 0))
     282           0 :         goto cleanup_error_redirection;
     283             : 
     284             :       /* Set promiscous mode on interface */
     285           0 :       vnet_main_t *vnm = vnet_get_main ();
     286           0 :       vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
     287             :       /* Make sure it is main interface */
     288           0 :       if (hi->sw_if_index == sw_if_index)
     289           0 :         ethernet_set_flags (vnm, hi->hw_if_index,
     290             :                             ETHERNET_INTERFACE_FLAG_ACCEPT_ALL);
     291             :     }
     292           2 :   else if (traffic_type == SR_STEER_IPV4)
     293           1 :     if (!sr_policy->is_encap)
     294           0 :       goto cleanup_error_encap;
     295             : 
     296           2 : update_fib:
     297             :   /* FIB API calls - Recursive route through the BindingSID */
     298           2 :   if (traffic_type == SR_STEER_IPV6)
     299             :     {
     300           1 :       pfx.fp_proto = FIB_PROTOCOL_IP6;
     301           1 :       pfx.fp_len = steer_pl->classify.l3.mask_width;
     302           1 :       pfx.fp_addr.ip6 = steer_pl->classify.l3.prefix.ip6;
     303             : 
     304           1 :       fib_table_entry_path_add (fib_table_find (FIB_PROTOCOL_IP6,
     305             :                                                 (table_id !=
     306             :                                                  (u32) ~ 0 ?
     307             :                                                  table_id : 0)),
     308             :                                 &pfx, FIB_SOURCE_SR,
     309             :                                 FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT,
     310             :                                 DPO_PROTO_IP6,
     311           1 :                                 (ip46_address_t *) & sr_policy->bsid, ~0,
     312             :                                 sm->fib_table_ip6, 1, NULL,
     313             :                                 FIB_ROUTE_PATH_FLAG_NONE);
     314             :     }
     315           1 :   else if (traffic_type == SR_STEER_IPV4)
     316             :     {
     317           1 :       pfx.fp_proto = FIB_PROTOCOL_IP4;
     318           1 :       pfx.fp_len = steer_pl->classify.l3.mask_width;
     319           1 :       pfx.fp_addr.ip4 = steer_pl->classify.l3.prefix.ip4;
     320             : 
     321           1 :       fib_table_entry_path_add (fib_table_find (FIB_PROTOCOL_IP4,
     322             :                                                 (table_id !=
     323             :                                                  (u32) ~ 0 ?
     324             :                                                  table_id : 0)),
     325             :                                 &pfx, FIB_SOURCE_SR,
     326             :                                 FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT,
     327             :                                 DPO_PROTO_IP6,
     328           1 :                                 (ip46_address_t *) & sr_policy->bsid, ~0,
     329             :                                 sm->fib_table_ip4, 1, NULL,
     330             :                                 FIB_ROUTE_PATH_FLAG_NONE);
     331             :     }
     332           0 :   else if (traffic_type == SR_STEER_L2)
     333             :     {
     334           0 :       if (sw_if_index < vec_len (sm->sw_iface_sr_policies))
     335           0 :         sm->sw_iface_sr_policies[sw_if_index] = steer_pl->sr_policy;
     336             :       else
     337             :         {
     338           0 :           vec_resize (sm->sw_iface_sr_policies,
     339             :                       (pool_len (sm->vnet_main->interface_main.sw_interfaces)
     340             :                        - vec_len (sm->sw_iface_sr_policies)));
     341           0 :           sm->sw_iface_sr_policies[sw_if_index] = steer_pl->sr_policy;
     342             :         }
     343             :     }
     344             : 
     345           2 :   return 0;
     346             : 
     347           0 : cleanup_error_encap:
     348           0 :   pool_put (sm->steer_policies, steer_pl);
     349           0 :   mhash_unset (&sm->sr_steer_policies_hash, &key, NULL);
     350           0 :   return -5;
     351             : 
     352           0 : cleanup_error_redirection:
     353           0 :   pool_put (sm->steer_policies, steer_pl);
     354           0 :   mhash_unset (&sm->sr_steer_policies_hash, &key, NULL);
     355           0 :   return -3;
     356             : }
     357             : 
     358             : static clib_error_t *
     359           1 : sr_steer_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
     360             :                             vlib_cli_command_t * cmd)
     361             : {
     362           1 :   vnet_main_t *vnm = vnet_get_main ();
     363             : 
     364           1 :   int is_del = 0;
     365             : 
     366             :   ip46_address_t prefix;
     367           1 :   u32 dst_mask_width = 0;
     368           1 :   u32 sw_if_index = (u32) ~ 0;
     369           1 :   u8 traffic_type = 0;
     370           1 :   u32 fib_table = (u32) ~ 0;
     371             : 
     372             :   ip6_address_t bsid;
     373           1 :   u32 sr_policy_index = (u32) ~ 0;
     374             : 
     375           1 :   u8 sr_policy_set = 0;
     376             : 
     377           1 :   clib_memset (&prefix, 0, sizeof (ip46_address_t));
     378             : 
     379             :   int rv;
     380           3 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     381             :     {
     382           2 :       if (unformat (input, "del"))
     383           0 :         is_del = 1;
     384           2 :       else if (!traffic_type
     385           1 :                && unformat (input, "l3 %U/%d", unformat_ip6_address,
     386             :                             &prefix.ip6, &dst_mask_width))
     387           0 :         traffic_type = SR_STEER_IPV6;
     388           2 :       else if (!traffic_type
     389           1 :                && unformat (input, "l3 %U/%d", unformat_ip4_address,
     390             :                             &prefix.ip4, &dst_mask_width))
     391           1 :         traffic_type = SR_STEER_IPV4;
     392           1 :       else if (!traffic_type
     393           0 :                && unformat (input, "l2 %U", unformat_vnet_sw_interface, vnm,
     394             :                             &sw_if_index))
     395           0 :         traffic_type = SR_STEER_L2;
     396           1 :       else if (!sr_policy_set
     397           1 :                && unformat (input, "via index %d", &sr_policy_index))
     398           0 :         sr_policy_set = 1;
     399           1 :       else if (!sr_policy_set
     400           1 :                && unformat (input, "via bsid %U",
     401             :                             unformat_ip6_address, &bsid))
     402           1 :         sr_policy_set = 1;
     403           0 :       else if (fib_table == (u32) ~ 0
     404           0 :                && unformat (input, "fib-table %d", &fib_table));
     405             :       else
     406             :         break;
     407             :     }
     408             : 
     409           1 :   if (!traffic_type)
     410           0 :     return clib_error_return (0, "No L2/L3 traffic specified");
     411           1 :   if (!is_del && !sr_policy_set)
     412           0 :     return clib_error_return (0, "No SR policy specified");
     413             : 
     414             :   /* Make sure that the prefixes are clean */
     415           1 :   if (traffic_type == SR_STEER_IPV4)
     416             :     {
     417           1 :       u32 mask =
     418           1 :         (dst_mask_width ? (0xFFFFFFFFu >> (32 - dst_mask_width)) : 0);
     419           1 :       prefix.ip4.as_u32 &= mask;
     420             :     }
     421           0 :   else if (traffic_type == SR_STEER_IPV6)
     422             :     {
     423             :       ip6_address_t mask;
     424           0 :       ip6_address_mask_from_width (&mask, dst_mask_width);
     425           0 :       ip6_address_mask (&prefix.ip6, &mask);
     426             :     }
     427             : 
     428             :   rv =
     429           1 :     sr_steering_policy (is_del, (sr_policy_index == ~(u32) 0 ? &bsid : NULL),
     430             :                         sr_policy_index, fib_table, &prefix, dst_mask_width,
     431             :                         sw_if_index, traffic_type);
     432             : 
     433           1 :   switch (rv)
     434             :     {
     435           1 :     case 0:
     436           1 :       break;
     437           0 :     case 1:
     438           0 :       return 0;
     439           0 :     case -1:
     440           0 :       return clib_error_return (0, "Incorrect API usage.");
     441           0 :     case -2:
     442           0 :       return clib_error_return (0,
     443             :                                 "The requested SR policy could not be located. Review the BSID/index.");
     444           0 :     case -3:
     445           0 :       return clib_error_return (0,
     446             :                                 "Unable to do SW redirect. Incorrect interface.");
     447           0 :     case -4:
     448           0 :       return clib_error_return (0,
     449             :                                 "The requested SR steering policy could not be deleted.");
     450           0 :     case -5:
     451           0 :       return clib_error_return (0,
     452             :                                 "The SR policy is not an encapsulation one.");
     453           0 :     default:
     454           0 :       return clib_error_return (0, "BUG: sr steer policy returns %d", rv);
     455             :     }
     456           1 :   return 0;
     457             : }
     458             : 
     459             : /* *INDENT-OFF* */
     460      285289 : VLIB_CLI_COMMAND (sr_steer_policy_command, static) = {
     461             :   .path = "sr steer",
     462             :   .short_help = "sr steer (del) [l3 <ip_addr/mask>|l2 <sf_if>] "
     463             :     "via [index <sr_policy_index>|bsid <bsid_ip6_addr>] "
     464             :     "(fib-table <fib_table_index>)",
     465             :   .long_help =
     466             :     "\tSteer a L2 or L3 traffic through an existing SR policy.\n"
     467             :     "\tExamples:\n"
     468             :     "\t\tsr steer l3 2001::/64 via sr_policy index 5\n"
     469             :     "\t\tsr steer l3 2001::/64 via sr_policy bsid 2010::9999:1\n"
     470             :     "\t\tsr steer l2 GigabitEthernet0/5/0 via sr_policy index 5\n"
     471             :     "\t\tsr steer del l3 2001::/64 via sr_policy index 5\n",
     472             :   .function = sr_steer_policy_command_fn,
     473             : };
     474             : /* *INDENT-ON* */
     475             : 
     476             : static clib_error_t *
     477           3 : show_sr_steering_policies_command_fn (vlib_main_t * vm,
     478             :                                       unformat_input_t * input,
     479             :                                       vlib_cli_command_t * cmd)
     480             : {
     481           3 :   ip6_sr_main_t *sm = &sr_main;
     482           3 :   ip6_sr_steering_policy_t **steer_policies = 0;
     483             :   ip6_sr_steering_policy_t *steer_pl;
     484             : 
     485           3 :   vnet_main_t *vnm = vnet_get_main ();
     486             : 
     487           3 :   ip6_sr_policy_t *pl = 0;
     488             :   int i;
     489             : 
     490           3 :   vlib_cli_output (vm, "SR steering policies:");
     491             :   /* *INDENT-OFF* */
     492           5 :   pool_foreach (steer_pl, sm->steer_policies) {vec_add1(steer_policies, steer_pl);}
     493             :   /* *INDENT-ON* */
     494           3 :   vlib_cli_output (vm, "Traffic\t\tSR policy BSID");
     495           5 :   for (i = 0; i < vec_len (steer_policies); i++)
     496             :     {
     497           2 :       steer_pl = steer_policies[i];
     498           2 :       pl = pool_elt_at_index (sm->sr_policies, steer_pl->sr_policy);
     499           2 :       if (steer_pl->classify.traffic_type == SR_STEER_L2)
     500             :         {
     501           0 :           vlib_cli_output (vm, "L2 %U\t%U",
     502             :                            format_vnet_sw_if_index_name, vnm,
     503             :                            steer_pl->classify.l2.sw_if_index,
     504             :                            format_ip6_address, &pl->bsid);
     505             :         }
     506           2 :       else if (steer_pl->classify.traffic_type == SR_STEER_IPV4)
     507             :         {
     508           1 :           vlib_cli_output (vm, "L3 %U/%d\t%U",
     509             :                            format_ip4_address,
     510             :                            &steer_pl->classify.l3.prefix.ip4,
     511             :                            steer_pl->classify.l3.mask_width,
     512             :                            format_ip6_address, &pl->bsid);
     513             :         }
     514           1 :       else if (steer_pl->classify.traffic_type == SR_STEER_IPV6)
     515             :         {
     516           1 :           vlib_cli_output (vm, "L3 %U/%d\t%U",
     517             :                            format_ip6_address,
     518             :                            &steer_pl->classify.l3.prefix.ip6,
     519             :                            steer_pl->classify.l3.mask_width,
     520             :                            format_ip6_address, &pl->bsid);
     521             :         }
     522             :     }
     523           3 :   return 0;
     524             : }
     525             : 
     526             : /* *INDENT-OFF* */
     527      285289 : VLIB_CLI_COMMAND (show_sr_steering_policies_command, static) = {
     528             :   .path = "show sr steering-policies",
     529             :   .short_help = "show sr steering-policies",
     530             :   .function = show_sr_steering_policies_command_fn,
     531             : };
     532             : /* *INDENT-ON* */
     533             : 
     534             : clib_error_t *
     535         575 : sr_steering_init (vlib_main_t * vm)
     536             : {
     537         575 :   ip6_sr_main_t *sm = &sr_main;
     538             : 
     539             :   /* Init memory for function keys */
     540         575 :   mhash_init (&sm->sr_steer_policies_hash, sizeof (uword),
     541             :               sizeof (sr_steering_key_t));
     542             : 
     543         575 :   sm->sw_iface_sr_policies = 0;
     544             : 
     545         575 :   sm->vnet_main = vnet_get_main ();
     546             : 
     547         575 :   return 0;
     548             : }
     549             : 
     550             : /* *INDENT-OFF* */
     551       68543 : VLIB_INIT_FUNCTION (sr_steering_init);
     552             : /* *INDENT-ON* */
     553             : 
     554             : /* *INDENT-OFF* */
     555       76635 : VNET_FEATURE_INIT (sr_pl_rewrite_encaps_l2, static) =
     556             : {
     557             :   .arc_name = "device-input",
     558             :   .node_name = "sr-pl-rewrite-encaps-l2",
     559             :   .runs_before = VNET_FEATURES ("ethernet-input"),
     560             : };
     561             : /* *INDENT-ON* */
     562             : 
     563             : /*
     564             : * fd.io coding-style-patch-verification: ON
     565             : *
     566             : * Local Variables:
     567             : * eval: (c-set-style "gnu")
     568             : * End:
     569             : */

Generated by: LCOV version 1.14