LCOV - code coverage report
Current view: top level - vnet/ip - ip.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 57 113 50.4 %
Date: 2023-10-26 01:39:38 Functions: 12 18 66.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 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/fib/fib_table.h>
      18             : 
      19             : u32 ip_flow_hash_router_id;
      20             : 
      21             : ethernet_type_t
      22           0 : ip_address_family_to_ether_type (ip_address_family_t af)
      23             : {
      24           0 :   switch (af)
      25             :     {
      26           0 :     case AF_IP4:
      27           0 :       return (ETHERNET_TYPE_IP4);
      28           0 :     case AF_IP6:
      29           0 :       return (ETHERNET_TYPE_IP6);
      30             :     }
      31           0 :   ASSERT (0);
      32           0 :   return (ETHERNET_TYPE_IP4);
      33             : }
      34             : 
      35             : u8
      36         595 : ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4)
      37             : {
      38         595 :   if (is_ip4)
      39         414 :     return (ip46_address->ip4.as_u32 == 0);
      40             :   else
      41         181 :     return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 0);
      42             : }
      43             : 
      44             : u8
      45          14 : ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4)
      46             : {
      47          14 :   if (is_ip4)
      48          14 :     return (ip46_address->ip4.as_u8[0] == 127);
      49             :   else
      50           0 :     return (ip46_address->as_u64[0] == 0 &&
      51           0 :             clib_net_to_host_u64 (ip46_address->as_u64[1]) == 1);
      52             : }
      53             : 
      54             : u8
      55          20 : ip4_is_local_host (ip4_address_t * ip4_address)
      56             : {
      57          20 :   return (ip4_address->as_u8[0] == 127);
      58             : }
      59             : 
      60             : u8
      61           3 : ip6_is_local_host (ip6_address_t * ip6_address)
      62             : {
      63           6 :   return (ip6_address->as_u64[0] == 0 &&
      64           3 :           clib_net_to_host_u64 (ip6_address->as_u64[1]) == 1);
      65             : }
      66             : 
      67             : /**
      68             :  * Checks that an ip is local to the requested fib
      69             :  */
      70             : u8
      71          13 : ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4)
      72             : {
      73             :   fib_node_index_t fei;
      74             :   fib_entry_flag_t flags;
      75             :   fib_prefix_t prefix;
      76             : 
      77             :   /* Check if requester is local */
      78          13 :   if (is_ip4)
      79             :     {
      80          13 :       prefix.fp_len = 32;
      81          13 :       prefix.fp_proto = FIB_PROTOCOL_IP4;
      82             :     }
      83             :   else
      84             :     {
      85           0 :       prefix.fp_len = 128;
      86           0 :       prefix.fp_proto = FIB_PROTOCOL_IP6;
      87             :     }
      88             : 
      89          13 :   clib_memcpy_fast (&prefix.fp_addr, ip46_address, sizeof (ip46_address_t));
      90          13 :   fei = fib_table_lookup (fib_index, &prefix);
      91          13 :   flags = fib_entry_get_flags (fei);
      92             : 
      93          13 :   return (flags & FIB_ENTRY_FLAG_LOCAL);
      94             : }
      95             : 
      96             : void
      97         528 : ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4)
      98             : {
      99         528 :   if (is_ip4)
     100             :     {
     101         507 :       ip46_address_mask_ip4 (dst);
     102         507 :       dst->ip4.as_u32 = src->ip4.as_u32;
     103             :     }
     104             :   else
     105          21 :     clib_memcpy_fast (&dst->ip6, &src->ip6, sizeof (ip6_address_t));
     106         528 : }
     107             : 
     108             : void
     109           0 : ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
     110             : {
     111           0 :   if (is_ip4)
     112             :     {
     113           0 :       ip46_address_mask_ip4 (dst);
     114           0 :       dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
     115             :     }
     116             :   else
     117           0 :     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
     118             :                       sizeof (ip6_address_t));
     119           0 : }
     120             : 
     121             : /* *INDENT-OFF* */
     122             : static const char *ip_arc_names[N_IP_FEATURE_LOCATIONS][N_AF][N_SAFI] = {
     123             :   [IP_FEATURE_INPUT] = {
     124             :     [AF_IP4] = {
     125             :       [SAFI_UNICAST] = "ip4-unicast",
     126             :       [SAFI_MULTICAST] = "ip4-multicast",
     127             :     },
     128             :     [AF_IP6] = {
     129             :       [SAFI_UNICAST] = "ip6-unicast",
     130             :       [SAFI_MULTICAST] = "ip6-multicast",
     131             :     },
     132             :   },
     133             :   [IP_FEATURE_OUTPUT] = {
     134             :     [AF_IP4] = {
     135             :       [SAFI_UNICAST] = "ip4-output",
     136             :       [SAFI_MULTICAST] = "ip4-output",
     137             :     },
     138             :     [AF_IP6] = {
     139             :       [SAFI_UNICAST] = "ip6-output",
     140             :       [SAFI_MULTICAST] = "ip6-output",
     141             :     },
     142             :   },
     143             :   [IP_FEATURE_LOCAL] = {
     144             :     [AF_IP4] = {
     145             :       [SAFI_UNICAST] = "ip4-local",
     146             :       [SAFI_MULTICAST] = "ip4-local",
     147             :     },
     148             :     [AF_IP6] = {
     149             :       [SAFI_UNICAST] = "ip6-local",
     150             :       [SAFI_MULTICAST] = "ip6-local",
     151             :     },
     152             :   },
     153             :   [IP_FEATURE_PUNT] = {
     154             :     [AF_IP4] = {
     155             :       [SAFI_UNICAST] = "ip4-punt",
     156             :       [SAFI_MULTICAST] = "ip4-punt",
     157             :     },
     158             :     [AF_IP6] = {
     159             :       [SAFI_UNICAST] = "ip6-punt",
     160             :       [SAFI_MULTICAST] = "ip6-punt",
     161             :     },
     162             :   },
     163             :   [IP_FEATURE_DROP] = {
     164             :     [AF_IP4] = {
     165             :       [SAFI_UNICAST] = "ip4-drop",
     166             :       [SAFI_MULTICAST] = "ip4-drop",
     167             :     },
     168             :     [AF_IP6] = {
     169             :       [SAFI_UNICAST] = "ip6-drop",
     170             :       [SAFI_MULTICAST] = "ip6-drop",
     171             :     },
     172             :   },
     173             : };
     174             : /* *INDENT-ON* */
     175             : 
     176             : void
     177          36 : ip_feature_enable_disable (ip_address_family_t af,
     178             :                            ip_sub_address_family_t safi,
     179             :                            ip_feature_location_t loc,
     180             :                            const char *feature_name,
     181             :                            u32 sw_if_index, int enable,
     182             :                            void *feature_config, u32 n_feature_config_bytes)
     183             : {
     184          36 :   if (IP_FEATURE_INPUT == loc)
     185             :     {
     186          36 :       if (N_SAFI == safi)
     187         108 :         FOR_EACH_IP_ADDRESS_SUB_FAMILY (safi)
     188          72 :           vnet_feature_enable_disable (ip_arc_names[loc][af][safi],
     189             :                                        feature_name, sw_if_index,
     190             :                                        enable, feature_config,
     191             :                                        n_feature_config_bytes);
     192             :       else
     193           0 :         vnet_feature_enable_disable (ip_arc_names[loc][af][safi],
     194             :                                      feature_name, sw_if_index,
     195             :                                      enable, feature_config,
     196             :                                      n_feature_config_bytes);
     197             :     }
     198             :   else
     199           0 :     vnet_feature_enable_disable (ip_arc_names[loc][af][SAFI_UNICAST],
     200             :                                  feature_name, sw_if_index,
     201             :                                  enable, feature_config,
     202             :                                  n_feature_config_bytes);
     203          36 : }
     204             : 
     205             : int
     206           5 : ip_flow_hash_set (ip_address_family_t af, u32 table_id, u32 flow_hash_config)
     207             : {
     208             :   fib_protocol_t fproto;
     209             :   u32 fib_index;
     210             : 
     211           5 :   fproto = ip_address_family_to_fib_proto (af);
     212           5 :   fib_index = fib_table_find (fproto, table_id);
     213             : 
     214           5 :   if (~0 == fib_index)
     215           0 :     return VNET_API_ERROR_NO_SUCH_FIB;
     216             : 
     217           5 :   fib_table_set_flow_hash_config (fib_index, fproto, flow_hash_config);
     218             : 
     219           5 :   return 0;
     220             : }
     221             : 
     222             : void
     223           2 : ip_flow_hash_router_id_set (u32 router_id)
     224             : {
     225           2 :   ip_flow_hash_router_id = router_id;
     226           2 : }
     227             : 
     228             : u8 *
     229          31 : format_ip_address_family (u8 * s, va_list * args)
     230             : {
     231          31 :   ip_address_family_t af = va_arg (*args, int); // int promo ip_address_family_t);
     232             : 
     233          31 :   switch (af)
     234             :     {
     235          17 :     case AF_IP4:
     236          17 :       return (format (s, "ip4"));
     237          14 :     case AF_IP6:
     238          14 :       return (format (s, "ip6"));
     239             :     }
     240             : 
     241           0 :   return (format (s, "unknown"));
     242             : }
     243             : 
     244             : uword
     245           0 : unformat_ip_address_family (unformat_input_t * input, va_list * args)
     246             : {
     247           0 :   ip_address_family_t *af = va_arg (*args, ip_address_family_t *);
     248             : 
     249           0 :   if (unformat (input, "ip4") || unformat (input, "ipv4") ||
     250           0 :       unformat (input, "IP4") || unformat (input, "IPv4"))
     251             :     {
     252           0 :       *af = AF_IP4;
     253           0 :       return (1);
     254             :     }
     255           0 :   else if (unformat (input, "ip6") || unformat (input, "ipv6") ||
     256           0 :            unformat (input, "IP6") || unformat (input, "IPv6"))
     257             :     {
     258           0 :       *af = AF_IP6;
     259           0 :       return (1);
     260             :     }
     261           0 :   return (0);
     262             : }
     263             : 
     264             : u8 *
     265           0 : format_ip_sub_address_family (u8 * s, va_list * args)
     266             : {
     267           0 :   ip_sub_address_family_t safi = va_arg (*args, int);   // int promo ip_sub_address_family_t);
     268             : 
     269           0 :   switch (safi)
     270             :     {
     271           0 :     case SAFI_UNICAST:
     272           0 :       return (format (s, "unicast"));
     273           0 :     case SAFI_MULTICAST:
     274           0 :       return (format (s, "multicast"));
     275             :     }
     276             : 
     277           0 :   return (format (s, "unknown"));
     278             : }
     279             : 
     280             : uword
     281           0 : unformat_ip_sub_address_family (unformat_input_t * input, va_list * args)
     282             : {
     283           0 :   ip_sub_address_family_t *safi = va_arg (*args, ip_sub_address_family_t *);
     284             : 
     285           0 :   if (unformat (input, "unicast") || unformat (input, "uni"))
     286             :     {
     287           0 :       *safi = SAFI_UNICAST;
     288           0 :       return (1);
     289             :     }
     290           0 :   else if (unformat (input, "multicast") || unformat (input, "multi"))
     291             :     {
     292           0 :       *safi = SAFI_MULTICAST;
     293           0 :       return (1);
     294             :     }
     295           0 :   return (0);
     296             : }
     297             : 
     298             : u8 *
     299     1397620 : format_ip_dscp (u8 * s, va_list * va)
     300             : {
     301     1397620 :   ip_dscp_t dscp = va_arg (*va, u32);   // int promotion of u8
     302             : 
     303     1397620 :   switch (dscp)
     304             :     {
     305             : #define _(n,v)                                                  \
     306             :     case IP_DSCP_##v:                                           \
     307             :       return (format (s, "%s", #v));
     308     1389180 :       foreach_ip_dscp
     309             : #undef _
     310             :     }
     311             : 
     312        8443 :   return (format (s, "unknown"));
     313             : }
     314             : 
     315             : uword
     316           0 : unformat_ip_dscp (unformat_input_t * input, va_list * args)
     317             : {
     318           0 :   ip_dscp_t *dscp = va_arg (*args, ip_dscp_t *);
     319             : 
     320             :   if (0)
     321             :     ;
     322             : #define _(n,v)                                                  \
     323             :   else if (unformat (input, #v))                                \
     324             :     *dscp = IP_DSCP_##v;
     325           0 :   foreach_ip_dscp
     326             : #undef _
     327             :     else
     328           0 :     return 0;
     329             : 
     330           0 :   return 1;
     331             : }
     332             : 
     333             : u8 *
     334     1397000 : format_ip_ecn (u8 * s, va_list * va)
     335             : {
     336     1397000 :   ip_ecn_t ecn = va_arg (*va, u32);     // int promotion of u8
     337             : 
     338     1397000 :   switch (ecn)
     339             :     {
     340             : #define _(n,v)                                                  \
     341             :     case IP_ECN_##v:                                           \
     342             :       return (format (s, "%s", #v));
     343     1397000 :       foreach_ip_ecn
     344             : #undef _
     345             :     }
     346             : 
     347           0 :   return (format (s, "unknown"));
     348             : }
     349             : 
     350             : /*
     351             :  * fd.io coding-style-patch-verification: ON
     352             :  *
     353             :  * Local Variables:
     354             :  * eval: (c-set-style "gnu")
     355             :  * End:
     356             :  */

Generated by: LCOV version 1.14