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>