Annotation of embedaddon/quagga/zebra/router-id.c, revision 1.1.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>