[ospfd] Restructure opsf_if_update() and ospf_network_run()
[jleu-quagga.git] / bgpd / bgp_zebra.c
blob0b6ab45a715e192b9cf45e7740be34634ccb81dd
1 /* zebra client
2 Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <zebra.h>
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"
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"
39 #include "bgpd/bgp_debug.h"
41 /* All information about zebra. */
42 static struct zclient *zclient = NULL;
43 struct in_addr router_id_zebra;
45 /* Router-id update message from zebra. */
46 static int
47 bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
49 struct prefix router_id;
50 struct listnode *node, *nnode;
51 struct bgp *bgp;
53 zebra_router_id_update_read(zclient->ibuf,&router_id);
55 if (BGP_DEBUG(zebra, ZEBRA))
57 char buf[128];
58 prefix2str(&router_id, buf, sizeof(buf));
59 zlog_debug("Zebra rcvd: router id update %s", buf);
62 router_id_zebra = router_id.u.prefix4;
64 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
66 if (!bgp->router_id_static.s_addr)
67 bgp_router_id_set (bgp, &router_id.u.prefix4);
70 return 0;
73 /* Inteface addition message from zebra. */
74 static int
75 bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
77 struct interface *ifp;
79 ifp = zebra_interface_add_read (zclient->ibuf);
81 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
82 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
84 return 0;
87 static int
88 bgp_interface_delete (int command, struct zclient *zclient,
89 zebra_size_t length)
91 struct stream *s;
92 struct interface *ifp;
94 s = zclient->ibuf;
95 ifp = zebra_interface_state_read (s);
96 ifp->ifindex = IFINDEX_INTERNAL;
98 if (BGP_DEBUG(zebra, ZEBRA))
99 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
101 return 0;
104 static int
105 bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
107 struct stream *s;
108 struct interface *ifp;
109 struct connected *c;
110 struct listnode *node, *nnode;
112 s = zclient->ibuf;
113 ifp = zebra_interface_state_read (s);
115 if (! ifp)
116 return 0;
118 if (BGP_DEBUG(zebra, ZEBRA))
119 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
121 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
122 bgp_connected_add (c);
124 return 0;
127 static int
128 bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
130 struct stream *s;
131 struct interface *ifp;
132 struct connected *c;
133 struct listnode *node, *nnode;
135 s = zclient->ibuf;
136 ifp = zebra_interface_state_read (s);
137 if (! ifp)
138 return 0;
140 if (BGP_DEBUG(zebra, ZEBRA))
141 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
143 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
144 bgp_connected_delete (c);
146 /* Fast external-failover (Currently IPv4 only) */
148 struct listnode *mnode;
149 struct bgp *bgp;
150 struct peer *peer;
151 struct interface *peer_if;
153 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
155 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
156 continue;
158 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
160 if (peer->ttl != 1)
161 continue;
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;
168 if (ifp == peer_if)
169 BGP_EVENT_ADD (peer, BGP_Stop);
174 return 0;
177 static int
178 bgp_interface_address_add (int command, struct zclient *zclient,
179 zebra_size_t length)
181 struct connected *ifc;
183 ifc = zebra_interface_address_read (command, zclient->ibuf);
185 if (ifc == NULL)
186 return 0;
188 if (BGP_DEBUG(zebra, ZEBRA))
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);
196 if (if_is_operative (ifc->ifp))
197 bgp_connected_add (ifc);
199 return 0;
202 static int
203 bgp_interface_address_delete (int command, struct zclient *zclient,
204 zebra_size_t length)
206 struct connected *ifc;
208 ifc = zebra_interface_address_read (command, zclient->ibuf);
210 if (ifc == NULL)
211 return 0;
213 if (BGP_DEBUG(zebra, ZEBRA))
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);
221 if (if_is_operative (ifc->ifp))
222 bgp_connected_delete (ifc);
224 connected_free (ifc);
226 return 0;
229 /* Zebra route add and delete treatment. */
230 static int
231 zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
233 struct stream *s;
234 struct zapi_ipv4 api;
235 unsigned long ifindex;
236 struct in_addr nexthop;
237 struct prefix_ipv4 p;
239 s = zclient->ibuf;
240 ifindex = 0;
241 nexthop.s_addr = 0;
243 /* Type, flags, message. */
244 api.type = stream_getc (s);
245 api.flags = stream_getc (s);
246 api.message = stream_getc (s);
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));
254 /* Nexthop, ifindex, distance, metric. */
255 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
257 api.nexthop_num = stream_getc (s);
258 nexthop.s_addr = stream_get_ipv4 (s);
260 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
262 api.ifindex_num = stream_getc (s);
263 ifindex = stream_getl (s);
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;
272 if (command == ZEBRA_IPV4_ROUTE_ADD)
274 if (BGP_DEBUG(zebra, ZEBRA))
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);
284 bgp_redistribute_add((struct prefix *)&p, &nexthop, api.metric, api.type);
286 else
288 if (BGP_DEBUG(zebra, ZEBRA))
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);
299 bgp_redistribute_delete((struct prefix *)&p, api.type);
302 return 0;
305 #ifdef HAVE_IPV6
306 /* Zebra route add and delete treatment. */
307 static int
308 zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
310 struct stream *s;
311 struct zapi_ipv6 api;
312 unsigned long ifindex;
313 struct in6_addr nexthop;
314 struct prefix_ipv6 p;
316 s = zclient->ibuf;
317 ifindex = 0;
318 memset (&nexthop, 0, sizeof (struct in6_addr));
320 /* Type, flags, message. */
321 api.type = stream_getc (s);
322 api.flags = stream_getc (s);
323 api.message = stream_getc (s);
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));
331 /* Nexthop, ifindex, distance, metric. */
332 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
334 api.nexthop_num = stream_getc (s);
335 stream_get (&nexthop, s, 16);
337 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
339 api.ifindex_num = stream_getc (s);
340 ifindex = stream_getl (s);
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;
351 /* Simply ignore link-local address. */
352 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
353 return 0;
355 if (command == ZEBRA_IPV6_ROUTE_ADD)
357 if (BGP_DEBUG(zebra, ZEBRA))
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);
365 bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);
367 else
369 if (BGP_DEBUG(zebra, ZEBRA))
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);
377 bgp_redistribute_delete ((struct prefix *) &p, api.type);
380 return 0;
382 #endif /* HAVE_IPV6 */
384 struct interface *
385 if_lookup_by_ipv4 (struct in_addr *addr)
387 struct listnode *ifnode;
388 struct listnode *cnode;
389 struct interface *ifp;
390 struct connected *connected;
391 struct prefix_ipv4 p;
392 struct prefix *cp;
394 p.family = AF_INET;
395 p.prefix = *addr;
396 p.prefixlen = IPV4_MAX_BITLEN;
398 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
400 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
402 cp = connected->address;
404 if (cp->family == AF_INET)
405 if (prefix_match (cp, (struct prefix *)&p))
406 return ifp;
409 return NULL;
412 struct interface *
413 if_lookup_by_ipv4_exact (struct in_addr *addr)
415 struct listnode *ifnode;
416 struct listnode *cnode;
417 struct interface *ifp;
418 struct connected *connected;
419 struct prefix *cp;
421 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
423 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
425 cp = connected->address;
427 if (cp->family == AF_INET)
428 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
429 return ifp;
432 return NULL;
435 #ifdef HAVE_IPV6
436 struct interface *
437 if_lookup_by_ipv6 (struct in6_addr *addr)
439 struct listnode *ifnode;
440 struct listnode *cnode;
441 struct interface *ifp;
442 struct connected *connected;
443 struct prefix_ipv6 p;
444 struct prefix *cp;
446 p.family = AF_INET6;
447 p.prefix = *addr;
448 p.prefixlen = IPV6_MAX_BITLEN;
450 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
452 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
454 cp = connected->address;
456 if (cp->family == AF_INET6)
457 if (prefix_match (cp, (struct prefix *)&p))
458 return ifp;
461 return NULL;
464 struct interface *
465 if_lookup_by_ipv6_exact (struct in6_addr *addr)
467 struct listnode *ifnode;
468 struct listnode *cnode;
469 struct interface *ifp;
470 struct connected *connected;
471 struct prefix *cp;
473 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
475 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
477 cp = connected->address;
479 if (cp->family == AF_INET6)
480 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
481 return ifp;
484 return NULL;
487 static int
488 if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
490 struct listnode *cnode;
491 struct connected *connected;
492 struct prefix *cp;
494 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
496 cp = connected->address;
498 if (cp->family == AF_INET6)
499 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
501 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
502 return 1;
505 return 0;
508 static int
509 if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
511 struct listnode *cnode;
512 struct connected *connected;
513 struct prefix *cp;
515 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
517 cp = connected->address;
519 if (cp->family == AF_INET6)
520 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
522 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
523 return 1;
526 return 0;
528 #endif /* HAVE_IPV6 */
531 bgp_nexthop_set (union sockunion *local, union sockunion *remote,
532 struct bgp_nexthop *nexthop, struct peer *peer)
534 int ret = 0;
535 struct interface *ifp = NULL;
537 memset (nexthop, 0, sizeof (struct bgp_nexthop));
539 if (!local)
540 return -1;
541 if (!remote)
542 return -1;
544 if (local->sa.sa_family == AF_INET)
546 nexthop->v4 = local->sin.sin_addr;
547 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
549 #ifdef HAVE_IPV6
550 if (local->sa.sa_family == AF_INET6)
552 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
554 if (peer->ifname)
555 ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
557 else
558 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
560 #endif /* HAVE_IPV6 */
562 if (!ifp)
563 return -1;
565 nexthop->ifp = ifp;
567 /* IPv4 connection. */
568 if (local->sa.sa_family == AF_INET)
570 #ifdef HAVE_IPV6
571 /* IPv6 nexthop*/
572 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
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 */
582 #ifdef HAVE_IPV6
583 /* IPv6 connection. */
584 if (local->sa.sa_family == AF_INET6)
586 struct interface *direct = NULL;
588 /* IPv4 nexthop. I don't care about it. */
589 if (peer->local_id.s_addr)
590 nexthop->v4 = peer->local_id;
592 /* Global address*/
593 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
595 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
596 IPV6_MAX_BYTELEN);
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);
603 else
604 /* Link-local address. */
606 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
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);
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;
625 /* KAME stack specific treatment. */
626 #ifdef KAME
627 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
628 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
630 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
632 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
633 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
635 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
637 #endif /* KAME */
638 #endif /* HAVE_IPV6 */
639 return ret;
642 #ifdef HAVE_IPV6
643 static unsigned int
644 bgp_ifindex_by_nexthop (struct in6_addr *addr)
646 struct listnode *ifnode;
647 struct listnode *cnode;
648 struct interface *ifp;
649 struct connected *connected;
650 struct prefix_ipv6 p;
652 p.family = AF_INET6;
653 p.prefix = *addr;
654 p.prefixlen = IPV6_MAX_BITLEN;
656 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
658 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
660 struct prefix *cp;
662 cp = connected->address;
664 if (cp->family == AF_INET6)
666 if (prefix_match (cp, (struct prefix *)&p))
667 return ifp->ifindex;
671 return 0;
673 #endif /* HAVE_IPV6 */
675 void
676 bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp)
678 int flags;
679 u_char distance;
680 struct peer *peer;
682 if (zclient->sock < 0)
683 return;
685 if (! zclient->redist[ZEBRA_ROUTE_BGP])
686 return;
688 flags = 0;
689 peer = info->peer;
691 if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
693 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
694 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
697 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
698 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
699 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
701 if (p->family == AF_INET)
703 struct zapi_ipv4 api;
704 struct in_addr *nexthop;
706 api.flags = flags;
707 nexthop = &info->attr->nexthop;
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;
718 distance = bgp_distance_apply (p, info, bgp);
720 if (distance)
722 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
723 api.distance = distance;
726 if (BGP_DEBUG(zebra, ZEBRA))
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);
736 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
737 (struct prefix_ipv4 *) p, &api);
739 #ifdef HAVE_IPV6
740 /* We have to think about a IPv6 link-local address curse. */
741 if (p->family == AF_INET6)
743 unsigned int ifindex;
744 struct in6_addr *nexthop;
745 struct zapi_ipv6 api;
747 ifindex = 0;
748 nexthop = NULL;
750 assert (info->attr->extra);
752 /* Only global address nexthop exists. */
753 if (info->attr->extra->mp_nexthop_len == 16)
754 nexthop = &info->attr->extra->mp_nexthop_global;
756 /* If both global and link-local address present. */
757 if (info->attr->extra->mp_nexthop_len == 32)
759 /* Workaround for Cisco's nexthop bug. */
760 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
761 && peer->su_remote->sa.sa_family == AF_INET6)
762 nexthop = &peer->su_remote->sin6.sin6_addr;
763 else
764 nexthop = &info->attr->extra->mp_nexthop_local;
766 if (info->peer->nexthop.ifp)
767 ifindex = info->peer->nexthop.ifp->ifindex;
770 if (nexthop == NULL)
771 return;
773 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
775 if (info->peer->ifname)
776 ifindex = if_nametoindex (info->peer->ifname);
777 else if (info->peer->nexthop.ifp)
778 ifindex = info->peer->nexthop.ifp->ifindex;
781 /* Make Zebra API structure. */
782 api.flags = flags;
783 api.type = ZEBRA_ROUTE_BGP;
784 api.message = 0;
785 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
786 api.nexthop_num = 1;
787 api.nexthop = &nexthop;
788 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
789 api.ifindex_num = 1;
790 api.ifindex = &ifindex;
791 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
792 api.metric = info->attr->med;
794 if (BGP_DEBUG(zebra, ZEBRA))
796 char buf[2][INET6_ADDRSTRLEN];
797 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
798 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
799 p->prefixlen,
800 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
801 api.metric);
804 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
805 (struct prefix_ipv6 *) p, &api);
807 #endif /* HAVE_IPV6 */
810 void
811 bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info)
813 int flags;
814 struct peer *peer;
816 if (zclient->sock < 0)
817 return;
819 if (! zclient->redist[ZEBRA_ROUTE_BGP])
820 return;
822 peer = info->peer;
823 flags = 0;
825 if (peer_sort (peer) == BGP_PEER_IBGP)
827 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
828 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
831 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
832 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
833 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
835 if (p->family == AF_INET)
837 struct zapi_ipv4 api;
838 struct in_addr *nexthop;
840 api.flags = flags;
841 nexthop = &info->attr->nexthop;
843 api.type = ZEBRA_ROUTE_BGP;
844 api.message = 0;
845 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
846 api.nexthop_num = 1;
847 api.nexthop = &nexthop;
848 api.ifindex_num = 0;
849 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
850 api.metric = info->attr->med;
852 if (BGP_DEBUG(zebra, ZEBRA))
854 char buf[2][INET_ADDRSTRLEN];
855 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
856 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
857 p->prefixlen,
858 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
859 api.metric);
862 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
863 (struct prefix_ipv4 *) p, &api);
865 #ifdef HAVE_IPV6
866 /* We have to think about a IPv6 link-local address curse. */
867 if (p->family == AF_INET6)
869 struct zapi_ipv6 api;
870 unsigned int ifindex;
871 struct in6_addr *nexthop;
873 assert (info->attr->extra);
875 ifindex = 0;
876 nexthop = NULL;
878 /* Only global address nexthop exists. */
879 if (info->attr->extra->mp_nexthop_len == 16)
880 nexthop = &info->attr->extra->mp_nexthop_global;
882 /* If both global and link-local address present. */
883 if (info->attr->extra->mp_nexthop_len == 32)
885 nexthop = &info->attr->extra->mp_nexthop_local;
886 if (info->peer->nexthop.ifp)
887 ifindex = info->peer->nexthop.ifp->ifindex;
890 if (nexthop == NULL)
891 return;
893 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
894 if (info->peer->ifname)
895 ifindex = if_nametoindex (info->peer->ifname);
897 api.flags = flags;
898 api.type = ZEBRA_ROUTE_BGP;
899 api.message = 0;
900 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
901 api.nexthop_num = 1;
902 api.nexthop = &nexthop;
903 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
904 api.ifindex_num = 1;
905 api.ifindex = &ifindex;
906 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
907 api.metric = info->attr->med;
909 if (BGP_DEBUG(zebra, ZEBRA))
911 char buf[2][INET6_ADDRSTRLEN];
912 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
913 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
914 p->prefixlen,
915 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
916 api.metric);
919 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
920 (struct prefix_ipv6 *) p, &api);
922 #endif /* HAVE_IPV6 */
925 /* Other routes redistribution into BGP. */
927 bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
929 /* Set flag to BGP instance. */
930 bgp->redist[afi][type] = 1;
932 /* Return if already redistribute flag is set. */
933 if (zclient->redist[type])
934 return CMD_WARNING;
936 zclient->redist[type] = 1;
938 /* Return if zebra connection is not established. */
939 if (zclient->sock < 0)
940 return CMD_WARNING;
942 if (BGP_DEBUG(zebra, ZEBRA))
943 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
945 /* Send distribute add message to zebra. */
946 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
948 return CMD_SUCCESS;
951 /* Redistribute with route-map specification. */
953 bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
954 const char *name)
956 if (bgp->rmap[afi][type].name
957 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
958 return 0;
960 if (bgp->rmap[afi][type].name)
961 free (bgp->rmap[afi][type].name);
962 bgp->rmap[afi][type].name = strdup (name);
963 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
965 return 1;
968 /* Redistribute with metric specification. */
970 bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
971 u_int32_t metric)
973 if (bgp->redist_metric_flag[afi][type]
974 && bgp->redist_metric[afi][type] == metric)
975 return 0;
977 bgp->redist_metric_flag[afi][type] = 1;
978 bgp->redist_metric[afi][type] = metric;
980 return 1;
983 /* Unset redistribution. */
985 bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
987 /* Unset flag from BGP instance. */
988 bgp->redist[afi][type] = 0;
990 /* Unset route-map. */
991 if (bgp->rmap[afi][type].name)
992 free (bgp->rmap[afi][type].name);
993 bgp->rmap[afi][type].name = NULL;
994 bgp->rmap[afi][type].map = NULL;
996 /* Unset metric. */
997 bgp->redist_metric_flag[afi][type] = 0;
998 bgp->redist_metric[afi][type] = 0;
1000 /* Return if zebra connection is disabled. */
1001 if (! zclient->redist[type])
1002 return CMD_WARNING;
1003 zclient->redist[type] = 0;
1005 if (bgp->redist[AFI_IP][type] == 0
1006 && bgp->redist[AFI_IP6][type] == 0
1007 && zclient->sock >= 0)
1009 /* Send distribute delete message to zebra. */
1010 if (BGP_DEBUG(zebra, ZEBRA))
1011 zlog_debug("Zebra send: redistribute delete %s",
1012 zebra_route_string(type));
1013 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
1016 /* Withdraw redistributed routes from current BGP's routing table. */
1017 bgp_redistribute_withdraw (bgp, afi, type);
1019 return CMD_SUCCESS;
1022 /* Unset redistribution route-map configuration. */
1024 bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
1026 if (! bgp->rmap[afi][type].name)
1027 return 0;
1029 /* Unset route-map. */
1030 free (bgp->rmap[afi][type].name);
1031 bgp->rmap[afi][type].name = NULL;
1032 bgp->rmap[afi][type].map = NULL;
1034 return 1;
1037 /* Unset redistribution metric configuration. */
1039 bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1041 if (! bgp->redist_metric_flag[afi][type])
1042 return 0;
1044 /* Unset metric. */
1045 bgp->redist_metric_flag[afi][type] = 0;
1046 bgp->redist_metric[afi][type] = 0;
1048 return 1;
1051 void
1052 bgp_zclient_reset (void)
1054 zclient_reset (zclient);
1057 void
1058 bgp_zebra_init (void)
1060 /* Set default values. */
1061 zclient = zclient_new ();
1062 zclient_init (zclient, ZEBRA_ROUTE_BGP);
1063 zclient->router_id_update = bgp_router_id_update;
1064 zclient->interface_add = bgp_interface_add;
1065 zclient->interface_delete = bgp_interface_delete;
1066 zclient->interface_address_add = bgp_interface_address_add;
1067 zclient->interface_address_delete = bgp_interface_address_delete;
1068 zclient->ipv4_route_add = zebra_read_ipv4;
1069 zclient->ipv4_route_delete = zebra_read_ipv4;
1070 zclient->interface_up = bgp_interface_up;
1071 zclient->interface_down = bgp_interface_down;
1072 #ifdef HAVE_IPV6
1073 zclient->ipv6_route_add = zebra_read_ipv6;
1074 zclient->ipv6_route_delete = zebra_read_ipv6;
1075 #endif /* HAVE_IPV6 */
1077 /* Interface related init. */
1078 if_init ();