blob: 45d502a576751c3d452630050bedc253ea956909 [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);
ajsd2fc8892005-04-02 18:38:43 +0000110 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000111
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000112 if (BGP_DEBUG(zebra, ZEBRA))
113 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
114
paul718e3742002-12-13 20:15:29 +0000115 return 0;
116}
117
paul94f2b392005-06-28 12:44:16 +0000118static int
Feng Luc99f3482014-10-16 09:52:36 +0800119bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
120 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000121{
122 struct stream *s;
123 struct interface *ifp;
124 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000125 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000126
127 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800128 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000129
130 if (! ifp)
131 return 0;
132
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000133 if (BGP_DEBUG(zebra, ZEBRA))
134 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
135
paul1eb8ef22005-04-07 07:30:20 +0000136 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
137 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000138
139 return 0;
140}
141
paul94f2b392005-06-28 12:44:16 +0000142static int
Feng Luc99f3482014-10-16 09:52:36 +0800143bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
144 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000145{
146 struct stream *s;
147 struct interface *ifp;
148 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000149 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000150
151 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800152 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000153 if (! ifp)
154 return 0;
155
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000156 if (BGP_DEBUG(zebra, ZEBRA))
157 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
158
paul1eb8ef22005-04-07 07:30:20 +0000159 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
160 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000161
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000162 /* Fast external-failover */
paul718e3742002-12-13 20:15:29 +0000163 {
paul1eb8ef22005-04-07 07:30:20 +0000164 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000165 struct bgp *bgp;
166 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000167
paul1eb8ef22005-04-07 07:30:20 +0000168 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000169 {
170 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
171 continue;
172
paul1eb8ef22005-04-07 07:30:20 +0000173 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000174 {
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000175 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
paul718e3742002-12-13 20:15:29 +0000176 continue;
177
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000178 if (ifp == peer->nexthop.ifp)
paul718e3742002-12-13 20:15:29 +0000179 BGP_EVENT_ADD (peer, BGP_Stop);
180 }
181 }
182 }
183
184 return 0;
185}
186
paul94f2b392005-06-28 12:44:16 +0000187static int
paul718e3742002-12-13 20:15:29 +0000188bgp_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800189 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000190{
191 struct connected *ifc;
192
Feng Luc99f3482014-10-16 09:52:36 +0800193 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000194
195 if (ifc == NULL)
196 return 0;
197
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000198 if (BGP_DEBUG(zebra, ZEBRA))
199 {
200 char buf[128];
201 prefix2str(ifc->address, buf, sizeof(buf));
202 zlog_debug("Zebra rcvd: interface %s address add %s",
203 ifc->ifp->name, buf);
204 }
205
paul2e3b2e42002-12-13 21:03:13 +0000206 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000207 bgp_connected_add (ifc);
208
209 return 0;
210}
211
paul94f2b392005-06-28 12:44:16 +0000212static int
paul718e3742002-12-13 20:15:29 +0000213bgp_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800214 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000215{
216 struct connected *ifc;
217
Feng Luc99f3482014-10-16 09:52:36 +0800218 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000219
220 if (ifc == NULL)
221 return 0;
222
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000223 if (BGP_DEBUG(zebra, ZEBRA))
224 {
225 char buf[128];
226 prefix2str(ifc->address, buf, sizeof(buf));
227 zlog_debug("Zebra rcvd: interface %s address delete %s",
228 ifc->ifp->name, buf);
229 }
230
paul2e3b2e42002-12-13 21:03:13 +0000231 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000232 bgp_connected_delete (ifc);
233
234 connected_free (ifc);
235
236 return 0;
237}
238
239/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000240static int
Feng Luc99f3482014-10-16 09:52:36 +0800241zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
242 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000243{
244 struct stream *s;
245 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000246 struct in_addr nexthop;
247 struct prefix_ipv4 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500248 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000249
250 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000251 nexthop.s_addr = 0;
252
253 /* Type, flags, message. */
254 api.type = stream_getc (s);
255 api.flags = stream_getc (s);
256 api.message = stream_getc (s);
257
258 /* IPv4 prefix. */
259 memset (&p, 0, sizeof (struct prefix_ipv4));
260 p.family = AF_INET;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500261 plength = stream_getc (s);
262 p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000263 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
264
265 /* Nexthop, ifindex, distance, metric. */
266 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
267 {
268 api.nexthop_num = stream_getc (s);
269 nexthop.s_addr = stream_get_ipv4 (s);
270 }
271 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
272 {
273 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400274 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000275 }
276 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
277 api.distance = stream_getc (s);
278 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
279 api.metric = stream_getl (s);
280 else
281 api.metric = 0;
282
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500283 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
Paul Jakma96d10602016-07-01 14:23:45 +0100284 api.tag = stream_getl (s);
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500285 else
286 api.tag = 0;
287
paul718e3742002-12-13 20:15:29 +0000288 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000289 {
290 if (BGP_DEBUG(zebra, ZEBRA))
291 {
292 char buf[2][INET_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500293 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000294 zebra_route_string(api.type),
295 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
296 p.prefixlen,
297 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500298 api.metric,
299 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000300 }
Piotr Chytła605aa332015-12-01 10:03:54 -0500301 bgp_redistribute_add ((struct prefix *)&p, &nexthop, NULL,
302 api.metric, api.type, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000303 }
paul718e3742002-12-13 20:15:29 +0000304 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000305 {
306 if (BGP_DEBUG(zebra, ZEBRA))
307 {
308 char buf[2][INET_ADDRSTRLEN];
309 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500310 "nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000311 zebra_route_string(api.type),
312 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
313 p.prefixlen,
314 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500315 api.metric,
316 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000317 }
318 bgp_redistribute_delete((struct prefix *)&p, api.type);
319 }
paul718e3742002-12-13 20:15:29 +0000320
321 return 0;
322}
323
paul718e3742002-12-13 20:15:29 +0000324/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000325static int
Feng Luc99f3482014-10-16 09:52:36 +0800326zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
327 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000328{
329 struct stream *s;
330 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000331 struct in6_addr nexthop;
332 struct prefix_ipv6 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500333 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000334
335 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000336 memset (&nexthop, 0, sizeof (struct in6_addr));
337
338 /* Type, flags, message. */
339 api.type = stream_getc (s);
340 api.flags = stream_getc (s);
341 api.message = stream_getc (s);
342
343 /* IPv6 prefix. */
344 memset (&p, 0, sizeof (struct prefix_ipv6));
345 p.family = AF_INET6;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500346 plength = stream_getc (s);
347 p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000348 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
349
350 /* Nexthop, ifindex, distance, metric. */
351 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
352 {
353 api.nexthop_num = stream_getc (s);
354 stream_get (&nexthop, s, 16);
355 }
356 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
357 {
358 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400359 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000360 }
361 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
362 api.distance = stream_getc (s);
363 else
364 api.distance = 0;
365 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
366 api.metric = stream_getl (s);
367 else
368 api.metric = 0;
369
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500370 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
Paul Jakma96d10602016-07-01 14:23:45 +0100371 api.tag = stream_getl (s);
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500372 else
373 api.tag = 0;
374
paul718e3742002-12-13 20:15:29 +0000375 /* Simply ignore link-local address. */
376 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
377 return 0;
378
379 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000380 {
381 if (BGP_DEBUG(zebra, ZEBRA))
382 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400383 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500384 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000385 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400386 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
387 p.prefixlen,
388 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500389 api.metric,
390 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000391 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400392 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
Piotr Chytła605aa332015-12-01 10:03:54 -0500393 api.metric, api.type, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000394 }
paul718e3742002-12-13 20:15:29 +0000395 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000396 {
397 if (BGP_DEBUG(zebra, ZEBRA))
398 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400399 char buf[2][INET6_ADDRSTRLEN];
400 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500401 "nexthop %s metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000402 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400403 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
404 p.prefixlen,
405 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500406 api.metric,
407 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000408 }
409 bgp_redistribute_delete ((struct prefix *) &p, api.type);
410 }
paul718e3742002-12-13 20:15:29 +0000411
412 return 0;
413}
David Lamparter6b0655a2014-06-04 06:53:35 +0200414
paul718e3742002-12-13 20:15:29 +0000415struct interface *
416if_lookup_by_ipv4 (struct in_addr *addr)
417{
hasso52dc7ee2004-09-23 19:18:23 +0000418 struct listnode *ifnode;
419 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000420 struct interface *ifp;
421 struct connected *connected;
422 struct prefix_ipv4 p;
423 struct prefix *cp;
424
425 p.family = AF_INET;
426 p.prefix = *addr;
427 p.prefixlen = IPV4_MAX_BITLEN;
428
paul1eb8ef22005-04-07 07:30:20 +0000429 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000430 {
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000432 {
paul718e3742002-12-13 20:15:29 +0000433 cp = connected->address;
434
435 if (cp->family == AF_INET)
436 if (prefix_match (cp, (struct prefix *)&p))
437 return ifp;
438 }
439 }
440 return NULL;
441}
442
443struct interface *
444if_lookup_by_ipv4_exact (struct in_addr *addr)
445{
hasso52dc7ee2004-09-23 19:18:23 +0000446 struct listnode *ifnode;
447 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000448 struct interface *ifp;
449 struct connected *connected;
450 struct prefix *cp;
451
paul1eb8ef22005-04-07 07:30:20 +0000452 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000453 {
paul1eb8ef22005-04-07 07:30:20 +0000454 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000455 {
paul718e3742002-12-13 20:15:29 +0000456 cp = connected->address;
457
458 if (cp->family == AF_INET)
459 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
460 return ifp;
461 }
462 }
463 return NULL;
464}
465
paul718e3742002-12-13 20:15:29 +0000466struct interface *
467if_lookup_by_ipv6 (struct in6_addr *addr)
468{
hasso52dc7ee2004-09-23 19:18:23 +0000469 struct listnode *ifnode;
470 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000471 struct interface *ifp;
472 struct connected *connected;
473 struct prefix_ipv6 p;
474 struct prefix *cp;
475
476 p.family = AF_INET6;
477 p.prefix = *addr;
478 p.prefixlen = IPV6_MAX_BITLEN;
479
paul1eb8ef22005-04-07 07:30:20 +0000480 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000481 {
paul1eb8ef22005-04-07 07:30:20 +0000482 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000483 {
paul718e3742002-12-13 20:15:29 +0000484 cp = connected->address;
485
486 if (cp->family == AF_INET6)
487 if (prefix_match (cp, (struct prefix *)&p))
488 return ifp;
489 }
490 }
491 return NULL;
492}
493
494struct interface *
495if_lookup_by_ipv6_exact (struct in6_addr *addr)
496{
hasso52dc7ee2004-09-23 19:18:23 +0000497 struct listnode *ifnode;
498 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000499 struct interface *ifp;
500 struct connected *connected;
501 struct prefix *cp;
502
paul1eb8ef22005-04-07 07:30:20 +0000503 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000504 {
paul1eb8ef22005-04-07 07:30:20 +0000505 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000506 {
paul718e3742002-12-13 20:15:29 +0000507 cp = connected->address;
508
509 if (cp->family == AF_INET6)
510 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
511 return ifp;
512 }
513 }
514 return NULL;
515}
516
paul94f2b392005-06-28 12:44:16 +0000517static int
paul718e3742002-12-13 20:15:29 +0000518if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
519{
hasso52dc7ee2004-09-23 19:18:23 +0000520 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000521 struct connected *connected;
522 struct prefix *cp;
523
paul1eb8ef22005-04-07 07:30:20 +0000524 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000525 {
paul718e3742002-12-13 20:15:29 +0000526 cp = connected->address;
527
528 if (cp->family == AF_INET6)
529 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
530 {
531 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
532 return 1;
533 }
534 }
535 return 0;
536}
537
paul94f2b392005-06-28 12:44:16 +0000538static int
paul718e3742002-12-13 20:15:29 +0000539if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
540{
hasso52dc7ee2004-09-23 19:18:23 +0000541 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000542 struct connected *connected;
543 struct prefix *cp;
544
paul1eb8ef22005-04-07 07:30:20 +0000545 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000546 {
paul718e3742002-12-13 20:15:29 +0000547 cp = connected->address;
548
549 if (cp->family == AF_INET6)
550 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
551 {
552 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
553 return 1;
554 }
555 }
556 return 0;
557}
paul718e3742002-12-13 20:15:29 +0000558
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000559static int
560if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
561{
562 struct listnode *cnode;
563 struct connected *connected;
564 struct prefix *cp;
565
566 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
567 {
568 cp = connected->address;
569 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
570 {
571 *addr = cp->u.prefix4;
572 return 1;
573 }
574 }
575 return 0;
576}
577
paul718e3742002-12-13 20:15:29 +0000578int
579bgp_nexthop_set (union sockunion *local, union sockunion *remote,
580 struct bgp_nexthop *nexthop, struct peer *peer)
581{
582 int ret = 0;
583 struct interface *ifp = NULL;
584
585 memset (nexthop, 0, sizeof (struct bgp_nexthop));
586
587 if (!local)
588 return -1;
589 if (!remote)
590 return -1;
591
592 if (local->sa.sa_family == AF_INET)
593 {
594 nexthop->v4 = local->sin.sin_addr;
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700595 if (peer->update_if)
596 ifp = if_lookup_by_name (peer->update_if);
597 else
598 ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr);
paul718e3742002-12-13 20:15:29 +0000599 }
paul718e3742002-12-13 20:15:29 +0000600 if (local->sa.sa_family == AF_INET6)
601 {
602 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
603 {
604 if (peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200605 ifp = if_lookup_by_name (peer->ifname);
paul718e3742002-12-13 20:15:29 +0000606 }
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700607 else if (peer->update_if)
608 ifp = if_lookup_by_name (peer->update_if);
paul718e3742002-12-13 20:15:29 +0000609 else
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700610 ifp = if_lookup_by_ipv6_exact (&local->sin6.sin6_addr);
paul718e3742002-12-13 20:15:29 +0000611 }
paul718e3742002-12-13 20:15:29 +0000612
613 if (!ifp)
614 return -1;
615
616 nexthop->ifp = ifp;
617
618 /* IPv4 connection. */
619 if (local->sa.sa_family == AF_INET)
620 {
paul718e3742002-12-13 20:15:29 +0000621 /* IPv6 nexthop*/
622 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
623
624 /* There is no global nexthop. */
625 if (!ret)
626 if_get_ipv6_local (ifp, &nexthop->v6_global);
627 else
628 if_get_ipv6_local (ifp, &nexthop->v6_local);
paul718e3742002-12-13 20:15:29 +0000629 }
630
paul718e3742002-12-13 20:15:29 +0000631 /* IPv6 connection. */
632 if (local->sa.sa_family == AF_INET6)
633 {
634 struct interface *direct = NULL;
635
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000636 /* IPv4 nexthop. */
637 ret = if_get_ipv4_address(ifp, &nexthop->v4);
638 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000639 nexthop->v4 = peer->local_id;
640
641 /* Global address*/
642 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
643 {
644 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
645 IPV6_MAX_BYTELEN);
646
647 /* If directory connected set link-local address. */
648 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
649 if (direct)
650 if_get_ipv6_local (ifp, &nexthop->v6_local);
651 }
652 else
653 /* Link-local address. */
654 {
655 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
656
657 /* If there is no global address. Set link-local address as
658 global. I know this break RFC specification... */
659 if (!ret)
660 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
661 IPV6_MAX_BYTELEN);
662 else
663 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
664 IPV6_MAX_BYTELEN);
665 }
666 }
667
668 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
669 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
670 peer->shared_network = 1;
671 else
672 peer->shared_network = 0;
673
674 /* KAME stack specific treatment. */
675#ifdef KAME
676 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
677 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
678 {
679 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
680 }
681 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
682 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
683 {
684 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
685 }
686#endif /* KAME */
paul718e3742002-12-13 20:15:29 +0000687 return ret;
688}
689
paul718e3742002-12-13 20:15:29 +0000690void
G.Balaji5a616c02011-11-26 21:58:42 +0400691bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000692{
693 int flags;
694 u_char distance;
695 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700696 struct bgp_info *mpinfo;
697 size_t oldsize, newsize;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500698 u_int32_t nhcount;
Paul Jakma96d10602016-07-01 14:23:45 +0100699 route_tag_t tag = 0;
paul718e3742002-12-13 20:15:29 +0000700
701 if (zclient->sock < 0)
702 return;
703
Feng Luc99f3482014-10-16 09:52:36 +0800704 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000705 return;
706
707 flags = 0;
708 peer = info->peer;
709
Piotr Chytła605aa332015-12-01 10:03:54 -0500710 if ((info->attr->extra) && (info->attr->extra->tag != 0))
711 tag = info->attr->extra->tag;
712
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000713 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000714 {
715 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
716 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
717 }
718
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000719 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000720 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000721 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
722
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500723 nhcount = 1 + bgp_info_mpath_count (info);
Josh Bailey8196f132011-07-20 20:47:07 -0700724
paul718e3742002-12-13 20:15:29 +0000725 if (p->family == AF_INET)
726 {
727 struct zapi_ipv4 api;
728 struct in_addr *nexthop;
729
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500730 /* resize nexthop buffer size if necessary */
731 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
732 (sizeof (struct in_addr *) * nhcount))
733 {
734 newsize = (sizeof (struct in_addr *) * nhcount);
735 newsize = stream_resize (bgp_nexthop_buf, newsize);
736 if (newsize == oldsize)
737 {
738 zlog_err ("can't resize nexthop buffer");
739 return;
740 }
741 }
742 stream_reset (bgp_nexthop_buf);
743
Feng Luc99f3482014-10-16 09:52:36 +0800744 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000745 api.flags = flags;
746 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700747 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
748 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
749 mpinfo = bgp_info_mpath_next (mpinfo))
750 {
751 nexthop = &mpinfo->attr->nexthop;
752 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
753 }
paul718e3742002-12-13 20:15:29 +0000754
755 api.type = ZEBRA_ROUTE_BGP;
756 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400757 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000758 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500759 api.nexthop_num = nhcount;
Josh Bailey8196f132011-07-20 20:47:07 -0700760 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000761 api.ifindex_num = 0;
762 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
763 api.metric = info->attr->med;
764
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500765 if (tag)
Piotr Chytła605aa332015-12-01 10:03:54 -0500766 {
767 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
768 api.tag = tag;
769 }
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500770
paul718e3742002-12-13 20:15:29 +0000771 distance = bgp_distance_apply (p, info, bgp);
772
773 if (distance)
774 {
775 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
776 api.distance = distance;
777 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000778
779 if (BGP_DEBUG(zebra, ZEBRA))
780 {
Josh Bailey8196f132011-07-20 20:47:07 -0700781 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000782 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700783 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500784 " tag %u count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000785 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
786 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700787 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500788 api.metric, api.tag, api.nexthop_num);
Josh Bailey8196f132011-07-20 20:47:07 -0700789 for (i = 1; i < api.nexthop_num; i++)
790 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
791 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
792 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000793 }
794
paul0a589352004-05-08 11:48:26 +0000795 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
796 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000797 }
Lou Berger205e6742016-01-12 13:42:11 -0500798
paul718e3742002-12-13 20:15:29 +0000799 /* We have to think about a IPv6 link-local address curse. */
800 if (p->family == AF_INET6)
801 {
Paul Jakma9099f9b2016-01-18 10:12:10 +0000802 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000803 struct in6_addr *nexthop;
804 struct zapi_ipv6 api;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500805 int valid_nh_count = 0;
806
807 /* resize nexthop buffer size if necessary */
808 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
809 (sizeof (struct in6_addr *) * nhcount))
810 {
811 newsize = (sizeof (struct in6_addr *) * nhcount);
812 newsize = stream_resize (bgp_nexthop_buf, newsize);
813 if (newsize == oldsize)
814 {
815 zlog_err ("can't resize nexthop buffer");
816 return;
817 }
818 }
819 stream_reset (bgp_nexthop_buf);
820
821 /* resize ifindices buffer size if necessary */
822 if ((oldsize = stream_get_size (bgp_ifindices_buf)) <
823 (sizeof (unsigned int) * nhcount))
824 {
825 newsize = (sizeof (unsigned int) * nhcount);
826 newsize = stream_resize (bgp_ifindices_buf, newsize);
827 if (newsize == oldsize)
828 {
829 zlog_err ("can't resize nexthop buffer");
830 return;
831 }
832 }
833 stream_reset (bgp_ifindices_buf);
paul718e3742002-12-13 20:15:29 +0000834
835 ifindex = 0;
836 nexthop = NULL;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500837
Paul Jakmafb982c22007-05-04 20:15:47 +0000838 assert (info->attr->extra);
839
paul718e3742002-12-13 20:15:29 +0000840 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000841 if (info->attr->extra->mp_nexthop_len == 16)
842 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000843
844 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000845 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000846 {
847 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000848 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000849 && peer->su_remote->sa.sa_family == AF_INET6)
850 nexthop = &peer->su_remote->sin6.sin6_addr;
851 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000852 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000853
854 if (info->peer->nexthop.ifp)
855 ifindex = info->peer->nexthop.ifp->ifindex;
856 }
857
858 if (nexthop == NULL)
859 return;
860
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500861 if (!ifindex)
paul718e3742002-12-13 20:15:29 +0000862 {
863 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200864 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000865 else if (info->peer->nexthop.ifp)
866 ifindex = info->peer->nexthop.ifp->ifindex;
867 }
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500868 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
869 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
870 valid_nh_count++;
871
872 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
873 mpinfo = bgp_info_mpath_next (mpinfo))
874 {
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500875 ifindex = 0;
876
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500877 /* Only global address nexthop exists. */
878 if (mpinfo->attr->extra->mp_nexthop_len == 16)
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500879 nexthop = &mpinfo->attr->extra->mp_nexthop_global;
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500880
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500881 /* If both global and link-local address present. */
882 if (mpinfo->attr->extra->mp_nexthop_len == 32)
883 {
884 /* Workaround for Cisco's nexthop bug. */
885 if (IN6_IS_ADDR_UNSPECIFIED (&mpinfo->attr->extra->mp_nexthop_global)
886 && mpinfo->peer->su_remote->sa.sa_family == AF_INET6)
887 {
888 nexthop = &mpinfo->peer->su_remote->sin6.sin6_addr;
889 }
890 else
891 {
892 nexthop = &mpinfo->attr->extra->mp_nexthop_local;
893 }
894
895 if (mpinfo->peer->nexthop.ifp)
896 {
897 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
898 }
899 }
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500900
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500901 if (nexthop == NULL)
902 {
903 continue;
904 }
905
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500906 if (!ifindex)
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500907 {
908 if (mpinfo->peer->ifname)
909 {
910 ifindex = if_nametoindex (mpinfo->peer->ifname);
911 }
912 else if (mpinfo->peer->nexthop.ifp)
913 {
914 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
915 }
916 }
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500917
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500918 if (ifindex == 0)
919 {
920 continue;
921 }
922
923 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
924 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
925 valid_nh_count++;
926 }
paul718e3742002-12-13 20:15:29 +0000927
928 /* Make Zebra API structure. */
Feng Luc99f3482014-10-16 09:52:36 +0800929 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000930 api.flags = flags;
931 api.type = ZEBRA_ROUTE_BGP;
932 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400933 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000934 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500935 api.nexthop_num = valid_nh_count;
936 api.nexthop = (struct in6_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000937 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500938 api.ifindex_num = valid_nh_count;
939 api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf);
paul718e3742002-12-13 20:15:29 +0000940 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
941 api.metric = info->attr->med;
942
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100943 distance = ipv6_bgp_distance_apply (p, info, bgp);
944
945 if (distance)
946 {
947 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
948 api.distance = distance;
949 }
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500950
951 if (tag)
952 {
953 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
954 api.tag = tag;
955 }
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100956
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000957 if (BGP_DEBUG(zebra, ZEBRA))
958 {
959 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500960 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u"
961 " tag %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000962 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
963 p->prefixlen,
964 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
Piotr Chytłaeefddcc2015-12-01 09:48:02 -0500965 api.metric, api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000966 }
967
paul0a589352004-05-08 11:48:26 +0000968 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
969 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000970 }
paul718e3742002-12-13 20:15:29 +0000971}
972
973void
G.Balaji5a616c02011-11-26 21:58:42 +0400974bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000975{
976 int flags;
977 struct peer *peer;
978
979 if (zclient->sock < 0)
980 return;
981
Feng Luc99f3482014-10-16 09:52:36 +0800982 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000983 return;
984
985 peer = info->peer;
986 flags = 0;
987
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000988 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000989 {
990 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
991 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
992 }
993
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000994 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000995 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000996 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
997
998 if (p->family == AF_INET)
999 {
1000 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +00001001
Feng Luc99f3482014-10-16 09:52:36 +08001002 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +00001003 api.flags = flags;
paul718e3742002-12-13 20:15:29 +00001004
1005 api.type = ZEBRA_ROUTE_BGP;
1006 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +04001007 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +00001008 api.nexthop_num = 0;
paul718e3742002-12-13 20:15:29 +00001009 api.ifindex_num = 0;
1010 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1011 api.metric = info->attr->med;
1012
Piotr Chytła605aa332015-12-01 10:03:54 -05001013 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1014 {
1015 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1016 api.tag = info->attr->extra->tag;
1017 }
1018
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001019 if (BGP_DEBUG(zebra, ZEBRA))
1020 {
1021 char buf[2][INET_ADDRSTRLEN];
Piotr Chytła605aa332015-12-01 10:03:54 -05001022 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001023 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
1024 p->prefixlen,
Piotr Chytła605aa332015-12-01 10:03:54 -05001025 api.metric,
1026 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001027 }
1028
paul0a589352004-05-08 11:48:26 +00001029 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
1030 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +00001031 }
Lou Berger205e6742016-01-12 13:42:11 -05001032
paul718e3742002-12-13 20:15:29 +00001033 /* We have to think about a IPv6 link-local address curse. */
1034 if (p->family == AF_INET6)
1035 {
1036 struct zapi_ipv6 api;
Paul Jakmafb982c22007-05-04 20:15:47 +00001037
Feng Luc99f3482014-10-16 09:52:36 +08001038 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +00001039 api.flags = flags;
1040 api.type = ZEBRA_ROUTE_BGP;
1041 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +04001042 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +00001043 api.nexthop_num = 0;
1044 api.ifindex_num = 0;
paul718e3742002-12-13 20:15:29 +00001045 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1046 api.metric = info->attr->med;
1047
Piotr Chytła605aa332015-12-01 10:03:54 -05001048 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1049 {
1050 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1051 api.tag = info->attr->extra->tag;
1052 }
1053
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001054 if (BGP_DEBUG(zebra, ZEBRA))
1055 {
1056 char buf[2][INET6_ADDRSTRLEN];
Piotr Chytła605aa332015-12-01 10:03:54 -05001057 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001058 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
1059 p->prefixlen,
Piotr Chytła605aa332015-12-01 10:03:54 -05001060 api.metric,
1061 api.tag);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001062 }
1063
paul0a589352004-05-08 11:48:26 +00001064 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
1065 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +00001066 }
paul718e3742002-12-13 20:15:29 +00001067}
David Lamparter6b0655a2014-06-04 06:53:35 +02001068
paul718e3742002-12-13 20:15:29 +00001069/* Other routes redistribution into BGP. */
1070int
1071bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
1072{
1073 /* Set flag to BGP instance. */
1074 bgp->redist[afi][type] = 1;
1075
1076 /* Return if already redistribute flag is set. */
Feng Luc99f3482014-10-16 09:52:36 +08001077 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001078 return CMD_WARNING;
1079
Feng Luc99f3482014-10-16 09:52:36 +08001080 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001081
1082 /* Return if zebra connection is not established. */
1083 if (zclient->sock < 0)
1084 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001085
1086 if (BGP_DEBUG(zebra, ZEBRA))
1087 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +00001088
1089 /* Send distribute add message to zebra. */
Feng Luc99f3482014-10-16 09:52:36 +08001090 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001091
1092 return CMD_SUCCESS;
1093}
1094
1095/* Redistribute with route-map specification. */
1096int
paulfd79ac92004-10-13 05:06:08 +00001097bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
1098 const char *name)
paul718e3742002-12-13 20:15:29 +00001099{
1100 if (bgp->rmap[afi][type].name
1101 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
1102 return 0;
1103
1104 if (bgp->rmap[afi][type].name)
1105 free (bgp->rmap[afi][type].name);
1106 bgp->rmap[afi][type].name = strdup (name);
1107 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
1108
1109 return 1;
1110}
1111
1112/* Redistribute with metric specification. */
1113int
1114bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
1115 u_int32_t metric)
1116{
1117 if (bgp->redist_metric_flag[afi][type]
1118 && bgp->redist_metric[afi][type] == metric)
1119 return 0;
1120
1121 bgp->redist_metric_flag[afi][type] = 1;
1122 bgp->redist_metric[afi][type] = metric;
1123
1124 return 1;
1125}
1126
1127/* Unset redistribution. */
1128int
1129bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
1130{
1131 /* Unset flag from BGP instance. */
1132 bgp->redist[afi][type] = 0;
1133
1134 /* Unset route-map. */
1135 if (bgp->rmap[afi][type].name)
1136 free (bgp->rmap[afi][type].name);
1137 bgp->rmap[afi][type].name = NULL;
1138 bgp->rmap[afi][type].map = NULL;
1139
1140 /* Unset metric. */
1141 bgp->redist_metric_flag[afi][type] = 0;
1142 bgp->redist_metric[afi][type] = 0;
1143
1144 /* Return if zebra connection is disabled. */
Feng Luc99f3482014-10-16 09:52:36 +08001145 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001146 return CMD_WARNING;
Feng Luc99f3482014-10-16 09:52:36 +08001147 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001148
1149 if (bgp->redist[AFI_IP][type] == 0
1150 && bgp->redist[AFI_IP6][type] == 0
1151 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001152 {
1153 /* Send distribute delete message to zebra. */
1154 if (BGP_DEBUG(zebra, ZEBRA))
1155 zlog_debug("Zebra send: redistribute delete %s",
1156 zebra_route_string(type));
Feng Luc99f3482014-10-16 09:52:36 +08001157 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
1158 VRF_DEFAULT);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001159 }
paul718e3742002-12-13 20:15:29 +00001160
1161 /* Withdraw redistributed routes from current BGP's routing table. */
1162 bgp_redistribute_withdraw (bgp, afi, type);
1163
1164 return CMD_SUCCESS;
1165}
1166
paul718e3742002-12-13 20:15:29 +00001167void
paul94f2b392005-06-28 12:44:16 +00001168bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001169{
1170 zclient_reset (zclient);
1171}
1172
Feng Luc99f3482014-10-16 09:52:36 +08001173static void
1174bgp_zebra_connected (struct zclient *zclient)
1175{
Lou Berger68bfb612016-10-06 09:59:32 -04001176 zclient_num_connects++;
Feng Luc99f3482014-10-16 09:52:36 +08001177 zclient_send_requests (zclient, VRF_DEFAULT);
1178}
1179
paul718e3742002-12-13 20:15:29 +00001180void
Donald Sharp71252932015-09-24 09:25:19 -04001181bgp_zebra_init (struct thread_master *master)
paul718e3742002-12-13 20:15:29 +00001182{
Lou Berger68bfb612016-10-06 09:59:32 -04001183 zclient_num_connects = 0;
1184
paul718e3742002-12-13 20:15:29 +00001185 /* Set default values. */
Donald Sharp71252932015-09-24 09:25:19 -04001186 zclient = zclient_new (master);
paul718e3742002-12-13 20:15:29 +00001187 zclient_init (zclient, ZEBRA_ROUTE_BGP);
Feng Luc99f3482014-10-16 09:52:36 +08001188 zclient->zebra_connected = bgp_zebra_connected;
hasso18a6dce2004-10-03 18:18:34 +00001189 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001190 zclient->interface_add = bgp_interface_add;
1191 zclient->interface_delete = bgp_interface_delete;
1192 zclient->interface_address_add = bgp_interface_address_add;
1193 zclient->interface_address_delete = bgp_interface_address_delete;
1194 zclient->ipv4_route_add = zebra_read_ipv4;
1195 zclient->ipv4_route_delete = zebra_read_ipv4;
1196 zclient->interface_up = bgp_interface_up;
1197 zclient->interface_down = bgp_interface_down;
paul718e3742002-12-13 20:15:29 +00001198 zclient->ipv6_route_add = zebra_read_ipv6;
1199 zclient->ipv6_route_delete = zebra_read_ipv6;
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001200 zclient->nexthop_update = bgp_read_nexthop_update;
paul718e3742002-12-13 20:15:29 +00001201
Josh Bailey8196f132011-07-20 20:47:07 -07001202 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -05001203 bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001204}
Lou Berger82dd7072016-01-12 13:41:57 -05001205
1206void
1207bgp_zebra_destroy(void)
1208{
1209 if (zclient == NULL)
1210 return;
1211 zclient_stop(zclient);
1212 zclient_free(zclient);
1213 zclient = NULL;
1214}
Lou Berger68bfb612016-10-06 09:59:32 -04001215
1216int
1217bgp_zebra_num_connects(void)
1218{
1219 return zclient_num_connects;
1220}