blob: 4066a9a18b0e8212eb720c61037557fa74993893 [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"
David Lamparter6b0655a2014-06-04 06:53:35 +020042
paul718e3742002-12-13 20:15:29 +000043/* All information about zebra. */
Chris Caputo228da422009-07-18 05:44:03 +000044struct zclient *zclient = NULL;
hasso18a6dce2004-10-03 18:18:34 +000045struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000046
Josh Bailey8196f132011-07-20 20:47:07 -070047/* Growable buffer for nexthops sent to zebra */
48struct stream *bgp_nexthop_buf = NULL;
49
hasso18a6dce2004-10-03 18:18:34 +000050/* Router-id update message from zebra. */
paul94f2b392005-06-28 12:44:16 +000051static int
Feng Luc99f3482014-10-16 09:52:36 +080052bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
53 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000054{
hasso18a6dce2004-10-03 18:18:34 +000055 struct prefix router_id;
paul1eb8ef22005-04-07 07:30:20 +000056 struct listnode *node, *nnode;
hasso18a6dce2004-10-03 18:18:34 +000057 struct bgp *bgp;
paul718e3742002-12-13 20:15:29 +000058
hasso18a6dce2004-10-03 18:18:34 +000059 zebra_router_id_update_read(zclient->ibuf,&router_id);
Andrew J. Schorra39275d2006-11-30 16:36:57 +000060
61 if (BGP_DEBUG(zebra, ZEBRA))
62 {
63 char buf[128];
64 prefix2str(&router_id, buf, sizeof(buf));
65 zlog_debug("Zebra rcvd: router id update %s", buf);
66 }
67
hasso18a6dce2004-10-03 18:18:34 +000068 router_id_zebra = router_id.u.prefix4;
69
paul1eb8ef22005-04-07 07:30:20 +000070 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
paul718e3742002-12-13 20:15:29 +000071 {
hasso18a6dce2004-10-03 18:18:34 +000072 if (!bgp->router_id_static.s_addr)
paul1eb8ef22005-04-07 07:30:20 +000073 bgp_router_id_set (bgp, &router_id.u.prefix4);
paul718e3742002-12-13 20:15:29 +000074 }
paul718e3742002-12-13 20:15:29 +000075
paul718e3742002-12-13 20:15:29 +000076 return 0;
77}
78
79/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000080static int
Feng Luc99f3482014-10-16 09:52:36 +080081bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
82 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000083{
84 struct interface *ifp;
85
Feng Luc99f3482014-10-16 09:52:36 +080086 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +000087
Andrew J. Schorra39275d2006-11-30 16:36:57 +000088 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
89 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
90
paul718e3742002-12-13 20:15:29 +000091 return 0;
92}
93
paul94f2b392005-06-28 12:44:16 +000094static int
paul718e3742002-12-13 20:15:29 +000095bgp_interface_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +080096 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000097{
98 struct stream *s;
99 struct interface *ifp;
100
101 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800102 ifp = zebra_interface_state_read (s, vrf_id);
ajsd2fc8892005-04-02 18:38:43 +0000103 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000104
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000105 if (BGP_DEBUG(zebra, ZEBRA))
106 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
107
paul718e3742002-12-13 20:15:29 +0000108 return 0;
109}
110
paul94f2b392005-06-28 12:44:16 +0000111static int
Feng Luc99f3482014-10-16 09:52:36 +0800112bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
113 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000114{
115 struct stream *s;
116 struct interface *ifp;
117 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000118 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000119
120 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800121 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000122
123 if (! ifp)
124 return 0;
125
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000126 if (BGP_DEBUG(zebra, ZEBRA))
127 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
128
paul1eb8ef22005-04-07 07:30:20 +0000129 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
130 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000131
132 return 0;
133}
134
paul94f2b392005-06-28 12:44:16 +0000135static int
Feng Luc99f3482014-10-16 09:52:36 +0800136bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
137 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000138{
139 struct stream *s;
140 struct interface *ifp;
141 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000142 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000143
144 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800145 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000146 if (! ifp)
147 return 0;
148
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000149 if (BGP_DEBUG(zebra, ZEBRA))
150 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
151
paul1eb8ef22005-04-07 07:30:20 +0000152 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
153 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000154
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000155 /* Fast external-failover */
paul718e3742002-12-13 20:15:29 +0000156 {
paul1eb8ef22005-04-07 07:30:20 +0000157 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000158 struct bgp *bgp;
159 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000160
paul1eb8ef22005-04-07 07:30:20 +0000161 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000162 {
163 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
164 continue;
165
paul1eb8ef22005-04-07 07:30:20 +0000166 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000167 {
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000168 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
paul718e3742002-12-13 20:15:29 +0000169 continue;
170
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000171 if (ifp == peer->nexthop.ifp)
paul718e3742002-12-13 20:15:29 +0000172 BGP_EVENT_ADD (peer, BGP_Stop);
173 }
174 }
175 }
176
177 return 0;
178}
179
paul94f2b392005-06-28 12:44:16 +0000180static int
paul718e3742002-12-13 20:15:29 +0000181bgp_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800182 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000183{
184 struct connected *ifc;
185
Feng Luc99f3482014-10-16 09:52:36 +0800186 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000187
188 if (ifc == NULL)
189 return 0;
190
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000191 if (BGP_DEBUG(zebra, ZEBRA))
192 {
193 char buf[128];
194 prefix2str(ifc->address, buf, sizeof(buf));
195 zlog_debug("Zebra rcvd: interface %s address add %s",
196 ifc->ifp->name, buf);
197 }
198
paul2e3b2e42002-12-13 21:03:13 +0000199 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000200 bgp_connected_add (ifc);
201
202 return 0;
203}
204
paul94f2b392005-06-28 12:44:16 +0000205static int
paul718e3742002-12-13 20:15:29 +0000206bgp_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800207 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000208{
209 struct connected *ifc;
210
Feng Luc99f3482014-10-16 09:52:36 +0800211 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000212
213 if (ifc == NULL)
214 return 0;
215
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000216 if (BGP_DEBUG(zebra, ZEBRA))
217 {
218 char buf[128];
219 prefix2str(ifc->address, buf, sizeof(buf));
220 zlog_debug("Zebra rcvd: interface %s address delete %s",
221 ifc->ifp->name, buf);
222 }
223
paul2e3b2e42002-12-13 21:03:13 +0000224 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000225 bgp_connected_delete (ifc);
226
227 connected_free (ifc);
228
229 return 0;
230}
231
232/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000233static int
Feng Luc99f3482014-10-16 09:52:36 +0800234zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
235 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000236{
237 struct stream *s;
238 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000239 struct in_addr nexthop;
240 struct prefix_ipv4 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500241 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000242
243 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000244 nexthop.s_addr = 0;
245
246 /* Type, flags, message. */
247 api.type = stream_getc (s);
248 api.flags = stream_getc (s);
249 api.message = stream_getc (s);
250
251 /* IPv4 prefix. */
252 memset (&p, 0, sizeof (struct prefix_ipv4));
253 p.family = AF_INET;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500254 plength = stream_getc (s);
255 p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000256 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
257
258 /* Nexthop, ifindex, distance, metric. */
259 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
260 {
261 api.nexthop_num = stream_getc (s);
262 nexthop.s_addr = stream_get_ipv4 (s);
263 }
264 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
265 {
266 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400267 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000268 }
269 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
270 api.distance = stream_getc (s);
271 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
272 api.metric = stream_getl (s);
273 else
274 api.metric = 0;
275
276 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000277 {
278 if (BGP_DEBUG(zebra, ZEBRA))
279 {
280 char buf[2][INET_ADDRSTRLEN];
281 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
282 zebra_route_string(api.type),
283 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
284 p.prefixlen,
285 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
286 api.metric);
287 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400288 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
289 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000290 }
paul718e3742002-12-13 20:15:29 +0000291 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000292 {
293 if (BGP_DEBUG(zebra, ZEBRA))
294 {
295 char buf[2][INET_ADDRSTRLEN];
296 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
297 "nexthop %s metric %u",
298 zebra_route_string(api.type),
299 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
300 p.prefixlen,
301 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
302 api.metric);
303 }
304 bgp_redistribute_delete((struct prefix *)&p, api.type);
305 }
paul718e3742002-12-13 20:15:29 +0000306
307 return 0;
308}
309
paul718e3742002-12-13 20:15:29 +0000310/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000311static int
Feng Luc99f3482014-10-16 09:52:36 +0800312zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
313 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000314{
315 struct stream *s;
316 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000317 struct in6_addr nexthop;
318 struct prefix_ipv6 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500319 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000320
321 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000322 memset (&nexthop, 0, sizeof (struct in6_addr));
323
324 /* Type, flags, message. */
325 api.type = stream_getc (s);
326 api.flags = stream_getc (s);
327 api.message = stream_getc (s);
328
329 /* IPv6 prefix. */
330 memset (&p, 0, sizeof (struct prefix_ipv6));
331 p.family = AF_INET6;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500332 plength = stream_getc (s);
333 p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000334 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
335
336 /* Nexthop, ifindex, distance, metric. */
337 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
338 {
339 api.nexthop_num = stream_getc (s);
340 stream_get (&nexthop, s, 16);
341 }
342 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
343 {
344 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400345 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000346 }
347 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
348 api.distance = stream_getc (s);
349 else
350 api.distance = 0;
351 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
352 api.metric = stream_getl (s);
353 else
354 api.metric = 0;
355
356 /* Simply ignore link-local address. */
357 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
358 return 0;
359
360 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000361 {
362 if (BGP_DEBUG(zebra, ZEBRA))
363 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400364 char buf[2][INET6_ADDRSTRLEN];
365 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000366 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400367 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
368 p.prefixlen,
369 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
370 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000371 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400372 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
373 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000374 }
paul718e3742002-12-13 20:15:29 +0000375 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000376 {
377 if (BGP_DEBUG(zebra, ZEBRA))
378 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400379 char buf[2][INET6_ADDRSTRLEN];
380 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
381 "nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000382 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400383 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
384 p.prefixlen,
385 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
386 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000387 }
388 bgp_redistribute_delete ((struct prefix *) &p, api.type);
389 }
paul718e3742002-12-13 20:15:29 +0000390
391 return 0;
392}
David Lamparter6b0655a2014-06-04 06:53:35 +0200393
paul718e3742002-12-13 20:15:29 +0000394struct interface *
395if_lookup_by_ipv4 (struct in_addr *addr)
396{
hasso52dc7ee2004-09-23 19:18:23 +0000397 struct listnode *ifnode;
398 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000399 struct interface *ifp;
400 struct connected *connected;
401 struct prefix_ipv4 p;
402 struct prefix *cp;
403
404 p.family = AF_INET;
405 p.prefix = *addr;
406 p.prefixlen = IPV4_MAX_BITLEN;
407
paul1eb8ef22005-04-07 07:30:20 +0000408 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000409 {
paul1eb8ef22005-04-07 07:30:20 +0000410 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000411 {
paul718e3742002-12-13 20:15:29 +0000412 cp = connected->address;
413
414 if (cp->family == AF_INET)
415 if (prefix_match (cp, (struct prefix *)&p))
416 return ifp;
417 }
418 }
419 return NULL;
420}
421
422struct interface *
423if_lookup_by_ipv4_exact (struct in_addr *addr)
424{
hasso52dc7ee2004-09-23 19:18:23 +0000425 struct listnode *ifnode;
426 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000427 struct interface *ifp;
428 struct connected *connected;
429 struct prefix *cp;
430
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000432 {
paul1eb8ef22005-04-07 07:30:20 +0000433 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000434 {
paul718e3742002-12-13 20:15:29 +0000435 cp = connected->address;
436
437 if (cp->family == AF_INET)
438 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
439 return ifp;
440 }
441 }
442 return NULL;
443}
444
paul718e3742002-12-13 20:15:29 +0000445struct interface *
446if_lookup_by_ipv6 (struct in6_addr *addr)
447{
hasso52dc7ee2004-09-23 19:18:23 +0000448 struct listnode *ifnode;
449 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000450 struct interface *ifp;
451 struct connected *connected;
452 struct prefix_ipv6 p;
453 struct prefix *cp;
454
455 p.family = AF_INET6;
456 p.prefix = *addr;
457 p.prefixlen = IPV6_MAX_BITLEN;
458
paul1eb8ef22005-04-07 07:30:20 +0000459 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000460 {
paul1eb8ef22005-04-07 07:30:20 +0000461 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000462 {
paul718e3742002-12-13 20:15:29 +0000463 cp = connected->address;
464
465 if (cp->family == AF_INET6)
466 if (prefix_match (cp, (struct prefix *)&p))
467 return ifp;
468 }
469 }
470 return NULL;
471}
472
473struct interface *
474if_lookup_by_ipv6_exact (struct in6_addr *addr)
475{
hasso52dc7ee2004-09-23 19:18:23 +0000476 struct listnode *ifnode;
477 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000478 struct interface *ifp;
479 struct connected *connected;
480 struct prefix *cp;
481
paul1eb8ef22005-04-07 07:30:20 +0000482 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000483 {
paul1eb8ef22005-04-07 07:30:20 +0000484 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000485 {
paul718e3742002-12-13 20:15:29 +0000486 cp = connected->address;
487
488 if (cp->family == AF_INET6)
489 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
490 return ifp;
491 }
492 }
493 return NULL;
494}
495
paul94f2b392005-06-28 12:44:16 +0000496static int
paul718e3742002-12-13 20:15:29 +0000497if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
498{
hasso52dc7ee2004-09-23 19:18:23 +0000499 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000500 struct connected *connected;
501 struct prefix *cp;
502
paul1eb8ef22005-04-07 07:30:20 +0000503 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000504 {
paul718e3742002-12-13 20:15:29 +0000505 cp = connected->address;
506
507 if (cp->family == AF_INET6)
508 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
509 {
510 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
511 return 1;
512 }
513 }
514 return 0;
515}
516
paul94f2b392005-06-28 12:44:16 +0000517static int
paul718e3742002-12-13 20:15:29 +0000518if_get_ipv6_local (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}
paul718e3742002-12-13 20:15:29 +0000537
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000538static int
539if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
540{
541 struct listnode *cnode;
542 struct connected *connected;
543 struct prefix *cp;
544
545 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
546 {
547 cp = connected->address;
548 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
549 {
550 *addr = cp->u.prefix4;
551 return 1;
552 }
553 }
554 return 0;
555}
556
paul718e3742002-12-13 20:15:29 +0000557int
558bgp_nexthop_set (union sockunion *local, union sockunion *remote,
559 struct bgp_nexthop *nexthop, struct peer *peer)
560{
561 int ret = 0;
562 struct interface *ifp = NULL;
563
564 memset (nexthop, 0, sizeof (struct bgp_nexthop));
565
566 if (!local)
567 return -1;
568 if (!remote)
569 return -1;
570
571 if (local->sa.sa_family == AF_INET)
572 {
573 nexthop->v4 = local->sin.sin_addr;
574 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
575 }
paul718e3742002-12-13 20:15:29 +0000576 if (local->sa.sa_family == AF_INET6)
577 {
578 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
579 {
580 if (peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200581 ifp = if_lookup_by_name (peer->ifname);
paul718e3742002-12-13 20:15:29 +0000582 }
583 else
584 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
585 }
paul718e3742002-12-13 20:15:29 +0000586
587 if (!ifp)
588 return -1;
589
590 nexthop->ifp = ifp;
591
592 /* IPv4 connection. */
593 if (local->sa.sa_family == AF_INET)
594 {
paul718e3742002-12-13 20:15:29 +0000595 /* IPv6 nexthop*/
596 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
597
598 /* There is no global nexthop. */
599 if (!ret)
600 if_get_ipv6_local (ifp, &nexthop->v6_global);
601 else
602 if_get_ipv6_local (ifp, &nexthop->v6_local);
paul718e3742002-12-13 20:15:29 +0000603 }
604
paul718e3742002-12-13 20:15:29 +0000605 /* IPv6 connection. */
606 if (local->sa.sa_family == AF_INET6)
607 {
608 struct interface *direct = NULL;
609
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000610 /* IPv4 nexthop. */
611 ret = if_get_ipv4_address(ifp, &nexthop->v4);
612 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000613 nexthop->v4 = peer->local_id;
614
615 /* Global address*/
616 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
617 {
618 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
619 IPV6_MAX_BYTELEN);
620
621 /* If directory connected set link-local address. */
622 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
623 if (direct)
624 if_get_ipv6_local (ifp, &nexthop->v6_local);
625 }
626 else
627 /* Link-local address. */
628 {
629 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
630
631 /* If there is no global address. Set link-local address as
632 global. I know this break RFC specification... */
633 if (!ret)
634 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
635 IPV6_MAX_BYTELEN);
636 else
637 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
638 IPV6_MAX_BYTELEN);
639 }
640 }
641
642 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
643 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
644 peer->shared_network = 1;
645 else
646 peer->shared_network = 0;
647
648 /* KAME stack specific treatment. */
649#ifdef KAME
650 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
651 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
652 {
653 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
654 }
655 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
656 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
657 {
658 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
659 }
660#endif /* KAME */
paul718e3742002-12-13 20:15:29 +0000661 return ret;
662}
663
paul718e3742002-12-13 20:15:29 +0000664void
G.Balaji5a616c02011-11-26 21:58:42 +0400665bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000666{
667 int flags;
668 u_char distance;
669 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700670 struct bgp_info *mpinfo;
671 size_t oldsize, newsize;
paul718e3742002-12-13 20:15:29 +0000672
673 if (zclient->sock < 0)
674 return;
675
Feng Luc99f3482014-10-16 09:52:36 +0800676 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000677 return;
678
679 flags = 0;
680 peer = info->peer;
681
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000682 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000683 {
684 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
685 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
686 }
687
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000688 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000689 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000690 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
691
Josh Bailey8196f132011-07-20 20:47:07 -0700692 /* resize nexthop buffer size if necessary */
693 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
694 (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
695 {
696 newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
697 newsize = stream_resize (bgp_nexthop_buf, newsize);
698 if (newsize == oldsize)
699 {
700 zlog_err ("can't resize nexthop buffer");
701 return;
702 }
703 }
704
705 stream_reset (bgp_nexthop_buf);
706
paul718e3742002-12-13 20:15:29 +0000707 if (p->family == AF_INET)
708 {
709 struct zapi_ipv4 api;
710 struct in_addr *nexthop;
711
Feng Luc99f3482014-10-16 09:52:36 +0800712 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000713 api.flags = flags;
714 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700715 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
716 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
717 mpinfo = bgp_info_mpath_next (mpinfo))
718 {
719 nexthop = &mpinfo->attr->nexthop;
720 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
721 }
paul718e3742002-12-13 20:15:29 +0000722
723 api.type = ZEBRA_ROUTE_BGP;
724 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400725 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000726 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Josh Bailey8196f132011-07-20 20:47:07 -0700727 api.nexthop_num = 1 + bgp_info_mpath_count (info);
728 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000729 api.ifindex_num = 0;
730 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
731 api.metric = info->attr->med;
732
733 distance = bgp_distance_apply (p, info, bgp);
734
735 if (distance)
736 {
737 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
738 api.distance = distance;
739 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000740
741 if (BGP_DEBUG(zebra, ZEBRA))
742 {
Josh Bailey8196f132011-07-20 20:47:07 -0700743 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000744 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700745 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
746 " count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000747 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
748 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700749 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
750 api.metric, api.nexthop_num);
751 for (i = 1; i < api.nexthop_num; i++)
752 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
753 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
754 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000755 }
756
paul0a589352004-05-08 11:48:26 +0000757 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
758 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000759 }
Lou Berger205e6742016-01-12 13:42:11 -0500760
paul718e3742002-12-13 20:15:29 +0000761 /* We have to think about a IPv6 link-local address curse. */
762 if (p->family == AF_INET6)
763 {
Paul Jakma9099f9b2016-01-18 10:12:10 +0000764 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000765 struct in6_addr *nexthop;
766 struct zapi_ipv6 api;
767
768 ifindex = 0;
769 nexthop = NULL;
Paul Jakmafb982c22007-05-04 20:15:47 +0000770
771 assert (info->attr->extra);
772
paul718e3742002-12-13 20:15:29 +0000773 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000774 if (info->attr->extra->mp_nexthop_len == 16)
775 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000776
777 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000778 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000779 {
780 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000781 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000782 && peer->su_remote->sa.sa_family == AF_INET6)
783 nexthop = &peer->su_remote->sin6.sin6_addr;
784 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000785 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000786
787 if (info->peer->nexthop.ifp)
788 ifindex = info->peer->nexthop.ifp->ifindex;
789 }
790
791 if (nexthop == NULL)
792 return;
793
794 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
795 {
796 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200797 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000798 else if (info->peer->nexthop.ifp)
799 ifindex = info->peer->nexthop.ifp->ifindex;
800 }
801
802 /* Make Zebra API structure. */
Feng Luc99f3482014-10-16 09:52:36 +0800803 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000804 api.flags = flags;
805 api.type = ZEBRA_ROUTE_BGP;
806 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400807 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000808 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
809 api.nexthop_num = 1;
810 api.nexthop = &nexthop;
811 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
812 api.ifindex_num = 1;
813 api.ifindex = &ifindex;
814 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
815 api.metric = info->attr->med;
816
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100817 distance = ipv6_bgp_distance_apply (p, info, bgp);
818
819 if (distance)
820 {
821 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
822 api.distance = distance;
823 }
824
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000825 if (BGP_DEBUG(zebra, ZEBRA))
826 {
827 char buf[2][INET6_ADDRSTRLEN];
828 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
829 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
830 p->prefixlen,
831 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
832 api.metric);
833 }
834
paul0a589352004-05-08 11:48:26 +0000835 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
836 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000837 }
paul718e3742002-12-13 20:15:29 +0000838}
839
840void
G.Balaji5a616c02011-11-26 21:58:42 +0400841bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000842{
843 int flags;
844 struct peer *peer;
845
846 if (zclient->sock < 0)
847 return;
848
Feng Luc99f3482014-10-16 09:52:36 +0800849 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000850 return;
851
852 peer = info->peer;
853 flags = 0;
854
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000855 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000856 {
857 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
858 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
859 }
860
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000861 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000862 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000863 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
864
865 if (p->family == AF_INET)
866 {
867 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000868
Feng Luc99f3482014-10-16 09:52:36 +0800869 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000870 api.flags = flags;
paul718e3742002-12-13 20:15:29 +0000871
872 api.type = ZEBRA_ROUTE_BGP;
873 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400874 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +0000875 api.nexthop_num = 0;
paul718e3742002-12-13 20:15:29 +0000876 api.ifindex_num = 0;
877 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
878 api.metric = info->attr->med;
879
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000880 if (BGP_DEBUG(zebra, ZEBRA))
881 {
882 char buf[2][INET_ADDRSTRLEN];
Paul Jakma64e0ac22015-11-18 16:00:54 +0000883 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000884 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
885 p->prefixlen,
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000886 api.metric);
887 }
888
paul0a589352004-05-08 11:48:26 +0000889 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
890 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000891 }
Lou Berger205e6742016-01-12 13:42:11 -0500892
paul718e3742002-12-13 20:15:29 +0000893 /* We have to think about a IPv6 link-local address curse. */
894 if (p->family == AF_INET6)
895 {
896 struct zapi_ipv6 api;
Paul Jakmafb982c22007-05-04 20:15:47 +0000897
Feng Luc99f3482014-10-16 09:52:36 +0800898 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000899 api.flags = flags;
900 api.type = ZEBRA_ROUTE_BGP;
901 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400902 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +0000903 api.nexthop_num = 0;
904 api.ifindex_num = 0;
paul718e3742002-12-13 20:15:29 +0000905 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
906 api.metric = info->attr->med;
907
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000908 if (BGP_DEBUG(zebra, ZEBRA))
909 {
910 char buf[2][INET6_ADDRSTRLEN];
Paul Jakma64e0ac22015-11-18 16:00:54 +0000911 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000912 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
913 p->prefixlen,
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000914 api.metric);
915 }
916
paul0a589352004-05-08 11:48:26 +0000917 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
918 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000919 }
paul718e3742002-12-13 20:15:29 +0000920}
David Lamparter6b0655a2014-06-04 06:53:35 +0200921
paul718e3742002-12-13 20:15:29 +0000922/* Other routes redistribution into BGP. */
923int
924bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
925{
926 /* Set flag to BGP instance. */
927 bgp->redist[afi][type] = 1;
928
929 /* Return if already redistribute flag is set. */
Feng Luc99f3482014-10-16 09:52:36 +0800930 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000931 return CMD_WARNING;
932
Feng Luc99f3482014-10-16 09:52:36 +0800933 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000934
935 /* Return if zebra connection is not established. */
936 if (zclient->sock < 0)
937 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000938
939 if (BGP_DEBUG(zebra, ZEBRA))
940 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000941
942 /* Send distribute add message to zebra. */
Feng Luc99f3482014-10-16 09:52:36 +0800943 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000944
945 return CMD_SUCCESS;
946}
947
948/* Redistribute with route-map specification. */
949int
paulfd79ac92004-10-13 05:06:08 +0000950bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
951 const char *name)
paul718e3742002-12-13 20:15:29 +0000952{
953 if (bgp->rmap[afi][type].name
954 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
955 return 0;
956
957 if (bgp->rmap[afi][type].name)
958 free (bgp->rmap[afi][type].name);
959 bgp->rmap[afi][type].name = strdup (name);
960 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
961
962 return 1;
963}
964
965/* Redistribute with metric specification. */
966int
967bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
968 u_int32_t metric)
969{
970 if (bgp->redist_metric_flag[afi][type]
971 && bgp->redist_metric[afi][type] == metric)
972 return 0;
973
974 bgp->redist_metric_flag[afi][type] = 1;
975 bgp->redist_metric[afi][type] = metric;
976
977 return 1;
978}
979
980/* Unset redistribution. */
981int
982bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
983{
984 /* Unset flag from BGP instance. */
985 bgp->redist[afi][type] = 0;
986
987 /* Unset route-map. */
988 if (bgp->rmap[afi][type].name)
989 free (bgp->rmap[afi][type].name);
990 bgp->rmap[afi][type].name = NULL;
991 bgp->rmap[afi][type].map = NULL;
992
993 /* Unset metric. */
994 bgp->redist_metric_flag[afi][type] = 0;
995 bgp->redist_metric[afi][type] = 0;
996
997 /* Return if zebra connection is disabled. */
Feng Luc99f3482014-10-16 09:52:36 +0800998 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000999 return CMD_WARNING;
Feng Luc99f3482014-10-16 09:52:36 +08001000 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001001
1002 if (bgp->redist[AFI_IP][type] == 0
1003 && bgp->redist[AFI_IP6][type] == 0
1004 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001005 {
1006 /* Send distribute delete message to zebra. */
1007 if (BGP_DEBUG(zebra, ZEBRA))
1008 zlog_debug("Zebra send: redistribute delete %s",
1009 zebra_route_string(type));
Feng Luc99f3482014-10-16 09:52:36 +08001010 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
1011 VRF_DEFAULT);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001012 }
paul718e3742002-12-13 20:15:29 +00001013
1014 /* Withdraw redistributed routes from current BGP's routing table. */
1015 bgp_redistribute_withdraw (bgp, afi, type);
1016
1017 return CMD_SUCCESS;
1018}
1019
1020/* Unset redistribution route-map configuration. */
1021int
1022bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
1023{
1024 if (! bgp->rmap[afi][type].name)
1025 return 0;
1026
1027 /* Unset route-map. */
1028 free (bgp->rmap[afi][type].name);
1029 bgp->rmap[afi][type].name = NULL;
1030 bgp->rmap[afi][type].map = NULL;
1031
1032 return 1;
1033}
1034
1035/* Unset redistribution metric configuration. */
1036int
1037bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1038{
1039 if (! bgp->redist_metric_flag[afi][type])
1040 return 0;
1041
1042 /* Unset metric. */
1043 bgp->redist_metric_flag[afi][type] = 0;
1044 bgp->redist_metric[afi][type] = 0;
1045
1046 return 1;
1047}
David Lamparter6b0655a2014-06-04 06:53:35 +02001048
paul718e3742002-12-13 20:15:29 +00001049void
paul94f2b392005-06-28 12:44:16 +00001050bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001051{
1052 zclient_reset (zclient);
1053}
1054
Feng Luc99f3482014-10-16 09:52:36 +08001055static void
1056bgp_zebra_connected (struct zclient *zclient)
1057{
1058 zclient_send_requests (zclient, VRF_DEFAULT);
1059}
1060
paul718e3742002-12-13 20:15:29 +00001061void
Donald Sharp71252932015-09-24 09:25:19 -04001062bgp_zebra_init (struct thread_master *master)
paul718e3742002-12-13 20:15:29 +00001063{
1064 /* Set default values. */
Donald Sharp71252932015-09-24 09:25:19 -04001065 zclient = zclient_new (master);
paul718e3742002-12-13 20:15:29 +00001066 zclient_init (zclient, ZEBRA_ROUTE_BGP);
Feng Luc99f3482014-10-16 09:52:36 +08001067 zclient->zebra_connected = bgp_zebra_connected;
hasso18a6dce2004-10-03 18:18:34 +00001068 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001069 zclient->interface_add = bgp_interface_add;
1070 zclient->interface_delete = bgp_interface_delete;
1071 zclient->interface_address_add = bgp_interface_address_add;
1072 zclient->interface_address_delete = bgp_interface_address_delete;
1073 zclient->ipv4_route_add = zebra_read_ipv4;
1074 zclient->ipv4_route_delete = zebra_read_ipv4;
1075 zclient->interface_up = bgp_interface_up;
1076 zclient->interface_down = bgp_interface_down;
paul718e3742002-12-13 20:15:29 +00001077 zclient->ipv6_route_add = zebra_read_ipv6;
1078 zclient->ipv6_route_delete = zebra_read_ipv6;
paul718e3742002-12-13 20:15:29 +00001079
Josh Bailey8196f132011-07-20 20:47:07 -07001080 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001081}
Lou Berger82dd7072016-01-12 13:41:57 -05001082
1083void
1084bgp_zebra_destroy(void)
1085{
1086 if (zclient == NULL)
1087 return;
1088 zclient_stop(zclient);
1089 zclient_free(zclient);
1090 zclient = NULL;
1091}