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 list
*rid_all_sorted_list
= &_rid_all_sorted_list
;
47 static struct list
*rid_lo_sorted_list
= &_rid_lo_sorted_list
;
48 static struct prefix rid_user_assigned
;
50 /* master zebra server structure */
51 extern struct zebra_t zebrad
;
53 static struct connected
*
54 router_id_find_node (struct list
*l
, struct connected
*ifc
)
56 struct listnode
*node
;
59 for (ALL_LIST_ELEMENTS_RO (l
, node
, c
))
60 if (prefix_same (ifc
->address
, c
->address
))
67 router_id_bad_address (struct connected
*ifc
)
69 if (ifc
->address
->family
!= AF_INET
)
72 /* non-redistributable addresses shouldn't be used for RIDs either */
73 if (!zebra_check_addr (ifc
->address
))
80 router_id_get (struct prefix
*p
)
82 struct listnode
*node
;
85 p
->u
.prefix4
.s_addr
= 0;
89 if (rid_user_assigned
.u
.prefix4
.s_addr
)
90 p
->u
.prefix4
.s_addr
= rid_user_assigned
.u
.prefix4
.s_addr
;
91 else if (!list_isempty (rid_lo_sorted_list
))
93 node
= listtail (rid_lo_sorted_list
);
94 c
= listgetdata (node
);
95 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
97 else if (!list_isempty (rid_all_sorted_list
))
99 node
= listtail (rid_all_sorted_list
);
100 c
= listgetdata (node
);
101 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
106 router_id_set (struct prefix
*p
)
109 struct listnode
*node
;
110 struct zserv
*client
;
112 rid_user_assigned
.u
.prefix4
.s_addr
= p
->u
.prefix4
.s_addr
;
116 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
117 zsend_router_id_update (client
, &p2
);
121 router_id_add_address (struct connected
*ifc
)
123 struct list
*l
= NULL
;
124 struct listnode
*node
;
125 struct prefix before
;
127 struct zserv
*client
;
129 if (router_id_bad_address (ifc
))
132 router_id_get (&before
);
134 if (!strncmp (ifc
->ifp
->name
, "lo", 2)
135 || !strncmp (ifc
->ifp
->name
, "dummy", 5))
136 l
= rid_lo_sorted_list
;
138 l
= rid_all_sorted_list
;
140 if (!router_id_find_node (l
, ifc
))
141 listnode_add_sort (l
, ifc
);
143 router_id_get (&after
);
145 if (prefix_same (&before
, &after
))
148 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
149 zsend_router_id_update (client
, &after
);
153 router_id_del_address (struct connected
*ifc
)
158 struct prefix before
;
159 struct listnode
*node
;
160 struct zserv
*client
;
162 if (router_id_bad_address (ifc
))
165 router_id_get (&before
);
167 if (!strncmp (ifc
->ifp
->name
, "lo", 2)
168 || !strncmp (ifc
->ifp
->name
, "dummy", 5))
169 l
= rid_lo_sorted_list
;
171 l
= rid_all_sorted_list
;
173 if ((c
= router_id_find_node (l
, ifc
)))
174 listnode_delete (l
, c
);
176 router_id_get (&after
);
178 if (prefix_same (&before
, &after
))
181 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
182 zsend_router_id_update (client
, &after
);
186 router_id_write (struct vty
*vty
)
188 if (rid_user_assigned
.u
.prefix4
.s_addr
)
189 vty_out (vty
, "router-id %s%s", inet_ntoa (rid_user_assigned
.u
.prefix4
),
196 "Manually set the router-id\n"
197 "IP address to use for router-id\n")
201 rid
.u
.prefix4
.s_addr
= inet_addr (argv
[0]);
202 if (!rid
.u
.prefix4
.s_addr
)
206 rid
.family
= AF_INET
;
208 router_id_set (&rid
);
217 "Remove the manually configured router-id\n")
221 rid
.u
.prefix4
.s_addr
= 0;
223 rid
.family
= AF_INET
;
225 router_id_set (&rid
);
231 router_id_cmp (void *a
, void *b
)
233 const struct connected
*ifa
= (const struct connected
*)a
;
234 const struct connected
*ifb
= (const struct connected
*)b
;
236 return IPV4_ADDR_CMP(&ifa
->address
->u
.prefix4
.s_addr
,&ifb
->address
->u
.prefix4
.s_addr
);
240 router_id_init (void)
242 install_element (CONFIG_NODE
, &router_id_cmd
);
243 install_element (CONFIG_NODE
, &no_router_id_cmd
);
245 memset (rid_all_sorted_list
, 0, sizeof (_rid_all_sorted_list
));
246 memset (rid_lo_sorted_list
, 0, sizeof (_rid_lo_sorted_list
));
247 memset (&rid_user_assigned
, 0, sizeof (rid_user_assigned
));
249 rid_all_sorted_list
->cmp
= router_id_cmp
;
250 rid_lo_sorted_list
->cmp
= router_id_cmp
;
252 rid_user_assigned
.family
= AF_INET
;
253 rid_user_assigned
.prefixlen
= 32;