]> git.proxmox.com Git - mirror_frr.git/blob - zebra/router-id.c
isisd: implement the 'lsp-too-large' notification
[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 along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <zebra.h>
24
25 #include "if.h"
26 #include "vty.h"
27 #include "sockunion.h"
28 #include "prefix.h"
29 #include "stream.h"
30 #include "command.h"
31 #include "memory.h"
32 #include "zebra_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/zapi_msg.h"
43 #include "zebra/zebra_vrf.h"
44 #include "zebra/router-id.h"
45 #include "zebra/redistribute.h"
46
47 /* master zebra server structure */
48 extern struct zebra_t zebrad;
49
50 static struct connected *router_id_find_node(struct list *l,
51 struct connected *ifc)
52 {
53 struct listnode *node;
54 struct connected *c;
55
56 for (ALL_LIST_ELEMENTS_RO(l, node, c))
57 if (prefix_same(ifc->address, c->address))
58 return c;
59
60 return NULL;
61 }
62
63 static int router_id_bad_address(struct connected *ifc)
64 {
65 if (ifc->address->family != AF_INET)
66 return 1;
67
68 /* non-redistributable addresses shouldn't be used for RIDs either */
69 if (!zebra_check_addr(ifc->address))
70 return 1;
71
72 return 0;
73 }
74
75 void 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 node = listtail(zvrf->rid_lo_sorted_list);
89 c = listgetdata(node);
90 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
91 } else if (!list_isempty(zvrf->rid_all_sorted_list)) {
92 node = listtail(zvrf->rid_all_sorted_list);
93 c = listgetdata(node);
94 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
95 }
96 }
97
98 static void router_id_set(struct prefix *p, vrf_id_t vrf_id)
99 {
100 struct prefix p2;
101 struct listnode *node;
102 struct zserv *client;
103 struct zebra_vrf *zvrf;
104
105 if (p->u.prefix4.s_addr == 0) /* unset */
106 {
107 zvrf = vrf_info_lookup(vrf_id);
108 if (!zvrf)
109 return;
110 } else /* set */
111 zvrf = vrf_info_get(vrf_id);
112
113 zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
114
115 router_id_get(&p2, vrf_id);
116
117 for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
118 zsend_router_id_update(client, &p2, vrf_id);
119 }
120
121 void 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 struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
129
130 if (router_id_bad_address(ifc))
131 return;
132
133 router_id_get(&before, zvrf_id(zvrf));
134
135 if (if_is_loopback(ifc->ifp))
136 l = zvrf->rid_lo_sorted_list;
137 else
138 l = zvrf->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, zvrf_id(zvrf));
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, zvrf_id(zvrf));
150 }
151
152 void router_id_del_address(struct connected *ifc)
153 {
154 struct connected *c;
155 struct list *l;
156 struct prefix after;
157 struct prefix before;
158 struct listnode *node;
159 struct zserv *client;
160 struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
161
162 if (router_id_bad_address(ifc))
163 return;
164
165 router_id_get(&before, zvrf_id(zvrf));
166
167 if (if_is_loopback(ifc->ifp))
168 l = zvrf->rid_lo_sorted_list;
169 else
170 l = zvrf->rid_all_sorted_list;
171
172 if ((c = router_id_find_node(l, ifc)))
173 listnode_delete(l, c);
174
175 router_id_get(&after, zvrf_id(zvrf));
176
177 if (prefix_same(&before, &after))
178 return;
179
180 for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
181 zsend_router_id_update(client, &after, zvrf_id(zvrf));
182 }
183
184 void router_id_write(struct vty *vty)
185 {
186 struct vrf *vrf;
187 struct zebra_vrf *zvrf;
188
189 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
190 if ((zvrf = vrf->info) != NULL)
191 if (zvrf->rid_user_assigned.u.prefix4.s_addr) {
192 if (zvrf_id(zvrf) == VRF_DEFAULT)
193 vty_out(vty, "router-id %s\n",
194 inet_ntoa(
195 zvrf->rid_user_assigned
196 .u.prefix4));
197 else
198 vty_out(vty, "router-id %s vrf %s\n",
199 inet_ntoa(
200 zvrf->rid_user_assigned
201 .u.prefix4),
202 zvrf_name(zvrf));
203 }
204 }
205
206 DEFUN (router_id,
207 router_id_cmd,
208 "router-id A.B.C.D [vrf NAME]",
209 "Manually set the router-id\n"
210 "IP address to use for router-id\n"
211 VRF_CMD_HELP_STR)
212 {
213 int idx_ipv4 = 1;
214 int idx_name = 3;
215
216 struct prefix rid;
217 vrf_id_t vrf_id = VRF_DEFAULT;
218
219 rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg);
220 if (!rid.u.prefix4.s_addr)
221 return CMD_WARNING_CONFIG_FAILED;
222
223 rid.prefixlen = 32;
224 rid.family = AF_INET;
225
226 if (argc > 2)
227 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
228
229 router_id_set(&rid, vrf_id);
230
231 return CMD_SUCCESS;
232 }
233
234 DEFUN (no_router_id,
235 no_router_id_cmd,
236 "no router-id [A.B.C.D [vrf NAME]]",
237 NO_STR
238 "Remove the manually configured router-id\n"
239 "IP address to use for router-id\n"
240 VRF_CMD_HELP_STR)
241 {
242 int idx_name = 4;
243
244 struct prefix rid;
245 vrf_id_t vrf_id = VRF_DEFAULT;
246
247 rid.u.prefix4.s_addr = 0;
248 rid.prefixlen = 0;
249 rid.family = AF_INET;
250
251 if (argc > 3)
252 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
253
254 router_id_set(&rid, vrf_id);
255
256 return CMD_SUCCESS;
257 }
258
259
260 static int router_id_cmp(void *a, void *b)
261 {
262 const struct connected *ifa = (const struct connected *)a;
263 const struct connected *ifb = (const struct connected *)b;
264
265 return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,
266 &ifb->address->u.prefix4.s_addr);
267 }
268
269 void router_id_cmd_init(void)
270 {
271 install_element(CONFIG_NODE, &router_id_cmd);
272 install_element(CONFIG_NODE, &no_router_id_cmd);
273 }
274
275 void router_id_init(struct zebra_vrf *zvrf)
276 {
277 zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
278 zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
279
280 memset(zvrf->rid_all_sorted_list, 0,
281 sizeof(zvrf->_rid_all_sorted_list));
282 memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_sorted_list));
283 memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned));
284
285 zvrf->rid_all_sorted_list->cmp = router_id_cmp;
286 zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
287
288 zvrf->rid_user_assigned.family = AF_INET;
289 zvrf->rid_user_assigned.prefixlen = 32;
290 }