back to topotato report
topotato coverage report
Current view: top level - ripd - rip_zebra.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 96 117 82.1 %
Date: 2023-02-24 19:38:44 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /* RIPd and zebra interface.
       2             :  * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
       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 "command.h"
      24             : #include "prefix.h"
      25             : #include "table.h"
      26             : #include "stream.h"
      27             : #include "memory.h"
      28             : #include "zclient.h"
      29             : #include "log.h"
      30             : #include "vrf.h"
      31             : #include "ripd/ripd.h"
      32             : #include "ripd/rip_debug.h"
      33             : #include "ripd/rip_interface.h"
      34             : 
      35             : /* All information about zebra. */
      36             : struct zclient *zclient = NULL;
      37             : 
      38             : /* Send ECMP routes to zebra. */
      39          20 : static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp,
      40             :                                 uint8_t cmd)
      41             : {
      42          20 :         struct list *list = (struct list *)rp->info;
      43          20 :         struct zapi_route api;
      44          20 :         struct zapi_nexthop *api_nh;
      45          20 :         struct listnode *listnode = NULL;
      46          20 :         struct rip_info *rinfo = NULL;
      47          20 :         int count = 0;
      48             : 
      49          20 :         memset(&api, 0, sizeof(api));
      50          20 :         api.vrf_id = rip->vrf->vrf_id;
      51          20 :         api.type = ZEBRA_ROUTE_RIP;
      52          20 :         api.safi = SAFI_UNICAST;
      53             : 
      54          20 :         SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
      55          40 :         for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
      56          20 :                 if (count >= MULTIPATH_NUM)
      57             :                         break;
      58          20 :                 api_nh = &api.nexthops[count];
      59          20 :                 api_nh->vrf_id = rip->vrf->vrf_id;
      60          20 :                 api_nh->gate = rinfo->nh.gate;
      61          20 :                 api_nh->type = NEXTHOP_TYPE_IPV4;
      62          20 :                 if (cmd == ZEBRA_ROUTE_ADD)
      63          10 :                         SET_FLAG(rinfo->flags, RIP_RTF_FIB);
      64             :                 else
      65          10 :                         UNSET_FLAG(rinfo->flags, RIP_RTF_FIB);
      66          20 :                 count++;
      67             :         }
      68             : 
      69          20 :         api.prefix = rp->p;
      70          20 :         api.nexthop_num = count;
      71             : 
      72          20 :         rinfo = listgetdata(listhead(list));
      73             : 
      74          20 :         SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
      75          20 :         api.metric = rinfo->metric;
      76             : 
      77          20 :         if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) {
      78           0 :                 SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
      79           0 :                 api.distance = rinfo->distance;
      80             :         }
      81             : 
      82          20 :         if (rinfo->tag) {
      83           0 :                 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
      84           0 :                 api.tag = rinfo->tag;
      85             :         }
      86             : 
      87          20 :         zclient_route_send(cmd, zclient, &api);
      88             : 
      89          20 :         if (IS_RIP_DEBUG_ZEBRA) {
      90           0 :                 if (rip->ecmp)
      91           0 :                         zlog_debug("%s: %pFX nexthops %d",
      92             :                                    (cmd == ZEBRA_ROUTE_ADD)
      93             :                                            ? "Install into zebra"
      94             :                                            : "Delete from zebra",
      95             :                                    &rp->p, count);
      96             :                 else
      97           0 :                         zlog_debug("%s: %pFX",
      98             :                                    (cmd == ZEBRA_ROUTE_ADD)
      99             :                                            ? "Install into zebra"
     100             :                                            : "Delete from zebra", &rp->p);
     101             :         }
     102             : 
     103          20 :         rip->counters.route_changes++;
     104          20 : }
     105             : 
     106             : /* Add/update ECMP routes to zebra. */
     107          10 : void rip_zebra_ipv4_add(struct rip *rip, struct route_node *rp)
     108             : {
     109          10 :         rip_zebra_ipv4_send(rip, rp, ZEBRA_ROUTE_ADD);
     110          10 : }
     111             : 
     112             : /* Delete ECMP routes from zebra. */
     113          10 : void rip_zebra_ipv4_delete(struct rip *rip, struct route_node *rp)
     114             : {
     115          10 :         rip_zebra_ipv4_send(rip, rp, ZEBRA_ROUTE_DELETE);
     116          10 : }
     117             : 
     118             : /* Zebra route add and delete treatment. */
     119          11 : static int rip_zebra_read_route(ZAPI_CALLBACK_ARGS)
     120             : {
     121          11 :         struct rip *rip;
     122          11 :         struct zapi_route api;
     123          11 :         struct nexthop nh;
     124             : 
     125          11 :         rip = rip_lookup_by_vrf_id(vrf_id);
     126          11 :         if (!rip)
     127             :                 return 0;
     128             : 
     129          11 :         if (zapi_route_decode(zclient->ibuf, &api) < 0)
     130             :                 return -1;
     131             : 
     132          11 :         memset(&nh, 0, sizeof(nh));
     133          11 :         nh.type = api.nexthops[0].type;
     134          11 :         nh.gate.ipv4 = api.nexthops[0].gate.ipv4;
     135          11 :         nh.ifindex = api.nexthops[0].ifindex;
     136             : 
     137             :         /* Then fetch IPv4 prefixes. */
     138          11 :         if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
     139           6 :                 rip_redistribute_add(rip, api.type, RIP_ROUTE_REDISTRIBUTE,
     140             :                                      (struct prefix_ipv4 *)&api.prefix, &nh,
     141           6 :                                      api.metric, api.distance, api.tag);
     142           5 :         else if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL)
     143           5 :                 rip_redistribute_delete(rip, api.type, RIP_ROUTE_REDISTRIBUTE,
     144             :                                         (struct prefix_ipv4 *)&api.prefix,
     145             :                                         nh.ifindex);
     146             : 
     147             :         return 0;
     148             : }
     149             : 
     150           2 : void rip_redistribute_conf_update(struct rip *rip, int type)
     151             : {
     152           2 :         zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
     153           2 :                                 type, 0, rip->vrf->vrf_id);
     154           2 : }
     155             : 
     156           0 : void rip_redistribute_conf_delete(struct rip *rip, int type)
     157             : {
     158           0 :         if (zclient->sock > 0)
     159           0 :                 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
     160           0 :                                         AFI_IP, type, 0, rip->vrf->vrf_id);
     161             : 
     162             :         /* Remove the routes from RIP table. */
     163           0 :         rip_redistribute_withdraw(rip, type);
     164           0 : }
     165             : 
     166         580 : int rip_redistribute_check(struct rip *rip, int type)
     167             : {
     168         580 :         return rip->redist[type].enabled;
     169             : }
     170             : 
     171           5 : void rip_redistribute_enable(struct rip *rip)
     172             : {
     173         160 :         for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
     174         155 :                 if (!rip_redistribute_check(rip, i))
     175         155 :                         continue;
     176             : 
     177           0 :                 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
     178           0 :                                         i, 0, rip->vrf->vrf_id);
     179             :         }
     180           5 : }
     181             : 
     182           5 : void rip_redistribute_disable(struct rip *rip)
     183             : {
     184         160 :         for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
     185         155 :                 if (!rip_redistribute_check(rip, i))
     186         153 :                         continue;
     187             : 
     188           2 :                 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
     189           2 :                                         AFI_IP, i, 0, rip->vrf->vrf_id);
     190             :         }
     191           5 : }
     192             : 
     193           9 : void rip_show_redistribute_config(struct vty *vty, struct rip *rip)
     194             : {
     195         288 :         for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
     196         279 :                 if (i == zclient->redist_default
     197         270 :                     || !rip_redistribute_check(rip, i))
     198         277 :                         continue;
     199             : 
     200           2 :                 vty_out(vty, " %s", zebra_route_string(i));
     201             :         }
     202           9 : }
     203             : 
     204           5 : void rip_zebra_vrf_register(struct vrf *vrf)
     205             : {
     206           5 :         if (vrf->vrf_id == VRF_DEFAULT)
     207             :                 return;
     208             : 
     209           0 :         if (IS_RIP_DEBUG_EVENT)
     210           0 :                 zlog_debug("%s: register VRF %s(%u) to zebra", __func__,
     211             :                            vrf->name, vrf->vrf_id);
     212             : 
     213           0 :         zclient_send_reg_requests(zclient, vrf->vrf_id);
     214             : }
     215             : 
     216           5 : void rip_zebra_vrf_deregister(struct vrf *vrf)
     217             : {
     218           5 :         if (vrf->vrf_id == VRF_DEFAULT)
     219             :                 return;
     220             : 
     221           0 :         if (IS_RIP_DEBUG_EVENT)
     222           0 :                 zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__,
     223             :                            vrf->name, vrf->vrf_id);
     224             : 
     225           0 :         zclient_send_dereg_requests(zclient, vrf->vrf_id);
     226             : }
     227             : 
     228           5 : static void rip_zebra_connected(struct zclient *zclient)
     229             : {
     230           5 :         zclient_send_reg_requests(zclient, VRF_DEFAULT);
     231           5 : }
     232             : 
     233             : zclient_handler *const rip_handlers[] = {
     234             :         [ZEBRA_INTERFACE_ADDRESS_ADD] = rip_interface_address_add,
     235             :         [ZEBRA_INTERFACE_ADDRESS_DELETE] = rip_interface_address_delete,
     236             :         [ZEBRA_INTERFACE_VRF_UPDATE] = rip_interface_vrf_update,
     237             :         [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = rip_zebra_read_route,
     238             :         [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = rip_zebra_read_route,
     239             : };
     240             : 
     241           5 : void rip_zclient_init(struct thread_master *master)
     242             : {
     243             :         /* Set default value to the zebra client structure. */
     244           5 :         zclient = zclient_new(master, &zclient_options_default, rip_handlers,
     245             :                               array_size(rip_handlers));
     246           5 :         zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
     247           5 :         zclient->zebra_connected = rip_zebra_connected;
     248           5 : }
     249             : 
     250           5 : void rip_zclient_stop(void)
     251             : {
     252           5 :         zclient_stop(zclient);
     253           5 :         zclient_free(zclient);
     254           5 : }

Generated by: LCOV version v1.16-topotato