blob: 13f71de949e7b9894cf39baf4f157e288ec77519 [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
hasso18a6dce2004-10-03 18:18:34 +000051bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
paul718e3742002-12-13 20:15:29 +000052{
hasso18a6dce2004-10-03 18:18:34 +000053 struct prefix router_id;
paul1eb8ef22005-04-07 07:30:20 +000054 struct listnode *node, *nnode;
hasso18a6dce2004-10-03 18:18:34 +000055 struct bgp *bgp;
paul718e3742002-12-13 20:15:29 +000056
hasso18a6dce2004-10-03 18:18:34 +000057 zebra_router_id_update_read(zclient->ibuf,&router_id);
Andrew J. Schorra39275d2006-11-30 16:36:57 +000058
59 if (BGP_DEBUG(zebra, ZEBRA))
60 {
61 char buf[128];
62 prefix2str(&router_id, buf, sizeof(buf));
63 zlog_debug("Zebra rcvd: router id update %s", buf);
64 }
65
hasso18a6dce2004-10-03 18:18:34 +000066 router_id_zebra = router_id.u.prefix4;
67
paul1eb8ef22005-04-07 07:30:20 +000068 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
paul718e3742002-12-13 20:15:29 +000069 {
hasso18a6dce2004-10-03 18:18:34 +000070 if (!bgp->router_id_static.s_addr)
paul1eb8ef22005-04-07 07:30:20 +000071 bgp_router_id_set (bgp, &router_id.u.prefix4);
paul718e3742002-12-13 20:15:29 +000072 }
paul718e3742002-12-13 20:15:29 +000073
paul718e3742002-12-13 20:15:29 +000074 return 0;
75}
76
77/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000078static int
paul718e3742002-12-13 20:15:29 +000079bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
80{
81 struct interface *ifp;
82
83 ifp = zebra_interface_add_read (zclient->ibuf);
paul718e3742002-12-13 20:15:29 +000084
Andrew J. Schorra39275d2006-11-30 16:36:57 +000085 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
86 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
87
paul718e3742002-12-13 20:15:29 +000088 return 0;
89}
90
paul94f2b392005-06-28 12:44:16 +000091static int
paul718e3742002-12-13 20:15:29 +000092bgp_interface_delete (int command, struct zclient *zclient,
93 zebra_size_t length)
94{
95 struct stream *s;
96 struct interface *ifp;
97
98 s = zclient->ibuf;
99 ifp = zebra_interface_state_read (s);
ajsd2fc8892005-04-02 18:38:43 +0000100 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000101
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000102 if (BGP_DEBUG(zebra, ZEBRA))
103 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
104
paul718e3742002-12-13 20:15:29 +0000105 return 0;
106}
107
paul94f2b392005-06-28 12:44:16 +0000108static int
paul718e3742002-12-13 20:15:29 +0000109bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
110{
111 struct stream *s;
112 struct interface *ifp;
113 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000114 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000115
116 s = zclient->ibuf;
117 ifp = zebra_interface_state_read (s);
118
119 if (! ifp)
120 return 0;
121
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000122 if (BGP_DEBUG(zebra, ZEBRA))
123 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
124
paul1eb8ef22005-04-07 07:30:20 +0000125 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
126 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000127
128 return 0;
129}
130
paul94f2b392005-06-28 12:44:16 +0000131static int
paul718e3742002-12-13 20:15:29 +0000132bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
133{
134 struct stream *s;
135 struct interface *ifp;
136 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000137 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000138
139 s = zclient->ibuf;
140 ifp = zebra_interface_state_read (s);
141 if (! ifp)
142 return 0;
143
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000144 if (BGP_DEBUG(zebra, ZEBRA))
145 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
146
paul1eb8ef22005-04-07 07:30:20 +0000147 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
148 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000149
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000150 /* Fast external-failover */
paul718e3742002-12-13 20:15:29 +0000151 {
paul1eb8ef22005-04-07 07:30:20 +0000152 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000153 struct bgp *bgp;
154 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000155
paul1eb8ef22005-04-07 07:30:20 +0000156 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000157 {
158 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
159 continue;
160
paul1eb8ef22005-04-07 07:30:20 +0000161 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000162 {
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000163 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
paul718e3742002-12-13 20:15:29 +0000164 continue;
165
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000166 if (ifp == peer->nexthop.ifp)
paul718e3742002-12-13 20:15:29 +0000167 BGP_EVENT_ADD (peer, BGP_Stop);
168 }
169 }
170 }
171
172 return 0;
173}
174
paul94f2b392005-06-28 12:44:16 +0000175static int
paul718e3742002-12-13 20:15:29 +0000176bgp_interface_address_add (int command, struct zclient *zclient,
177 zebra_size_t length)
178{
179 struct connected *ifc;
180
paul0a589352004-05-08 11:48:26 +0000181 ifc = zebra_interface_address_read (command, zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000182
183 if (ifc == NULL)
184 return 0;
185
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000186 if (BGP_DEBUG(zebra, ZEBRA))
187 {
188 char buf[128];
189 prefix2str(ifc->address, buf, sizeof(buf));
190 zlog_debug("Zebra rcvd: interface %s address add %s",
191 ifc->ifp->name, buf);
192 }
193
paul2e3b2e42002-12-13 21:03:13 +0000194 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000195 bgp_connected_add (ifc);
196
197 return 0;
198}
199
paul94f2b392005-06-28 12:44:16 +0000200static int
paul718e3742002-12-13 20:15:29 +0000201bgp_interface_address_delete (int command, struct zclient *zclient,
202 zebra_size_t length)
203{
204 struct connected *ifc;
205
paul0a589352004-05-08 11:48:26 +0000206 ifc = zebra_interface_address_read (command, zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000207
208 if (ifc == NULL)
209 return 0;
210
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000211 if (BGP_DEBUG(zebra, ZEBRA))
212 {
213 char buf[128];
214 prefix2str(ifc->address, buf, sizeof(buf));
215 zlog_debug("Zebra rcvd: interface %s address delete %s",
216 ifc->ifp->name, buf);
217 }
218
paul2e3b2e42002-12-13 21:03:13 +0000219 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000220 bgp_connected_delete (ifc);
221
222 connected_free (ifc);
223
224 return 0;
225}
226
227/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000228static int
paul718e3742002-12-13 20:15:29 +0000229zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
230{
231 struct stream *s;
232 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000233 struct in_addr nexthop;
234 struct prefix_ipv4 p;
235
236 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000237 nexthop.s_addr = 0;
238
239 /* Type, flags, message. */
240 api.type = stream_getc (s);
241 api.flags = stream_getc (s);
242 api.message = stream_getc (s);
243
244 /* IPv4 prefix. */
245 memset (&p, 0, sizeof (struct prefix_ipv4));
246 p.family = AF_INET;
247 p.prefixlen = stream_getc (s);
248 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
249
250 /* Nexthop, ifindex, distance, metric. */
251 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
252 {
253 api.nexthop_num = stream_getc (s);
254 nexthop.s_addr = stream_get_ipv4 (s);
255 }
256 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
257 {
258 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400259 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000260 }
261 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
262 api.distance = stream_getc (s);
263 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
264 api.metric = stream_getl (s);
265 else
266 api.metric = 0;
267
268 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000269 {
270 if (BGP_DEBUG(zebra, ZEBRA))
271 {
272 char buf[2][INET_ADDRSTRLEN];
273 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
274 zebra_route_string(api.type),
275 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
276 p.prefixlen,
277 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
278 api.metric);
279 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400280 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
281 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000282 }
paul718e3742002-12-13 20:15:29 +0000283 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000284 {
285 if (BGP_DEBUG(zebra, ZEBRA))
286 {
287 char buf[2][INET_ADDRSTRLEN];
288 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
289 "nexthop %s metric %u",
290 zebra_route_string(api.type),
291 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
292 p.prefixlen,
293 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
294 api.metric);
295 }
296 bgp_redistribute_delete((struct prefix *)&p, api.type);
297 }
paul718e3742002-12-13 20:15:29 +0000298
299 return 0;
300}
301
302#ifdef HAVE_IPV6
303/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000304static int
paul718e3742002-12-13 20:15:29 +0000305zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
306{
307 struct stream *s;
308 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000309 struct in6_addr nexthop;
310 struct prefix_ipv6 p;
311
312 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000313 memset (&nexthop, 0, sizeof (struct in6_addr));
314
315 /* Type, flags, message. */
316 api.type = stream_getc (s);
317 api.flags = stream_getc (s);
318 api.message = stream_getc (s);
319
320 /* IPv6 prefix. */
321 memset (&p, 0, sizeof (struct prefix_ipv6));
322 p.family = AF_INET6;
323 p.prefixlen = stream_getc (s);
324 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
325
326 /* Nexthop, ifindex, distance, metric. */
327 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
328 {
329 api.nexthop_num = stream_getc (s);
330 stream_get (&nexthop, s, 16);
331 }
332 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
333 {
334 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400335 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000336 }
337 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
338 api.distance = stream_getc (s);
339 else
340 api.distance = 0;
341 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
342 api.metric = stream_getl (s);
343 else
344 api.metric = 0;
345
346 /* Simply ignore link-local address. */
347 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
348 return 0;
349
350 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000351 {
352 if (BGP_DEBUG(zebra, ZEBRA))
353 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400354 char buf[2][INET6_ADDRSTRLEN];
355 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000356 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400357 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
358 p.prefixlen,
359 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
360 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000361 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400362 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
363 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000364 }
paul718e3742002-12-13 20:15:29 +0000365 else
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 delete %s %s/%d "
371 "nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000372 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400373 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
374 p.prefixlen,
375 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
376 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000377 }
378 bgp_redistribute_delete ((struct prefix *) &p, api.type);
379 }
paul718e3742002-12-13 20:15:29 +0000380
381 return 0;
382}
383#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +0200384
paul718e3742002-12-13 20:15:29 +0000385struct interface *
386if_lookup_by_ipv4 (struct in_addr *addr)
387{
hasso52dc7ee2004-09-23 19:18:23 +0000388 struct listnode *ifnode;
389 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000390 struct interface *ifp;
391 struct connected *connected;
392 struct prefix_ipv4 p;
393 struct prefix *cp;
394
395 p.family = AF_INET;
396 p.prefix = *addr;
397 p.prefixlen = IPV4_MAX_BITLEN;
398
paul1eb8ef22005-04-07 07:30:20 +0000399 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000400 {
paul1eb8ef22005-04-07 07:30:20 +0000401 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000402 {
paul718e3742002-12-13 20:15:29 +0000403 cp = connected->address;
404
405 if (cp->family == AF_INET)
406 if (prefix_match (cp, (struct prefix *)&p))
407 return ifp;
408 }
409 }
410 return NULL;
411}
412
413struct interface *
414if_lookup_by_ipv4_exact (struct in_addr *addr)
415{
hasso52dc7ee2004-09-23 19:18:23 +0000416 struct listnode *ifnode;
417 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000418 struct interface *ifp;
419 struct connected *connected;
420 struct prefix *cp;
421
paul1eb8ef22005-04-07 07:30:20 +0000422 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000423 {
paul1eb8ef22005-04-07 07:30:20 +0000424 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000425 {
paul718e3742002-12-13 20:15:29 +0000426 cp = connected->address;
427
428 if (cp->family == AF_INET)
429 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
430 return ifp;
431 }
432 }
433 return NULL;
434}
435
436#ifdef HAVE_IPV6
437struct interface *
438if_lookup_by_ipv6 (struct in6_addr *addr)
439{
hasso52dc7ee2004-09-23 19:18:23 +0000440 struct listnode *ifnode;
441 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000442 struct interface *ifp;
443 struct connected *connected;
444 struct prefix_ipv6 p;
445 struct prefix *cp;
446
447 p.family = AF_INET6;
448 p.prefix = *addr;
449 p.prefixlen = IPV6_MAX_BITLEN;
450
paul1eb8ef22005-04-07 07:30:20 +0000451 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000452 {
paul1eb8ef22005-04-07 07:30:20 +0000453 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000454 {
paul718e3742002-12-13 20:15:29 +0000455 cp = connected->address;
456
457 if (cp->family == AF_INET6)
458 if (prefix_match (cp, (struct prefix *)&p))
459 return ifp;
460 }
461 }
462 return NULL;
463}
464
465struct interface *
466if_lookup_by_ipv6_exact (struct in6_addr *addr)
467{
hasso52dc7ee2004-09-23 19:18:23 +0000468 struct listnode *ifnode;
469 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000470 struct interface *ifp;
471 struct connected *connected;
472 struct prefix *cp;
473
paul1eb8ef22005-04-07 07:30:20 +0000474 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000475 {
paul1eb8ef22005-04-07 07:30:20 +0000476 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000477 {
paul718e3742002-12-13 20:15:29 +0000478 cp = connected->address;
479
480 if (cp->family == AF_INET6)
481 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
482 return ifp;
483 }
484 }
485 return NULL;
486}
487
paul94f2b392005-06-28 12:44:16 +0000488static int
paul718e3742002-12-13 20:15:29 +0000489if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
490{
hasso52dc7ee2004-09-23 19:18:23 +0000491 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000492 struct connected *connected;
493 struct prefix *cp;
494
paul1eb8ef22005-04-07 07:30:20 +0000495 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000496 {
paul718e3742002-12-13 20:15:29 +0000497 cp = connected->address;
498
499 if (cp->family == AF_INET6)
500 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
501 {
502 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
503 return 1;
504 }
505 }
506 return 0;
507}
508
paul94f2b392005-06-28 12:44:16 +0000509static int
paul718e3742002-12-13 20:15:29 +0000510if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
511{
hasso52dc7ee2004-09-23 19:18:23 +0000512 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000513 struct connected *connected;
514 struct prefix *cp;
515
paul1eb8ef22005-04-07 07:30:20 +0000516 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000517 {
paul718e3742002-12-13 20:15:29 +0000518 cp = connected->address;
519
520 if (cp->family == AF_INET6)
521 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
522 {
523 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
524 return 1;
525 }
526 }
527 return 0;
528}
529#endif /* HAVE_IPV6 */
530
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000531static int
532if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
533{
534 struct listnode *cnode;
535 struct connected *connected;
536 struct prefix *cp;
537
538 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
539 {
540 cp = connected->address;
541 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
542 {
543 *addr = cp->u.prefix4;
544 return 1;
545 }
546 }
547 return 0;
548}
549
paul718e3742002-12-13 20:15:29 +0000550int
551bgp_nexthop_set (union sockunion *local, union sockunion *remote,
552 struct bgp_nexthop *nexthop, struct peer *peer)
553{
554 int ret = 0;
555 struct interface *ifp = NULL;
556
557 memset (nexthop, 0, sizeof (struct bgp_nexthop));
558
559 if (!local)
560 return -1;
561 if (!remote)
562 return -1;
563
564 if (local->sa.sa_family == AF_INET)
565 {
566 nexthop->v4 = local->sin.sin_addr;
567 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
568 }
569#ifdef HAVE_IPV6
570 if (local->sa.sa_family == AF_INET6)
571 {
572 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
573 {
574 if (peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200575 ifp = if_lookup_by_name (peer->ifname);
paul718e3742002-12-13 20:15:29 +0000576 }
577 else
578 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
579 }
580#endif /* HAVE_IPV6 */
581
582 if (!ifp)
583 return -1;
584
585 nexthop->ifp = ifp;
586
587 /* IPv4 connection. */
588 if (local->sa.sa_family == AF_INET)
589 {
590#ifdef HAVE_IPV6
591 /* IPv6 nexthop*/
592 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
593
594 /* There is no global nexthop. */
595 if (!ret)
596 if_get_ipv6_local (ifp, &nexthop->v6_global);
597 else
598 if_get_ipv6_local (ifp, &nexthop->v6_local);
599#endif /* HAVE_IPV6 */
600 }
601
602#ifdef HAVE_IPV6
603 /* IPv6 connection. */
604 if (local->sa.sa_family == AF_INET6)
605 {
606 struct interface *direct = NULL;
607
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000608 /* IPv4 nexthop. */
609 ret = if_get_ipv4_address(ifp, &nexthop->v4);
610 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000611 nexthop->v4 = peer->local_id;
612
613 /* Global address*/
614 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
615 {
616 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
617 IPV6_MAX_BYTELEN);
618
619 /* If directory connected set link-local address. */
620 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
621 if (direct)
622 if_get_ipv6_local (ifp, &nexthop->v6_local);
623 }
624 else
625 /* Link-local address. */
626 {
627 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
628
629 /* If there is no global address. Set link-local address as
630 global. I know this break RFC specification... */
631 if (!ret)
632 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
633 IPV6_MAX_BYTELEN);
634 else
635 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
636 IPV6_MAX_BYTELEN);
637 }
638 }
639
640 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
641 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
642 peer->shared_network = 1;
643 else
644 peer->shared_network = 0;
645
646 /* KAME stack specific treatment. */
647#ifdef KAME
648 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
649 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
650 {
651 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
652 }
653 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
654 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
655 {
656 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
657 }
658#endif /* KAME */
659#endif /* HAVE_IPV6 */
660 return ret;
661}
662
paul718e3742002-12-13 20:15:29 +0000663void
G.Balaji5a616c02011-11-26 21:58:42 +0400664bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000665{
666 int flags;
667 u_char distance;
668 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700669 struct bgp_info *mpinfo;
670 size_t oldsize, newsize;
paul718e3742002-12-13 20:15:29 +0000671
672 if (zclient->sock < 0)
673 return;
674
675 if (! zclient->redist[ZEBRA_ROUTE_BGP])
676 return;
677
678 flags = 0;
679 peer = info->peer;
680
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000681 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000682 {
683 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
684 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
685 }
686
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000687 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000688 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000689 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
690
Josh Bailey8196f132011-07-20 20:47:07 -0700691 /* resize nexthop buffer size if necessary */
692 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
693 (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
694 {
695 newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
696 newsize = stream_resize (bgp_nexthop_buf, newsize);
697 if (newsize == oldsize)
698 {
699 zlog_err ("can't resize nexthop buffer");
700 return;
701 }
702 }
703
704 stream_reset (bgp_nexthop_buf);
705
paul718e3742002-12-13 20:15:29 +0000706 if (p->family == AF_INET)
707 {
708 struct zapi_ipv4 api;
709 struct in_addr *nexthop;
710
711 api.flags = flags;
712 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700713 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
714 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
715 mpinfo = bgp_info_mpath_next (mpinfo))
716 {
717 nexthop = &mpinfo->attr->nexthop;
718 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
719 }
paul718e3742002-12-13 20:15:29 +0000720
721 api.type = ZEBRA_ROUTE_BGP;
722 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400723 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000724 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Josh Bailey8196f132011-07-20 20:47:07 -0700725 api.nexthop_num = 1 + bgp_info_mpath_count (info);
726 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000727 api.ifindex_num = 0;
728 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
729 api.metric = info->attr->med;
730
731 distance = bgp_distance_apply (p, info, bgp);
732
733 if (distance)
734 {
735 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
736 api.distance = distance;
737 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000738
739 if (BGP_DEBUG(zebra, ZEBRA))
740 {
Josh Bailey8196f132011-07-20 20:47:07 -0700741 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000742 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700743 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
744 " count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000745 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
746 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700747 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
748 api.metric, api.nexthop_num);
749 for (i = 1; i < api.nexthop_num; i++)
750 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
751 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
752 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000753 }
754
paul0a589352004-05-08 11:48:26 +0000755 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
756 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000757 }
758#ifdef HAVE_IPV6
759 /* We have to think about a IPv6 link-local address curse. */
760 if (p->family == AF_INET6)
761 {
762 unsigned int ifindex;
763 struct in6_addr *nexthop;
764 struct zapi_ipv6 api;
765
766 ifindex = 0;
767 nexthop = NULL;
Paul Jakmafb982c22007-05-04 20:15:47 +0000768
769 assert (info->attr->extra);
770
paul718e3742002-12-13 20:15:29 +0000771 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000772 if (info->attr->extra->mp_nexthop_len == 16)
773 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000774
775 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000776 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000777 {
778 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000779 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000780 && peer->su_remote->sa.sa_family == AF_INET6)
781 nexthop = &peer->su_remote->sin6.sin6_addr;
782 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000783 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000784
785 if (info->peer->nexthop.ifp)
786 ifindex = info->peer->nexthop.ifp->ifindex;
787 }
788
789 if (nexthop == NULL)
790 return;
791
792 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
793 {
794 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200795 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000796 else if (info->peer->nexthop.ifp)
797 ifindex = info->peer->nexthop.ifp->ifindex;
798 }
799
800 /* Make Zebra API structure. */
801 api.flags = flags;
802 api.type = ZEBRA_ROUTE_BGP;
803 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400804 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000805 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
806 api.nexthop_num = 1;
807 api.nexthop = &nexthop;
808 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
809 api.ifindex_num = 1;
810 api.ifindex = &ifindex;
811 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
812 api.metric = info->attr->med;
813
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000814 if (BGP_DEBUG(zebra, ZEBRA))
815 {
816 char buf[2][INET6_ADDRSTRLEN];
817 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
818 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
819 p->prefixlen,
820 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
821 api.metric);
822 }
823
paul0a589352004-05-08 11:48:26 +0000824 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
825 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000826 }
827#endif /* HAVE_IPV6 */
828}
829
830void
G.Balaji5a616c02011-11-26 21:58:42 +0400831bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000832{
833 int flags;
834 struct peer *peer;
835
836 if (zclient->sock < 0)
837 return;
838
839 if (! zclient->redist[ZEBRA_ROUTE_BGP])
840 return;
841
842 peer = info->peer;
843 flags = 0;
844
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000845 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000846 {
847 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
848 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
849 }
850
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000851 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000852 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000853 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
854
855 if (p->family == AF_INET)
856 {
857 struct zapi_ipv4 api;
858 struct in_addr *nexthop;
859
860 api.flags = flags;
861 nexthop = &info->attr->nexthop;
862
863 api.type = ZEBRA_ROUTE_BGP;
864 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400865 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000866 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
867 api.nexthop_num = 1;
868 api.nexthop = &nexthop;
869 api.ifindex_num = 0;
870 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
871 api.metric = info->attr->med;
872
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000873 if (BGP_DEBUG(zebra, ZEBRA))
874 {
875 char buf[2][INET_ADDRSTRLEN];
876 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
877 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
878 p->prefixlen,
879 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
880 api.metric);
881 }
882
paul0a589352004-05-08 11:48:26 +0000883 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
884 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000885 }
886#ifdef HAVE_IPV6
887 /* We have to think about a IPv6 link-local address curse. */
888 if (p->family == AF_INET6)
889 {
890 struct zapi_ipv6 api;
891 unsigned int ifindex;
892 struct in6_addr *nexthop;
Paul Jakmafb982c22007-05-04 20:15:47 +0000893
894 assert (info->attr->extra);
895
paul718e3742002-12-13 20:15:29 +0000896 ifindex = 0;
897 nexthop = NULL;
898
899 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000900 if (info->attr->extra->mp_nexthop_len == 16)
901 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000902
903 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000904 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000905 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000906 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000907 if (info->peer->nexthop.ifp)
908 ifindex = info->peer->nexthop.ifp->ifindex;
909 }
910
911 if (nexthop == NULL)
912 return;
913
914 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
915 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200916 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000917
918 api.flags = flags;
919 api.type = ZEBRA_ROUTE_BGP;
920 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400921 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000922 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
923 api.nexthop_num = 1;
924 api.nexthop = &nexthop;
925 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
926 api.ifindex_num = 1;
927 api.ifindex = &ifindex;
928 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
929 api.metric = info->attr->med;
930
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000931 if (BGP_DEBUG(zebra, ZEBRA))
932 {
933 char buf[2][INET6_ADDRSTRLEN];
934 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
935 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
936 p->prefixlen,
937 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
938 api.metric);
939 }
940
paul0a589352004-05-08 11:48:26 +0000941 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
942 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000943 }
944#endif /* HAVE_IPV6 */
945}
David Lamparter6b0655a2014-06-04 06:53:35 +0200946
paul718e3742002-12-13 20:15:29 +0000947/* Other routes redistribution into BGP. */
948int
949bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
950{
951 /* Set flag to BGP instance. */
952 bgp->redist[afi][type] = 1;
953
954 /* Return if already redistribute flag is set. */
955 if (zclient->redist[type])
956 return CMD_WARNING;
957
958 zclient->redist[type] = 1;
959
960 /* Return if zebra connection is not established. */
961 if (zclient->sock < 0)
962 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000963
964 if (BGP_DEBUG(zebra, ZEBRA))
965 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000966
967 /* Send distribute add message to zebra. */
ajs634f9ea2005-04-11 15:51:40 +0000968 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
paul718e3742002-12-13 20:15:29 +0000969
970 return CMD_SUCCESS;
971}
972
973/* Redistribute with route-map specification. */
974int
paulfd79ac92004-10-13 05:06:08 +0000975bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
976 const char *name)
paul718e3742002-12-13 20:15:29 +0000977{
978 if (bgp->rmap[afi][type].name
979 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
980 return 0;
981
982 if (bgp->rmap[afi][type].name)
983 free (bgp->rmap[afi][type].name);
984 bgp->rmap[afi][type].name = strdup (name);
985 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
986
987 return 1;
988}
989
990/* Redistribute with metric specification. */
991int
992bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
993 u_int32_t metric)
994{
995 if (bgp->redist_metric_flag[afi][type]
996 && bgp->redist_metric[afi][type] == metric)
997 return 0;
998
999 bgp->redist_metric_flag[afi][type] = 1;
1000 bgp->redist_metric[afi][type] = metric;
1001
1002 return 1;
1003}
1004
1005/* Unset redistribution. */
1006int
1007bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
1008{
1009 /* Unset flag from BGP instance. */
1010 bgp->redist[afi][type] = 0;
1011
1012 /* Unset route-map. */
1013 if (bgp->rmap[afi][type].name)
1014 free (bgp->rmap[afi][type].name);
1015 bgp->rmap[afi][type].name = NULL;
1016 bgp->rmap[afi][type].map = NULL;
1017
1018 /* Unset metric. */
1019 bgp->redist_metric_flag[afi][type] = 0;
1020 bgp->redist_metric[afi][type] = 0;
1021
1022 /* Return if zebra connection is disabled. */
1023 if (! zclient->redist[type])
1024 return CMD_WARNING;
1025 zclient->redist[type] = 0;
1026
1027 if (bgp->redist[AFI_IP][type] == 0
1028 && bgp->redist[AFI_IP6][type] == 0
1029 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001030 {
1031 /* Send distribute delete message to zebra. */
1032 if (BGP_DEBUG(zebra, ZEBRA))
1033 zlog_debug("Zebra send: redistribute delete %s",
1034 zebra_route_string(type));
1035 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
1036 }
paul718e3742002-12-13 20:15:29 +00001037
1038 /* Withdraw redistributed routes from current BGP's routing table. */
1039 bgp_redistribute_withdraw (bgp, afi, type);
1040
1041 return CMD_SUCCESS;
1042}
1043
1044/* Unset redistribution route-map configuration. */
1045int
1046bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
1047{
1048 if (! bgp->rmap[afi][type].name)
1049 return 0;
1050
1051 /* Unset route-map. */
1052 free (bgp->rmap[afi][type].name);
1053 bgp->rmap[afi][type].name = NULL;
1054 bgp->rmap[afi][type].map = NULL;
1055
1056 return 1;
1057}
1058
1059/* Unset redistribution metric configuration. */
1060int
1061bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1062{
1063 if (! bgp->redist_metric_flag[afi][type])
1064 return 0;
1065
1066 /* Unset metric. */
1067 bgp->redist_metric_flag[afi][type] = 0;
1068 bgp->redist_metric[afi][type] = 0;
1069
1070 return 1;
1071}
David Lamparter6b0655a2014-06-04 06:53:35 +02001072
paul718e3742002-12-13 20:15:29 +00001073void
paul94f2b392005-06-28 12:44:16 +00001074bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001075{
1076 zclient_reset (zclient);
1077}
1078
1079void
paul94f2b392005-06-28 12:44:16 +00001080bgp_zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001081{
1082 /* Set default values. */
1083 zclient = zclient_new ();
1084 zclient_init (zclient, ZEBRA_ROUTE_BGP);
hasso18a6dce2004-10-03 18:18:34 +00001085 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001086 zclient->interface_add = bgp_interface_add;
1087 zclient->interface_delete = bgp_interface_delete;
1088 zclient->interface_address_add = bgp_interface_address_add;
1089 zclient->interface_address_delete = bgp_interface_address_delete;
1090 zclient->ipv4_route_add = zebra_read_ipv4;
1091 zclient->ipv4_route_delete = zebra_read_ipv4;
1092 zclient->interface_up = bgp_interface_up;
1093 zclient->interface_down = bgp_interface_down;
1094#ifdef HAVE_IPV6
1095 zclient->ipv6_route_add = zebra_read_ipv6;
1096 zclient->ipv6_route_delete = zebra_read_ipv6;
1097#endif /* HAVE_IPV6 */
1098
Josh Bailey8196f132011-07-20 20:47:07 -07001099 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001100}