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"
32 #include "zebra_memory.h"
34 #include "connected.h"
41 #include "zebra/zebra_router.h"
42 #include "zebra/zapi_msg.h"
43 #include "zebra/zebra_vrf.h"
44 #include "zebra/router-id.h"
45 #include "zebra/redistribute.h"
47 static struct connected
*router_id_find_node(struct list
*l
,
48 struct connected
*ifc
)
50 struct listnode
*node
;
53 for (ALL_LIST_ELEMENTS_RO(l
, node
, c
))
54 if (prefix_same(ifc
->address
, c
->address
))
60 static int router_id_bad_address(struct connected
*ifc
)
62 if (ifc
->address
->family
!= AF_INET
)
65 /* non-redistributable addresses shouldn't be used for RIDs either */
66 if (!zebra_check_addr(ifc
->address
))
72 void router_id_get(struct prefix
*p
, vrf_id_t vrf_id
)
74 struct listnode
*node
;
76 struct zebra_vrf
*zvrf
= vrf_info_get(vrf_id
);
78 p
->u
.prefix4
.s_addr
= 0;
82 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
)
83 p
->u
.prefix4
.s_addr
= zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
;
84 else if (!list_isempty(zvrf
->rid_lo_sorted_list
)) {
85 node
= listtail(zvrf
->rid_lo_sorted_list
);
86 c
= listgetdata(node
);
87 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
88 } else if (!list_isempty(zvrf
->rid_all_sorted_list
)) {
89 node
= listtail(zvrf
->rid_all_sorted_list
);
90 c
= listgetdata(node
);
91 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
95 static void router_id_set(struct prefix
*p
, vrf_id_t vrf_id
)
98 struct listnode
*node
;
100 struct zebra_vrf
*zvrf
;
102 if (p
->u
.prefix4
.s_addr
== 0) /* unset */
104 zvrf
= vrf_info_lookup(vrf_id
);
108 zvrf
= vrf_info_get(vrf_id
);
110 zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
= p
->u
.prefix4
.s_addr
;
112 router_id_get(&p2
, vrf_id
);
114 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
115 zsend_router_id_update(client
, &p2
, vrf_id
);
118 void router_id_add_address(struct connected
*ifc
)
120 struct list
*l
= NULL
;
121 struct listnode
*node
;
122 struct prefix before
;
124 struct zserv
*client
;
125 struct zebra_vrf
*zvrf
= vrf_info_get(ifc
->ifp
->vrf_id
);
127 if (router_id_bad_address(ifc
))
130 router_id_get(&before
, zvrf_id(zvrf
));
132 if (if_is_loopback(ifc
->ifp
))
133 l
= zvrf
->rid_lo_sorted_list
;
135 l
= zvrf
->rid_all_sorted_list
;
137 if (!router_id_find_node(l
, ifc
))
138 listnode_add_sort(l
, ifc
);
140 router_id_get(&after
, zvrf_id(zvrf
));
142 if (prefix_same(&before
, &after
))
145 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
146 zsend_router_id_update(client
, &after
, zvrf_id(zvrf
));
149 void router_id_del_address(struct connected
*ifc
)
154 struct prefix before
;
155 struct listnode
*node
;
156 struct zserv
*client
;
157 struct zebra_vrf
*zvrf
= vrf_info_get(ifc
->ifp
->vrf_id
);
159 if (router_id_bad_address(ifc
))
162 router_id_get(&before
, zvrf_id(zvrf
));
164 if (if_is_loopback(ifc
->ifp
))
165 l
= zvrf
->rid_lo_sorted_list
;
167 l
= zvrf
->rid_all_sorted_list
;
169 if ((c
= router_id_find_node(l
, ifc
)))
170 listnode_delete(l
, c
);
172 router_id_get(&after
, zvrf_id(zvrf
));
174 if (prefix_same(&before
, &after
))
177 for (ALL_LIST_ELEMENTS_RO(zrouter
.client_list
, node
, client
))
178 zsend_router_id_update(client
, &after
, zvrf_id(zvrf
));
181 void router_id_write(struct vty
*vty
)
184 struct zebra_vrf
*zvrf
;
186 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
187 if ((zvrf
= vrf
->info
) != NULL
)
188 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
) {
189 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
190 vty_out(vty
, "router-id %s\n",
192 zvrf
->rid_user_assigned
195 vty_out(vty
, "router-id %s vrf %s\n",
197 zvrf
->rid_user_assigned
205 "router-id A.B.C.D [vrf NAME]",
206 "Manually set the router-id\n"
207 "IP address to use for router-id\n"
214 vrf_id_t vrf_id
= VRF_DEFAULT
;
216 rid
.u
.prefix4
.s_addr
= inet_addr(argv
[idx_ipv4
]->arg
);
217 if (!rid
.u
.prefix4
.s_addr
)
218 return CMD_WARNING_CONFIG_FAILED
;
221 rid
.family
= AF_INET
;
224 VRF_GET_ID(vrf_id
, argv
[idx_name
]->arg
, false);
226 router_id_set(&rid
, vrf_id
);
233 "no router-id [A.B.C.D [vrf NAME]]",
235 "Remove the manually configured router-id\n"
236 "IP address to use for router-id\n"
242 vrf_id_t vrf_id
= VRF_DEFAULT
;
244 rid
.u
.prefix4
.s_addr
= 0;
246 rid
.family
= AF_INET
;
249 VRF_GET_ID(vrf_id
, argv
[idx_name
]->arg
, false);
251 router_id_set(&rid
, vrf_id
);
256 DEFUN (show_router_id
,
258 "show router-id [vrf NAME]",
260 "Show the configured router-id\n"
265 vrf_id_t vrf_id
= VRF_DEFAULT
;
266 struct zebra_vrf
*zvrf
;
269 VRF_GET_ID(vrf_id
, argv
[idx_name
]->arg
, false);
271 zvrf
= vrf_info_get(vrf_id
);
273 if ((zvrf
!= NULL
) && (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
)) {
274 vty_out(vty
, "zebra:\n");
275 if (vrf_id
== VRF_DEFAULT
)
276 vty_out(vty
, " router-id %s vrf default\n",
277 inet_ntoa(zvrf
->rid_user_assigned
.u
.prefix4
));
279 vty_out(vty
, " router-id %s vrf %s\n",
280 inet_ntoa(zvrf
->rid_user_assigned
.u
.prefix4
),
281 argv
[idx_name
]->arg
);
287 static int router_id_cmp(void *a
, void *b
)
289 const struct connected
*ifa
= (const struct connected
*)a
;
290 const struct connected
*ifb
= (const struct connected
*)b
;
292 return IPV4_ADDR_CMP(&ifa
->address
->u
.prefix4
.s_addr
,
293 &ifb
->address
->u
.prefix4
.s_addr
);
296 void router_id_cmd_init(void)
298 install_element(CONFIG_NODE
, &router_id_cmd
);
299 install_element(CONFIG_NODE
, &no_router_id_cmd
);
300 install_element(VIEW_NODE
, &show_router_id_cmd
);
303 void router_id_init(struct zebra_vrf
*zvrf
)
305 zvrf
->rid_all_sorted_list
= &zvrf
->_rid_all_sorted_list
;
306 zvrf
->rid_lo_sorted_list
= &zvrf
->_rid_lo_sorted_list
;
308 memset(zvrf
->rid_all_sorted_list
, 0,
309 sizeof(zvrf
->_rid_all_sorted_list
));
310 memset(zvrf
->rid_lo_sorted_list
, 0, sizeof(zvrf
->_rid_lo_sorted_list
));
311 memset(&zvrf
->rid_user_assigned
, 0, sizeof(zvrf
->rid_user_assigned
));
313 zvrf
->rid_all_sorted_list
->cmp
= router_id_cmp
;
314 zvrf
->rid_lo_sorted_list
->cmp
= router_id_cmp
;
316 zvrf
->rid_user_assigned
.family
= AF_INET
;
317 zvrf
->rid_user_assigned
.prefixlen
= 32;