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
19 * along with GNU Zebra; see the file COPYING. If not, write to the Free
20 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 #include "sockunion.h"
34 #include "connected.h"
41 #include "zebra/zserv.h"
42 #include "zebra/router-id.h"
43 #include "zebra/redistribute.h"
45 /* master zebra server structure */
46 extern struct zebra_t zebrad;
48 static struct connected *
49 router_id_find_node (struct list *l, struct connected *ifc)
51 struct listnode *node;
54 for (ALL_LIST_ELEMENTS_RO (l, node, c))
55 if (prefix_same (ifc->address, c->address))
62 router_id_bad_address (struct connected *ifc)
64 if (ifc->address->family != AF_INET)
67 /* non-redistributable addresses shouldn't be used for RIDs either */
68 if (!zebra_check_addr (ifc->address))
75 router_id_get (struct prefix *p, vrf_id_t vrf_id)
77 struct listnode *node;
79 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
81 p->u.prefix4.s_addr = 0;
85 if (zvrf->rid_user_assigned.u.prefix4.s_addr)
86 p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
87 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;
93 else if (!list_isempty (zvrf->rid_all_sorted_list))
95 node = listtail (zvrf->rid_all_sorted_list);
96 c = listgetdata (node);
97 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
102 router_id_set (struct prefix *p, vrf_id_t vrf_id)
105 struct listnode *node;
106 struct zserv *client;
107 struct zebra_vrf *zvrf;
109 if (p->u.prefix4.s_addr == 0) /* unset */
111 zvrf = vrf_info_lookup (vrf_id);
116 zvrf = vrf_info_get (vrf_id);
118 zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
120 router_id_get (&p2, vrf_id);
122 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
123 zsend_router_id_update (client, &p2, vrf_id);
127 router_id_add_address (struct connected *ifc)
129 struct list *l = NULL;
130 struct listnode *node;
131 struct prefix before;
133 struct zserv *client;
134 struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
136 if (router_id_bad_address (ifc))
139 router_id_get (&before, zvrf->vrf_id);
141 if (!strncmp (ifc->ifp->name, "lo", 2)
142 || !strncmp (ifc->ifp->name, "dummy", 5))
143 l = zvrf->rid_lo_sorted_list;
145 l = zvrf->rid_all_sorted_list;
147 if (!router_id_find_node (l, ifc))
148 listnode_add_sort (l, ifc);
150 router_id_get (&after, zvrf->vrf_id);
152 if (prefix_same (&before, &after))
155 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
156 zsend_router_id_update (client, &after, zvrf->vrf_id);
160 router_id_del_address (struct connected *ifc)
165 struct prefix before;
166 struct listnode *node;
167 struct zserv *client;
168 struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
170 if (router_id_bad_address (ifc))
173 router_id_get (&before, zvrf->vrf_id);
175 if (!strncmp (ifc->ifp->name, "lo", 2)
176 || !strncmp (ifc->ifp->name, "dummy", 5))
177 l = zvrf->rid_lo_sorted_list;
179 l = zvrf->rid_all_sorted_list;
181 if ((c = router_id_find_node (l, ifc)))
182 listnode_delete (l, c);
184 router_id_get (&after, zvrf->vrf_id);
186 if (prefix_same (&before, &after))
189 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
190 zsend_router_id_update (client, &after, zvrf->vrf_id);
194 router_id_write (struct vty *vty)
196 struct zebra_vrf *zvrf;
199 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
200 if ((zvrf = vrf_iter2info (iter)) != NULL)
201 if (zvrf->rid_user_assigned.u.prefix4.s_addr)
203 if (zvrf->vrf_id == VRF_DEFAULT)
204 vty_out (vty, "router-id %s%s",
205 inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
208 vty_out (vty, "router-id %s vrf %u%s",
209 inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
218 "Manually set the router-id\n"
219 "IP address to use for router-id\n")
222 vrf_id_t vrf_id = VRF_DEFAULT;
224 rid.u.prefix4.s_addr = inet_addr (argv[0]);
225 if (!rid.u.prefix4.s_addr)
229 rid.family = AF_INET;
232 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
234 router_id_set (&rid, vrf_id);
241 "router-id A.B.C.D " VRF_CMD_STR,
242 "Manually set the router-id\n"
243 "IP address to use for router-id\n"
250 "Remove the manually configured router-id\n")
253 vrf_id_t vrf_id = VRF_DEFAULT;
255 rid.u.prefix4.s_addr = 0;
257 rid.family = AF_INET;
260 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
262 router_id_set (&rid, vrf_id);
268 no_router_id_vrf_cmd,
269 "no router-id " VRF_CMD_STR,
271 "Remove the manually configured router-id\n"
275 router_id_cmp (void *a, void *b)
277 const struct connected *ifa = (const struct connected *)a;
278 const struct connected *ifb = (const struct connected *)b;
280 return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,&ifb->address->u.prefix4.s_addr);
284 router_id_cmd_init (void)
286 install_element (CONFIG_NODE, &router_id_cmd);
287 install_element (CONFIG_NODE, &no_router_id_cmd);
288 install_element (CONFIG_NODE, &router_id_vrf_cmd);
289 install_element (CONFIG_NODE, &no_router_id_vrf_cmd);
293 router_id_init (struct zebra_vrf *zvrf)
295 zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
296 zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
298 memset (zvrf->rid_all_sorted_list, 0, sizeof (zvrf->_rid_all_sorted_list));
299 memset (zvrf->rid_lo_sorted_list, 0, sizeof (zvrf->_rid_lo_sorted_list));
300 memset (&zvrf->rid_user_assigned, 0, sizeof (zvrf->rid_user_assigned));
302 zvrf->rid_all_sorted_list->cmp = router_id_cmp;
303 zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
305 zvrf->rid_user_assigned.family = AF_INET;
306 zvrf->rid_user_assigned.prefixlen = 32;