blob: 57b515e13d7b376a44b490696e6dc01e1d316807 [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)
Lou Berger40278bd2016-01-12 13:41:45 -0500153 {
154 if (IS_ZEBRA_DEBUG_EVENT)
155 zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, zebra_check_addr=%d",
156 __func__, CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED),
157 newrib->type, newrib->distance, zebra_check_addr (&rn->p));
158 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
159 && newrib->type == type
160 && newrib->distance != DISTANCE_INFINITY
161 && zebra_check_addr (&rn->p))
162 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
163 }
164
paul718e3742002-12-13 20:15:29 +0000165#ifdef HAVE_IPV6
Feng Luc99f3482014-10-16 09:52:36 +0800166 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000167 if (table)
168 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000169 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000170 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
171 && newrib->type == type
172 && newrib->distance != DISTANCE_INFINITY
173 && zebra_check_addr (&rn->p))
paulb9df2d22004-05-09 09:09:59 +0000174 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000175#endif /* HAVE_IPV6 */
176}
177
paul718e3742002-12-13 20:15:29 +0000178void
179redistribute_add (struct prefix *p, struct rib *rib)
180{
paul1eb8ef22005-04-07 07:30:20 +0000181 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000182 struct zserv *client;
183
paul1eb8ef22005-04-07 07:30:20 +0000184 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
185 {
Feng Luc99f3482014-10-16 09:52:36 +0800186 if ((is_default (p) &&
187 vrf_bitmap_check (client->redist_default, rib->vrf_id))
188 || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
paul1eb8ef22005-04-07 07:30:20 +0000189 {
190 if (p->family == AF_INET)
191 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000192#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000193 if (p->family == AF_INET6)
194 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000195#endif /* HAVE_IPV6 */
paul1eb8ef22005-04-07 07:30:20 +0000196 }
197 }
paul718e3742002-12-13 20:15:29 +0000198}
199
200void
201redistribute_delete (struct prefix *p, struct rib *rib)
202{
paul1eb8ef22005-04-07 07:30:20 +0000203 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000204 struct zserv *client;
205
206 /* Add DISTANCE_INFINITY check. */
207 if (rib->distance == DISTANCE_INFINITY)
208 return;
209
paul1eb8ef22005-04-07 07:30:20 +0000210 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
211 {
Feng Luc99f3482014-10-16 09:52:36 +0800212 if ((is_default (p) &&
213 vrf_bitmap_check (client->redist_default, rib->vrf_id))
214 || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
paul1eb8ef22005-04-07 07:30:20 +0000215 {
216 if (p->family == AF_INET)
217 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000218#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000219 if (p->family == AF_INET6)
220 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
221#endif /* HAVE_IPV6 */
222 }
223 }
paul718e3742002-12-13 20:15:29 +0000224}
225
226void
Feng Luc99f3482014-10-16 09:52:36 +0800227zebra_redistribute_add (int command, struct zserv *client, int length,
228 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000229{
230 int type;
231
232 type = stream_getc (client->ibuf);
233
David Lamparterebf08632009-08-27 00:27:40 +0200234 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
235 return;
236
Feng Luc99f3482014-10-16 09:52:36 +0800237 if (! vrf_bitmap_check (client->redist[type], vrf_id))
paul718e3742002-12-13 20:15:29 +0000238 {
Feng Luc99f3482014-10-16 09:52:36 +0800239 vrf_bitmap_set (client->redist[type], vrf_id);
240 zebra_redistribute (client, type, vrf_id);
paul718e3742002-12-13 20:15:29 +0000241 }
David Lamparterebf08632009-08-27 00:27:40 +0200242}
paul718e3742002-12-13 20:15:29 +0000243
244void
Feng Luc99f3482014-10-16 09:52:36 +0800245zebra_redistribute_delete (int command, struct zserv *client, int length,
246 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000247{
248 int type;
249
250 type = stream_getc (client->ibuf);
251
David Lamparterebf08632009-08-27 00:27:40 +0200252 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
253 return;
254
Feng Luc99f3482014-10-16 09:52:36 +0800255 vrf_bitmap_unset (client->redist[type], vrf_id);
David Lamparterebf08632009-08-27 00:27:40 +0200256}
paul718e3742002-12-13 20:15:29 +0000257
258void
Feng Luc99f3482014-10-16 09:52:36 +0800259zebra_redistribute_default_add (int command, struct zserv *client, int length,
260 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000261{
Feng Luc99f3482014-10-16 09:52:36 +0800262 vrf_bitmap_set (client->redist_default, vrf_id);
263 zebra_redistribute_default (client, vrf_id);
paul718e3742002-12-13 20:15:29 +0000264}
265
266void
267zebra_redistribute_default_delete (int command, struct zserv *client,
Feng Luc99f3482014-10-16 09:52:36 +0800268 int length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000269{
Feng Luc99f3482014-10-16 09:52:36 +0800270 vrf_bitmap_unset (client->redist_default, vrf_id);
paul718e3742002-12-13 20:15:29 +0000271}
272
273/* Interface up information. */
274void
275zebra_interface_up_update (struct interface *ifp)
276{
paul1eb8ef22005-04-07 07:30:20 +0000277 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000278 struct zserv *client;
279
280 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000281 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000282
paul1eb8ef22005-04-07 07:30:20 +0000283 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
284 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
paul718e3742002-12-13 20:15:29 +0000285}
286
287/* Interface down information. */
288void
289zebra_interface_down_update (struct interface *ifp)
290{
paul1eb8ef22005-04-07 07:30:20 +0000291 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000292 struct zserv *client;
293
294 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000295 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000296
paul1eb8ef22005-04-07 07:30:20 +0000297 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
298 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
paul718e3742002-12-13 20:15:29 +0000299}
300
301/* Interface information update. */
302void
303zebra_interface_add_update (struct interface *ifp)
304{
paul1eb8ef22005-04-07 07:30:20 +0000305 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000306 struct zserv *client;
307
308 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000309 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000310
paul1eb8ef22005-04-07 07:30:20 +0000311 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
312 if (client->ifinfo)
313 zsend_interface_add (client, ifp);
paul718e3742002-12-13 20:15:29 +0000314}
315
316void
317zebra_interface_delete_update (struct interface *ifp)
318{
paul1eb8ef22005-04-07 07:30:20 +0000319 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000320 struct zserv *client;
321
322 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000323 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000324
paul1eb8ef22005-04-07 07:30:20 +0000325 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
326 if (client->ifinfo)
327 zsend_interface_delete (client, ifp);
paul718e3742002-12-13 20:15:29 +0000328}
329
330/* Interface address addition. */
331void
332zebra_interface_address_add_update (struct interface *ifp,
333 struct connected *ifc)
334{
paul1eb8ef22005-04-07 07:30:20 +0000335 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000336 struct zserv *client;
337 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000338
339 if (IS_ZEBRA_DEBUG_EVENT)
340 {
Timo Teräsbe6335d2015-05-23 11:08:41 +0300341 char buf[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -0700342
paul718e3742002-12-13 20:15:29 +0000343 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +0300344 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
345 prefix2str (p, buf, sizeof(buf)),
346 ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000347 }
348
Christian Frankec7df92d2013-01-24 14:04:47 +0000349 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
350 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
351
hasso18a6dce2004-10-03 18:18:34 +0000352 router_id_add_address(ifc);
353
paul1eb8ef22005-04-07 07:30:20 +0000354 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
355 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
356 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000357}
358
359/* Interface address deletion. */
360void
361zebra_interface_address_delete_update (struct interface *ifp,
362 struct connected *ifc)
363{
paul1eb8ef22005-04-07 07:30:20 +0000364 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000365 struct zserv *client;
366 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000367
368 if (IS_ZEBRA_DEBUG_EVENT)
369 {
Timo Teräsbe6335d2015-05-23 11:08:41 +0300370 char buf[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -0700371
paul718e3742002-12-13 20:15:29 +0000372 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +0300373 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
374 prefix2str (p, buf, sizeof(buf)),
375 ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000376 }
377
hasso18a6dce2004-10-03 18:18:34 +0000378 router_id_del_address(ifc);
379
paul1eb8ef22005-04-07 07:30:20 +0000380 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
381 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
382 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000383}