Annotation of embedaddon/quagga/zebra/router-id.c, revision 1.1

1.1     ! misho       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: router_id_find_node (struct list *l, struct connected *ifc)
        !            53: {
        !            54:   struct listnode *node;
        !            55:   struct connected *c;
        !            56: 
        !            57:   for (ALL_LIST_ELEMENTS_RO (l, node, c))
        !            58:     if (prefix_same (ifc->address, c->address))
        !            59:       return c;
        !            60: 
        !            61:   return NULL;
        !            62: }
        !            63: 
        !            64: static int
        !            65: router_id_bad_address (struct connected *ifc)
        !            66: {
        !            67:   if (ifc->address->family != AF_INET)
        !            68:     return 1;
        !            69:   
        !            70:   /* non-redistributable addresses shouldn't be used for RIDs either */
        !            71:   if (!zebra_check_addr (ifc->address))
        !            72:     return 1;
        !            73:   
        !            74:   return 0;
        !            75: }
        !            76: 
        !            77: void
        !            78: router_id_get (struct prefix *p)
        !            79: {
        !            80:   struct listnode *node;
        !            81:   struct connected *c;
        !            82: 
        !            83:   p->u.prefix4.s_addr = 0;
        !            84:   p->family = AF_INET;
        !            85:   p->prefixlen = 32;
        !            86: 
        !            87:   if (rid_user_assigned.u.prefix4.s_addr)
        !            88:     p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr;
        !            89:   else if (!list_isempty (&rid_lo_sorted_list))
        !            90:     {
        !            91:       node = listtail (&rid_lo_sorted_list);
        !            92:       c = listgetdata (node);
        !            93:       p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
        !            94:     }
        !            95:   else if (!list_isempty (&rid_all_sorted_list))
        !            96:     {
        !            97:       node = listtail (&rid_all_sorted_list);
        !            98:       c = listgetdata (node);
        !            99:       p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
        !           100:     }
        !           101: }
        !           102: 
        !           103: static void
        !           104: router_id_set (struct prefix *p)
        !           105: {
        !           106:   struct prefix p2;
        !           107:   struct listnode *node;
        !           108:   struct zserv *client;
        !           109: 
        !           110:   rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
        !           111: 
        !           112:   router_id_get (&p2);
        !           113: 
        !           114:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
        !           115:     zsend_router_id_update (client, &p2);
        !           116: }
        !           117: 
        !           118: void
        !           119: router_id_add_address (struct connected *ifc)
        !           120: {
        !           121:   struct list *l = NULL;
        !           122:   struct listnode *node;
        !           123:   struct prefix before;
        !           124:   struct prefix after;
        !           125:   struct zserv *client;
        !           126: 
        !           127:   if (router_id_bad_address (ifc))
        !           128:     return;
        !           129: 
        !           130:   router_id_get (&before);
        !           131: 
        !           132:   if (!strncmp (ifc->ifp->name, "lo", 2)
        !           133:       || !strncmp (ifc->ifp->name, "dummy", 5))
        !           134:     l = &rid_lo_sorted_list;
        !           135:   else
        !           136:     l = &rid_all_sorted_list;
        !           137:   
        !           138:   if (!router_id_find_node (l, ifc))
        !           139:     listnode_add_sort (l, ifc);
        !           140: 
        !           141:   router_id_get (&after);
        !           142: 
        !           143:   if (prefix_same (&before, &after))
        !           144:     return;
        !           145: 
        !           146:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
        !           147:     zsend_router_id_update (client, &after);
        !           148: }
        !           149: 
        !           150: void
        !           151: 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:   if (router_id_bad_address (ifc))
        !           161:     return;
        !           162: 
        !           163:   router_id_get (&before);
        !           164: 
        !           165:   if (!strncmp (ifc->ifp->name, "lo", 2)
        !           166:       || !strncmp (ifc->ifp->name, "dummy", 5))
        !           167:     l = &rid_lo_sorted_list;
        !           168:   else
        !           169:     l = &rid_all_sorted_list;
        !           170: 
        !           171:   if ((c = router_id_find_node (l, ifc)))
        !           172:     listnode_delete (l, c);
        !           173: 
        !           174:   router_id_get (&after);
        !           175: 
        !           176:   if (prefix_same (&before, &after))
        !           177:     return;
        !           178: 
        !           179:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
        !           180:     zsend_router_id_update (client, &after);
        !           181: }
        !           182: 
        !           183: void
        !           184: router_id_write (struct vty *vty)
        !           185: {
        !           186:   if (rid_user_assigned.u.prefix4.s_addr)
        !           187:     vty_out (vty, "router-id %s%s", inet_ntoa (rid_user_assigned.u.prefix4),
        !           188:             VTY_NEWLINE);
        !           189: }
        !           190: 
        !           191: 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:   rid.u.prefix4.s_addr = inet_addr (argv[0]);
        !           200:   if (!rid.u.prefix4.s_addr)
        !           201:     return CMD_WARNING;
        !           202: 
        !           203:   rid.prefixlen = 32;
        !           204:   rid.family = AF_INET;
        !           205: 
        !           206:   router_id_set (&rid);
        !           207: 
        !           208:   return CMD_SUCCESS;
        !           209: }
        !           210: 
        !           211: 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:   rid.u.prefix4.s_addr = 0;
        !           220:   rid.prefixlen = 0;
        !           221:   rid.family = AF_INET;
        !           222: 
        !           223:   router_id_set (&rid);
        !           224: 
        !           225:   return CMD_SUCCESS;
        !           226: }
        !           227: 
        !           228: static int
        !           229: router_id_cmp (void *a, void *b)
        !           230: {
        !           231:   const struct connected *ifa = (const struct connected *)a;
        !           232:   const struct connected *ifb = (const struct connected *)b;
        !           233:   unsigned int A = ntohl(ifa->address->u.prefix4.s_addr);
        !           234:   unsigned int B = ntohl(ifb->address->u.prefix4.s_addr);
        !           235: 
        !           236:   return (int) (A - B);
        !           237: }
        !           238: 
        !           239: void
        !           240: router_id_init (void)
        !           241: {
        !           242:   install_element (CONFIG_NODE, &router_id_cmd);
        !           243:   install_element (CONFIG_NODE, &no_router_id_cmd);
        !           244: 
        !           245:   memset (&rid_all_sorted_list, 0, sizeof (rid_all_sorted_list));
        !           246:   memset (&rid_lo_sorted_list, 0, sizeof (rid_lo_sorted_list));
        !           247:   memset (&rid_user_assigned, 0, sizeof (rid_user_assigned));
        !           248: 
        !           249:   rid_all_sorted_list.cmp = router_id_cmp;
        !           250:   rid_lo_sorted_list.cmp = router_id_cmp;
        !           251: 
        !           252:   rid_user_assigned.family = AF_INET;
        !           253:   rid_user_assigned.prefixlen = 32;
        !           254: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>