blob: 5ec821988341bdb0cb0f5f8366a81d1be67cfa9e [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
Feng Luc99f3482014-10-16 09:52:36 +080071int
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
Feng Luc99f3482014-10-16 09:52:36 +080089zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000090{
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 Luc99f3482014-10-16 09:52:36 +0800105 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
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 Luc99f3482014-10-16 09:52:36 +0800125 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
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
Feng Luc99f3482014-10-16 09:52:36 +0800143zebra_redistribute (struct zserv *client, int type, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000144{
145 struct rib *newrib;
146 struct route_table *table;
147 struct route_node *rn;
148
Feng Luc99f3482014-10-16 09:52:36 +0800149 table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
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 Luc99f3482014-10-16 09:52:36 +0800160 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
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 {
Feng Luc99f3482014-10-16 09:52:36 +0800180 if ((is_default (p) &&
181 vrf_bitmap_check (client->redist_default, rib->vrf_id))
182 || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
paul1eb8ef22005-04-07 07:30:20 +0000183 {
184 if (p->family == AF_INET)
185 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000186#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000187 if (p->family == AF_INET6)
188 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000189#endif /* HAVE_IPV6 */
paul1eb8ef22005-04-07 07:30:20 +0000190 }
191 }
paul718e3742002-12-13 20:15:29 +0000192}
193
194void
195redistribute_delete (struct prefix *p, struct rib *rib)
196{
paul1eb8ef22005-04-07 07:30:20 +0000197 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000198 struct zserv *client;
199
200 /* Add DISTANCE_INFINITY check. */
201 if (rib->distance == DISTANCE_INFINITY)
202 return;
203
paul1eb8ef22005-04-07 07:30:20 +0000204 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
205 {
Feng Luc99f3482014-10-16 09:52:36 +0800206 if ((is_default (p) &&
207 vrf_bitmap_check (client->redist_default, rib->vrf_id))
208 || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
paul1eb8ef22005-04-07 07:30:20 +0000209 {
210 if (p->family == AF_INET)
211 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000212#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000213 if (p->family == AF_INET6)
214 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
215#endif /* HAVE_IPV6 */
216 }
217 }
paul718e3742002-12-13 20:15:29 +0000218}
219
220void
Feng Luc99f3482014-10-16 09:52:36 +0800221zebra_redistribute_add (int command, struct zserv *client, int length,
222 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000223{
224 int type;
225
226 type = stream_getc (client->ibuf);
227
David Lamparterebf08632009-08-27 00:27:40 +0200228 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
229 return;
230
Feng Luc99f3482014-10-16 09:52:36 +0800231 if (! vrf_bitmap_check (client->redist[type], vrf_id))
paul718e3742002-12-13 20:15:29 +0000232 {
Feng Luc99f3482014-10-16 09:52:36 +0800233 vrf_bitmap_set (client->redist[type], vrf_id);
234 zebra_redistribute (client, type, vrf_id);
paul718e3742002-12-13 20:15:29 +0000235 }
David Lamparterebf08632009-08-27 00:27:40 +0200236}
paul718e3742002-12-13 20:15:29 +0000237
238void
Feng Luc99f3482014-10-16 09:52:36 +0800239zebra_redistribute_delete (int command, struct zserv *client, int length,
240 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000241{
242 int type;
243
244 type = stream_getc (client->ibuf);
245
David Lamparterebf08632009-08-27 00:27:40 +0200246 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
247 return;
248
Feng Luc99f3482014-10-16 09:52:36 +0800249 vrf_bitmap_unset (client->redist[type], vrf_id);
David Lamparterebf08632009-08-27 00:27:40 +0200250}
paul718e3742002-12-13 20:15:29 +0000251
252void
Feng Luc99f3482014-10-16 09:52:36 +0800253zebra_redistribute_default_add (int command, struct zserv *client, int length,
254 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000255{
Feng Luc99f3482014-10-16 09:52:36 +0800256 vrf_bitmap_set (client->redist_default, vrf_id);
257 zebra_redistribute_default (client, vrf_id);
paul718e3742002-12-13 20:15:29 +0000258}
259
260void
261zebra_redistribute_default_delete (int command, struct zserv *client,
Feng Luc99f3482014-10-16 09:52:36 +0800262 int length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000263{
Feng Luc99f3482014-10-16 09:52:36 +0800264 vrf_bitmap_unset (client->redist_default, vrf_id);
paul718e3742002-12-13 20:15:29 +0000265}
266
267/* Interface up information. */
268void
269zebra_interface_up_update (struct interface *ifp)
270{
paul1eb8ef22005-04-07 07:30:20 +0000271 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000272 struct zserv *client;
273
274 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000275 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000276
paul1eb8ef22005-04-07 07:30:20 +0000277 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
278 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
paul718e3742002-12-13 20:15:29 +0000279}
280
281/* Interface down information. */
282void
283zebra_interface_down_update (struct interface *ifp)
284{
paul1eb8ef22005-04-07 07:30:20 +0000285 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000286 struct zserv *client;
287
288 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000289 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000290
paul1eb8ef22005-04-07 07:30:20 +0000291 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
292 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
paul718e3742002-12-13 20:15:29 +0000293}
294
295/* Interface information update. */
296void
297zebra_interface_add_update (struct interface *ifp)
298{
paul1eb8ef22005-04-07 07:30:20 +0000299 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000300 struct zserv *client;
301
302 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000303 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000304
paul1eb8ef22005-04-07 07:30:20 +0000305 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
306 if (client->ifinfo)
307 zsend_interface_add (client, ifp);
paul718e3742002-12-13 20:15:29 +0000308}
309
310void
311zebra_interface_delete_update (struct interface *ifp)
312{
paul1eb8ef22005-04-07 07:30:20 +0000313 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000314 struct zserv *client;
315
316 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000317 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000318
paul1eb8ef22005-04-07 07:30:20 +0000319 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
320 if (client->ifinfo)
321 zsend_interface_delete (client, ifp);
paul718e3742002-12-13 20:15:29 +0000322}
323
324/* Interface address addition. */
325void
326zebra_interface_address_add_update (struct interface *ifp,
327 struct connected *ifc)
328{
paul1eb8ef22005-04-07 07:30:20 +0000329 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000330 struct zserv *client;
331 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000332
333 if (IS_ZEBRA_DEBUG_EVENT)
334 {
Timo Teräsbe6335d2015-05-23 11:08:41 +0300335 char buf[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -0700336
paul718e3742002-12-13 20:15:29 +0000337 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +0300338 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
339 prefix2str (p, buf, sizeof(buf)),
340 ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000341 }
342
Christian Frankec7df92d2013-01-24 14:04:47 +0000343 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
344 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
345
hasso18a6dce2004-10-03 18:18:34 +0000346 router_id_add_address(ifc);
347
paul1eb8ef22005-04-07 07:30:20 +0000348 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
349 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
350 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000351}
352
353/* Interface address deletion. */
354void
355zebra_interface_address_delete_update (struct interface *ifp,
356 struct connected *ifc)
357{
paul1eb8ef22005-04-07 07:30:20 +0000358 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000359 struct zserv *client;
360 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000361
362 if (IS_ZEBRA_DEBUG_EVENT)
363 {
Timo Teräsbe6335d2015-05-23 11:08:41 +0300364 char buf[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -0700365
paul718e3742002-12-13 20:15:29 +0000366 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +0300367 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
368 prefix2str (p, buf, sizeof(buf)),
369 ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000370 }
371
hasso18a6dce2004-10-03 18:18:34 +0000372 router_id_del_address(ifc);
373
paul1eb8ef22005-04-07 07:30:20 +0000374 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
375 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
376 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000377}