]> git.proxmox.com Git - mirror_frr.git/blame - zebra/router-id.c
Merge pull request #5793 from ton31337/fix/formatting_show_bgp_summary_failed
[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
d62a17ae 72void router_id_get(struct prefix *p, vrf_id_t vrf_id)
18a6dce6 73{
d62a17ae 74 struct listnode *node;
75 struct connected *c;
76 struct zebra_vrf *zvrf = vrf_info_get(vrf_id);
77
975a328e 78 p->u.prefix4.s_addr = INADDR_ANY;
d62a17ae 79 p->family = AF_INET;
80 p->prefixlen = 32;
81
975a328e 82 if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY)
d62a17ae 83 p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
84 else if (!list_isempty(zvrf->rid_lo_sorted_list)) {
85 node = listtail(zvrf->rid_lo_sorted_list);
86 c = listgetdata(node);
87 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
88 } else if (!list_isempty(zvrf->rid_all_sorted_list)) {
89 node = listtail(zvrf->rid_all_sorted_list);
90 c = listgetdata(node);
91 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
92 }
18a6dce6 93}
94
d62a17ae 95static void router_id_set(struct prefix *p, vrf_id_t vrf_id)
18a6dce6 96{
d62a17ae 97 struct prefix p2;
98 struct listnode *node;
99 struct zserv *client;
100 struct zebra_vrf *zvrf;
101
102 if (p->u.prefix4.s_addr == 0) /* unset */
103 {
104 zvrf = vrf_info_lookup(vrf_id);
105 if (!zvrf)
106 return;
107 } else /* set */
108 zvrf = vrf_info_get(vrf_id);
109
110 zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
111
112 router_id_get(&p2, vrf_id);
113
161e9ab7 114 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
d62a17ae 115 zsend_router_id_update(client, &p2, vrf_id);
18a6dce6 116}
117
d62a17ae 118void router_id_add_address(struct connected *ifc)
18a6dce6 119{
d62a17ae 120 struct list *l = NULL;
121 struct listnode *node;
122 struct prefix before;
123 struct prefix after;
124 struct zserv *client;
a36898e7 125 struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
d62a17ae 126
127 if (router_id_bad_address(ifc))
128 return;
129
130 router_id_get(&before, zvrf_id(zvrf));
131
106935f6 132 if (if_is_loopback(ifc->ifp))
d62a17ae 133 l = zvrf->rid_lo_sorted_list;
134 else
135 l = zvrf->rid_all_sorted_list;
136
137 if (!router_id_find_node(l, ifc))
138 listnode_add_sort(l, ifc);
139
140 router_id_get(&after, zvrf_id(zvrf));
141
142 if (prefix_same(&before, &after))
143 return;
144
161e9ab7 145 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
d62a17ae 146 zsend_router_id_update(client, &after, zvrf_id(zvrf));
18a6dce6 147}
148
d62a17ae 149void router_id_del_address(struct connected *ifc)
18a6dce6 150{
d62a17ae 151 struct connected *c;
152 struct list *l;
153 struct prefix after;
154 struct prefix before;
155 struct listnode *node;
156 struct zserv *client;
a36898e7 157 struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
18a6dce6 158
d62a17ae 159 if (router_id_bad_address(ifc))
160 return;
18a6dce6 161
d62a17ae 162 router_id_get(&before, zvrf_id(zvrf));
18a6dce6 163
106935f6 164 if (if_is_loopback(ifc->ifp))
d62a17ae 165 l = zvrf->rid_lo_sorted_list;
166 else
167 l = zvrf->rid_all_sorted_list;
18a6dce6 168
d62a17ae 169 if ((c = router_id_find_node(l, ifc)))
170 listnode_delete(l, c);
18a6dce6 171
d62a17ae 172 router_id_get(&after, zvrf_id(zvrf));
18a6dce6 173
d62a17ae 174 if (prefix_same(&before, &after))
175 return;
18a6dce6 176
161e9ab7 177 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client))
d62a17ae 178 zsend_router_id_update(client, &after, zvrf_id(zvrf));
18a6dce6 179}
180
d62a17ae 181void router_id_write(struct vty *vty)
18a6dce6 182{
d62a17ae 183 struct vrf *vrf;
184 struct zebra_vrf *zvrf;
185
a2addae8
RW
186 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
187 if ((zvrf = vrf->info) != NULL)
975a328e
DA
188 if (zvrf->rid_user_assigned.u.prefix4.s_addr
189 != INADDR_ANY) {
a2addae8
RW
190 if (zvrf_id(zvrf) == VRF_DEFAULT)
191 vty_out(vty, "router-id %s\n",
192 inet_ntoa(
193 zvrf->rid_user_assigned
194 .u.prefix4));
195 else
196 vty_out(vty, "router-id %s vrf %s\n",
197 inet_ntoa(
198 zvrf->rid_user_assigned
199 .u.prefix4),
200 zvrf_name(zvrf));
201 }
18a6dce6 202}
203
204DEFUN (router_id,
205 router_id_cmd,
92300491 206 "router-id A.B.C.D [vrf NAME]",
18a6dce6 207 "Manually set the router-id\n"
92300491
DW
208 "IP address to use for router-id\n"
209 VRF_CMD_HELP_STR)
18a6dce6 210{
d62a17ae 211 int idx_ipv4 = 1;
212 int idx_name = 3;
92300491 213
d62a17ae 214 struct prefix rid;
215 vrf_id_t vrf_id = VRF_DEFAULT;
18a6dce6 216
d62a17ae 217 rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg);
218 if (!rid.u.prefix4.s_addr)
219 return CMD_WARNING_CONFIG_FAILED;
18a6dce6 220
d62a17ae 221 rid.prefixlen = 32;
222 rid.family = AF_INET;
18a6dce6 223
d62a17ae 224 if (argc > 2)
ec1db588 225 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
c6ffe645 226
d62a17ae 227 router_id_set(&rid, vrf_id);
18a6dce6 228
d62a17ae 229 return CMD_SUCCESS;
18a6dce6 230}
231
232DEFUN (no_router_id,
233 no_router_id_cmd,
92300491 234 "no router-id [A.B.C.D [vrf NAME]]",
18a6dce6 235 NO_STR
92300491
DW
236 "Remove the manually configured router-id\n"
237 "IP address to use for router-id\n"
238 VRF_CMD_HELP_STR)
18a6dce6 239{
d62a17ae 240 int idx_name = 4;
92300491 241
d62a17ae 242 struct prefix rid;
243 vrf_id_t vrf_id = VRF_DEFAULT;
18a6dce6 244
d62a17ae 245 rid.u.prefix4.s_addr = 0;
246 rid.prefixlen = 0;
247 rid.family = AF_INET;
18a6dce6 248
d62a17ae 249 if (argc > 3)
ec1db588 250 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
c6ffe645 251
d62a17ae 252 router_id_set(&rid, vrf_id);
18a6dce6 253
d62a17ae 254 return CMD_SUCCESS;
18a6dce6 255}
256
13b01f2f
JAG
257DEFUN (show_router_id,
258 show_router_id_cmd,
259 "show router-id [vrf NAME]",
260 SHOW_STR
261 "Show the configured router-id\n"
262 VRF_CMD_HELP_STR)
263{
264 int idx_name = 3;
265
266 vrf_id_t vrf_id = VRF_DEFAULT;
267 struct zebra_vrf *zvrf;
268
269 if (argc > 2)
270 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
271
272 zvrf = vrf_info_get(vrf_id);
273
274 if ((zvrf != NULL) && (zvrf->rid_user_assigned.u.prefix4.s_addr)) {
275 vty_out(vty, "zebra:\n");
276 if (vrf_id == VRF_DEFAULT)
277 vty_out(vty, " router-id %s vrf default\n",
278 inet_ntoa(zvrf->rid_user_assigned.u.prefix4));
279 else
280 vty_out(vty, " router-id %s vrf %s\n",
281 inet_ntoa(zvrf->rid_user_assigned.u.prefix4),
282 argv[idx_name]->arg);
283 }
284
285 return CMD_SUCCESS;
286}
813d4307 287
d62a17ae 288static int router_id_cmp(void *a, void *b)
18a6dce6 289{
d62a17ae 290 const struct connected *ifa = (const struct connected *)a;
291 const struct connected *ifb = (const struct connected *)b;
18a6dce6 292
d62a17ae 293 return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,
294 &ifb->address->u.prefix4.s_addr);
18a6dce6 295}
296
d62a17ae 297void router_id_cmd_init(void)
18a6dce6 298{
d62a17ae 299 install_element(CONFIG_NODE, &router_id_cmd);
300 install_element(CONFIG_NODE, &no_router_id_cmd);
13b01f2f 301 install_element(VIEW_NODE, &show_router_id_cmd);
c6ffe645
FL
302}
303
d62a17ae 304void router_id_init(struct zebra_vrf *zvrf)
c6ffe645 305{
d62a17ae 306 zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
307 zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
18a6dce6 308
d62a17ae 309 memset(zvrf->rid_all_sorted_list, 0,
310 sizeof(zvrf->_rid_all_sorted_list));
311 memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_sorted_list));
312 memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned));
18a6dce6 313
d62a17ae 314 zvrf->rid_all_sorted_list->cmp = router_id_cmp;
315 zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
18a6dce6 316
d62a17ae 317 zvrf->rid_user_assigned.family = AF_INET;
318 zvrf->rid_user_assigned.prefixlen = 32;
18a6dce6 319}