blob: 38fecd9f24921925e81e1d41464aa3060f33e086 [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
hasso18a6dce2004-10-03 18:18:34 +000053/* Router-id update message from zebra. */
paul94f2b392005-06-28 12:44:16 +000054static int
Feng Luc99f3482014-10-16 09:52:36 +080055bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
56 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000057{
hasso18a6dce2004-10-03 18:18:34 +000058 struct prefix router_id;
paul718e3742002-12-13 20:15:29 +000059
hasso18a6dce2004-10-03 18:18:34 +000060 zebra_router_id_update_read(zclient->ibuf,&router_id);
Andrew J. Schorra39275d2006-11-30 16:36:57 +000061
62 if (BGP_DEBUG(zebra, ZEBRA))
63 {
64 char buf[128];
65 prefix2str(&router_id, buf, sizeof(buf));
66 zlog_debug("Zebra rcvd: router id update %s", buf);
67 }
68
hasso18a6dce2004-10-03 18:18:34 +000069 router_id_zebra = router_id.u.prefix4;
70
David Lamparter584083d2016-05-24 18:58:08 +020071 bgp_router_id_zebra_bump ();
paul718e3742002-12-13 20:15:29 +000072 return 0;
73}
74
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -050075/* Nexthop update message from zebra. */
76static int
77bgp_read_nexthop_update (int command, struct zclient *zclient,
78 zebra_size_t length, vrf_id_t vrf_id)
79{
80 bgp_parse_nexthop_update();
81 return 0;
82}
83
paul718e3742002-12-13 20:15:29 +000084/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000085static int
Feng Luc99f3482014-10-16 09:52:36 +080086bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
87 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000088{
89 struct interface *ifp;
90
Feng Luc99f3482014-10-16 09:52:36 +080091 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +000092
Andrew J. Schorra39275d2006-11-30 16:36:57 +000093 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
94 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
95
paul718e3742002-12-13 20:15:29 +000096 return 0;
97}
98
paul94f2b392005-06-28 12:44:16 +000099static int
paul718e3742002-12-13 20:15:29 +0000100bgp_interface_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800101 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000102{
103 struct stream *s;
104 struct interface *ifp;
105
106 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800107 ifp = zebra_interface_state_read (s, vrf_id);
ajsd2fc8892005-04-02 18:38:43 +0000108 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000109
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000110 if (BGP_DEBUG(zebra, ZEBRA))
111 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
112
paul718e3742002-12-13 20:15:29 +0000113 return 0;
114}
115
paul94f2b392005-06-28 12:44:16 +0000116static int
Feng Luc99f3482014-10-16 09:52:36 +0800117bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
118 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000119{
120 struct stream *s;
121 struct interface *ifp;
122 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000123 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000124
125 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800126 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000127
128 if (! ifp)
129 return 0;
130
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000131 if (BGP_DEBUG(zebra, ZEBRA))
132 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
133
paul1eb8ef22005-04-07 07:30:20 +0000134 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
135 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000136
137 return 0;
138}
139
paul94f2b392005-06-28 12:44:16 +0000140static int
Feng Luc99f3482014-10-16 09:52:36 +0800141bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
142 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000143{
144 struct stream *s;
145 struct interface *ifp;
146 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000147 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000148
149 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800150 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000151 if (! ifp)
152 return 0;
153
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000154 if (BGP_DEBUG(zebra, ZEBRA))
155 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
156
paul1eb8ef22005-04-07 07:30:20 +0000157 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
158 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000159
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000160 /* Fast external-failover */
paul718e3742002-12-13 20:15:29 +0000161 {
paul1eb8ef22005-04-07 07:30:20 +0000162 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000163 struct bgp *bgp;
164 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000165
paul1eb8ef22005-04-07 07:30:20 +0000166 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000167 {
168 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
169 continue;
170
paul1eb8ef22005-04-07 07:30:20 +0000171 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000172 {
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000173 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
paul718e3742002-12-13 20:15:29 +0000174 continue;
175
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000176 if (ifp == peer->nexthop.ifp)
paul718e3742002-12-13 20:15:29 +0000177 BGP_EVENT_ADD (peer, BGP_Stop);
178 }
179 }
180 }
181
182 return 0;
183}
184
paul94f2b392005-06-28 12:44:16 +0000185static int
paul718e3742002-12-13 20:15:29 +0000186bgp_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800187 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000188{
189 struct connected *ifc;
190
Feng Luc99f3482014-10-16 09:52:36 +0800191 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000192
193 if (ifc == NULL)
194 return 0;
195
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000196 if (BGP_DEBUG(zebra, ZEBRA))
197 {
198 char buf[128];
199 prefix2str(ifc->address, buf, sizeof(buf));
200 zlog_debug("Zebra rcvd: interface %s address add %s",
201 ifc->ifp->name, buf);
202 }
203
paul2e3b2e42002-12-13 21:03:13 +0000204 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000205 bgp_connected_add (ifc);
206
207 return 0;
208}
209
paul94f2b392005-06-28 12:44:16 +0000210static int
paul718e3742002-12-13 20:15:29 +0000211bgp_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800212 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000213{
214 struct connected *ifc;
215
Feng Luc99f3482014-10-16 09:52:36 +0800216 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000217
218 if (ifc == NULL)
219 return 0;
220
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000221 if (BGP_DEBUG(zebra, ZEBRA))
222 {
223 char buf[128];
224 prefix2str(ifc->address, buf, sizeof(buf));
225 zlog_debug("Zebra rcvd: interface %s address delete %s",
226 ifc->ifp->name, buf);
227 }
228
paul2e3b2e42002-12-13 21:03:13 +0000229 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000230 bgp_connected_delete (ifc);
231
232 connected_free (ifc);
233
234 return 0;
235}
236
237/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000238static int
Feng Luc99f3482014-10-16 09:52:36 +0800239zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
240 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000241{
242 struct stream *s;
243 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000244 struct in_addr nexthop;
245 struct prefix_ipv4 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500246 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000247
248 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000249 nexthop.s_addr = 0;
250
251 /* Type, flags, message. */
252 api.type = stream_getc (s);
253 api.flags = stream_getc (s);
254 api.message = stream_getc (s);
255
256 /* IPv4 prefix. */
257 memset (&p, 0, sizeof (struct prefix_ipv4));
258 p.family = AF_INET;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500259 plength = stream_getc (s);
260 p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000261 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
262
263 /* Nexthop, ifindex, distance, metric. */
264 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
265 {
266 api.nexthop_num = stream_getc (s);
267 nexthop.s_addr = stream_get_ipv4 (s);
268 }
269 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
270 {
271 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400272 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000273 }
274 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
275 api.distance = stream_getc (s);
276 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
277 api.metric = stream_getl (s);
278 else
279 api.metric = 0;
280
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500281 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
Paul Jakma96d10602016-07-01 14:23:45 +0100282 api.tag = stream_getl (s);
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500283 else
284 api.tag = 0;
285
paul718e3742002-12-13 20:15:29 +0000286 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000287 {
288 if (BGP_DEBUG(zebra, ZEBRA))
289 {
290 char buf[2][INET_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500291 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000292 zebra_route_string(api.type),
293 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
294 p.prefixlen,
295 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500296 api.metric,
297 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000298 }
Piotr Chytła605aa332015-12-01 10:03:54 -0500299 bgp_redistribute_add ((struct prefix *)&p, &nexthop, NULL,
300 api.metric, api.type, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000301 }
paul718e3742002-12-13 20:15:29 +0000302 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000303 {
304 if (BGP_DEBUG(zebra, ZEBRA))
305 {
306 char buf[2][INET_ADDRSTRLEN];
307 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500308 "nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000309 zebra_route_string(api.type),
310 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
311 p.prefixlen,
312 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500313 api.metric,
314 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000315 }
316 bgp_redistribute_delete((struct prefix *)&p, api.type);
317 }
paul718e3742002-12-13 20:15:29 +0000318
319 return 0;
320}
321
paul718e3742002-12-13 20:15:29 +0000322/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000323static int
Feng Luc99f3482014-10-16 09:52:36 +0800324zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
325 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000326{
327 struct stream *s;
328 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000329 struct in6_addr nexthop;
330 struct prefix_ipv6 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500331 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000332
333 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000334 memset (&nexthop, 0, sizeof (struct in6_addr));
335
336 /* Type, flags, message. */
337 api.type = stream_getc (s);
338 api.flags = stream_getc (s);
339 api.message = stream_getc (s);
340
341 /* IPv6 prefix. */
342 memset (&p, 0, sizeof (struct prefix_ipv6));
343 p.family = AF_INET6;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500344 plength = stream_getc (s);
345 p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000346 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
347
348 /* Nexthop, ifindex, distance, metric. */
349 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
350 {
351 api.nexthop_num = stream_getc (s);
352 stream_get (&nexthop, s, 16);
353 }
354 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
355 {
356 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400357 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000358 }
359 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
360 api.distance = stream_getc (s);
361 else
362 api.distance = 0;
363 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
364 api.metric = stream_getl (s);
365 else
366 api.metric = 0;
367
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500368 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
Paul Jakma96d10602016-07-01 14:23:45 +0100369 api.tag = stream_getl (s);
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500370 else
371 api.tag = 0;
372
paul718e3742002-12-13 20:15:29 +0000373 /* Simply ignore link-local address. */
374 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
375 return 0;
376
377 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000378 {
379 if (BGP_DEBUG(zebra, ZEBRA))
380 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400381 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500382 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000383 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400384 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
385 p.prefixlen,
386 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500387 api.metric,
388 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000389 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400390 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
Piotr Chytła605aa332015-12-01 10:03:54 -0500391 api.metric, api.type, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000392 }
paul718e3742002-12-13 20:15:29 +0000393 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000394 {
395 if (BGP_DEBUG(zebra, ZEBRA))
396 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400397 char buf[2][INET6_ADDRSTRLEN];
398 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500399 "nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000400 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400401 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
402 p.prefixlen,
403 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500404 api.metric,
405 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000406 }
407 bgp_redistribute_delete ((struct prefix *) &p, api.type);
408 }
paul718e3742002-12-13 20:15:29 +0000409
410 return 0;
411}
David Lamparter6b0655a2014-06-04 06:53:35 +0200412
paul718e3742002-12-13 20:15:29 +0000413struct interface *
414if_lookup_by_ipv4 (struct in_addr *addr)
415{
hasso52dc7ee2004-09-23 19:18:23 +0000416 struct listnode *ifnode;
417 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000418 struct interface *ifp;
419 struct connected *connected;
420 struct prefix_ipv4 p;
421 struct prefix *cp;
422
423 p.family = AF_INET;
424 p.prefix = *addr;
425 p.prefixlen = IPV4_MAX_BITLEN;
426
paul1eb8ef22005-04-07 07:30:20 +0000427 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000428 {
paul1eb8ef22005-04-07 07:30:20 +0000429 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000430 {
paul718e3742002-12-13 20:15:29 +0000431 cp = connected->address;
432
433 if (cp->family == AF_INET)
434 if (prefix_match (cp, (struct prefix *)&p))
435 return ifp;
436 }
437 }
438 return NULL;
439}
440
441struct interface *
442if_lookup_by_ipv4_exact (struct in_addr *addr)
443{
hasso52dc7ee2004-09-23 19:18:23 +0000444 struct listnode *ifnode;
445 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000446 struct interface *ifp;
447 struct connected *connected;
448 struct prefix *cp;
449
paul1eb8ef22005-04-07 07:30:20 +0000450 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000451 {
paul1eb8ef22005-04-07 07:30:20 +0000452 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000453 {
paul718e3742002-12-13 20:15:29 +0000454 cp = connected->address;
455
456 if (cp->family == AF_INET)
457 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
458 return ifp;
459 }
460 }
461 return NULL;
462}
463
paul718e3742002-12-13 20:15:29 +0000464struct interface *
465if_lookup_by_ipv6 (struct in6_addr *addr)
466{
hasso52dc7ee2004-09-23 19:18:23 +0000467 struct listnode *ifnode;
468 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000469 struct interface *ifp;
470 struct connected *connected;
471 struct prefix_ipv6 p;
472 struct prefix *cp;
473
474 p.family = AF_INET6;
475 p.prefix = *addr;
476 p.prefixlen = IPV6_MAX_BITLEN;
477
paul1eb8ef22005-04-07 07:30:20 +0000478 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000479 {
paul1eb8ef22005-04-07 07:30:20 +0000480 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000481 {
paul718e3742002-12-13 20:15:29 +0000482 cp = connected->address;
483
484 if (cp->family == AF_INET6)
485 if (prefix_match (cp, (struct prefix *)&p))
486 return ifp;
487 }
488 }
489 return NULL;
490}
491
492struct interface *
493if_lookup_by_ipv6_exact (struct in6_addr *addr)
494{
hasso52dc7ee2004-09-23 19:18:23 +0000495 struct listnode *ifnode;
496 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000497 struct interface *ifp;
498 struct connected *connected;
499 struct prefix *cp;
500
paul1eb8ef22005-04-07 07:30:20 +0000501 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000502 {
paul1eb8ef22005-04-07 07:30:20 +0000503 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000504 {
paul718e3742002-12-13 20:15:29 +0000505 cp = connected->address;
506
507 if (cp->family == AF_INET6)
508 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
509 return ifp;
510 }
511 }
512 return NULL;
513}
514
paul94f2b392005-06-28 12:44:16 +0000515static int
paul718e3742002-12-13 20:15:29 +0000516if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
517{
hasso52dc7ee2004-09-23 19:18:23 +0000518 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000519 struct connected *connected;
520 struct prefix *cp;
521
paul1eb8ef22005-04-07 07:30:20 +0000522 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000523 {
paul718e3742002-12-13 20:15:29 +0000524 cp = connected->address;
525
526 if (cp->family == AF_INET6)
527 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
528 {
529 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
530 return 1;
531 }
532 }
533 return 0;
534}
535
paul94f2b392005-06-28 12:44:16 +0000536static int
paul718e3742002-12-13 20:15:29 +0000537if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
538{
hasso52dc7ee2004-09-23 19:18:23 +0000539 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000540 struct connected *connected;
541 struct prefix *cp;
542
paul1eb8ef22005-04-07 07:30:20 +0000543 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000544 {
paul718e3742002-12-13 20:15:29 +0000545 cp = connected->address;
546
547 if (cp->family == AF_INET6)
548 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
549 {
550 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
551 return 1;
552 }
553 }
554 return 0;
555}
paul718e3742002-12-13 20:15:29 +0000556
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000557static int
558if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
559{
560 struct listnode *cnode;
561 struct connected *connected;
562 struct prefix *cp;
563
564 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
565 {
566 cp = connected->address;
567 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
568 {
569 *addr = cp->u.prefix4;
570 return 1;
571 }
572 }
573 return 0;
574}
575
paul718e3742002-12-13 20:15:29 +0000576int
577bgp_nexthop_set (union sockunion *local, union sockunion *remote,
578 struct bgp_nexthop *nexthop, struct peer *peer)
579{
580 int ret = 0;
581 struct interface *ifp = NULL;
582
583 memset (nexthop, 0, sizeof (struct bgp_nexthop));
584
585 if (!local)
586 return -1;
587 if (!remote)
588 return -1;
589
590 if (local->sa.sa_family == AF_INET)
591 {
592 nexthop->v4 = local->sin.sin_addr;
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700593 if (peer->update_if)
594 ifp = if_lookup_by_name (peer->update_if);
595 else
596 ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr);
paul718e3742002-12-13 20:15:29 +0000597 }
paul718e3742002-12-13 20:15:29 +0000598 if (local->sa.sa_family == AF_INET6)
599 {
600 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
601 {
602 if (peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200603 ifp = if_lookup_by_name (peer->ifname);
paul718e3742002-12-13 20:15:29 +0000604 }
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700605 else if (peer->update_if)
606 ifp = if_lookup_by_name (peer->update_if);
paul718e3742002-12-13 20:15:29 +0000607 else
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700608 ifp = if_lookup_by_ipv6_exact (&local->sin6.sin6_addr);
paul718e3742002-12-13 20:15:29 +0000609 }
paul718e3742002-12-13 20:15:29 +0000610
611 if (!ifp)
612 return -1;
613
614 nexthop->ifp = ifp;
615
616 /* IPv4 connection. */
617 if (local->sa.sa_family == AF_INET)
618 {
paul718e3742002-12-13 20:15:29 +0000619 /* IPv6 nexthop*/
620 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
621
622 /* There is no global nexthop. */
623 if (!ret)
624 if_get_ipv6_local (ifp, &nexthop->v6_global);
625 else
626 if_get_ipv6_local (ifp, &nexthop->v6_local);
paul718e3742002-12-13 20:15:29 +0000627 }
628
paul718e3742002-12-13 20:15:29 +0000629 /* IPv6 connection. */
630 if (local->sa.sa_family == AF_INET6)
631 {
632 struct interface *direct = NULL;
633
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000634 /* IPv4 nexthop. */
635 ret = if_get_ipv4_address(ifp, &nexthop->v4);
636 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000637 nexthop->v4 = peer->local_id;
638
639 /* Global address*/
640 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
641 {
642 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
643 IPV6_MAX_BYTELEN);
644
645 /* If directory connected set link-local address. */
646 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
647 if (direct)
648 if_get_ipv6_local (ifp, &nexthop->v6_local);
649 }
650 else
651 /* Link-local address. */
652 {
653 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
654
655 /* If there is no global address. Set link-local address as
656 global. I know this break RFC specification... */
657 if (!ret)
658 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
659 IPV6_MAX_BYTELEN);
660 else
661 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
662 IPV6_MAX_BYTELEN);
663 }
664 }
665
666 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
667 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
668 peer->shared_network = 1;
669 else
670 peer->shared_network = 0;
671
672 /* KAME stack specific treatment. */
673#ifdef KAME
674 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
675 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
676 {
677 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
678 }
679 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
680 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
681 {
682 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
683 }
684#endif /* KAME */
paul718e3742002-12-13 20:15:29 +0000685 return ret;
686}
687
paul718e3742002-12-13 20:15:29 +0000688void
G.Balaji5a616c02011-11-26 21:58:42 +0400689bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000690{
691 int flags;
692 u_char distance;
693 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700694 struct bgp_info *mpinfo;
695 size_t oldsize, newsize;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500696 u_int32_t nhcount;
Paul Jakma96d10602016-07-01 14:23:45 +0100697 route_tag_t tag = 0;
paul718e3742002-12-13 20:15:29 +0000698
699 if (zclient->sock < 0)
700 return;
701
Feng Luc99f3482014-10-16 09:52:36 +0800702 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000703 return;
704
705 flags = 0;
706 peer = info->peer;
707
Piotr Chytła605aa332015-12-01 10:03:54 -0500708 if ((info->attr->extra) && (info->attr->extra->tag != 0))
709 tag = info->attr->extra->tag;
710
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000711 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000712 {
713 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
714 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
715 }
716
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000717 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000718 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000719 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
720
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500721 nhcount = 1 + bgp_info_mpath_count (info);
Josh Bailey8196f132011-07-20 20:47:07 -0700722
paul718e3742002-12-13 20:15:29 +0000723 if (p->family == AF_INET)
724 {
725 struct zapi_ipv4 api;
726 struct in_addr *nexthop;
727
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500728 /* resize nexthop buffer size if necessary */
729 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
730 (sizeof (struct in_addr *) * nhcount))
731 {
732 newsize = (sizeof (struct in_addr *) * nhcount);
733 newsize = stream_resize (bgp_nexthop_buf, newsize);
734 if (newsize == oldsize)
735 {
736 zlog_err ("can't resize nexthop buffer");
737 return;
738 }
739 }
740 stream_reset (bgp_nexthop_buf);
741
Feng Luc99f3482014-10-16 09:52:36 +0800742 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000743 api.flags = flags;
744 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700745 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
746 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
747 mpinfo = bgp_info_mpath_next (mpinfo))
748 {
749 nexthop = &mpinfo->attr->nexthop;
750 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
751 }
paul718e3742002-12-13 20:15:29 +0000752
753 api.type = ZEBRA_ROUTE_BGP;
754 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400755 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000756 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500757 api.nexthop_num = nhcount;
Josh Bailey8196f132011-07-20 20:47:07 -0700758 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000759 api.ifindex_num = 0;
760 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
761 api.metric = info->attr->med;
762
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500763 if (tag)
Piotr Chytła605aa332015-12-01 10:03:54 -0500764 {
765 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
766 api.tag = tag;
767 }
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500768
paul718e3742002-12-13 20:15:29 +0000769 distance = bgp_distance_apply (p, info, bgp);
770
771 if (distance)
772 {
773 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
774 api.distance = distance;
775 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000776
777 if (BGP_DEBUG(zebra, ZEBRA))
778 {
Josh Bailey8196f132011-07-20 20:47:07 -0700779 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000780 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700781 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500782 " tag %u count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000783 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
784 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700785 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500786 api.metric, api.tag, api.nexthop_num);
Josh Bailey8196f132011-07-20 20:47:07 -0700787 for (i = 1; i < api.nexthop_num; i++)
788 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
789 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
790 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000791 }
792
paul0a589352004-05-08 11:48:26 +0000793 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
794 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000795 }
Lou Berger205e6742016-01-12 13:42:11 -0500796
paul718e3742002-12-13 20:15:29 +0000797 /* We have to think about a IPv6 link-local address curse. */
798 if (p->family == AF_INET6)
799 {
Paul Jakma9099f9b2016-01-18 10:12:10 +0000800 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000801 struct in6_addr *nexthop;
802 struct zapi_ipv6 api;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500803 int valid_nh_count = 0;
804
805 /* resize nexthop buffer size if necessary */
806 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
807 (sizeof (struct in6_addr *) * nhcount))
808 {
809 newsize = (sizeof (struct in6_addr *) * nhcount);
810 newsize = stream_resize (bgp_nexthop_buf, newsize);
811 if (newsize == oldsize)
812 {
813 zlog_err ("can't resize nexthop buffer");
814 return;
815 }
816 }
817 stream_reset (bgp_nexthop_buf);
818
819 /* resize ifindices buffer size if necessary */
820 if ((oldsize = stream_get_size (bgp_ifindices_buf)) <
821 (sizeof (unsigned int) * nhcount))
822 {
823 newsize = (sizeof (unsigned int) * nhcount);
824 newsize = stream_resize (bgp_ifindices_buf, newsize);
825 if (newsize == oldsize)
826 {
827 zlog_err ("can't resize nexthop buffer");
828 return;
829 }
830 }
831 stream_reset (bgp_ifindices_buf);
paul718e3742002-12-13 20:15:29 +0000832
833 ifindex = 0;
834 nexthop = NULL;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500835
Paul Jakmafb982c22007-05-04 20:15:47 +0000836 assert (info->attr->extra);
837
paul718e3742002-12-13 20:15:29 +0000838 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000839 if (info->attr->extra->mp_nexthop_len == 16)
840 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000841
842 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000843 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000844 {
845 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000846 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000847 && peer->su_remote->sa.sa_family == AF_INET6)
848 nexthop = &peer->su_remote->sin6.sin6_addr;
849 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000850 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000851
852 if (info->peer->nexthop.ifp)
853 ifindex = info->peer->nexthop.ifp->ifindex;
854 }
855
856 if (nexthop == NULL)
857 return;
858
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500859 if (!ifindex)
paul718e3742002-12-13 20:15:29 +0000860 {
861 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200862 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000863 else if (info->peer->nexthop.ifp)
864 ifindex = info->peer->nexthop.ifp->ifindex;
865 }
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500866 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
867 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
868 valid_nh_count++;
869
870 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
871 mpinfo = bgp_info_mpath_next (mpinfo))
872 {
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500873 ifindex = 0;
874
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500875 /* Only global address nexthop exists. */
876 if (mpinfo->attr->extra->mp_nexthop_len == 16)
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500877 nexthop = &mpinfo->attr->extra->mp_nexthop_global;
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500878
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500879 /* If both global and link-local address present. */
880 if (mpinfo->attr->extra->mp_nexthop_len == 32)
881 {
882 /* Workaround for Cisco's nexthop bug. */
883 if (IN6_IS_ADDR_UNSPECIFIED (&mpinfo->attr->extra->mp_nexthop_global)
884 && mpinfo->peer->su_remote->sa.sa_family == AF_INET6)
885 {
886 nexthop = &mpinfo->peer->su_remote->sin6.sin6_addr;
887 }
888 else
889 {
890 nexthop = &mpinfo->attr->extra->mp_nexthop_local;
891 }
892
893 if (mpinfo->peer->nexthop.ifp)
894 {
895 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
896 }
897 }
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500898
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500899 if (nexthop == NULL)
900 {
901 continue;
902 }
903
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500904 if (!ifindex)
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500905 {
906 if (mpinfo->peer->ifname)
907 {
908 ifindex = if_nametoindex (mpinfo->peer->ifname);
909 }
910 else if (mpinfo->peer->nexthop.ifp)
911 {
912 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
913 }
914 }
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500915
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500916 if (ifindex == 0)
917 {
918 continue;
919 }
920
921 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
922 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
923 valid_nh_count++;
924 }
paul718e3742002-12-13 20:15:29 +0000925
926 /* Make Zebra API structure. */
Feng Luc99f3482014-10-16 09:52:36 +0800927 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000928 api.flags = flags;
929 api.type = ZEBRA_ROUTE_BGP;
930 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400931 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000932 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500933 api.nexthop_num = valid_nh_count;
934 api.nexthop = (struct in6_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000935 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500936 api.ifindex_num = valid_nh_count;
937 api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf);
paul718e3742002-12-13 20:15:29 +0000938 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
939 api.metric = info->attr->med;
940
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100941 distance = ipv6_bgp_distance_apply (p, info, bgp);
942
943 if (distance)
944 {
945 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
946 api.distance = distance;
947 }
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500948
949 if (tag)
950 {
951 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
952 api.tag = tag;
953 }
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100954
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000955 if (BGP_DEBUG(zebra, ZEBRA))
956 {
957 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500958 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u"
959 " tag %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000960 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
961 p->prefixlen,
962 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500963 api.metric, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000964 }
965
paul0a589352004-05-08 11:48:26 +0000966 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
967 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000968 }
paul718e3742002-12-13 20:15:29 +0000969}
970
971void
G.Balaji5a616c02011-11-26 21:58:42 +0400972bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000973{
974 int flags;
975 struct peer *peer;
976
977 if (zclient->sock < 0)
978 return;
979
Feng Luc99f3482014-10-16 09:52:36 +0800980 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000981 return;
982
983 peer = info->peer;
984 flags = 0;
985
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000986 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000987 {
988 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
989 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
990 }
991
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000992 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000993 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000994 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
995
996 if (p->family == AF_INET)
997 {
998 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000999
Feng Luc99f3482014-10-16 09:52:36 +08001000 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +00001001 api.flags = flags;
paul718e3742002-12-13 20:15:29 +00001002
1003 api.type = ZEBRA_ROUTE_BGP;
1004 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +04001005 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +00001006 api.nexthop_num = 0;
paul718e3742002-12-13 20:15:29 +00001007 api.ifindex_num = 0;
1008 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1009 api.metric = info->attr->med;
1010
Piotr Chytła605aa332015-12-01 10:03:54 -05001011 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1012 {
1013 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1014 api.tag = info->attr->extra->tag;
1015 }
1016
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001017 if (BGP_DEBUG(zebra, ZEBRA))
1018 {
1019 char buf[2][INET_ADDRSTRLEN];
Piotr Chytła605aa332015-12-01 10:03:54 -05001020 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001021 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
1022 p->prefixlen,
Piotr Chytła605aa332015-12-01 10:03:54 -05001023 api.metric,
1024 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001025 }
1026
paul0a589352004-05-08 11:48:26 +00001027 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
1028 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +00001029 }
Lou Berger205e6742016-01-12 13:42:11 -05001030
paul718e3742002-12-13 20:15:29 +00001031 /* We have to think about a IPv6 link-local address curse. */
1032 if (p->family == AF_INET6)
1033 {
1034 struct zapi_ipv6 api;
Paul Jakmafb982c22007-05-04 20:15:47 +00001035
Feng Luc99f3482014-10-16 09:52:36 +08001036 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +00001037 api.flags = flags;
1038 api.type = ZEBRA_ROUTE_BGP;
1039 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +04001040 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +00001041 api.nexthop_num = 0;
1042 api.ifindex_num = 0;
paul718e3742002-12-13 20:15:29 +00001043 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1044 api.metric = info->attr->med;
1045
Piotr Chytła605aa332015-12-01 10:03:54 -05001046 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1047 {
1048 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1049 api.tag = info->attr->extra->tag;
1050 }
1051
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001052 if (BGP_DEBUG(zebra, ZEBRA))
1053 {
1054 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytła605aa332015-12-01 10:03:54 -05001055 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001056 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
1057 p->prefixlen,
Piotr Chytła605aa332015-12-01 10:03:54 -05001058 api.metric,
1059 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001060 }
1061
paul0a589352004-05-08 11:48:26 +00001062 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
1063 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +00001064 }
paul718e3742002-12-13 20:15:29 +00001065}
David Lamparter6b0655a2014-06-04 06:53:35 +02001066
paul718e3742002-12-13 20:15:29 +00001067/* Other routes redistribution into BGP. */
1068int
1069bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
1070{
1071 /* Set flag to BGP instance. */
1072 bgp->redist[afi][type] = 1;
1073
1074 /* Return if already redistribute flag is set. */
Feng Luc99f3482014-10-16 09:52:36 +08001075 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001076 return CMD_WARNING;
1077
Feng Luc99f3482014-10-16 09:52:36 +08001078 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001079
1080 /* Return if zebra connection is not established. */
1081 if (zclient->sock < 0)
1082 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001083
1084 if (BGP_DEBUG(zebra, ZEBRA))
1085 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +00001086
1087 /* Send distribute add message to zebra. */
Feng Luc99f3482014-10-16 09:52:36 +08001088 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001089
1090 return CMD_SUCCESS;
1091}
1092
1093/* Redistribute with route-map specification. */
1094int
paulfd79ac92004-10-13 05:06:08 +00001095bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
1096 const char *name)
paul718e3742002-12-13 20:15:29 +00001097{
1098 if (bgp->rmap[afi][type].name
1099 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
1100 return 0;
1101
1102 if (bgp->rmap[afi][type].name)
1103 free (bgp->rmap[afi][type].name);
1104 bgp->rmap[afi][type].name = strdup (name);
1105 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
1106
1107 return 1;
1108}
1109
1110/* Redistribute with metric specification. */
1111int
1112bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
1113 u_int32_t metric)
1114{
1115 if (bgp->redist_metric_flag[afi][type]
1116 && bgp->redist_metric[afi][type] == metric)
1117 return 0;
1118
1119 bgp->redist_metric_flag[afi][type] = 1;
1120 bgp->redist_metric[afi][type] = metric;
1121
1122 return 1;
1123}
1124
1125/* Unset redistribution. */
1126int
1127bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
1128{
1129 /* Unset flag from BGP instance. */
1130 bgp->redist[afi][type] = 0;
1131
1132 /* Unset route-map. */
1133 if (bgp->rmap[afi][type].name)
1134 free (bgp->rmap[afi][type].name);
1135 bgp->rmap[afi][type].name = NULL;
1136 bgp->rmap[afi][type].map = NULL;
1137
1138 /* Unset metric. */
1139 bgp->redist_metric_flag[afi][type] = 0;
1140 bgp->redist_metric[afi][type] = 0;
1141
1142 /* Return if zebra connection is disabled. */
Feng Luc99f3482014-10-16 09:52:36 +08001143 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001144 return CMD_WARNING;
Feng Luc99f3482014-10-16 09:52:36 +08001145 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001146
1147 if (bgp->redist[AFI_IP][type] == 0
1148 && bgp->redist[AFI_IP6][type] == 0
1149 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001150 {
1151 /* Send distribute delete message to zebra. */
1152 if (BGP_DEBUG(zebra, ZEBRA))
1153 zlog_debug("Zebra send: redistribute delete %s",
1154 zebra_route_string(type));
Feng Luc99f3482014-10-16 09:52:36 +08001155 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
1156 VRF_DEFAULT);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001157 }
paul718e3742002-12-13 20:15:29 +00001158
1159 /* Withdraw redistributed routes from current BGP's routing table. */
1160 bgp_redistribute_withdraw (bgp, afi, type);
1161
1162 return CMD_SUCCESS;
1163}
1164
paul718e3742002-12-13 20:15:29 +00001165void
paul94f2b392005-06-28 12:44:16 +00001166bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001167{
1168 zclient_reset (zclient);
1169}
1170
Feng Luc99f3482014-10-16 09:52:36 +08001171static void
1172bgp_zebra_connected (struct zclient *zclient)
1173{
1174 zclient_send_requests (zclient, VRF_DEFAULT);
1175}
1176
paul718e3742002-12-13 20:15:29 +00001177void
Donald Sharp71252932015-09-24 09:25:19 -04001178bgp_zebra_init (struct thread_master *master)
paul718e3742002-12-13 20:15:29 +00001179{
1180 /* Set default values. */
Donald Sharp71252932015-09-24 09:25:19 -04001181 zclient = zclient_new (master);
paul718e3742002-12-13 20:15:29 +00001182 zclient_init (zclient, ZEBRA_ROUTE_BGP);
Feng Luc99f3482014-10-16 09:52:36 +08001183 zclient->zebra_connected = bgp_zebra_connected;
hasso18a6dce2004-10-03 18:18:34 +00001184 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001185 zclient->interface_add = bgp_interface_add;
1186 zclient->interface_delete = bgp_interface_delete;
1187 zclient->interface_address_add = bgp_interface_address_add;
1188 zclient->interface_address_delete = bgp_interface_address_delete;
1189 zclient->ipv4_route_add = zebra_read_ipv4;
1190 zclient->ipv4_route_delete = zebra_read_ipv4;
1191 zclient->interface_up = bgp_interface_up;
1192 zclient->interface_down = bgp_interface_down;
paul718e3742002-12-13 20:15:29 +00001193 zclient->ipv6_route_add = zebra_read_ipv6;
1194 zclient->ipv6_route_delete = zebra_read_ipv6;
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001195 zclient->nexthop_update = bgp_read_nexthop_update;
paul718e3742002-12-13 20:15:29 +00001196
Josh Bailey8196f132011-07-20 20:47:07 -07001197 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -05001198 bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001199}
Lou Berger82dd7072016-01-12 13:41:57 -05001200
1201void
1202bgp_zebra_destroy(void)
1203{
1204 if (zclient == NULL)
1205 return;
1206 zclient_stop(zclient);
1207 zclient_free(zclient);
1208 zclient = NULL;
1209}