blob: e534bee86dddb9aaeb8bc3fa0447b5bb13b2428b [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"
32
33#include "bgpd/bgpd.h"
34#include "bgpd/bgp_route.h"
35#include "bgpd/bgp_attr.h"
36#include "bgpd/bgp_nexthop.h"
37#include "bgpd/bgp_zebra.h"
38#include "bgpd/bgp_fsm.h"
Andrew J. Schorra39275d2006-11-30 16:36:57 +000039#include "bgpd/bgp_debug.h"
Josh Bailey8196f132011-07-20 20:47:07 -070040#include "bgpd/bgp_mpath.h"
David Lamparter6b0655a2014-06-04 06:53:35 +020041
paul718e3742002-12-13 20:15:29 +000042/* All information about zebra. */
Chris Caputo228da422009-07-18 05:44:03 +000043struct zclient *zclient = NULL;
hasso18a6dce2004-10-03 18:18:34 +000044struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000045
Josh Bailey8196f132011-07-20 20:47:07 -070046/* Growable buffer for nexthops sent to zebra */
47struct stream *bgp_nexthop_buf = NULL;
48
hasso18a6dce2004-10-03 18:18:34 +000049/* Router-id update message from zebra. */
paul94f2b392005-06-28 12:44:16 +000050static int
Feng Luc99f3482014-10-16 09:52:36 +080051bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
52 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000053{
hasso18a6dce2004-10-03 18:18:34 +000054 struct prefix router_id;
paul1eb8ef22005-04-07 07:30:20 +000055 struct listnode *node, *nnode;
hasso18a6dce2004-10-03 18:18:34 +000056 struct bgp *bgp;
paul718e3742002-12-13 20:15:29 +000057
hasso18a6dce2004-10-03 18:18:34 +000058 zebra_router_id_update_read(zclient->ibuf,&router_id);
Andrew J. Schorra39275d2006-11-30 16:36:57 +000059
60 if (BGP_DEBUG(zebra, ZEBRA))
61 {
62 char buf[128];
63 prefix2str(&router_id, buf, sizeof(buf));
64 zlog_debug("Zebra rcvd: router id update %s", buf);
65 }
66
hasso18a6dce2004-10-03 18:18:34 +000067 router_id_zebra = router_id.u.prefix4;
68
paul1eb8ef22005-04-07 07:30:20 +000069 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
paul718e3742002-12-13 20:15:29 +000070 {
hasso18a6dce2004-10-03 18:18:34 +000071 if (!bgp->router_id_static.s_addr)
paul1eb8ef22005-04-07 07:30:20 +000072 bgp_router_id_set (bgp, &router_id.u.prefix4);
paul718e3742002-12-13 20:15:29 +000073 }
paul718e3742002-12-13 20:15:29 +000074
paul718e3742002-12-13 20:15:29 +000075 return 0;
76}
77
78/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000079static int
Feng Luc99f3482014-10-16 09:52:36 +080080bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
81 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000082{
83 struct interface *ifp;
84
Feng Luc99f3482014-10-16 09:52:36 +080085 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +000086
Andrew J. Schorra39275d2006-11-30 16:36:57 +000087 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
88 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
89
paul718e3742002-12-13 20:15:29 +000090 return 0;
91}
92
paul94f2b392005-06-28 12:44:16 +000093static int
paul718e3742002-12-13 20:15:29 +000094bgp_interface_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +080095 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000096{
97 struct stream *s;
98 struct interface *ifp;
99
100 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800101 ifp = zebra_interface_state_read (s, vrf_id);
ajsd2fc8892005-04-02 18:38:43 +0000102 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000103
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000104 if (BGP_DEBUG(zebra, ZEBRA))
105 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
106
paul718e3742002-12-13 20:15:29 +0000107 return 0;
108}
109
paul94f2b392005-06-28 12:44:16 +0000110static int
Feng Luc99f3482014-10-16 09:52:36 +0800111bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
112 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000113{
114 struct stream *s;
115 struct interface *ifp;
116 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000117 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000118
119 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800120 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000121
122 if (! ifp)
123 return 0;
124
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000125 if (BGP_DEBUG(zebra, ZEBRA))
126 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
127
paul1eb8ef22005-04-07 07:30:20 +0000128 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
129 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000130
131 return 0;
132}
133
paul94f2b392005-06-28 12:44:16 +0000134static int
Feng Luc99f3482014-10-16 09:52:36 +0800135bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
136 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000137{
138 struct stream *s;
139 struct interface *ifp;
140 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000141 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000142
143 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800144 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000145 if (! ifp)
146 return 0;
147
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000148 if (BGP_DEBUG(zebra, ZEBRA))
149 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
150
paul1eb8ef22005-04-07 07:30:20 +0000151 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
152 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000153
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000154 /* Fast external-failover */
paul718e3742002-12-13 20:15:29 +0000155 {
paul1eb8ef22005-04-07 07:30:20 +0000156 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000157 struct bgp *bgp;
158 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000159
paul1eb8ef22005-04-07 07:30:20 +0000160 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000161 {
162 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
163 continue;
164
paul1eb8ef22005-04-07 07:30:20 +0000165 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000166 {
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000167 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
paul718e3742002-12-13 20:15:29 +0000168 continue;
169
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000170 if (ifp == peer->nexthop.ifp)
paul718e3742002-12-13 20:15:29 +0000171 BGP_EVENT_ADD (peer, BGP_Stop);
172 }
173 }
174 }
175
176 return 0;
177}
178
paul94f2b392005-06-28 12:44:16 +0000179static int
paul718e3742002-12-13 20:15:29 +0000180bgp_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800181 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000182{
183 struct connected *ifc;
184
Feng Luc99f3482014-10-16 09:52:36 +0800185 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000186
187 if (ifc == NULL)
188 return 0;
189
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000190 if (BGP_DEBUG(zebra, ZEBRA))
191 {
192 char buf[128];
193 prefix2str(ifc->address, buf, sizeof(buf));
194 zlog_debug("Zebra rcvd: interface %s address add %s",
195 ifc->ifp->name, buf);
196 }
197
paul2e3b2e42002-12-13 21:03:13 +0000198 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000199 bgp_connected_add (ifc);
200
201 return 0;
202}
203
paul94f2b392005-06-28 12:44:16 +0000204static int
paul718e3742002-12-13 20:15:29 +0000205bgp_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800206 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000207{
208 struct connected *ifc;
209
Feng Luc99f3482014-10-16 09:52:36 +0800210 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000211
212 if (ifc == NULL)
213 return 0;
214
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000215 if (BGP_DEBUG(zebra, ZEBRA))
216 {
217 char buf[128];
218 prefix2str(ifc->address, buf, sizeof(buf));
219 zlog_debug("Zebra rcvd: interface %s address delete %s",
220 ifc->ifp->name, buf);
221 }
222
paul2e3b2e42002-12-13 21:03:13 +0000223 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000224 bgp_connected_delete (ifc);
225
226 connected_free (ifc);
227
228 return 0;
229}
230
231/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000232static int
Feng Luc99f3482014-10-16 09:52:36 +0800233zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
234 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000235{
236 struct stream *s;
237 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000238 struct in_addr nexthop;
239 struct prefix_ipv4 p;
240
241 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000242 nexthop.s_addr = 0;
243
244 /* Type, flags, message. */
245 api.type = stream_getc (s);
246 api.flags = stream_getc (s);
247 api.message = stream_getc (s);
248
249 /* IPv4 prefix. */
250 memset (&p, 0, sizeof (struct prefix_ipv4));
251 p.family = AF_INET;
252 p.prefixlen = stream_getc (s);
253 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
254
255 /* Nexthop, ifindex, distance, metric. */
256 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
257 {
258 api.nexthop_num = stream_getc (s);
259 nexthop.s_addr = stream_get_ipv4 (s);
260 }
261 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
262 {
263 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400264 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000265 }
266 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
267 api.distance = stream_getc (s);
268 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
269 api.metric = stream_getl (s);
270 else
271 api.metric = 0;
272
273 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000274 {
275 if (BGP_DEBUG(zebra, ZEBRA))
276 {
277 char buf[2][INET_ADDRSTRLEN];
278 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
279 zebra_route_string(api.type),
280 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
281 p.prefixlen,
282 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
283 api.metric);
284 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400285 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
286 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000287 }
paul718e3742002-12-13 20:15:29 +0000288 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000289 {
290 if (BGP_DEBUG(zebra, ZEBRA))
291 {
292 char buf[2][INET_ADDRSTRLEN];
293 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
294 "nexthop %s metric %u",
295 zebra_route_string(api.type),
296 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
297 p.prefixlen,
298 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
299 api.metric);
300 }
301 bgp_redistribute_delete((struct prefix *)&p, api.type);
302 }
paul718e3742002-12-13 20:15:29 +0000303
304 return 0;
305}
306
307#ifdef HAVE_IPV6
308/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000309static int
Feng Luc99f3482014-10-16 09:52:36 +0800310zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
311 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000312{
313 struct stream *s;
314 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000315 struct in6_addr nexthop;
316 struct prefix_ipv6 p;
317
318 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000319 memset (&nexthop, 0, sizeof (struct in6_addr));
320
321 /* Type, flags, message. */
322 api.type = stream_getc (s);
323 api.flags = stream_getc (s);
324 api.message = stream_getc (s);
325
326 /* IPv6 prefix. */
327 memset (&p, 0, sizeof (struct prefix_ipv6));
328 p.family = AF_INET6;
329 p.prefixlen = stream_getc (s);
330 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
331
332 /* Nexthop, ifindex, distance, metric. */
333 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
334 {
335 api.nexthop_num = stream_getc (s);
336 stream_get (&nexthop, s, 16);
337 }
338 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
339 {
340 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400341 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000342 }
343 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
344 api.distance = stream_getc (s);
345 else
346 api.distance = 0;
347 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
348 api.metric = stream_getl (s);
349 else
350 api.metric = 0;
351
352 /* Simply ignore link-local address. */
353 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
354 return 0;
355
356 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000357 {
358 if (BGP_DEBUG(zebra, ZEBRA))
359 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400360 char buf[2][INET6_ADDRSTRLEN];
361 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000362 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400363 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
364 p.prefixlen,
365 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
366 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000367 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400368 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
369 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000370 }
paul718e3742002-12-13 20:15:29 +0000371 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000372 {
373 if (BGP_DEBUG(zebra, ZEBRA))
374 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400375 char buf[2][INET6_ADDRSTRLEN];
376 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
377 "nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000378 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400379 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
380 p.prefixlen,
381 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
382 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000383 }
384 bgp_redistribute_delete ((struct prefix *) &p, api.type);
385 }
paul718e3742002-12-13 20:15:29 +0000386
387 return 0;
388}
389#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +0200390
paul718e3742002-12-13 20:15:29 +0000391struct interface *
392if_lookup_by_ipv4 (struct in_addr *addr)
393{
hasso52dc7ee2004-09-23 19:18:23 +0000394 struct listnode *ifnode;
395 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000396 struct interface *ifp;
397 struct connected *connected;
398 struct prefix_ipv4 p;
399 struct prefix *cp;
400
401 p.family = AF_INET;
402 p.prefix = *addr;
403 p.prefixlen = IPV4_MAX_BITLEN;
404
paul1eb8ef22005-04-07 07:30:20 +0000405 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000406 {
paul1eb8ef22005-04-07 07:30:20 +0000407 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000408 {
paul718e3742002-12-13 20:15:29 +0000409 cp = connected->address;
410
411 if (cp->family == AF_INET)
412 if (prefix_match (cp, (struct prefix *)&p))
413 return ifp;
414 }
415 }
416 return NULL;
417}
418
419struct interface *
420if_lookup_by_ipv4_exact (struct in_addr *addr)
421{
hasso52dc7ee2004-09-23 19:18:23 +0000422 struct listnode *ifnode;
423 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000424 struct interface *ifp;
425 struct connected *connected;
426 struct prefix *cp;
427
paul1eb8ef22005-04-07 07:30:20 +0000428 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000429 {
paul1eb8ef22005-04-07 07:30:20 +0000430 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000431 {
paul718e3742002-12-13 20:15:29 +0000432 cp = connected->address;
433
434 if (cp->family == AF_INET)
435 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
436 return ifp;
437 }
438 }
439 return NULL;
440}
441
442#ifdef HAVE_IPV6
443struct interface *
444if_lookup_by_ipv6 (struct in6_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_ipv6 p;
451 struct prefix *cp;
452
453 p.family = AF_INET6;
454 p.prefix = *addr;
455 p.prefixlen = IPV6_MAX_BITLEN;
456
paul1eb8ef22005-04-07 07:30:20 +0000457 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000458 {
paul1eb8ef22005-04-07 07:30:20 +0000459 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000460 {
paul718e3742002-12-13 20:15:29 +0000461 cp = connected->address;
462
463 if (cp->family == AF_INET6)
464 if (prefix_match (cp, (struct prefix *)&p))
465 return ifp;
466 }
467 }
468 return NULL;
469}
470
471struct interface *
472if_lookup_by_ipv6_exact (struct in6_addr *addr)
473{
hasso52dc7ee2004-09-23 19:18:23 +0000474 struct listnode *ifnode;
475 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000476 struct interface *ifp;
477 struct connected *connected;
478 struct prefix *cp;
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 (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
488 return ifp;
489 }
490 }
491 return NULL;
492}
493
paul94f2b392005-06-28 12:44:16 +0000494static int
paul718e3742002-12-13 20:15:29 +0000495if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
496{
hasso52dc7ee2004-09-23 19:18:23 +0000497 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000498 struct connected *connected;
499 struct prefix *cp;
500
paul1eb8ef22005-04-07 07:30:20 +0000501 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000502 {
paul718e3742002-12-13 20:15:29 +0000503 cp = connected->address;
504
505 if (cp->family == AF_INET6)
506 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
507 {
508 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
509 return 1;
510 }
511 }
512 return 0;
513}
514
paul94f2b392005-06-28 12:44:16 +0000515static int
paul718e3742002-12-13 20:15:29 +0000516if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
517{
hasso52dc7ee2004-09-23 19:18:23 +0000518 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000519 struct connected *connected;
520 struct prefix *cp;
521
paul1eb8ef22005-04-07 07:30:20 +0000522 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000523 {
paul718e3742002-12-13 20:15:29 +0000524 cp = connected->address;
525
526 if (cp->family == AF_INET6)
527 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
528 {
529 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
530 return 1;
531 }
532 }
533 return 0;
534}
535#endif /* HAVE_IPV6 */
536
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000537static int
538if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
539{
540 struct listnode *cnode;
541 struct connected *connected;
542 struct prefix *cp;
543
544 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
545 {
546 cp = connected->address;
547 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
548 {
549 *addr = cp->u.prefix4;
550 return 1;
551 }
552 }
553 return 0;
554}
555
paul718e3742002-12-13 20:15:29 +0000556int
557bgp_nexthop_set (union sockunion *local, union sockunion *remote,
558 struct bgp_nexthop *nexthop, struct peer *peer)
559{
560 int ret = 0;
561 struct interface *ifp = NULL;
562
563 memset (nexthop, 0, sizeof (struct bgp_nexthop));
564
565 if (!local)
566 return -1;
567 if (!remote)
568 return -1;
569
570 if (local->sa.sa_family == AF_INET)
571 {
572 nexthop->v4 = local->sin.sin_addr;
573 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
574 }
575#ifdef HAVE_IPV6
576 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 }
586#endif /* HAVE_IPV6 */
587
588 if (!ifp)
589 return -1;
590
591 nexthop->ifp = ifp;
592
593 /* IPv4 connection. */
594 if (local->sa.sa_family == AF_INET)
595 {
596#ifdef HAVE_IPV6
597 /* IPv6 nexthop*/
598 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
599
600 /* There is no global nexthop. */
601 if (!ret)
602 if_get_ipv6_local (ifp, &nexthop->v6_global);
603 else
604 if_get_ipv6_local (ifp, &nexthop->v6_local);
605#endif /* HAVE_IPV6 */
606 }
607
608#ifdef HAVE_IPV6
609 /* IPv6 connection. */
610 if (local->sa.sa_family == AF_INET6)
611 {
612 struct interface *direct = NULL;
613
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000614 /* IPv4 nexthop. */
615 ret = if_get_ipv4_address(ifp, &nexthop->v4);
616 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000617 nexthop->v4 = peer->local_id;
618
619 /* Global address*/
620 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
621 {
622 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
623 IPV6_MAX_BYTELEN);
624
625 /* If directory connected set link-local address. */
626 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
627 if (direct)
628 if_get_ipv6_local (ifp, &nexthop->v6_local);
629 }
630 else
631 /* Link-local address. */
632 {
633 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
634
635 /* If there is no global address. Set link-local address as
636 global. I know this break RFC specification... */
637 if (!ret)
638 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
639 IPV6_MAX_BYTELEN);
640 else
641 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
642 IPV6_MAX_BYTELEN);
643 }
644 }
645
646 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
647 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
648 peer->shared_network = 1;
649 else
650 peer->shared_network = 0;
651
652 /* KAME stack specific treatment. */
653#ifdef KAME
654 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
655 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
656 {
657 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
658 }
659 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
660 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
661 {
662 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
663 }
664#endif /* KAME */
665#endif /* HAVE_IPV6 */
666 return ret;
667}
668
paul718e3742002-12-13 20:15:29 +0000669void
G.Balaji5a616c02011-11-26 21:58:42 +0400670bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000671{
672 int flags;
673 u_char distance;
674 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700675 struct bgp_info *mpinfo;
676 size_t oldsize, newsize;
paul718e3742002-12-13 20:15:29 +0000677
678 if (zclient->sock < 0)
679 return;
680
Feng Luc99f3482014-10-16 09:52:36 +0800681 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000682 return;
683
684 flags = 0;
685 peer = info->peer;
686
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000687 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000688 {
689 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
690 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
691 }
692
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000693 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000694 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000695 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
696
Josh Bailey8196f132011-07-20 20:47:07 -0700697 /* resize nexthop buffer size if necessary */
698 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
699 (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
700 {
701 newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
702 newsize = stream_resize (bgp_nexthop_buf, newsize);
703 if (newsize == oldsize)
704 {
705 zlog_err ("can't resize nexthop buffer");
706 return;
707 }
708 }
709
710 stream_reset (bgp_nexthop_buf);
711
paul718e3742002-12-13 20:15:29 +0000712 if (p->family == AF_INET)
713 {
714 struct zapi_ipv4 api;
715 struct in_addr *nexthop;
716
Feng Luc99f3482014-10-16 09:52:36 +0800717 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000718 api.flags = flags;
719 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700720 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
721 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
722 mpinfo = bgp_info_mpath_next (mpinfo))
723 {
724 nexthop = &mpinfo->attr->nexthop;
725 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
726 }
paul718e3742002-12-13 20:15:29 +0000727
728 api.type = ZEBRA_ROUTE_BGP;
729 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400730 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000731 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Josh Bailey8196f132011-07-20 20:47:07 -0700732 api.nexthop_num = 1 + bgp_info_mpath_count (info);
733 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000734 api.ifindex_num = 0;
735 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
736 api.metric = info->attr->med;
737
738 distance = bgp_distance_apply (p, info, bgp);
739
740 if (distance)
741 {
742 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
743 api.distance = distance;
744 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000745
746 if (BGP_DEBUG(zebra, ZEBRA))
747 {
Josh Bailey8196f132011-07-20 20:47:07 -0700748 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000749 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700750 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
751 " count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000752 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
753 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700754 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
755 api.metric, api.nexthop_num);
756 for (i = 1; i < api.nexthop_num; i++)
757 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
758 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
759 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000760 }
761
paul0a589352004-05-08 11:48:26 +0000762 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
763 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000764 }
765#ifdef HAVE_IPV6
766 /* We have to think about a IPv6 link-local address curse. */
767 if (p->family == AF_INET6)
768 {
769 unsigned int ifindex;
770 struct in6_addr *nexthop;
771 struct zapi_ipv6 api;
772
773 ifindex = 0;
774 nexthop = NULL;
Paul Jakmafb982c22007-05-04 20:15:47 +0000775
776 assert (info->attr->extra);
777
paul718e3742002-12-13 20:15:29 +0000778 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000779 if (info->attr->extra->mp_nexthop_len == 16)
780 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000781
782 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000783 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000784 {
785 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000786 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000787 && peer->su_remote->sa.sa_family == AF_INET6)
788 nexthop = &peer->su_remote->sin6.sin6_addr;
789 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000790 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000791
792 if (info->peer->nexthop.ifp)
793 ifindex = info->peer->nexthop.ifp->ifindex;
794 }
795
796 if (nexthop == NULL)
797 return;
798
799 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
800 {
801 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200802 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000803 else if (info->peer->nexthop.ifp)
804 ifindex = info->peer->nexthop.ifp->ifindex;
805 }
806
807 /* Make Zebra API structure. */
Feng Luc99f3482014-10-16 09:52:36 +0800808 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000809 api.flags = flags;
810 api.type = ZEBRA_ROUTE_BGP;
811 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400812 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000813 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
814 api.nexthop_num = 1;
815 api.nexthop = &nexthop;
816 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
817 api.ifindex_num = 1;
818 api.ifindex = &ifindex;
819 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
820 api.metric = info->attr->med;
821
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000822 if (BGP_DEBUG(zebra, ZEBRA))
823 {
824 char buf[2][INET6_ADDRSTRLEN];
825 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
826 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
827 p->prefixlen,
828 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
829 api.metric);
830 }
831
paul0a589352004-05-08 11:48:26 +0000832 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
833 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000834 }
835#endif /* HAVE_IPV6 */
836}
837
838void
G.Balaji5a616c02011-11-26 21:58:42 +0400839bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000840{
841 int flags;
842 struct peer *peer;
843
844 if (zclient->sock < 0)
845 return;
846
Feng Luc99f3482014-10-16 09:52:36 +0800847 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000848 return;
849
850 peer = info->peer;
851 flags = 0;
852
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000853 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000854 {
855 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
856 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
857 }
858
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000859 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000860 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000861 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
862
863 if (p->family == AF_INET)
864 {
865 struct zapi_ipv4 api;
866 struct in_addr *nexthop;
867
Feng Luc99f3482014-10-16 09:52:36 +0800868 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000869 api.flags = flags;
870 nexthop = &info->attr->nexthop;
871
872 api.type = ZEBRA_ROUTE_BGP;
873 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400874 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000875 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
876 api.nexthop_num = 1;
877 api.nexthop = &nexthop;
878 api.ifindex_num = 0;
879 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
880 api.metric = info->attr->med;
881
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000882 if (BGP_DEBUG(zebra, ZEBRA))
883 {
884 char buf[2][INET_ADDRSTRLEN];
885 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
886 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
887 p->prefixlen,
888 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
889 api.metric);
890 }
891
paul0a589352004-05-08 11:48:26 +0000892 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
893 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000894 }
895#ifdef HAVE_IPV6
896 /* We have to think about a IPv6 link-local address curse. */
897 if (p->family == AF_INET6)
898 {
899 struct zapi_ipv6 api;
900 unsigned int ifindex;
901 struct in6_addr *nexthop;
Paul Jakmafb982c22007-05-04 20:15:47 +0000902
903 assert (info->attr->extra);
904
paul718e3742002-12-13 20:15:29 +0000905 ifindex = 0;
906 nexthop = NULL;
907
908 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000909 if (info->attr->extra->mp_nexthop_len == 16)
910 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000911
912 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000913 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000914 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000915 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000916 if (info->peer->nexthop.ifp)
917 ifindex = info->peer->nexthop.ifp->ifindex;
918 }
919
920 if (nexthop == NULL)
921 return;
922
923 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
924 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200925 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000926
Feng Luc99f3482014-10-16 09:52:36 +0800927 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000928 api.flags = flags;
929 api.type = ZEBRA_ROUTE_BGP;
930 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400931 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000932 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
933 api.nexthop_num = 1;
934 api.nexthop = &nexthop;
935 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
936 api.ifindex_num = 1;
937 api.ifindex = &ifindex;
938 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
939 api.metric = info->attr->med;
940
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000941 if (BGP_DEBUG(zebra, ZEBRA))
942 {
943 char buf[2][INET6_ADDRSTRLEN];
944 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
945 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
946 p->prefixlen,
947 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
948 api.metric);
949 }
950
paul0a589352004-05-08 11:48:26 +0000951 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
952 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000953 }
954#endif /* HAVE_IPV6 */
955}
David Lamparter6b0655a2014-06-04 06:53:35 +0200956
paul718e3742002-12-13 20:15:29 +0000957/* Other routes redistribution into BGP. */
958int
959bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
960{
961 /* Set flag to BGP instance. */
962 bgp->redist[afi][type] = 1;
963
964 /* Return if already redistribute flag is set. */
Feng Luc99f3482014-10-16 09:52:36 +0800965 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000966 return CMD_WARNING;
967
Feng Luc99f3482014-10-16 09:52:36 +0800968 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000969
970 /* Return if zebra connection is not established. */
971 if (zclient->sock < 0)
972 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000973
974 if (BGP_DEBUG(zebra, ZEBRA))
975 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000976
977 /* Send distribute add message to zebra. */
Feng Luc99f3482014-10-16 09:52:36 +0800978 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000979
980 return CMD_SUCCESS;
981}
982
983/* Redistribute with route-map specification. */
984int
paulfd79ac92004-10-13 05:06:08 +0000985bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
986 const char *name)
paul718e3742002-12-13 20:15:29 +0000987{
988 if (bgp->rmap[afi][type].name
989 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
990 return 0;
991
992 if (bgp->rmap[afi][type].name)
993 free (bgp->rmap[afi][type].name);
994 bgp->rmap[afi][type].name = strdup (name);
995 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
996
997 return 1;
998}
999
1000/* Redistribute with metric specification. */
1001int
1002bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
1003 u_int32_t metric)
1004{
1005 if (bgp->redist_metric_flag[afi][type]
1006 && bgp->redist_metric[afi][type] == metric)
1007 return 0;
1008
1009 bgp->redist_metric_flag[afi][type] = 1;
1010 bgp->redist_metric[afi][type] = metric;
1011
1012 return 1;
1013}
1014
1015/* Unset redistribution. */
1016int
1017bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
1018{
1019 /* Unset flag from BGP instance. */
1020 bgp->redist[afi][type] = 0;
1021
1022 /* Unset route-map. */
1023 if (bgp->rmap[afi][type].name)
1024 free (bgp->rmap[afi][type].name);
1025 bgp->rmap[afi][type].name = NULL;
1026 bgp->rmap[afi][type].map = NULL;
1027
1028 /* Unset metric. */
1029 bgp->redist_metric_flag[afi][type] = 0;
1030 bgp->redist_metric[afi][type] = 0;
1031
1032 /* Return if zebra connection is disabled. */
Feng Luc99f3482014-10-16 09:52:36 +08001033 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +00001034 return CMD_WARNING;
Feng Luc99f3482014-10-16 09:52:36 +08001035 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001036
1037 if (bgp->redist[AFI_IP][type] == 0
1038 && bgp->redist[AFI_IP6][type] == 0
1039 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001040 {
1041 /* Send distribute delete message to zebra. */
1042 if (BGP_DEBUG(zebra, ZEBRA))
1043 zlog_debug("Zebra send: redistribute delete %s",
1044 zebra_route_string(type));
Feng Luc99f3482014-10-16 09:52:36 +08001045 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
1046 VRF_DEFAULT);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001047 }
paul718e3742002-12-13 20:15:29 +00001048
1049 /* Withdraw redistributed routes from current BGP's routing table. */
1050 bgp_redistribute_withdraw (bgp, afi, type);
1051
1052 return CMD_SUCCESS;
1053}
1054
1055/* Unset redistribution route-map configuration. */
1056int
1057bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
1058{
1059 if (! bgp->rmap[afi][type].name)
1060 return 0;
1061
1062 /* Unset route-map. */
1063 free (bgp->rmap[afi][type].name);
1064 bgp->rmap[afi][type].name = NULL;
1065 bgp->rmap[afi][type].map = NULL;
1066
1067 return 1;
1068}
1069
1070/* Unset redistribution metric configuration. */
1071int
1072bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1073{
1074 if (! bgp->redist_metric_flag[afi][type])
1075 return 0;
1076
1077 /* Unset metric. */
1078 bgp->redist_metric_flag[afi][type] = 0;
1079 bgp->redist_metric[afi][type] = 0;
1080
1081 return 1;
1082}
David Lamparter6b0655a2014-06-04 06:53:35 +02001083
paul718e3742002-12-13 20:15:29 +00001084void
paul94f2b392005-06-28 12:44:16 +00001085bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001086{
1087 zclient_reset (zclient);
1088}
1089
Feng Luc99f3482014-10-16 09:52:36 +08001090static void
1091bgp_zebra_connected (struct zclient *zclient)
1092{
1093 zclient_send_requests (zclient, VRF_DEFAULT);
1094}
1095
paul718e3742002-12-13 20:15:29 +00001096void
Donald Sharp71252932015-09-24 09:25:19 -04001097bgp_zebra_init (struct thread_master *master)
paul718e3742002-12-13 20:15:29 +00001098{
1099 /* Set default values. */
Donald Sharp71252932015-09-24 09:25:19 -04001100 zclient = zclient_new (master);
paul718e3742002-12-13 20:15:29 +00001101 zclient_init (zclient, ZEBRA_ROUTE_BGP);
Feng Luc99f3482014-10-16 09:52:36 +08001102 zclient->zebra_connected = bgp_zebra_connected;
hasso18a6dce2004-10-03 18:18:34 +00001103 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001104 zclient->interface_add = bgp_interface_add;
1105 zclient->interface_delete = bgp_interface_delete;
1106 zclient->interface_address_add = bgp_interface_address_add;
1107 zclient->interface_address_delete = bgp_interface_address_delete;
1108 zclient->ipv4_route_add = zebra_read_ipv4;
1109 zclient->ipv4_route_delete = zebra_read_ipv4;
1110 zclient->interface_up = bgp_interface_up;
1111 zclient->interface_down = bgp_interface_down;
1112#ifdef HAVE_IPV6
1113 zclient->ipv6_route_add = zebra_read_ipv6;
1114 zclient->ipv6_route_delete = zebra_read_ipv6;
1115#endif /* HAVE_IPV6 */
1116
Josh Bailey8196f132011-07-20 20:47:07 -07001117 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001118}