back to topotato report
topotato coverage report
Current view: top level - ospfd - ospf_lsdb.c (source / functions) Hit Total Coverage
Test: test_ospf_topo1.py::OSPFTopo1Test Lines: 116 146 79.5 %
Date: 2023-02-24 18:38:32 Functions: 13 17 76.5 %

          Line data    Source code
       1             : /*
       2             :  * OSPF LSDB support.
       3             :  * Copyright (C) 1999, 2000 Alex Zinin, Kunihiro Ishiguro, Toshiaki Takada
       4             :  *
       5             :  * This file is part of GNU Zebra.
       6             :  *
       7             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       8             :  * under the terms of the GNU General Public License as published by the
       9             :  * Free Software Foundation; either version 2, or (at your option) any
      10             :  * later version.
      11             :  *
      12             :  * GNU Zebra is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License along
      18             :  * with this program; see the file COPYING; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : #include <zebra.h>
      23             : 
      24             : #include "prefix.h"
      25             : #include "table.h"
      26             : #include "memory.h"
      27             : #include "log.h"
      28             : 
      29             : #include "ospfd/ospfd.h"
      30             : #include "ospfd/ospf_asbr.h"
      31             : #include "ospfd/ospf_lsa.h"
      32             : #include "ospfd/ospf_lsdb.h"
      33             : 
      34          15 : struct ospf_lsdb *ospf_lsdb_new(void)
      35             : {
      36          15 :         struct ospf_lsdb *new;
      37             : 
      38          15 :         new = XCALLOC(MTYPE_OSPF_LSDB, sizeof(struct ospf_lsdb));
      39          15 :         ospf_lsdb_init(new);
      40             : 
      41          15 :         return new;
      42             : }
      43             : 
      44         177 : void ospf_lsdb_init(struct ospf_lsdb *lsdb)
      45             : {
      46         177 :         int i;
      47             : 
      48        2124 :         for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
      49        1947 :                 lsdb->type[i].db = route_table_init();
      50         177 : }
      51             : 
      52          15 : void ospf_lsdb_free(struct ospf_lsdb *lsdb)
      53             : {
      54          15 :         ospf_lsdb_cleanup(lsdb);
      55          15 :         XFREE(MTYPE_OSPF_LSDB, lsdb);
      56          15 : }
      57             : 
      58         177 : void ospf_lsdb_cleanup(struct ospf_lsdb *lsdb)
      59             : {
      60         177 :         int i;
      61         177 :         assert(lsdb);
      62         177 :         assert(lsdb->total == 0);
      63             : 
      64         177 :         ospf_lsdb_delete_all(lsdb);
      65             : 
      66        2301 :         for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
      67        1947 :                 route_table_finish(lsdb->type[i].db);
      68         177 : }
      69             : 
      70        1706 : void ls_prefix_set(struct prefix_ls *lp, struct ospf_lsa *lsa)
      71             : {
      72        1706 :         if (lp && lsa && lsa->data) {
      73        1706 :                 lp->family = AF_UNSPEC;
      74        1706 :                 lp->prefixlen = 64;
      75        1706 :                 lp->id = lsa->data->id;
      76        1706 :                 lp->adv_router = lsa->data->adv_router;
      77             :         }
      78        1706 : }
      79             : 
      80         297 : static void ospf_lsdb_delete_entry(struct ospf_lsdb *lsdb,
      81             :                                    struct route_node *rn)
      82             : {
      83         297 :         struct ospf_lsa *lsa = rn->info;
      84             : 
      85         297 :         if (!lsa)
      86             :                 return;
      87             : 
      88         297 :         assert(rn->table == lsdb->type[lsa->data->type].db);
      89             : 
      90         297 :         if (IS_LSA_SELF(lsa))
      91         187 :                 lsdb->type[lsa->data->type].count_self--;
      92         297 :         lsdb->type[lsa->data->type].count--;
      93         297 :         lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
      94         297 :         lsdb->total--;
      95         297 :         rn->info = NULL;
      96         297 :         route_unlock_node(rn);
      97             : #ifdef MONITOR_LSDB_CHANGE
      98         297 :         if (lsdb->del_lsa_hook != NULL)
      99         114 :                 (*lsdb->del_lsa_hook)(lsa);
     100             : #endif                         /* MONITOR_LSDB_CHANGE */
     101         297 :         ospf_lsa_unlock(&lsa); /* lsdb */
     102         297 :         return;
     103             : }
     104             : 
     105             : /* Add new LSA to lsdb. */
     106         297 : void ospf_lsdb_add(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
     107             : {
     108         297 :         struct route_table *table;
     109         297 :         struct prefix_ls lp;
     110         297 :         struct route_node *rn;
     111             : 
     112         297 :         table = lsdb->type[lsa->data->type].db;
     113         297 :         ls_prefix_set(&lp, lsa);
     114         297 :         rn = route_node_get(table, (struct prefix *)&lp);
     115             : 
     116             :         /* nothing to do? */
     117         297 :         if (rn->info && rn->info == lsa) {
     118           0 :                 route_unlock_node(rn);
     119           0 :                 return;
     120             :         }
     121             : 
     122             :         /* purge old entry? */
     123         297 :         if (rn->info)
     124         101 :                 ospf_lsdb_delete_entry(lsdb, rn);
     125             : 
     126         297 :         if (IS_LSA_SELF(lsa))
     127         187 :                 lsdb->type[lsa->data->type].count_self++;
     128         297 :         lsdb->type[lsa->data->type].count++;
     129         297 :         lsdb->total++;
     130             : 
     131             : #ifdef MONITOR_LSDB_CHANGE
     132         297 :         if (lsdb->new_lsa_hook != NULL)
     133         161 :                 (*lsdb->new_lsa_hook)(lsa);
     134             : #endif /* MONITOR_LSDB_CHANGE */
     135         297 :         lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
     136         297 :         rn->info = ospf_lsa_lock(lsa); /* lsdb */
     137             : }
     138             : 
     139         152 : void ospf_lsdb_delete(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
     140             : {
     141         152 :         struct route_table *table;
     142         152 :         struct prefix_ls lp;
     143         152 :         struct route_node *rn;
     144             : 
     145         152 :         if (!lsdb || !lsa)
     146           0 :                 return;
     147             : 
     148         152 :         assert(lsa->data->type < OSPF_MAX_LSA);
     149         152 :         table = lsdb->type[lsa->data->type].db;
     150         152 :         ls_prefix_set(&lp, lsa);
     151         152 :         if ((rn = route_node_lookup(table, (struct prefix *)&lp))) {
     152         151 :                 if (rn->info == lsa)
     153         151 :                         ospf_lsdb_delete_entry(lsdb, rn);
     154         151 :                 route_unlock_node(rn); /* route_node_lookup */
     155             :         }
     156             : }
     157             : 
     158         196 : void ospf_lsdb_delete_all(struct ospf_lsdb *lsdb)
     159             : {
     160         196 :         struct route_table *table;
     161         196 :         struct route_node *rn;
     162         196 :         int i;
     163             : 
     164        2352 :         for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) {
     165        2156 :                 table = lsdb->type[i].db;
     166        2227 :                 for (rn = route_top(table); rn; rn = route_next(rn))
     167          71 :                         if (rn->info != NULL)
     168          45 :                                 ospf_lsdb_delete_entry(lsdb, rn);
     169             :         }
     170         196 : }
     171             : 
     172        1257 : struct ospf_lsa *ospf_lsdb_lookup(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
     173             : {
     174        1257 :         struct route_table *table;
     175        1257 :         struct prefix_ls lp;
     176        1257 :         struct route_node *rn;
     177        1257 :         struct ospf_lsa *find;
     178             : 
     179        1257 :         table = lsdb->type[lsa->data->type].db;
     180        1257 :         ls_prefix_set(&lp, lsa);
     181        1257 :         rn = route_node_lookup(table, (struct prefix *)&lp);
     182        1257 :         if (rn) {
     183         501 :                 find = rn->info;
     184         501 :                 route_unlock_node(rn);
     185         501 :                 return find;
     186             :         }
     187             :         return NULL;
     188             : }
     189             : 
     190         455 : struct ospf_lsa *ospf_lsdb_lookup_by_id(struct ospf_lsdb *lsdb, uint8_t type,
     191             :                                         struct in_addr id,
     192             :                                         struct in_addr adv_router)
     193             : {
     194         455 :         struct route_table *table;
     195         455 :         struct prefix_ls lp;
     196         455 :         struct route_node *rn;
     197         455 :         struct ospf_lsa *find;
     198             : 
     199         455 :         table = lsdb->type[type].db;
     200             : 
     201         455 :         memset(&lp, 0, sizeof(lp));
     202         455 :         lp.family = AF_UNSPEC;
     203         455 :         lp.prefixlen = 64;
     204         455 :         lp.id = id;
     205         455 :         lp.adv_router = adv_router;
     206             : 
     207         455 :         rn = route_node_lookup(table, (struct prefix *)&lp);
     208         455 :         if (rn) {
     209         260 :                 find = rn->info;
     210         260 :                 route_unlock_node(rn);
     211         260 :                 return find;
     212             :         }
     213             :         return NULL;
     214             : }
     215             : 
     216           0 : struct ospf_lsa *ospf_lsdb_lookup_by_id_next(struct ospf_lsdb *lsdb,
     217             :                                              uint8_t type, struct in_addr id,
     218             :                                              struct in_addr adv_router,
     219             :                                              int first)
     220             : {
     221           0 :         struct route_table *table;
     222           0 :         struct prefix_ls lp;
     223           0 :         struct route_node *rn;
     224           0 :         struct ospf_lsa *find;
     225             : 
     226           0 :         table = lsdb->type[type].db;
     227             : 
     228           0 :         memset(&lp, 0, sizeof(lp));
     229           0 :         lp.family = AF_UNSPEC;
     230           0 :         lp.prefixlen = 64;
     231           0 :         lp.id = id;
     232           0 :         lp.adv_router = adv_router;
     233             : 
     234           0 :         if (first)
     235           0 :                 rn = route_top(table);
     236             :         else {
     237           0 :                 if ((rn = route_node_lookup(table, (struct prefix *)&lp))
     238             :                     == NULL)
     239             :                         return NULL;
     240           0 :                 rn = route_next(rn);
     241             :         }
     242             : 
     243           0 :         for (; rn; rn = route_next(rn))
     244           0 :                 if (rn->info)
     245             :                         break;
     246             : 
     247           0 :         if (rn && rn->info) {
     248           0 :                 find = rn->info;
     249           0 :                 route_unlock_node(rn);
     250           0 :                 return find;
     251             :         }
     252             :         return NULL;
     253             : }
     254             : 
     255         214 : unsigned long ospf_lsdb_count_all(struct ospf_lsdb *lsdb)
     256             : {
     257         214 :         return lsdb->total;
     258             : }
     259             : 
     260           0 : unsigned long ospf_lsdb_count(struct ospf_lsdb *lsdb, int type)
     261             : {
     262           0 :         return lsdb->type[type].count;
     263             : }
     264             : 
     265           0 : unsigned long ospf_lsdb_count_self(struct ospf_lsdb *lsdb, int type)
     266             : {
     267           0 :         return lsdb->type[type].count_self;
     268             : }
     269             : 
     270           0 : unsigned int ospf_lsdb_checksum(struct ospf_lsdb *lsdb, int type)
     271             : {
     272           0 :         return lsdb->type[type].checksum;
     273             : }
     274             : 
     275          74 : unsigned long ospf_lsdb_isempty(struct ospf_lsdb *lsdb)
     276             : {
     277          74 :         return (lsdb->total == 0);
     278             : }

Generated by: LCOV version v1.16-topotato