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