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

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"
1.1.1.2 ! misho      39: #include "vrf.h"
1.1       misho      40: 
                     41: #include "zebra/zserv.h"
                     42: #include "zebra/router-id.h"
                     43: #include "zebra/redistribute.h"
                     44: 
                     45: /* master zebra server structure */
                     46: extern struct zebra_t zebrad;
                     47: 
                     48: static struct connected *
                     49: router_id_find_node (struct list *l, struct connected *ifc)
                     50: {
                     51:   struct listnode *node;
                     52:   struct connected *c;
                     53: 
                     54:   for (ALL_LIST_ELEMENTS_RO (l, node, c))
                     55:     if (prefix_same (ifc->address, c->address))
                     56:       return c;
                     57: 
                     58:   return NULL;
                     59: }
                     60: 
                     61: static int
                     62: router_id_bad_address (struct connected *ifc)
                     63: {
                     64:   if (ifc->address->family != AF_INET)
                     65:     return 1;
                     66:   
                     67:   /* non-redistributable addresses shouldn't be used for RIDs either */
                     68:   if (!zebra_check_addr (ifc->address))
                     69:     return 1;
                     70:   
                     71:   return 0;
                     72: }
                     73: 
                     74: void
1.1.1.2 ! misho      75: router_id_get (struct prefix *p, vrf_id_t vrf_id)
1.1       misho      76: {
                     77:   struct listnode *node;
                     78:   struct connected *c;
1.1.1.2 ! misho      79:   struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
1.1       misho      80: 
                     81:   p->u.prefix4.s_addr = 0;
                     82:   p->family = AF_INET;
                     83:   p->prefixlen = 32;
                     84: 
1.1.1.2 ! misho      85:   if (zvrf->rid_user_assigned.u.prefix4.s_addr)
        !            86:     p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
        !            87:   else if (!list_isempty (zvrf->rid_lo_sorted_list))
1.1       misho      88:     {
1.1.1.2 ! misho      89:       node = listtail (zvrf->rid_lo_sorted_list);
1.1       misho      90:       c = listgetdata (node);
                     91:       p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
                     92:     }
1.1.1.2 ! misho      93:   else if (!list_isempty (zvrf->rid_all_sorted_list))
1.1       misho      94:     {
1.1.1.2 ! misho      95:       node = listtail (zvrf->rid_all_sorted_list);
1.1       misho      96:       c = listgetdata (node);
                     97:       p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
                     98:     }
                     99: }
                    100: 
                    101: static void
