File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / router-id.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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: #include "vrf.h"
   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
   75: router_id_get (struct prefix *p, vrf_id_t vrf_id)
   76: {
   77:   struct listnode *node;
   78:   struct connected *c;
   79:   struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
   80: 
   81:   p->u.prefix4.s_addr = 0;
   82:   p->family = AF_INET;
   83:   p->prefixlen = 32;
   84: 
   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))
   88:     {
   89:       node = listtail (zvrf->rid_lo_sorted_list);
   90:       c = listgetdata (node);
   91:       p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
   92:     }
   93:   else if (!list_isempty (zvrf->rid_all_sorted_list))
   94:     {
   95:       node = listtail (zvrf->rid_all_sorted_list);
   96:       c = listgetdata (node);
   97:       p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
   98:     }
   99: }
  100: 
  101: static void
  102: router_id_set (struct prefix *p, vrf_id_t vrf_id)
  103: {
  104:   struct prefix p2;
  105:   struct listnode *node;
  106:   struct zserv *client;
  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);
  117: 
  118:   zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
  119: 
  120:   router_id_get (&p2, vrf_id);
  121: 
  122:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
  123:     zsend_router_id_update (client, &p2, vrf_id);
  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;
  134:   struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
  135: 
  136:   if (router_id_bad_address (ifc))
  137:     return;
  138: 
  139:   router_id_get (&before, zvrf->vrf_id);
  140: 
  141:   if (!strncmp (ifc->ifp->name, "lo", 2)
  142:       || !strncmp (ifc->ifp->name, "dummy", 5))
  143:     l = zvrf->rid_lo_sorted_list;
  144:   else
  145:     l = zvrf->rid_all_sorted_list;
  146:   
  147:   if (!router_id_find_node (l, ifc))
  148:     listnode_add_sort (l, ifc);
  149: 
  150:   router_id_get (&after, zvrf->vrf_id);
  151: 
  152:   if (prefix_same (&before, &after))
  153:     return;
  154: 
  155:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
  156:     zsend_router_id_update (client, &after, zvrf->vrf_id);
  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;
  168:   struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
  169: 
  170:   if (router_id_bad_address (ifc))
  171:     return;
  172: 
  173:   router_id_get (&before, zvrf->vrf_id);
  174: 
  175:   if (!strncmp (ifc->ifp->name, "lo", 2)
  176:       || !strncmp (ifc->ifp->name, "dummy", 5))
  177:     l = zvrf->rid_lo_sorted_list;
  178:   else
  179:     l = zvrf->rid_all_sorted_list;
  180: 
  181:   if ((c = router_id_find_node (l, ifc)))
  182:     listnode_delete (l, c);
  183: 
  184:   router_id_get (&after, zvrf->vrf_id);
  185: 
  186:   if (prefix_same (&before, &after))
  187:     return;
  188: 
  189:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
  190:     zsend_router_id_update (client, &after, zvrf->vrf_id);
  191: }
  192: 
  193: void
  194: router_id_write (struct vty *vty)
  195: {
  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:         }
  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;
  222:   vrf_id_t vrf_id = VRF_DEFAULT;
  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: 
  231:   if (argc > 1)
  232:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
  233: 
  234:   router_id_set (&rid, vrf_id);
  235: 
  236:   return CMD_SUCCESS;
  237: }
  238: 
  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: 
  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;
  253:   vrf_id_t vrf_id = VRF_DEFAULT;
  254: 
  255:   rid.u.prefix4.s_addr = 0;
  256:   rid.prefixlen = 0;
  257:   rid.family = AF_INET;
  258: 
  259:   if (argc > 0)
  260:     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
  261: 
  262:   router_id_set (&rid, vrf_id);
  263: 
  264:   return CMD_SUCCESS;
  265: }
  266: 
  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: 
  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: 
  280:   return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,&ifb->address->u.prefix4.s_addr);
  281: }
  282: 
  283: void
  284: router_id_cmd_init (void)
  285: {
  286:   install_element (CONFIG_NODE, &router_id_cmd);
  287:   install_element (CONFIG_NODE, &no_router_id_cmd);
  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;
  297: 
  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));
  301: 
  302:   zvrf->rid_all_sorted_list->cmp = router_id_cmp;
  303:   zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
  304: 
  305:   zvrf->rid_user_assigned.family = AF_INET;
  306:   zvrf->rid_user_assigned.prefixlen = 32;
  307: }

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