blob: baf76fb052d84050d4faf53f0687ab0d3ae88fa1 [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"
paul718e3742002-12-13 20:15:29 +000040
41/* All information about zebra. */
Chris Caputo228da422009-07-18 05:44:03 +000042struct zclient *zclient = NULL;
hasso18a6dce2004-10-03 18:18:34 +000043struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000044
hasso18a6dce2004-10-03 18:18:34 +000045/* Router-id update message from zebra. */
paul94f2b392005-06-28 12:44:16 +000046static int
hasso18a6dce2004-10-03 18:18:34 +000047bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
paul718e3742002-12-13 20:15:29 +000048{
hasso18a6dce2004-10-03 18:18:34 +000049 struct prefix router_id;
paul1eb8ef22005-04-07 07:30:20 +000050 struct listnode *node, *nnode;
hasso18a6dce2004-10-03 18:18:34 +000051 struct bgp *bgp;
paul718e3742002-12-13 20:15:29 +000052
hasso18a6dce2004-10-03 18:18:34 +000053 zebra_router_id_update_read(zclient->ibuf,&router_id);
Andrew J. Schorra39275d2006-11-30 16:36:57 +000054
55 if (BGP_DEBUG(zebra, ZEBRA))
56 {
57 char buf[128];
58 prefix2str(&router_id, buf, sizeof(buf));
59 zlog_debug("Zebra rcvd: router id update %s", buf);
60 }
61
hasso18a6dce2004-10-03 18:18:34 +000062 router_id_zebra = router_id.u.prefix4;
63
paul1eb8ef22005-04-07 07:30:20 +000064 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
paul718e3742002-12-13 20:15:29 +000065 {
hasso18a6dce2004-10-03 18:18:34 +000066 if (!bgp->router_id_static.s_addr)
paul1eb8ef22005-04-07 07:30:20 +000067 bgp_router_id_set (bgp, &router_id.u.prefix4);
paul718e3742002-12-13 20:15:29 +000068 }
paul718e3742002-12-13 20:15:29 +000069
paul718e3742002-12-13 20:15:29 +000070 return 0;
71}
72
73/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000074static int
paul718e3742002-12-13 20:15:29 +000075bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
76{
77 struct interface *ifp;
78
79 ifp = zebra_interface_add_read (zclient->ibuf);
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,
89 zebra_size_t length)
90{
91 struct stream *s;
92 struct interface *ifp;
93
94 s = zclient->ibuf;
95 ifp = zebra_interface_state_read (s);
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
paul718e3742002-12-13 20:15:29 +0000105bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
106{
107 struct stream *s;
108 struct interface *ifp;
109 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000110 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000111
112 s = zclient->ibuf;
113 ifp = zebra_interface_state_read (s);
114
115 if (! ifp)
116 return 0;
117
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000118 if (BGP_DEBUG(zebra, ZEBRA))
119 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
120
paul1eb8ef22005-04-07 07:30:20 +0000121 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
122 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000123
124 return 0;
125}
126
paul94f2b392005-06-28 12:44:16 +0000127static int
paul718e3742002-12-13 20:15:29 +0000128bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
129{
130 struct stream *s;
131 struct interface *ifp;
132 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000133 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000134
135 s = zclient->ibuf;
136 ifp = zebra_interface_state_read (s);
137 if (! ifp)
138 return 0;
139
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000140 if (BGP_DEBUG(zebra, ZEBRA))
141 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
142
paul1eb8ef22005-04-07 07:30:20 +0000143 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
144 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000145
146 /* Fast external-failover (Currently IPv4 only) */
147 {
paul1eb8ef22005-04-07 07:30:20 +0000148 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000149 struct bgp *bgp;
150 struct peer *peer;
151 struct interface *peer_if;
152
paul1eb8ef22005-04-07 07:30:20 +0000153 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000154 {
155 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
156 continue;
157
paul1eb8ef22005-04-07 07:30:20 +0000158 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000159 {
160 if (peer->ttl != 1)
161 continue;
162
163 if (peer->su.sa.sa_family == AF_INET)
164 peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);
165 else
166 continue;
167
168 if (ifp == peer_if)
169 BGP_EVENT_ADD (peer, BGP_Stop);
170 }
171 }
172 }
173
174 return 0;
175}
176
paul94f2b392005-06-28 12:44:16 +0000177static int
paul718e3742002-12-13 20:15:29 +0000178bgp_interface_address_add (int command, struct zclient *zclient,
179 zebra_size_t length)
180{
181 struct connected *ifc;
182
paul0a589352004-05-08 11:48:26 +0000183 ifc = zebra_interface_address_read (command, zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000184
185 if (ifc == NULL)
186 return 0;
187
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000188 if (BGP_DEBUG(zebra, ZEBRA))
189 {
190 char buf[128];
191 prefix2str(ifc->address, buf, sizeof(buf));
192 zlog_debug("Zebra rcvd: interface %s address add %s",
193 ifc->ifp->name, buf);
194 }
195
paul2e3b2e42002-12-13 21:03:13 +0000196 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000197 bgp_connected_add (ifc);
198
199 return 0;
200}
201
paul94f2b392005-06-28 12:44:16 +0000202static int
paul718e3742002-12-13 20:15:29 +0000203bgp_interface_address_delete (int command, struct zclient *zclient,
204 zebra_size_t length)
205{
206 struct connected *ifc;
207
paul0a589352004-05-08 11:48:26 +0000208 ifc = zebra_interface_address_read (command, zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000209
210 if (ifc == NULL)
211 return 0;
212
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000213 if (BGP_DEBUG(zebra, ZEBRA))
214 {
215 char buf[128];
216 prefix2str(ifc->address, buf, sizeof(buf));
217 zlog_debug("Zebra rcvd: interface %s address delete %s",
218 ifc->ifp->name, buf);
219 }
220
paul2e3b2e42002-12-13 21:03:13 +0000221 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000222 bgp_connected_delete (ifc);
223
224 connected_free (ifc);
225
226 return 0;
227}
228
229/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000230static int
paul718e3742002-12-13 20:15:29 +0000231zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
232{
233 struct stream *s;
234 struct zapi_ipv4 api;
paul718e3742002-12-13 20:15:29 +0000235 struct in_addr nexthop;
236 struct prefix_ipv4 p;
237
238 s = zclient->ibuf;
paul718e3742002-12-13 20:15:29 +0000239 nexthop.s_addr = 0;
240
241 /* Type, flags, message. */
242 api.type = stream_getc (s);
243 api.flags = stream_getc (s);
244 api.message = stream_getc (s);
245
246 /* IPv4 prefix. */
247 memset (&p, 0, sizeof (struct prefix_ipv4));
248 p.family = AF_INET;
249 p.prefixlen = stream_getc (s);
250 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
251
252 /* Nexthop, ifindex, distance, metric. */
253 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
254 {
255 api.nexthop_num = stream_getc (s);
256 nexthop.s_addr = stream_get_ipv4 (s);
257 }
258 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
259 {
260 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400261 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000262 }
263 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
264 api.distance = stream_getc (s);
265 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
266 api.metric = stream_getl (s);
267 else
268 api.metric = 0;
269
270 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000271 {
272 if (BGP_DEBUG(zebra, ZEBRA))
273 {
274 char buf[2][INET_ADDRSTRLEN];
275 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
276 zebra_route_string(api.type),
277 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
278 p.prefixlen,
279 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
280 api.metric);
281 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400282 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
283 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000284 }
paul718e3742002-12-13 20:15:29 +0000285 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000286 {
287 if (BGP_DEBUG(zebra, ZEBRA))
288 {
289 char buf[2][INET_ADDRSTRLEN];
290 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
291 "nexthop %s metric %u",
292 zebra_route_string(api.type),
293 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
294 p.prefixlen,
295 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
296 api.metric);
297 }
298 bgp_redistribute_delete((struct prefix *)&p, api.type);
299 }
paul718e3742002-12-13 20:15:29 +0000300
301 return 0;
302}
303
304#ifdef HAVE_IPV6
305/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000306static int
paul718e3742002-12-13 20:15:29 +0000307zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
308{
309 struct stream *s;
310 struct zapi_ipv6 api;
paul718e3742002-12-13 20:15:29 +0000311 struct in6_addr nexthop;
312 struct prefix_ipv6 p;
313
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;
325 p.prefixlen = stream_getc (s);
326 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
327
328 /* Nexthop, ifindex, distance, metric. */
329 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
330 {
331 api.nexthop_num = stream_getc (s);
332 stream_get (&nexthop, s, 16);
333 }
334 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
335 {
336 api.ifindex_num = stream_getc (s);
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400337 stream_getl (s); /* ifindex, unused */
paul718e3742002-12-13 20:15:29 +0000338 }
339 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
340 api.distance = stream_getc (s);
341 else
342 api.distance = 0;
343 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
344 api.metric = stream_getl (s);
345 else
346 api.metric = 0;
347
348 /* Simply ignore link-local address. */
349 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
350 return 0;
351
352 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000353 {
354 if (BGP_DEBUG(zebra, ZEBRA))
355 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400356 char buf[2][INET6_ADDRSTRLEN];
357 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000358 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400359 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
360 p.prefixlen,
361 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
362 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000363 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400364 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
365 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000366 }
paul718e3742002-12-13 20:15:29 +0000367 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000368 {
369 if (BGP_DEBUG(zebra, ZEBRA))
370 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400371 char buf[2][INET6_ADDRSTRLEN];
372 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
373 "nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000374 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400375 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
376 p.prefixlen,
377 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
378 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000379 }
380 bgp_redistribute_delete ((struct prefix *) &p, api.type);
381 }
paul718e3742002-12-13 20:15:29 +0000382
383 return 0;
384}
385#endif /* HAVE_IPV6 */
386
387struct 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
438#ifdef HAVE_IPV6
439struct interface *
440if_lookup_by_ipv6 (struct in6_addr *addr)
441{
hasso52dc7ee2004-09-23 19:18:23 +0000442 struct listnode *ifnode;
443 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000444 struct interface *ifp;
445 struct connected *connected;
446 struct prefix_ipv6 p;
447 struct prefix *cp;
448
449 p.family = AF_INET6;
450 p.prefix = *addr;
451 p.prefixlen = IPV6_MAX_BITLEN;
452
paul1eb8ef22005-04-07 07:30:20 +0000453 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000454 {
paul1eb8ef22005-04-07 07:30:20 +0000455 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000456 {
paul718e3742002-12-13 20:15:29 +0000457 cp = connected->address;
458
459 if (cp->family == AF_INET6)
460 if (prefix_match (cp, (struct prefix *)&p))
461 return ifp;
462 }
463 }
464 return NULL;
465}
466
467struct interface *
468if_lookup_by_ipv6_exact (struct in6_addr *addr)
469{
hasso52dc7ee2004-09-23 19:18:23 +0000470 struct listnode *ifnode;
471 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000472 struct interface *ifp;
473 struct connected *connected;
474 struct prefix *cp;
475
paul1eb8ef22005-04-07 07:30:20 +0000476 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000477 {
paul1eb8ef22005-04-07 07:30:20 +0000478 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000479 {
paul718e3742002-12-13 20:15:29 +0000480 cp = connected->address;
481
482 if (cp->family == AF_INET6)
483 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
484 return ifp;
485 }
486 }
487 return NULL;
488}
489
paul94f2b392005-06-28 12:44:16 +0000490static int
paul718e3742002-12-13 20:15:29 +0000491if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
492{
hasso52dc7ee2004-09-23 19:18:23 +0000493 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000494 struct connected *connected;
495 struct prefix *cp;
496
paul1eb8ef22005-04-07 07:30:20 +0000497 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000498 {
paul718e3742002-12-13 20:15:29 +0000499 cp = connected->address;
500
501 if (cp->family == AF_INET6)
502 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
503 {
504 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
505 return 1;
506 }
507 }
508 return 0;
509}
510
paul94f2b392005-06-28 12:44:16 +0000511static int
paul718e3742002-12-13 20:15:29 +0000512if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
513{
hasso52dc7ee2004-09-23 19:18:23 +0000514 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000515 struct connected *connected;
516 struct prefix *cp;
517
paul1eb8ef22005-04-07 07:30:20 +0000518 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000519 {
paul718e3742002-12-13 20:15:29 +0000520 cp = connected->address;
521
522 if (cp->family == AF_INET6)
523 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
524 {
525 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
526 return 1;
527 }
528 }
529 return 0;
530}
531#endif /* HAVE_IPV6 */
532
533int
534bgp_nexthop_set (union sockunion *local, union sockunion *remote,
535 struct bgp_nexthop *nexthop, struct peer *peer)
536{
537 int ret = 0;
538 struct interface *ifp = NULL;
539
540 memset (nexthop, 0, sizeof (struct bgp_nexthop));
541
542 if (!local)
543 return -1;
544 if (!remote)
545 return -1;
546
547 if (local->sa.sa_family == AF_INET)
548 {
549 nexthop->v4 = local->sin.sin_addr;
550 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
551 }
552#ifdef HAVE_IPV6
553 if (local->sa.sa_family == AF_INET6)
554 {
555 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
556 {
557 if (peer->ifname)
558 ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
559 }
560 else
561 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
562 }
563#endif /* HAVE_IPV6 */
564
565 if (!ifp)
566 return -1;
567
568 nexthop->ifp = ifp;
569
570 /* IPv4 connection. */
571 if (local->sa.sa_family == AF_INET)
572 {
573#ifdef HAVE_IPV6
574 /* IPv6 nexthop*/
575 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
576
577 /* There is no global nexthop. */
578 if (!ret)
579 if_get_ipv6_local (ifp, &nexthop->v6_global);
580 else
581 if_get_ipv6_local (ifp, &nexthop->v6_local);
582#endif /* HAVE_IPV6 */
583 }
584
585#ifdef HAVE_IPV6
586 /* IPv6 connection. */
587 if (local->sa.sa_family == AF_INET6)
588 {
589 struct interface *direct = NULL;
590
591 /* IPv4 nexthop. I don't care about it. */
592 if (peer->local_id.s_addr)
593 nexthop->v4 = peer->local_id;
594
595 /* Global address*/
596 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
597 {
598 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
599 IPV6_MAX_BYTELEN);
600
601 /* If directory connected set link-local address. */
602 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
603 if (direct)
604 if_get_ipv6_local (ifp, &nexthop->v6_local);
605 }
606 else
607 /* Link-local address. */
608 {
609 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
610
611 /* If there is no global address. Set link-local address as
612 global. I know this break RFC specification... */
613 if (!ret)
614 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
615 IPV6_MAX_BYTELEN);
616 else
617 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
618 IPV6_MAX_BYTELEN);
619 }
620 }
621
622 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
623 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
624 peer->shared_network = 1;
625 else
626 peer->shared_network = 0;
627
628 /* KAME stack specific treatment. */
629#ifdef KAME
630 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
631 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
632 {
633 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
634 }
635 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
636 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
637 {
638 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
639 }
640#endif /* KAME */
641#endif /* HAVE_IPV6 */
642 return ret;
643}
644
paul718e3742002-12-13 20:15:29 +0000645void
G.Balaji5a616c02011-11-26 21:58:42 +0400646bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000647{
648 int flags;
649 u_char distance;
650 struct peer *peer;
651
652 if (zclient->sock < 0)
653 return;
654
655 if (! zclient->redist[ZEBRA_ROUTE_BGP])
656 return;
657
658 flags = 0;
659 peer = info->peer;
660
661 if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
662 {
663 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
664 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
665 }
666
667 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000668 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000669 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
670
671 if (p->family == AF_INET)
672 {
673 struct zapi_ipv4 api;
674 struct in_addr *nexthop;
675
676 api.flags = flags;
677 nexthop = &info->attr->nexthop;
678
679 api.type = ZEBRA_ROUTE_BGP;
680 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400681 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000682 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
683 api.nexthop_num = 1;
684 api.nexthop = &nexthop;
685 api.ifindex_num = 0;
686 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
687 api.metric = info->attr->med;
688
689 distance = bgp_distance_apply (p, info, bgp);
690
691 if (distance)
692 {
693 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
694 api.distance = distance;
695 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000696
697 if (BGP_DEBUG(zebra, ZEBRA))
698 {
699 char buf[2][INET_ADDRSTRLEN];
700 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u",
701 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
702 p->prefixlen,
703 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
704 api.metric);
705 }
706
paul0a589352004-05-08 11:48:26 +0000707 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
708 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000709 }
710#ifdef HAVE_IPV6
711 /* We have to think about a IPv6 link-local address curse. */
712 if (p->family == AF_INET6)
713 {
714 unsigned int ifindex;
715 struct in6_addr *nexthop;
716 struct zapi_ipv6 api;
717
718 ifindex = 0;
719 nexthop = NULL;
Paul Jakmafb982c22007-05-04 20:15:47 +0000720
721 assert (info->attr->extra);
722
paul718e3742002-12-13 20:15:29 +0000723 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000724 if (info->attr->extra->mp_nexthop_len == 16)
725 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000726
727 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000728 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000729 {
730 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000731 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000732 && peer->su_remote->sa.sa_family == AF_INET6)
733 nexthop = &peer->su_remote->sin6.sin6_addr;
734 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000735 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000736
737 if (info->peer->nexthop.ifp)
738 ifindex = info->peer->nexthop.ifp->ifindex;
739 }
740
741 if (nexthop == NULL)
742 return;
743
744 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
745 {
746 if (info->peer->ifname)
747 ifindex = if_nametoindex (info->peer->ifname);
748 else if (info->peer->nexthop.ifp)
749 ifindex = info->peer->nexthop.ifp->ifindex;
750 }
751
752 /* Make Zebra API structure. */
753 api.flags = flags;
754 api.type = ZEBRA_ROUTE_BGP;
755 api.message = 0;
756 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
757 api.nexthop_num = 1;
758 api.nexthop = &nexthop;
759 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
760 api.ifindex_num = 1;
761 api.ifindex = &ifindex;
762 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
763 api.metric = info->attr->med;
764
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000765 if (BGP_DEBUG(zebra, ZEBRA))
766 {
767 char buf[2][INET6_ADDRSTRLEN];
768 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
769 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
770 p->prefixlen,
771 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
772 api.metric);
773 }
774
paul0a589352004-05-08 11:48:26 +0000775 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
776 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000777 }
778#endif /* HAVE_IPV6 */
779}
780
781void
G.Balaji5a616c02011-11-26 21:58:42 +0400782bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
paul718e3742002-12-13 20:15:29 +0000783{
784 int flags;
785 struct peer *peer;
786
787 if (zclient->sock < 0)
788 return;
789
790 if (! zclient->redist[ZEBRA_ROUTE_BGP])
791 return;
792
793 peer = info->peer;
794 flags = 0;
795
796 if (peer_sort (peer) == BGP_PEER_IBGP)
797 {
798 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
799 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
800 }
801
802 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000803 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000804 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
805
806 if (p->family == AF_INET)
807 {
808 struct zapi_ipv4 api;
809 struct in_addr *nexthop;
810
811 api.flags = flags;
812 nexthop = &info->attr->nexthop;
813
814 api.type = ZEBRA_ROUTE_BGP;
815 api.message = 0;
G.Balaji5a616c02011-11-26 21:58:42 +0400816 api.safi = safi;
paul718e3742002-12-13 20:15:29 +0000817 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
818 api.nexthop_num = 1;
819 api.nexthop = &nexthop;
820 api.ifindex_num = 0;
821 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
822 api.metric = info->attr->med;
823
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000824 if (BGP_DEBUG(zebra, ZEBRA))
825 {
826 char buf[2][INET_ADDRSTRLEN];
827 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
828 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
829 p->prefixlen,
830 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
831 api.metric);
832 }
833
paul0a589352004-05-08 11:48:26 +0000834 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
835 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000836 }
837#ifdef HAVE_IPV6
838 /* We have to think about a IPv6 link-local address curse. */
839 if (p->family == AF_INET6)
840 {
841 struct zapi_ipv6 api;
842 unsigned int ifindex;
843 struct in6_addr *nexthop;
Paul Jakmafb982c22007-05-04 20:15:47 +0000844
845 assert (info->attr->extra);
846
paul718e3742002-12-13 20:15:29 +0000847 ifindex = 0;
848 nexthop = NULL;
849
850 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000851 if (info->attr->extra->mp_nexthop_len == 16)
852 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000853
854 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000855 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000856 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000857 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000858 if (info->peer->nexthop.ifp)
859 ifindex = info->peer->nexthop.ifp->ifindex;
860 }
861
862 if (nexthop == NULL)
863 return;
864
865 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
866 if (info->peer->ifname)
867 ifindex = if_nametoindex (info->peer->ifname);
868
869 api.flags = flags;
870 api.type = ZEBRA_ROUTE_BGP;
871 api.message = 0;
872 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
873 api.nexthop_num = 1;
874 api.nexthop = &nexthop;
875 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
876 api.ifindex_num = 1;
877 api.ifindex = &ifindex;
878 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
879 api.metric = info->attr->med;
880
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000881 if (BGP_DEBUG(zebra, ZEBRA))
882 {
883 char buf[2][INET6_ADDRSTRLEN];
884 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
885 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
886 p->prefixlen,
887 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
888 api.metric);
889 }
890
paul0a589352004-05-08 11:48:26 +0000891 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
892 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000893 }
894#endif /* HAVE_IPV6 */
895}
896
897/* Other routes redistribution into BGP. */
898int
899bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
900{
901 /* Set flag to BGP instance. */
902 bgp->redist[afi][type] = 1;
903
904 /* Return if already redistribute flag is set. */
905 if (zclient->redist[type])
906 return CMD_WARNING;
907
908 zclient->redist[type] = 1;
909
910 /* Return if zebra connection is not established. */
911 if (zclient->sock < 0)
912 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000913
914 if (BGP_DEBUG(zebra, ZEBRA))
915 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000916
917 /* Send distribute add message to zebra. */
ajs634f9ea2005-04-11 15:51:40 +0000918 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
paul718e3742002-12-13 20:15:29 +0000919
920 return CMD_SUCCESS;
921}
922
923/* Redistribute with route-map specification. */
924int
paulfd79ac92004-10-13 05:06:08 +0000925bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
926 const char *name)
paul718e3742002-12-13 20:15:29 +0000927{
928 if (bgp->rmap[afi][type].name
929 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
930 return 0;
931
932 if (bgp->rmap[afi][type].name)
933 free (bgp->rmap[afi][type].name);
934 bgp->rmap[afi][type].name = strdup (name);
935 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
936
937 return 1;
938}
939
940/* Redistribute with metric specification. */
941int
942bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
943 u_int32_t metric)
944{
945 if (bgp->redist_metric_flag[afi][type]
946 && bgp->redist_metric[afi][type] == metric)
947 return 0;
948
949 bgp->redist_metric_flag[afi][type] = 1;
950 bgp->redist_metric[afi][type] = metric;
951
952 return 1;
953}
954
955/* Unset redistribution. */
956int
957bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
958{
959 /* Unset flag from BGP instance. */
960 bgp->redist[afi][type] = 0;
961
962 /* Unset route-map. */
963 if (bgp->rmap[afi][type].name)
964 free (bgp->rmap[afi][type].name);
965 bgp->rmap[afi][type].name = NULL;
966 bgp->rmap[afi][type].map = NULL;
967
968 /* Unset metric. */
969 bgp->redist_metric_flag[afi][type] = 0;
970 bgp->redist_metric[afi][type] = 0;
971
972 /* Return if zebra connection is disabled. */
973 if (! zclient->redist[type])
974 return CMD_WARNING;
975 zclient->redist[type] = 0;
976
977 if (bgp->redist[AFI_IP][type] == 0
978 && bgp->redist[AFI_IP6][type] == 0
979 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000980 {
981 /* Send distribute delete message to zebra. */
982 if (BGP_DEBUG(zebra, ZEBRA))
983 zlog_debug("Zebra send: redistribute delete %s",
984 zebra_route_string(type));
985 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
986 }
paul718e3742002-12-13 20:15:29 +0000987
988 /* Withdraw redistributed routes from current BGP's routing table. */
989 bgp_redistribute_withdraw (bgp, afi, type);
990
991 return CMD_SUCCESS;
992}
993
994/* Unset redistribution route-map configuration. */
995int
996bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
997{
998 if (! bgp->rmap[afi][type].name)
999 return 0;
1000
1001 /* Unset route-map. */
1002 free (bgp->rmap[afi][type].name);
1003 bgp->rmap[afi][type].name = NULL;
1004 bgp->rmap[afi][type].map = NULL;
1005
1006 return 1;
1007}
1008
1009/* Unset redistribution metric configuration. */
1010int
1011bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1012{
1013 if (! bgp->redist_metric_flag[afi][type])
1014 return 0;
1015
1016 /* Unset metric. */
1017 bgp->redist_metric_flag[afi][type] = 0;
1018 bgp->redist_metric[afi][type] = 0;
1019
1020 return 1;
1021}
1022
1023void
paul94f2b392005-06-28 12:44:16 +00001024bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001025{
1026 zclient_reset (zclient);
1027}
1028
1029void
paul94f2b392005-06-28 12:44:16 +00001030bgp_zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001031{
1032 /* Set default values. */
1033 zclient = zclient_new ();
1034 zclient_init (zclient, ZEBRA_ROUTE_BGP);
hasso18a6dce2004-10-03 18:18:34 +00001035 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001036 zclient->interface_add = bgp_interface_add;
1037 zclient->interface_delete = bgp_interface_delete;
1038 zclient->interface_address_add = bgp_interface_address_add;
1039 zclient->interface_address_delete = bgp_interface_address_delete;
1040 zclient->ipv4_route_add = zebra_read_ipv4;
1041 zclient->ipv4_route_delete = zebra_read_ipv4;
1042 zclient->interface_up = bgp_interface_up;
1043 zclient->interface_down = bgp_interface_down;
1044#ifdef HAVE_IPV6
1045 zclient->ipv6_route_add = zebra_read_ipv6;
1046 zclient->ipv6_route_delete = zebra_read_ipv6;
1047#endif /* HAVE_IPV6 */
1048
1049 /* Interface related init. */
1050 if_init ();
1051}