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"
40 #include "zebra/zserv.h"
41 #include "zebra/router-id.h"
42 #include "zebra/redistribute.h"
44 static struct list rid_all_sorted_list
;
45 static struct list rid_lo_sorted_list
;
46 static struct prefix rid_user_assigned
;
48 /* master zebra server structure */
49 extern struct zebra_t zebrad
;
51 static struct connected
*
52 router_id_find_node (struct list
*l
, struct connected
*ifc
)
54 struct listnode
*node
;
57 for (ALL_LIST_ELEMENTS_RO (l
, node
, c
))
58 if (prefix_same (ifc
->address
, c
->address
))
65 router_id_bad_address (struct connected
*ifc
)
67 if (ifc
->address
->family
!= AF_INET
)
70 /* non-redistributable addresses shouldn't be used for RIDs either */
71 if (!zebra_check_addr (ifc
->address
))
78 router_id_get (struct prefix
*p
)
80 struct listnode
*node
;
83 p
->u
.prefix4
.s_addr
= 0;
87 if (rid_user_assigned
.u
.prefix4
.s_addr
)
88 p
->u
.prefix4
.s_addr
= rid_user_assigned
.u
.prefix4
.s_addr
;
89 else if (!list_isempty (&rid_lo_sorted_list
))
91 node
= listtail (&rid_lo_sorted_list
);
92 c
= listgetdata (node
);
93 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
95 else if (!list_isempty (&rid_all_sorted_list
))
97 node
= listtail (&rid_all_sorted_list
);
98 c
= listgetdata (node
);
99 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
104 router_id_set (struct prefix
*p
)
107 struct listnode
*node
;
108 struct zserv
*client
;
110 rid_user_assigned
.u
.prefix4
.s_addr
= p
->u
.prefix4
.s_addr
;
114 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
115 zsend_router_id_update (client
, &p2
);
119 router_id_add_address (struct connected
*ifc
)
121 struct list
*l
= NULL
;
122 struct listnode
*node
;
123 struct prefix before
;
125 struct zserv
*client
;
127 if (router_id_bad_address (ifc
))
130 router_id_get (&before
);
132 if (!strncmp (ifc
->ifp
->name
, "lo", 2)
133 || !strncmp (ifc
->ifp
->name
, "dummy", 5))
134 l
= &rid_lo_sorted_list
;
136 l
= &rid_all_sorted_list
;
138 if (!router_id_find_node (l
, ifc
))
139 listnode_add (l
, ifc
);
141 router_id_get (&after
);
143 if (prefix_same (&before
, &after
))
146 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
147 zsend_router_id_update (client
, &after
);
151 router_id_del_address (struct connected
*ifc
)
156 struct prefix before
;
157 struct listnode
*node
;
158 struct zserv
*client
;
160 if (router_id_bad_address (ifc
))
163 router_id_get (&before
);
165 if (!strncmp (ifc
->ifp
->name
, "lo", 2)
166 || !strncmp (ifc
->ifp
->name
, "dummy", 5))
167 l
= &rid_lo_sorted_list
;
169 l
= &rid_all_sorted_list
;
171 if ((c
= router_id_find_node (l
, ifc
)))
172 listnode_delete (l
, c
);
174 router_id_get (&after
);
176 if (prefix_same (&before
, &after
))
179 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
180 zsend_router_id_update (client
, &after
);
184 router_id_write (struct vty
*vty
)
186 if (rid_user_assigned
.u
.prefix4
.s_addr
)
187 vty_out (vty
, "router-id %s%s", inet_ntoa (rid_user_assigned
.u
.prefix4
),
194 "Manually set the router-id\n"
195 "IP address to use for router-id\n")
199 rid
.u
.prefix4
.s_addr
= inet_addr (argv
[0]);
200 if (!rid
.u
.prefix4
.s_addr
)
204 rid
.family
= AF_INET
;
206 router_id_set (&rid
);
215 "Remove the manually configured router-id\n")
219 rid
.u
.prefix4
.s_addr
= 0;
221 rid
.family
= AF_INET
;
223 router_id_set (&rid
);
229 router_id_cmp (void *a
, void *b
)
233 A
= ((struct connected
*) a
)->address
->u
.prefix4
.s_addr
;
234 B
= ((struct connected
*) b
)->address
->u
.prefix4
.s_addr
;
244 router_id_init (void)
246 install_element (CONFIG_NODE
, &router_id_cmd
);
247 install_element (CONFIG_NODE
, &no_router_id_cmd
);
249 memset (&rid_all_sorted_list
, 0, sizeof (rid_all_sorted_list
));
250 memset (&rid_lo_sorted_list
, 0, sizeof (rid_lo_sorted_list
));
251 memset (&rid_user_assigned
, 0, sizeof (rid_user_assigned
));
253 rid_all_sorted_list
.cmp
= router_id_cmp
;
254 rid_lo_sorted_list
.cmp
= router_id_cmp
;
256 rid_user_assigned
.family
= AF_INET
;
257 rid_user_assigned
.prefixlen
= 32;