blob: b9e8a5c2e243f4f104c3920b22b61ede27dd8da0 [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
281 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000282 {
283 if (BGP_DEBUG(zebra, ZEBRA))
284 {
285 char buf[2][INET_ADDRSTRLEN];
286 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
287 zebra_route_string(api.type),
288 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
289 p.prefixlen,
290 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
291 api.metric);
292 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400293 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
294 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000295 }
paul718e3742002-12-13 20:15:29 +0000296 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000297 {
298 if (BGP_DEBUG(zebra, ZEBRA))
299 {
300 char buf[2][INET_ADDRSTRLEN];
301 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
302 "nexthop %s metric %u",
303 zebra_route_string(api.type),
304 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
305 p.prefixlen,
306 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
307 api.metric);
308 }
309 bgp_redistribute_delete((struct prefix *)&p, api.type);
310 }
paul718e3742002-12-13 20:15:29 +0000311
312 return 0;
313}
314
paul718e3742002-12-13 20:15:29 +0000315/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000316static int
Feng Luc99f3482014-10-16 09:52:36 +0800317zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
318 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000319{
320 struct stream *s;
321 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000322 struct in6_addr nexthop;
323 struct prefix_ipv6 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500324 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000325
326 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000327 memset (&nexthop, 0, sizeof (struct in6_addr));
328
329 /* Type, flags, message. */
330 api.type = stream_getc (s);
331 api.flags = stream_getc (s);
332 api.message = stream_getc (s);
333
334 /* IPv6 prefix. */
335 memset (&p, 0, sizeof (struct prefix_ipv6));
336 p.family = AF_INET6;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500337 plength = stream_getc (s);
338 p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000339 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
340
341 /* Nexthop, ifindex, distance, metric. */
342 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
343 {
344 api.nexthop_num = stream_getc (s);
345 stream_get (&nexthop, s, 16);
346 }
347 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
348 {
349 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400350 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000351 }
352 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
353 api.distance = stream_getc (s);
354 else
355 api.distance = 0;
356 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
357 api.metric = stream_getl (s);
358 else
359 api.metric = 0;
360
361 /* Simply ignore link-local address. */
362 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
363 return 0;
364
365 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000366 {
367 if (BGP_DEBUG(zebra, ZEBRA))
368 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400369 char buf[2][INET6_ADDRSTRLEN];
370 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000371 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400372 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
373 p.prefixlen,
374 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
375 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000376 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400377 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
378 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000379 }
paul718e3742002-12-13 20:15:29 +0000380 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000381 {
382 if (BGP_DEBUG(zebra, ZEBRA))
383 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400384 char buf[2][INET6_ADDRSTRLEN];
385 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
386 "nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000387 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400388 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
389 p.prefixlen,
390 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
391 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000392 }
393 bgp_redistribute_delete ((struct prefix *) &p, api.type);
394 }
paul718e3742002-12-13 20:15:29 +0000395
396 return 0;
397}
David Lamparter6b0655a2014-06-04 06:53:35 +0200398
paul718e3742002-12-13 20:15:29 +0000399struct interface *
400if_lookup_by_ipv4 (struct in_addr *addr)
401{
hasso52dc7ee2004-09-23 19:18:23 +0000402 struct listnode *ifnode;
403 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000404 struct interface *ifp;
405 struct connected *connected;
406 struct prefix_ipv4 p;
407 struct prefix *cp;
408
409 p.family = AF_INET;
410 p.prefix = *addr;
411 p.prefixlen = IPV4_MAX_BITLEN;
412
paul1eb8ef22005-04-07 07:30:20 +0000413 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000414 {
paul1eb8ef22005-04-07 07:30:20 +0000415 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000416 {
paul718e3742002-12-13 20:15:29 +0000417 cp = connected->address;
418
419 if (cp->family == AF_INET)
420 if (prefix_match (cp, (struct prefix *)&p))
421 return ifp;
422 }
423 }
424 return NULL;
425}
426
427struct interface *
428if_lookup_by_ipv4_exact (struct in_addr *addr)
429{
hasso52dc7ee2004-09-23 19:18:23 +0000430 struct listnode *ifnode;
431 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000432 struct interface *ifp;
433 struct connected *connected;
434 struct prefix *cp;
435
paul1eb8ef22005-04-07 07:30:20 +0000436 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000437 {
paul1eb8ef22005-04-07 07:30:20 +0000438 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000439 {
paul718e3742002-12-13 20:15:29 +0000440 cp = connected->address;
441
442 if (cp->family == AF_INET)
443 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
444 return ifp;
445 }
446 }
447 return NULL;
448}
449
paul718e3742002-12-13 20:15:29 +0000450struct interface *
451if_lookup_by_ipv6 (struct in6_addr *addr)
452{
hasso52dc7ee2004-09-23 19:18:23 +0000453 struct listnode *ifnode;
454 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000455 struct interface *ifp;
456 struct connected *connected;
457 struct prefix_ipv6 p;
458 struct prefix *cp;
459
460 p.family = AF_INET6;
461 p.prefix = *addr;
462 p.prefixlen = IPV6_MAX_BITLEN;
463
paul1eb8ef22005-04-07 07:30:20 +0000464 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000465 {
paul1eb8ef22005-04-07 07:30:20 +0000466 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000467 {
paul718e3742002-12-13 20:15:29 +0000468 cp = connected->address;
469
470 if (cp->family == AF_INET6)
471 if (prefix_match (cp, (struct prefix *)&p))
472 return ifp;
473 }
474 }
475 return NULL;
476}
477
478struct interface *
479if_lookup_by_ipv6_exact (struct in6_addr *addr)
480{
hasso52dc7ee2004-09-23 19:18:23 +0000481 struct listnode *ifnode;
482 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000483 struct interface *ifp;
484 struct connected *connected;
485 struct prefix *cp;
486
paul1eb8ef22005-04-07 07:30:20 +0000487 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000488 {
paul1eb8ef22005-04-07 07:30:20 +0000489 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000490 {
paul718e3742002-12-13 20:15:29 +0000491 cp = connected->address;
492
493 if (cp->family == AF_INET6)
494 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
495 return ifp;
496 }
497 }
498 return NULL;
499}
500
paul94f2b392005-06-28 12:44:16 +0000501static int
paul718e3742002-12-13 20:15:29 +0000502if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
503{
hasso52dc7ee2004-09-23 19:18:23 +0000504 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000505 struct connected *connected;
506 struct prefix *cp;
507
paul1eb8ef22005-04-07 07:30:20 +0000508 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000509 {
paul718e3742002-12-13 20:15:29 +0000510 cp = connected->address;
511
512 if (cp->family == AF_INET6)
513 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
514 {
515 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
516 return 1;
517 }
518 }
519 return 0;
520}
521
paul94f2b392005-06-28 12:44:16 +0000522static int
paul718e3742002-12-13 20:15:29 +0000523if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
524{
hasso52dc7ee2004-09-23 19:18:23 +0000525 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000526 struct connected *connected;
527 struct prefix *cp;
528
paul1eb8ef22005-04-07 07:30:20 +0000529 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000530 {
paul718e3742002-12-13 20:15:29 +0000531 cp = connected->address;
532
533 if (cp->family == AF_INET6)
534 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
535 {
536 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
537 return 1;
538 }
539 }
540 return 0;
541}
paul718e3742002-12-13 20:15:29 +0000542
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000543static int
544if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
545{
546 struct listnode *cnode;
547 struct connected *connected;
548 struct prefix *cp;
549
550 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
551 {
552 cp = connected->address;
553 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
554 {
555 *addr = cp->u.prefix4;
556 return 1;
557 }
558 }
559 return 0;
560}
561
paul718e3742002-12-13 20:15:29 +0000562int
563bgp_nexthop_set (union sockunion *local, union sockunion *remote,
564 struct bgp_nexthop *nexthop, struct peer *peer)
565{
566 int ret = 0;
567 struct interface *ifp = NULL;
568
569 memset (nexthop, 0, sizeof (struct bgp_nexthop));
570
571 if (!local)
572 return -1;
573 if (!remote)
574 return -1;
575
576 if (local->sa.sa_family == AF_INET)
577 {
578 nexthop->v4 = local->sin.sin_addr;
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700579 if (peer->update_if)
580 ifp = if_lookup_by_name (peer->update_if);
581 else
582 ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr);
paul718e3742002-12-13 20:15:29 +0000583 }
paul718e3742002-12-13 20:15:29 +0000584 if (local->sa.sa_family == AF_INET6)
585 {
586 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
587 {
588 if (peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200589 ifp = if_lookup_by_name (peer->ifname);
paul718e3742002-12-13 20:15:29 +0000590 }
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700591 else if (peer->update_if)
592 ifp = if_lookup_by_name (peer->update_if);
paul718e3742002-12-13 20:15:29 +0000593 else
Vivek Venkatramanfa2e7862015-05-19 18:03:54 -0700594 ifp = if_lookup_by_ipv6_exact (&local->sin6.sin6_addr);
paul718e3742002-12-13 20:15:29 +0000595 }
paul718e3742002-12-13 20:15:29 +0000596
597 if (!ifp)
598 return -1;
599
600 nexthop->ifp = ifp;
601
602 /* IPv4 connection. */
603 if (local->sa.sa_family == AF_INET)
604 {
paul718e3742002-12-13 20:15:29 +0000605 /* IPv6 nexthop*/
606 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
607
608 /* There is no global nexthop. */
609 if (!ret)
610 if_get_ipv6_local (ifp, &nexthop->v6_global);
611 else
612 if_get_ipv6_local (ifp, &nexthop->v6_local);
paul718e3742002-12-13 20:15:29 +0000613 }
614
paul718e3742002-12-13 20:15:29 +0000615 /* IPv6 connection. */
616 if (local->sa.sa_family == AF_INET6)
617 {
618 struct interface *direct = NULL;
619
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000620 /* IPv4 nexthop. */
621 ret = if_get_ipv4_address(ifp, &nexthop->v4);
622 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000623 nexthop->v4 = peer->local_id;
624
625 /* Global address*/
626 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
627 {
628 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
629 IPV6_MAX_BYTELEN);
630
631 /* If directory connected set link-local address. */
632 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
633 if (direct)
634 if_get_ipv6_local (ifp, &nexthop->v6_local);
635 }
636 else
637 /* Link-local address. */
638 {
639 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
640
641 /* If there is no global address. Set link-local address as
642 global. I know this break RFC specification... */
643 if (!ret)
644 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
645 IPV6_MAX_BYTELEN);
646 else
647 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
648 IPV6_MAX_BYTELEN);
649 }
650 }
651
652 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
653 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
654 peer->shared_network = 1;
655 else
656 peer->shared_network = 0;
657
658 /* KAME stack specific treatment. */
659#ifdef KAME
660 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
661 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
662 {
663 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
664 }
665 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
666 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
667 {
668 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
669 }
670#endif /* KAME */
paul718e3742002-12-13 20:15:29 +0000671 return ret;
672}
673
paul718e3742002-12-13 20:15:29 +0000674void
G.Balaji5a616c02011-11-26 21:58:42 +0400675bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000676{
677 int flags;
678 u_char distance;
679 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700680 struct bgp_info *mpinfo;
681 size_t oldsize, newsize;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500682 u_int32_t nhcount;
paul718e3742002-12-13 20:15:29 +0000683
684 if (zclient->sock < 0)
685 return;
686
Feng Luc99f3482014-10-16 09:52:36 +0800687 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000688 return;
689
690 flags = 0;
691 peer = info->peer;
692
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000693 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000694 {
695 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
696 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
697 }
698
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000699 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000700 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000701 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
702
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500703 nhcount = 1 + bgp_info_mpath_count (info);
Josh Bailey8196f132011-07-20 20:47:07 -0700704
paul718e3742002-12-13 20:15:29 +0000705 if (p->family == AF_INET)
706 {
707 struct zapi_ipv4 api;
708 struct in_addr *nexthop;
709
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500710 /* resize nexthop buffer size if necessary */
711 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
712 (sizeof (struct in_addr *) * nhcount))
713 {
714 newsize = (sizeof (struct in_addr *) * nhcount);
715 newsize = stream_resize (bgp_nexthop_buf, newsize);
716 if (newsize == oldsize)
717 {
718 zlog_err ("can't resize nexthop buffer");
719 return;
720 }
721 }
722 stream_reset (bgp_nexthop_buf);
723
Feng Luc99f3482014-10-16 09:52:36 +0800724 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000725 api.flags = flags;
726 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700727 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
728 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
729 mpinfo = bgp_info_mpath_next (mpinfo))
730 {
731 nexthop = &mpinfo->attr->nexthop;
732 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
733 }
paul718e3742002-12-13 20:15:29 +0000734
735 api.type = ZEBRA_ROUTE_BGP;
736 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400737 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000738 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500739 api.nexthop_num = nhcount;
Josh Bailey8196f132011-07-20 20:47:07 -0700740 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000741 api.ifindex_num = 0;
742 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
743 api.metric = info->attr->med;
744
745 distance = bgp_distance_apply (p, info, bgp);
746
747 if (distance)
748 {
749 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
750 api.distance = distance;
751 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000752
753 if (BGP_DEBUG(zebra, ZEBRA))
754 {
Josh Bailey8196f132011-07-20 20:47:07 -0700755 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000756 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700757 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
758 " count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000759 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
760 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700761 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
762 api.metric, api.nexthop_num);
763 for (i = 1; i < api.nexthop_num; i++)
764 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
765 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
766 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000767 }
768
paul0a589352004-05-08 11:48:26 +0000769 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
770 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000771 }
Lou Berger205e6742016-01-12 13:42:11 -0500772
paul718e3742002-12-13 20:15:29 +0000773 /* We have to think about a IPv6 link-local address curse. */
774 if (p->family == AF_INET6)
775 {
Paul Jakma9099f9b2016-01-18 10:12:10 +0000776 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000777 struct in6_addr *nexthop;
778 struct zapi_ipv6 api;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500779 int valid_nh_count = 0;
780
781 /* resize nexthop buffer size if necessary */
782 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
783 (sizeof (struct in6_addr *) * nhcount))
784 {
785 newsize = (sizeof (struct in6_addr *) * nhcount);
786 newsize = stream_resize (bgp_nexthop_buf, newsize);
787 if (newsize == oldsize)
788 {
789 zlog_err ("can't resize nexthop buffer");
790 return;
791 }
792 }
793 stream_reset (bgp_nexthop_buf);
794
795 /* resize ifindices buffer size if necessary */
796 if ((oldsize = stream_get_size (bgp_ifindices_buf)) <
797 (sizeof (unsigned int) * nhcount))
798 {
799 newsize = (sizeof (unsigned int) * nhcount);
800 newsize = stream_resize (bgp_ifindices_buf, newsize);
801 if (newsize == oldsize)
802 {
803 zlog_err ("can't resize nexthop buffer");
804 return;
805 }
806 }
807 stream_reset (bgp_ifindices_buf);
paul718e3742002-12-13 20:15:29 +0000808
809 ifindex = 0;
810 nexthop = NULL;
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500811
Paul Jakmafb982c22007-05-04 20:15:47 +0000812 assert (info->attr->extra);
813
paul718e3742002-12-13 20:15:29 +0000814 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000815 if (info->attr->extra->mp_nexthop_len == 16)
816 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000817
818 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000819 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000820 {
821 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000822 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000823 && peer->su_remote->sa.sa_family == AF_INET6)
824 nexthop = &peer->su_remote->sin6.sin6_addr;
825 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000826 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000827
828 if (info->peer->nexthop.ifp)
829 ifindex = info->peer->nexthop.ifp->ifindex;
830 }
831
832 if (nexthop == NULL)
833 return;
834
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500835 if (!ifindex)
paul718e3742002-12-13 20:15:29 +0000836 {
837 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200838 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000839 else if (info->peer->nexthop.ifp)
840 ifindex = info->peer->nexthop.ifp->ifindex;
841 }
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500842 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
843 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
844 valid_nh_count++;
845
846 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
847 mpinfo = bgp_info_mpath_next (mpinfo))
848 {
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500849 ifindex = 0;
850
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500851 /* Only global address nexthop exists. */
852 if (mpinfo->attr->extra->mp_nexthop_len == 16)
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500853 nexthop = &mpinfo->attr->extra->mp_nexthop_global;
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500854
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500855 /* If both global and link-local address present. */
856 if (mpinfo->attr->extra->mp_nexthop_len == 32)
857 {
858 /* Workaround for Cisco's nexthop bug. */
859 if (IN6_IS_ADDR_UNSPECIFIED (&mpinfo->attr->extra->mp_nexthop_global)
860 && mpinfo->peer->su_remote->sa.sa_family == AF_INET6)
861 {
862 nexthop = &mpinfo->peer->su_remote->sin6.sin6_addr;
863 }
864 else
865 {
866 nexthop = &mpinfo->attr->extra->mp_nexthop_local;
867 }
868
869 if (mpinfo->peer->nexthop.ifp)
870 {
871 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
872 }
873 }
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500874
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500875 if (nexthop == NULL)
876 {
877 continue;
878 }
879
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500880 if (!ifindex)
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500881 {
882 if (mpinfo->peer->ifname)
883 {
884 ifindex = if_nametoindex (mpinfo->peer->ifname);
885 }
886 else if (mpinfo->peer->nexthop.ifp)
887 {
888 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
889 }
890 }
Dinesh Dutt4feb0d02015-11-09 20:14:55 -0500891
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500892 if (ifindex == 0)
893 {
894 continue;
895 }
896
897 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
898 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
899 valid_nh_count++;
900 }
paul718e3742002-12-13 20:15:29 +0000901
902 /* Make Zebra API structure. */
Feng Luc99f3482014-10-16 09:52:36 +0800903 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000904 api.flags = flags;
905 api.type = ZEBRA_ROUTE_BGP;
906 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400907 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000908 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500909 api.nexthop_num = valid_nh_count;
910 api.nexthop = (struct in6_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000911 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500912 api.ifindex_num = valid_nh_count;
913 api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf);
paul718e3742002-12-13 20:15:29 +0000914 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
915 api.metric = info->attr->med;
916
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100917 distance = ipv6_bgp_distance_apply (p, info, bgp);
918
919 if (distance)
920 {
921 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
922 api.distance = distance;
923 }
924
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000925 if (BGP_DEBUG(zebra, ZEBRA))
926 {
927 char buf[2][INET6_ADDRSTRLEN];
928 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
929 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
930 p->prefixlen,
931 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
932 api.metric);
933 }
934
paul0a589352004-05-08 11:48:26 +0000935 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
936 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000937 }
paul718e3742002-12-13 20:15:29 +0000938}
939
940void
G.Balaji5a616c02011-11-26 21:58:42 +0400941bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000942{
943 int flags;
944 struct peer *peer;
945
946 if (zclient->sock < 0)
947 return;
948
Feng Luc99f3482014-10-16 09:52:36 +0800949 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000950 return;
951
952 peer = info->peer;
953 flags = 0;
954
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000955 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000956 {
957 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
958 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
959 }
960
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000961 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000962 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000963 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
964
965 if (p->family == AF_INET)
966 {
967 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000968
Feng Luc99f3482014-10-16 09:52:36 +0800969 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000970 api.flags = flags;
paul718e3742002-12-13 20:15:29 +0000971
972 api.type = ZEBRA_ROUTE_BGP;
973 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400974 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +0000975 api.nexthop_num = 0;
paul718e3742002-12-13 20:15:29 +0000976 api.ifindex_num = 0;
977 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
978 api.metric = info->attr->med;
979
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000980 if (BGP_DEBUG(zebra, ZEBRA))
981 {
982 char buf[2][INET_ADDRSTRLEN];
Paul Jakma64e0ac22015-11-18 16:00:54 +0000983 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000984 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
985 p->prefixlen,
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000986 api.metric);
987 }
988
paul0a589352004-05-08 11:48:26 +0000989 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
990 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000991 }
Lou Berger205e6742016-01-12 13:42:11 -0500992
paul718e3742002-12-13 20:15:29 +0000993 /* We have to think about a IPv6 link-local address curse. */
994 if (p->family == AF_INET6)
995 {
996 struct zapi_ipv6 api;
Paul Jakmafb982c22007-05-04 20:15:47 +0000997
Feng Luc99f3482014-10-16 09:52:36 +0800998 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000999 api.flags = flags;
1000 api.type = ZEBRA_ROUTE_BGP;
1001 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +04001002 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +00001003 api.nexthop_num = 0;
1004 api.ifindex_num = 0;
paul718e3742002-12-13 20:15:29 +00001005 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1006 api.metric = info->attr->med;
1007
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001008 if (BGP_DEBUG(zebra, ZEBRA))
1009 {
1010 char buf[2][INET6_ADDRSTRLEN];
Paul Jakma64e0ac22015-11-18 16:00:54 +00001011 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001012 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
1013 p->prefixlen,
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001014 api.metric);
1015 }
1016
paul0a589352004-05-08 11:48:26 +00001017 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
1018 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +00001019 }
paul718e3742002-12-13 20:15:29 +00001020}
David Lamparter6b0655a2014-06-04 06:53:35 +02001021
paul718e3742002-12-13 20:15:29 +00001022/* Other routes redistribution into BGP. */
1023int
1024bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
1025{
1026 /* Set flag to BGP instance. */
1027 bgp->redist[afi][type] = 1;
1028
1029 /* Return if already redistribute flag is set. */
Feng Luc99f3482014-10-16 09:52:36 +08001030 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001031 return CMD_WARNING;
1032
Feng Luc99f3482014-10-16 09:52:36 +08001033 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001034
1035 /* Return if zebra connection is not established. */
1036 if (zclient->sock < 0)
1037 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001038
1039 if (BGP_DEBUG(zebra, ZEBRA))
1040 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +00001041
1042 /* Send distribute add message to zebra. */
Feng Luc99f3482014-10-16 09:52:36 +08001043 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001044
1045 return CMD_SUCCESS;
1046}
1047
1048/* Redistribute with route-map specification. */
1049int
paulfd79ac92004-10-13 05:06:08 +00001050bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
1051 const char *name)
paul718e3742002-12-13 20:15:29 +00001052{
1053 if (bgp->rmap[afi][type].name
1054 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
1055 return 0;
1056
1057 if (bgp->rmap[afi][type].name)
1058 free (bgp->rmap[afi][type].name);
1059 bgp->rmap[afi][type].name = strdup (name);
1060 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
1061
1062 return 1;
1063}
1064
1065/* Redistribute with metric specification. */
1066int
1067bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
1068 u_int32_t metric)
1069{
1070 if (bgp->redist_metric_flag[afi][type]
1071 && bgp->redist_metric[afi][type] == metric)
1072 return 0;
1073
1074 bgp->redist_metric_flag[afi][type] = 1;
1075 bgp->redist_metric[afi][type] = metric;
1076
1077 return 1;
1078}
1079
1080/* Unset redistribution. */
1081int
1082bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
1083{
1084 /* Unset flag from BGP instance. */
1085 bgp->redist[afi][type] = 0;
1086
1087 /* Unset route-map. */
1088 if (bgp->rmap[afi][type].name)
1089 free (bgp->rmap[afi][type].name);
1090 bgp->rmap[afi][type].name = NULL;
1091 bgp->rmap[afi][type].map = NULL;
1092
1093 /* Unset metric. */
1094 bgp->redist_metric_flag[afi][type] = 0;
1095 bgp->redist_metric[afi][type] = 0;
1096
1097 /* Return if zebra connection is disabled. */
Feng Luc99f3482014-10-16 09:52:36 +08001098 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001099 return CMD_WARNING;
Feng Luc99f3482014-10-16 09:52:36 +08001100 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001101
1102 if (bgp->redist[AFI_IP][type] == 0
1103 && bgp->redist[AFI_IP6][type] == 0
1104 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001105 {
1106 /* Send distribute delete message to zebra. */
1107 if (BGP_DEBUG(zebra, ZEBRA))
1108 zlog_debug("Zebra send: redistribute delete %s",
1109 zebra_route_string(type));
Feng Luc99f3482014-10-16 09:52:36 +08001110 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
1111 VRF_DEFAULT);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001112 }
paul718e3742002-12-13 20:15:29 +00001113
1114 /* Withdraw redistributed routes from current BGP's routing table. */
1115 bgp_redistribute_withdraw (bgp, afi, type);
1116
1117 return CMD_SUCCESS;
1118}
1119
paul718e3742002-12-13 20:15:29 +00001120void
paul94f2b392005-06-28 12:44:16 +00001121bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001122{
1123 zclient_reset (zclient);
1124}
1125
Feng Luc99f3482014-10-16 09:52:36 +08001126static void
1127bgp_zebra_connected (struct zclient *zclient)
1128{
1129 zclient_send_requests (zclient, VRF_DEFAULT);
1130}
1131
paul718e3742002-12-13 20:15:29 +00001132void
Donald Sharp71252932015-09-24 09:25:19 -04001133bgp_zebra_init (struct thread_master *master)
paul718e3742002-12-13 20:15:29 +00001134{
1135 /* Set default values. */
Donald Sharp71252932015-09-24 09:25:19 -04001136 zclient = zclient_new (master);
paul718e3742002-12-13 20:15:29 +00001137 zclient_init (zclient, ZEBRA_ROUTE_BGP);
Feng Luc99f3482014-10-16 09:52:36 +08001138 zclient->zebra_connected = bgp_zebra_connected;
hasso18a6dce2004-10-03 18:18:34 +00001139 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001140 zclient->interface_add = bgp_interface_add;
1141 zclient->interface_delete = bgp_interface_delete;
1142 zclient->interface_address_add = bgp_interface_address_add;
1143 zclient->interface_address_delete = bgp_interface_address_delete;
1144 zclient->ipv4_route_add = zebra_read_ipv4;
1145 zclient->ipv4_route_delete = zebra_read_ipv4;
1146 zclient->interface_up = bgp_interface_up;
1147 zclient->interface_down = bgp_interface_down;
paul718e3742002-12-13 20:15:29 +00001148 zclient->ipv6_route_add = zebra_read_ipv6;
1149 zclient->ipv6_route_delete = zebra_read_ipv6;
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001150 zclient->nexthop_update = bgp_read_nexthop_update;
paul718e3742002-12-13 20:15:29 +00001151
Josh Bailey8196f132011-07-20 20:47:07 -07001152 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -05001153 bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001154}
Lou Berger82dd7072016-01-12 13:41:57 -05001155
1156void
1157bgp_zebra_destroy(void)
1158{
1159 if (zclient == NULL)
1160 return;
1161 zclient_stop(zclient);
1162 zclient_free(zclient);
1163 zclient = NULL;
1164}