blob: a7a6b2580d4fe8790f493bfc1853240f631a744a [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))
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700162 {
163 client->redist_v4_add_cnt++;
164 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
165 }
Lou Berger40278bd2016-01-12 13:41:45 -0500166 }
167
paul718e3742002-12-13 20:15:29 +0000168#ifdef HAVE_IPV6
Feng Luc99f3482014-10-16 09:52:36 +0800169 table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
paul718e3742002-12-13 20:15:29 +0000170 if (table)
171 for (rn = route_top (table); rn; rn = route_next (rn))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000172 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000173 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
174 && newrib->type == type
175 && newrib->distance != DISTANCE_INFINITY
176 && zebra_check_addr (&rn->p))
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700177 {
178 client->redist_v6_add_cnt++;
179 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
180 }
paul718e3742002-12-13 20:15:29 +0000181#endif /* HAVE_IPV6 */
182}
183
paul718e3742002-12-13 20:15:29 +0000184void
185redistribute_add (struct prefix *p, struct rib *rib)
186{
paul1eb8ef22005-04-07 07:30:20 +0000187 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000188 struct zserv *client;
189
paul1eb8ef22005-04-07 07:30:20 +0000190 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
191 {
Feng Luc99f3482014-10-16 09:52:36 +0800192 if ((is_default (p) &&
193 vrf_bitmap_check (client->redist_default, rib->vrf_id))
194 || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
paul1eb8ef22005-04-07 07:30:20 +0000195 {
196 if (p->family == AF_INET)
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700197 {
198 client->redist_v4_add_cnt++;
199 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
200 }
paul1eb8ef22005-04-07 07:30:20 +0000201 if (p->family == AF_INET6)
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700202 {
203 client->redist_v6_add_cnt++;
204 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
205 }
paul1eb8ef22005-04-07 07:30:20 +0000206 }
207 }
paul718e3742002-12-13 20:15:29 +0000208}
209
210void
211redistribute_delete (struct prefix *p, struct rib *rib)
212{
paul1eb8ef22005-04-07 07:30:20 +0000213 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000214 struct zserv *client;
215
216 /* Add DISTANCE_INFINITY check. */
217 if (rib->distance == DISTANCE_INFINITY)
218 return;
219
paul1eb8ef22005-04-07 07:30:20 +0000220 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
221 {
Feng Luc99f3482014-10-16 09:52:36 +0800222 if ((is_default (p) &&
223 vrf_bitmap_check (client->redist_default, rib->vrf_id))
224 || vrf_bitmap_check (client->redist[rib->type], rib->vrf_id))
paul1eb8ef22005-04-07 07:30:20 +0000225 {
226 if (p->family == AF_INET)
227 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000228#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000229 if (p->family == AF_INET6)
230 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
231#endif /* HAVE_IPV6 */
232 }
233 }
paul718e3742002-12-13 20:15:29 +0000234}
235
236void
Feng Luc99f3482014-10-16 09:52:36 +0800237zebra_redistribute_add (int command, struct zserv *client, int length,
238 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000239{
240 int type;
241
242 type = stream_getc (client->ibuf);
243
David Lamparterebf08632009-08-27 00:27:40 +0200244 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
245 return;
246
Feng Luc99f3482014-10-16 09:52:36 +0800247 if (! vrf_bitmap_check (client->redist[type], vrf_id))
paul718e3742002-12-13 20:15:29 +0000248 {
Feng Luc99f3482014-10-16 09:52:36 +0800249 vrf_bitmap_set (client->redist[type], vrf_id);
250 zebra_redistribute (client, type, vrf_id);
paul718e3742002-12-13 20:15:29 +0000251 }
David Lamparterebf08632009-08-27 00:27:40 +0200252}
paul718e3742002-12-13 20:15:29 +0000253
254void
Feng Luc99f3482014-10-16 09:52:36 +0800255zebra_redistribute_delete (int command, struct zserv *client, int length,
256 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000257{
258 int type;
259
260 type = stream_getc (client->ibuf);
261
David Lamparterebf08632009-08-27 00:27:40 +0200262 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
263 return;
264
Feng Luc99f3482014-10-16 09:52:36 +0800265 vrf_bitmap_unset (client->redist[type], vrf_id);
David Lamparterebf08632009-08-27 00:27:40 +0200266}
paul718e3742002-12-13 20:15:29 +0000267
268void
Feng Luc99f3482014-10-16 09:52:36 +0800269zebra_redistribute_default_add (int command, struct zserv *client, int length,
270 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000271{
Feng Luc99f3482014-10-16 09:52:36 +0800272 vrf_bitmap_set (client->redist_default, vrf_id);
273 zebra_redistribute_default (client, vrf_id);
paul718e3742002-12-13 20:15:29 +0000274}
275
276void
277zebra_redistribute_default_delete (int command, struct zserv *client,
Feng Luc99f3482014-10-16 09:52:36 +0800278 int length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000279{
Feng Luc99f3482014-10-16 09:52:36 +0800280 vrf_bitmap_unset (client->redist_default, vrf_id);
paul718e3742002-12-13 20:15:29 +0000281}
282
283/* Interface up information. */
284void
285zebra_interface_up_update (struct interface *ifp)
286{
paul1eb8ef22005-04-07 07:30:20 +0000287 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000288 struct zserv *client;
289
290 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000291 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000292
paul1eb8ef22005-04-07 07:30:20 +0000293 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
Olivier Dugeon15773a82016-04-19 18:29:55 +0200294 if (client->ifinfo)
295 {
296 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
297 zsend_interface_link_params (client, ifp);
298 }
paul718e3742002-12-13 20:15:29 +0000299}
300
301/* Interface down information. */
302void
303zebra_interface_down_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_DOWN %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))
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700312 {
313 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
314 }
paul718e3742002-12-13 20:15:29 +0000315}
316
317/* Interface information update. */
318void
319zebra_interface_add_update (struct interface *ifp)
320{
paul1eb8ef22005-04-07 07:30:20 +0000321 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000322 struct zserv *client;
323
324 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000325 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000326
paul1eb8ef22005-04-07 07:30:20 +0000327 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
328 if (client->ifinfo)
Olivier Dugeon15773a82016-04-19 18:29:55 +0200329 {
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700330 client->ifadd_cnt++;
331 zsend_interface_add (client, ifp);
Olivier Dugeon15773a82016-04-19 18:29:55 +0200332 zsend_interface_link_params (client, ifp);
333 }
paul718e3742002-12-13 20:15:29 +0000334}
335
336void
337zebra_interface_delete_update (struct interface *ifp)
338{
paul1eb8ef22005-04-07 07:30:20 +0000339 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000340 struct zserv *client;
341
342 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000343 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000344
paul1eb8ef22005-04-07 07:30:20 +0000345 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
346 if (client->ifinfo)
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700347 {
348 client->ifdel_cnt++;
349 zsend_interface_delete (client, ifp);
350 }
paul718e3742002-12-13 20:15:29 +0000351}
352
353/* Interface address addition. */
354void
355zebra_interface_address_add_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_ADD %s on %s",
368 prefix2str (p, buf, sizeof(buf)),
369 ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000370 }
371
Christian Frankec7df92d2013-01-24 14:04:47 +0000372 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
373 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
374
hasso18a6dce2004-10-03 18:18:34 +0000375 router_id_add_address(ifc);
376
paul1eb8ef22005-04-07 07:30:20 +0000377 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
378 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700379 {
380 client->connected_rt_add_cnt++;
381 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
382 }
paul718e3742002-12-13 20:15:29 +0000383}
384
385/* Interface address deletion. */
386void
387zebra_interface_address_delete_update (struct interface *ifp,
388 struct connected *ifc)
389{
paul1eb8ef22005-04-07 07:30:20 +0000390 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000391 struct zserv *client;
392 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000393
394 if (IS_ZEBRA_DEBUG_EVENT)
395 {
Timo Teräsbe6335d2015-05-23 11:08:41 +0300396 char buf[PREFIX_STRLEN];
Stephen Hemminger81cce012009-04-28 14:28:00 -0700397
paul718e3742002-12-13 20:15:29 +0000398 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +0300399 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
400 prefix2str (p, buf, sizeof(buf)),
401 ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000402 }
403
hasso18a6dce2004-10-03 18:18:34 +0000404 router_id_del_address(ifc);
405
paul1eb8ef22005-04-07 07:30:20 +0000406 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
407 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
Dinesh Dutt9ae85522015-05-19 17:47:22 -0700408 {
409 client->connected_rt_del_cnt++;
410 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
411 }
paul718e3742002-12-13 20:15:29 +0000412}
Olivier Dugeon15773a82016-04-19 18:29:55 +0200413
414/* Interface parameters update */
415void
416zebra_interface_parameters_update (struct interface *ifp)
417{
418 struct listnode *node, *nnode;
419 struct zserv *client;
420
421 if (IS_ZEBRA_DEBUG_EVENT)
422 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s", ifp->name);
423
424 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
425 if (client->ifinfo)
426 zsend_interface_link_params (client, ifp);
427}