1.1.1.2 ! misho     102: router_id_set (struct prefix *p, vrf_id_t vrf_id)
1.1       misho     103: {
                    104:   struct prefix p2;
                    105:   struct listnode *node;
                    106:   struct zserv *client;
1.1.1.2 ! misho     107:   struct zebra_vrf *zvrf;
        !           108: 
        !           109:   if (p->u.prefix4.s_addr == 0) /* unset */
        !           110:     {
        !           111:       zvrf = vrf_info_lookup (vrf_id);
        !           112:       if (! zvrf)
        !           113:         return;
        !           114:     }
        !           115:   else /* set */
        !           116:     zvrf = vrf_info_get (vrf_id);
1.1       misho     117: 
1.1.1.2 ! misho     118:   zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
1.1       misho     119: 
1.1.1.2 ! misho     120:   router_id_get (&p2, vrf_id);
1.1       misho     121: 
                    122:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1.1.1.2 ! misho     123:     zsend_router_id_update (client, &p2, vrf_id);
1.1       misho     124: }
                    125: 
                    126: void
                    127: router_id_add_address (struct connected *ifc)
                    128: {
                    129:   struct list *l = NULL;
                    130:   struct listnode *node;
                    131:   struct prefix before;
                    132:   struct prefix after;
                    133:   struct zserv *client;
1.1.1.2 ! misho     134:   struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
1.1       misho     135: 
                    136:   if (router_id_bad_address (ifc))
                    137:     return;
                    138: 
1.1.1.2 ! misho     139:   router_id_get (&before, zvrf->vrf_id);
1.1       misho     140: 
                    141:   if (!strncmp (ifc->ifp->name, "lo", 2)
                    142:       || !strncmp (ifc->ifp->name, "dummy", 5))
1.1.1.2 ! misho     143:     l = zvrf->rid_lo_sorted_list;
1.1       misho     144:   else
1.1.1.2 ! misho     145:     l = zvrf->rid_all_sorted_list;
1.1       misho     146:   
                    147:   if (!router_id_find_node (l, ifc))
                    148:     listnode_add_sort (l, ifc);
                    149: 
1.1.1.2 ! misho     150:   router_id_get (&after, zvrf->vrf_id);
1.1       misho     151: 
                    152:   if (prefix_same (&before, &after))
                    153:     return;
                    154: 
                    155:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1.1.1.2 ! misho     156:     zsend_router_id_update (client, &after, zvrf->vrf_id);
1.1       misho     157: }
                    158: 
                    159: void
                    160: router_id_del_address (struct connected *ifc)
                    161: {
                    162:   struct connected *c;
                    163:   struct list *l;
                    164:   struct prefix after;
                    165:   struct prefix before;
                    166:   struct listnode *node;
                    167:   struct zserv *client;
1.1.1.2 ! misho     168:   struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
1.1       misho     169: 
                    170:   if (router_id_bad_address (ifc))
                    171:     return;
                    172: 
1.1.1.2 ! misho     173:   router_id_get (&before, zvrf->vrf_id);
1.1       misho     174: 
                    175:   if (!strncmp (ifc->ifp->name, "lo", 2)
                    176:       || !strncmp (ifc->ifp->name, "dummy", 5))
1.1.1.2 ! misho     177:     l = zvrf->rid_lo_sorted_list;
1.1       misho     178:   else
1.1.1.2 ! misho     179:     l = zvrf->rid_all_sorted_list;
1.1       misho     180: 
                    181:   if ((c = router_id_find_node (l, ifc)))
                    182:     listnode_delete (l, c);
                    183: 
1.1.1.2 ! misho     184:   router_id_get (&after, zvrf->vrf_id);
1.1       misho     185: 
                    186:   if (prefix_same (&before, &after))
                    187:     return;
                    188: 
                    189:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1.1.1.2 ! misho     190:     zsend_router_id_update (client, &after, zvrf->vrf_id);
1.1       misho     191: }
                    192: 
                    193: void
                    194: router_id_write (struct vty *vty)
                    195: {
1.1.1.2 ! misho     196:   struct zebra_vrf *zvrf;
        !           197:   vrf_iter_t iter;
        !           198: 
        !           199:   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
        !           200:     if ((zvrf = vrf_iter2info (iter)) != NULL)
        !           201:       if (zvrf->rid_user_assigned.u.prefix4.s_addr)
        !           202:         {
        !           203:           if (zvrf->vrf_id == VRF_DEFAULT)
        !           204:             vty_out (vty, "router-id %s%s",
        !           205:                      inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
        !           206:                      VTY_NEWLINE);
        !           207:           else
        !           208:             vty_out (vty, "router-id %s vrf %u%s",
        !           209:                      inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
        !           210:                      zvrf->vrf_id,
        !           211:                      VTY_NEWLINE);
        !           212:         }
1.1       misho     213: }
                    214: 
                    215: DEFUN (router_id,
                    216:        router_id_cmd,
                    217:        "router-id A.B.C.D",
                    218:        "Manually set the router-id\n"
                    219:        "IP address to use for router-id\n")
                    220: {
                    221:   struct prefix rid;
1.1.1.2 ! misho     222:   vrf_id_t vrf_id = VRF_DEFAULT;
1.1       misho     223: 
                    224:   rid.u.prefix4.s_addr = inet_addr (argv[0]);
                    225:   if (!rid.u.prefix4.s_addr)
                    226:     return CMD_WARNING;
                    227: 
                    228:   rid.prefixlen = 32;
                    229:   rid.family = AF_INET;
                    230: 
1.1.1.2 ! misho     231:   if (argc > 1)
        !           232:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
        !           233: 
        !           234:   router_id_set (&rid, vrf_id);
1.1       misho     235: 
                    236:   return CMD_SUCCESS;
                    237: }
                    238: 
