]>
git.proxmox.com Git - mirror_frr.git/blob - zebra/router-id.c
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/zserv.h"
42 #include "zebra/zebra_vrf.h"
43 #include "zebra/router-id.h"
44 #include "zebra/redistribute.h"
46 /* master zebra server structure */
47 extern struct zebra_t zebrad
;
49 static struct connected
*
50 router_id_find_node (struct list
*l
, struct connected
*ifc
)
52 struct listnode
*node
;
55 for (ALL_LIST_ELEMENTS_RO (l
, node
, c
))
56 if (prefix_same (ifc
->address
, c
->address
))
63 router_id_bad_address (struct connected
*ifc
)
65 if (ifc
->address
->family
!= AF_INET
)
68 /* non-redistributable addresses shouldn't be used for RIDs either */
69 if (!zebra_check_addr (ifc
->address
))
76 router_id_get (struct prefix
*p
, vrf_id_t vrf_id
)
78 struct listnode
*node
;
80 struct zebra_vrf
*zvrf
= vrf_info_get (vrf_id
);
82 p
->u
.prefix4
.s_addr
= 0;
86 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
)
87 p
->u
.prefix4
.s_addr
= zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
;
88 else if (!list_isempty (zvrf
->rid_lo_sorted_list
))
90 node
= listtail (zvrf
->rid_lo_sorted_list
);
91 c
= listgetdata (node
);
92 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
94 else if (!list_isempty (zvrf
->rid_all_sorted_list
))
96 node
= listtail (zvrf
->rid_all_sorted_list
);
97 c
= listgetdata (node
);
98 p
->u
.prefix4
.s_addr
= c
->address
->u
.prefix4
.s_addr
;
103 router_id_set (struct prefix
*p
, vrf_id_t vrf_id
)
106 struct listnode
*node
;
107 struct zserv
*client
;
108 struct zebra_vrf
*zvrf
;
110 if (p
->u
.prefix4
.s_addr
== 0) /* unset */
112 zvrf
= vrf_info_lookup (vrf_id
);
117 zvrf
= vrf_info_get (vrf_id
);
119 zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
= p
->u
.prefix4
.s_addr
;
121 router_id_get (&p2
, vrf_id
);
123 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
124 zsend_router_id_update (client
, &p2
, vrf_id
);
128 router_id_add_address (struct connected
*ifc
)
130 struct list
*l
= NULL
;
131 struct listnode
*node
;
132 struct prefix before
;
134 struct zserv
*client
;
135 struct zebra_vrf
*zvrf
= vrf_info_get (ifc
->ifp
->vrf_id
);
137 if (router_id_bad_address (ifc
))
140 router_id_get (&before
, zvrf_id (zvrf
));
142 if (!strncmp (ifc
->ifp
->name
, "lo", 2)
143 || !strncmp (ifc
->ifp
->name
, "dummy", 5))
144 l
= zvrf
->rid_lo_sorted_list
;
146 l
= zvrf
->rid_all_sorted_list
;
148 if (!router_id_find_node (l
, ifc
))
149 listnode_add_sort (l
, ifc
);
151 router_id_get (&after
, zvrf_id (zvrf
));
153 if (prefix_same (&before
, &after
))
156 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
157 zsend_router_id_update (client
, &after
, zvrf_id (zvrf
));
161 router_id_del_address (struct connected
*ifc
)
166 struct prefix before
;
167 struct listnode
*node
;
168 struct zserv
*client
;
169 struct zebra_vrf
*zvrf
= vrf_info_get (ifc
->ifp
->vrf_id
);
171 if (router_id_bad_address (ifc
))
174 router_id_get (&before
, zvrf_id (zvrf
));
176 if (!strncmp (ifc
->ifp
->name
, "lo", 2)
177 || !strncmp (ifc
->ifp
->name
, "dummy", 5))
178 l
= zvrf
->rid_lo_sorted_list
;
180 l
= zvrf
->rid_all_sorted_list
;
182 if ((c
= router_id_find_node (l
, ifc
)))
183 listnode_delete (l
, c
);
185 router_id_get (&after
, zvrf_id (zvrf
));
187 if (prefix_same (&before
, &after
))
190 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
191 zsend_router_id_update (client
, &after
, zvrf_id (zvrf
));
195 router_id_write (struct vty
*vty
)
198 struct zebra_vrf
*zvrf
;
200 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
201 if ((zvrf
= vrf
->info
) != NULL
)
202 if (zvrf
->rid_user_assigned
.u
.prefix4
.s_addr
)
204 if (zvrf_id (zvrf
) == VRF_DEFAULT
)
205 vty_outln (vty
, "router-id %s",
206 inet_ntoa(zvrf
->rid_user_assigned
.u
.prefix4
));
208 vty_outln (vty
, "router-id %s vrf %s",
209 inet_ntoa (zvrf
->rid_user_assigned
.u
.prefix4
),
216 "router-id A.B.C.D [vrf NAME]",
217 "Manually set the router-id\n"
218 "IP address to use for router-id\n"
225 vrf_id_t vrf_id
= VRF_DEFAULT
;
227 rid
.u
.prefix4
.s_addr
= inet_addr (argv
[idx_ipv4
]->arg
);
228 if (!rid
.u
.prefix4
.s_addr
)
232 rid
.family
= AF_INET
;
235 VRF_GET_ID (vrf_id
, argv
[idx_name
]->arg
);
237 router_id_set (&rid
, vrf_id
);
244 "no router-id [A.B.C.D [vrf NAME]]",
246 "Remove the manually configured router-id\n"
247 "IP address to use for router-id\n"
253 vrf_id_t vrf_id
= VRF_DEFAULT
;
255 rid
.u
.prefix4
.s_addr
= 0;
257 rid
.family
= AF_INET
;
260 VRF_GET_ID (vrf_id
, argv
[idx_name
]->arg
);
262 router_id_set (&rid
, vrf_id
);
270 router_id_cmp (void *a
, void *b
)
272 const struct connected
*ifa
= (const struct connected
*)a
;
273 const struct connected
*ifb
= (const struct connected
*)b
;
275 return IPV4_ADDR_CMP(&ifa
->address
->u
.prefix4
.s_addr
,&ifb
->address
->u
.prefix4
.s_addr
);
279 router_id_cmd_init (void)
281 install_element (CONFIG_NODE
, &router_id_cmd
);
282 install_element (CONFIG_NODE
, &no_router_id_cmd
);
286 router_id_init (struct zebra_vrf
*zvrf
)
288 zvrf
->rid_all_sorted_list
= &zvrf
->_rid_all_sorted_list
;
289 zvrf
->rid_lo_sorted_list
= &zvrf
->_rid_lo_sorted_list
;
291 memset (zvrf
->rid_all_sorted_list
, 0, sizeof (zvrf
->_rid_all_sorted_list
));
292 memset (zvrf
->rid_lo_sorted_list
, 0, sizeof (zvrf
->_rid_lo_sorted_list
));
293 memset (&zvrf
->rid_user_assigned
, 0, sizeof (zvrf
->rid_user_assigned
));
295 zvrf
->rid_all_sorted_list
->cmp
= router_id_cmp
;
296 zvrf
->rid_lo_sorted_list
->cmp
= router_id_cmp
;
298 zvrf
->rid_user_assigned
.family
= AF_INET
;
299 zvrf
->rid_user_assigned
.prefixlen
= 32;