1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Router ID for zebra daemon.
5 * Copyright (C) 2004 James R. Leu
7 * This file is part of Quagga routing suite.
14 #include "sockunion.h"
20 #include "connected.h"
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"
33 static struct connected
*router_id_find_node(struct list
*l
,
34 struct connected
*ifc
)
36 struct listnode
*node
;
39 for (ALL_LIST_ELEMENTS_RO(l
, node
, c
))
40 if (prefix_same(ifc
->address
, c
->address
))
46 static int router_id_bad_address(struct connected
*ifc
)
48 /* non-redistributable addresses shouldn't be used for RIDs either */
49 if (!zebra_check_addr(ifc
->address
))
55 static bool router_id_v6_is_any(struct prefix
*p
)
57 return memcmp(&p
->u
.prefix6
, &in6addr_any
, sizeof(struct in6_addr
))
61 int router_id_get(afi_t afi
, struct prefix
*p
, struct zebra_vrf
*zvrf
)
63 struct listnode
*node
;
65 struct in6_addr
*addr
= NULL
;
69 p
->u
.prefix4
.s_addr
= INADDR_ANY
;
71 p
->prefixlen
= IPV4_MAX_BITLEN
;
72 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
!= INADDR_ANY
)
74 zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
;
75 else if (!list_isempty(zvrf
->rid_lo_sorted_list
)) {
76 node
= listtail(zvrf
->rid_lo_sorted_list
);
77 c
= listgetdata(node
);
78 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
79 } else if (!list_isempty(zvrf
->rid_all_sorted_list
)) {
80 node
= listtail(zvrf
->rid_all_sorted_list
);
81 c
= listgetdata(node
);
82 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
86 p
->u
.prefix6
= in6addr_any
;
88 p
->prefixlen
= IPV6_MAX_BITLEN
;
89 if (!router_id_v6_is_any(&zvrf
->rid6_user_assigned
))
90 addr
= &zvrf
->rid6_user_assigned
.u
.prefix6
;
91 else if (!list_isempty(zvrf
->rid6_lo_sorted_list
)) {
92 node
= listtail(zvrf
->rid6_lo_sorted_list
);
93 c
= listgetdata(node
);
94 addr
= &c
->address
->u
.prefix6
;
95 } else if (!list_isempty(zvrf
->rid6_all_sorted_list
)) {
96 node
= listtail(zvrf
->rid6_all_sorted_list
);
97 c
= listgetdata(node
);
98 addr
= &c
->address
->u
.prefix6
;
101 memcpy(&p
->u
.prefix6
, addr
, sizeof(struct in6_addr
));
109 assert(!"Reached end of function we should never hit");
112 static int router_id_set(afi_t afi
, struct prefix
*p
, struct zebra_vrf
*zvrf
)
114 struct prefix after
, before
;
115 struct listnode
*node
;
116 struct zserv
*client
;
118 router_id_get(afi
, &before
, zvrf
);
122 zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
= p
->u
.prefix4
.s_addr
;
125 zvrf
->rid6_user_assigned
.u
.prefix6
= p
->u
.prefix6
;
133 router_id_get(afi
, &after
, zvrf
);
136 * If we've been told that the router-id is exactly the same
137 * do we need to really do anything here?
139 if (prefix_same(&before
, &after
))
142 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
143 zsend_router_id_update(client
, afi
, &after
, zvrf
->vrf
->vrf_id
);
148 void router_id_add_address(struct connected
*ifc
)
150 struct list
*l
= NULL
;
151 struct listnode
*node
;
152 struct prefix before
;
154 struct zserv
*client
;
155 struct zebra_vrf
*zvrf
= ifc
->ifp
->vrf
->info
;
158 struct list
*rid_all
;
160 if (router_id_bad_address(ifc
))
163 switch (ifc
->address
->family
) {
166 rid_lo
= zvrf
->rid_lo_sorted_list
;
167 rid_all
= zvrf
->rid_all_sorted_list
;
171 rid_lo
= zvrf
->rid6_lo_sorted_list
;
172 rid_all
= zvrf
->rid6_all_sorted_list
;
178 router_id_get(afi
, &before
, zvrf
);
180 l
= if_is_loopback(ifc
->ifp
) ? rid_lo
: rid_all
;
182 if (!router_id_find_node(l
, ifc
))
183 listnode_add_sort(l
, ifc
);
185 router_id_get(afi
, &after
, zvrf
);
187 if (prefix_same(&before
, &after
))
190 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
191 zsend_router_id_update(client
, afi
, &after
, zvrf_id(zvrf
));
194 void router_id_del_address(struct connected
*ifc
)
199 struct prefix before
;
200 struct listnode
*node
;
201 struct zserv
*client
;
202 struct zebra_vrf
*zvrf
= ifc
->ifp
->vrf
->info
;
205 struct list
*rid_all
;
207 if (router_id_bad_address(ifc
))
210 switch (ifc
->address
->family
) {
213 rid_lo
= zvrf
->rid_lo_sorted_list
;
214 rid_all
= zvrf
->rid_all_sorted_list
;
218 rid_lo
= zvrf
->rid6_lo_sorted_list
;
219 rid_all
= zvrf
->rid6_all_sorted_list
;
225 router_id_get(afi
, &before
, zvrf
);
227 if (if_is_loopback(ifc
->ifp
))
232 if ((c
= router_id_find_node(l
, ifc
)))
233 listnode_delete(l
, c
);
235 router_id_get(afi
, &after
, zvrf
);
237 if (prefix_same(&before
, &after
))
240 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
241 zsend_router_id_update(client
, afi
, &after
, zvrf_id(zvrf
));
244 void router_id_write(struct vty
*vty
, struct zebra_vrf
*zvrf
)
248 memset(space
, 0, sizeof(space
));
250 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
251 snprintf(space
, sizeof(space
), "%s", " ");
253 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
!= INADDR_ANY
) {
254 vty_out(vty
, "%sip router-id %pI4\n", space
,
255 &zvrf
->rid_user_assigned
.u
.prefix4
);
257 if (!router_id_v6_is_any(&zvrf
->rid6_user_assigned
)) {
258 vty_out(vty
, "%sipv6 router-id %pI6\n", space
,
259 &zvrf
->rid_user_assigned
.u
.prefix6
);
265 "ip router-id A.B.C.D vrf NAME",
267 "Manually set the router-id\n"
268 "IP address to use for router-id\n"
274 struct zebra_vrf
*zvrf
;
276 argv_find(argv
, argc
, "A.B.C.D", &idx
);
278 if (!inet_pton(AF_INET
, argv
[idx
]->arg
, &rid
.u
.prefix4
))
279 return CMD_WARNING_CONFIG_FAILED
;
281 rid
.prefixlen
= IPV4_MAX_BITLEN
;
282 rid
.family
= AF_INET
;
284 argv_find(argv
, argc
, "NAME", &idx
);
285 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
287 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
288 router_id_set(AFI_IP
, &rid
, zvrf
);
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"
300 DEFUN (ipv6_router_id
,
302 "ipv6 router-id X:X::X:X vrf NAME",
304 "Manually set the router-id\n"
305 "IPv6 address to use for router-id\n"
311 struct zebra_vrf
*zvrf
;
313 argv_find(argv
, argc
, "X:X::X:X", &idx
);
315 if (!inet_pton(AF_INET6
, argv
[idx
]->arg
, &rid
.u
.prefix6
))
316 return CMD_WARNING_CONFIG_FAILED
;
318 rid
.prefixlen
= IPV6_MAX_BITLEN
;
319 rid
.family
= AF_INET6
;
321 argv_find(argv
, argc
, "NAME", &idx
);
322 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
324 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
325 router_id_set(AFI_IP6
, &rid
, zvrf
);
331 DEFUN (ip_router_id_in_vrf
,
332 ip_router_id_in_vrf_cmd
,
333 "ip router-id A.B.C.D",
335 "Manually set the router-id\n"
336 "IP address to use for router-id\n")
338 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
342 argv_find(argv
, argc
, "A.B.C.D", &idx
);
344 if (!inet_pton(AF_INET
, argv
[idx
]->arg
, &rid
.u
.prefix4
))
345 return CMD_WARNING_CONFIG_FAILED
;
347 rid
.prefixlen
= IPV4_MAX_BITLEN
;
348 rid
.family
= AF_INET
;
350 router_id_set(AFI_IP
, &rid
, zvrf
);
355 ALIAS (ip_router_id_in_vrf
,
356 router_id_in_vrf_cmd
,
358 "Manually set the router-id\n"
359 "IP address to use for router-id\n");
361 DEFUN (ipv6_router_id_in_vrf
,
362 ipv6_router_id_in_vrf_cmd
,
363 "ipv6 router-id X:X::X:X",
365 "Manually set the IPv6 router-id\n"
366 "IPV6 address to use for router-id\n")
368 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
372 argv_find(argv
, argc
, "X:X::X:X", &idx
);
374 if (!inet_pton(AF_INET6
, argv
[idx
]->arg
, &rid
.u
.prefix6
))
375 return CMD_WARNING_CONFIG_FAILED
;
377 rid
.prefixlen
= IPV6_MAX_BITLEN
;
378 rid
.family
= AF_INET6
;
380 router_id_set(AFI_IP6
, &rid
, zvrf
);
385 DEFUN (no_ip_router_id
,
387 "no ip router-id [A.B.C.D vrf NAME]",
390 "Remove the manually configured router-id\n"
391 "IP address to use for router-id\n"
396 vrf_id_t vrf_id
= VRF_DEFAULT
;
397 struct zebra_vrf
*zvrf
;
399 rid
.u
.prefix4
.s_addr
= 0;
401 rid
.family
= AF_INET
;
403 if (argv_find(argv
, argc
, "NAME", &idx
))
404 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
406 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
407 router_id_set(AFI_IP
, &rid
, zvrf
);
412 ALIAS (no_ip_router_id
,
414 "no router-id [A.B.C.D vrf NAME]",
416 "Remove the manually configured router-id\n"
417 "IP address to use for router-id\n"
420 DEFUN (no_ipv6_router_id
,
421 no_ipv6_router_id_cmd
,
422 "no ipv6 router-id [X:X::X:X vrf NAME]",
425 "Remove the manually configured IPv6 router-id\n"
426 "IPv6 address to use for router-id\n"
431 vrf_id_t vrf_id
= VRF_DEFAULT
;
432 struct zebra_vrf
*zvrf
;
434 memset(&rid
, 0, sizeof(rid
));
435 rid
.family
= AF_INET
;
437 if (argv_find(argv
, argc
, "NAME", &idx
))
438 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
440 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
441 router_id_set(AFI_IP6
, &rid
, zvrf
);
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]",
451 "Remove the manually configured router-id\n"
452 "IP address to use for router-id\n")
454 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
458 rid
.u
.prefix4
.s_addr
= 0;
460 rid
.family
= AF_INET
;
462 router_id_set(AFI_IP
, &rid
, zvrf
);
467 ALIAS (no_ip_router_id_in_vrf
,
468 no_router_id_in_vrf_cmd
,
469 "no router-id [A.B.C.D]",
471 "Remove the manually configured router-id\n"
472 "IP address to use for router-id\n");
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]",
479 "Remove the manually configured IPv6 router-id\n"
480 "IPv6 address to use for router-id\n")
482 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
486 memset(&rid
, 0, sizeof(rid
));
487 rid
.family
= AF_INET
;
489 router_id_set(AFI_IP6
, &rid
, zvrf
);
494 DEFUN (show_ip_router_id
,
495 show_ip_router_id_cmd
,
496 "show [ip|ipv6] router-id [vrf NAME]",
500 "Show the configured router-id\n"
504 vrf_id_t vrf_id
= VRF_DEFAULT
;
505 struct zebra_vrf
*zvrf
;
506 const char *vrf_name
= "default";
507 char addr_name
[INET6_ADDRSTRLEN
];
510 is_ipv6
= argv_find(argv
, argc
, "ipv6", &idx
);
512 if (argv_find(argv
, argc
, "NAME", &idx
)) {
513 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
514 vrf_name
= argv
[idx
]->arg
;
517 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
521 if (router_id_v6_is_any(&zvrf
->rid6_user_assigned
))
523 inet_ntop(AF_INET6
, &zvrf
->rid6_user_assigned
.u
.prefix6
,
524 addr_name
, sizeof(addr_name
));
526 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
529 inet_ntop(AF_INET
, &zvrf
->rid_user_assigned
.u
.prefix4
,
530 addr_name
, sizeof(addr_name
));
533 vty_out(vty
, "zebra:\n");
534 vty_out(vty
, " router-id %s vrf %s\n", addr_name
, vrf_name
);
540 static int router_id_cmp(void *a
, void *b
)
542 const struct connected
*ifa
= (const struct connected
*)a
;
543 const struct connected
*ifb
= (const struct connected
*)b
;
545 return IPV4_ADDR_CMP(&ifa
->address
->u
.prefix4
.s_addr
,
546 &ifb
->address
->u
.prefix4
.s_addr
);
549 static int router_id_v6_cmp(void *a
, void *b
)
551 const struct connected
*ifa
= (const struct connected
*)a
;
552 const struct connected
*ifb
= (const struct connected
*)b
;
554 return IPV6_ADDR_CMP(&ifa
->address
->u
.prefix6
,
555 &ifb
->address
->u
.prefix6
);
558 void router_id_cmd_init(void)
560 install_element(CONFIG_NODE
, &ip_router_id_cmd
);
561 install_element(CONFIG_NODE
, &router_id_cmd
);
562 install_element(CONFIG_NODE
, &ipv6_router_id_cmd
);
563 install_element(CONFIG_NODE
, &no_ip_router_id_cmd
);
564 install_element(CONFIG_NODE
, &no_router_id_cmd
);
565 install_element(CONFIG_NODE
, &ip_router_id_in_vrf_cmd
);
566 install_element(VRF_NODE
, &ip_router_id_in_vrf_cmd
);
567 install_element(CONFIG_NODE
, &router_id_in_vrf_cmd
);
568 install_element(VRF_NODE
, &router_id_in_vrf_cmd
);
569 install_element(CONFIG_NODE
, &ipv6_router_id_in_vrf_cmd
);
570 install_element(VRF_NODE
, &ipv6_router_id_in_vrf_cmd
);
571 install_element(CONFIG_NODE
, &no_ipv6_router_id_cmd
);
572 install_element(CONFIG_NODE
, &no_ip_router_id_in_vrf_cmd
);
573 install_element(VRF_NODE
, &no_ip_router_id_in_vrf_cmd
);
574 install_element(CONFIG_NODE
, &no_router_id_in_vrf_cmd
);
575 install_element(VRF_NODE
, &no_router_id_in_vrf_cmd
);
576 install_element(CONFIG_NODE
, &no_ipv6_router_id_in_vrf_cmd
);
577 install_element(VRF_NODE
, &no_ipv6_router_id_in_vrf_cmd
);
578 install_element(VIEW_NODE
, &show_ip_router_id_cmd
);
581 void router_id_init(struct zebra_vrf
*zvrf
)
583 zvrf
->rid_all_sorted_list
= &zvrf
->_rid_all_sorted_list
;
584 zvrf
->rid_lo_sorted_list
= &zvrf
->_rid_lo_sorted_list
;
585 zvrf
->rid6_all_sorted_list
= &zvrf
->_rid6_all_sorted_list
;
586 zvrf
->rid6_lo_sorted_list
= &zvrf
->_rid6_lo_sorted_list
;
588 memset(zvrf
->rid_all_sorted_list
, 0,
589 sizeof(zvrf
->_rid_all_sorted_list
));
590 memset(zvrf
->rid_lo_sorted_list
, 0, sizeof(zvrf
->_rid_lo_sorted_list
));
591 memset(&zvrf
->rid_user_assigned
, 0, sizeof(zvrf
->rid_user_assigned
));
592 memset(zvrf
->rid6_all_sorted_list
, 0,
593 sizeof(zvrf
->_rid6_all_sorted_list
));
594 memset(zvrf
->rid6_lo_sorted_list
, 0,
595 sizeof(zvrf
->_rid6_lo_sorted_list
));
596 memset(&zvrf
->rid6_user_assigned
, 0, sizeof(zvrf
->rid6_user_assigned
));
598 zvrf
->rid_all_sorted_list
->cmp
= router_id_cmp
;
599 zvrf
->rid_lo_sorted_list
->cmp
= router_id_cmp
;
600 zvrf
->rid6_all_sorted_list
->cmp
= router_id_v6_cmp
;
601 zvrf
->rid6_lo_sorted_list
->cmp
= router_id_v6_cmp
;
603 zvrf
->rid_user_assigned
.family
= AF_INET
;
604 zvrf
->rid_user_assigned
.prefixlen
= IPV4_MAX_BITLEN
;
605 zvrf
->rid6_user_assigned
.family
= AF_INET6
;
606 zvrf
->rid6_user_assigned
.prefixlen
= IPV6_MAX_BITLEN
;