1.1.1.2 ! misho     239: ALIAS (router_id,
        !           240:        router_id_vrf_cmd,
        !           241:        "router-id A.B.C.D " VRF_CMD_STR,
        !           242:        "Manually set the router-id\n"
        !           243:        "IP address to use for router-id\n"
        !           244:        VRF_CMD_HELP_STR)
        !           245: 
1.1       misho     246: DEFUN (no_router_id,
                    247:        no_router_id_cmd,
                    248:        "no router-id",
                    249:        NO_STR
                    250:        "Remove the manually configured router-id\n")
                    251: {
                    252:   struct prefix rid;
1.1.1.2 ! misho     253:   vrf_id_t vrf_id = VRF_DEFAULT;
1.1       misho     254: 
                    255:   rid.u.prefix4.s_addr = 0;
                    256:   rid.prefixlen = 0;
                    257:   rid.family = AF_INET;
                    258: 
1.1.1.2 ! misho     259:   if (argc > 0)
        !           260:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
        !           261: 
        !           262:   router_id_set (&rid, vrf_id);
1.1       misho     263: 
                    264:   return CMD_SUCCESS;
                    265: }
                    266: 
1.1.1.2 ! misho     267: ALIAS (no_router_id,
        !           268:        no_router_id_vrf_cmd,
        !           269:        "no router-id " VRF_CMD_STR,
        !           270:        NO_STR
        !           271:        "Remove the manually configured router-id\n"
        !           272:        VRF_CMD_HELP_STR)
        !           273: 
1.1       misho     274: static int
                    275: router_id_cmp (void *a, void *b)
                    276: {
                    277:   const struct connected *ifa = (const struct connected *)a;
                    278:   const struct connected *ifb = (const struct connected *)b;
                    279: 
1.1.1.2 ! misho     280:   return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,&ifb->address->u.prefix4.s_addr);
1.1       misho     281: }
                    282: 
                    283: void
1.1.1.2 ! misho     284: router_id_cmd_init (void)
1.1       misho     285: {
                    286:   install_element (CONFIG_NODE, &router_id_cmd);
                    287:   install_element (CONFIG_NODE, &no_router_id_cmd);
1.1.1.2 ! misho     288:   install_element (CONFIG_NODE, &router_id_vrf_cmd);
        !           289:   install_element (CONFIG_NODE, &no_router_id_vrf_cmd);
        !           290: }
        !           291: 
        !           292: void
        !           293: router_id_init (struct zebra_vrf *zvrf)
        !           294: {
        !           295:   zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
        !           296:   zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
1.1       misho     297: 
1.1.1.2 ! misho     298:   memset (zvrf->rid_all_sorted_list, 0, sizeof (zvrf->_rid_all_sorted_list));
        !           299:   memset (zvrf->rid_lo_sorted_list, 0, sizeof (zvrf->_rid_lo_sorted_list));
        !           300:   memset (&zvrf->rid_user_assigned, 0, sizeof (zvrf->rid_user_assigned));
1.1       misho     301: 
1.1.1.2 ! misho     302:   zvrf->rid_all_sorted_list->cmp = router_id_cmp;
        !           303:   zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
1.1       misho     304: 
1.1.1.2 ! misho     305:   zvrf->rid_user_assigned.family = AF_INET;
        !           306:   zvrf->rid_user_assigned.prefixlen = 32;
1.1       misho     307: }

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