blob: 4a25aa91cee8d93a999631fa298e08ae571bd54e [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* zebra client
2 Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21#include <zebra.h>
22
23#include "command.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "log.h"
28#include "sockunion.h"
29#include "zclient.h"
30#include "routemap.h"
31#include "thread.h"
Donald Sharp04907292016-01-07 10:03:01 -050032#include "filter.h"
paul718e3742002-12-13 20:15:29 +000033
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_route.h"
36#include "bgpd/bgp_attr.h"
37#include "bgpd/bgp_nexthop.h"
38#include "bgpd/bgp_zebra.h"
39#include "bgpd/bgp_fsm.h"
Andrew J. Schorra39275d2006-11-30 16:36:57 +000040#include "bgpd/bgp_debug.h"
Josh Bailey8196f132011-07-20 20:47:07 -070041#include "bgpd/bgp_mpath.h"
David Lamparter6b0655a2014-06-04 06:53:35 +020042
paul718e3742002-12-13 20:15:29 +000043/* All information about zebra. */
Chris Caputo228da422009-07-18 05:44:03 +000044struct zclient *zclient = NULL;
hasso18a6dce2004-10-03 18:18:34 +000045struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000046
Josh Bailey8196f132011-07-20 20:47:07 -070047/* Growable buffer for nexthops sent to zebra */
48struct stream *bgp_nexthop_buf = NULL;
49
hasso18a6dce2004-10-03 18:18:34 +000050/* Router-id update message from zebra. */
paul94f2b392005-06-28 12:44:16 +000051static int
Feng Luc99f3482014-10-16 09:52:36 +080052bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
53 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000054{
hasso18a6dce2004-10-03 18:18:34 +000055 struct prefix router_id;
paul1eb8ef22005-04-07 07:30:20 +000056 struct listnode *node, *nnode;
hasso18a6dce2004-10-03 18:18:34 +000057 struct bgp *bgp;
paul718e3742002-12-13 20:15:29 +000058
hasso18a6dce2004-10-03 18:18:34 +000059 zebra_router_id_update_read(zclient->ibuf,&router_id);
Andrew J. Schorra39275d2006-11-30 16:36:57 +000060
61 if (BGP_DEBUG(zebra, ZEBRA))
62 {
63 char buf[128];
64 prefix2str(&router_id, buf, sizeof(buf));
65 zlog_debug("Zebra rcvd: router id update %s", buf);
66 }
67
hasso18a6dce2004-10-03 18:18:34 +000068 router_id_zebra = router_id.u.prefix4;
69
paul1eb8ef22005-04-07 07:30:20 +000070 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
paul718e3742002-12-13 20:15:29 +000071 {
hasso18a6dce2004-10-03 18:18:34 +000072 if (!bgp->router_id_static.s_addr)
paul1eb8ef22005-04-07 07:30:20 +000073 bgp_router_id_set (bgp, &router_id.u.prefix4);
paul718e3742002-12-13 20:15:29 +000074 }
paul718e3742002-12-13 20:15:29 +000075
paul718e3742002-12-13 20:15:29 +000076 return 0;
77}
78
79/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000080static int
Feng Luc99f3482014-10-16 09:52:36 +080081bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
82 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000083{
84 struct interface *ifp;
85
Feng Luc99f3482014-10-16 09:52:36 +080086 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +000087
Andrew J. Schorra39275d2006-11-30 16:36:57 +000088 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
89 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
90
paul718e3742002-12-13 20:15:29 +000091 return 0;
92}
93
paul94f2b392005-06-28 12:44:16 +000094static int
paul718e3742002-12-13 20:15:29 +000095bgp_interface_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +080096 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +000097{
98 struct stream *s;
99 struct interface *ifp;
100
101 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800102 ifp = zebra_interface_state_read (s, vrf_id);
ajsd2fc8892005-04-02 18:38:43 +0000103 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000104
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000105 if (BGP_DEBUG(zebra, ZEBRA))
106 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
107
paul718e3742002-12-13 20:15:29 +0000108 return 0;
109}
110
paul94f2b392005-06-28 12:44:16 +0000111static int
Feng Luc99f3482014-10-16 09:52:36 +0800112bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
113 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000114{
115 struct stream *s;
116 struct interface *ifp;
117 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000118 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000119
120 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800121 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000122
123 if (! ifp)
124 return 0;
125
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000126 if (BGP_DEBUG(zebra, ZEBRA))
127 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
128
paul1eb8ef22005-04-07 07:30:20 +0000129 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
130 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000131
132 return 0;
133}
134
paul94f2b392005-06-28 12:44:16 +0000135static int
Feng Luc99f3482014-10-16 09:52:36 +0800136bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
137 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000138{
139 struct stream *s;
140 struct interface *ifp;
141 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000142 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000143
144 s = zclient->ibuf;
Feng Luc99f3482014-10-16 09:52:36 +0800145 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000146 if (! ifp)
147 return 0;
148
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000149 if (BGP_DEBUG(zebra, ZEBRA))
150 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
151
paul1eb8ef22005-04-07 07:30:20 +0000152 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
153 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000154
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000155 /* Fast external-failover */
paul718e3742002-12-13 20:15:29 +0000156 {
paul1eb8ef22005-04-07 07:30:20 +0000157 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000158 struct bgp *bgp;
159 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000160
paul1eb8ef22005-04-07 07:30:20 +0000161 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000162 {
163 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
164 continue;
165
paul1eb8ef22005-04-07 07:30:20 +0000166 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000167 {
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000168 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
paul718e3742002-12-13 20:15:29 +0000169 continue;
170
Pradosh Mohapatra8da86892013-09-11 03:33:55 +0000171 if (ifp == peer->nexthop.ifp)
paul718e3742002-12-13 20:15:29 +0000172 BGP_EVENT_ADD (peer, BGP_Stop);
173 }
174 }
175 }
176
177 return 0;
178}
179
paul94f2b392005-06-28 12:44:16 +0000180static int
paul718e3742002-12-13 20:15:29 +0000181bgp_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800182 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000183{
184 struct connected *ifc;
185
Feng Luc99f3482014-10-16 09:52:36 +0800186 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000187
188 if (ifc == NULL)
189 return 0;
190
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000191 if (BGP_DEBUG(zebra, ZEBRA))
192 {
193 char buf[128];
194 prefix2str(ifc->address, buf, sizeof(buf));
195 zlog_debug("Zebra rcvd: interface %s address add %s",
196 ifc->ifp->name, buf);
197 }
198
paul2e3b2e42002-12-13 21:03:13 +0000199 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000200 bgp_connected_add (ifc);
201
202 return 0;
203}
204
paul94f2b392005-06-28 12:44:16 +0000205static int
paul718e3742002-12-13 20:15:29 +0000206bgp_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800207 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000208{
209 struct connected *ifc;
210
Feng Luc99f3482014-10-16 09:52:36 +0800211 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000212
213 if (ifc == NULL)
214 return 0;
215
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000216 if (BGP_DEBUG(zebra, ZEBRA))
217 {
218 char buf[128];
219 prefix2str(ifc->address, buf, sizeof(buf));
220 zlog_debug("Zebra rcvd: interface %s address delete %s",
221 ifc->ifp->name, buf);
222 }
223
paul2e3b2e42002-12-13 21:03:13 +0000224 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000225 bgp_connected_delete (ifc);
226
227 connected_free (ifc);
228
229 return 0;
230}
231
232/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000233static int
Feng Luc99f3482014-10-16 09:52:36 +0800234zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
235 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000236{
237 struct stream *s;
238 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000239 struct in_addr nexthop;
240 struct prefix_ipv4 p;
241
242 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000243 nexthop.s_addr = 0;
244
245 /* Type, flags, message. */
246 api.type = stream_getc (s);
247 api.flags = stream_getc (s);
248 api.message = stream_getc (s);
249
250 /* IPv4 prefix. */
251 memset (&p, 0, sizeof (struct prefix_ipv4));
252 p.family = AF_INET;
253 p.prefixlen = stream_getc (s);
254 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
255
256 /* Nexthop, ifindex, distance, metric. */
257 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
258 {
259 api.nexthop_num = stream_getc (s);
260 nexthop.s_addr = stream_get_ipv4 (s);
261 }
262 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
263 {
264 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400265 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000266 }
267 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
268 api.distance = stream_getc (s);
269 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
270 api.metric = stream_getl (s);
271 else
272 api.metric = 0;
273
274 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000275 {
276 if (BGP_DEBUG(zebra, ZEBRA))
277 {
278 char buf[2][INET_ADDRSTRLEN];
279 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
280 zebra_route_string(api.type),
281 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
282 p.prefixlen,
283 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
284 api.metric);
285 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400286 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
287 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000288 }
paul718e3742002-12-13 20:15:29 +0000289 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000290 {
291 if (BGP_DEBUG(zebra, ZEBRA))
292 {
293 char buf[2][INET_ADDRSTRLEN];
294 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
295 "nexthop %s metric %u",
296 zebra_route_string(api.type),
297 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
298 p.prefixlen,
299 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
300 api.metric);
301 }
302 bgp_redistribute_delete((struct prefix *)&p, api.type);
303 }
paul718e3742002-12-13 20:15:29 +0000304
305 return 0;
306}
307
308#ifdef HAVE_IPV6
309/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000310static int
Feng Luc99f3482014-10-16 09:52:36 +0800311zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
312 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000313{
314 struct stream *s;
315 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000316 struct in6_addr nexthop;
317 struct prefix_ipv6 p;
318
319 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000320 memset (&nexthop, 0, sizeof (struct in6_addr));
321
322 /* Type, flags, message. */
323 api.type = stream_getc (s);
324 api.flags = stream_getc (s);
325 api.message = stream_getc (s);
326
327 /* IPv6 prefix. */
328 memset (&p, 0, sizeof (struct prefix_ipv6));
329 p.family = AF_INET6;
330 p.prefixlen = stream_getc (s);
331 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
332
333 /* Nexthop, ifindex, distance, metric. */
334 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
335 {
336 api.nexthop_num = stream_getc (s);
337 stream_get (&nexthop, s, 16);
338 }
339 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
340 {
341 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400342 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000343 }
344 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
345 api.distance = stream_getc (s);
346 else
347 api.distance = 0;
348 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
349 api.metric = stream_getl (s);
350 else
351 api.metric = 0;
352
353 /* Simply ignore link-local address. */
354 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
355 return 0;
356
357 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000358 {
359 if (BGP_DEBUG(zebra, ZEBRA))
360 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400361 char buf[2][INET6_ADDRSTRLEN];
362 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000363 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400364 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
365 p.prefixlen,
366 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
367 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000368 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400369 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
370 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000371 }
paul718e3742002-12-13 20:15:29 +0000372 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000373 {
374 if (BGP_DEBUG(zebra, ZEBRA))
375 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400376 char buf[2][INET6_ADDRSTRLEN];
377 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
378 "nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000379 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400380 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
381 p.prefixlen,
382 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
383 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000384 }
385 bgp_redistribute_delete ((struct prefix *) &p, api.type);
386 }
paul718e3742002-12-13 20:15:29 +0000387
388 return 0;
389}
390#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +0200391
paul718e3742002-12-13 20:15:29 +0000392struct interface *
393if_lookup_by_ipv4 (struct in_addr *addr)
394{
hasso52dc7ee2004-09-23 19:18:23 +0000395 struct listnode *ifnode;
396 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000397 struct interface *ifp;
398 struct connected *connected;
399 struct prefix_ipv4 p;
400 struct prefix *cp;
401
402 p.family = AF_INET;
403 p.prefix = *addr;
404 p.prefixlen = IPV4_MAX_BITLEN;
405
paul1eb8ef22005-04-07 07:30:20 +0000406 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000407 {
paul1eb8ef22005-04-07 07:30:20 +0000408 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000409 {
paul718e3742002-12-13 20:15:29 +0000410 cp = connected->address;
411
412 if (cp->family == AF_INET)
413 if (prefix_match (cp, (struct prefix *)&p))
414 return ifp;
415 }
416 }
417 return NULL;
418}
419
420struct interface *
421if_lookup_by_ipv4_exact (struct in_addr *addr)
422{
hasso52dc7ee2004-09-23 19:18:23 +0000423 struct listnode *ifnode;
424 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000425 struct interface *ifp;
426 struct connected *connected;
427 struct prefix *cp;
428
paul1eb8ef22005-04-07 07:30:20 +0000429 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000430 {
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000432 {
paul718e3742002-12-13 20:15:29 +0000433 cp = connected->address;
434
435 if (cp->family == AF_INET)
436 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
437 return ifp;
438 }
439 }
440 return NULL;
441}
442
443#ifdef HAVE_IPV6
444struct interface *
445if_lookup_by_ipv6 (struct in6_addr *addr)
446{
hasso52dc7ee2004-09-23 19:18:23 +0000447 struct listnode *ifnode;
448 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000449 struct interface *ifp;
450 struct connected *connected;
451 struct prefix_ipv6 p;
452 struct prefix *cp;
453
454 p.family = AF_INET6;
455 p.prefix = *addr;
456 p.prefixlen = IPV6_MAX_BITLEN;
457
paul1eb8ef22005-04-07 07:30:20 +0000458 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000459 {
paul1eb8ef22005-04-07 07:30:20 +0000460 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000461 {
paul718e3742002-12-13 20:15:29 +0000462 cp = connected->address;
463
464 if (cp->family == AF_INET6)
465 if (prefix_match (cp, (struct prefix *)&p))
466 return ifp;
467 }
468 }
469 return NULL;
470}
471
472struct interface *
473if_lookup_by_ipv6_exact (struct in6_addr *addr)
474{
hasso52dc7ee2004-09-23 19:18:23 +0000475 struct listnode *ifnode;
476 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000477 struct interface *ifp;
478 struct connected *connected;
479 struct prefix *cp;
480
paul1eb8ef22005-04-07 07:30:20 +0000481 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000482 {
paul1eb8ef22005-04-07 07:30:20 +0000483 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000484 {
paul718e3742002-12-13 20:15:29 +0000485 cp = connected->address;
486
487 if (cp->family == AF_INET6)
488 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
489 return ifp;
490 }
491 }
492 return NULL;
493}
494
paul94f2b392005-06-28 12:44:16 +0000495static int
paul718e3742002-12-13 20:15:29 +0000496if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
497{
hasso52dc7ee2004-09-23 19:18:23 +0000498 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000499 struct connected *connected;
500 struct prefix *cp;
501
paul1eb8ef22005-04-07 07:30:20 +0000502 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000503 {
paul718e3742002-12-13 20:15:29 +0000504 cp = connected->address;
505
506 if (cp->family == AF_INET6)
507 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
508 {
509 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
510 return 1;
511 }
512 }
513 return 0;
514}
515
paul94f2b392005-06-28 12:44:16 +0000516static int
paul718e3742002-12-13 20:15:29 +0000517if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
518{
hasso52dc7ee2004-09-23 19:18:23 +0000519 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000520 struct connected *connected;
521 struct prefix *cp;
522
paul1eb8ef22005-04-07 07:30:20 +0000523 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000524 {
paul718e3742002-12-13 20:15:29 +0000525 cp = connected->address;
526
527 if (cp->family == AF_INET6)
528 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
529 {
530 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
531 return 1;
532 }
533 }
534 return 0;
535}
536#endif /* HAVE_IPV6 */
537
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000538static int
539if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
540{
541 struct listnode *cnode;
542 struct connected *connected;
543 struct prefix *cp;
544
545 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
546 {
547 cp = connected->address;
548 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
549 {
550 *addr = cp->u.prefix4;
551 return 1;
552 }
553 }
554 return 0;
555}
556
paul718e3742002-12-13 20:15:29 +0000557int
558bgp_nexthop_set (union sockunion *local, union sockunion *remote,
559 struct bgp_nexthop *nexthop, struct peer *peer)
560{
561 int ret = 0;
562 struct interface *ifp = NULL;
563
564 memset (nexthop, 0, sizeof (struct bgp_nexthop));
565
566 if (!local)
567 return -1;
568 if (!remote)
569 return -1;
570
571 if (local->sa.sa_family == AF_INET)
572 {
573 nexthop->v4 = local->sin.sin_addr;
574 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
575 }
576#ifdef HAVE_IPV6
577 if (local->sa.sa_family == AF_INET6)
578 {
579 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
580 {
581 if (peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200582 ifp = if_lookup_by_name (peer->ifname);
paul718e3742002-12-13 20:15:29 +0000583 }
584 else
585 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
586 }
587#endif /* HAVE_IPV6 */
588
589 if (!ifp)
590 return -1;
591
592 nexthop->ifp = ifp;
593
594 /* IPv4 connection. */
595 if (local->sa.sa_family == AF_INET)
596 {
597#ifdef HAVE_IPV6
598 /* IPv6 nexthop*/
599 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
600
601 /* There is no global nexthop. */
602 if (!ret)
603 if_get_ipv6_local (ifp, &nexthop->v6_global);
604 else
605 if_get_ipv6_local (ifp, &nexthop->v6_local);
606#endif /* HAVE_IPV6 */
607 }
608
609#ifdef HAVE_IPV6
610 /* IPv6 connection. */
611 if (local->sa.sa_family == AF_INET6)
612 {
613 struct interface *direct = NULL;
614
Pradosh Mohapatra6ee06fa2014-01-12 18:30:13 +0000615 /* IPv4 nexthop. */
616 ret = if_get_ipv4_address(ifp, &nexthop->v4);
617 if (!ret && peer->local_id.s_addr)
paul718e3742002-12-13 20:15:29 +0000618 nexthop->v4 = peer->local_id;
619
620 /* Global address*/
621 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
622 {
623 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
624 IPV6_MAX_BYTELEN);
625
626 /* If directory connected set link-local address. */
627 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
628 if (direct)
629 if_get_ipv6_local (ifp, &nexthop->v6_local);
630 }
631 else
632 /* Link-local address. */
633 {
634 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
635
636 /* If there is no global address. Set link-local address as
637 global. I know this break RFC specification... */
638 if (!ret)
639 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
640 IPV6_MAX_BYTELEN);
641 else
642 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
643 IPV6_MAX_BYTELEN);
644 }
645 }
646
647 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
648 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
649 peer->shared_network = 1;
650 else
651 peer->shared_network = 0;
652
653 /* KAME stack specific treatment. */
654#ifdef KAME
655 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
656 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
657 {
658 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
659 }
660 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
661 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
662 {
663 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
664 }
665#endif /* KAME */
666#endif /* HAVE_IPV6 */
667 return ret;
668}
669
paul718e3742002-12-13 20:15:29 +0000670void
G.Balaji5a616c02011-11-26 21:58:42 +0400671bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000672{
673 int flags;
674 u_char distance;
675 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700676 struct bgp_info *mpinfo;
677 size_t oldsize, newsize;
paul718e3742002-12-13 20:15:29 +0000678
679 if (zclient->sock < 0)
680 return;
681
Feng Luc99f3482014-10-16 09:52:36 +0800682 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000683 return;
684
685 flags = 0;
686 peer = info->peer;
687
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000688 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
paul718e3742002-12-13 20:15:29 +0000689 {
690 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
691 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
692 }
693
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000694 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000695 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000696 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
697
Josh Bailey8196f132011-07-20 20:47:07 -0700698 /* resize nexthop buffer size if necessary */
699 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
700 (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
701 {
702 newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
703 newsize = stream_resize (bgp_nexthop_buf, newsize);
704 if (newsize == oldsize)
705 {
706 zlog_err ("can't resize nexthop buffer");
707 return;
708 }
709 }
710
711 stream_reset (bgp_nexthop_buf);
712
paul718e3742002-12-13 20:15:29 +0000713 if (p->family == AF_INET)
714 {
715 struct zapi_ipv4 api;
716 struct in_addr *nexthop;
717
Feng Luc99f3482014-10-16 09:52:36 +0800718 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000719 api.flags = flags;
720 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700721 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
722 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
723 mpinfo = bgp_info_mpath_next (mpinfo))
724 {
725 nexthop = &mpinfo->attr->nexthop;
726 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
727 }
paul718e3742002-12-13 20:15:29 +0000728
729 api.type = ZEBRA_ROUTE_BGP;
730 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400731 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000732 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Josh Bailey8196f132011-07-20 20:47:07 -0700733 api.nexthop_num = 1 + bgp_info_mpath_count (info);
734 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000735 api.ifindex_num = 0;
736 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
737 api.metric = info->attr->med;
738
739 distance = bgp_distance_apply (p, info, bgp);
740
741 if (distance)
742 {
743 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
744 api.distance = distance;
745 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000746
747 if (BGP_DEBUG(zebra, ZEBRA))
748 {
Josh Bailey8196f132011-07-20 20:47:07 -0700749 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000750 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700751 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
752 " count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000753 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
754 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700755 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
756 api.metric, api.nexthop_num);
757 for (i = 1; i < api.nexthop_num; i++)
758 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
759 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
760 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000761 }
762
paul0a589352004-05-08 11:48:26 +0000763 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
764 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000765 }
766#ifdef HAVE_IPV6
767 /* We have to think about a IPv6 link-local address curse. */
768 if (p->family == AF_INET6)
769 {
770 unsigned int ifindex;
771 struct in6_addr *nexthop;
772 struct zapi_ipv6 api;
773
774 ifindex = 0;
775 nexthop = NULL;
Paul Jakmafb982c22007-05-04 20:15:47 +0000776
777 assert (info->attr->extra);
778
paul718e3742002-12-13 20:15:29 +0000779 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000780 if (info->attr->extra->mp_nexthop_len == 16)
781 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000782
783 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000784 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000785 {
786 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000787 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000788 && peer->su_remote->sa.sa_family == AF_INET6)
789 nexthop = &peer->su_remote->sin6.sin6_addr;
790 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000791 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000792
793 if (info->peer->nexthop.ifp)
794 ifindex = info->peer->nexthop.ifp->ifindex;
795 }
796
797 if (nexthop == NULL)
798 return;
799
800 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
801 {
802 if (info->peer->ifname)
Feng Lu395828e2015-05-22 11:39:55 +0200803 ifindex = ifname2ifindex (info->peer->ifname);
paul718e3742002-12-13 20:15:29 +0000804 else if (info->peer->nexthop.ifp)
805 ifindex = info->peer->nexthop.ifp->ifindex;
806 }
807
808 /* Make Zebra API structure. */
Feng Luc99f3482014-10-16 09:52:36 +0800809 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000810 api.flags = flags;
811 api.type = ZEBRA_ROUTE_BGP;
812 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400813 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000814 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
815 api.nexthop_num = 1;
816 api.nexthop = &nexthop;
817 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
818 api.ifindex_num = 1;
819 api.ifindex = &ifindex;
820 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
821 api.metric = info->attr->med;
822
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000823 if (BGP_DEBUG(zebra, ZEBRA))
824 {
825 char buf[2][INET6_ADDRSTRLEN];
826 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
827 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
828 p->prefixlen,
829 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
830 api.metric);
831 }
832
paul0a589352004-05-08 11:48:26 +0000833 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
834 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000835 }
836#endif /* HAVE_IPV6 */
837}
838
839void
G.Balaji5a616c02011-11-26 21:58:42 +0400840bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000841{
842 int flags;
843 struct peer *peer;
844
845 if (zclient->sock < 0)
846 return;
847
Feng Luc99f3482014-10-16 09:52:36 +0800848 if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000849 return;
850
851 peer = info->peer;
852 flags = 0;
853
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000854 if (peer->sort == BGP_PEER_IBGP)
paul718e3742002-12-13 20:15:29 +0000855 {
856 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
857 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
858 }
859
Jorge Boncompte [DTI2]6d85b152012-05-07 16:52:54 +0000860 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000861 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000862 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
863
864 if (p->family == AF_INET)
865 {
866 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000867
Feng Luc99f3482014-10-16 09:52:36 +0800868 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000869 api.flags = flags;
paul718e3742002-12-13 20:15:29 +0000870
871 api.type = ZEBRA_ROUTE_BGP;
872 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400873 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +0000874 api.nexthop_num = 0;
paul718e3742002-12-13 20:15:29 +0000875 api.ifindex_num = 0;
876 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
877 api.metric = info->attr->med;
878
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000879 if (BGP_DEBUG(zebra, ZEBRA))
880 {
881 char buf[2][INET_ADDRSTRLEN];
Paul Jakma64e0ac22015-11-18 16:00:54 +0000882 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000883 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
884 p->prefixlen,
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000885 api.metric);
886 }
887
paul0a589352004-05-08 11:48:26 +0000888 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
889 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000890 }
891#ifdef HAVE_IPV6
892 /* We have to think about a IPv6 link-local address curse. */
893 if (p->family == AF_INET6)
894 {
895 struct zapi_ipv6 api;
Paul Jakmafb982c22007-05-04 20:15:47 +0000896
Feng Luc99f3482014-10-16 09:52:36 +0800897 api.vrf_id = VRF_DEFAULT;
paul718e3742002-12-13 20:15:29 +0000898 api.flags = flags;
899 api.type = ZEBRA_ROUTE_BGP;
900 api.message = 0;
G.Balajic7ec1792011-11-26 22:04:05 +0400901 api.safi = safi;
Paul Jakma64e0ac22015-11-18 16:00:54 +0000902 api.nexthop_num = 0;
903 api.ifindex_num = 0;
paul718e3742002-12-13 20:15:29 +0000904 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
905 api.metric = info->attr->med;
906
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000907 if (BGP_DEBUG(zebra, ZEBRA))
908 {
909 char buf[2][INET6_ADDRSTRLEN];
Paul Jakma64e0ac22015-11-18 16:00:54 +0000910 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000911 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
912 p->prefixlen,
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000913 api.metric);
914 }
915
paul0a589352004-05-08 11:48:26 +0000916 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
917 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000918 }
919#endif /* HAVE_IPV6 */
920}
David Lamparter6b0655a2014-06-04 06:53:35 +0200921
paul718e3742002-12-13 20:15:29 +0000922/* Other routes redistribution into BGP. */
923int
924bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
925{
926 /* Set flag to BGP instance. */
927 bgp->redist[afi][type] = 1;
928
929 /* Return if already redistribute flag is set. */
Feng Luc99f3482014-10-16 09:52:36 +0800930 if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000931 return CMD_WARNING;
932
Feng Luc99f3482014-10-16 09:52:36 +0800933 vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000934
935 /* Return if zebra connection is not established. */
936 if (zclient->sock < 0)
937 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000938
939 if (BGP_DEBUG(zebra, ZEBRA))
940 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000941
942 /* Send distribute add message to zebra. */
Feng Luc99f3482014-10-16 09:52:36 +0800943 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000944
945 return CMD_SUCCESS;
946}
947
948/* Redistribute with route-map specification. */
949int
paulfd79ac92004-10-13 05:06:08 +0000950bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
951 const char *name)
paul718e3742002-12-13 20:15:29 +0000952{
953 if (bgp->rmap[afi][type].name
954 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
955 return 0;
956
957 if (bgp->rmap[afi][type].name)
958 free (bgp->rmap[afi][type].name);
959 bgp->rmap[afi][type].name = strdup (name);
960 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
961
962 return 1;
963}
964
965/* Redistribute with metric specification. */
966int
967bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
968 u_int32_t metric)
969{
970 if (bgp->redist_metric_flag[afi][type]
971 && bgp->redist_metric[afi][type] == metric)
972 return 0;
973
974 bgp->redist_metric_flag[afi][type] = 1;
975 bgp->redist_metric[afi][type] = metric;
976
977 return 1;
978}
979
980/* Unset redistribution. */
981int
982bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
983{
984 /* Unset flag from BGP instance. */
985 bgp->redist[afi][type] = 0;
986
987 /* Unset route-map. */
988 if (bgp->rmap[afi][type].name)
989 free (bgp->rmap[afi][type].name);
990 bgp->rmap[afi][type].name = NULL;
991 bgp->rmap[afi][type].map = NULL;
992
993 /* Unset metric. */
994 bgp->redist_metric_flag[afi][type] = 0;
995 bgp->redist_metric[afi][type] = 0;
996
997 /* Return if zebra connection is disabled. */
Feng Luc99f3482014-10-16 09:52:36 +0800998 if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
paul718e3742002-12-13 20:15:29 +0000999 return CMD_WARNING;
Feng Luc99f3482014-10-16 09:52:36 +08001000 vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);
paul718e3742002-12-13 20:15:29 +00001001
1002 if (bgp->redist[AFI_IP][type] == 0
1003 && bgp->redist[AFI_IP6][type] == 0
1004 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001005 {
1006 /* Send distribute delete message to zebra. */
1007 if (BGP_DEBUG(zebra, ZEBRA))
1008 zlog_debug("Zebra send: redistribute delete %s",
1009 zebra_route_string(type));
Feng Luc99f3482014-10-16 09:52:36 +08001010 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
1011 VRF_DEFAULT);
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001012 }
paul718e3742002-12-13 20:15:29 +00001013
1014 /* Withdraw redistributed routes from current BGP's routing table. */
1015 bgp_redistribute_withdraw (bgp, afi, type);
1016
1017 return CMD_SUCCESS;
1018}
1019
1020/* Unset redistribution route-map configuration. */
1021int
1022bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
1023{
1024 if (! bgp->rmap[afi][type].name)
1025 return 0;
1026
1027 /* Unset route-map. */
1028 free (bgp->rmap[afi][type].name);
1029 bgp->rmap[afi][type].name = NULL;
1030 bgp->rmap[afi][type].map = NULL;
1031
1032 return 1;
1033}
1034
1035/* Unset redistribution metric configuration. */
1036int
1037bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1038{
1039 if (! bgp->redist_metric_flag[afi][type])
1040 return 0;
1041
1042 /* Unset metric. */
1043 bgp->redist_metric_flag[afi][type] = 0;
1044 bgp->redist_metric[afi][type] = 0;
1045
1046 return 1;
1047}
David Lamparter6b0655a2014-06-04 06:53:35 +02001048
paul718e3742002-12-13 20:15:29 +00001049void
paul94f2b392005-06-28 12:44:16 +00001050bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001051{
1052 zclient_reset (zclient);
1053}
1054
Feng Luc99f3482014-10-16 09:52:36 +08001055static void
1056bgp_zebra_connected (struct zclient *zclient)
1057{
1058 zclient_send_requests (zclient, VRF_DEFAULT);
1059}
1060
paul718e3742002-12-13 20:15:29 +00001061void
Donald Sharp71252932015-09-24 09:25:19 -04001062bgp_zebra_init (struct thread_master *master)
paul718e3742002-12-13 20:15:29 +00001063{
1064 /* Set default values. */
Donald Sharp71252932015-09-24 09:25:19 -04001065 zclient = zclient_new (master);
paul718e3742002-12-13 20:15:29 +00001066 zclient_init (zclient, ZEBRA_ROUTE_BGP);
Feng Luc99f3482014-10-16 09:52:36 +08001067 zclient->zebra_connected = bgp_zebra_connected;
hasso18a6dce2004-10-03 18:18:34 +00001068 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001069 zclient->interface_add = bgp_interface_add;
1070 zclient->interface_delete = bgp_interface_delete;
1071 zclient->interface_address_add = bgp_interface_address_add;
1072 zclient->interface_address_delete = bgp_interface_address_delete;
1073 zclient->ipv4_route_add = zebra_read_ipv4;
1074 zclient->ipv4_route_delete = zebra_read_ipv4;
1075 zclient->interface_up = bgp_interface_up;
1076 zclient->interface_down = bgp_interface_down;
1077#ifdef HAVE_IPV6
1078 zclient->ipv6_route_add = zebra_read_ipv6;
1079 zclient->ipv6_route_delete = zebra_read_ipv6;
1080#endif /* HAVE_IPV6 */
1081
Josh Bailey8196f132011-07-20 20:47:07 -07001082 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001083}