blob: 301c15b052fca98f14266725eb628e95b4838c52 [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. */
42static struct 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 }
284 bgp_redistribute_add((struct prefix *)&p, &nexthop, api.metric, api.type);
285 }
paul718e3742002-12-13 20:15:29 +0000286 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000287 {
288 if (BGP_DEBUG(zebra, ZEBRA))
289 {
290 char buf[2][INET_ADDRSTRLEN];
291 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
292 "nexthop %s metric %u",
293 zebra_route_string(api.type),
294 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
295 p.prefixlen,
296 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
297 api.metric);
298 }
299 bgp_redistribute_delete((struct prefix *)&p, api.type);
300 }
paul718e3742002-12-13 20:15:29 +0000301
302 return 0;
303}
304
305#ifdef HAVE_IPV6
306/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000307static int
paul718e3742002-12-13 20:15:29 +0000308zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
309{
310 struct stream *s;
311 struct zapi_ipv6 api;
312 unsigned long ifindex;
313 struct in6_addr nexthop;
314 struct prefix_ipv6 p;
315
316 s = zclient->ibuf;
317 ifindex = 0;
318 memset (&nexthop, 0, sizeof (struct in6_addr));
319
320 /* Type, flags, message. */
321 api.type = stream_getc (s);
322 api.flags = stream_getc (s);
323 api.message = stream_getc (s);
324
325 /* IPv6 prefix. */
326 memset (&p, 0, sizeof (struct prefix_ipv6));
327 p.family = AF_INET6;
328 p.prefixlen = stream_getc (s);
329 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
330
331 /* Nexthop, ifindex, distance, metric. */
332 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
333 {
334 api.nexthop_num = stream_getc (s);
335 stream_get (&nexthop, s, 16);
336 }
337 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
338 {
339 api.ifindex_num = stream_getc (s);
340 ifindex = stream_getl (s);
341 }
342 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
343 api.distance = stream_getc (s);
344 else
345 api.distance = 0;
346 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
347 api.metric = stream_getl (s);
348 else
349 api.metric = 0;
350
351 /* Simply ignore link-local address. */
352 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
353 return 0;
354
355 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000356 {
357 if (BGP_DEBUG(zebra, ZEBRA))
358 {
359 char buf[INET6_ADDRSTRLEN];
360 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d metric %u",
361 zebra_route_string(api.type),
362 inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
363 p.prefixlen, api.metric);
364 }
365 bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);
366 }
paul718e3742002-12-13 20:15:29 +0000367 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000368 {
369 if (BGP_DEBUG(zebra, ZEBRA))
370 {
371 char buf[INET6_ADDRSTRLEN];
372 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d metric %u",
373 zebra_route_string(api.type),
374 inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
375 p.prefixlen, api.metric);
376 }
377 bgp_redistribute_delete ((struct prefix *) &p, api.type);
378 }
paul718e3742002-12-13 20:15:29 +0000379
380 return 0;
381}
382#endif /* HAVE_IPV6 */
383
384struct interface *
385if_lookup_by_ipv4 (struct in_addr *addr)
386{
hasso52dc7ee2004-09-23 19:18:23 +0000387 struct listnode *ifnode;
388 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000389 struct interface *ifp;
390 struct connected *connected;
391 struct prefix_ipv4 p;
392 struct prefix *cp;
393
394 p.family = AF_INET;
395 p.prefix = *addr;
396 p.prefixlen = IPV4_MAX_BITLEN;
397
paul1eb8ef22005-04-07 07:30:20 +0000398 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000399 {
paul1eb8ef22005-04-07 07:30:20 +0000400 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000401 {
paul718e3742002-12-13 20:15:29 +0000402 cp = connected->address;
403
404 if (cp->family == AF_INET)
405 if (prefix_match (cp, (struct prefix *)&p))
406 return ifp;
407 }
408 }
409 return NULL;
410}
411
412struct interface *
413if_lookup_by_ipv4_exact (struct in_addr *addr)
414{
hasso52dc7ee2004-09-23 19:18:23 +0000415 struct listnode *ifnode;
416 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000417 struct interface *ifp;
418 struct connected *connected;
419 struct prefix *cp;
420
paul1eb8ef22005-04-07 07:30:20 +0000421 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000422 {
paul1eb8ef22005-04-07 07:30:20 +0000423 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000424 {
paul718e3742002-12-13 20:15:29 +0000425 cp = connected->address;
426
427 if (cp->family == AF_INET)
428 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
429 return ifp;
430 }
431 }
432 return NULL;
433}
434
435#ifdef HAVE_IPV6
436struct interface *
437if_lookup_by_ipv6 (struct in6_addr *addr)
438{
hasso52dc7ee2004-09-23 19:18:23 +0000439 struct listnode *ifnode;
440 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000441 struct interface *ifp;
442 struct connected *connected;
443 struct prefix_ipv6 p;
444 struct prefix *cp;
445
446 p.family = AF_INET6;
447 p.prefix = *addr;
448 p.prefixlen = IPV6_MAX_BITLEN;
449
paul1eb8ef22005-04-07 07:30:20 +0000450 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000451 {
paul1eb8ef22005-04-07 07:30:20 +0000452 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000453 {
paul718e3742002-12-13 20:15:29 +0000454 cp = connected->address;
455
456 if (cp->family == AF_INET6)
457 if (prefix_match (cp, (struct prefix *)&p))
458 return ifp;
459 }
460 }
461 return NULL;
462}
463
464struct interface *
465if_lookup_by_ipv6_exact (struct in6_addr *addr)
466{
hasso52dc7ee2004-09-23 19:18:23 +0000467 struct listnode *ifnode;
468 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000469 struct interface *ifp;
470 struct connected *connected;
471 struct prefix *cp;
472
paul1eb8ef22005-04-07 07:30:20 +0000473 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000474 {
paul1eb8ef22005-04-07 07:30:20 +0000475 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000476 {
paul718e3742002-12-13 20:15:29 +0000477 cp = connected->address;
478
479 if (cp->family == AF_INET6)
480 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
481 return ifp;
482 }
483 }
484 return NULL;
485}
486
paul94f2b392005-06-28 12:44:16 +0000487static int
paul718e3742002-12-13 20:15:29 +0000488if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
489{
hasso52dc7ee2004-09-23 19:18:23 +0000490 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000491 struct connected *connected;
492 struct prefix *cp;
493
paul1eb8ef22005-04-07 07:30:20 +0000494 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000495 {
paul718e3742002-12-13 20:15:29 +0000496 cp = connected->address;
497
498 if (cp->family == AF_INET6)
499 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
500 {
501 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
502 return 1;
503 }
504 }
505 return 0;
506}
507
paul94f2b392005-06-28 12:44:16 +0000508static int
paul718e3742002-12-13 20:15:29 +0000509if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
510{
hasso52dc7ee2004-09-23 19:18:23 +0000511 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000512 struct connected *connected;
513 struct prefix *cp;
514
paul1eb8ef22005-04-07 07:30:20 +0000515 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000516 {
paul718e3742002-12-13 20:15:29 +0000517 cp = connected->address;
518
519 if (cp->family == AF_INET6)
520 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
521 {
522 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
523 return 1;
524 }
525 }
526 return 0;
527}
528#endif /* HAVE_IPV6 */
529
530int
531bgp_nexthop_set (union sockunion *local, union sockunion *remote,
532 struct bgp_nexthop *nexthop, struct peer *peer)
533{
534 int ret = 0;
535 struct interface *ifp = NULL;
536
537 memset (nexthop, 0, sizeof (struct bgp_nexthop));
538
539 if (!local)
540 return -1;
541 if (!remote)
542 return -1;
543
544 if (local->sa.sa_family == AF_INET)
545 {
546 nexthop->v4 = local->sin.sin_addr;
547 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
548 }
549#ifdef HAVE_IPV6
550 if (local->sa.sa_family == AF_INET6)
551 {
552 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
553 {
554 if (peer->ifname)
555 ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
556 }
557 else
558 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
559 }
560#endif /* HAVE_IPV6 */
561
562 if (!ifp)
563 return -1;
564
565 nexthop->ifp = ifp;
566
567 /* IPv4 connection. */
568 if (local->sa.sa_family == AF_INET)
569 {
570#ifdef HAVE_IPV6
571 /* IPv6 nexthop*/
572 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
573
574 /* There is no global nexthop. */
575 if (!ret)
576 if_get_ipv6_local (ifp, &nexthop->v6_global);
577 else
578 if_get_ipv6_local (ifp, &nexthop->v6_local);
579#endif /* HAVE_IPV6 */
580 }
581
582#ifdef HAVE_IPV6
583 /* IPv6 connection. */
584 if (local->sa.sa_family == AF_INET6)
585 {
586 struct interface *direct = NULL;
587
588 /* IPv4 nexthop. I don't care about it. */
589 if (peer->local_id.s_addr)
590 nexthop->v4 = peer->local_id;
591
592 /* Global address*/
593 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
594 {
595 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
596 IPV6_MAX_BYTELEN);
597
598 /* If directory connected set link-local address. */
599 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
600 if (direct)
601 if_get_ipv6_local (ifp, &nexthop->v6_local);
602 }
603 else
604 /* Link-local address. */
605 {
606 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
607
608 /* If there is no global address. Set link-local address as
609 global. I know this break RFC specification... */
610 if (!ret)
611 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
612 IPV6_MAX_BYTELEN);
613 else
614 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
615 IPV6_MAX_BYTELEN);
616 }
617 }
618
619 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
620 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
621 peer->shared_network = 1;
622 else
623 peer->shared_network = 0;
624
625 /* KAME stack specific treatment. */
626#ifdef KAME
627 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
628 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
629 {
630 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
631 }
632 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
633 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
634 {
635 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
636 }
637#endif /* KAME */
638#endif /* HAVE_IPV6 */
639 return ret;
640}
641
642#ifdef HAVE_IPV6
paul94f2b392005-06-28 12:44:16 +0000643static unsigned int
paul718e3742002-12-13 20:15:29 +0000644bgp_ifindex_by_nexthop (struct in6_addr *addr)
645{
hasso52dc7ee2004-09-23 19:18:23 +0000646 struct listnode *ifnode;
647 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000648 struct interface *ifp;
649 struct connected *connected;
650 struct prefix_ipv6 p;
651
652 p.family = AF_INET6;
653 p.prefix = *addr;
654 p.prefixlen = IPV6_MAX_BITLEN;
655
paul1eb8ef22005-04-07 07:30:20 +0000656 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000657 {
paul1eb8ef22005-04-07 07:30:20 +0000658 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000659 {
660 struct prefix *cp;
661
paul718e3742002-12-13 20:15:29 +0000662 cp = connected->address;
663
664 if (cp->family == AF_INET6)
665 {
666 if (prefix_match (cp, (struct prefix *)&p))
667 return ifp->ifindex;
668 }
669 }
670 }
671 return 0;
672}
673#endif /* HAVE_IPV6 */
674
675void
676bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp)
677{
678 int flags;
679 u_char distance;
680 struct peer *peer;
681
682 if (zclient->sock < 0)
683 return;
684
685 if (! zclient->redist[ZEBRA_ROUTE_BGP])
686 return;
687
688 flags = 0;
689 peer = info->peer;
690
691 if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
692 {
693 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
694 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
695 }
696
697 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000698 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000699 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
700
701 if (p->family == AF_INET)
702 {
703 struct zapi_ipv4 api;
704 struct in_addr *nexthop;
705
706 api.flags = flags;
707 nexthop = &info->attr->nexthop;
708
709 api.type = ZEBRA_ROUTE_BGP;
710 api.message = 0;
711 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
712 api.nexthop_num = 1;
713 api.nexthop = &nexthop;
714 api.ifindex_num = 0;
715 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
716 api.metric = info->attr->med;
717
718 distance = bgp_distance_apply (p, info, bgp);
719
720 if (distance)
721 {
722 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
723 api.distance = distance;
724 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000725
726 if (BGP_DEBUG(zebra, ZEBRA))
727 {
728 char buf[2][INET_ADDRSTRLEN];
729 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u",
730 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
731 p->prefixlen,
732 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
733 api.metric);
734 }
735
paul0a589352004-05-08 11:48:26 +0000736 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
737 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000738 }
739#ifdef HAVE_IPV6
740 /* We have to think about a IPv6 link-local address curse. */
741 if (p->family == AF_INET6)
742 {
743 unsigned int ifindex;
744 struct in6_addr *nexthop;
745 struct zapi_ipv6 api;
746
747 ifindex = 0;
748 nexthop = NULL;
749
750 /* Only global address nexthop exists. */
751 if (info->attr->mp_nexthop_len == 16)
752 nexthop = &info->attr->mp_nexthop_global;
753
754 /* If both global and link-local address present. */
755 if (info->attr->mp_nexthop_len == 32)
756 {
757 /* Workaround for Cisco's nexthop bug. */
758 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->mp_nexthop_global)
759 && peer->su_remote->sa.sa_family == AF_INET6)
760 nexthop = &peer->su_remote->sin6.sin6_addr;
761 else
762 nexthop = &info->attr->mp_nexthop_local;
763
764 if (info->peer->nexthop.ifp)
765 ifindex = info->peer->nexthop.ifp->ifindex;
766 }
767
768 if (nexthop == NULL)
769 return;
770
771 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
772 {
773 if (info->peer->ifname)
774 ifindex = if_nametoindex (info->peer->ifname);
775 else if (info->peer->nexthop.ifp)
776 ifindex = info->peer->nexthop.ifp->ifindex;
777 }
778
779 /* Make Zebra API structure. */
780 api.flags = flags;
781 api.type = ZEBRA_ROUTE_BGP;
782 api.message = 0;
783 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
784 api.nexthop_num = 1;
785 api.nexthop = &nexthop;
786 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
787 api.ifindex_num = 1;
788 api.ifindex = &ifindex;
789 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
790 api.metric = info->attr->med;
791
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000792 if (BGP_DEBUG(zebra, ZEBRA))
793 {
794 char buf[2][INET6_ADDRSTRLEN];
795 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
796 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
797 p->prefixlen,
798 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
799 api.metric);
800 }
801
paul0a589352004-05-08 11:48:26 +0000802 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
803 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000804 }
805#endif /* HAVE_IPV6 */
806}
807
808void
809bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info)
810{
811 int flags;
812 struct peer *peer;
813
814 if (zclient->sock < 0)
815 return;
816
817 if (! zclient->redist[ZEBRA_ROUTE_BGP])
818 return;
819
820 peer = info->peer;
821 flags = 0;
822
823 if (peer_sort (peer) == BGP_PEER_IBGP)
824 {
825 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
826 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
827 }
828
829 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000830 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000831 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
832
833 if (p->family == AF_INET)
834 {
835 struct zapi_ipv4 api;
836 struct in_addr *nexthop;
837
838 api.flags = flags;
839 nexthop = &info->attr->nexthop;
840
841 api.type = ZEBRA_ROUTE_BGP;
842 api.message = 0;
843 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
844 api.nexthop_num = 1;
845 api.nexthop = &nexthop;
846 api.ifindex_num = 0;
847 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
848 api.metric = info->attr->med;
849
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000850 if (BGP_DEBUG(zebra, ZEBRA))
851 {
852 char buf[2][INET_ADDRSTRLEN];
853 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
854 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
855 p->prefixlen,
856 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
857 api.metric);
858 }
859
paul0a589352004-05-08 11:48:26 +0000860 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
861 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000862 }
863#ifdef HAVE_IPV6
864 /* We have to think about a IPv6 link-local address curse. */
865 if (p->family == AF_INET6)
866 {
867 struct zapi_ipv6 api;
868 unsigned int ifindex;
869 struct in6_addr *nexthop;
870
871 ifindex = 0;
872 nexthop = NULL;
873
874 /* Only global address nexthop exists. */
875 if (info->attr->mp_nexthop_len == 16)
876 nexthop = &info->attr->mp_nexthop_global;
877
878 /* If both global and link-local address present. */
879 if (info->attr->mp_nexthop_len == 32)
880 {
881 nexthop = &info->attr->mp_nexthop_local;
882 if (info->peer->nexthop.ifp)
883 ifindex = info->peer->nexthop.ifp->ifindex;
884 }
885
886 if (nexthop == NULL)
887 return;
888
889 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
890 if (info->peer->ifname)
891 ifindex = if_nametoindex (info->peer->ifname);
892
893 api.flags = flags;
894 api.type = ZEBRA_ROUTE_BGP;
895 api.message = 0;
896 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
897 api.nexthop_num = 1;
898 api.nexthop = &nexthop;
899 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
900 api.ifindex_num = 1;
901 api.ifindex = &ifindex;
902 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
903 api.metric = info->attr->med;
904
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000905 if (BGP_DEBUG(zebra, ZEBRA))
906 {
907 char buf[2][INET6_ADDRSTRLEN];
908 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
909 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
910 p->prefixlen,
911 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
912 api.metric);
913 }
914
paul0a589352004-05-08 11:48:26 +0000915 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
916 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000917 }
918#endif /* HAVE_IPV6 */
919}
920
921/* Other routes redistribution into BGP. */
922int
923bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
924{
925 /* Set flag to BGP instance. */
926 bgp->redist[afi][type] = 1;
927
928 /* Return if already redistribute flag is set. */
929 if (zclient->redist[type])
930 return CMD_WARNING;
931
932 zclient->redist[type] = 1;
933
934 /* Return if zebra connection is not established. */
935 if (zclient->sock < 0)
936 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000937
938 if (BGP_DEBUG(zebra, ZEBRA))
939 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000940
941 /* Send distribute add message to zebra. */
ajs634f9ea2005-04-11 15:51:40 +0000942 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
paul718e3742002-12-13 20:15:29 +0000943
944 return CMD_SUCCESS;
945}
946
947/* Redistribute with route-map specification. */
948int
paulfd79ac92004-10-13 05:06:08 +0000949bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
950 const char *name)
paul718e3742002-12-13 20:15:29 +0000951{
952 if (bgp->rmap[afi][type].name
953 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
954 return 0;
955
956 if (bgp->rmap[afi][type].name)
957 free (bgp->rmap[afi][type].name);
958 bgp->rmap[afi][type].name = strdup (name);
959 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
960
961 return 1;
962}
963
964/* Redistribute with metric specification. */
965int
966bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
967 u_int32_t metric)
968{
969 if (bgp->redist_metric_flag[afi][type]
970 && bgp->redist_metric[afi][type] == metric)
971 return 0;
972
973 bgp->redist_metric_flag[afi][type] = 1;
974 bgp->redist_metric[afi][type] = metric;
975
976 return 1;
977}
978
979/* Unset redistribution. */
980int
981bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
982{
983 /* Unset flag from BGP instance. */
984 bgp->redist[afi][type] = 0;
985
986 /* Unset route-map. */
987 if (bgp->rmap[afi][type].name)
988 free (bgp->rmap[afi][type].name);
989 bgp->rmap[afi][type].name = NULL;
990 bgp->rmap[afi][type].map = NULL;
991
992 /* Unset metric. */
993 bgp->redist_metric_flag[afi][type] = 0;
994 bgp->redist_metric[afi][type] = 0;
995
996 /* Return if zebra connection is disabled. */
997 if (! zclient->redist[type])
998 return CMD_WARNING;
999 zclient->redist[type] = 0;
1000
1001 if (bgp->redist[AFI_IP][type] == 0
1002 && bgp->redist[AFI_IP6][type] == 0
1003 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001004 {
1005 /* Send distribute delete message to zebra. */
1006 if (BGP_DEBUG(zebra, ZEBRA))
1007 zlog_debug("Zebra send: redistribute delete %s",
1008 zebra_route_string(type));
1009 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
1010 }
paul718e3742002-12-13 20:15:29 +00001011
1012 /* Withdraw redistributed routes from current BGP's routing table. */
1013 bgp_redistribute_withdraw (bgp, afi, type);
1014
1015 return CMD_SUCCESS;
1016}
1017
1018/* Unset redistribution route-map configuration. */
1019int
1020bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
1021{
1022 if (! bgp->rmap[afi][type].name)
1023 return 0;
1024
1025 /* Unset route-map. */
1026 free (bgp->rmap[afi][type].name);
1027 bgp->rmap[afi][type].name = NULL;
1028 bgp->rmap[afi][type].map = NULL;
1029
1030 return 1;
1031}
1032
1033/* Unset redistribution metric configuration. */
1034int
1035bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1036{
1037 if (! bgp->redist_metric_flag[afi][type])
1038 return 0;
1039
1040 /* Unset metric. */
1041 bgp->redist_metric_flag[afi][type] = 0;
1042 bgp->redist_metric[afi][type] = 0;
1043
1044 return 1;
1045}
1046
1047void
paul94f2b392005-06-28 12:44:16 +00001048bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001049{
1050 zclient_reset (zclient);
1051}
1052
1053void
paul94f2b392005-06-28 12:44:16 +00001054bgp_zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001055{
1056 /* Set default values. */
1057 zclient = zclient_new ();
1058 zclient_init (zclient, ZEBRA_ROUTE_BGP);
hasso18a6dce2004-10-03 18:18:34 +00001059 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001060 zclient->interface_add = bgp_interface_add;
1061 zclient->interface_delete = bgp_interface_delete;
1062 zclient->interface_address_add = bgp_interface_address_add;
1063 zclient->interface_address_delete = bgp_interface_address_delete;
1064 zclient->ipv4_route_add = zebra_read_ipv4;
1065 zclient->ipv4_route_delete = zebra_read_ipv4;
1066 zclient->interface_up = bgp_interface_up;
1067 zclient->interface_down = bgp_interface_down;
1068#ifdef HAVE_IPV6
1069 zclient->ipv6_route_add = zebra_read_ipv6;
1070 zclient->ipv6_route_delete = zebra_read_ipv6;
1071#endif /* HAVE_IPV6 */
1072
1073 /* Interface related init. */
1074 if_init ();
1075}