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