blob: 40ecbce010c7e28be62bd9093f2c8bf0d48756d2 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* zebra client
2 Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21#include <zebra.h>
22
23#include "command.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "log.h"
28#include "sockunion.h"
29#include "zclient.h"
30#include "routemap.h"
31#include "thread.h"
Donald Sharp04907292016-01-07 10:03:01 -050032#include "filter.h"
paul718e3742002-12-13 20:15:29 +000033
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_route.h"
36#include "bgpd/bgp_attr.h"
37#include "bgpd/bgp_nexthop.h"
38#include "bgpd/bgp_zebra.h"
39#include "bgpd/bgp_fsm.h"
Andrew J. Schorra39275d2006-11-30 16:36:57 +000040#include "bgpd/bgp_debug.h"
Josh Bailey8196f132011-07-20 20:47:07 -070041#include "bgpd/bgp_mpath.h"
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -050042#include "bgpd/bgp_nexthop.h"
43#include "bgpd/bgp_nht.h"
David Lamparter6b0655a2014-06-04 06:53:35 +020044
paul718e3742002-12-13 20:15:29 +000045/* All information about zebra. */
Chris Caputo228da422009-07-18 05:44:03 +000046struct zclient *zclient = NULL;
hasso18a6dce2004-10-03 18:18:34 +000047struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000048
Josh Bailey8196f132011-07-20 20:47:07 -070049/* Growable buffer for nexthops sent to zebra */
50struct stream *bgp_nexthop_buf = NULL;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -050051struct stream *bgp_ifindices_buf = NULL;
Josh Bailey8196f132011-07-20 20:47:07 -070052
Lou Berger68bfb612016-10-06 09:59:32 -040053int zclient_num_connects;
54
hasso18a6dce2004-10-03 18:18:34 +000055/* Router-id update message from zebra. */
paul94f2b392005-06-28 12:44:16 +000056static int
Feng Luc99f3482014-10-16 09:52:36 +080057bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
58 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000059{
hasso18a6dce2004-10-03 18:18:34 +000060 struct prefix router_id;
paul718e3742002-12-13 20:15:29 +000061
hasso18a6dce2004-10-03 18:18:34 +000062 zebra_router_id_update_read(zclient->ibuf,&router_id);
Andrew J. Schorra39275d2006-11-30 16:36:57 +000063
64 if (BGP_DEBUG(zebra, ZEBRA))
65 {
66 char buf[128];
67 prefix2str(&router_id, buf, sizeof(buf));
68 zlog_debug("Zebra rcvd: router id update %s", buf);
69 }
70
hasso18a6dce2004-10-03 18:18:34 +000071 router_id_zebra = router_id.u.prefix4;
72
David Lamparter584083d2016-05-24 18:58:08 +020073 bgp_router_id_zebra_bump ();
paul718e3742002-12-13 20:15:29 +000074 return 0;
75}
76
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -050077/* Nexthop update message from zebra. */
78static int
79bgp_read_nexthop_update (int command, struct zclient *zclient,
80 zebra_size_t length, vrf_id_t vrf_id)
81{
82 bgp_parse_nexthop_update();
83 return 0;
84}
85
paul718e3742002-12-13 20:15:29 +000086/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000087static int
Feng Luc99f3482014-10-16 09:52:36 +080088bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
89 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000090{
91 struct interface *ifp;
92
Feng Luc99f3482014-10-16 09:52:36 +080093 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +000094
Andrew J. Schorra39275d2006-11-30 16:36:57 +000095 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
96 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
97
paul718e3742002-12-13 20:15:29 +000098 return 0;
99}
100
paul94f2b392005-06-28 12:44:16 +0000101static int
paul718e3742002-12-13 20:15:29 +0000102bgp_interface_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800103 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000104{
105 struct stream *s;
106 struct interface *ifp;
107
108 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800109 ifp = zebra_interface_state_read (s, vrf_id);
Christian Franke708ea622016-06-14 20:06:57 +0200110 if (! ifp)
111 return 0;
112
ajsd2fc8892005-04-02 18:38:43 +0000113 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000114
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000115 if (BGP_DEBUG(zebra, ZEBRA))
116 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
117
paul718e3742002-12-13 20:15:29 +0000118 return 0;
119}
120
paul94f2b392005-06-28 12:44:16 +0000121static int
Feng Luc99f3482014-10-16 09:52:36 +0800122bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
123 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000124{
125 struct stream *s;
126 struct interface *ifp;
127 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000128 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000129
130 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800131 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000132
133 if (! ifp)
134 return 0;
135
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000136 if (BGP_DEBUG(zebra, ZEBRA))
137 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
138
paul1eb8ef22005-04-07 07:30:20 +0000139 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
140 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000141
142 return 0;
143}
144
paul94f2b392005-06-28 12:44:16 +0000145static int
Feng Luc99f3482014-10-16 09:52:36 +0800146bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
147 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000148{
149 struct stream *s;
150 struct interface *ifp;
151 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000152 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000153
154 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800155 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000156 if (! ifp)
157 return 0;
158
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000159 if (BGP_DEBUG(zebra, ZEBRA))
160 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
161
paul1eb8ef22005-04-07 07:30:20 +0000162 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
163 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000164
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000165 /* Fast external-failover */
paul718e3742002-12-13 20:15:29 +0000166 {
paul1eb8ef22005-04-07 07:30:20 +0000167 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000168 struct bgp *bgp;
169 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000170
paul1eb8ef22005-04-07 07:30:20 +0000171 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000172 {
173 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
174 continue;
175
paul1eb8ef22005-04-07 07:30:20 +0000176 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000177 {
Timo Teräse3443a22016-10-19 16:02:34 +0300178 if (peer->gtsm_hops != 1 && peer_ttl (peer) != 1)
179 continue;
180 if (ifp == peer->nexthop.ifp)
181 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000182 }
183 }
184 }
185
186 return 0;
187}
188
paul94f2b392005-06-28 12:44:16 +0000189static int
paul718e3742002-12-13 20:15:29 +0000190bgp_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800191 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000192{
193 struct connected *ifc;
194
Feng Luc99f3482014-10-16 09:52:36 +0800195 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000196
197 if (ifc == NULL)
198 return 0;
199
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000200 if (BGP_DEBUG(zebra, ZEBRA))
201 {
202 char buf[128];
203 prefix2str(ifc->address, buf, sizeof(buf));
204 zlog_debug("Zebra rcvd: interface %s address add %s",
205 ifc->ifp->name, buf);
206 }
207
paul2e3b2e42002-12-13 21:03:13 +0000208 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000209 bgp_connected_add (ifc);
210
211 return 0;
212}
213
paul94f2b392005-06-28 12:44:16 +0000214static int
paul718e3742002-12-13 20:15:29 +0000215bgp_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800216 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000217{
218 struct connected *ifc;
219
Feng Luc99f3482014-10-16 09:52:36 +0800220 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000221
222 if (ifc == NULL)
223 return 0;
224
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000225 if (BGP_DEBUG(zebra, ZEBRA))
226 {
227 char buf[128];
228 prefix2str(ifc->address, buf, sizeof(buf));
229 zlog_debug("Zebra rcvd: interface %s address delete %s",
230 ifc->ifp->name, buf);
231 }
232
paul2e3b2e42002-12-13 21:03:13 +0000233 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000234 bgp_connected_delete (ifc);
235
236 connected_free (ifc);
237
238 return 0;
239}
240
241/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000242static int
Feng Luc99f3482014-10-16 09:52:36 +0800243zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
244 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000245{
246 struct stream *s;
247 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000248 struct in_addr nexthop;
249 struct prefix_ipv4 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500250 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000251
252 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000253 nexthop.s_addr = 0;
254
255 /* Type, flags, message. */
256 api.type = stream_getc (s);
257 api.flags = stream_getc (s);
258 api.message = stream_getc (s);
259
260 /* IPv4 prefix. */
261 memset (&p, 0, sizeof (struct prefix_ipv4));
262 p.family = AF_INET;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500263 plength = stream_getc (s);
264 p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000265 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
266
267 /* Nexthop, ifindex, distance, metric. */
268 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
269 {
270 api.nexthop_num = stream_getc (s);
271 nexthop.s_addr = stream_get_ipv4 (s);
272 }
273 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
274 {
275 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400276 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000277 }
278 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
279 api.distance = stream_getc (s);
280 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
281 api.metric = stream_getl (s);
282 else
283 api.metric = 0;
284
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500285 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
Paul Jakma96d10602016-07-01 14:23:45 +0100286 api.tag = stream_getl (s);
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500287 else
288 api.tag = 0;
289
paul718e3742002-12-13 20:15:29 +0000290 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000291 {
292 if (BGP_DEBUG(zebra, ZEBRA))
293 {
294 char buf[2][INET_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500295 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000296 zebra_route_string(api.type),
297 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
298 p.prefixlen,
299 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500300 api.metric,
301 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000302 }
Piotr Chytła605aa332015-12-01 10:03:54 -0500303 bgp_redistribute_add ((struct prefix *)&p, &nexthop, NULL,
304 api.metric, api.type, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000305 }
paul718e3742002-12-13 20:15:29 +0000306 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000307 {
308 if (BGP_DEBUG(zebra, ZEBRA))
309 {
310 char buf[2][INET_ADDRSTRLEN];
311 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500312 "nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000313 zebra_route_string(api.type),
314 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
315 p.prefixlen,
316 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500317 api.metric,
318 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000319 }
320 bgp_redistribute_delete((struct prefix *)&p, api.type);
321 }
paul718e3742002-12-13 20:15:29 +0000322
323 return 0;
324}
325
paul718e3742002-12-13 20:15:29 +0000326/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000327static int
Feng Luc99f3482014-10-16 09:52:36 +0800328zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
329 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000330{
331 struct stream *s;
332 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000333 struct in6_addr nexthop;
334 struct prefix_ipv6 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500335 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000336
337 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000338 memset (&nexthop, 0, sizeof (struct in6_addr));
339
340 /* Type, flags, message. */
341 api.type = stream_getc (s);
342 api.flags = stream_getc (s);
343 api.message = stream_getc (s);
344
345 /* IPv6 prefix. */
346 memset (&p, 0, sizeof (struct prefix_ipv6));
347 p.family = AF_INET6;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500348 plength = stream_getc (s);
349 p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000350 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
351
352 /* Nexthop, ifindex, distance, metric. */
353 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
354 {
355 api.nexthop_num = stream_getc (s);
356 stream_get (&nexthop, s, 16);
357 }
358 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
359 {
360 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400361 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000362 }
363 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
364 api.distance = stream_getc (s);
365 else
366 api.distance = 0;
367 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
368 api.metric = stream_getl (s);
369 else
370 api.metric = 0;
371
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500372 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
Paul Jakma96d10602016-07-01 14:23:45 +0100373 api.tag = stream_getl (s);
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500374 else
375 api.tag = 0;
376
paul718e3742002-12-13 20:15:29 +0000377 /* Simply ignore link-local address. */
378 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
379 return 0;
380
381 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000382 {
383 if (BGP_DEBUG(zebra, ZEBRA))
384 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400385 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500386 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000387 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400388 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
389 p.prefixlen,
390 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500391 api.metric,
392 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000393 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400394 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
Piotr Chytła605aa332015-12-01 10:03:54 -0500395 api.metric, api.type, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000396 }
paul718e3742002-12-13 20:15:29 +0000397 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000398 {
399 if (BGP_DEBUG(zebra, ZEBRA))
400 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400401 char buf[2][INET6_ADDRSTRLEN];
402 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500403 "nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000404 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400405 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
406 p.prefixlen,
407 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500408 api.metric,
409 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000410 }
411 bgp_redistribute_delete ((struct prefix *) &p, api.type);
412 }
paul718e3742002-12-13 20:15:29 +0000413
414 return 0;
415}
David Lamparter6b0655a2014-06-04 06:53:35 +0200416
paul718e3742002-12-13 20:15:29 +0000417struct interface *
418if_lookup_by_ipv4 (struct in_addr *addr)
419{
hasso52dc7ee2004-09-23 19:18:23 +0000420 struct listnode *ifnode;
421 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000422 struct interface *ifp;
423 struct connected *connected;
424 struct prefix_ipv4 p;
425 struct prefix *cp;
426
427 p.family = AF_INET;
428 p.prefix = *addr;
429 p.prefixlen = IPV4_MAX_BITLEN;
430
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000432 {
paul1eb8ef22005-04-07 07:30:20 +0000433 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000434 {
paul718e3742002-12-13 20:15:29 +0000435 cp = connected->address;
436
437 if (cp->family == AF_INET)
438 if (prefix_match (cp, (struct prefix *)&p))
439 return ifp;
440 }
441 }
442 return NULL;
443}
444
445struct interface *
446if_lookup_by_ipv4_exact (struct in_addr *addr)
447{
hasso52dc7ee2004-09-23 19:18:23 +0000448 struct listnode *ifnode;
449 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000450 struct interface *ifp;
451 struct connected *connected;
452 struct prefix *cp;
453
paul1eb8ef22005-04-07 07:30:20 +0000454 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000455 {
paul1eb8ef22005-04-07 07:30:20 +0000456 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000457 {
paul718e3742002-12-13 20:15:29 +0000458 cp = connected->address;
459
460 if (cp->family == AF_INET)
461 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
462 return ifp;
463 }
464 }
465 return NULL;
466}
467
paul718e3742002-12-13 20:15:29 +0000468struct interface *
469if_lookup_by_ipv6 (struct in6_addr *addr)
470{
hasso52dc7ee2004-09-23 19:18:23 +0000471 struct listnode *ifnode;
472 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000473 struct interface *ifp;
474 struct connected *connected;
475 struct prefix_ipv6 p;
476 struct prefix *cp;
477
478 p.family = AF_INET6;
479 p.prefix = *addr;
480 p.prefixlen = IPV6_MAX_BITLEN;
481
paul1eb8ef22005-04-07 07:30:20 +0000482 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000483 {
paul1eb8ef22005-04-07 07:30:20 +0000484 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000485 {
paul718e3742002-12-13 20:15:29 +0000486 cp = connected->address;
487
488 if (cp->family == AF_INET6)
489 if (prefix_match (cp, (struct prefix *)&p))
490 return ifp;
491 }
492 }
493 return NULL;
494}
495
496struct interface *
497if_lookup_by_ipv6_exact (struct in6_addr *addr)
498{
hasso52dc7ee2004-09-23 19:18:23 +0000499 struct listnode *ifnode;
500 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000501 struct interface *ifp;
502 struct connected *connected;
503 struct prefix *cp;
504
paul1eb8ef22005-04-07 07:30:20 +0000505 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000506 {
paul1eb8ef22005-04-07 07:30:20 +0000507 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000508 {
paul718e3742002-12-13 20:15:29 +0000509 cp = connected->address;
510
511 if (cp->family == AF_INET6)
512 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
513 return ifp;
514 }
515 }
516 return NULL;
517}
518
paul94f2b392005-06-28 12:44:16 +0000519static int
paul718e3742002-12-13 20:15:29 +0000520if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
521{
hasso52dc7ee2004-09-23 19:18:23 +0000522 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000523 struct connected *connected;
524 struct prefix *cp;
525
paul1eb8ef22005-04-07 07:30:20 +0000526 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000527 {
paul718e3742002-12-13 20:15:29 +0000528 cp = connected->address;
529
530 if (cp->family == AF_INET6)
531 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
532 {
533 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
534 return 1;
535 }
536 }
537 return 0;
538}
539
paul94f2b392005-06-28 12:44:16 +0000540static int
paul718e3742002-12-13 20:15:29 +0000541if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
542{
hasso52dc7ee2004-09-23 19:18:23 +0000543 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000544 struct connected *connected;
545 struct prefix *cp;
546
paul1eb8ef22005-04-07 07:30:20 +0000547 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000548 {
paul718e3742002-12-13 20:15:29 +0000549 cp = connected->address;
550
551 if (cp->family == AF_INET6)
552 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
553 {
554 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
555 return 1;
556 }
557 }
558 return 0;
559}
paul718e3742002-12-13 20:15:29 +0000560
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000561static int
562if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
563{
564 struct listnode *cnode;
565 struct connected *connected;
566 struct prefix *cp;
567
568 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
569 {
570 cp = connected->address;
571 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
572 {
573 *addr = cp->u.prefix4;
574 return 1;
575 }
576 }
577 return 0;
578}
579
paul718e3742002-12-13 20:15:29 +0000580int
581bgp_nexthop_set (union sockunion *local, union sockunion *remote,
582 struct bgp_nexthop *nexthop, struct peer *peer)
583{
584 int ret = 0;
585 struct interface *ifp = NULL;
586
587 memset (nexthop, 0, sizeof (struct bgp_nexthop));
588
589 if (!local)
590 return -1;
591 if (!remote)
592 return -1;
593
594 if (local->sa.sa_family == AF_INET)
595 {
596 nexthop->v4 = local->sin.sin_addr;
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700597 if (peer->update_if)
598 ifp = if_lookup_by_name (peer->update_if);
599 else
600 ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr);
paul718e3742002-12-13 20:15:29 +0000601 }
paul718e3742002-12-13 20:15:29 +0000602 if (local->sa.sa_family == AF_INET6)
603 {
604 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
605 {
606 if (peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200607 ifp = if_lookup_by_name (peer->ifname);
paul718e3742002-12-13 20:15:29 +0000608 }
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700609 else if (peer->update_if)
610 ifp = if_lookup_by_name (peer->update_if);
paul718e3742002-12-13 20:15:29 +0000611 else
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700612 ifp = if_lookup_by_ipv6_exact (&local->sin6.sin6_addr);
paul718e3742002-12-13 20:15:29 +0000613 }
paul718e3742002-12-13 20:15:29 +0000614
615 if (!ifp)
616 return -1;
617
618 nexthop->ifp = ifp;
619
620 /* IPv4 connection. */
621 if (local->sa.sa_family == AF_INET)
622 {
paul718e3742002-12-13 20:15:29 +0000623 /* IPv6 nexthop*/
624 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
625
626 /* There is no global nexthop. */
627 if (!ret)
628 if_get_ipv6_local (ifp, &nexthop->v6_global);
629 else
630 if_get_ipv6_local (ifp, &nexthop->v6_local);
paul718e3742002-12-13 20:15:29 +0000631 }
632
paul718e3742002-12-13 20:15:29 +0000633 /* IPv6 connection. */
634 if (local->sa.sa_family == AF_INET6)
635 {
636 struct interface *direct = NULL;
637
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000638 /* IPv4 nexthop. */
639 ret = if_get_ipv4_address(ifp, &nexthop->v4);
640 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000641 nexthop->v4 = peer->local_id;
642
643 /* Global address*/
644 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
645 {
646 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
647 IPV6_MAX_BYTELEN);
648
649 /* If directory connected set link-local address. */
650 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
651 if (direct)
652 if_get_ipv6_local (ifp, &nexthop->v6_local);
653 }
654 else
655 /* Link-local address. */
656 {
657 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
658
659 /* If there is no global address. Set link-local address as
660 global. I know this break RFC specification... */
661 if (!ret)
662 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
663 IPV6_MAX_BYTELEN);
664 else
665 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
666 IPV6_MAX_BYTELEN);
667 }
668 }
669
670 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
671 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
672 peer->shared_network = 1;
673 else
674 peer->shared_network = 0;
675
676 /* KAME stack specific treatment. */
677#ifdef KAME
678 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
679 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
680 {
681 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
682 }
683 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
684 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
685 {
686 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
687 }
688#endif /* KAME */
paul718e3742002-12-13 20:15:29 +0000689 return ret;
690}
691
paul718e3742002-12-13 20:15:29 +0000692void
G.Balaji5a616c02011-11-26 21:58:42 +0400693bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000694{
695 int flags;
696 u_char distance;
697 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700698 struct bgp_info *mpinfo;
699 size_t oldsize, newsize;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500700 u_int32_t nhcount;
Paul Jakma96d10602016-07-01 14:23:45 +0100701 route_tag_t tag = 0;
paul718e3742002-12-13 20:15:29 +0000702
703 if (zclient->sock < 0)
704 return;
705
Feng Luc99f3482014-10-16 09:52:36 +0800706 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000707 return;
708
709 flags = 0;
710 peer = info->peer;
711
Piotr Chytła605aa332015-12-01 10:03:54 -0500712 if ((info->attr->extra) && (info->attr->extra->tag != 0))
713 tag = info->attr->extra->tag;
714
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000715 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000716 {
717 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
718 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
719 }
720
Timo Teräse3443a22016-10-19 16:02:34 +0300721 if ((peer->sort == BGP_PEER_EBGP && peer_ttl (peer) != 1)
hasso6ffd2072005-02-02 14:50:11 +0000722 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000723 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
724
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500725 nhcount = 1 + bgp_info_mpath_count (info);
Josh Bailey8196f132011-07-20 20:47:07 -0700726
paul718e3742002-12-13 20:15:29 +0000727 if (p->family == AF_INET)
728 {
729 struct zapi_ipv4 api;
730 struct in_addr *nexthop;
731
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500732 /* resize nexthop buffer size if necessary */
733 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
734 (sizeof (struct in_addr *) * nhcount))
735 {
736 newsize = (sizeof (struct in_addr *) * nhcount);
737 newsize = stream_resize (bgp_nexthop_buf, newsize);
738 if (newsize == oldsize)
739 {
740 zlog_err ("can't resize nexthop buffer");
741 return;
742 }
743 }
744 stream_reset (bgp_nexthop_buf);
745
Feng Luc99f3482014-10-16 09:52:36 +0800746 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000747 api.flags = flags;
748 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700749 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
750 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
751 mpinfo = bgp_info_mpath_next (mpinfo))
752 {
753 nexthop = &mpinfo->attr->nexthop;
754 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
755 }
paul718e3742002-12-13 20:15:29 +0000756
757 api.type = ZEBRA_ROUTE_BGP;
758 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400759 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000760 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500761 api.nexthop_num = nhcount;
Josh Bailey8196f132011-07-20 20:47:07 -0700762 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000763 api.ifindex_num = 0;
764 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
765 api.metric = info->attr->med;
766
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500767 if (tag)
Piotr Chytła605aa332015-12-01 10:03:54 -0500768 {
769 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
770 api.tag = tag;
771 }
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500772
paul718e3742002-12-13 20:15:29 +0000773 distance = bgp_distance_apply (p, info, bgp);
774
775 if (distance)
776 {
777 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
778 api.distance = distance;
779 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000780
781 if (BGP_DEBUG(zebra, ZEBRA))
782 {
Josh Bailey8196f132011-07-20 20:47:07 -0700783 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000784 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700785 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500786 " tag %u count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000787 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
788 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700789 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500790 api.metric, api.tag, api.nexthop_num);
Josh Bailey8196f132011-07-20 20:47:07 -0700791 for (i = 1; i < api.nexthop_num; i++)
792 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
793 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
794 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000795 }
796
paul0a589352004-05-08 11:48:26 +0000797 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
798 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000799 }
Lou Berger205e6742016-01-12 13:42:11 -0500800
paul718e3742002-12-13 20:15:29 +0000801 /* We have to think about a IPv6 link-local address curse. */
802 if (p->family == AF_INET6)
803 {
Paul Jakma9099f9b2016-01-18 10:12:10 +0000804 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000805 struct in6_addr *nexthop;
806 struct zapi_ipv6 api;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500807 int valid_nh_count = 0;
808
809 /* resize nexthop buffer size if necessary */
810 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
811 (sizeof (struct in6_addr *) * nhcount))
812 {
813 newsize = (sizeof (struct in6_addr *) * nhcount);
814 newsize = stream_resize (bgp_nexthop_buf, newsize);
815 if (newsize == oldsize)
816 {
817 zlog_err ("can't resize nexthop buffer");
818 return;
819 }
820 }
821 stream_reset (bgp_nexthop_buf);
822
823 /* resize ifindices buffer size if necessary */
824 if ((oldsize = stream_get_size (bgp_ifindices_buf)) <
825 (sizeof (unsigned int) * nhcount))
826 {
827 newsize = (sizeof (unsigned int) * nhcount);
828 newsize = stream_resize (bgp_ifindices_buf, newsize);
829 if (newsize == oldsize)
830 {
831 zlog_err ("can't resize nexthop buffer");
832 return;
833 }
834 }
835 stream_reset (bgp_ifindices_buf);
paul718e3742002-12-13 20:15:29 +0000836
837 ifindex = 0;
838 nexthop = NULL;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500839
Paul Jakmafb982c22007-05-04 20:15:47 +0000840 assert (info->attr->extra);
841
paul718e3742002-12-13 20:15:29 +0000842 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000843 if (info->attr->extra->mp_nexthop_len == 16)
844 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000845
846 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000847 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000848 {
849 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000850 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000851 && peer->su_remote->sa.sa_family == AF_INET6)
852 nexthop = &peer->su_remote->sin6.sin6_addr;
853 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000854 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000855
856 if (info->peer->nexthop.ifp)
857 ifindex = info->peer->nexthop.ifp->ifindex;
858 }
859
860 if (nexthop == NULL)
861 return;
862
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500863 if (!ifindex)
paul718e3742002-12-13 20:15:29 +0000864 {
865 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200866 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000867 else if (info->peer->nexthop.ifp)
868 ifindex = info->peer->nexthop.ifp->ifindex;
869 }
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500870 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
871 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
872 valid_nh_count++;
873
874 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
875 mpinfo = bgp_info_mpath_next (mpinfo))
876 {
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500877 ifindex = 0;
878
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500879 /* Only global address nexthop exists. */
880 if (mpinfo->attr->extra->mp_nexthop_len == 16)
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500881 nexthop = &mpinfo->attr->extra->mp_nexthop_global;
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500882
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500883 /* If both global and link-local address present. */
884 if (mpinfo->attr->extra->mp_nexthop_len == 32)
885 {
886 /* Workaround for Cisco's nexthop bug. */
887 if (IN6_IS_ADDR_UNSPECIFIED (&mpinfo->attr->extra->mp_nexthop_global)
888 && mpinfo->peer->su_remote->sa.sa_family == AF_INET6)
889 {
890 nexthop = &mpinfo->peer->su_remote->sin6.sin6_addr;
891 }
892 else
893 {
894 nexthop = &mpinfo->attr->extra->mp_nexthop_local;
895 }
896
897 if (mpinfo->peer->nexthop.ifp)
898 {
899 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
900 }
901 }
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500902
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500903 if (nexthop == NULL)
904 {
905 continue;
906 }
907
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500908 if (!ifindex)
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500909 {
910 if (mpinfo->peer->ifname)
911 {
912 ifindex = if_nametoindex (mpinfo->peer->ifname);
913 }
914 else if (mpinfo->peer->nexthop.ifp)
915 {
916 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
917 }
918 }
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500919
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500920 if (ifindex == 0)
921 {
922 continue;
923 }
924
925 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
926 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
927 valid_nh_count++;
928 }
paul718e3742002-12-13 20:15:29 +0000929
930 /* Make Zebra API structure. */
Feng Luc99f3482014-10-16 09:52:36 +0800931 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000932 api.flags = flags;
933 api.type = ZEBRA_ROUTE_BGP;
934 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400935 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000936 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500937 api.nexthop_num = valid_nh_count;
938 api.nexthop = (struct in6_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000939 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500940 api.ifindex_num = valid_nh_count;
941 api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf);
paul718e3742002-12-13 20:15:29 +0000942 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
943 api.metric = info->attr->med;
944
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100945 distance = ipv6_bgp_distance_apply (p, info, bgp);
946
947 if (distance)
948 {
949 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
950 api.distance = distance;
951 }
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500952
953 if (tag)
954 {
955 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
956 api.tag = tag;
957 }
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100958
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000959 if (BGP_DEBUG(zebra, ZEBRA))
960 {
961 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500962 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u"
963 " tag %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000964 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
965 p->prefixlen,
966 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500967 api.metric, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000968 }
969
paul0a589352004-05-08 11:48:26 +0000970 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
971 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000972 }
paul718e3742002-12-13 20:15:29 +0000973}
974
975void
G.Balaji5a616c02011-11-26 21:58:42 +0400976bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000977{
978 int flags;
979 struct peer *peer;
980
981 if (zclient->sock < 0)
982 return;
983
Feng Luc99f3482014-10-16 09:52:36 +0800984 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000985 return;
986
987 peer = info->peer;
988 flags = 0;
989
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000990 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000991 {
992 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
993 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
994 }
995
Timo Teräse3443a22016-10-19 16:02:34 +0300996 if ((peer->sort == BGP_PEER_EBGP && peer_ttl (peer) != 1)
hasso6ffd2072005-02-02 14:50:11 +0000997 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000998 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
999
1000 if (p->family == AF_INET)
1001 {
1002 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +00001003
Feng Luc99f3482014-10-16 09:52:36 +08001004 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +00001005 api.flags = flags;
paul718e3742002-12-13 20:15:29 +00001006
1007 api.type = ZEBRA_ROUTE_BGP;
1008 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +04001009 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +00001010 api.nexthop_num = 0;
paul718e3742002-12-13 20:15:29 +00001011 api.ifindex_num = 0;
1012 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1013 api.metric = info->attr->med;
1014
Piotr Chytła605aa332015-12-01 10:03:54 -05001015 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1016 {
1017 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1018 api.tag = info->attr->extra->tag;
1019 }
1020
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001021 if (BGP_DEBUG(zebra, ZEBRA))
1022 {
1023 char buf[2][INET_ADDRSTRLEN];
Piotr Chytła605aa332015-12-01 10:03:54 -05001024 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001025 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
1026 p->prefixlen,
Piotr Chytła605aa332015-12-01 10:03:54 -05001027 api.metric,
1028 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001029 }
1030
paul0a589352004-05-08 11:48:26 +00001031 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
1032 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +00001033 }
Lou Berger205e6742016-01-12 13:42:11 -05001034
paul718e3742002-12-13 20:15:29 +00001035 /* We have to think about a IPv6 link-local address curse. */
1036 if (p->family == AF_INET6)
1037 {
1038 struct zapi_ipv6 api;
Paul Jakmafb982c22007-05-04 20:15:47 +00001039
Feng Luc99f3482014-10-16 09:52:36 +08001040 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +00001041 api.flags = flags;
1042 api.type = ZEBRA_ROUTE_BGP;
1043 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +04001044 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +00001045 api.nexthop_num = 0;
1046 api.ifindex_num = 0;
paul718e3742002-12-13 20:15:29 +00001047 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1048 api.metric = info->attr->med;
1049
Piotr Chytła605aa332015-12-01 10:03:54 -05001050 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1051 {
1052 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1053 api.tag = info->attr->extra->tag;
1054 }
1055
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001056 if (BGP_DEBUG(zebra, ZEBRA))
1057 {
1058 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytła605aa332015-12-01 10:03:54 -05001059 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001060 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
1061 p->prefixlen,
Piotr Chytła605aa332015-12-01 10:03:54 -05001062 api.metric,
1063 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001064 }
1065
paul0a589352004-05-08 11:48:26 +00001066 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
1067 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +00001068 }
paul718e3742002-12-13 20:15:29 +00001069}
David Lamparter6b0655a2014-06-04 06:53:35 +02001070
paul718e3742002-12-13 20:15:29 +00001071/* Other routes redistribution into BGP. */
1072int
1073bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
1074{
1075 /* Set flag to BGP instance. */
1076 bgp->redist[afi][type] = 1;
1077
1078 /* Return if already redistribute flag is set. */
Feng Luc99f3482014-10-16 09:52:36 +08001079 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001080 return CMD_WARNING;
1081
Feng Luc99f3482014-10-16 09:52:36 +08001082 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001083
1084 /* Return if zebra connection is not established. */
1085 if (zclient->sock < 0)
1086 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001087
1088 if (BGP_DEBUG(zebra, ZEBRA))
1089 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +00001090
1091 /* Send distribute add message to zebra. */
Feng Luc99f3482014-10-16 09:52:36 +08001092 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001093
1094 return CMD_SUCCESS;
1095}
1096
1097/* Redistribute with route-map specification. */
1098int
paulfd79ac92004-10-13 05:06:08 +00001099bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
1100 const char *name)
paul718e3742002-12-13 20:15:29 +00001101{
1102 if (bgp->rmap[afi][type].name
1103 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
1104 return 0;
1105
1106 if (bgp->rmap[afi][type].name)
1107 free (bgp->rmap[afi][type].name);
1108 bgp->rmap[afi][type].name = strdup (name);
1109 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
1110
1111 return 1;
1112}
1113
1114/* Redistribute with metric specification. */
1115int
1116bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
1117 u_int32_t metric)
1118{
1119 if (bgp->redist_metric_flag[afi][type]
1120 && bgp->redist_metric[afi][type] == metric)
1121 return 0;
1122
1123 bgp->redist_metric_flag[afi][type] = 1;
1124 bgp->redist_metric[afi][type] = metric;
1125
1126 return 1;
1127}
1128
1129/* Unset redistribution. */
1130int
1131bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
1132{
1133 /* Unset flag from BGP instance. */
1134 bgp->redist[afi][type] = 0;
1135
1136 /* Unset route-map. */
1137 if (bgp->rmap[afi][type].name)
1138 free (bgp->rmap[afi][type].name);
1139 bgp->rmap[afi][type].name = NULL;
1140 bgp->rmap[afi][type].map = NULL;
1141
1142 /* Unset metric. */
1143 bgp->redist_metric_flag[afi][type] = 0;
1144 bgp->redist_metric[afi][type] = 0;
1145
1146 /* Return if zebra connection is disabled. */
Feng Luc99f3482014-10-16 09:52:36 +08001147 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001148 return CMD_WARNING;
Feng Luc99f3482014-10-16 09:52:36 +08001149 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001150
1151 if (bgp->redist[AFI_IP][type] == 0
1152 && bgp->redist[AFI_IP6][type] == 0
1153 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001154 {
1155 /* Send distribute delete message to zebra. */
1156 if (BGP_DEBUG(zebra, ZEBRA))
1157 zlog_debug("Zebra send: redistribute delete %s",
1158 zebra_route_string(type));
Feng Luc99f3482014-10-16 09:52:36 +08001159 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
1160 VRF_DEFAULT);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001161 }
paul718e3742002-12-13 20:15:29 +00001162
1163 /* Withdraw redistributed routes from current BGP's routing table. */
1164 bgp_redistribute_withdraw (bgp, afi, type);
1165
1166 return CMD_SUCCESS;
1167}
1168
paul718e3742002-12-13 20:15:29 +00001169void
paul94f2b392005-06-28 12:44:16 +00001170bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001171{
1172 zclient_reset (zclient);
1173}
1174
Feng Luc99f3482014-10-16 09:52:36 +08001175static void
1176bgp_zebra_connected (struct zclient *zclient)
1177{
Lou Berger68bfb612016-10-06 09:59:32 -04001178 zclient_num_connects++;
Feng Luc99f3482014-10-16 09:52:36 +08001179 zclient_send_requests (zclient, VRF_DEFAULT);
1180}
1181
paul718e3742002-12-13 20:15:29 +00001182void
Donald Sharp71252932015-09-24 09:25:19 -04001183bgp_zebra_init (struct thread_master *master)
paul718e3742002-12-13 20:15:29 +00001184{
Lou Berger68bfb612016-10-06 09:59:32 -04001185 zclient_num_connects = 0;
1186
paul718e3742002-12-13 20:15:29 +00001187 /* Set default values. */
Donald Sharp71252932015-09-24 09:25:19 -04001188 zclient = zclient_new (master);
paul718e3742002-12-13 20:15:29 +00001189 zclient_init (zclient, ZEBRA_ROUTE_BGP);
Feng Luc99f3482014-10-16 09:52:36 +08001190 zclient->zebra_connected = bgp_zebra_connected;
hasso18a6dce2004-10-03 18:18:34 +00001191 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001192 zclient->interface_add = bgp_interface_add;
1193 zclient->interface_delete = bgp_interface_delete;
1194 zclient->interface_address_add = bgp_interface_address_add;
1195 zclient->interface_address_delete = bgp_interface_address_delete;
1196 zclient->ipv4_route_add = zebra_read_ipv4;
1197 zclient->ipv4_route_delete = zebra_read_ipv4;
1198 zclient->interface_up = bgp_interface_up;
1199 zclient->interface_down = bgp_interface_down;
paul718e3742002-12-13 20:15:29 +00001200 zclient->ipv6_route_add = zebra_read_ipv6;
1201 zclient->ipv6_route_delete = zebra_read_ipv6;
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001202 zclient->nexthop_update = bgp_read_nexthop_update;
paul718e3742002-12-13 20:15:29 +00001203
Josh Bailey8196f132011-07-20 20:47:07 -07001204 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -05001205 bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001206}
Lou Berger82dd7072016-01-12 13:41:57 -05001207
1208void
1209bgp_zebra_destroy(void)
1210{
1211 if (zclient == NULL)
1212 return;
1213 zclient_stop(zclient);
1214 zclient_free(zclient);
1215 zclient = NULL;
1216}
Lou Berger68bfb612016-10-06 09:59:32 -04001217
1218int
1219bgp_zebra_num_connects(void)
1220{
1221 return zclient_num_connects;
1222}