blob: 85380f0fc814bf1f19e35c89066fdcc0545a0a3c [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;
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
David Lamparter584083d2016-05-24 18:58:08 +020068 bgp_router_id_zebra_bump ();
paul718e3742002-12-13 20:15:29 +000069 return 0;
70}
71
72/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000073static int
Feng Luc99f3482014-10-16 09:52:36 +080074bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
75 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000076{
77 struct interface *ifp;
78
Feng Luc99f3482014-10-16 09:52:36 +080079 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +000080
Andrew J. Schorra39275d2006-11-30 16:36:57 +000081 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
82 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
83
paul718e3742002-12-13 20:15:29 +000084 return 0;
85}
86
paul94f2b392005-06-28 12:44:16 +000087static int
paul718e3742002-12-13 20:15:29 +000088bgp_interface_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +080089 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000090{
91 struct stream *s;
92 struct interface *ifp;
93
94 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +080095 ifp = zebra_interface_state_read (s, vrf_id);
ajsd2fc8892005-04-02 18:38:43 +000096 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +000097
Andrew J. Schorra39275d2006-11-30 16:36:57 +000098 if (BGP_DEBUG(zebra, ZEBRA))
99 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
100
paul718e3742002-12-13 20:15:29 +0000101 return 0;
102}
103
paul94f2b392005-06-28 12:44:16 +0000104static int
Feng Luc99f3482014-10-16 09:52:36 +0800105bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
106 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000107{
108 struct stream *s;
109 struct interface *ifp;
110 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000111 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000112
113 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800114 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000115
116 if (! ifp)
117 return 0;
118
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000119 if (BGP_DEBUG(zebra, ZEBRA))
120 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
121
paul1eb8ef22005-04-07 07:30:20 +0000122 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
123 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000124
125 return 0;
126}
127
paul94f2b392005-06-28 12:44:16 +0000128static int
Feng Luc99f3482014-10-16 09:52:36 +0800129bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
130 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000131{
132 struct stream *s;
133 struct interface *ifp;
134 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000135 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000136
137 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800138 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000139 if (! ifp)
140 return 0;
141
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000142 if (BGP_DEBUG(zebra, ZEBRA))
143 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
144
paul1eb8ef22005-04-07 07:30:20 +0000145 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
146 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000147
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000148 /* Fast external-failover */
paul718e3742002-12-13 20:15:29 +0000149 {
paul1eb8ef22005-04-07 07:30:20 +0000150 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000151 struct bgp *bgp;
152 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000153
paul1eb8ef22005-04-07 07:30:20 +0000154 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000155 {
156 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
157 continue;
158
paul1eb8ef22005-04-07 07:30:20 +0000159 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000160 {
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000161 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
paul718e3742002-12-13 20:15:29 +0000162 continue;
163
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000164 if (ifp == peer->nexthop.ifp)
paul718e3742002-12-13 20:15:29 +0000165 BGP_EVENT_ADD (peer, BGP_Stop);
166 }
167 }
168 }
169
170 return 0;
171}
172
paul94f2b392005-06-28 12:44:16 +0000173static int
paul718e3742002-12-13 20:15:29 +0000174bgp_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800175 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000176{
177 struct connected *ifc;
178
Feng Luc99f3482014-10-16 09:52:36 +0800179 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000180
181 if (ifc == NULL)
182 return 0;
183
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000184 if (BGP_DEBUG(zebra, ZEBRA))
185 {
186 char buf[128];
187 prefix2str(ifc->address, buf, sizeof(buf));
188 zlog_debug("Zebra rcvd: interface %s address add %s",
189 ifc->ifp->name, buf);
190 }
191
paul2e3b2e42002-12-13 21:03:13 +0000192 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000193 bgp_connected_add (ifc);
194
195 return 0;
196}
197
paul94f2b392005-06-28 12:44:16 +0000198static int
paul718e3742002-12-13 20:15:29 +0000199bgp_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800200 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000201{
202 struct connected *ifc;
203
Feng Luc99f3482014-10-16 09:52:36 +0800204 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000205
206 if (ifc == NULL)
207 return 0;
208
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000209 if (BGP_DEBUG(zebra, ZEBRA))
210 {
211 char buf[128];
212 prefix2str(ifc->address, buf, sizeof(buf));
213 zlog_debug("Zebra rcvd: interface %s address delete %s",
214 ifc->ifp->name, buf);
215 }
216
paul2e3b2e42002-12-13 21:03:13 +0000217 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000218 bgp_connected_delete (ifc);
219
220 connected_free (ifc);
221
222 return 0;
223}
224
225/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000226static int
Feng Luc99f3482014-10-16 09:52:36 +0800227zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
228 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000229{
230 struct stream *s;
231 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000232 struct in_addr nexthop;
233 struct prefix_ipv4 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500234 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000235
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;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500247 plength = stream_getc (s);
248 p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000249 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
250
251 /* Nexthop, ifindex, distance, metric. */
252 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
253 {
254 api.nexthop_num = stream_getc (s);
255 nexthop.s_addr = stream_get_ipv4 (s);
256 }
257 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
258 {
259 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400260 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000261 }
262 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
263 api.distance = stream_getc (s);
264 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
265 api.metric = stream_getl (s);
266 else
267 api.metric = 0;
268
269 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000270 {
271 if (BGP_DEBUG(zebra, ZEBRA))
272 {
273 char buf[2][INET_ADDRSTRLEN];
274 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
275 zebra_route_string(api.type),
276 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
277 p.prefixlen,
278 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
279 api.metric);
280 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400281 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
282 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000283 }
paul718e3742002-12-13 20:15:29 +0000284 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000285 {
286 if (BGP_DEBUG(zebra, ZEBRA))
287 {
288 char buf[2][INET_ADDRSTRLEN];
289 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
290 "nexthop %s metric %u",
291 zebra_route_string(api.type),
292 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
293 p.prefixlen,
294 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
295 api.metric);
296 }
297 bgp_redistribute_delete((struct prefix *)&p, api.type);
298 }
paul718e3742002-12-13 20:15:29 +0000299
300 return 0;
301}
302
paul718e3742002-12-13 20:15:29 +0000303/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000304static int
Feng Luc99f3482014-10-16 09:52:36 +0800305zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
306 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000307{
308 struct stream *s;
309 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000310 struct in6_addr nexthop;
311 struct prefix_ipv6 p;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500312 unsigned char plength = 0;
paul718e3742002-12-13 20:15:29 +0000313
314 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000315 memset (&nexthop, 0, sizeof (struct in6_addr));
316
317 /* Type, flags, message. */
318 api.type = stream_getc (s);
319 api.flags = stream_getc (s);
320 api.message = stream_getc (s);
321
322 /* IPv6 prefix. */
323 memset (&p, 0, sizeof (struct prefix_ipv6));
324 p.family = AF_INET6;
Donald Sharp5e57b5f2016-03-11 16:28:34 -0500325 plength = stream_getc (s);
326 p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength);
paul718e3742002-12-13 20:15:29 +0000327 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
328
329 /* Nexthop, ifindex, distance, metric. */
330 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
331 {
332 api.nexthop_num = stream_getc (s);
333 stream_get (&nexthop, s, 16);
334 }
335 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
336 {
337 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400338 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000339 }
340 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
341 api.distance = stream_getc (s);
342 else
343 api.distance = 0;
344 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
345 api.metric = stream_getl (s);
346 else
347 api.metric = 0;
348
349 /* Simply ignore link-local address. */
350 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
351 return 0;
352
353 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000354 {
355 if (BGP_DEBUG(zebra, ZEBRA))
356 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400357 char buf[2][INET6_ADDRSTRLEN];
358 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000359 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400360 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
361 p.prefixlen,
362 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
363 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000364 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400365 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
366 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000367 }
paul718e3742002-12-13 20:15:29 +0000368 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000369 {
370 if (BGP_DEBUG(zebra, ZEBRA))
371 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400372 char buf[2][INET6_ADDRSTRLEN];
373 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
374 "nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000375 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400376 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
377 p.prefixlen,
378 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
379 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000380 }
381 bgp_redistribute_delete ((struct prefix *) &p, api.type);
382 }
paul718e3742002-12-13 20:15:29 +0000383
384 return 0;
385}
David Lamparter6b0655a2014-06-04 06:53:35 +0200386
paul718e3742002-12-13 20:15:29 +0000387struct interface *
388if_lookup_by_ipv4 (struct in_addr *addr)
389{
hasso52dc7ee2004-09-23 19:18:23 +0000390 struct listnode *ifnode;
391 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000392 struct interface *ifp;
393 struct connected *connected;
394 struct prefix_ipv4 p;
395 struct prefix *cp;
396
397 p.family = AF_INET;
398 p.prefix = *addr;
399 p.prefixlen = IPV4_MAX_BITLEN;
400
paul1eb8ef22005-04-07 07:30:20 +0000401 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000402 {
paul1eb8ef22005-04-07 07:30:20 +0000403 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000404 {
paul718e3742002-12-13 20:15:29 +0000405 cp = connected->address;
406
407 if (cp->family == AF_INET)
408 if (prefix_match (cp, (struct prefix *)&p))
409 return ifp;
410 }
411 }
412 return NULL;
413}
414
415struct interface *
416if_lookup_by_ipv4_exact (struct in_addr *addr)
417{
hasso52dc7ee2004-09-23 19:18:23 +0000418 struct listnode *ifnode;
419 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000420 struct interface *ifp;
421 struct connected *connected;
422 struct prefix *cp;
423
paul1eb8ef22005-04-07 07:30:20 +0000424 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000425 {
paul1eb8ef22005-04-07 07:30:20 +0000426 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000427 {
paul718e3742002-12-13 20:15:29 +0000428 cp = connected->address;
429
430 if (cp->family == AF_INET)
431 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
432 return ifp;
433 }
434 }
435 return NULL;
436}
437
paul718e3742002-12-13 20:15:29 +0000438struct interface *
439if_lookup_by_ipv6 (struct in6_addr *addr)
440{
hasso52dc7ee2004-09-23 19:18:23 +0000441 struct listnode *ifnode;
442 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000443 struct interface *ifp;
444 struct connected *connected;
445 struct prefix_ipv6 p;
446 struct prefix *cp;
447
448 p.family = AF_INET6;
449 p.prefix = *addr;
450 p.prefixlen = IPV6_MAX_BITLEN;
451
paul1eb8ef22005-04-07 07:30:20 +0000452 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000453 {
paul1eb8ef22005-04-07 07:30:20 +0000454 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000455 {
paul718e3742002-12-13 20:15:29 +0000456 cp = connected->address;
457
458 if (cp->family == AF_INET6)
459 if (prefix_match (cp, (struct prefix *)&p))
460 return ifp;
461 }
462 }
463 return NULL;
464}
465
466struct interface *
467if_lookup_by_ipv6_exact (struct in6_addr *addr)
468{
hasso52dc7ee2004-09-23 19:18:23 +0000469 struct listnode *ifnode;
470 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000471 struct interface *ifp;
472 struct connected *connected;
473 struct prefix *cp;
474
paul1eb8ef22005-04-07 07:30:20 +0000475 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000476 {
paul1eb8ef22005-04-07 07:30:20 +0000477 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000478 {
paul718e3742002-12-13 20:15:29 +0000479 cp = connected->address;
480
481 if (cp->family == AF_INET6)
482 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
483 return ifp;
484 }
485 }
486 return NULL;
487}
488
paul94f2b392005-06-28 12:44:16 +0000489static int
paul718e3742002-12-13 20:15:29 +0000490if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
491{
hasso52dc7ee2004-09-23 19:18:23 +0000492 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000493 struct connected *connected;
494 struct prefix *cp;
495
paul1eb8ef22005-04-07 07:30:20 +0000496 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000497 {
paul718e3742002-12-13 20:15:29 +0000498 cp = connected->address;
499
500 if (cp->family == AF_INET6)
501 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
502 {
503 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
504 return 1;
505 }
506 }
507 return 0;
508}
509
paul94f2b392005-06-28 12:44:16 +0000510static int
paul718e3742002-12-13 20:15:29 +0000511if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
512{
hasso52dc7ee2004-09-23 19:18:23 +0000513 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000514 struct connected *connected;
515 struct prefix *cp;
516
paul1eb8ef22005-04-07 07:30:20 +0000517 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000518 {
paul718e3742002-12-13 20:15:29 +0000519 cp = connected->address;
520
521 if (cp->family == AF_INET6)
522 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
523 {
524 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
525 return 1;
526 }
527 }
528 return 0;
529}
paul718e3742002-12-13 20:15:29 +0000530
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 }
paul718e3742002-12-13 20:15:29 +0000569 if (local->sa.sa_family == AF_INET6)
570 {
571 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
572 {
573 if (peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200574 ifp = if_lookup_by_name (peer->ifname);
paul718e3742002-12-13 20:15:29 +0000575 }
576 else
577 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
578 }
paul718e3742002-12-13 20:15:29 +0000579
580 if (!ifp)
581 return -1;
582
583 nexthop->ifp = ifp;
584
585 /* IPv4 connection. */
586 if (local->sa.sa_family == AF_INET)
587 {
paul718e3742002-12-13 20:15:29 +0000588 /* IPv6 nexthop*/
589 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
590
591 /* There is no global nexthop. */
592 if (!ret)
593 if_get_ipv6_local (ifp, &nexthop->v6_global);
594 else
595 if_get_ipv6_local (ifp, &nexthop->v6_local);
paul718e3742002-12-13 20:15:29 +0000596 }
597
paul718e3742002-12-13 20:15:29 +0000598 /* IPv6 connection. */
599 if (local->sa.sa_family == AF_INET6)
600 {
601 struct interface *direct = NULL;
602
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000603 /* IPv4 nexthop. */
604 ret = if_get_ipv4_address(ifp, &nexthop->v4);
605 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000606 nexthop->v4 = peer->local_id;
607
608 /* Global address*/
609 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
610 {
611 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
612 IPV6_MAX_BYTELEN);
613
614 /* If directory connected set link-local address. */
615 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
616 if (direct)
617 if_get_ipv6_local (ifp, &nexthop->v6_local);
618 }
619 else
620 /* Link-local address. */
621 {
622 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
623
624 /* If there is no global address. Set link-local address as
625 global. I know this break RFC specification... */
626 if (!ret)
627 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
628 IPV6_MAX_BYTELEN);
629 else
630 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
631 IPV6_MAX_BYTELEN);
632 }
633 }
634
635 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
636 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
637 peer->shared_network = 1;
638 else
639 peer->shared_network = 0;
640
641 /* KAME stack specific treatment. */
642#ifdef KAME
643 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
644 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
645 {
646 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
647 }
648 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
649 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
650 {
651 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
652 }
653#endif /* KAME */
paul718e3742002-12-13 20:15:29 +0000654 return ret;
655}
656
paul718e3742002-12-13 20:15:29 +0000657void
G.Balaji5a616c02011-11-26 21:58:42 +0400658bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000659{
660 int flags;
661 u_char distance;
662 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700663 struct bgp_info *mpinfo;
664 size_t oldsize, newsize;
paul718e3742002-12-13 20:15:29 +0000665
666 if (zclient->sock < 0)
667 return;
668
Feng Luc99f3482014-10-16 09:52:36 +0800669 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000670 return;
671
672 flags = 0;
673 peer = info->peer;
674
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000675 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000676 {
677 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
678 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
679 }
680
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000681 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000682 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000683 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
684
Josh Bailey8196f132011-07-20 20:47:07 -0700685 /* resize nexthop buffer size if necessary */
686 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
687 (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
688 {
689 newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
690 newsize = stream_resize (bgp_nexthop_buf, newsize);
691 if (newsize == oldsize)
692 {
693 zlog_err ("can't resize nexthop buffer");
694 return;
695 }
696 }
697
698 stream_reset (bgp_nexthop_buf);
699
paul718e3742002-12-13 20:15:29 +0000700 if (p->family == AF_INET)
701 {
702 struct zapi_ipv4 api;
703 struct in_addr *nexthop;
704
Feng Luc99f3482014-10-16 09:52:36 +0800705 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000706 api.flags = flags;
707 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700708 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
709 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
710 mpinfo = bgp_info_mpath_next (mpinfo))
711 {
712 nexthop = &mpinfo->attr->nexthop;
713 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
714 }
paul718e3742002-12-13 20:15:29 +0000715
716 api.type = ZEBRA_ROUTE_BGP;
717 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400718 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000719 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Josh Bailey8196f132011-07-20 20:47:07 -0700720 api.nexthop_num = 1 + bgp_info_mpath_count (info);
721 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000722 api.ifindex_num = 0;
723 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
724 api.metric = info->attr->med;
725
726 distance = bgp_distance_apply (p, info, bgp);
727
728 if (distance)
729 {
730 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
731 api.distance = distance;
732 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000733
734 if (BGP_DEBUG(zebra, ZEBRA))
735 {
Josh Bailey8196f132011-07-20 20:47:07 -0700736 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000737 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700738 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
739 " count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000740 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
741 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700742 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
743 api.metric, api.nexthop_num);
744 for (i = 1; i < api.nexthop_num; i++)
745 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
746 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
747 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000748 }
749
paul0a589352004-05-08 11:48:26 +0000750 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
751 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000752 }
Lou Berger205e6742016-01-12 13:42:11 -0500753
paul718e3742002-12-13 20:15:29 +0000754 /* We have to think about a IPv6 link-local address curse. */
755 if (p->family == AF_INET6)
756 {
Paul Jakma9099f9b2016-01-18 10:12:10 +0000757 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000758 struct in6_addr *nexthop;
759 struct zapi_ipv6 api;
760
761 ifindex = 0;
762 nexthop = NULL;
Paul Jakmafb982c22007-05-04 20:15:47 +0000763
764 assert (info->attr->extra);
765
paul718e3742002-12-13 20:15:29 +0000766 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000767 if (info->attr->extra->mp_nexthop_len == 16)
768 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000769
770 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000771 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000772 {
773 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000774 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000775 && peer->su_remote->sa.sa_family == AF_INET6)
776 nexthop = &peer->su_remote->sin6.sin6_addr;
777 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000778 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000779
780 if (info->peer->nexthop.ifp)
781 ifindex = info->peer->nexthop.ifp->ifindex;
782 }
783
784 if (nexthop == NULL)
785 return;
786
787 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
788 {
789 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200790 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000791 else if (info->peer->nexthop.ifp)
792 ifindex = info->peer->nexthop.ifp->ifindex;
793 }
794
795 /* Make Zebra API structure. */
Feng Luc99f3482014-10-16 09:52:36 +0800796 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000797 api.flags = flags;
798 api.type = ZEBRA_ROUTE_BGP;
799 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400800 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000801 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
802 api.nexthop_num = 1;
803 api.nexthop = &nexthop;
804 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
805 api.ifindex_num = 1;
806 api.ifindex = &ifindex;
807 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
808 api.metric = info->attr->med;
809
Roman Hoog Antink6184c392014-03-17 14:01:42 +0100810 distance = ipv6_bgp_distance_apply (p, info, bgp);
811
812 if (distance)
813 {
814 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
815 api.distance = distance;
816 }
817
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000818 if (BGP_DEBUG(zebra, ZEBRA))
819 {
820 char buf[2][INET6_ADDRSTRLEN];
821 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
822 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
823 p->prefixlen,
824 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
825 api.metric);
826 }
827
paul0a589352004-05-08 11:48:26 +0000828 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
829 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000830 }
paul718e3742002-12-13 20:15:29 +0000831}
832
833void
G.Balaji5a616c02011-11-26 21:58:42 +0400834bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000835{
836 int flags;
837 struct peer *peer;
838
839 if (zclient->sock < 0)
840 return;
841
Feng Luc99f3482014-10-16 09:52:36 +0800842 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000843 return;
844
845 peer = info->peer;
846 flags = 0;
847
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000848 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000849 {
850 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
851 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
852 }
853
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000854 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000855 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000856 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
857
858 if (p->family == AF_INET)
859 {
860 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000861
Feng Luc99f3482014-10-16 09:52:36 +0800862 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000863 api.flags = flags;
paul718e3742002-12-13 20:15:29 +0000864
865 api.type = ZEBRA_ROUTE_BGP;
866 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400867 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +0000868 api.nexthop_num = 0;
paul718e3742002-12-13 20:15:29 +0000869 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];
Paul Jakma64e0ac22015-11-18 16:00:54 +0000876 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000877 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
878 p->prefixlen,
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000879 api.metric);
880 }
881
paul0a589352004-05-08 11:48:26 +0000882 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
883 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000884 }
Lou Berger205e6742016-01-12 13:42:11 -0500885
paul718e3742002-12-13 20:15:29 +0000886 /* We have to think about a IPv6 link-local address curse. */
887 if (p->family == AF_INET6)
888 {
889 struct zapi_ipv6 api;
Paul Jakmafb982c22007-05-04 20:15:47 +0000890
Feng Luc99f3482014-10-16 09:52:36 +0800891 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000892 api.flags = flags;
893 api.type = ZEBRA_ROUTE_BGP;
894 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400895 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +0000896 api.nexthop_num = 0;
897 api.ifindex_num = 0;
paul718e3742002-12-13 20:15:29 +0000898 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
899 api.metric = info->attr->med;
900
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000901 if (BGP_DEBUG(zebra, ZEBRA))
902 {
903 char buf[2][INET6_ADDRSTRLEN];
Paul Jakma64e0ac22015-11-18 16:00:54 +0000904 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000905 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
906 p->prefixlen,
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000907 api.metric);
908 }
909
paul0a589352004-05-08 11:48:26 +0000910 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
911 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000912 }
paul718e3742002-12-13 20:15:29 +0000913}
David Lamparter6b0655a2014-06-04 06:53:35 +0200914
paul718e3742002-12-13 20:15:29 +0000915/* Other routes redistribution into BGP. */
916int
917bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
918{
919 /* Set flag to BGP instance. */
920 bgp->redist[afi][type] = 1;
921
922 /* Return if already redistribute flag is set. */
Feng Luc99f3482014-10-16 09:52:36 +0800923 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000924 return CMD_WARNING;
925
Feng Luc99f3482014-10-16 09:52:36 +0800926 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000927
928 /* Return if zebra connection is not established. */
929 if (zclient->sock < 0)
930 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000931
932 if (BGP_DEBUG(zebra, ZEBRA))
933 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000934
935 /* Send distribute add message to zebra. */
Feng Luc99f3482014-10-16 09:52:36 +0800936 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000937
938 return CMD_SUCCESS;
939}
940
941/* Redistribute with route-map specification. */
942int
paulfd79ac92004-10-13 05:06:08 +0000943bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
944 const char *name)
paul718e3742002-12-13 20:15:29 +0000945{
946 if (bgp->rmap[afi][type].name
947 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
948 return 0;
949
950 if (bgp->rmap[afi][type].name)
951 free (bgp->rmap[afi][type].name);
952 bgp->rmap[afi][type].name = strdup (name);
953 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
954
955 return 1;
956}
957
958/* Redistribute with metric specification. */
959int
960bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
961 u_int32_t metric)
962{
963 if (bgp->redist_metric_flag[afi][type]
964 && bgp->redist_metric[afi][type] == metric)
965 return 0;
966
967 bgp->redist_metric_flag[afi][type] = 1;
968 bgp->redist_metric[afi][type] = metric;
969
970 return 1;
971}
972
973/* Unset redistribution. */
974int
975bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
976{
977 /* Unset flag from BGP instance. */
978 bgp->redist[afi][type] = 0;
979
980 /* Unset route-map. */
981 if (bgp->rmap[afi][type].name)
982 free (bgp->rmap[afi][type].name);
983 bgp->rmap[afi][type].name = NULL;
984 bgp->rmap[afi][type].map = NULL;
985
986 /* Unset metric. */
987 bgp->redist_metric_flag[afi][type] = 0;
988 bgp->redist_metric[afi][type] = 0;
989
990 /* Return if zebra connection is disabled. */
Feng Luc99f3482014-10-16 09:52:36 +0800991 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000992 return CMD_WARNING;
Feng Luc99f3482014-10-16 09:52:36 +0800993 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000994
995 if (bgp->redist[AFI_IP][type] == 0
996 && bgp->redist[AFI_IP6][type] == 0
997 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000998 {
999 /* Send distribute delete message to zebra. */
1000 if (BGP_DEBUG(zebra, ZEBRA))
1001 zlog_debug("Zebra send: redistribute delete %s",
1002 zebra_route_string(type));
Feng Luc99f3482014-10-16 09:52:36 +08001003 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
1004 VRF_DEFAULT);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001005 }
paul718e3742002-12-13 20:15:29 +00001006
1007 /* Withdraw redistributed routes from current BGP's routing table. */
1008 bgp_redistribute_withdraw (bgp, afi, type);
1009
1010 return CMD_SUCCESS;
1011}
1012
1013/* Unset redistribution route-map configuration. */
1014int
1015bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
1016{
1017 if (! bgp->rmap[afi][type].name)
1018 return 0;
1019
1020 /* Unset route-map. */
1021 free (bgp->rmap[afi][type].name);
1022 bgp->rmap[afi][type].name = NULL;
1023 bgp->rmap[afi][type].map = NULL;
1024
1025 return 1;
1026}
1027
1028/* Unset redistribution metric configuration. */
1029int
1030bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1031{
1032 if (! bgp->redist_metric_flag[afi][type])
1033 return 0;
1034
1035 /* Unset metric. */
1036 bgp->redist_metric_flag[afi][type] = 0;
1037 bgp->redist_metric[afi][type] = 0;
1038
1039 return 1;
1040}
David Lamparter6b0655a2014-06-04 06:53:35 +02001041
paul718e3742002-12-13 20:15:29 +00001042void
paul94f2b392005-06-28 12:44:16 +00001043bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001044{
1045 zclient_reset (zclient);
1046}
1047
Feng Luc99f3482014-10-16 09:52:36 +08001048static void
1049bgp_zebra_connected (struct zclient *zclient)
1050{
1051 zclient_send_requests (zclient, VRF_DEFAULT);
1052}
1053
paul718e3742002-12-13 20:15:29 +00001054void
Donald Sharp71252932015-09-24 09:25:19 -04001055bgp_zebra_init (struct thread_master *master)
paul718e3742002-12-13 20:15:29 +00001056{
1057 /* Set default values. */
Donald Sharp71252932015-09-24 09:25:19 -04001058 zclient = zclient_new (master);
paul718e3742002-12-13 20:15:29 +00001059 zclient_init (zclient, ZEBRA_ROUTE_BGP);
Feng Luc99f3482014-10-16 09:52:36 +08001060 zclient->zebra_connected = bgp_zebra_connected;
hasso18a6dce2004-10-03 18:18:34 +00001061 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001062 zclient->interface_add = bgp_interface_add;
1063 zclient->interface_delete = bgp_interface_delete;
1064 zclient->interface_address_add = bgp_interface_address_add;
1065 zclient->interface_address_delete = bgp_interface_address_delete;
1066 zclient->ipv4_route_add = zebra_read_ipv4;
1067 zclient->ipv4_route_delete = zebra_read_ipv4;
1068 zclient->interface_up = bgp_interface_up;
1069 zclient->interface_down = bgp_interface_down;
paul718e3742002-12-13 20:15:29 +00001070 zclient->ipv6_route_add = zebra_read_ipv6;
1071 zclient->ipv6_route_delete = zebra_read_ipv6;
paul718e3742002-12-13 20:15:29 +00001072
Josh Bailey8196f132011-07-20 20:47:07 -07001073 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001074}
Lou Berger82dd7072016-01-12 13:41:57 -05001075
1076void
1077bgp_zebra_destroy(void)
1078{
1079 if (zclient == NULL)
1080 return;
1081 zclient_stop(zclient);
1082 zclient_free(zclient);
1083 zclient = NULL;
1084}