]> git.proxmox.com Git - mirror_frr.git/blob - zebra/router-id.c
Quagga: Fix compile warnings for GCC4.9
[mirror_frr.git] / zebra / router-id.c
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 list *rid_all_sorted_list = &_rid_all_sorted_list;
47 static struct list *rid_lo_sorted_list = &_rid_lo_sorted_list;
48 static struct prefix rid_user_assigned;
49
50 /* master zebra server structure */
51 extern struct zebra_t zebrad;
52
53 static struct connected *
54 router_id_find_node (struct list *l, struct connected *ifc)
55 {
56 struct listnode *node;
57 struct connected *c;
58
59 for (ALL_LIST_ELEMENTS_RO (l, node, c))
60 if (prefix_same (ifc->address, c->address))
61 return c;
62
63 return NULL;
64 }
65
66 static int
67 router_id_bad_address (struct connected *ifc)
68 {
69 if (ifc->address->family != AF_INET)
70 return 1;
71
72 /* non-redistributable addresses shouldn't be used for RIDs either */
73 if (!zebra_check_addr (ifc->address))
74 return 1;
75
76 return 0;
77 }
78
79 void
80 router_id_get (struct prefix *p)
81 {
82 struct listnode *node;
83 struct connected *c;
84
85 p->u.prefix4.s_addr = 0;
86 p->family = AF_INET;
87 p->prefixlen = 32;
88
89 if (rid_user_assigned.u.prefix4.s_addr)
90 p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr;
91 else if (!list_isempty (rid_lo_sorted_list))
92 {
93 node = listtail (rid_lo_sorted_list);
94 c = listgetdata (node);
95 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
96 }
97 else if (!list_isempty (rid_all_sorted_list))
98 {
99 node = listtail (rid_all_sorted_list);
100 c = listgetdata (node);
101 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
102 }
103 }
104
105 static void
106 router_id_set (struct prefix *p)
107 {
108 struct prefix p2;
109 struct listnode *node;
110 struct zserv *client;
111
112 rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
113
114 router_id_get (&p2);
115
116 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
117 zsend_router_id_update (client, &p2);
118 }
119
120 void
121 router_id_add_address (struct connected *ifc)
122 {
123 struct list *l = NULL;
124 struct listnode *node;
125 struct prefix before;
126 struct prefix after;
127 struct zserv *client;
128
129 if (router_id_bad_address (ifc))
130 return;
131
132 router_id_get (&before);
133
134 if (!strncmp (ifc->ifp->name, "lo", 2)
135 || !strncmp (ifc->ifp->name, "dummy", 5))
136 l = rid_lo_sorted_list;
137 else
138 l = rid_all_sorted_list;
139
140 if (!router_id_find_node (l, ifc))
141 listnode_add_sort (l, ifc);
142
143 router_id_get (&after);
144
145 if (prefix_same (&before, &after))
146 return;
147
148 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
149 zsend_router_id_update (client, &after);
150 }
151
152 void
153 router_id_del_address (struct connected *ifc)
154 {
155 struct connected *c;
156 struct list *l;
157 struct prefix after;
158 struct prefix before;
159 struct listnode *node;
160 struct zserv *client;
161
162 if (router_id_bad_address (ifc))
163 return;
164
165 router_id_get (&before);
166
167 if (!strncmp (ifc->ifp->name, "lo", 2)
168 || !strncmp (ifc->ifp->name, "dummy", 5))
169 l = rid_lo_sorted_list;
170 else
171 l = rid_all_sorted_list;
172
173 if ((c = router_id_find_node (l, ifc)))
174 listnode_delete (l, c);
175
176 router_id_get (&after);
177
178 if (prefix_same (&before, &after))
179 return;
180
181 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
182 zsend_router_id_update (client, &after);
183 }
184
185 void
186 router_id_write (struct vty *vty)
187 {
188 if (rid_user_assigned.u.prefix4.s_addr)
189 vty_out (vty, "router-id %s%s", inet_ntoa (rid_user_assigned.u.prefix4),
190 VTY_NEWLINE);
191 }
192
193 DEFUN (router_id,
194 router_id_cmd,
195 "router-id A.B.C.D",
196 "Manually set the router-id\n"
197 "IP address to use for router-id\n")
198 {
199 struct prefix rid;
200
201 rid.u.prefix4.s_addr = inet_addr (argv[0]);
202 if (!rid.u.prefix4.s_addr)
203 return CMD_WARNING;
204
205 rid.prefixlen = 32;
206 rid.family = AF_INET;
207
208 router_id_set (&rid);
209
210 return CMD_SUCCESS;
211 }
212
213 DEFUN (no_router_id,
214 no_router_id_cmd,
215 "no router-id",
216 NO_STR
217 "Remove the manually configured router-id\n")
218 {
219 struct prefix rid;
220
221 rid.u.prefix4.s_addr = 0;
222 rid.prefixlen = 0;
223 rid.family = AF_INET;
224
225 router_id_set (&rid);
226
227 return CMD_SUCCESS;
228 }
229
230 static int
231 router_id_cmp (void *a, void *b)
232 {
233 const struct connected *ifa = (const struct connected *)a;
234 const struct connected *ifb = (const struct connected *)b;
235
236 return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,&ifb->address->u.prefix4.s_addr);
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 }