blob: d7af349aacc804c3b01367ee3d29e247c67f6451 [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;
235 unsigned long ifindex;
236 struct in_addr nexthop;
237 struct prefix_ipv4 p;
238
239 s = zclient->ibuf;
240 ifindex = 0;
241 nexthop.s_addr = 0;
242
243 /* Type, flags, message. */
244 api.type = stream_getc (s);
245 api.flags = stream_getc (s);
246 api.message = stream_getc (s);
247
248 /* IPv4 prefix. */
249 memset (&p, 0, sizeof (struct prefix_ipv4));
250 p.family = AF_INET;
251 p.prefixlen = stream_getc (s);
252 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
253
254 /* Nexthop, ifindex, distance, metric. */
255 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
256 {
257 api.nexthop_num = stream_getc (s);
258 nexthop.s_addr = stream_get_ipv4 (s);
259 }
260 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
261 {
262 api.ifindex_num = stream_getc (s);
263 ifindex = stream_getl (s);
264 }
265 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
266 api.distance = stream_getc (s);
267 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
268 api.metric = stream_getl (s);
269 else
270 api.metric = 0;
271
272 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000273 {
274 if (BGP_DEBUG(zebra, ZEBRA))
275 {
276 char buf[2][INET_ADDRSTRLEN];
277 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
278 zebra_route_string(api.type),
279 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
280 p.prefixlen,
281 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
282 api.metric);
283 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400284 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
285 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000286 }
paul718e3742002-12-13 20:15:29 +0000287 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000288 {
289 if (BGP_DEBUG(zebra, ZEBRA))
290 {
291 char buf[2][INET_ADDRSTRLEN];
292 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
293 "nexthop %s metric %u",
294 zebra_route_string(api.type),
295 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
296 p.prefixlen,
297 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
298 api.metric);
299 }
300 bgp_redistribute_delete((struct prefix *)&p, api.type);
301 }
paul718e3742002-12-13 20:15:29 +0000302
303 return 0;
304}
305
306#ifdef HAVE_IPV6
307/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000308static int
paul718e3742002-12-13 20:15:29 +0000309zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
310{
311 struct stream *s;
312 struct zapi_ipv6 api;
313 unsigned long ifindex;
314 struct in6_addr nexthop;
315 struct prefix_ipv6 p;
316
317 s = zclient->ibuf;
318 ifindex = 0;
319 memset (&nexthop, 0, sizeof (struct in6_addr));
320
321 /* Type, flags, message. */
322 api.type = stream_getc (s);
323 api.flags = stream_getc (s);
324 api.message = stream_getc (s);
325
326 /* IPv6 prefix. */
327 memset (&p, 0, sizeof (struct prefix_ipv6));
328 p.family = AF_INET6;
329 p.prefixlen = stream_getc (s);
330 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
331
332 /* Nexthop, ifindex, distance, metric. */
333 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
334 {
335 api.nexthop_num = stream_getc (s);
336 stream_get (&nexthop, s, 16);
337 }
338 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
339 {
340 api.ifindex_num = stream_getc (s);
341 ifindex = stream_getl (s);
342 }
343 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
344 api.distance = stream_getc (s);
345 else
346 api.distance = 0;
347 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
348 api.metric = stream_getl (s);
349 else
350 api.metric = 0;
351
352 /* Simply ignore link-local address. */
353 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
354 return 0;
355
356 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000357 {
358 if (BGP_DEBUG(zebra, ZEBRA))
359 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400360 char buf[2][INET6_ADDRSTRLEN];
361 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000362 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400363 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
364 p.prefixlen,
365 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
366 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000367 }
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400368 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
369 api.metric, api.type);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000370 }
paul718e3742002-12-13 20:15:29 +0000371 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000372 {
373 if (BGP_DEBUG(zebra, ZEBRA))
374 {
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400375 char buf[2][INET6_ADDRSTRLEN];
376 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
377 "nexthop %s metric %u",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000378 zebra_route_string(api.type),
Stephen Hemmingerf04a80a2011-12-06 14:51:10 +0400379 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
380 p.prefixlen,
381 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
382 api.metric);
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000383 }
384 bgp_redistribute_delete ((struct prefix *) &p, api.type);
385 }
paul718e3742002-12-13 20:15:29 +0000386
387 return 0;
388}
389#endif /* HAVE_IPV6 */
390
391struct interface *
392if_lookup_by_ipv4 (struct in_addr *addr)
393{
hasso52dc7ee2004-09-23 19:18:23 +0000394 struct listnode *ifnode;
395 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000396 struct interface *ifp;
397 struct connected *connected;
398 struct prefix_ipv4 p;
399 struct prefix *cp;
400
401 p.family = AF_INET;
402 p.prefix = *addr;
403 p.prefixlen = IPV4_MAX_BITLEN;
404
paul1eb8ef22005-04-07 07:30:20 +0000405 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000406 {
paul1eb8ef22005-04-07 07:30:20 +0000407 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000408 {
paul718e3742002-12-13 20:15:29 +0000409 cp = connected->address;
410
411 if (cp->family == AF_INET)
412 if (prefix_match (cp, (struct prefix *)&p))
413 return ifp;
414 }
415 }
416 return NULL;
417}
418
419struct interface *
420if_lookup_by_ipv4_exact (struct in_addr *addr)
421{
hasso52dc7ee2004-09-23 19:18:23 +0000422 struct listnode *ifnode;
423 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000424 struct interface *ifp;
425 struct connected *connected;
426 struct prefix *cp;
427
paul1eb8ef22005-04-07 07:30:20 +0000428 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000429 {
paul1eb8ef22005-04-07 07:30:20 +0000430 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000431 {
paul718e3742002-12-13 20:15:29 +0000432 cp = connected->address;
433
434 if (cp->family == AF_INET)
435 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
436 return ifp;
437 }
438 }
439 return NULL;
440}
441
442#ifdef HAVE_IPV6
443struct interface *
444if_lookup_by_ipv6 (struct in6_addr *addr)
445{
hasso52dc7ee2004-09-23 19:18:23 +0000446 struct listnode *ifnode;
447 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000448 struct interface *ifp;
449 struct connected *connected;
450 struct prefix_ipv6 p;
451 struct prefix *cp;
452
453 p.family = AF_INET6;
454 p.prefix = *addr;
455 p.prefixlen = IPV6_MAX_BITLEN;
456
paul1eb8ef22005-04-07 07:30:20 +0000457 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000458 {
paul1eb8ef22005-04-07 07:30:20 +0000459 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000460 {
paul718e3742002-12-13 20:15:29 +0000461 cp = connected->address;
462
463 if (cp->family == AF_INET6)
464 if (prefix_match (cp, (struct prefix *)&p))
465 return ifp;
466 }
467 }
468 return NULL;
469}
470
471struct interface *
472if_lookup_by_ipv6_exact (struct in6_addr *addr)
473{
hasso52dc7ee2004-09-23 19:18:23 +0000474 struct listnode *ifnode;
475 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000476 struct interface *ifp;
477 struct connected *connected;
478 struct prefix *cp;
479
paul1eb8ef22005-04-07 07:30:20 +0000480 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000481 {
paul1eb8ef22005-04-07 07:30:20 +0000482 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000483 {
paul718e3742002-12-13 20:15:29 +0000484 cp = connected->address;
485
486 if (cp->family == AF_INET6)
487 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
488 return ifp;
489 }
490 }
491 return NULL;
492}
493
paul94f2b392005-06-28 12:44:16 +0000494static int
paul718e3742002-12-13 20:15:29 +0000495if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
496{
hasso52dc7ee2004-09-23 19:18:23 +0000497 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000498 struct connected *connected;
499 struct prefix *cp;
500
paul1eb8ef22005-04-07 07:30:20 +0000501 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000502 {
paul718e3742002-12-13 20:15:29 +0000503 cp = connected->address;
504
505 if (cp->family == AF_INET6)
506 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
507 {
508 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
509 return 1;
510 }
511 }
512 return 0;
513}
514
paul94f2b392005-06-28 12:44:16 +0000515static int
paul718e3742002-12-13 20:15:29 +0000516if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
517{
hasso52dc7ee2004-09-23 19:18:23 +0000518 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000519 struct connected *connected;
520 struct prefix *cp;
521
paul1eb8ef22005-04-07 07:30:20 +0000522 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000523 {
paul718e3742002-12-13 20:15:29 +0000524 cp = connected->address;
525
526 if (cp->family == AF_INET6)
527 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
528 {
529 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
530 return 1;
531 }
532 }
533 return 0;
534}
535#endif /* HAVE_IPV6 */
536
537int
538bgp_nexthop_set (union sockunion *local, union sockunion *remote,
539 struct bgp_nexthop *nexthop, struct peer *peer)
540{
541 int ret = 0;
542 struct interface *ifp = NULL;
543
544 memset (nexthop, 0, sizeof (struct bgp_nexthop));
545
546 if (!local)
547 return -1;
548 if (!remote)
549 return -1;
550
551 if (local->sa.sa_family == AF_INET)
552 {
553 nexthop->v4 = local->sin.sin_addr;
554 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
555 }
556#ifdef HAVE_IPV6
557 if (local->sa.sa_family == AF_INET6)
558 {
559 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
560 {
561 if (peer->ifname)
562 ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
563 }
564 else
565 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
566 }
567#endif /* HAVE_IPV6 */
568
569 if (!ifp)
570 return -1;
571
572 nexthop->ifp = ifp;
573
574 /* IPv4 connection. */
575 if (local->sa.sa_family == AF_INET)
576 {
577#ifdef HAVE_IPV6
578 /* IPv6 nexthop*/
579 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
580
581 /* There is no global nexthop. */
582 if (!ret)
583 if_get_ipv6_local (ifp, &nexthop->v6_global);
584 else
585 if_get_ipv6_local (ifp, &nexthop->v6_local);
586#endif /* HAVE_IPV6 */
587 }
588
589#ifdef HAVE_IPV6
590 /* IPv6 connection. */
591 if (local->sa.sa_family == AF_INET6)
592 {
593 struct interface *direct = NULL;
594
595 /* IPv4 nexthop. I don't care about it. */
596 if (peer->local_id.s_addr)
597 nexthop->v4 = peer->local_id;
598
599 /* Global address*/
600 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
601 {
602 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
603 IPV6_MAX_BYTELEN);
604
605 /* If directory connected set link-local address. */
606 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
607 if (direct)
608 if_get_ipv6_local (ifp, &nexthop->v6_local);
609 }
610 else
611 /* Link-local address. */
612 {
613 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
614
615 /* If there is no global address. Set link-local address as
616 global. I know this break RFC specification... */
617 if (!ret)
618 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
619 IPV6_MAX_BYTELEN);
620 else
621 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
622 IPV6_MAX_BYTELEN);
623 }
624 }
625
626 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
627 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
628 peer->shared_network = 1;
629 else
630 peer->shared_network = 0;
631
632 /* KAME stack specific treatment. */
633#ifdef KAME
634 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
635 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
636 {
637 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
638 }
639 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
640 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
641 {
642 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
643 }
644#endif /* KAME */
645#endif /* HAVE_IPV6 */
646 return ret;
647}
648
paul718e3742002-12-13 20:15:29 +0000649void
650bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp)
651{
652 int flags;
653 u_char distance;
654 struct peer *peer;
655
656 if (zclient->sock < 0)
657 return;
658
659 if (! zclient->redist[ZEBRA_ROUTE_BGP])
660 return;
661
662 flags = 0;
663 peer = info->peer;
664
665 if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
666 {
667 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
668 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
669 }
670
671 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000672 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000673 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
674
675 if (p->family == AF_INET)
676 {
677 struct zapi_ipv4 api;
678 struct in_addr *nexthop;
679
680 api.flags = flags;
681 nexthop = &info->attr->nexthop;
682
683 api.type = ZEBRA_ROUTE_BGP;
684 api.message = 0;
685 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
686 api.nexthop_num = 1;
687 api.nexthop = &nexthop;
688 api.ifindex_num = 0;
689 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
690 api.metric = info->attr->med;
691
692 distance = bgp_distance_apply (p, info, bgp);
693
694 if (distance)
695 {
696 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
697 api.distance = distance;
698 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000699
700 if (BGP_DEBUG(zebra, ZEBRA))
701 {
702 char buf[2][INET_ADDRSTRLEN];
703 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u",
704 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
705 p->prefixlen,
706 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
707 api.metric);
708 }
709
paul0a589352004-05-08 11:48:26 +0000710 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
711 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000712 }
713#ifdef HAVE_IPV6
714 /* We have to think about a IPv6 link-local address curse. */
715 if (p->family == AF_INET6)
716 {
717 unsigned int ifindex;
718 struct in6_addr *nexthop;
719 struct zapi_ipv6 api;
720
721 ifindex = 0;
722 nexthop = NULL;
Paul Jakmafb982c22007-05-04 20:15:47 +0000723
724 assert (info->attr->extra);
725
paul718e3742002-12-13 20:15:29 +0000726 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000727 if (info->attr->extra->mp_nexthop_len == 16)
728 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000729
730 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000731 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000732 {
733 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000734 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000735 && peer->su_remote->sa.sa_family == AF_INET6)
736 nexthop = &peer->su_remote->sin6.sin6_addr;
737 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000738 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000739
740 if (info->peer->nexthop.ifp)
741 ifindex = info->peer->nexthop.ifp->ifindex;
742 }
743
744 if (nexthop == NULL)
745 return;
746
747 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
748 {
749 if (info->peer->ifname)
750 ifindex = if_nametoindex (info->peer->ifname);
751 else if (info->peer->nexthop.ifp)
752 ifindex = info->peer->nexthop.ifp->ifindex;
753 }
754
755 /* Make Zebra API structure. */
756 api.flags = flags;
757 api.type = ZEBRA_ROUTE_BGP;
758 api.message = 0;
759 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
760 api.nexthop_num = 1;
761 api.nexthop = &nexthop;
762 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
763 api.ifindex_num = 1;
764 api.ifindex = &ifindex;
765 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
766 api.metric = info->attr->med;
767
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000768 if (BGP_DEBUG(zebra, ZEBRA))
769 {
770 char buf[2][INET6_ADDRSTRLEN];
771 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
772 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
773 p->prefixlen,
774 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
775 api.metric);
776 }
777
paul0a589352004-05-08 11:48:26 +0000778 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
779 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000780 }
781#endif /* HAVE_IPV6 */
782}
783
784void
785bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info)
786{
787 int flags;
788 struct peer *peer;
789
790 if (zclient->sock < 0)
791 return;
792
793 if (! zclient->redist[ZEBRA_ROUTE_BGP])
794 return;
795
796 peer = info->peer;
797 flags = 0;
798
799 if (peer_sort (peer) == BGP_PEER_IBGP)
800 {
801 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
802 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
803 }
804
805 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000806 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000807 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
808
809 if (p->family == AF_INET)
810 {
811 struct zapi_ipv4 api;
812 struct in_addr *nexthop;
813
814 api.flags = flags;
815 nexthop = &info->attr->nexthop;
816
817 api.type = ZEBRA_ROUTE_BGP;
818 api.message = 0;
819 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
820 api.nexthop_num = 1;
821 api.nexthop = &nexthop;
822 api.ifindex_num = 0;
823 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
824 api.metric = info->attr->med;
825
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000826 if (BGP_DEBUG(zebra, ZEBRA))
827 {
828 char buf[2][INET_ADDRSTRLEN];
829 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
830 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
831 p->prefixlen,
832 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
833 api.metric);
834 }
835
paul0a589352004-05-08 11:48:26 +0000836 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
837 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000838 }
839#ifdef HAVE_IPV6
840 /* We have to think about a IPv6 link-local address curse. */
841 if (p->family == AF_INET6)
842 {
843 struct zapi_ipv6 api;
844 unsigned int ifindex;
845 struct in6_addr *nexthop;
Paul Jakmafb982c22007-05-04 20:15:47 +0000846
847 assert (info->attr->extra);
848
paul718e3742002-12-13 20:15:29 +0000849 ifindex = 0;
850 nexthop = NULL;
851
852 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000853 if (info->attr->extra->mp_nexthop_len == 16)
854 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000855
856 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000857 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000858 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000859 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000860 if (info->peer->nexthop.ifp)
861 ifindex = info->peer->nexthop.ifp->ifindex;
862 }
863
864 if (nexthop == NULL)
865 return;
866
867 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
868 if (info->peer->ifname)
869 ifindex = if_nametoindex (info->peer->ifname);
870
871 api.flags = flags;
872 api.type = ZEBRA_ROUTE_BGP;
873 api.message = 0;
874 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
875 api.nexthop_num = 1;
876 api.nexthop = &nexthop;
877 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
878 api.ifindex_num = 1;
879 api.ifindex = &ifindex;
880 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
881 api.metric = info->attr->med;
882
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000883 if (BGP_DEBUG(zebra, ZEBRA))
884 {
885 char buf[2][INET6_ADDRSTRLEN];
886 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
887 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
888 p->prefixlen,
889 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
890 api.metric);
891 }
892
paul0a589352004-05-08 11:48:26 +0000893 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
894 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000895 }
896#endif /* HAVE_IPV6 */
897}
898
899/* Other routes redistribution into BGP. */
900int
901bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
902{
903 /* Set flag to BGP instance. */
904 bgp->redist[afi][type] = 1;
905
906 /* Return if already redistribute flag is set. */
907 if (zclient->redist[type])
908 return CMD_WARNING;
909
910 zclient->redist[type] = 1;
911
912 /* Return if zebra connection is not established. */
913 if (zclient->sock < 0)
914 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000915
916 if (BGP_DEBUG(zebra, ZEBRA))
917 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000918
919 /* Send distribute add message to zebra. */
ajs634f9ea2005-04-11 15:51:40 +0000920 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
paul718e3742002-12-13 20:15:29 +0000921
922 return CMD_SUCCESS;
923}
924
925/* Redistribute with route-map specification. */
926int
paulfd79ac92004-10-13 05:06:08 +0000927bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
928 const char *name)
paul718e3742002-12-13 20:15:29 +0000929{
930 if (bgp->rmap[afi][type].name
931 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
932 return 0;
933
934 if (bgp->rmap[afi][type].name)
935 free (bgp->rmap[afi][type].name);
936 bgp->rmap[afi][type].name = strdup (name);
937 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
938
939 return 1;
940}
941
942/* Redistribute with metric specification. */
943int
944bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
945 u_int32_t metric)
946{
947 if (bgp->redist_metric_flag[afi][type]
948 && bgp->redist_metric[afi][type] == metric)
949 return 0;
950
951 bgp->redist_metric_flag[afi][type] = 1;
952 bgp->redist_metric[afi][type] = metric;
953
954 return 1;
955}
956
957/* Unset redistribution. */
958int
959bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
960{
961 /* Unset flag from BGP instance. */
962 bgp->redist[afi][type] = 0;
963
964 /* Unset route-map. */
965 if (bgp->rmap[afi][type].name)
966 free (bgp->rmap[afi][type].name);
967 bgp->rmap[afi][type].name = NULL;
968 bgp->rmap[afi][type].map = NULL;
969
970 /* Unset metric. */
971 bgp->redist_metric_flag[afi][type] = 0;
972 bgp->redist_metric[afi][type] = 0;
973
974 /* Return if zebra connection is disabled. */
975 if (! zclient->redist[type])
976 return CMD_WARNING;
977 zclient->redist[type] = 0;
978
979 if (bgp->redist[AFI_IP][type] == 0
980 && bgp->redist[AFI_IP6][type] == 0
981 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000982 {
983 /* Send distribute delete message to zebra. */
984 if (BGP_DEBUG(zebra, ZEBRA))
985 zlog_debug("Zebra send: redistribute delete %s",
986 zebra_route_string(type));
987 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
988 }
paul718e3742002-12-13 20:15:29 +0000989
990 /* Withdraw redistributed routes from current BGP's routing table. */
991 bgp_redistribute_withdraw (bgp, afi, type);
992
993 return CMD_SUCCESS;
994}
995
996/* Unset redistribution route-map configuration. */
997int
998bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
999{
1000 if (! bgp->rmap[afi][type].name)
1001 return 0;
1002
1003 /* Unset route-map. */
1004 free (bgp->rmap[afi][type].name);
1005 bgp->rmap[afi][type].name = NULL;
1006 bgp->rmap[afi][type].map = NULL;
1007
1008 return 1;
1009}
1010
1011/* Unset redistribution metric configuration. */
1012int
1013bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1014{
1015 if (! bgp->redist_metric_flag[afi][type])
1016 return 0;
1017
1018 /* Unset metric. */
1019 bgp->redist_metric_flag[afi][type] = 0;
1020 bgp->redist_metric[afi][type] = 0;
1021
1022 return 1;
1023}
1024
1025void
paul94f2b392005-06-28 12:44:16 +00001026bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001027{
1028 zclient_reset (zclient);
1029}
1030
1031void
paul94f2b392005-06-28 12:44:16 +00001032bgp_zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001033{
1034 /* Set default values. */
1035 zclient = zclient_new ();
1036 zclient_init (zclient, ZEBRA_ROUTE_BGP);
hasso18a6dce2004-10-03 18:18:34 +00001037 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001038 zclient->interface_add = bgp_interface_add;
1039 zclient->interface_delete = bgp_interface_delete;
1040 zclient->interface_address_add = bgp_interface_address_add;
1041 zclient->interface_address_delete = bgp_interface_address_delete;
1042 zclient->ipv4_route_add = zebra_read_ipv4;
1043 zclient->ipv4_route_delete = zebra_read_ipv4;
1044 zclient->interface_up = bgp_interface_up;
1045 zclient->interface_down = bgp_interface_down;
1046#ifdef HAVE_IPV6
1047 zclient->ipv6_route_add = zebra_read_ipv6;
1048 zclient->ipv6_route_delete = zebra_read_ipv6;
1049#endif /* HAVE_IPV6 */
1050
1051 /* Interface related init. */
1052 if_init ();
1053}