LCOV - code coverage report
Current view: top level - vnet/fib - fib_sas.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 30 52 57.7 %
Date: 2023-07-05 22:20:52 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2020 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             : /**
      17             :  * @brief FIB Source Address selection
      18             :  *
      19             :  * Use the FIB for source address selection on an interface
      20             :  */
      21             : 
      22             : #include <vnet/fib/fib_sas.h>
      23             : #include <vnet/adj/adj_glean.h>
      24             : #include <vnet/ip/ip6_link.h>
      25             : 
      26             : 
      27             : bool
      28           0 : fib_sas_get (u32 sw_if_index,
      29             :              ip_address_family_t af,
      30             :              const ip46_address_t *dst,
      31             :              ip46_address_t *src)
      32             : {
      33           0 :     switch (af)
      34             :     {
      35           0 :     case AF_IP4:
      36           0 :         if (dst)
      37           0 :             return (fib_sas4_get(sw_if_index, &dst->ip4, &src->ip4));
      38             :         else
      39           0 :             return (fib_sas4_get(sw_if_index, NULL, &src->ip4));
      40           0 :     case AF_IP6:
      41           0 :         if (dst)
      42           0 :             return (fib_sas6_get(sw_if_index, &dst->ip6, &src->ip6));
      43             :         else
      44           0 :             return (fib_sas6_get(sw_if_index, NULL, &src->ip6));
      45             :     }
      46           0 :     return (false);
      47             : }
      48             : 
      49             : bool
      50        1119 : fib_sas4_get (u32 sw_if_index,
      51             :               const ip4_address_t *dst,
      52             :               ip4_address_t *src)
      53             : {
      54        1119 :     ip46_address_t d_tmp, *d_tmpp = NULL;
      55             :     const ip46_address_t *s_tmp;
      56             :     vnet_sw_interface_t *swif;
      57             : 
      58        1119 :     if (dst)
      59             :     {
      60        1051 :         d_tmpp = &d_tmp;
      61        1051 :         d_tmp.ip4 = *dst;
      62             :     }
      63             : 
      64        1119 :     if (vnet_sw_interface_is_p2p(vnet_get_main(), sw_if_index))
      65             :     {
      66             :         ip4_address_t *ip4;
      67           0 :         ip4 = ip_interface_get_first_ip (sw_if_index, 1);
      68           0 :         if (ip4) {
      69           0 :             src->as_u32 = ip4->as_u32;
      70           0 :             return (true);
      71             :         } else {
      72           0 :             return (false);
      73             :         }
      74             :     }
      75             : 
      76             :     /*
      77             :      * If the interface is unnumbered then use the IP interface
      78             :      */
      79        1119 :     swif = vnet_get_sw_interface (vnet_get_main(), sw_if_index);
      80             : 
      81        1119 :     if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
      82           2 :         sw_if_index = swif->unnumbered_sw_if_index;
      83             : 
      84             :     /*
      85             :      * get the source address from the glean adjacency
      86             :      */
      87        1119 :     s_tmp = adj_glean_get_src (FIB_PROTOCOL_IP4, sw_if_index, d_tmpp);
      88             : 
      89        1119 :     if (NULL != s_tmp)
      90             :     {
      91        1066 :         src->as_u32 = s_tmp->ip4.as_u32;
      92        1066 :         return (true);
      93             :     }
      94             : 
      95          53 :     return (false);
      96             : }
      97             : 
      98             : bool
      99          93 : fib_sas6_get (u32 sw_if_index,
     100             :               const ip6_address_t *dst,
     101             :               ip6_address_t *src)
     102             : {
     103          93 :     ip46_address_t d_tmp, *d_tmpp = NULL;
     104             :     const ip46_address_t *s_tmp;
     105             : 
     106          93 :     if (dst)
     107             :     {
     108          93 :         d_tmpp = &d_tmp;
     109          93 :         d_tmp.ip6 = *dst;
     110             :     }
     111             : 
     112             :     /*
     113             :      * if the dst is v6 and link local, use the source link local
     114             :      */
     115          93 :     if (dst && ip6_address_is_link_local_unicast (dst))
     116             :     {
     117           4 :         const ip6_address_t *ll = ip6_get_link_local_address (sw_if_index);
     118           4 :         if (NULL == ll)
     119             :         {
     120           0 :             return (false);
     121             :         }
     122           4 :         ip6_address_copy (src, ll);
     123           4 :         return (true);
     124             :     }
     125             : 
     126          89 :     if (vnet_sw_interface_is_p2p(vnet_get_main(), sw_if_index))
     127             :     {
     128             :         ip6_address_t *ip6;
     129           0 :         ip6 = ip_interface_get_first_ip (sw_if_index, 0);
     130           0 :         if (ip6) {
     131           0 :             ip6_address_copy(src, ip6);
     132           0 :             return (true);
     133             :         } else {
     134           0 :             return (false);
     135             :         }
     136             :     }
     137             : 
     138             :     /*
     139             :      * get the source address from the glean adjacency
     140             :      */
     141          89 :     s_tmp = adj_glean_get_src (FIB_PROTOCOL_IP6, sw_if_index, d_tmpp);
     142             : 
     143          89 :     if (NULL != s_tmp)
     144             :     {
     145          85 :         ip6_address_copy(src, &s_tmp->ip6);
     146          85 :         return (true);
     147             :     }
     148             : 
     149           4 :     return (false);
     150             : }

Generated by: LCOV version 1.14