back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_table.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 56 93 60.2 %
Date: 2023-02-24 19:38:44 Functions: 10 13 76.9 %

          Line data    Source code
       1             : /* BGP routing table
       2             :  * Copyright (C) 1998, 2001 Kunihiro Ishiguro
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include "prefix.h"
      24             : #include "memory.h"
      25             : #include "sockunion.h"
      26             : #include "queue.h"
      27             : #include "filter.h"
      28             : #include "command.h"
      29             : #include "printfrr.h"
      30             : 
      31             : #include "bgpd/bgpd.h"
      32             : #include "bgpd/bgp_table.h"
      33             : #include "bgp_addpath.h"
      34             : #include "bgp_trace.h"
      35             : 
      36        4249 : void bgp_table_lock(struct bgp_table *rt)
      37             : {
      38        4249 :         rt->lock++;
      39         271 : }
      40             : 
      41        2368 : void bgp_table_unlock(struct bgp_table *rt)
      42             : {
      43        2368 :         assert(rt->lock > 0);
      44        2368 :         rt->lock--;
      45             : 
      46        2368 :         if (rt->lock != 0) {
      47             :                 return;
      48             :         }
      49             : 
      50        2196 :         route_table_finish(rt->route_table);
      51        2196 :         rt->route_table = NULL;
      52             : 
      53        2196 :         XFREE(MTYPE_BGP_TABLE, rt);
      54             : }
      55             : 
      56        1134 : void bgp_table_finish(struct bgp_table **rt)
      57             : {
      58        1134 :         if (*rt != NULL) {
      59        1134 :                 bgp_table_unlock(*rt);
      60        1134 :                 *rt = NULL;
      61             :         }
      62        1134 : }
      63             : 
      64             : /*
      65             :  * bgp_dest_unlock_node
      66             :  */
      67        1412 : void bgp_dest_unlock_node(struct bgp_dest *dest)
      68             : {
      69        1412 :         frrtrace(1, frr_bgp, bgp_dest_unlock, dest);
      70        1412 :         bgp_delete_listnode(dest);
      71        1412 :         route_unlock_node(bgp_dest_to_rnode(dest));
      72        1412 : }
      73             : 
      74             : /*
      75             :  * bgp_dest_lock_node
      76             :  */
      77         501 : struct bgp_dest *bgp_dest_lock_node(struct bgp_dest *dest)
      78             : {
      79         501 :         frrtrace(1, frr_bgp, bgp_dest_lock, dest);
      80         501 :         struct route_node *rn = route_lock_node(bgp_dest_to_rnode(dest));
      81             : 
      82         501 :         return bgp_dest_from_rnode(rn);
      83             : }
      84             : 
      85             : /*
      86             :  * bgp_dest_get_prefix_str
      87             :  */
      88           0 : const char *bgp_dest_get_prefix_str(struct bgp_dest *dest)
      89             : {
      90           0 :         const struct prefix *p = NULL;
      91           0 :         static char str[PREFIX_STRLEN] = {0};
      92             : 
      93           0 :         p = bgp_dest_get_prefix(dest);
      94           0 :         if (p)
      95           0 :                 return prefix2str(p, str, sizeof(str));
      96             : 
      97             :         return NULL;
      98             : }
      99             : 
     100             : /*
     101             :  * bgp_node_create
     102             :  */
     103         648 : static struct route_node *bgp_node_create(route_table_delegate_t *delegate,
     104             :                                           struct route_table *table)
     105             : {
     106         648 :         struct bgp_node *node;
     107         648 :         node = XCALLOC(MTYPE_BGP_NODE, sizeof(struct bgp_node));
     108             : 
     109         648 :         RB_INIT(bgp_adj_out_rb, &node->adj_out);
     110         648 :         return bgp_dest_to_rnode(node);
     111             : }
     112             : 
     113             : /*
     114             :  * bgp_node_destroy
     115             :  */
     116         425 : static void bgp_node_destroy(route_table_delegate_t *delegate,
     117             :                              struct route_table *table, struct route_node *node)
     118             : {
     119         425 :         struct bgp_node *bgp_node;
     120         425 :         struct bgp_table *rt;
     121         425 :         bgp_node = bgp_dest_from_rnode(node);
     122         425 :         rt = table->info;
     123             : 
     124         425 :         if (rt->bgp) {
     125         425 :                 bgp_addpath_free_node_data(&rt->bgp->tx_addpath,
     126             :                                          &bgp_node->tx_addpath,
     127             :                                          rt->afi, rt->safi);
     128             :         }
     129             : 
     130         425 :         XFREE(MTYPE_BGP_NODE, bgp_node);
     131         425 : }
     132             : 
     133             : /*
     134             :  * Function vector to customize the behavior of the route table
     135             :  * library for BGP route tables.
     136             :  */
     137             : route_table_delegate_t bgp_table_delegate = {.create_node = bgp_node_create,
     138             :                                              .destroy_node = bgp_node_destroy};
     139             : 
     140             : /*
     141             :  * bgp_table_init
     142             :  */
     143        3978 : struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t afi, safi_t safi)
     144             : {
     145        3978 :         struct bgp_table *rt;
     146             : 
     147        3978 :         rt = XCALLOC(MTYPE_BGP_TABLE, sizeof(struct bgp_table));
     148             : 
     149        3978 :         rt->route_table = route_table_init_with_delegate(&bgp_table_delegate);
     150             : 
     151             :         /*
     152             :          * Set up back pointer to bgp_table.
     153             :          */
     154        3978 :         route_table_set_info(rt->route_table, rt);
     155             : 
     156             :         /*
     157             :          * pointer to bgp instance allows working back from bgp_path_info to bgp
     158             :          */
     159        3978 :         rt->bgp = bgp;
     160             : 
     161        3978 :         bgp_table_lock(rt);
     162        3978 :         rt->afi = afi;
     163        3978 :         rt->safi = safi;
     164             : 
     165        3978 :         return rt;
     166             : }
     167             : 
     168             : /* Delete the route node from the selection deferral route list */
     169        1412 : void bgp_delete_listnode(struct bgp_node *node)
     170             : {
     171        1412 :         struct route_node *rn = NULL;
     172        1412 :         struct bgp_table *table = NULL;
     173        1412 :         struct bgp *bgp = NULL;
     174        1412 :         afi_t afi;
     175        1412 :         safi_t safi;
     176             : 
     177             :         /* If the route to be deleted is selection pending, update the
     178             :          * route node in gr_info
     179             :          */
     180        1412 :         if (CHECK_FLAG(node->flags, BGP_NODE_SELECT_DEFER)) {
     181           0 :                 table = bgp_dest_table(node);
     182             : 
     183           0 :                 if (table) {
     184           0 :                         bgp = table->bgp;
     185           0 :                         afi = table->afi;
     186           0 :                         safi = table->safi;
     187             :                 } else
     188             :                         return;
     189             : 
     190           0 :                 rn = bgp_dest_to_rnode(node);
     191             : 
     192           0 :                 if (bgp && rn && rn->lock == 1) {
     193             :                         /* Delete the route from the selection pending list */
     194           0 :                         bgp->gr_info[afi][safi].gr_deferred--;
     195           0 :                         UNSET_FLAG(node->flags, BGP_NODE_SELECT_DEFER);
     196             :                 }
     197             :         }
     198             : }
     199             : 
     200           0 : struct bgp_node *bgp_table_subtree_lookup(const struct bgp_table *table,
     201             :                                           const struct prefix *p)
     202             : {
     203           0 :         struct bgp_node *node = bgp_dest_from_rnode(table->route_table->top);
     204           0 :         struct bgp_node *matched = NULL;
     205             : 
     206           0 :         if (node == NULL)
     207             :                 return NULL;
     208             : 
     209             : 
     210           0 :         while (node) {
     211           0 :                 const struct prefix *node_p = bgp_dest_get_prefix(node);
     212             : 
     213           0 :                 if (node_p->prefixlen >= p->prefixlen) {
     214           0 :                         if (!prefix_match(p, node_p))
     215             :                                 return NULL;
     216             : 
     217             :                         matched = node;
     218             :                         break;
     219             :                 }
     220             : 
     221           0 :                 if (!prefix_match(node_p, p))
     222             :                         return NULL;
     223             : 
     224           0 :                 if (node_p->prefixlen == p->prefixlen) {
     225             :                         matched = node;
     226             :                         break;
     227             :                 }
     228             : 
     229           0 :                 node = bgp_dest_from_rnode(node->link[prefix_bit(
     230             :                         &p->u.prefix, node_p->prefixlen)]);
     231             :         }
     232             : 
     233           0 :         if (!matched)
     234             :                 return NULL;
     235             : 
     236           0 :         bgp_dest_lock_node(matched);
     237           0 :         return matched;
     238             : }
     239             : 
     240          48 : printfrr_ext_autoreg_p("BD", printfrr_bd);
     241           0 : static ssize_t printfrr_bd(struct fbuf *buf, struct printfrr_eargs *ea,
     242             :                            const void *ptr)
     243             : {
     244           0 :         const struct bgp_dest *dest = ptr;
     245           0 :         const struct prefix *p = bgp_dest_get_prefix(dest);
     246           0 :         char cbuf[PREFIX_STRLEN];
     247             : 
     248           0 :         if (!dest)
     249           0 :                 return bputs(buf, "(null)");
     250             : 
     251             :         /* need to get the real length even if buffer too small */
     252           0 :         prefix2str(p, cbuf, sizeof(cbuf));
     253           0 :         return bputs(buf, cbuf);
     254             : }

Generated by: LCOV version v1.16-topotato