]>
Commit | Line | Data |
---|---|---|
18a6dce6 | 1 | /* |
2 | * Router ID for zebra daemon. | |
3 | * | |
d62a17ae | 4 | * Copyright (C) 2004 James R. Leu |
18a6dce6 | 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 | * | |
896014f4 DL |
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 | |
18a6dce6 | 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" | |
4a1ab8e4 | 32 | #include "zebra_memory.h" |
18a6dce6 | 33 | #include "ioctl.h" |
34 | #include "connected.h" | |
35 | #include "network.h" | |
36 | #include "log.h" | |
37 | #include "table.h" | |
38 | #include "rib.h" | |
c6ffe645 | 39 | #include "vrf.h" |
18a6dce6 | 40 | |
161e9ab7 | 41 | #include "zebra/zebra_router.h" |
bf094f69 | 42 | #include "zebra/zapi_msg.h" |
7c551956 | 43 | #include "zebra/zebra_vrf.h" |
a1ac18c4 | 44 | #include "zebra/router-id.h" |
6dc686a2 | 45 | #include "zebra/redistribute.h" |
18a6dce6 | 46 | |
d62a17ae | 47 | static struct connected *router_id_find_node(struct list *l, |
48 | struct connected *ifc) | |
18a6dce6 | 49 | { |
d62a17ae | 50 | struct listnode *node; |
51 | struct connected *c; | |
18a6dce6 | 52 | |
d62a17ae | 53 | for (ALL_LIST_ELEMENTS_RO(l, node, c)) |
54 | if (prefix_same(ifc->address, c->address)) | |
55 | return c; | |
1eb8ef25 | 56 | |
d62a17ae | 57 | return NULL; |
18a6dce6 | 58 | } |
59 | ||
d62a17ae | 60 | static int router_id_bad_address(struct connected *ifc) |
18a6dce6 | 61 | { |
d62a17ae | 62 | /* non-redistributable addresses shouldn't be used for RIDs either */ |
63 | if (!zebra_check_addr(ifc->address)) | |
64 | return 1; | |
65 | ||
66 | return 0; | |
18a6dce6 | 67 | } |
68 | ||
98a3fb0a SM |
69 | static bool router_id_v6_is_any(struct prefix *p) |
70 | { | |
71 | return memcmp(&p->u.prefix6, &in6addr_any, sizeof(struct in6_addr)) | |
72 | == 0; | |
73 | } | |
74 | ||
75 | int router_id_get(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf) | |
18a6dce6 | 76 | { |
d62a17ae | 77 | struct listnode *node; |
78 | struct connected *c; | |
98a3fb0a SM |
79 | struct in6_addr *addr = NULL; |
80 | ||
81 | switch (afi) { | |
82 | case AFI_IP: | |
83 | p->u.prefix4.s_addr = INADDR_ANY; | |
84 | p->family = AF_INET; | |
85 | p->prefixlen = 32; | |
86 | if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) | |
87 | p->u.prefix4.s_addr = | |
88 | zvrf->rid_user_assigned.u.prefix4.s_addr; | |
89 | else if (!list_isempty(zvrf->rid_lo_sorted_list)) { | |
90 | node = listtail(zvrf->rid_lo_sorted_list); | |
91 | c = listgetdata(node); | |
92 | p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; | |
93 | } else if (!list_isempty(zvrf->rid_all_sorted_list)) { | |
94 | node = listtail(zvrf->rid_all_sorted_list); | |
95 | c = listgetdata(node); | |
96 | p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; | |
97 | } | |
98 | return 0; | |
99 | case AFI_IP6: | |
100 | p->u.prefix6 = in6addr_any; | |
101 | p->family = AF_INET6; | |
102 | p->prefixlen = 128; | |
103 | if (!router_id_v6_is_any(&zvrf->rid6_user_assigned)) | |
104 | addr = &zvrf->rid6_user_assigned.u.prefix6; | |
105 | else if (!list_isempty(zvrf->rid6_lo_sorted_list)) { | |
106 | node = listtail(zvrf->rid6_lo_sorted_list); | |
107 | c = listgetdata(node); | |
108 | addr = &c->address->u.prefix6; | |
109 | } else if (!list_isempty(zvrf->rid6_all_sorted_list)) { | |
110 | node = listtail(zvrf->rid6_all_sorted_list); | |
111 | c = listgetdata(node); | |
112 | addr = &c->address->u.prefix6; | |
113 | } | |
114 | if (addr) | |
115 | memcpy(&p->u.prefix6, addr, sizeof(struct in6_addr)); | |
116 | return 0; | |
117 | default: | |
118 | return -1; | |
d62a17ae | 119 | } |
18a6dce6 | 120 | } |
121 | ||
98a3fb0a | 122 | static int router_id_set(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf) |
18a6dce6 | 123 | { |
d62a17ae | 124 | struct prefix p2; |
125 | struct listnode *node; | |
126 | struct zserv *client; | |
d62a17ae | 127 | |
98a3fb0a SM |
128 | switch (afi) { |
129 | case AFI_IP: | |
130 | zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr; | |
131 | break; | |
132 | case AFI_IP6: | |
133 | zvrf->rid6_user_assigned.u.prefix6 = p->u.prefix6; | |
134 | break; | |
135 | default: | |
136 | return -1; | |
137 | } | |
d62a17ae | 138 | |
98a3fb0a | 139 | router_id_get(afi, &p2, zvrf); |
d62a17ae | 140 | |
161e9ab7 | 141 | for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) |
98a3fb0a SM |
142 | zsend_router_id_update(client, afi, &p2, zvrf->vrf->vrf_id); |
143 | ||
144 | return 0; | |
18a6dce6 | 145 | } |
146 | ||
d62a17ae | 147 | void router_id_add_address(struct connected *ifc) |
18a6dce6 | 148 | { |
d62a17ae | 149 | struct list *l = NULL; |
150 | struct listnode *node; | |
151 | struct prefix before; | |
152 | struct prefix after; | |
153 | struct zserv *client; | |
a36898e7 | 154 | struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id); |
98a3fb0a SM |
155 | afi_t afi; |
156 | struct list *rid_lo; | |
157 | struct list *rid_all; | |
d62a17ae | 158 | |
159 | if (router_id_bad_address(ifc)) | |
160 | return; | |
161 | ||
98a3fb0a SM |
162 | switch (ifc->address->family) { |
163 | case AF_INET: | |
164 | afi = AFI_IP; | |
165 | rid_lo = zvrf->rid_lo_sorted_list; | |
166 | rid_all = zvrf->rid_all_sorted_list; | |
167 | break; | |
168 | case AF_INET6: | |
169 | afi = AFI_IP6; | |
170 | rid_lo = zvrf->rid6_lo_sorted_list; | |
171 | rid_all = zvrf->rid6_all_sorted_list; | |
172 | break; | |
173 | default: | |
174 | return; | |
175 | } | |
d62a17ae | 176 | |
98a3fb0a SM |
177 | router_id_get(afi, &before, zvrf); |
178 | ||
179 | l = if_is_loopback(ifc->ifp) ? rid_lo : rid_all; | |
d62a17ae | 180 | |
181 | if (!router_id_find_node(l, ifc)) | |
182 | listnode_add_sort(l, ifc); | |
183 | ||
98a3fb0a | 184 | router_id_get(afi, &after, zvrf); |
d62a17ae | 185 | |
186 | if (prefix_same(&before, &after)) | |
187 | return; | |
188 | ||
161e9ab7 | 189 | for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) |
98a3fb0a | 190 | zsend_router_id_update(client, afi, &after, zvrf_id(zvrf)); |
18a6dce6 | 191 | } |
192 | ||
d62a17ae | 193 | void router_id_del_address(struct connected *ifc) |
18a6dce6 | 194 | { |
d62a17ae | 195 | struct connected *c; |
196 | struct list *l; | |
197 | struct prefix after; | |
198 | struct prefix before; | |
199 | struct listnode *node; | |
200 | struct zserv *client; | |
a36898e7 | 201 | struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id); |
98a3fb0a SM |
202 | afi_t afi; |
203 | struct list *rid_lo; | |
204 | struct list *rid_all; | |
18a6dce6 | 205 | |
d62a17ae | 206 | if (router_id_bad_address(ifc)) |
207 | return; | |
18a6dce6 | 208 | |
98a3fb0a SM |
209 | switch (ifc->address->family) { |
210 | case AF_INET: | |
211 | afi = AFI_IP; | |
212 | rid_lo = zvrf->rid_lo_sorted_list; | |
213 | rid_all = zvrf->rid_all_sorted_list; | |
214 | break; | |
215 | case AF_INET6: | |
216 | afi = AFI_IP6; | |
217 | rid_lo = zvrf->rid6_lo_sorted_list; | |
218 | rid_all = zvrf->rid6_all_sorted_list; | |
219 | break; | |
220 | default: | |
221 | return; | |
222 | } | |
223 | ||
224 | router_id_get(afi, &before, zvrf); | |
18a6dce6 | 225 | |
106935f6 | 226 | if (if_is_loopback(ifc->ifp)) |
98a3fb0a | 227 | l = rid_lo; |
d62a17ae | 228 | else |
98a3fb0a | 229 | l = rid_all; |
18a6dce6 | 230 | |
d62a17ae | 231 | if ((c = router_id_find_node(l, ifc))) |
232 | listnode_delete(l, c); | |
18a6dce6 | 233 | |
98a3fb0a | 234 | router_id_get(afi, &after, zvrf); |
18a6dce6 | 235 | |
d62a17ae | 236 | if (prefix_same(&before, &after)) |
237 | return; | |
18a6dce6 | 238 | |
161e9ab7 | 239 | for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) |
98a3fb0a | 240 | zsend_router_id_update(client, afi, &after, zvrf_id(zvrf)); |
18a6dce6 | 241 | } |
242 | ||
03fba42e | 243 | void router_id_write(struct vty *vty, struct zebra_vrf *zvrf) |
18a6dce6 | 244 | { |
03fba42e DS |
245 | char space[2]; |
246 | ||
247 | memset(space, 0, sizeof(space)); | |
248 | ||
249 | if (zvrf_id(zvrf) != VRF_DEFAULT) | |
250 | snprintf(space, sizeof(space), "%s", " "); | |
d62a17ae | 251 | |
03fba42e | 252 | if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) { |
98a3fb0a SM |
253 | vty_out(vty, "%sip router-id %pI4\n", space, |
254 | &zvrf->rid_user_assigned.u.prefix4); | |
255 | } | |
256 | if (!router_id_v6_is_any(&zvrf->rid6_user_assigned)) { | |
257 | vty_out(vty, "%sipv6 router-id %pI6\n", space, | |
258 | &zvrf->rid_user_assigned.u.prefix6); | |
03fba42e | 259 | } |
18a6dce6 | 260 | } |
261 | ||
98a3fb0a SM |
262 | DEFUN (ip_router_id, |
263 | ip_router_id_cmd, | |
264 | "ip router-id A.B.C.D vrf NAME", | |
265 | IP_STR | |
18a6dce6 | 266 | "Manually set the router-id\n" |
98a3fb0a SM |
267 | "IP address to use for router-id\n" |
268 | VRF_CMD_HELP_STR) | |
18a6dce6 | 269 | { |
98a3fb0a SM |
270 | int idx = 0; |
271 | struct prefix rid; | |
272 | vrf_id_t vrf_id; | |
03fba42e | 273 | struct zebra_vrf *zvrf; |
92300491 | 274 | |
98a3fb0a | 275 | argv_find(argv, argc, "A.B.C.D", &idx); |
18a6dce6 | 276 | |
98a3fb0a | 277 | if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4)) |
d62a17ae | 278 | return CMD_WARNING_CONFIG_FAILED; |
18a6dce6 | 279 | |
d62a17ae | 280 | rid.prefixlen = 32; |
281 | rid.family = AF_INET; | |
18a6dce6 | 282 | |
98a3fb0a SM |
283 | argv_find(argv, argc, "NAME", &idx); |
284 | VRF_GET_ID(vrf_id, argv[idx]->arg, false); | |
c6ffe645 | 285 | |
03fba42e | 286 | zvrf = vrf_info_lookup(vrf_id); |
98a3fb0a | 287 | router_id_set(AFI_IP, &rid, zvrf); |
03fba42e DS |
288 | |
289 | return CMD_SUCCESS; | |
290 | } | |
291 | ||
98a3fb0a SM |
292 | ALIAS (ip_router_id, |
293 | router_id_cmd, | |
294 | "router-id A.B.C.D vrf NAME", | |
295 | "Manually set the router-id\n" | |
296 | "IP address to use for router-id\n" | |
297 | VRF_CMD_HELP_STR); | |
298 | ||
299 | DEFUN (ipv6_router_id, | |
300 | ipv6_router_id_cmd, | |
301 | "ipv6 router-id X:X::X:X vrf NAME", | |
302 | IPV6_STR | |
303 | "Manually set the router-id\n" | |
304 | "IPv6 address to use for router-id\n" | |
305 | VRF_CMD_HELP_STR) | |
306 | { | |
307 | int idx = 0; | |
308 | struct prefix rid; | |
309 | vrf_id_t vrf_id; | |
310 | struct zebra_vrf *zvrf; | |
311 | ||
312 | argv_find(argv, argc, "X:X::X:X", &idx); | |
313 | ||
314 | if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6)) | |
315 | return CMD_WARNING_CONFIG_FAILED; | |
316 | ||
317 | rid.prefixlen = 128; | |
318 | rid.family = AF_INET6; | |
319 | ||
320 | argv_find(argv, argc, "NAME", &idx); | |
321 | VRF_GET_ID(vrf_id, argv[idx]->arg, false); | |
322 | ||
323 | zvrf = vrf_info_lookup(vrf_id); | |
324 | router_id_set(AFI_IP6, &rid, zvrf); | |
325 | ||
326 | return CMD_SUCCESS; | |
327 | } | |
328 | ||
329 | ||
330 | DEFUN (ip_router_id_in_vrf, | |
331 | ip_router_id_in_vrf_cmd, | |
332 | "ip router-id A.B.C.D", | |
333 | IP_STR | |
03fba42e DS |
334 | "Manuall set the router-id\n" |
335 | "IP address to use for router-id\n") | |
336 | { | |
337 | ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); | |
98a3fb0a | 338 | int idx = 0; |
03fba42e DS |
339 | struct prefix rid; |
340 | ||
98a3fb0a SM |
341 | argv_find(argv, argc, "A.B.C.D", &idx); |
342 | ||
343 | if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4)) | |
03fba42e DS |
344 | return CMD_WARNING_CONFIG_FAILED; |
345 | ||
346 | rid.prefixlen = 32; | |
347 | rid.family = AF_INET; | |
348 | ||
98a3fb0a | 349 | router_id_set(AFI_IP, &rid, zvrf); |
18a6dce6 | 350 | |
d62a17ae | 351 | return CMD_SUCCESS; |
18a6dce6 | 352 | } |
353 | ||
98a3fb0a SM |
354 | ALIAS (ip_router_id_in_vrf, |
355 | router_id_in_vrf_cmd, | |
356 | "router-id A.B.C.D", | |
357 | "Manually set the router-id\n" | |
358 | "IP address to use for router-id\n"); | |
359 | ||
360 | DEFUN (ipv6_router_id_in_vrf, | |
361 | ipv6_router_id_in_vrf_cmd, | |
362 | "ipv6 router-id X:X::X:X", | |
363 | IP6_STR | |
364 | "Manuall set the IPv6 router-id\n" | |
365 | "IPV6 address to use for router-id\n") | |
366 | { | |
367 | ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); | |
368 | int idx = 0; | |
369 | struct prefix rid; | |
370 | ||
371 | argv_find(argv, argc, "X:X::X:X", &idx); | |
372 | ||
373 | if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6)) | |
374 | return CMD_WARNING_CONFIG_FAILED; | |
375 | ||
376 | rid.prefixlen = 128; | |
377 | rid.family = AF_INET6; | |
378 | ||
379 | router_id_set(AFI_IP6, &rid, zvrf); | |
380 | ||
381 | return CMD_SUCCESS; | |
382 | } | |
383 | ||
384 | DEFUN (no_ip_router_id, | |
385 | no_ip_router_id_cmd, | |
386 | "no ip router-id [A.B.C.D vrf NAME]", | |
18a6dce6 | 387 | NO_STR |
98a3fb0a | 388 | IP_STR |
92300491 | 389 | "Remove the manually configured router-id\n" |
98a3fb0a SM |
390 | "IP address to use for router-id\n" |
391 | VRF_CMD_HELP_STR) | |
18a6dce6 | 392 | { |
98a3fb0a | 393 | int idx = 0; |
d62a17ae | 394 | struct prefix rid; |
395 | vrf_id_t vrf_id = VRF_DEFAULT; | |
03fba42e | 396 | struct zebra_vrf *zvrf; |
18a6dce6 | 397 | |
d62a17ae | 398 | rid.u.prefix4.s_addr = 0; |
399 | rid.prefixlen = 0; | |
400 | rid.family = AF_INET; | |
18a6dce6 | 401 | |
98a3fb0a SM |
402 | if (argv_find(argv, argc, "NAME", &idx)) |
403 | VRF_GET_ID(vrf_id, argv[idx]->arg, false); | |
c6ffe645 | 404 | |
98a3fb0a SM |
405 | zvrf = vrf_info_lookup(vrf_id); |
406 | router_id_set(AFI_IP, &rid, zvrf); | |
03fba42e DS |
407 | |
408 | return CMD_SUCCESS; | |
409 | } | |
410 | ||
98a3fb0a SM |
411 | ALIAS (no_ip_router_id, |
412 | no_router_id_cmd, | |
413 | "no router-id [A.B.C.D vrf NAME]", | |
414 | NO_STR | |
415 | "Remove the manually configured router-id\n" | |
416 | "IP address to use for router-id\n" | |
417 | VRF_CMD_HELP_STR); | |
418 | ||
419 | DEFUN (no_ipv6_router_id, | |
420 | no_ipv6_router_id_cmd, | |
421 | "no ipv6 router-id [X:X::X:X vrf NAME]", | |
422 | NO_STR | |
423 | IPV6_STR | |
424 | "Remove the manually configured IPv6 router-id\n" | |
425 | "IPv6 address to use for router-id\n" | |
426 | VRF_CMD_HELP_STR) | |
427 | { | |
428 | int idx = 0; | |
429 | struct prefix rid; | |
430 | vrf_id_t vrf_id = VRF_DEFAULT; | |
431 | struct zebra_vrf *zvrf; | |
432 | ||
433 | memset(&rid, 0, sizeof(rid)); | |
434 | rid.family = AF_INET; | |
435 | ||
436 | if (argv_find(argv, argc, "NAME", &idx)) | |
437 | VRF_GET_ID(vrf_id, argv[idx]->arg, false); | |
438 | ||
439 | zvrf = vrf_info_lookup(vrf_id); | |
440 | router_id_set(AFI_IP6, &rid, zvrf); | |
441 | ||
442 | return CMD_SUCCESS; | |
443 | } | |
444 | ||
445 | DEFUN (no_ip_router_id_in_vrf, | |
446 | no_ip_router_id_in_vrf_cmd, | |
447 | "no ip router-id [A.B.C.D]", | |
03fba42e | 448 | NO_STR |
98a3fb0a | 449 | IP_STR |
03fba42e DS |
450 | "Remove the manually configured router-id\n" |
451 | "IP address to use for router-id\n") | |
452 | { | |
453 | ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); | |
454 | ||
455 | struct prefix rid; | |
456 | ||
457 | rid.u.prefix4.s_addr = 0; | |
458 | rid.prefixlen = 0; | |
459 | rid.family = AF_INET; | |
460 | ||
98a3fb0a | 461 | router_id_set(AFI_IP, &rid, zvrf); |
18a6dce6 | 462 | |
d62a17ae | 463 | return CMD_SUCCESS; |
18a6dce6 | 464 | } |
465 | ||
98a3fb0a SM |
466 | ALIAS (no_ip_router_id_in_vrf, |
467 | no_router_id_in_vrf_cmd, | |
468 | "no router-id [A.B.C.D]", | |
469 | NO_STR | |
470 | "Remove the manually configured router-id\n" | |
471 | "IP address to use for router-id\n"); | |
472 | ||
473 | DEFUN (no_ipv6_router_id_in_vrf, | |
474 | no_ipv6_router_id_in_vrf_cmd, | |
475 | "no ipv6 router-id [X:X::X:X]", | |
476 | NO_STR | |
477 | IP6_STR | |
478 | "Remove the manually configured IPv6 router-id\n" | |
479 | "IPv6 address to use for router-id\n") | |
480 | { | |
481 | ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); | |
482 | ||
483 | struct prefix rid; | |
484 | ||
485 | memset(&rid, 0, sizeof(rid)); | |
486 | rid.family = AF_INET; | |
487 | ||
488 | router_id_set(AFI_IP6, &rid, zvrf); | |
489 | ||
490 | return CMD_SUCCESS; | |
491 | } | |
492 | ||
493 | DEFUN (show_ip_router_id, | |
494 | show_ip_router_id_cmd, | |
495 | "show [ip|ipv6] router-id [vrf NAME]", | |
13b01f2f | 496 | SHOW_STR |
98a3fb0a SM |
497 | IP_STR |
498 | IPV6_STR | |
13b01f2f JAG |
499 | "Show the configured router-id\n" |
500 | VRF_CMD_HELP_STR) | |
501 | { | |
98a3fb0a SM |
502 | int idx = 0; |
503 | vrf_id_t vrf_id = VRF_DEFAULT; | |
504 | struct zebra_vrf *zvrf; | |
505 | const char *vrf_name = "default"; | |
506 | char addr_name[INET6_ADDRSTRLEN]; | |
507 | int is_ipv6 = 0; | |
13b01f2f | 508 | |
98a3fb0a | 509 | is_ipv6 = argv_find(argv, argc, "ipv6", &idx); |
13b01f2f | 510 | |
98a3fb0a SM |
511 | if (argv_find(argv, argc, "NAME", &idx)) { |
512 | VRF_GET_ID(vrf_id, argv[idx]->arg, false); | |
513 | vrf_name = argv[idx]->arg; | |
514 | } | |
13b01f2f | 515 | |
98a3fb0a | 516 | zvrf = vrf_info_get(vrf_id); |
13b01f2f | 517 | |
98a3fb0a SM |
518 | if (zvrf != NULL) { |
519 | if (is_ipv6) { | |
520 | if (router_id_v6_is_any(&zvrf->rid6_user_assigned)) | |
521 | return CMD_SUCCESS; | |
522 | inet_ntop(AF_INET6, &zvrf->rid6_user_assigned.u.prefix6, | |
523 | addr_name, sizeof(addr_name)); | |
524 | } else { | |
525 | if (zvrf->rid_user_assigned.u.prefix4.s_addr == 0) | |
526 | return CMD_SUCCESS; | |
527 | inet_ntop(AF_INET, &zvrf->rid_user_assigned.u.prefix4, | |
528 | addr_name, sizeof(addr_name)); | |
529 | } | |
530 | ||
531 | vty_out(vty, "zebra:\n"); | |
532 | vty_out(vty, " router-id %s vrf %s\n", addr_name, vrf_name); | |
533 | } | |
13b01f2f | 534 | |
98a3fb0a | 535 | return CMD_SUCCESS; |
13b01f2f | 536 | } |
813d4307 | 537 | |
d62a17ae | 538 | static int router_id_cmp(void *a, void *b) |
18a6dce6 | 539 | { |
d62a17ae | 540 | const struct connected *ifa = (const struct connected *)a; |
541 | const struct connected *ifb = (const struct connected *)b; | |
18a6dce6 | 542 | |
d62a17ae | 543 | return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr, |
544 | &ifb->address->u.prefix4.s_addr); | |
18a6dce6 | 545 | } |
546 | ||
98a3fb0a SM |
547 | static int router_id_v6_cmp(void *a, void *b) |
548 | { | |
549 | const struct connected *ifa = (const struct connected *)a; | |
550 | const struct connected *ifb = (const struct connected *)b; | |
551 | ||
552 | return IPV6_ADDR_CMP(&ifa->address->u.prefix6, | |
553 | &ifb->address->u.prefix6); | |
554 | } | |
555 | ||
d62a17ae | 556 | void router_id_cmd_init(void) |
18a6dce6 | 557 | { |
98a3fb0a | 558 | install_element(CONFIG_NODE, &ip_router_id_cmd); |
d62a17ae | 559 | install_element(CONFIG_NODE, &router_id_cmd); |
98a3fb0a SM |
560 | install_element(CONFIG_NODE, &ipv6_router_id_cmd); |
561 | install_element(CONFIG_NODE, &no_ip_router_id_cmd); | |
d62a17ae | 562 | install_element(CONFIG_NODE, &no_router_id_cmd); |
98a3fb0a SM |
563 | install_element(CONFIG_NODE, &ip_router_id_in_vrf_cmd); |
564 | install_element(VRF_NODE, &ip_router_id_in_vrf_cmd); | |
03fba42e DS |
565 | install_element(CONFIG_NODE, &router_id_in_vrf_cmd); |
566 | install_element(VRF_NODE, &router_id_in_vrf_cmd); | |
98a3fb0a SM |
567 | install_element(CONFIG_NODE, &ipv6_router_id_in_vrf_cmd); |
568 | install_element(VRF_NODE, &ipv6_router_id_in_vrf_cmd); | |
569 | install_element(CONFIG_NODE, &no_ipv6_router_id_cmd); | |
570 | install_element(CONFIG_NODE, &no_ip_router_id_in_vrf_cmd); | |
571 | install_element(VRF_NODE, &no_ip_router_id_in_vrf_cmd); | |
03fba42e DS |
572 | install_element(CONFIG_NODE, &no_router_id_in_vrf_cmd); |
573 | install_element(VRF_NODE, &no_router_id_in_vrf_cmd); | |
98a3fb0a SM |
574 | install_element(CONFIG_NODE, &no_ipv6_router_id_in_vrf_cmd); |
575 | install_element(VRF_NODE, &no_ipv6_router_id_in_vrf_cmd); | |
576 | install_element(VIEW_NODE, &show_ip_router_id_cmd); | |
c6ffe645 FL |
577 | } |
578 | ||
d62a17ae | 579 | void router_id_init(struct zebra_vrf *zvrf) |
c6ffe645 | 580 | { |
d62a17ae | 581 | zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list; |
582 | zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list; | |
98a3fb0a SM |
583 | zvrf->rid6_all_sorted_list = &zvrf->_rid6_all_sorted_list; |
584 | zvrf->rid6_lo_sorted_list = &zvrf->_rid6_lo_sorted_list; | |
18a6dce6 | 585 | |
d62a17ae | 586 | memset(zvrf->rid_all_sorted_list, 0, |
587 | sizeof(zvrf->_rid_all_sorted_list)); | |
588 | memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_sorted_list)); | |
589 | memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned)); | |
98a3fb0a SM |
590 | memset(zvrf->rid6_all_sorted_list, 0, |
591 | sizeof(zvrf->_rid6_all_sorted_list)); | |
592 | memset(zvrf->rid6_lo_sorted_list, 0, | |
593 | sizeof(zvrf->_rid6_lo_sorted_list)); | |
594 | memset(&zvrf->rid6_user_assigned, 0, sizeof(zvrf->rid6_user_assigned)); | |
18a6dce6 | 595 | |
d62a17ae | 596 | zvrf->rid_all_sorted_list->cmp = router_id_cmp; |
597 | zvrf->rid_lo_sorted_list->cmp = router_id_cmp; | |
98a3fb0a SM |
598 | zvrf->rid6_all_sorted_list->cmp = router_id_v6_cmp; |
599 | zvrf->rid6_lo_sorted_list->cmp = router_id_v6_cmp; | |
18a6dce6 | 600 | |
d62a17ae | 601 | zvrf->rid_user_assigned.family = AF_INET; |
602 | zvrf->rid_user_assigned.prefixlen = 32; | |
98a3fb0a SM |
603 | zvrf->rid6_user_assigned.family = AF_INET6; |
604 | zvrf->rid6_user_assigned.prefixlen = 128; | |
18a6dce6 | 605 | } |