blob: 8d5b4cae4bc99f921777a690695368d72ae3a41a [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"
33
34#include "zebra/rib.h"
35#include "zebra/zserv.h"
36#include "zebra/redistribute.h"
37#include "zebra/debug.h"
hasso18a6dce2004-10-03 18:18:34 +000038#include "zebra/router-id.h"
paul718e3742002-12-13 20:15:29 +000039
paulb21b19c2003-06-15 01:28:29 +000040/* master zebra server structure */
41extern struct zebra_t zebrad;
42
Paul Jakma6dc686a2007-04-10 19:24:45 +000043int
paul718e3742002-12-13 20:15:29 +000044zebra_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
Paul Jakma6dc686a2007-04-10 19:24:45 +000053 if (IPV4_NET127 (addr)
54 || IN_CLASSD (addr)
55 || IPV4_LINKLOCAL(addr))
paul718e3742002-12-13 20:15:29 +000056 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
ajs27da3982005-02-24 16:06:33 +000070static int
paul718e3742002-12-13 20:15:29 +000071is_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
ajs27da3982005-02-24 16:06:33 +000087static void
paul718e3742002-12-13 20:15:29 +000088zebra_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 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000110 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000111 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
112 && newrib->distance != DISTANCE_INFINITY)
paulb9df2d22004-05-09 09:09:59 +0000113 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000114 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 {
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000130 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000131 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
132 && newrib->distance != DISTANCE_INFINITY)
paulb9df2d22004-05-09 09:09:59 +0000133 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000134 route_unlock_node (rn);
135 }
136 }
137#endif /* HAVE_IPV6 */
138}
139
140/* Redistribute routes. */
ajs27da3982005-02-24 16:06:33 +0000141static void
paul718e3742002-12-13 20:15:29 +0000142zebra_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))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000151 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000152 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
153 && newrib->type == type
154 && newrib->distance != DISTANCE_INFINITY
155 && zebra_check_addr (&rn->p))
paulb9df2d22004-05-09 09:09:59 +0000156 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000157
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))
Avneesh Sachdev9fd92e32012-11-13 22:48:53 +0000162 RNODE_FOREACH_RIB (rn, newrib)
paul718e3742002-12-13 20:15:29 +0000163 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
164 && newrib->type == type
165 && newrib->distance != DISTANCE_INFINITY
166 && zebra_check_addr (&rn->p))
paulb9df2d22004-05-09 09:09:59 +0000167 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
paul718e3742002-12-13 20:15:29 +0000168#endif /* HAVE_IPV6 */
169}
170
paul718e3742002-12-13 20:15:29 +0000171void
172redistribute_add (struct prefix *p, struct rib *rib)
173{
paul1eb8ef22005-04-07 07:30:20 +0000174 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000175 struct zserv *client;
176
paul1eb8ef22005-04-07 07:30:20 +0000177 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
178 {
Timo Teräsf85592e2015-05-22 13:41:00 +0300179 if ((is_default (p) && client->redist_default)
180 || client->redist[rib->type])
paul1eb8ef22005-04-07 07:30:20 +0000181 {
182 if (p->family == AF_INET)
183 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000184#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000185 if (p->family == AF_INET6)
186 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000187#endif /* HAVE_IPV6 */
paul1eb8ef22005-04-07 07:30:20 +0000188 }
189 }
paul718e3742002-12-13 20:15:29 +0000190}
191
192void
193redistribute_delete (struct prefix *p, struct rib *rib)
194{
paul1eb8ef22005-04-07 07:30:20 +0000195 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000196 struct zserv *client;
197
198 /* Add DISTANCE_INFINITY check. */
199 if (rib->distance == DISTANCE_INFINITY)
200 return;
201
paul1eb8ef22005-04-07 07:30:20 +0000202 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
203 {
Timo Teräsf85592e2015-05-22 13:41:00 +0300204 if ((is_default (p) && client->redist_default)
205 || client->redist[rib->type])
paul1eb8ef22005-04-07 07:30:20 +0000206 {
207 if (p->family == AF_INET)
208 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
paul718e3742002-12-13 20:15:29 +0000209#ifdef HAVE_IPV6
paul1eb8ef22005-04-07 07:30:20 +0000210 if (p->family == AF_INET6)
211 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p, rib);
212#endif /* HAVE_IPV6 */
213 }
214 }
paul718e3742002-12-13 20:15:29 +0000215}
216
217void
218zebra_redistribute_add (int command, struct zserv *client, int length)
219{
220 int type;
221
222 type = stream_getc (client->ibuf);
223
David Lamparterebf08632009-08-27 00:27:40 +0200224 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
225 return;
226
227 if (! client->redist[type])
paul718e3742002-12-13 20:15:29 +0000228 {
David Lamparterebf08632009-08-27 00:27:40 +0200229 client->redist[type] = 1;
230 zebra_redistribute (client, type);
paul718e3742002-12-13 20:15:29 +0000231 }
David Lamparterebf08632009-08-27 00:27:40 +0200232}
paul718e3742002-12-13 20:15:29 +0000233
234void
235zebra_redistribute_delete (int command, struct zserv *client, int length)
236{
237 int type;
238
239 type = stream_getc (client->ibuf);
240
David Lamparterebf08632009-08-27 00:27:40 +0200241 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
242 return;
243
244 client->redist[type] = 0;
245}
paul718e3742002-12-13 20:15:29 +0000246
247void
248zebra_redistribute_default_add (int command, struct zserv *client, int length)
249{
250 client->redist_default = 1;
251 zebra_redistribute_default (client);
252}
253
254void
255zebra_redistribute_default_delete (int command, struct zserv *client,
256 int length)
257{
258 client->redist_default = 0;;
259}
260
261/* Interface up information. */
262void
263zebra_interface_up_update (struct interface *ifp)
264{
paul1eb8ef22005-04-07 07:30:20 +0000265 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000266 struct zserv *client;
267
268 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000269 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000270
paul1eb8ef22005-04-07 07:30:20 +0000271 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
272 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
paul718e3742002-12-13 20:15:29 +0000273}
274
275/* Interface down information. */
276void
277zebra_interface_down_update (struct interface *ifp)
278{
paul1eb8ef22005-04-07 07:30:20 +0000279 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000280 struct zserv *client;
281
282 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000283 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000284
paul1eb8ef22005-04-07 07:30:20 +0000285 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
286 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
paul718e3742002-12-13 20:15:29 +0000287}
288
289/* Interface information update. */
290void
291zebra_interface_add_update (struct interface *ifp)
292{
paul1eb8ef22005-04-07 07:30:20 +0000293 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000294 struct zserv *client;
295
296 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000297 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000298
paul1eb8ef22005-04-07 07:30:20 +0000299 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
300 if (client->ifinfo)
301 zsend_interface_add (client, ifp);
paul718e3742002-12-13 20:15:29 +0000302}
303
304void
305zebra_interface_delete_update (struct interface *ifp)
306{
paul1eb8ef22005-04-07 07:30:20 +0000307 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000308 struct zserv *client;
309
310 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +0000311 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000312
paul1eb8ef22005-04-07 07:30:20 +0000313 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
314 if (client->ifinfo)
315 zsend_interface_delete (client, ifp);
paul718e3742002-12-13 20:15:29 +0000316}
317
318/* Interface address addition. */
319void
320zebra_interface_address_add_update (struct interface *ifp,
321 struct connected *ifc)
322{
paul1eb8ef22005-04-07 07:30:20 +0000323 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000324 struct zserv *client;
325 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000326
327 if (IS_ZEBRA_DEBUG_EVENT)
328 {
Stephen Hemminger81cce012009-04-28 14:28:00 -0700329 char buf[INET6_ADDRSTRLEN];
330
paul718e3742002-12-13 20:15:29 +0000331 p = ifc->address;
ajsb6178002004-12-07 21:12:56 +0000332 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
Stephen Hemminger81cce012009-04-28 14:28:00 -0700333 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
ajsb6178002004-12-07 21:12:56 +0000334 p->prefixlen, ifc->ifp->name);
paul718e3742002-12-13 20:15:29 +0000335 }
336
Christian Frankec7df92d2013-01-24 14:04:47 +0000337 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
338 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
339
hasso18a6dce2004-10-03 18:18:34 +0000340 router_id_add_address(ifc);
341
paul1eb8ef22005-04-07 07:30:20 +0000342 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
343 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
344 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000345}
346
347/* Interface address deletion. */
348void
349zebra_interface_address_delete_update (struct interface *ifp,
350 struct connected *ifc)
351{
paul1eb8ef22005-04-07 07:30:20 +0000352 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000353 struct zserv *client;
354 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000355
356 if (IS_ZEBRA_DEBUG_EVENT)
357 {
Stephen Hemminger81cce012009-04-28 14:28:00 -0700358 char buf[INET6_ADDRSTRLEN];
359
paul718e3742002-12-13 20:15:29 +0000360 p = ifc->address;
ajsb6178002004-12-07 21:12:56 +0000361 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
Stephen Hemminger81cce012009-04-28 14:28:00 -0700362 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
paul718e3742002-12-13 20:15:29 +0000363 p->prefixlen, ifc->ifp->name);
364 }
365
hasso18a6dce2004-10-03 18:18:34 +0000366 router_id_del_address(ifc);
367
paul1eb8ef22005-04-07 07:30:20 +0000368 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
369 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
370 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000371}