LCOV - code coverage report
Current view: top level - vnet/dpo - receive_dpo.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 41 46 89.1 %
Date: 2023-07-05 22:20:52 Functions: 8 9 88.9 %

          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
      17             :  * The data-path object representing receiveing the packet, i.e. it's for-us
      18             :  */
      19             : #include <vlib/vlib.h>
      20             : #include <vnet/ip/ip.h>
      21             : #include <vnet/dpo/receive_dpo.h>
      22             : 
      23             : /**
      24             :  * @brief pool of all receive DPOs
      25             :  */
      26             : receive_dpo_t *receive_dpo_pool;
      27             : 
      28             : int
      29      155882 : dpo_is_receive (const dpo_id_t *dpo)
      30             : {
      31      155882 :     return (dpo->dpoi_type == DPO_RECEIVE);
      32             : }
      33             : 
      34             : static receive_dpo_t *
      35       20822 : receive_dpo_alloc (void)
      36             : {
      37             :     receive_dpo_t *rd;
      38             :     vlib_main_t *vm;
      39             :     u8 did_barrier_sync;
      40             : 
      41       20822 :     dpo_pool_barrier_sync (vm, receive_dpo_pool, did_barrier_sync);
      42       20822 :     pool_get_aligned(receive_dpo_pool, rd, CLIB_CACHE_LINE_BYTES);
      43       20822 :     dpo_pool_barrier_release (vm, did_barrier_sync);
      44             : 
      45       20822 :     clib_memset(rd, 0, sizeof(*rd));
      46             : 
      47       20822 :     return (rd);
      48             : }
      49             : 
      50             : static receive_dpo_t *
      51      555211 : receive_dpo_get_from_dpo (const dpo_id_t *dpo)
      52             : {
      53      555211 :     ASSERT(DPO_RECEIVE == dpo->dpoi_type);
      54             : 
      55      555211 :     return (receive_dpo_get(dpo->dpoi_index));
      56             : }
      57             : 
      58             : 
      59             : /*
      60             :  * receive_dpo_add_or_lock
      61             :  *
      62             :  * The next_hop address here is used for source address selection in the DP.
      63             :  * The local adj is added to an interface's receive prefix, the next-hop
      64             :  * passed here is the local prefix on the same interface.
      65             :  */
      66             : void
      67       20822 : receive_dpo_add_or_lock (dpo_proto_t proto,
      68             :                          u32 sw_if_index,
      69             :                          const ip46_address_t *nh_addr,
      70             :                          dpo_id_t *dpo)
      71             : {
      72             :     receive_dpo_t *rd;
      73             : 
      74       20822 :     rd = receive_dpo_alloc();
      75             : 
      76       20822 :     rd->rd_sw_if_index = sw_if_index;
      77       20822 :     if (NULL != nh_addr)
      78             :     {
      79       20822 :         rd->rd_addr = *nh_addr;
      80             :     }
      81             : 
      82       20822 :     dpo_set(dpo, DPO_RECEIVE, proto, (rd - receive_dpo_pool));
      83       20822 : }
      84             : 
      85             : static void
      86      281642 : receive_dpo_lock (dpo_id_t *dpo)
      87             : {
      88             :     receive_dpo_t *rd;
      89             : 
      90      281642 :     rd = receive_dpo_get_from_dpo(dpo);
      91      281642 :     rd->rd_locks++;
      92      281642 : }
      93             : 
      94             : static void
      95      273569 : receive_dpo_unlock (dpo_id_t *dpo)
      96             : {
      97             :     receive_dpo_t *rd;
      98             : 
      99      273569 :     rd = receive_dpo_get_from_dpo(dpo);
     100      273569 :     rd->rd_locks--;
     101             : 
     102      273569 :     if (0 == rd->rd_locks)
     103             :     {
     104       16786 :         pool_put(receive_dpo_pool, rd);
     105             :     }
     106      273569 : }
     107             : 
     108             : static u8*
     109        2304 : format_receive_dpo (u8 *s, va_list *ap)
     110             : {
     111        2304 :     CLIB_UNUSED(index_t index) = va_arg(*ap, index_t);
     112        2304 :     CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
     113        2304 :     vnet_main_t * vnm = vnet_get_main();
     114             :     receive_dpo_t *rd;
     115             : 
     116        2304 :     if (pool_is_free_index(receive_dpo_pool, index))
     117             :     {
     118           1 :         return (format(s, "dpo-receive DELETED"));
     119             :     }
     120             : 
     121        2303 :     rd = receive_dpo_get(index);
     122             : 
     123        2303 :     if (~0 != rd->rd_sw_if_index)
     124             :     {
     125         515 :         return (format(s, "dpo-receive: %U on %U",
     126             :                        format_ip46_address, &rd->rd_addr, IP46_TYPE_ANY,
     127             :                        format_vnet_sw_interface_name, vnm,
     128             :                        vnet_get_sw_interface(vnm, rd->rd_sw_if_index)));
     129             :     }
     130             :     else
     131             :     {
     132        1788 :         return (format(s, "dpo-receive"));
     133             :     }
     134             : }
     135             : 
     136             : static void
     137           0 : receive_dpo_mem_show (void)
     138             : {
     139           0 :     fib_show_memory_usage("Receive",
     140           0 :                           pool_elts(receive_dpo_pool),
     141           0 :                           pool_len(receive_dpo_pool),
     142             :                           sizeof(receive_dpo_t));
     143           0 : }
     144             : 
     145             : const static dpo_vft_t receive_vft = {
     146             :     .dv_lock = receive_dpo_lock,
     147             :     .dv_unlock = receive_dpo_unlock,
     148             :     .dv_format = format_receive_dpo,
     149             :     .dv_mem_show = receive_dpo_mem_show,
     150             : };
     151             : 
     152             : /**
     153             :  * @brief The per-protocol VLIB graph nodes that are assigned to a receive
     154             :  *        object.
     155             :  *
     156             :  * this means that these graph nodes are ones from which a receive is the
     157             :  * parent object in the DPO-graph.
     158             :  */
     159             : const static char *const receive_ip4_nodes[] = {
     160             :   "ip4-receive",
     161             :   NULL,
     162             : };
     163             : const static char *const receive_ip6_nodes[] = {
     164             :   "ip6-receive",
     165             :   NULL,
     166             : };
     167             : 
     168             : const static char* const * const receive_nodes[DPO_PROTO_NUM] =
     169             : {
     170             :     [DPO_PROTO_IP4]  = receive_ip4_nodes,
     171             :     [DPO_PROTO_IP6]  = receive_ip6_nodes,
     172             :     [DPO_PROTO_MPLS] = NULL,
     173             : };
     174             : 
     175             : void
     176         559 : receive_dpo_module_init (void)
     177             : {
     178         559 :     dpo_register(DPO_RECEIVE, &receive_vft, receive_nodes);
     179         559 : }

Generated by: LCOV version 1.14