LCOV - code coverage report
Current view: top level - zebra - router-id.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 64 97 66.0 %
Date: 2015-11-19 Functions: 7 11 63.6 %

          Line data    Source code
       1             : /*
       2             :  * Router ID for zebra daemon.
       3             :  *
       4             :  * Copyright (C) 2004 James R. Leu 
       5             :  *
       6             :  * This file is part of Quagga routing suite.
       7             :  *
       8             :  * Quagga is free software; you can redistribute it and/or modify it
       9             :  * under the terms of the GNU General Public License as published by the
      10             :  * Free Software Foundation; either version 2, or (at your option) any
      11             :  * later version.
      12             :  *
      13             :  * Quagga is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
      20             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      21             :  * 02111-1307, USA.
      22             :  */
      23             : 
      24             : #include <zebra.h>
      25             : 
      26             : #include "if.h"
      27             : #include "vty.h"
      28             : #include "sockunion.h"
      29             : #include "prefix.h"
      30             : #include "stream.h"
      31             : #include "command.h"
      32             : #include "memory.h"
      33             : #include "ioctl.h"
      34             : #include "connected.h"
      35             : #include "network.h"
      36             : #include "log.h"
      37             : #include "table.h"
      38             : #include "rib.h"
      39             : 
      40             : #include "zebra/zserv.h"
      41             : #include "zebra/router-id.h"
      42             : #include "zebra/redistribute.h"
      43             : 
      44             : static struct list rid_all_sorted_list;
      45             : static struct list rid_lo_sorted_list;
      46             : static struct prefix rid_user_assigned;
      47             : 
      48             : /* master zebra server structure */
      49             : extern struct zebra_t zebrad;
      50             : 
      51             : static struct connected *
      52          66 : router_id_find_node (struct list *l, struct connected *ifc)
      53             : {
      54             :   struct listnode *node;
      55             :   struct connected *c;
      56             : 
      57         105 :   for (ALL_LIST_ELEMENTS_RO (l, node, c))
      58          42 :     if (prefix_same (ifc->address, c->address))
      59           3 :       return c;
      60             : 
      61          63 :   return NULL;
      62             : }
      63             : 
      64             : static int
      65         287 : router_id_bad_address (struct connected *ifc)
      66             : {
      67         287 :   if (ifc->address->family != AF_INET)
      68         176 :     return 1;
      69             :   
      70             :   /* non-redistributable addresses shouldn't be used for RIDs either */
      71         111 :   if (!zebra_check_addr (ifc->address))
      72          45 :     return 1;
      73             :   
      74          66 :   return 0;
      75             : }
      76             : 
      77             : void
      78         132 : router_id_get (struct prefix *p)
      79             : {
      80             :   struct listnode *node;
      81             :   struct connected *c;
      82             : 
      83         132 :   p->u.prefix4.s_addr = 0;
      84         132 :   p->family = AF_INET;
      85         132 :   p->prefixlen = 32;
      86             : 
      87         132 :   if (rid_user_assigned.u.prefix4.s_addr)
      88           0 :     p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr;
      89         132 :   else if (!list_isempty (&rid_lo_sorted_list))
      90             :     {
      91           0 :       node = listtail (&rid_lo_sorted_list);
      92           0 :       c = listgetdata (node);
      93           0 :       p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
      94             :     }
      95         132 :   else if (!list_isempty (&rid_all_sorted_list))
      96             :     {
      97         101 :       node = listtail (&rid_all_sorted_list);
      98         101 :       c = listgetdata (node);
      99         101 :       p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
     100             :     }
     101         132 : }
     102             : 
     103             : static void
     104           0 : router_id_set (struct prefix *p)
     105             : {
     106             :   struct prefix p2;
     107             :   struct listnode *node;
     108             :   struct zserv *client;
     109             : 
     110           0 :   rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
     111             : 
     112           0 :   router_id_get (&p2);
     113             : 
     114           0 :   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
     115           0 :     zsend_router_id_update (client, &p2);
     116           0 : }
     117             : 
     118             : void
     119         279 : router_id_add_address (struct connected *ifc)
     120             : {
     121         279 :   struct list *l = NULL;
     122             :   struct listnode *node;
     123             :   struct prefix before;
     124             :   struct prefix after;
     125             :   struct zserv *client;
     126             : 
     127         279 :   if (router_id_bad_address (ifc))
     128         432 :     return;
     129             : 
     130          64 :   router_id_get (&before);
     131             : 
     132          64 :   if (!strncmp (ifc->ifp->name, "lo", 2)
     133          64 :       || !strncmp (ifc->ifp->name, "dummy", 5))
     134           0 :     l = &rid_lo_sorted_list;
     135             :   else
     136          64 :     l = &rid_all_sorted_list;
     137             :   
     138          64 :   if (!router_id_find_node (l, ifc))
     139          63 :     listnode_add_sort (l, ifc);
     140             : 
     141          64 :   router_id_get (&after);
     142             : 
     143          64 :   if (prefix_same (&before, &after))
     144           2 :     return;
     145             : 
     146          62 :   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
     147           0 :     zsend_router_id_update (client, &after);
     148             : }
     149             : 
     150             : void
     151           8 : router_id_del_address (struct connected *ifc)
     152             : {
     153             :   struct connected *c;
     154             :   struct list *l;
     155             :   struct prefix after;
     156             :   struct prefix before;
     157             :   struct listnode *node;
     158             :   struct zserv *client;
     159             : 
     160           8 :   if (router_id_bad_address (ifc))
     161          13 :     return;
     162             : 
     163           2 :   router_id_get (&before);
     164             : 
     165           2 :   if (!strncmp (ifc->ifp->name, "lo", 2)
     166           2 :       || !strncmp (ifc->ifp->name, "dummy", 5))
     167           0 :     l = &rid_lo_sorted_list;
     168             :   else
     169           2 :     l = &rid_all_sorted_list;
     170             : 
     171           2 :   if ((c = router_id_find_node (l, ifc)))
     172           2 :     listnode_delete (l, c);
     173             : 
     174           2 :   router_id_get (&after);
     175             : 
     176           2 :   if (prefix_same (&before, &after))
     177           1 :     return;
     178             : 
     179           1 :   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
     180           0 :     zsend_router_id_update (client, &after);
     181             : }
     182             : 
     183             : void
     184           0 : router_id_write (struct vty *vty)
     185             : {
     186           0 :   if (rid_user_assigned.u.prefix4.s_addr)
     187           0 :     vty_out (vty, "router-id %s%s", inet_ntoa (rid_user_assigned.u.prefix4),
     188           0 :              VTY_NEWLINE);
     189           0 : }
     190             : 
     191           0 : DEFUN (router_id,
     192             :        router_id_cmd,
     193             :        "router-id A.B.C.D",
     194             :        "Manually set the router-id\n"
     195             :        "IP address to use for router-id\n")
     196             : {
     197             :   struct prefix rid;
     198             : 
     199           0 :   rid.u.prefix4.s_addr = inet_addr (argv[0]);
     200           0 :   if (!rid.u.prefix4.s_addr)
     201           0 :     return CMD_WARNING;
     202             : 
     203           0 :   rid.prefixlen = 32;
     204           0 :   rid.family = AF_INET;
     205             : 
     206           0 :   router_id_set (&rid);
     207             : 
     208           0 :   return CMD_SUCCESS;
     209             : }
     210             : 
     211           0 : DEFUN (no_router_id,
     212             :        no_router_id_cmd,
     213             :        "no router-id",
     214             :        NO_STR
     215             :        "Remove the manually configured router-id\n")
     216             : {
     217             :   struct prefix rid;
     218             : 
     219           0 :   rid.u.prefix4.s_addr = 0;
     220           0 :   rid.prefixlen = 0;
     221           0 :   rid.family = AF_INET;
     222             : 
     223           0 :   router_id_set (&rid);
     224             : 
     225           0 :   return CMD_SUCCESS;
     226             : }
     227             : 
     228             : static int
     229          39 : router_id_cmp (void *a, void *b)
     230             : {
     231          39 :   const struct connected *ifa = (const struct connected *)a;
     232          39 :   const struct connected *ifb = (const struct connected *)b;
     233             : 
     234          39 :   return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,&ifb->address->u.prefix4.s_addr);
     235             : }
     236             : 
     237             : void
     238          45 : router_id_init (void)
     239             : {
     240          45 :   install_element (CONFIG_NODE, &router_id_cmd);
     241          45 :   install_element (CONFIG_NODE, &no_router_id_cmd);
     242             : 
     243          45 :   memset (&rid_all_sorted_list, 0, sizeof (rid_all_sorted_list));
     244          45 :   memset (&rid_lo_sorted_list, 0, sizeof (rid_lo_sorted_list));
     245          45 :   memset (&rid_user_assigned, 0, sizeof (rid_user_assigned));
     246             : 
     247          45 :   rid_all_sorted_list.cmp = router_id_cmp;
     248          45 :   rid_lo_sorted_list.cmp = router_id_cmp;
     249             : 
     250          45 :   rid_user_assigned.family = AF_INET;
     251          45 :   rid_user_assigned.prefixlen = 32;
     252          45 : }

Generated by: LCOV version 1.10