]> git.proxmox.com Git - mirror_frr.git/blame - zebra/router-id.c
zebra: add packet length into pbr support
[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
41#include "zebra/zserv.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
1f9a9fff
PJ
47/* master zebra server structure */
48extern struct zebra_t zebrad;
49
d62a17ae 50static struct connected *router_id_find_node(struct list *l,
51 struct connected *ifc)
18a6dce6 52{
d62a17ae 53 struct listnode *node;
54 struct connected *c;
18a6dce6 55
d62a17ae 56 for (ALL_LIST_ELEMENTS_RO(l, node, c))
57 if (prefix_same(ifc->address, c->address))
58 return c;
1eb8ef25 59
d62a17ae 60 return NULL;
18a6dce6 61}
62
d62a17ae 63static int router_id_bad_address(struct connected *ifc)
18a6dce6 64{
d62a17ae 65 if (ifc->address->family != AF_INET)
66 return 1;
67
68 /* non-redistributable addresses shouldn't be used for RIDs either */
69 if (!zebra_check_addr(ifc->address))
70 return 1;
71
72 return 0;
18a6dce6 73}
74
d62a17ae 75void router_id_get(struct prefix *p, vrf_id_t vrf_id)
18a6dce6 76{
d62a17ae 77 struct listnode *node;
78 struct connected *c;
79 struct zebra_vrf *zvrf = vrf_info_get(vrf_id);
80
81 p->u.prefix4.s_addr = 0;
82 p->family = AF_INET;
83 p->prefixlen = 32;
84
85 if (zvrf->rid_user_assigned.u.prefix4.s_addr)
86 p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
87 else if (!list_isempty(zvrf->rid_lo_sorted_list)) {
88 node = listtail(zvrf->rid_lo_sorted_list);
89 c = listgetdata(node);
90 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
91 } else if (!list_isempty(zvrf->rid_all_sorted_list)) {
92 node = listtail(zvrf->rid_all_sorted_list);
93 c = listgetdata(node);
94 p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
95 }
18a6dce6 96}
97
d62a17ae 98static void router_id_set(struct prefix *p, vrf_id_t vrf_id)
18a6dce6 99{
d62a17ae 100 struct prefix p2;
101 struct listnode *node;
102 struct zserv *client;
103 struct zebra_vrf *zvrf;
104
105 if (p->u.prefix4.s_addr == 0) /* unset */
106 {
107 zvrf = vrf_info_lookup(vrf_id);
108 if (!zvrf)
109 return;
110 } else /* set */
111 zvrf = vrf_info_get(vrf_id);
112
113 zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
114
115 router_id_get(&p2, vrf_id);
116
117 for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
118 zsend_router_id_update(client, &p2, vrf_id);
18a6dce6 119}
120
d62a17ae 121void router_id_add_address(struct connected *ifc)
18a6dce6 122{
d62a17ae 123 struct list *l = NULL;
124 struct listnode *node;
125 struct prefix before;
126 struct prefix after;
127 struct zserv *client;
128 struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
129
130 if (router_id_bad_address(ifc))
131 return;
132
133 router_id_get(&before, zvrf_id(zvrf));
134
135 if (!strncmp(ifc->ifp->name, "lo", 2)
136 || !strncmp(ifc->ifp->name, "dummy", 5))
137 l = zvrf->rid_lo_sorted_list;
138 else
139 l = zvrf->rid_all_sorted_list;
140
141 if (!router_id_find_node(l, ifc))
142 listnode_add_sort(l, ifc);
143
144 router_id_get(&after, zvrf_id(zvrf));
145
146 if (prefix_same(&before, &after))
147 return;
148
149 for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
150 zsend_router_id_update(client, &after, zvrf_id(zvrf));
18a6dce6 151}
152
d62a17ae 153void router_id_del_address(struct connected *ifc)
18a6dce6 154{
d62a17ae 155 struct connected *c;
156 struct list *l;
157 struct prefix after;
158 struct prefix before;
159 struct listnode *node;
160 struct zserv *client;
161 struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
18a6dce6 162
d62a17ae 163 if (router_id_bad_address(ifc))
164 return;
18a6dce6 165
d62a17ae 166 router_id_get(&before, zvrf_id(zvrf));
18a6dce6 167
d62a17ae 168 if (!strncmp(ifc->ifp->name, "lo", 2)
169 || !strncmp(ifc->ifp->name, "dummy", 5))
170 l = zvrf->rid_lo_sorted_list;
171 else
172 l = zvrf->rid_all_sorted_list;
18a6dce6 173
d62a17ae 174 if ((c = router_id_find_node(l, ifc)))
175 listnode_delete(l, c);
18a6dce6 176
d62a17ae 177 router_id_get(&after, zvrf_id(zvrf));
18a6dce6 178
d62a17ae 179 if (prefix_same(&before, &after))
180 return;
18a6dce6 181
d62a17ae 182 for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
183 zsend_router_id_update(client, &after, zvrf_id(zvrf));
18a6dce6 184}
185
d62a17ae 186void router_id_write(struct vty *vty)
18a6dce6 187{
d62a17ae 188 struct vrf *vrf;
189 struct zebra_vrf *zvrf;
190
a2addae8
RW
191 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
192 if ((zvrf = vrf->info) != NULL)
193 if (zvrf->rid_user_assigned.u.prefix4.s_addr) {
194 if (zvrf_id(zvrf) == VRF_DEFAULT)
195 vty_out(vty, "router-id %s\n",
196 inet_ntoa(
197 zvrf->rid_user_assigned
198 .u.prefix4));
199 else
200 vty_out(vty, "router-id %s vrf %s\n",
201 inet_ntoa(
202 zvrf->rid_user_assigned
203 .u.prefix4),
204 zvrf_name(zvrf));
205 }
18a6dce6 206}
207
208DEFUN (router_id,
209 router_id_cmd,
92300491 210 "router-id A.B.C.D [vrf NAME]",
18a6dce6 211 "Manually set the router-id\n"
92300491
DW
212 "IP address to use for router-id\n"
213 VRF_CMD_HELP_STR)
18a6dce6 214{
d62a17ae 215 int idx_ipv4 = 1;
216 int idx_name = 3;
92300491 217
d62a17ae 218 struct prefix rid;
219 vrf_id_t vrf_id = VRF_DEFAULT;
18a6dce6 220
d62a17ae 221 rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg);
222 if (!rid.u.prefix4.s_addr)
223 return CMD_WARNING_CONFIG_FAILED;
18a6dce6 224
d62a17ae 225 rid.prefixlen = 32;
226 rid.family = AF_INET;
18a6dce6 227
d62a17ae 228 if (argc > 2)
229 VRF_GET_ID(vrf_id, argv[idx_name]->arg);
c6ffe645 230
d62a17ae 231 router_id_set(&rid, vrf_id);
18a6dce6 232
d62a17ae 233 return CMD_SUCCESS;
18a6dce6 234}
235
236DEFUN (no_router_id,
237 no_router_id_cmd,
92300491 238 "no router-id [A.B.C.D [vrf NAME]]",
18a6dce6 239 NO_STR
92300491
DW
240 "Remove the manually configured router-id\n"
241 "IP address to use for router-id\n"
242 VRF_CMD_HELP_STR)
18a6dce6 243{
d62a17ae 244 int idx_name = 4;
92300491 245
d62a17ae 246 struct prefix rid;
247 vrf_id_t vrf_id = VRF_DEFAULT;
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)
254 VRF_GET_ID(vrf_id, argv[idx_name]->arg);
c6ffe645 255
d62a17ae 256 router_id_set(&rid, vrf_id);
18a6dce6 257
d62a17ae 258 return CMD_SUCCESS;
18a6dce6 259}
260
813d4307 261
d62a17ae 262static int router_id_cmp(void *a, void *b)
18a6dce6 263{
d62a17ae 264 const struct connected *ifa = (const struct connected *)a;
265 const struct connected *ifb = (const struct connected *)b;
18a6dce6 266
d62a17ae 267 return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,
268 &ifb->address->u.prefix4.s_addr);
18a6dce6 269}
270
d62a17ae 271void router_id_cmd_init(void)
18a6dce6 272{
d62a17ae 273 install_element(CONFIG_NODE, &router_id_cmd);
274 install_element(CONFIG_NODE, &no_router_id_cmd);
c6ffe645
FL
275}
276
d62a17ae 277void router_id_init(struct zebra_vrf *zvrf)
c6ffe645 278{
d62a17ae 279 zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
280 zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
18a6dce6 281
d62a17ae 282 memset(zvrf->rid_all_sorted_list, 0,
283 sizeof(zvrf->_rid_all_sorted_list));
284 memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_sorted_list));
285 memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned));
18a6dce6 286
d62a17ae 287 zvrf->rid_all_sorted_list->cmp = router_id_cmp;
288 zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
18a6dce6 289
d62a17ae 290 zvrf->rid_user_assigned.family = AF_INET;
291 zvrf->rid_user_assigned.prefixlen = 32;
18a6dce6 292}