]> git.proxmox.com Git - mirror_frr.git/blame - zebra/router-id.c
zebra: Allow router-id to be part of the vrf sub node
[mirror_frr.git] / zebra / router-id.c
CommitLineData
18a6dce6 1/*
2 * Router ID for zebra daemon.
3 *
d62a17ae 4 * Copyright (C) 2004 James R. Leu
18a6dce6 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
161e9ab7 41#include "zebra/zebra_router.h"
bf094f69 42#include "zebra/zapi_msg.h"
7c551956 43#include "zebra/zebra_vrf.h"
a1ac18c4 44#include "zebra/router-id.h"
6dc686a2 45#include "zebra/redistribute.h"
18a6dce6 46
d62a17ae 47static struct connected *router_id_find_node(struct list *l,
48 struct connected *ifc)
18a6dce6 49{
d62a17ae 50 struct listnode *node;
51 struct connected *c;
18a6dce6 52
d62a17ae 53 for (ALL_LIST_ELEMENTS_RO(l, node, c))
54 if (prefix_same(ifc->address, c->address))
55 return c;
1eb8ef25 56
d62a17ae 57 return NULL;
18a6dce6 58}
59
d62a17ae 60static int router_id_bad_address(struct connected *ifc)
18a6dce6 61{
d62a17ae 62 if (ifc->address->family != AF_INET)
63 return 1;
64
65 /* non-redistributable addresses shouldn't be used for RIDs either */
66 if (!zebra_check_addr(ifc->address))
67 return 1;
68
69 return 0;
18a6dce6 70}
71
03fba42e 72void router_id_get(struct prefix *p, struct zebra_vrf *zvrf)
18a6dce6 73{
d62a17ae 74 struct listnode *node;
75 struct connected *c;
d62a17ae 76
975a328e 77 p->u.prefix4.s_addr = INADDR_ANY;
d62a17ae 78 p->family = AF_INET;
79 p->prefixlen = 32;
80
975a328e 81 if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY)
d62a17ae 82 p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
83 else if (!list_isempty(zvrf->rid_lo_sorted_list)) {
84 node = listtail(zvrf->rid_lo_sorted_list);
85 c = listgetdata(node);
86 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
87 } else if (!list_isempty(zvrf->rid_all_sorted_list)) {
88 node = listtail(zvrf->rid_all_sorted_list);
89 c = listgetdata(node);
90 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
91 }
18a6dce6 92}
93
03fba42e 94static void router_id_set(struct prefix *p, struct zebra_vrf *zvrf)
18a6dce6 95{
d62a17ae 96 struct prefix p2;
97 struct listnode *node;
98 struct zserv *client;
d62a17ae 99
100 zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
101
03fba42e 102 router_id_get(&p2, zvrf);
d62a17ae 103
161e9ab7 104 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
03fba42e 105 zsend_router_id_update(client, &p2, zvrf->vrf->vrf_id);
18a6dce6 106}
107
d62a17ae 108void router_id_add_address(struct connected *ifc)
18a6dce6 109{
d62a17ae 110 struct list *l = NULL;
111 struct listnode *node;
112 struct prefix before;
113 struct prefix after;
114 struct zserv *client;
a36898e7 115 struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
d62a17ae 116
117 if (router_id_bad_address(ifc))
118 return;
119
03fba42e 120 router_id_get(&before, zvrf);
d62a17ae 121
106935f6 122 if (if_is_loopback(ifc->ifp))
d62a17ae 123 l = zvrf->rid_lo_sorted_list;
124 else
125 l = zvrf->rid_all_sorted_list;
126
127 if (!router_id_find_node(l, ifc))
128 listnode_add_sort(l, ifc);
129
03fba42e 130 router_id_get(&after, zvrf);
d62a17ae 131
132 if (prefix_same(&before, &after))
133 return;
134
161e9ab7 135 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
d62a17ae 136 zsend_router_id_update(client, &after, zvrf_id(zvrf));
18a6dce6 137}
138
d62a17ae 139void router_id_del_address(struct connected *ifc)
18a6dce6 140{
d62a17ae 141 struct connected *c;
142 struct list *l;
143 struct prefix after;
144 struct prefix before;
145 struct listnode *node;
146 struct zserv *client;
a36898e7 147 struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
18a6dce6 148
d62a17ae 149 if (router_id_bad_address(ifc))
150 return;
18a6dce6 151
03fba42e 152 router_id_get(&before, zvrf);
18a6dce6 153
106935f6 154 if (if_is_loopback(ifc->ifp))
d62a17ae 155 l = zvrf->rid_lo_sorted_list;
156 else
157 l = zvrf->rid_all_sorted_list;
18a6dce6 158
d62a17ae 159 if ((c = router_id_find_node(l, ifc)))
160 listnode_delete(l, c);
18a6dce6 161
03fba42e 162 router_id_get(&after, zvrf);
18a6dce6 163
d62a17ae 164 if (prefix_same(&before, &after))
165 return;
18a6dce6 166
161e9ab7 167 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
d62a17ae 168 zsend_router_id_update(client, &after, zvrf_id(zvrf));
18a6dce6 169}
170
03fba42e 171void router_id_write(struct vty *vty, struct zebra_vrf *zvrf)
18a6dce6 172{
03fba42e
DS
173 char space[2];
174
175 memset(space, 0, sizeof(space));
176
177 if (zvrf_id(zvrf) != VRF_DEFAULT)
178 snprintf(space, sizeof(space), "%s", " ");
d62a17ae 179
03fba42e
DS
180 if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) {
181 vty_out(vty, "%srouter-id %s\n", space,
182 inet_ntoa(zvrf->rid_user_assigned.u.prefix4));
183 }
18a6dce6 184}
185
186DEFUN (router_id,
187 router_id_cmd,
03fba42e 188 "router-id A.B.C.D vrf NAME",
18a6dce6 189 "Manually set the router-id\n"
03fba42e 190 "IP address to use for router-id\n" VRF_CMD_HELP_STR)
18a6dce6 191{
d62a17ae 192 int idx_ipv4 = 1;
193 int idx_name = 3;
03fba42e 194 struct zebra_vrf *zvrf;
92300491 195
d62a17ae 196 struct prefix rid;
197 vrf_id_t vrf_id = VRF_DEFAULT;
18a6dce6 198
d62a17ae 199 rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg);
200 if (!rid.u.prefix4.s_addr)
201 return CMD_WARNING_CONFIG_FAILED;
18a6dce6 202
d62a17ae 203 rid.prefixlen = 32;
204 rid.family = AF_INET;
18a6dce6 205
d62a17ae 206 if (argc > 2)
ec1db588 207 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
c6ffe645 208
03fba42e
DS
209 zvrf = vrf_info_lookup(vrf_id);
210 router_id_set(&rid, zvrf);
211
212 return CMD_SUCCESS;
213}
214
215DEFUN (router_id_in_vrf,
216 router_id_in_vrf_cmd,
217 "router-id A.B.C.D",
218 "Manuall set the router-id\n"
219 "IP address to use for router-id\n")
220{
221 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
222 int idx_ipv4 = 1;
223 struct prefix rid;
224
225 rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg);
226 if (!rid.u.prefix4.s_addr)
227 return CMD_WARNING_CONFIG_FAILED;
228
229 rid.prefixlen = 32;
230 rid.family = AF_INET;
231
232 router_id_set(&rid, zvrf);
18a6dce6 233
d62a17ae 234 return CMD_SUCCESS;
18a6dce6 235}
236
237DEFUN (no_router_id,
238 no_router_id_cmd,
03fba42e 239 "no router-id [A.B.C.D vrf NAME]",
18a6dce6 240 NO_STR
92300491 241 "Remove the manually configured router-id\n"
03fba42e 242 "IP address to use for router-id\n" VRF_CMD_HELP_STR)
18a6dce6 243{
d62a17ae 244 int idx_name = 4;
d62a17ae 245 struct prefix rid;
246 vrf_id_t vrf_id = VRF_DEFAULT;
03fba42e 247 struct zebra_vrf *zvrf;
18a6dce6 248
d62a17ae 249 rid.u.prefix4.s_addr = 0;
250 rid.prefixlen = 0;
251 rid.family = AF_INET;
18a6dce6 252
d62a17ae 253 if (argc > 3)
ec1db588 254 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
c6ffe645 255
03fba42e
DS
256 zvrf = vrf_info_get(vrf_id);
257 router_id_set(&rid, zvrf);
258
259 return CMD_SUCCESS;
260}
261
262DEFUN (no_router_id_in_vrf,
263 no_router_id_in_vrf_cmd,
264 "no router-id [A.B.C.D]",
265 NO_STR
266 "Remove the manually configured router-id\n"
267 "IP address to use for router-id\n")
268{
269 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
270
271 struct prefix rid;
272
273 rid.u.prefix4.s_addr = 0;
274 rid.prefixlen = 0;
275 rid.family = AF_INET;
276
277 router_id_set(&rid, zvrf);
18a6dce6 278
d62a17ae 279 return CMD_SUCCESS;
18a6dce6 280}
281
13b01f2f
JAG
282DEFUN (show_router_id,
283 show_router_id_cmd,
284 "show router-id [vrf NAME]",
285 SHOW_STR
286 "Show the configured router-id\n"
287 VRF_CMD_HELP_STR)
288{
289 int idx_name = 3;
290
291 vrf_id_t vrf_id = VRF_DEFAULT;
292 struct zebra_vrf *zvrf;
293
294 if (argc > 2)
295 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
296
297 zvrf = vrf_info_get(vrf_id);
298
299 if ((zvrf != NULL) && (zvrf->rid_user_assigned.u.prefix4.s_addr)) {
300 vty_out(vty, "zebra:\n");
301 if (vrf_id == VRF_DEFAULT)
302 vty_out(vty, " router-id %s vrf default\n",
303 inet_ntoa(zvrf->rid_user_assigned.u.prefix4));
304 else
305 vty_out(vty, " router-id %s vrf %s\n",
306 inet_ntoa(zvrf->rid_user_assigned.u.prefix4),
307 argv[idx_name]->arg);
308 }
309
310 return CMD_SUCCESS;
311}
813d4307 312
d62a17ae 313static int router_id_cmp(void *a, void *b)
18a6dce6 314{
d62a17ae 315 const struct connected *ifa = (const struct connected *)a;
316 const struct connected *ifb = (const struct connected *)b;
18a6dce6 317
d62a17ae 318 return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,
319 &ifb->address->u.prefix4.s_addr);
18a6dce6 320}
321
d62a17ae 322void router_id_cmd_init(void)
18a6dce6 323{
d62a17ae 324 install_element(CONFIG_NODE, &router_id_cmd);
325 install_element(CONFIG_NODE, &no_router_id_cmd);
03fba42e
DS
326 install_element(CONFIG_NODE, &router_id_in_vrf_cmd);
327 install_element(VRF_NODE, &router_id_in_vrf_cmd);
328 install_element(CONFIG_NODE, &no_router_id_in_vrf_cmd);
329 install_element(VRF_NODE, &no_router_id_in_vrf_cmd);
13b01f2f 330 install_element(VIEW_NODE, &show_router_id_cmd);
c6ffe645
FL
331}
332
d62a17ae 333void router_id_init(struct zebra_vrf *zvrf)
c6ffe645 334{
d62a17ae 335 zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
336 zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
18a6dce6 337
d62a17ae 338 memset(zvrf->rid_all_sorted_list, 0,
339 sizeof(zvrf->_rid_all_sorted_list));
340 memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_sorted_list));
341 memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned));
18a6dce6 342
d62a17ae 343 zvrf->rid_all_sorted_list->cmp = router_id_cmp;
344 zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
18a6dce6 345
d62a17ae 346 zvrf->rid_user_assigned.family = AF_INET;
347 zvrf->rid_user_assigned.prefixlen = 32;
18a6dce6 348}