back to topotato report
topotato coverage report
Current view: top level - zebra - zebra_router.c (source / functions) Hit Total Coverage
Test: test_pim_crp.py::PIMCandidateBSRTest Lines: 123 164 75.0 %
Date: 2023-02-16 02:09:37 Functions: 15 20 75.0 %

          Line data    Source code
       1             : /* Zebra Router Code.
       2             :  * Copyright (C) 2018 Cumulus Networks, Inc.
       3             :  *                    Donald Sharp
       4             :  *
       5             :  * This file is part of FRR.
       6             :  *
       7             :  * FRR 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             :  * FRR 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
      18             :  * along with FRR; see the file COPYING.  If not, write to the Free
      19             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      20             :  * 02111-1307, USA.
      21             :  */
      22             : #include "zebra.h"
      23             : 
      24             : #include <pthread.h>
      25             : #include "lib/frratomic.h"
      26             : 
      27             : #include "zebra_router.h"
      28             : #include "zebra_pbr.h"
      29             : #include "zebra_vxlan.h"
      30             : #include "zebra_mlag.h"
      31             : #include "zebra_nhg.h"
      32             : #include "zebra_neigh.h"
      33             : #include "zebra/zebra_tc.h"
      34             : #include "debug.h"
      35             : #include "zebra_script.h"
      36             : 
      37           9 : DEFINE_MTYPE_STATIC(ZEBRA, RIB_TABLE_INFO, "RIB table info");
      38           9 : DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_RT_TABLE, "Zebra VRF table");
      39             : 
      40             : struct zebra_router zrouter = {
      41             :         .multipath_num = MULTIPATH_NUM,
      42             :         .ipv4_multicast_mode = MCAST_NO_CONFIG,
      43             : };
      44             : 
      45             : static inline int
      46             : zebra_router_table_entry_compare(const struct zebra_router_table *e1,
      47             :                                  const struct zebra_router_table *e2);
      48             : 
      49          48 : RB_GENERATE(zebra_router_table_head, zebra_router_table,
      50             :             zebra_router_table_entry, zebra_router_table_entry_compare);
      51             : 
      52             : 
      53             : static inline int
      54          48 : zebra_router_table_entry_compare(const struct zebra_router_table *e1,
      55             :                                  const struct zebra_router_table *e2)
      56             : {
      57          48 :         if (e1->tableid < e2->tableid)
      58             :                 return -1;
      59          48 :         if (e1->tableid > e2->tableid)
      60             :                 return 1;
      61          48 :         if (e1->ns_id < e2->ns_id)
      62             :                 return -1;
      63          48 :         if (e1->ns_id > e2->ns_id)
      64             :                 return 1;
      65          48 :         if (e1->afi < e2->afi)
      66             :                 return -1;
      67          45 :         if (e1->afi > e2->afi)
      68             :                 return 1;
      69          27 :         return (e1->safi - e2->safi);
      70             : }
      71             : 
      72           0 : struct zebra_router_table *zebra_router_find_zrt(struct zebra_vrf *zvrf,
      73             :                                                  uint32_t tableid, afi_t afi,
      74             :                                                  safi_t safi)
      75             : {
      76           0 :         struct zebra_router_table finder;
      77           0 :         struct zebra_router_table *zrt;
      78             : 
      79           0 :         memset(&finder, 0, sizeof(finder));
      80           0 :         finder.afi = afi;
      81           0 :         finder.safi = safi;
      82           0 :         finder.tableid = tableid;
      83           0 :         finder.ns_id = zvrf->zns->ns_id;
      84           0 :         zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
      85             : 
      86           0 :         return zrt;
      87             : }
      88             : 
      89           0 : struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf,
      90             :                                             uint32_t tableid, afi_t afi,
      91             :                                             safi_t safi)
      92             : {
      93           0 :         struct zebra_router_table finder;
      94           0 :         struct zebra_router_table *zrt;
      95             : 
      96           0 :         memset(&finder, 0, sizeof(finder));
      97           0 :         finder.afi = afi;
      98           0 :         finder.safi = safi;
      99           0 :         finder.tableid = tableid;
     100           0 :         finder.ns_id = zvrf->zns->ns_id;
     101           0 :         zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
     102             : 
     103           0 :         if (zrt)
     104           0 :                 return zrt->table;
     105             :         else
     106             :                 return NULL;
     107             : }
     108             : 
     109          12 : struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
     110             :                                            uint32_t tableid, afi_t afi,
     111             :                                            safi_t safi)
     112             : {
     113          12 :         struct zebra_router_table finder;
     114          12 :         struct zebra_router_table *zrt;
     115          12 :         struct rib_table_info *info;
     116             : 
     117          12 :         memset(&finder, 0, sizeof(finder));
     118          12 :         finder.afi = afi;
     119          12 :         finder.safi = safi;
     120          12 :         finder.tableid = tableid;
     121          12 :         finder.ns_id = zvrf->zns->ns_id;
     122          12 :         zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
     123             : 
     124          12 :         if (zrt)
     125           0 :                 return zrt->table;
     126             : 
     127          12 :         zrt = XCALLOC(MTYPE_ZEBRA_RT_TABLE, sizeof(*zrt));
     128          12 :         zrt->tableid = tableid;
     129          12 :         zrt->afi = afi;
     130          12 :         zrt->safi = safi;
     131          12 :         zrt->ns_id = zvrf->zns->ns_id;
     132          24 :         zrt->table =
     133          12 :                 (afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
     134             : 
     135          12 :         info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info));
     136          12 :         info->zvrf = zvrf;
     137          12 :         info->afi = afi;
     138          12 :         info->safi = safi;
     139          12 :         info->table_id = tableid;
     140          12 :         route_table_set_info(zrt->table, info);
     141          12 :         zrt->table->cleanup = zebra_rtable_node_cleanup;
     142             : 
     143          12 :         RB_INSERT(zebra_router_table_head, &zrouter.tables, zrt);
     144          12 :         return zrt->table;
     145             : }
     146             : 
     147           0 : void zebra_router_show_table_summary(struct vty *vty)
     148             : {
     149           0 :         struct zebra_router_table *zrt;
     150             : 
     151           0 :         vty_out(vty,
     152             :                 "VRF             NS ID    VRF ID     AFI            SAFI    Table      Count\n");
     153           0 :         vty_out(vty,
     154             :                 "---------------------------------------------------------------------------\n");
     155           0 :         RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
     156           0 :                 struct rib_table_info *info = route_table_get_info(zrt->table);
     157             : 
     158           0 :                 vty_out(vty, "%-16s%5d %9d %7s %15s %8d %10lu\n", info->zvrf->vrf->name,
     159           0 :                         zrt->ns_id, info->zvrf->vrf->vrf_id,
     160             :                         afi2str(zrt->afi), safi2str(zrt->safi),
     161             :                         zrt->tableid,
     162             :                         zrt->table->count);
     163             :         }
     164           0 : }
     165             : 
     166           3 : void zebra_router_sweep_route(void)
     167             : {
     168           3 :         struct zebra_router_table *zrt;
     169             : 
     170          18 :         RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
     171          12 :                 if (zrt->ns_id != NS_DEFAULT)
     172           0 :                         continue;
     173          12 :                 rib_sweep_table(zrt->table);
     174             :         }
     175           3 : }
     176             : 
     177           3 : void zebra_router_sweep_nhgs(void)
     178             : {
     179           3 :         zebra_nhg_sweep_table(zrouter.nhgs_id);
     180           3 : }
     181             : 
     182          12 : static void zebra_router_free_table(struct zebra_router_table *zrt)
     183             : {
     184          12 :         void *table_info;
     185             : 
     186          12 :         table_info = route_table_get_info(zrt->table);
     187          12 :         route_table_finish(zrt->table);
     188          12 :         RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
     189             : 
     190          12 :         XFREE(MTYPE_RIB_TABLE_INFO, table_info);
     191          12 :         XFREE(MTYPE_ZEBRA_RT_TABLE, zrt);
     192          12 : }
     193             : 
     194          12 : void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
     195             :                                 afi_t afi, safi_t safi)
     196             : {
     197          12 :         struct zebra_router_table finder;
     198          12 :         struct zebra_router_table *zrt;
     199             : 
     200          12 :         memset(&finder, 0, sizeof(finder));
     201          12 :         finder.afi = afi;
     202          12 :         finder.safi = safi;
     203          12 :         finder.tableid = tableid;
     204          12 :         finder.ns_id = zvrf->zns->ns_id;
     205          12 :         zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
     206             : 
     207          12 :         if (!zrt)
     208           0 :                 return;
     209             : 
     210          12 :         zebra_router_free_table(zrt);
     211             : }
     212             : 
     213         184 : uint32_t zebra_router_get_next_sequence(void)
     214             : {
     215         184 :         return 1
     216         184 :                + atomic_fetch_add_explicit(&zrouter.sequence_num, 1,
     217             :                                            memory_order_relaxed);
     218             : }
     219             : 
     220           0 : void multicast_mode_ipv4_set(enum multicast_mode mode)
     221             : {
     222           0 :         if (IS_ZEBRA_DEBUG_RIB)
     223           0 :                 zlog_debug("%s: multicast lookup mode set (%d)", __func__,
     224             :                            mode);
     225           0 :         zrouter.ipv4_multicast_mode = mode;
     226           0 : }
     227             : 
     228           0 : enum multicast_mode multicast_mode_ipv4_get(void)
     229             : {
     230           0 :         return zrouter.ipv4_multicast_mode;
     231             : }
     232             : 
     233           3 : void zebra_router_terminate(void)
     234             : {
     235           3 :         struct zebra_router_table *zrt, *tmp;
     236             : 
     237           3 :         THREAD_OFF(zrouter.sweeper);
     238             : 
     239           6 :         RB_FOREACH_SAFE (zrt, zebra_router_table_head, &zrouter.tables, tmp)
     240           0 :                 zebra_router_free_table(zrt);
     241             : 
     242           3 :         work_queue_free_and_null(&zrouter.ribq);
     243           3 :         meta_queue_free(zrouter.mq, NULL);
     244             : 
     245           3 :         zebra_vxlan_disable();
     246           3 :         zebra_mlag_terminate();
     247           3 :         zebra_neigh_terminate();
     248             : 
     249             :         /* Free NHE in ID table only since it has unhashable entries as well */
     250           3 :         hash_iterate(zrouter.nhgs_id, zebra_nhg_hash_free_zero_id, NULL);
     251           3 :         hash_clean(zrouter.nhgs_id, zebra_nhg_hash_free);
     252           3 :         hash_free(zrouter.nhgs_id);
     253           3 :         hash_clean(zrouter.nhgs, NULL);
     254           3 :         hash_free(zrouter.nhgs);
     255             : 
     256           3 :         hash_clean(zrouter.rules_hash, zebra_pbr_rules_free);
     257           3 :         hash_free(zrouter.rules_hash);
     258             : 
     259           3 :         hash_clean(zrouter.ipset_entry_hash, zebra_pbr_ipset_entry_free),
     260           3 :                 hash_clean(zrouter.ipset_hash, zebra_pbr_ipset_free);
     261           3 :         hash_free(zrouter.ipset_hash);
     262           3 :         hash_free(zrouter.ipset_entry_hash);
     263           3 :         hash_clean(zrouter.iptable_hash, zebra_pbr_iptable_free);
     264           3 :         hash_free(zrouter.iptable_hash);
     265             : 
     266             : #ifdef HAVE_SCRIPTING
     267             :         zebra_script_destroy();
     268             : #endif
     269             : 
     270             :         /* OS-specific deinit */
     271           3 :         kernel_router_terminate();
     272           3 : }
     273             : 
     274          21 : bool zebra_router_notify_on_ack(void)
     275             : {
     276          21 :         return !zrouter.asic_offloaded || zrouter.notify_on_ack;
     277             : }
     278             : 
     279           3 : void zebra_router_init(bool asic_offload, bool notify_on_ack)
     280             : {
     281           3 :         zrouter.sequence_num = 0;
     282             : 
     283           3 :         zrouter.allow_delete = false;
     284             : 
     285           3 :         zrouter.packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS;
     286             : 
     287           3 :         zrouter.nhg_keep = ZEBRA_DEFAULT_NHG_KEEP_TIMER;
     288             : 
     289           3 :         zebra_vxlan_init();
     290           3 :         zebra_mlag_init();
     291           3 :         zebra_neigh_init();
     292             : 
     293           3 :         zrouter.rules_hash = hash_create_size(8, zebra_pbr_rules_hash_key,
     294             :                                               zebra_pbr_rules_hash_equal,
     295             :                                               "Rules Hash");
     296             : 
     297           6 :         zrouter.ipset_hash =
     298           3 :                 hash_create_size(8, zebra_pbr_ipset_hash_key,
     299             :                                  zebra_pbr_ipset_hash_equal, "IPset Hash");
     300             : 
     301           3 :         zrouter.ipset_entry_hash = hash_create_size(
     302             :                 8, zebra_pbr_ipset_entry_hash_key,
     303             :                 zebra_pbr_ipset_entry_hash_equal, "IPset Hash Entry");
     304             : 
     305           3 :         zrouter.iptable_hash = hash_create_size(8, zebra_pbr_iptable_hash_key,
     306             :                                                 zebra_pbr_iptable_hash_equal,
     307             :                                                 "IPtable Hash Entry");
     308             : 
     309           6 :         zrouter.nhgs =
     310           3 :                 hash_create_size(8, zebra_nhg_hash_key, zebra_nhg_hash_equal,
     311             :                                  "Zebra Router Nexthop Groups");
     312           6 :         zrouter.nhgs_id =
     313           3 :                 hash_create_size(8, zebra_nhg_id_key, zebra_nhg_hash_id_equal,
     314             :                                  "Zebra Router Nexthop Groups ID index");
     315             : 
     316           6 :         zrouter.rules_hash =
     317           3 :                 hash_create_size(8, zebra_pbr_rules_hash_key,
     318             :                                  zebra_pbr_rules_hash_equal, "Rules Hash");
     319             : 
     320           6 :         zrouter.qdisc_hash =
     321           3 :                 hash_create_size(8, zebra_tc_qdisc_hash_key,
     322             :                                  zebra_tc_qdisc_hash_equal, "TC (qdisc) Hash");
     323           3 :         zrouter.class_hash = hash_create_size(8, zebra_tc_class_hash_key,
     324             :                                               zebra_tc_class_hash_equal,
     325             :                                               "TC (classes) Hash");
     326           3 :         zrouter.filter_hash = hash_create_size(8, zebra_tc_filter_hash_key,
     327             :                                                zebra_tc_filter_hash_equal,
     328             :                                                "TC (filter) Hash");
     329             : 
     330           3 :         zrouter.asic_offloaded = asic_offload;
     331           3 :         zrouter.notify_on_ack = notify_on_ack;
     332             : 
     333             :         /*
     334             :          * If you start using asic_notification_nexthop_control
     335             :          * come talk to the FRR community about what you are doing
     336             :          * We would like to know.
     337             :          */
     338             : #if CONFDATE > 20251231
     339             :         CPP_NOTICE(
     340             :                 "Remove zrouter.asic_notification_nexthop_control as that it's not being maintained or used");
     341             : #endif
     342           3 :         zrouter.asic_notification_nexthop_control = false;
     343             : 
     344             : #ifdef HAVE_SCRIPTING
     345             :         zebra_script_init();
     346             : #endif
     347             : 
     348             :         /* OS-specific init */
     349           3 :         kernel_router_init();
     350           3 : }

Generated by: LCOV version v1.16-topotato