2 * Router ID for zebra daemon.
4 * Copyright (C) 2004 James R. Leu
6 * This file is part of Quagga routing suite.
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
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.
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
27 #include "sockunion.h"
33 #include "connected.h"
40 #include "zebra/zebra_router.h"
41 #include "zebra/zapi_msg.h"
42 #include "zebra/zebra_vrf.h"
43 #include "zebra/router-id.h"
44 #include "zebra/redistribute.h"
46 static struct connected
*router_id_find_node(struct list
*l
,
47 struct connected
*ifc
)
49 struct listnode
*node
;
52 for (ALL_LIST_ELEMENTS_RO(l
, node
, c
))
53 if (prefix_same(ifc
->address
, c
->address
))
59 static int router_id_bad_address(struct connected
*ifc
)
61 /* non-redistributable addresses shouldn't be used for RIDs either */
62 if (!zebra_check_addr(ifc
->address
))
68 static bool router_id_v6_is_any(struct prefix
*p
)
70 return memcmp(&p
->u
.prefix6
, &in6addr_any
, sizeof(struct in6_addr
))
74 int router_id_get(afi_t afi
, struct prefix
*p
, struct zebra_vrf
*zvrf
)
76 struct listnode
*node
;
78 struct in6_addr
*addr
= NULL
;
82 p
->u
.prefix4
.s_addr
= INADDR_ANY
;
84 p
->prefixlen
= IPV4_MAX_BITLEN
;
85 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
!= INADDR_ANY
)
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
;
99 p
->u
.prefix6
= in6addr_any
;
100 p
->family
= AF_INET6
;
101 p
->prefixlen
= IPV6_MAX_BITLEN
;
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
;
114 memcpy(&p
->u
.prefix6
, addr
, sizeof(struct in6_addr
));
121 static int router_id_set(afi_t afi
, struct prefix
*p
, struct zebra_vrf
*zvrf
)
123 struct prefix after
, before
;
124 struct listnode
*node
;
125 struct zserv
*client
;
127 router_id_get(afi
, &before
, zvrf
);
131 zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
= p
->u
.prefix4
.s_addr
;
134 zvrf
->rid6_user_assigned
.u
.prefix6
= p
->u
.prefix6
;
140 router_id_get(afi
, &after
, zvrf
);
143 * If we've been told that the router-id is exactly the same
144 * do we need to really do anything here?
146 if (prefix_same(&before
, &after
))
149 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
150 zsend_router_id_update(client
, afi
, &after
, zvrf
->vrf
->vrf_id
);
155 void router_id_add_address(struct connected
*ifc
)
157 struct list
*l
= NULL
;
158 struct listnode
*node
;
159 struct prefix before
;
161 struct zserv
*client
;
162 struct zebra_vrf
*zvrf
= ifc
->ifp
->vrf
->info
;
165 struct list
*rid_all
;
167 if (router_id_bad_address(ifc
))
170 switch (ifc
->address
->family
) {
173 rid_lo
= zvrf
->rid_lo_sorted_list
;
174 rid_all
= zvrf
->rid_all_sorted_list
;
178 rid_lo
= zvrf
->rid6_lo_sorted_list
;
179 rid_all
= zvrf
->rid6_all_sorted_list
;
185 router_id_get(afi
, &before
, zvrf
);
187 l
= if_is_loopback(ifc
->ifp
) ? rid_lo
: rid_all
;
189 if (!router_id_find_node(l
, ifc
))
190 listnode_add_sort(l
, ifc
);
192 router_id_get(afi
, &after
, zvrf
);
194 if (prefix_same(&before
, &after
))
197 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
198 zsend_router_id_update(client
, afi
, &after
, zvrf_id(zvrf
));
201 void router_id_del_address(struct connected
*ifc
)
206 struct prefix before
;
207 struct listnode
*node
;
208 struct zserv
*client
;
209 struct zebra_vrf
*zvrf
= ifc
->ifp
->vrf
->info
;
212 struct list
*rid_all
;
214 if (router_id_bad_address(ifc
))
217 switch (ifc
->address
->family
) {
220 rid_lo
= zvrf
->rid_lo_sorted_list
;
221 rid_all
= zvrf
->rid_all_sorted_list
;
225 rid_lo
= zvrf
->rid6_lo_sorted_list
;
226 rid_all
= zvrf
->rid6_all_sorted_list
;
232 router_id_get(afi
, &before
, zvrf
);
234 if (if_is_loopback(ifc
->ifp
))
239 if ((c
= router_id_find_node(l
, ifc
)))
240 listnode_delete(l
, c
);
242 router_id_get(afi
, &after
, zvrf
);
244 if (prefix_same(&before
, &after
))
247 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
248 zsend_router_id_update(client
, afi
, &after
, zvrf_id(zvrf
));
251 void router_id_write(struct vty
*vty
, struct zebra_vrf
*zvrf
)
255 memset(space
, 0, sizeof(space
));
257 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
258 snprintf(space
, sizeof(space
), "%s", " ");
260 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
!= INADDR_ANY
) {
261 vty_out(vty
, "%sip router-id %pI4\n", space
,
262 &zvrf
->rid_user_assigned
.u
.prefix4
);
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
);
272 "ip router-id A.B.C.D vrf NAME",
274 "Manually set the router-id\n"
275 "IP address to use for router-id\n"
281 struct zebra_vrf
*zvrf
;
283 argv_find(argv
, argc
, "A.B.C.D", &idx
);
285 if (!inet_pton(AF_INET
, argv
[idx
]->arg
, &rid
.u
.prefix4
))
286 return CMD_WARNING_CONFIG_FAILED
;
288 rid
.prefixlen
= IPV4_MAX_BITLEN
;
289 rid
.family
= AF_INET
;
291 argv_find(argv
, argc
, "NAME", &idx
);
292 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
294 zvrf
= vrf_info_lookup(vrf_id
);
295 router_id_set(AFI_IP
, &rid
, zvrf
);
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"
307 DEFUN (ipv6_router_id
,
309 "ipv6 router-id X:X::X:X vrf NAME",
311 "Manually set the router-id\n"
312 "IPv6 address to use for router-id\n"
318 struct zebra_vrf
*zvrf
;
320 argv_find(argv
, argc
, "X:X::X:X", &idx
);
322 if (!inet_pton(AF_INET6
, argv
[idx
]->arg
, &rid
.u
.prefix6
))
323 return CMD_WARNING_CONFIG_FAILED
;
325 rid
.prefixlen
= IPV6_MAX_BITLEN
;
326 rid
.family
= AF_INET6
;
328 argv_find(argv
, argc
, "NAME", &idx
);
329 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
331 zvrf
= vrf_info_lookup(vrf_id
);
332 router_id_set(AFI_IP6
, &rid
, zvrf
);
338 DEFUN (ip_router_id_in_vrf
,
339 ip_router_id_in_vrf_cmd
,
340 "ip router-id A.B.C.D",
342 "Manually set the router-id\n"
343 "IP address to use for router-id\n")
345 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
349 argv_find(argv
, argc
, "A.B.C.D", &idx
);
351 if (!inet_pton(AF_INET
, argv
[idx
]->arg
, &rid
.u
.prefix4
))
352 return CMD_WARNING_CONFIG_FAILED
;
354 rid
.prefixlen
= IPV4_MAX_BITLEN
;
355 rid
.family
= AF_INET
;
357 router_id_set(AFI_IP
, &rid
, zvrf
);
362 ALIAS (ip_router_id_in_vrf
,
363 router_id_in_vrf_cmd
,
365 "Manually set the router-id\n"
366 "IP address to use for router-id\n");
368 DEFUN (ipv6_router_id_in_vrf
,
369 ipv6_router_id_in_vrf_cmd
,
370 "ipv6 router-id X:X::X:X",
372 "Manually set the IPv6 router-id\n"
373 "IPV6 address to use for router-id\n")
375 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
379 argv_find(argv
, argc
, "X:X::X:X", &idx
);
381 if (!inet_pton(AF_INET6
, argv
[idx
]->arg
, &rid
.u
.prefix6
))
382 return CMD_WARNING_CONFIG_FAILED
;
384 rid
.prefixlen
= IPV6_MAX_BITLEN
;
385 rid
.family
= AF_INET6
;
387 router_id_set(AFI_IP6
, &rid
, zvrf
);
392 DEFUN (no_ip_router_id
,
394 "no ip router-id [A.B.C.D vrf NAME]",
397 "Remove the manually configured router-id\n"
398 "IP address to use for router-id\n"
403 vrf_id_t vrf_id
= VRF_DEFAULT
;
404 struct zebra_vrf
*zvrf
;
406 rid
.u
.prefix4
.s_addr
= 0;
408 rid
.family
= AF_INET
;
410 if (argv_find(argv
, argc
, "NAME", &idx
))
411 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
413 zvrf
= vrf_info_lookup(vrf_id
);
414 router_id_set(AFI_IP
, &rid
, zvrf
);
419 ALIAS (no_ip_router_id
,
421 "no router-id [A.B.C.D vrf NAME]",
423 "Remove the manually configured router-id\n"
424 "IP address to use for router-id\n"
427 DEFUN (no_ipv6_router_id
,
428 no_ipv6_router_id_cmd
,
429 "no ipv6 router-id [X:X::X:X vrf NAME]",
432 "Remove the manually configured IPv6 router-id\n"
433 "IPv6 address to use for router-id\n"
438 vrf_id_t vrf_id
= VRF_DEFAULT
;
439 struct zebra_vrf
*zvrf
;
441 memset(&rid
, 0, sizeof(rid
));
442 rid
.family
= AF_INET
;
444 if (argv_find(argv
, argc
, "NAME", &idx
))
445 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
447 zvrf
= vrf_info_lookup(vrf_id
);
448 router_id_set(AFI_IP6
, &rid
, zvrf
);
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]",
458 "Remove the manually configured router-id\n"
459 "IP address to use for router-id\n")
461 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
465 rid
.u
.prefix4
.s_addr
= 0;
467 rid
.family
= AF_INET
;
469 router_id_set(AFI_IP
, &rid
, zvrf
);
474 ALIAS (no_ip_router_id_in_vrf
,
475 no_router_id_in_vrf_cmd
,
476 "no router-id [A.B.C.D]",
478 "Remove the manually configured router-id\n"
479 "IP address to use for router-id\n");
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]",
486 "Remove the manually configured IPv6 router-id\n"
487 "IPv6 address to use for router-id\n")
489 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
493 memset(&rid
, 0, sizeof(rid
));
494 rid
.family
= AF_INET
;
496 router_id_set(AFI_IP6
, &rid
, zvrf
);
501 DEFUN (show_ip_router_id
,
502 show_ip_router_id_cmd
,
503 "show [ip|ipv6] router-id [vrf NAME]",
507 "Show the configured router-id\n"
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
];
517 is_ipv6
= argv_find(argv
, argc
, "ipv6", &idx
);
519 if (argv_find(argv
, argc
, "NAME", &idx
)) {
520 VRF_GET_ID(vrf_id
, argv
[idx
]->arg
, false);
521 vrf_name
= argv
[idx
]->arg
;
524 zvrf
= vrf_info_lookup(vrf_id
);
528 if (router_id_v6_is_any(&zvrf
->rid6_user_assigned
))
530 inet_ntop(AF_INET6
, &zvrf
->rid6_user_assigned
.u
.prefix6
,
531 addr_name
, sizeof(addr_name
));
533 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
536 inet_ntop(AF_INET
, &zvrf
->rid_user_assigned
.u
.prefix4
,
537 addr_name
, sizeof(addr_name
));
540 vty_out(vty
, "zebra:\n");
541 vty_out(vty
, " router-id %s vrf %s\n", addr_name
, vrf_name
);
547 static int router_id_cmp(void *a
, void *b
)
549 const struct connected
*ifa
= (const struct connected
*)a
;
550 const struct connected
*ifb
= (const struct connected
*)b
;
552 return IPV4_ADDR_CMP(&ifa
->address
->u
.prefix4
.s_addr
,
553 &ifb
->address
->u
.prefix4
.s_addr
);
556 static int router_id_v6_cmp(void *a
, void *b
)
558 const struct connected
*ifa
= (const struct connected
*)a
;
559 const struct connected
*ifb
= (const struct connected
*)b
;
561 return IPV6_ADDR_CMP(&ifa
->address
->u
.prefix6
,
562 &ifb
->address
->u
.prefix6
);
565 void router_id_cmd_init(void)
567 install_element(CONFIG_NODE
, &ip_router_id_cmd
);
568 install_element(CONFIG_NODE
, &router_id_cmd
);
569 install_element(CONFIG_NODE
, &ipv6_router_id_cmd
);
570 install_element(CONFIG_NODE
, &no_ip_router_id_cmd
);
571 install_element(CONFIG_NODE
, &no_router_id_cmd
);
572 install_element(CONFIG_NODE
, &ip_router_id_in_vrf_cmd
);
573 install_element(VRF_NODE
, &ip_router_id_in_vrf_cmd
);
574 install_element(CONFIG_NODE
, &router_id_in_vrf_cmd
);
575 install_element(VRF_NODE
, &router_id_in_vrf_cmd
);
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
);
581 install_element(CONFIG_NODE
, &no_router_id_in_vrf_cmd
);
582 install_element(VRF_NODE
, &no_router_id_in_vrf_cmd
);
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
);
588 void router_id_init(struct zebra_vrf
*zvrf
)
590 zvrf
->rid_all_sorted_list
= &zvrf
->_rid_all_sorted_list
;
591 zvrf
->rid_lo_sorted_list
= &zvrf
->_rid_lo_sorted_list
;
592 zvrf
->rid6_all_sorted_list
= &zvrf
->_rid6_all_sorted_list
;
593 zvrf
->rid6_lo_sorted_list
= &zvrf
->_rid6_lo_sorted_list
;
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
));
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
));
605 zvrf
->rid_all_sorted_list
->cmp
= router_id_cmp
;
606 zvrf
->rid_lo_sorted_list
->cmp
= router_id_cmp
;
607 zvrf
->rid6_all_sorted_list
->cmp
= router_id_v6_cmp
;
608 zvrf
->rid6_lo_sorted_list
->cmp
= router_id_v6_cmp
;
610 zvrf
->rid_user_assigned
.family
= AF_INET
;
611 zvrf
->rid_user_assigned
.prefixlen
= IPV4_MAX_BITLEN
;
612 zvrf
->rid6_user_assigned
.family
= AF_INET6
;
613 zvrf
->rid6_user_assigned
.prefixlen
= IPV6_MAX_BITLEN
;