LCOV - code coverage report
Current view: top level - vnet/fib - fib_urpf_list.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 11 11 100.0 %
Date: 2023-07-05 22:20:52 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 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             :  * @brief A unicast RPF list.
      17             :  * The uRPF list is the set of interfaces that a prefix can be reached through.
      18             :  * There are 3 levels of RPF check:
      19             :  *   - do we have any route to the source (i.e. it's not drop)
      20             :  *   - did the packet arrive on an interface that the source is reachable through
      21             :  *   - did the packet arrive from a peer that the source is reachable through
      22             :  * we don't support the last. But it could be done by storing adjs in the uPRF
      23             :  * list rather than interface indices.
      24             :  *
      25             :  * these conditions are checked against the list by:
      26             :  *   - the list is not empty
      27             :  *   - there is an interface in the list that is on the input interface.
      28             :  *   - there is an adj in the list whose MAC address matches the packet's
      29             :  *     source MAC and input interface.
      30             :  *
      31             :  * To speed the last two checks the interface list only needs to have the unique
      32             :  * interfaces present. If the uRPF check was instead implemented by forward
      33             :  * walking the DPO chain, then that walk would encounter a great deal of
      34             :  * non-adjacency objects (i.e. load-balances, mpls-labels, etc) and potentially
      35             :  * the same adjacency many times (esp. when UCMP is used).
      36             :  * To that end the uRPF list is a collapsed, unique interface only list.
      37             :  */
      38             : 
      39             : #ifndef __FIB_URPF_LIST_H__
      40             : #define __FIB_URPF_LIST_H__
      41             : 
      42             : #include <vnet/fib/fib_types.h>
      43             : #include <vnet/adj/adj.h>
      44             : 
      45             : /**
      46             :  * @brief flags
      47             :  */
      48             : typedef enum fib_urpf_list_flag_t_
      49             : {
      50             :     /**
      51             :      * @brief Set to indicated that the uRPF list has already been baked.
      52             :      * This is protection against it being baked more than once. These
      53             :      * are not chunky fries - once is enough.
      54             :      */
      55             :     FIB_URPF_LIST_BAKED = (1 << 0),
      56             : } fib_urpf_list_flag_t;
      57             : 
      58             : typedef struct fib_urpf_list_t_
      59             : {
      60             :     /**
      61             :      * The list of interfaces that comprise the allowed accepting interfaces
      62             :      */
      63             :     adj_index_t *furpf_itfs;
      64             : 
      65             :     /**
      66             :      * flags
      67             :      */
      68             :     fib_urpf_list_flag_t furpf_flags;
      69             : 
      70             :     /**
      71             :      * uRPF lists are shared amongst many entries so we require a locking
      72             :      * mechanism.
      73             :      */
      74             :     u32 furpf_locks;
      75             : } fib_urpf_list_t;
      76             : 
      77             : extern index_t fib_urpf_list_alloc_and_lock(void);
      78             : extern void fib_urpf_list_unlock(index_t urpf);
      79             : extern void fib_urpf_list_lock(index_t urpf);
      80             : 
      81             : extern void fib_urpf_list_append(index_t urpf, adj_index_t adj);
      82             : extern void fib_urpf_list_combine(index_t urpf1, index_t urpf2);
      83             : 
      84             : extern void fib_urpf_list_bake(index_t urpf);
      85             : 
      86             : extern u8 *format_fib_urpf_list(u8 *s, va_list *ap);
      87             : 
      88             : extern void fib_urpf_list_show_mem(void);
      89             : 
      90             : /**
      91             :  * @brief pool of all fib_urpf_list
      92             :  */
      93             : extern fib_urpf_list_t *fib_urpf_list_pool;
      94             : 
      95             : static inline fib_urpf_list_t *
      96      524801 : fib_urpf_list_get (index_t index)
      97             : {
      98      524801 :     return (pool_elt_at_index(fib_urpf_list_pool, index));
      99             : }
     100             : 
     101             : /**
     102             :  * @brief Data-Plane function to check an input interface against an uRPF list
     103             :  *
     104             :  * @param ui The uRPF list index to check against. Get this from the load-balance
     105             :  *             object that is the result of the FIB lookup
     106             :  * @param sw_if_index The SW interface index to validate
     107             :  *
     108             :  * @return 1 if the interface is found, 0 otherwise
     109             :  */
     110             : always_inline int
     111         901 : fib_urpf_check (index_t ui, u32 sw_if_index)
     112             : {
     113             :     fib_urpf_list_t *urpf;
     114             :     u32 *swi;
     115             : 
     116         901 :     urpf = fib_urpf_list_get(ui);
     117             : 
     118        1288 :     vec_foreach(swi, urpf->furpf_itfs)
     119             :     {
     120         656 :         if (*swi == sw_if_index)
     121         269 :             return (1);
     122             :     }
     123             : 
     124         632 :     return (0);
     125             : }
     126             : 
     127             : /**
     128             :  * @brief Data-Plane function to check the size of an uRPF list, (i.e. the number
     129             :  *        of interfaces in the list).
     130             :  *
     131             :  * @param ui The uRPF list index to check against. Get this from the load-balance
     132             :  *             object that is the result of the FIB lookup
     133             :  *
     134             :  * @return the number of interfaces in the list
     135             :  */
     136             : always_inline int
     137      117415 : fib_urpf_check_size (index_t ui)
     138             : {
     139             :     fib_urpf_list_t *urpf;
     140             : 
     141      117415 :     urpf = fib_urpf_list_get(ui);
     142             : 
     143      117415 :     return (vec_len(urpf->furpf_itfs));
     144             : }
     145             : 
     146             : #endif

Generated by: LCOV version 1.14