blob: 8bf8ea8c091a4a49e822b911f2ca65ee1cecf3d6 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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"
Feng Lu41f44a22015-05-22 11:39:56 +020033#include "vrf.h"
paul718e3742002-12-13 20:15:29 +000034
35#include "zebra/rib.h"
36#include "zebra/zserv.h"
37#include "zebra/redistribute.h"
38#include "zebra/debug.h"
hasso18a6dce2004-10-03 18:18:34 +000039#include "zebra/router-id.h"
paul718e3742002-12-13 20:15:29 +000040
paulb21b19c2003-06-15 01:28:29 +000041/* master zebra server structure */
42extern struct zebra_t zebrad;
43
Paul Jakma6dc686a2007-04-10 19:24:45 +000044int
paul718e3742002-12-13 20:15:29 +000045zebra_check_addr (struct prefix *p)
46{
47 if (p->family == AF_INET)
48 {
49 u_int32_t addr;
50
51 addr = p->u.prefix4.s_addr;
52 addr = ntohl (addr);
53
Paul Jakma6dc686a2007-04-10 19:24:45 +000054 if (IPV4_NET127 (addr)
55 || IN_CLASSD (addr)
56 || IPV4_LINKLOCAL(addr))
paul718e3742002-12-13 20:15:29 +000057 return 0;
58 }
59#ifdef HAVE_IPV6
60 if (p->family == AF_INET6)
61 {
62 if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
63 return 0;
64 if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
65 return 0;
66 }
67#endif /* HAVE_IPV6 */
68 return 1;
69}
70
ajs27da3982005-02-24 16:06:33 +000071static int
paul718e3742002-12-13 20:15:29 +000072is_default (struct prefix *p)
73{
74 if (p->family == AF_INET)
75 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
76 return 1;
77#ifdef HAVE_IPV6
78#if 0 /* IPv6 default separation is now pending until protocol daemon
79 can handle that. */
80 if (p->family == AF_INET6)
81 if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
82 return 1;
83#endif /* 0 */
84#endif /* HAVE_IPV6 */
85 return 0;
86}
87
ajs27da3982005-02-24 16:06:33 +000088static void
paul718e3742002-12-13 20:15:29 +000089zebra_redistribute_default (struct zserv *client)
90{
91 struct prefix_ipv4 p;
92 struct route_table *table;
93 struct route_node *rn;
94 struct rib *newrib;
95#ifdef HAVE_IPV6
96 struct prefix_ipv6 p6;
97#endif /* HAVE_IPV6 */
98
99
100 /* Lookup default route. */
101 memset (&p, 0, sizeof (struct prefix_ipv4));
102 p.family = AF_INET;
103
104 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +0200105 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000106 if (table)
107 {
108 rn = route_node_lookup (table, (struct prefix *)&p);
109 if (rn)
110 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000111 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000112 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
113 && newrib->distance != DISTANCE_INFINITY)
paulb9df2d22004-05-09 09:09:59 +0000114 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000115 route_unlock_node (rn);
116 }
117 }
118
119#ifdef HAVE_IPV6
120 /* Lookup default route. */
121 memset (&p6, 0, sizeof (struct prefix_ipv6));
122 p6.family = AF_INET6;
123
124 /* Lookup table. */
Feng Lu41f44a22015-05-22 11:39:56 +0200125 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000126 if (table)
127 {
128 rn = route_node_lookup (table, (struct prefix *)&p6);
129 if (rn)
130 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000131 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000132 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
133 && newrib->distance != DISTANCE_INFINITY)
paulb9df2d22004-05-09 09:09:59 +0000134 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000135 route_unlock_node (rn);
136 }
137 }
138#endif /* HAVE_IPV6 */
139}
140
141/* Redistribute routes. */
ajs27da3982005-02-24 16:06:33 +0000142static void
paul718e3742002-12-13 20:15:29 +0000143zebra_redistribute (struct zserv *client, int type)
144{
145 struct rib *newrib;
146 struct route_table *table;
147 struct route_node *rn;
148
Feng Lu41f44a22015-05-22 11:39:56 +0200149 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000150 if (table)
151 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000152 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000153 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
154 && newrib->type == type
155 && newrib->distance != DISTANCE_INFINITY
156 && zebra_check_addr (&rn->p))
paulb9df2d22004-05-09 09:09:59 +0000157 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000158
159#ifdef HAVE_IPV6
Feng Lu41f44a22015-05-22 11:39:56 +0200160 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000161 if (table)
162 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000163 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000164 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
165 && newrib->type == type
166 && newrib->distance != DISTANCE_INFINITY
167 && zebra_check_addr (&rn->p))
paulb9df2d22004-05-09 09:09:59 +0000168 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000169#endif /* HAVE_IPV6 */
170}
171
paul718e3742002-12-13 20:15:29 +0000172void
173redistribute_add (struct prefix *p, struct rib *rib)
174{
paul1eb8ef22005-04-07 07:30:20 +0000175 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000176 struct zserv *client;
177
paul1eb8ef22005-04-07 07:30:20 +0000178 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
179 {
Timo Teräsf85592e2015-05-22 13:41:00 +0300180 if ((is_default (p) && client->redist_default)
181 || client->redist[rib->type])
paul1eb8ef22005-04-07 07:30:20 +0000182 {
183 if (p->family == AF_INET)
184 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000185#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000186 if (p->family == AF_INET6)
187 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000188#endif /* HAVE_IPV6 */
paul1eb8ef22005-04-07 07:30:20 +0000189 }
190 }
paul718e3742002-12-13 20:15:29 +0000191}
192
193void
194redistribute_delete (struct prefix *p, struct rib *rib)
195{
paul1eb8ef22005-04-07 07:30:20 +0000196 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000197 struct zserv *client;
198
199 /* Add DISTANCE_INFINITY check. */
200 if (rib->distance == DISTANCE_INFINITY)
201 return;
202
paul1eb8ef22005-04-07 07:30:20 +0000203 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
204 {
Timo Teräsf85592e2015-05-22 13:41:00 +0300205 if ((is_default (p) && client->redist_default)
206 || client->redist[rib->type])
paul1eb8ef22005-04-07 07:30:20 +0000207 {
208 if (p->family == AF_INET)
209 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000210#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000211 if (p->family == AF_INET6)
212 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
213#endif /* HAVE_IPV6 */
214 }
215 }
paul718e3742002-12-13 20:15:29 +0000216}
217
218void
219zebra_redistribute_add (int command, struct zserv *client, int length)
220{
221 int type;
222
223 type = stream_getc (client->ibuf);
224
David Lamparterebf08632009-08-27 00:27:40 +0200225 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
226 return;
227
228 if (! client->redist[type])
paul718e3742002-12-13 20:15:29 +0000229 {
David Lamparterebf08632009-08-27 00:27:40 +0200230 client->redist[type] = 1;
231 zebra_redistribute (client, type);
paul718e3742002-12-13 20:15:29 +0000232 }
David Lamparterebf08632009-08-27 00:27:40 +0200233}
paul718e3742002-12-13 20:15:29 +0000234
235void
236zebra_redistribute_delete (int command, struct zserv *client, int length)
237{
238 int type;
239
240 type = stream_getc (client->ibuf);
241
David Lamparterebf08632009-08-27 00:27:40 +0200242 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
243 return;
244
245 client->redist[type] = 0;
246}
paul718e3742002-12-13 20:15:29 +0000247
248void
249zebra_redistribute_default_add (int command, struct zserv *client, int length)
250{
251 client->redist_default = 1;
252 zebra_redistribute_default (client);
253}
254
255void
256zebra_redistribute_default_delete (int command, struct zserv *client,
257 int length)
258{
259 client->redist_default = 0;;
260}
261
262/* Interface up information. */
263void
264zebra_interface_up_update (struct interface *ifp)
265{
paul1eb8ef22005-04-07 07:30:20 +0000266 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000267 struct zserv *client;
268
269 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000270 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000271
paul1eb8ef22005-04-07 07:30:20 +0000272 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
273 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
paul718e3742002-12-13 20:15:29 +0000274}
275
276/* Interface down information. */
277void
278zebra_interface_down_update (struct interface *ifp)
279{
paul1eb8ef22005-04-07 07:30:20 +0000280 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000281 struct zserv *client;
282
283 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000284 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000285
paul1eb8ef22005-04-07 07:30:20 +0000286 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
287 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
paul718e3742002-12-13 20:15:29 +0000288}
289
290/* Interface information update. */
291void
292zebra_interface_add_update (struct interface *ifp)
293{
paul1eb8ef22005-04-07 07:30:20 +0000294 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000295 struct zserv *client;
296
297 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000298 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000299
paul1eb8ef22005-04-07 07:30:20 +0000300 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
301 if (client->ifinfo)
302 zsend_interface_add (client, ifp);
paul718e3742002-12-13 20:15:29 +0000303}
304
305void
306zebra_interface_delete_update (struct interface *ifp)
307{
paul1eb8ef22005-04-07 07:30:20 +0000308 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000309 struct zserv *client;
310
311 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000312 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000313
paul1eb8ef22005-04-07 07:30:20 +0000314 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
315 if (client->ifinfo)
316 zsend_interface_delete (client, ifp);
paul718e3742002-12-13 20:15:29 +0000317}
318
319/* Interface address addition. */
320void
321zebra_interface_address_add_update (struct interface *ifp,
322 struct connected *ifc)
323{
paul1eb8ef22005-04-07 07:30:20 +0000324 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000325 struct zserv *client;
326 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000327
328 if (IS_ZEBRA_DEBUG_EVENT)
329 {
Timo Teräsbe6335d2015-05-23 11:08:41 +0300330 char buf[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -0700331
paul718e3742002-12-13 20:15:29 +0000332 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +0300333 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
334 prefix2str (p, buf, sizeof(buf)),
335 ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000336 }
337
Christian Frankec7df92d2013-01-24 14:04:47 +0000338 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
339 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
340
hasso18a6dce2004-10-03 18:18:34 +0000341 router_id_add_address(ifc);
342
paul1eb8ef22005-04-07 07:30:20 +0000343 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
344 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
345 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000346}
347
348/* Interface address deletion. */
349void
350zebra_interface_address_delete_update (struct interface *ifp,
351 struct connected *ifc)
352{
paul1eb8ef22005-04-07 07:30:20 +0000353 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000354 struct zserv *client;
355 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000356
357 if (IS_ZEBRA_DEBUG_EVENT)
358 {
Timo Teräsbe6335d2015-05-23 11:08:41 +0300359 char buf[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -0700360
paul718e3742002-12-13 20:15:29 +0000361 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +0300362 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
363 prefix2str (p, buf, sizeof(buf)),
364 ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000365 }
366
hasso18a6dce2004-10-03 18:18:34 +0000367 router_id_del_address(ifc);
368
paul1eb8ef22005-04-07 07:30:20 +0000369 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
370 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
371 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000372}