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>