]> git.proxmox.com Git - mirror_frr.git/blame - zebra/redistribute.c
iquagga-faster-compile.patch
[mirror_frr.git] / zebra / redistribute.c
CommitLineData
718e3744 1/* Redistribution Handler
2 * Copyright (C) 1998 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "vector.h"
25#include "vty.h"
26#include "command.h"
27#include "prefix.h"
28#include "table.h"
29#include "stream.h"
30#include "zclient.h"
31#include "linklist.h"
32#include "log.h"
33
34#include "zebra/rib.h"
35#include "zebra/zserv.h"
36#include "zebra/redistribute.h"
37#include "zebra/debug.h"
18a6dce6 38#include "zebra/router-id.h"
718e3744 39
b21b19c5 40/* master zebra server structure */
41extern struct zebra_t zebrad;
42
6dc686a2 43int
718e3744 44zebra_check_addr (struct prefix *p)
45{
46 if (p->family == AF_INET)
47 {
48 u_int32_t addr;
49
50 addr = p->u.prefix4.s_addr;
51 addr = ntohl (addr);
52
6dc686a2
PJ
53 if (IPV4_NET127 (addr)
54 || IN_CLASSD (addr)
55 || IPV4_LINKLOCAL(addr))
718e3744 56 return 0;
57 }
58#ifdef HAVE_IPV6
59 if (p->family == AF_INET6)
60 {
61 if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
62 return 0;
63 if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
64 return 0;
65 }
66#endif /* HAVE_IPV6 */
67 return 1;
68}
69
27da3988 70static int
718e3744 71is_default (struct prefix *p)
72{
73 if (p->family == AF_INET)
74 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
75 return 1;
76#ifdef HAVE_IPV6
77#if 0 /* IPv6 default separation is now pending until protocol daemon
78 can handle that. */
79 if (p->family == AF_INET6)
80 if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
81 return 1;
82#endif /* 0 */
83#endif /* HAVE_IPV6 */
84 return 0;
85}
86
27da3988 87static void
718e3744 88zebra_redistribute_default (struct zserv *client)
89{
90 struct prefix_ipv4 p;
91 struct route_table *table;
92 struct route_node *rn;
93 struct rib *newrib;
94#ifdef HAVE_IPV6
95 struct prefix_ipv6 p6;
96#endif /* HAVE_IPV6 */
97
98
99 /* Lookup default route. */
100 memset (&p, 0, sizeof (struct prefix_ipv4));
101 p.family = AF_INET;
102
103 /* Lookup table. */
104 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
105 if (table)
106 {
107 rn = route_node_lookup (table, (struct prefix *)&p);
108 if (rn)
109 {
9fd92e3c 110 RNODE_FOREACH_RIB (rn, newrib)
718e3744 111 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
112 && newrib->distance != DISTANCE_INFINITY)
b9df2d25 113 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
718e3744 114 route_unlock_node (rn);
115 }
116 }
117
118#ifdef HAVE_IPV6
119 /* Lookup default route. */
120 memset (&p6, 0, sizeof (struct prefix_ipv6));
121 p6.family = AF_INET6;
122
123 /* Lookup table. */
124 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
125 if (table)
126 {
127 rn = route_node_lookup (table, (struct prefix *)&p6);
128 if (rn)
129 {
9fd92e3c 130 RNODE_FOREACH_RIB (rn, newrib)
718e3744 131 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
132 && newrib->distance != DISTANCE_INFINITY)
b9df2d25 133 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
718e3744 134 route_unlock_node (rn);
135 }
136 }
137#endif /* HAVE_IPV6 */
138}
139
140/* Redistribute routes. */
27da3988 141static void
718e3744 142zebra_redistribute (struct zserv *client, int type)
143{
144 struct rib *newrib;
145 struct route_table *table;
146 struct route_node *rn;
147
148 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
149 if (table)
150 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 151 RNODE_FOREACH_RIB (rn, newrib)
718e3744 152 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
153 && newrib->type == type
154 && newrib->distance != DISTANCE_INFINITY
155 && zebra_check_addr (&rn->p))
b9df2d25 156 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
718e3744 157
158#ifdef HAVE_IPV6
159 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
160 if (table)
161 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 162 RNODE_FOREACH_RIB (rn, newrib)
718e3744 163 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
164 && newrib->type == type
165 && newrib->distance != DISTANCE_INFINITY
166 && zebra_check_addr (&rn->p))
b9df2d25 167 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
718e3744 168#endif /* HAVE_IPV6 */
169}
170
718e3744 171void
172redistribute_add (struct prefix *p, struct rib *rib)
173{
1eb8ef25 174 struct listnode *node, *nnode;
718e3744 175 struct zserv *client;
176
1eb8ef25 177 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
178 {
179 if (is_default (p))
180 {
181 if (client->redist_default || client->redist[rib->type])
182 {
183 if (p->family == AF_INET)
184 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
718e3744 185#ifdef HAVE_IPV6
1eb8ef25 186 if (p->family == AF_INET6)
187 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
718e3744 188#endif /* HAVE_IPV6 */
1eb8ef25 189 }
190 }
191 else if (client->redist[rib->type])
192 {
193 if (p->family == AF_INET)
194 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
718e3744 195#ifdef HAVE_IPV6
1eb8ef25 196 if (p->family == AF_INET6)
197 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
718e3744 198#endif /* HAVE_IPV6 */
1eb8ef25 199 }
200 }
718e3744 201}
202
203void
204redistribute_delete (struct prefix *p, struct rib *rib)
205{
1eb8ef25 206 struct listnode *node, *nnode;
718e3744 207 struct zserv *client;
208
209 /* Add DISTANCE_INFINITY check. */
210 if (rib->distance == DISTANCE_INFINITY)
211 return;
212
1eb8ef25 213 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
214 {
215 if (is_default (p))
216 {
217 if (client->redist_default || client->redist[rib->type])
218 {
219 if (p->family == AF_INET)
220 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
221 rib);
718e3744 222#ifdef HAVE_IPV6
1eb8ef25 223 if (p->family == AF_INET6)
224 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
225 rib);
226#endif /* HAVE_IPV6 */
227 }
228 }
229 else if (client->redist[rib->type])
230 {
231 if (p->family == AF_INET)
232 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
718e3744 233#ifdef HAVE_IPV6
1eb8ef25 234 if (p->family == AF_INET6)
235 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
236#endif /* HAVE_IPV6 */
237 }
238 }
718e3744 239}
240
241void
242zebra_redistribute_add (int command, struct zserv *client, int length)
243{
244 int type;
245
246 type = stream_getc (client->ibuf);
247
ebf08631
DL
248 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
249 return;
250
251 if (! client->redist[type])
718e3744 252 {
ebf08631
DL
253 client->redist[type] = 1;
254 zebra_redistribute (client, type);
718e3744 255 }
ebf08631 256}
718e3744 257
258void
259zebra_redistribute_delete (int command, struct zserv *client, int length)
260{
261 int type;
262
263 type = stream_getc (client->ibuf);
264
ebf08631
DL
265 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
266 return;
267
268 client->redist[type] = 0;
269}
718e3744 270
271void
272zebra_redistribute_default_add (int command, struct zserv *client, int length)
273{
274 client->redist_default = 1;
275 zebra_redistribute_default (client);
276}
277
278void
279zebra_redistribute_default_delete (int command, struct zserv *client,
280 int length)
281{
282 client->redist_default = 0;;
283}
284
285/* Interface up information. */
286void
287zebra_interface_up_update (struct interface *ifp)
288{
1eb8ef25 289 struct listnode *node, *nnode;
718e3744 290 struct zserv *client;
291
292 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 293 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
718e3744 294
1eb8ef25 295 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
296 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
718e3744 297}
298
299/* Interface down information. */
300void
301zebra_interface_down_update (struct interface *ifp)
302{
1eb8ef25 303 struct listnode *node, *nnode;
718e3744 304 struct zserv *client;
305
306 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 307 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
718e3744 308
1eb8ef25 309 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
310 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
718e3744 311}
312
313/* Interface information update. */
314void
315zebra_interface_add_update (struct interface *ifp)
316{
1eb8ef25 317 struct listnode *node, *nnode;
718e3744 318 struct zserv *client;
319
320 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 321 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
718e3744 322
1eb8ef25 323 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
324 if (client->ifinfo)
325 zsend_interface_add (client, ifp);
718e3744 326}
327
328void
329zebra_interface_delete_update (struct interface *ifp)
330{
1eb8ef25 331 struct listnode *node, *nnode;
718e3744 332 struct zserv *client;
333
334 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 335 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
718e3744 336
1eb8ef25 337 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
338 if (client->ifinfo)
339 zsend_interface_delete (client, ifp);
718e3744 340}
341
342/* Interface address addition. */
343void
344zebra_interface_address_add_update (struct interface *ifp,
345 struct connected *ifc)
346{
1eb8ef25 347 struct listnode *node, *nnode;
718e3744 348 struct zserv *client;
349 struct prefix *p;
718e3744 350
351 if (IS_ZEBRA_DEBUG_EVENT)
352 {
81cce018
SH
353 char buf[INET6_ADDRSTRLEN];
354
718e3744 355 p = ifc->address;
b6178002 356 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
81cce018 357 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
b6178002 358 p->prefixlen, ifc->ifp->name);
718e3744 359 }
360
c7df92de
CF
361 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
362 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
363
18a6dce6 364 router_id_add_address(ifc);
365
1eb8ef25 366 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
367 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
368 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
718e3744 369}
370
371/* Interface address deletion. */
372void
373zebra_interface_address_delete_update (struct interface *ifp,
374 struct connected *ifc)
375{
1eb8ef25 376 struct listnode *node, *nnode;
718e3744 377 struct zserv *client;
378 struct prefix *p;
718e3744 379
380 if (IS_ZEBRA_DEBUG_EVENT)
381 {
81cce018
SH
382 char buf[INET6_ADDRSTRLEN];
383
718e3744 384 p = ifc->address;
b6178002 385 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
81cce018 386 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
718e3744 387 p->prefixlen, ifc->ifp->name);
388 }
389
18a6dce6 390 router_id_del_address(ifc);
391
1eb8ef25 392 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
393 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
394 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
718e3744 395}