]> git.proxmox.com Git - mirror_frr.git/blame - zebra/router-id.c
Merge pull request #532 from opensourcerouting/gpl-headers
[mirror_frr.git] / zebra / router-id.c
CommitLineData
18a6dce6 1/*
2 * Router ID for zebra daemon.
3 *
4 * Copyright (C) 2004 James R. Leu
5 *
6 * This file is part of Quagga routing suite.
7 *
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
11 * later version.
12 *
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.
17 *
896014f4
DL
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
18a6dce6 21 */
22
23#include <zebra.h>
24
25#include "if.h"
26#include "vty.h"
27#include "sockunion.h"
28#include "prefix.h"
29#include "stream.h"
30#include "command.h"
31#include "memory.h"
4a1ab8e4 32#include "zebra_memory.h"
18a6dce6 33#include "ioctl.h"
34#include "connected.h"
35#include "network.h"
36#include "log.h"
37#include "table.h"
38#include "rib.h"
c6ffe645 39#include "vrf.h"
18a6dce6 40
41#include "zebra/zserv.h"
7c551956 42#include "zebra/zebra_vrf.h"
a1ac18c4 43#include "zebra/router-id.h"
6dc686a2 44#include "zebra/redistribute.h"
18a6dce6 45
1f9a9fff
PJ
46/* master zebra server structure */
47extern struct zebra_t zebrad;
48
18a6dce6 49static struct connected *
50router_id_find_node (struct list *l, struct connected *ifc)
51{
52 struct listnode *node;
53 struct connected *c;
54
1eb8ef25 55 for (ALL_LIST_ELEMENTS_RO (l, node, c))
56 if (prefix_same (ifc->address, c->address))
57 return c;
58
18a6dce6 59 return NULL;
60}
61
62static int
63router_id_bad_address (struct connected *ifc)
64{
18a6dce6 65 if (ifc->address->family != AF_INET)
66 return 1;
6dc686a2
PJ
67
68 /* non-redistributable addresses shouldn't be used for RIDs either */
69 if (!zebra_check_addr (ifc->address))
18a6dce6 70 return 1;
6dc686a2 71
18a6dce6 72 return 0;
73}
74
75void
c6ffe645 76router_id_get (struct prefix *p, vrf_id_t vrf_id)
18a6dce6 77{
78 struct listnode *node;
79 struct connected *c;
c6ffe645 80 struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
18a6dce6 81
82 p->u.prefix4.s_addr = 0;
83 p->family = AF_INET;
84 p->prefixlen = 32;
85
c6ffe645
FL
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))
18a6dce6 89 {
c6ffe645 90 node = listtail (zvrf->rid_lo_sorted_list);
1eb8ef25 91 c = listgetdata (node);
18a6dce6 92 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
93 }
c6ffe645 94 else if (!list_isempty (zvrf->rid_all_sorted_list))
18a6dce6 95 {
c6ffe645 96 node = listtail (zvrf->rid_all_sorted_list);
1eb8ef25 97 c = listgetdata (node);
18a6dce6 98 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
99 }
100}
101
102static void
c6ffe645 103router_id_set (struct prefix *p, vrf_id_t vrf_id)
18a6dce6 104{
105 struct prefix p2;
106 struct listnode *node;
107 struct zserv *client;
c6ffe645 108 struct zebra_vrf *zvrf;
18a6dce6 109
c6ffe645
FL
110 if (p->u.prefix4.s_addr == 0) /* unset */
111 {
112 zvrf = vrf_info_lookup (vrf_id);
113 if (! zvrf)
114 return;
115 }
116 else /* set */
117 zvrf = vrf_info_get (vrf_id);
18a6dce6 118
c6ffe645
FL
119 zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
120
121 router_id_get (&p2, vrf_id);
1eb8ef25 122
123 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
c6ffe645 124 zsend_router_id_update (client, &p2, vrf_id);
18a6dce6 125}
126
127void
128router_id_add_address (struct connected *ifc)
129{
130 struct list *l = NULL;
131 struct listnode *node;
132 struct prefix before;
133 struct prefix after;
134 struct zserv *client;
c6ffe645 135 struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
18a6dce6 136
137 if (router_id_bad_address (ifc))
138 return;
139
661512bf 140 router_id_get (&before, zvrf_id (zvrf));
18a6dce6 141
142 if (!strncmp (ifc->ifp->name, "lo", 2)
143 || !strncmp (ifc->ifp->name, "dummy", 5))
c6ffe645 144 l = zvrf->rid_lo_sorted_list;
18a6dce6 145 else
c6ffe645 146 l = zvrf->rid_all_sorted_list;
18a6dce6 147
148 if (!router_id_find_node (l, ifc))
b6516829 149 listnode_add_sort (l, ifc);
18a6dce6 150
661512bf 151 router_id_get (&after, zvrf_id (zvrf));
18a6dce6 152
153 if (prefix_same (&before, &after))
154 return;
155
1eb8ef25 156 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
661512bf 157 zsend_router_id_update (client, &after, zvrf_id (zvrf));
18a6dce6 158}
159
160void
161router_id_del_address (struct connected *ifc)
162{
163 struct connected *c;
164 struct list *l;
165 struct prefix after;
166 struct prefix before;
167 struct listnode *node;
168 struct zserv *client;
c6ffe645 169 struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
18a6dce6 170
171 if (router_id_bad_address (ifc))
172 return;
173
661512bf 174 router_id_get (&before, zvrf_id (zvrf));
18a6dce6 175
176 if (!strncmp (ifc->ifp->name, "lo", 2)
177 || !strncmp (ifc->ifp->name, "dummy", 5))
c6ffe645 178 l = zvrf->rid_lo_sorted_list;
18a6dce6 179 else
c6ffe645 180 l = zvrf->rid_all_sorted_list;
18a6dce6 181
182 if ((c = router_id_find_node (l, ifc)))
183 listnode_delete (l, c);
184
661512bf 185 router_id_get (&after, zvrf_id (zvrf));
18a6dce6 186
187 if (prefix_same (&before, &after))
188 return;
189
1eb8ef25 190 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
661512bf 191 zsend_router_id_update (client, &after, zvrf_id (zvrf));
18a6dce6 192}
193
194void
195router_id_write (struct vty *vty)
196{
1a1a7065 197 struct vrf *vrf;
c6ffe645 198 struct zebra_vrf *zvrf;
c6ffe645 199
a62c4901 200 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1a1a7065 201 if ((zvrf = vrf->info) != NULL)
c6ffe645
FL
202 if (zvrf->rid_user_assigned.u.prefix4.s_addr)
203 {
661512bf 204 if (zvrf_id (zvrf) == VRF_DEFAULT)
c6ffe645
FL
205 vty_out (vty, "router-id %s%s",
206 inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
207 VTY_NEWLINE);
208 else
1d75f883 209 vty_out (vty, "router-id %s vrf %s%s",
c6ffe645 210 inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
661512bf 211 zvrf_name (zvrf),
c6ffe645
FL
212 VTY_NEWLINE);
213 }
18a6dce6 214}
215
216DEFUN (router_id,
217 router_id_cmd,
92300491 218 "router-id A.B.C.D [vrf NAME]",
18a6dce6 219 "Manually set the router-id\n"
92300491
DW
220 "IP address to use for router-id\n"
221 VRF_CMD_HELP_STR)
18a6dce6 222{
7c022376 223 int idx_ipv4 = 1;
92300491
DW
224 int idx_name = 3;
225
18a6dce6 226 struct prefix rid;
c6ffe645 227 vrf_id_t vrf_id = VRF_DEFAULT;
18a6dce6 228
7c022376 229 rid.u.prefix4.s_addr = inet_addr (argv[idx_ipv4]->arg);
18a6dce6 230 if (!rid.u.prefix4.s_addr)
231 return CMD_WARNING;
232
233 rid.prefixlen = 32;
234 rid.family = AF_INET;
235
92300491
DW
236 if (argc > 2)
237 VRF_GET_ID (vrf_id, argv[idx_name]->arg);
c6ffe645
FL
238
239 router_id_set (&rid, vrf_id);
18a6dce6 240
241 return CMD_SUCCESS;
242}
243
244DEFUN (no_router_id,
245 no_router_id_cmd,
92300491 246 "no router-id [A.B.C.D [vrf NAME]]",
18a6dce6 247 NO_STR
92300491
DW
248 "Remove the manually configured router-id\n"
249 "IP address to use for router-id\n"
250 VRF_CMD_HELP_STR)
18a6dce6 251{
92300491
DW
252 int idx_name = 4;
253
18a6dce6 254 struct prefix rid;
c6ffe645 255 vrf_id_t vrf_id = VRF_DEFAULT;
18a6dce6 256
257 rid.u.prefix4.s_addr = 0;
258 rid.prefixlen = 0;
259 rid.family = AF_INET;
260
92300491
DW
261 if (argc > 3)
262 VRF_GET_ID (vrf_id, argv[idx_name]->arg);
c6ffe645
FL
263
264 router_id_set (&rid, vrf_id);
18a6dce6 265
266 return CMD_SUCCESS;
267}
268
813d4307 269
c6ffe645 270
a1ac18c4 271static int
18a6dce6 272router_id_cmp (void *a, void *b)
273{
b6516829
SH
274 const struct connected *ifa = (const struct connected *)a;
275 const struct connected *ifb = (const struct connected *)b;
18a6dce6 276
24c84dbe 277 return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,&ifb->address->u.prefix4.s_addr);
18a6dce6 278}
279
280void
c6ffe645 281router_id_cmd_init (void)
18a6dce6 282{
283 install_element (CONFIG_NODE, &router_id_cmd);
284 install_element (CONFIG_NODE, &no_router_id_cmd);
c6ffe645
FL
285}
286
287void
288router_id_init (struct zebra_vrf *zvrf)
289{
290 zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
291 zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
18a6dce6 292
c6ffe645
FL
293 memset (zvrf->rid_all_sorted_list, 0, sizeof (zvrf->_rid_all_sorted_list));
294 memset (zvrf->rid_lo_sorted_list, 0, sizeof (zvrf->_rid_lo_sorted_list));
295 memset (&zvrf->rid_user_assigned, 0, sizeof (zvrf->rid_user_assigned));
18a6dce6 296
c6ffe645
FL
297 zvrf->rid_all_sorted_list->cmp = router_id_cmp;
298 zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
18a6dce6 299
c6ffe645
FL
300 zvrf->rid_user_assigned.family = AF_INET;
301 zvrf->rid_user_assigned.prefixlen = 32;
18a6dce6 302}