usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / zebra / bgpd / bgp_zebra.c
blobec6e2d1c48654c5abb6774bf2ab3110d71ba0f04
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"
40 /* All information about zebra. */
41 static struct zclient *zclient = NULL;
43 /* Update default router id. */
44 int
45 bgp_if_update (struct interface *ifp)
47 struct bgp *bgp;
48 listnode cn;
49 struct listnode *nn;
50 struct listnode *nm;
51 struct peer *peer;
53 for (cn = listhead (ifp->connected); cn; nextnode (cn))
55 struct connected *co;
56 struct in_addr addr;
58 co = getdata (cn);
60 if (co->address->family == AF_INET)
62 addr = co->address->u.prefix4;
64 /* Ignore NET127. */
65 if (IPV4_NET127 (ntohl (addr.s_addr)))
66 continue;
68 LIST_LOOP (bm->bgp, bgp, nn)
70 /* Respect configured router id */
71 if (! (bgp->config & BGP_CONFIG_ROUTER_ID))
72 if (ntohl (bgp->router_id.s_addr) < ntohl (addr.s_addr))
74 bgp->router_id = addr;
75 LIST_LOOP (bgp->peer, peer, nm)
77 peer->local_id = addr;
83 return 0;
86 int
87 bgp_if_update_all ()
89 listnode node;
90 struct interface *ifp;
92 for (node = listhead (iflist); node; node = nextnode (node))
94 ifp = getdata (node);
95 bgp_if_update (ifp);
97 return 0;
100 /* Inteface addition message from zebra. */
102 bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
104 struct interface *ifp;
106 ifp = zebra_interface_add_read (zclient->ibuf);
107 bgp_if_update (ifp);
109 return 0;
113 bgp_interface_delete (int command, struct zclient *zclient,
114 zebra_size_t length)
116 struct stream *s;
117 struct interface *ifp;
119 s = zclient->ibuf;
120 ifp = zebra_interface_state_read (s);
122 return 0;
126 bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
128 struct stream *s;
129 struct interface *ifp;
130 struct connected *c;
131 listnode node;
133 s = zclient->ibuf;
134 ifp = zebra_interface_state_read (s);
136 if (! ifp)
137 return 0;
139 for (node = listhead (ifp->connected); node; nextnode (node))
141 c = getdata (node);
142 bgp_connected_add (c);
145 return 0;
149 bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
151 struct stream *s;
152 struct interface *ifp;
153 struct connected *c;
154 listnode node;
156 s = zclient->ibuf;
157 ifp = zebra_interface_state_read (s);
158 if (! ifp)
159 return 0;
161 for (node = listhead (ifp->connected); node; nextnode (node))
163 c = getdata (node);
164 bgp_connected_delete (c);
167 /* Fast external-failover (Currently IPv4 only) */
169 struct listnode *nn, *nm;
170 struct bgp *bgp;
171 struct peer *peer;
172 struct interface *peer_if;
174 LIST_LOOP (bm->bgp, bgp, nn)
176 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
177 continue;
179 LIST_LOOP (bgp->peer, peer, nm)
181 if (peer->ttl != 1)
182 continue;
184 if (peer->su.sa.sa_family == AF_INET)
185 peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);
186 else
187 continue;
189 if (ifp == peer_if)
190 BGP_EVENT_ADD (peer, BGP_Stop);
195 return 0;
199 bgp_interface_address_add (int command, struct zclient *zclient,
200 zebra_size_t length)
202 struct connected *ifc;
204 ifc = zebra_interface_address_add_read (zclient->ibuf);
206 if (ifc == NULL)
207 return 0;
209 bgp_if_update (ifc->ifp);
211 if (if_is_up (ifc->ifp))
212 bgp_connected_add (ifc);
214 return 0;
218 bgp_interface_address_delete (int command, struct zclient *zclient,
219 zebra_size_t length)
221 struct connected *ifc;
223 ifc = zebra_interface_address_delete_read (zclient->ibuf);
225 if (ifc == NULL)
226 return 0;
228 bgp_if_update (ifc->ifp);
230 if (if_is_up (ifc->ifp))
231 bgp_connected_delete (ifc);
233 connected_free (ifc);
235 return 0;
238 /* Zebra route add and delete treatment. */
240 zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
242 struct stream *s;
243 struct zapi_ipv4 api;
244 unsigned long ifindex;
245 struct in_addr nexthop;
246 struct prefix_ipv4 p;
248 s = zclient->ibuf;
249 ifindex = 0;
250 nexthop.s_addr = 0;
252 /* Type, flags, message. */
253 api.type = stream_getc (s);
254 api.flags = stream_getc (s);
255 api.message = stream_getc (s);
257 /* IPv4 prefix. */
258 memset (&p, 0, sizeof (struct prefix_ipv4));
259 p.family = AF_INET;
260 p.prefixlen = stream_getc (s);
261 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
263 /* Nexthop, ifindex, distance, metric. */
264 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
266 api.nexthop_num = stream_getc (s);
267 nexthop.s_addr = stream_get_ipv4 (s);
269 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
271 api.ifindex_num = stream_getc (s);
272 ifindex = stream_getl (s);
274 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
275 api.distance = stream_getc (s);
276 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
277 api.metric = stream_getl (s);
278 else
279 api.metric = 0;
281 if (command == ZEBRA_IPV4_ROUTE_ADD)
282 bgp_redistribute_add ((struct prefix *)&p, &nexthop, api.metric, api.type);
283 else
284 bgp_redistribute_delete ((struct prefix *)&p, api.type);
286 return 0;
289 #ifdef HAVE_IPV6
290 /* Zebra route add and delete treatment. */
292 zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
294 struct stream *s;
295 struct zapi_ipv6 api;
296 unsigned long ifindex;
297 struct in6_addr nexthop;
298 struct prefix_ipv6 p;
300 s = zclient->ibuf;
301 ifindex = 0;
302 memset (&nexthop, 0, sizeof (struct in6_addr));
304 /* Type, flags, message. */
305 api.type = stream_getc (s);
306 api.flags = stream_getc (s);
307 api.message = stream_getc (s);
309 /* IPv6 prefix. */
310 memset (&p, 0, sizeof (struct prefix_ipv6));
311 p.family = AF_INET6;
312 p.prefixlen = stream_getc (s);
313 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
315 /* Nexthop, ifindex, distance, metric. */
316 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
318 api.nexthop_num = stream_getc (s);
319 stream_get (&nexthop, s, 16);
321 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
323 api.ifindex_num = stream_getc (s);
324 ifindex = stream_getl (s);
326 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
327 api.distance = stream_getc (s);
328 else
329 api.distance = 0;
330 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
331 api.metric = stream_getl (s);
332 else
333 api.metric = 0;
335 /* Simply ignore link-local address. */
336 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
337 return 0;
339 if (command == ZEBRA_IPV6_ROUTE_ADD)
340 bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);
341 else
342 bgp_redistribute_delete ((struct prefix *) &p, api.type);
344 return 0;
346 #endif /* HAVE_IPV6 */
348 struct interface *
349 if_lookup_by_ipv4 (struct in_addr *addr)
351 listnode ifnode;
352 listnode cnode;
353 struct interface *ifp;
354 struct connected *connected;
355 struct prefix_ipv4 p;
356 struct prefix *cp;
358 p.family = AF_INET;
359 p.prefix = *addr;
360 p.prefixlen = IPV4_MAX_BITLEN;
362 for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
364 ifp = getdata (ifnode);
366 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
368 connected = getdata (cnode);
369 cp = connected->address;
371 if (cp->family == AF_INET)
372 if (prefix_match (cp, (struct prefix *)&p))
373 return ifp;
376 return NULL;
379 struct interface *
380 if_lookup_by_ipv4_exact (struct in_addr *addr)
382 listnode ifnode;
383 listnode cnode;
384 struct interface *ifp;
385 struct connected *connected;
386 struct prefix *cp;
388 for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
390 ifp = getdata (ifnode);
392 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
394 connected = getdata (cnode);
395 cp = connected->address;
397 if (cp->family == AF_INET)
398 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
399 return ifp;
402 return NULL;
405 #ifdef HAVE_IPV6
406 struct interface *
407 if_lookup_by_ipv6 (struct in6_addr *addr)
409 listnode ifnode;
410 listnode cnode;
411 struct interface *ifp;
412 struct connected *connected;
413 struct prefix_ipv6 p;
414 struct prefix *cp;
416 p.family = AF_INET6;
417 p.prefix = *addr;
418 p.prefixlen = IPV6_MAX_BITLEN;
420 for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
422 ifp = getdata (ifnode);
424 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
426 connected = getdata (cnode);
427 cp = connected->address;
429 if (cp->family == AF_INET6)
430 if (prefix_match (cp, (struct prefix *)&p))
431 return ifp;
434 return NULL;
437 struct interface *
438 if_lookup_by_ipv6_exact (struct in6_addr *addr)
440 listnode ifnode;
441 listnode cnode;
442 struct interface *ifp;
443 struct connected *connected;
444 struct prefix *cp;
446 for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
448 ifp = getdata (ifnode);
450 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
452 connected = getdata (cnode);
453 cp = connected->address;
455 if (cp->family == AF_INET6)
456 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
457 return ifp;
460 return NULL;
464 if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
466 listnode cnode;
467 struct connected *connected;
468 struct prefix *cp;
470 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
472 connected = getdata (cnode);
473 cp = connected->address;
475 if (cp->family == AF_INET6)
476 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
478 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
479 return 1;
482 return 0;
486 if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
488 listnode cnode;
489 struct connected *connected;
490 struct prefix *cp;
492 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
494 connected = getdata (cnode);
495 cp = connected->address;
497 if (cp->family == AF_INET6)
498 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
500 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
501 return 1;
504 return 0;
506 #endif /* HAVE_IPV6 */
509 bgp_nexthop_set (union sockunion *local, union sockunion *remote,
510 struct bgp_nexthop *nexthop, struct peer *peer)
512 int ret = 0;
513 struct interface *ifp = NULL;
515 memset (nexthop, 0, sizeof (struct bgp_nexthop));
517 if (!local)
518 return -1;
519 if (!remote)
520 return -1;
522 if (local->sa.sa_family == AF_INET)
524 nexthop->v4 = local->sin.sin_addr;
525 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
527 #ifdef HAVE_IPV6
528 if (local->sa.sa_family == AF_INET6)
530 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
532 if (peer->ifname)
533 ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
535 else
536 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
538 #endif /* HAVE_IPV6 */
540 if (!ifp)
541 return -1;
543 nexthop->ifp = ifp;
545 /* IPv4 connection. */
546 if (local->sa.sa_family == AF_INET)
548 #ifdef HAVE_IPV6
549 /* IPv6 nexthop*/
550 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
552 /* There is no global nexthop. */
553 if (!ret)
554 if_get_ipv6_local (ifp, &nexthop->v6_global);
555 else
556 if_get_ipv6_local (ifp, &nexthop->v6_local);
557 #endif /* HAVE_IPV6 */
560 #ifdef HAVE_IPV6
561 /* IPv6 connection. */
562 if (local->sa.sa_family == AF_INET6)
564 struct interface *direct = NULL;
566 /* IPv4 nexthop. I don't care about it. */
567 if (peer->local_id.s_addr)
568 nexthop->v4 = peer->local_id;
570 /* Global address*/
571 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
573 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
574 IPV6_MAX_BYTELEN);
576 /* If directory connected set link-local address. */
577 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
578 if (direct)
579 if_get_ipv6_local (ifp, &nexthop->v6_local);
581 else
582 /* Link-local address. */
584 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
586 /* If there is no global address. Set link-local address as
587 global. I know this break RFC specification... */
588 if (!ret)
589 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
590 IPV6_MAX_BYTELEN);
591 else
592 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
593 IPV6_MAX_BYTELEN);
597 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
598 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
599 peer->shared_network = 1;
600 else
601 peer->shared_network = 0;
603 /* KAME stack specific treatment. */
604 #ifdef KAME
605 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
606 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
608 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
610 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
611 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
613 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
615 #endif /* KAME */
616 #endif /* HAVE_IPV6 */
617 return ret;
620 #ifdef HAVE_IPV6
621 unsigned int
622 bgp_ifindex_by_nexthop (struct in6_addr *addr)
624 listnode ifnode;
625 listnode cnode;
626 struct interface *ifp;
627 struct connected *connected;
628 struct prefix_ipv6 p;
630 p.family = AF_INET6;
631 p.prefix = *addr;
632 p.prefixlen = IPV6_MAX_BITLEN;
634 for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
636 ifp = getdata (ifnode);
638 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
640 struct prefix *cp;
642 connected = getdata (cnode);
643 cp = connected->address;
645 if (cp->family == AF_INET6)
647 if (prefix_match (cp, (struct prefix *)&p))
648 return ifp->ifindex;
652 return 0;
654 #endif /* HAVE_IPV6 */
656 void
657 bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp)
659 int flags;
660 u_char distance;
661 struct peer *peer;
663 if (zclient->sock < 0)
664 return;
666 if (! zclient->redist[ZEBRA_ROUTE_BGP])
667 return;
669 flags = 0;
670 peer = info->peer;
672 if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
674 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
675 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
678 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
679 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
680 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
682 if (p->family == AF_INET)
684 struct zapi_ipv4 api;
685 struct in_addr *nexthop;
687 api.flags = flags;
688 nexthop = &info->attr->nexthop;
690 api.type = ZEBRA_ROUTE_BGP;
691 api.message = 0;
692 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
693 api.nexthop_num = 1;
694 api.nexthop = &nexthop;
695 api.ifindex_num = 0;
696 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
697 api.metric = info->attr->med;
699 distance = bgp_distance_apply (p, info, bgp);
701 if (distance)
703 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
704 api.distance = distance;
706 zapi_ipv4_add (zclient, (struct prefix_ipv4 *) p, &api);
708 #ifdef HAVE_IPV6
709 /* We have to think about a IPv6 link-local address curse. */
710 if (p->family == AF_INET6)
712 unsigned int ifindex;
713 struct in6_addr *nexthop;
714 struct zapi_ipv6 api;
716 ifindex = 0;
717 nexthop = NULL;
719 /* Only global address nexthop exists. */
720 if (info->attr->mp_nexthop_len == 16)
721 nexthop = &info->attr->mp_nexthop_global;
723 /* If both global and link-local address present. */
724 if (info->attr->mp_nexthop_len == 32)
726 /* Workaround for Cisco's nexthop bug. */
727 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->mp_nexthop_global)
728 && peer->su_remote->sa.sa_family == AF_INET6)
729 nexthop = &peer->su_remote->sin6.sin6_addr;
730 else
731 nexthop = &info->attr->mp_nexthop_local;
733 if (info->peer->nexthop.ifp)
734 ifindex = info->peer->nexthop.ifp->ifindex;
737 if (nexthop == NULL)
738 return;
740 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
742 if (info->peer->ifname)
743 ifindex = if_nametoindex (info->peer->ifname);
744 else if (info->peer->nexthop.ifp)
745 ifindex = info->peer->nexthop.ifp->ifindex;
748 /* Make Zebra API structure. */
749 api.flags = flags;
750 api.type = ZEBRA_ROUTE_BGP;
751 api.message = 0;
752 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
753 api.nexthop_num = 1;
754 api.nexthop = &nexthop;
755 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
756 api.ifindex_num = 1;
757 api.ifindex = &ifindex;
758 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
759 api.metric = info->attr->med;
761 zapi_ipv6_add (zclient, (struct prefix_ipv6 *) p, &api);
763 #endif /* HAVE_IPV6 */
766 void
767 bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info)
769 int flags;
770 struct peer *peer;
772 if (zclient->sock < 0)
773 return;
775 if (! zclient->redist[ZEBRA_ROUTE_BGP])
776 return;
778 peer = info->peer;
779 flags = 0;
781 if (peer_sort (peer) == BGP_PEER_IBGP)
783 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
784 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
787 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
788 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
789 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
791 if (p->family == AF_INET)
793 struct zapi_ipv4 api;
794 struct in_addr *nexthop;
796 api.flags = flags;
797 nexthop = &info->attr->nexthop;
799 api.type = ZEBRA_ROUTE_BGP;
800 api.message = 0;
801 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
802 api.nexthop_num = 1;
803 api.nexthop = &nexthop;
804 api.ifindex_num = 0;
805 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
806 api.metric = info->attr->med;
808 zapi_ipv4_delete (zclient, (struct prefix_ipv4 *) p, &api);
810 #ifdef HAVE_IPV6
811 /* We have to think about a IPv6 link-local address curse. */
812 if (p->family == AF_INET6)
814 struct zapi_ipv6 api;
815 unsigned int ifindex;
816 struct in6_addr *nexthop;
818 ifindex = 0;
819 nexthop = NULL;
821 /* Only global address nexthop exists. */
822 if (info->attr->mp_nexthop_len == 16)
823 nexthop = &info->attr->mp_nexthop_global;
825 /* If both global and link-local address present. */
826 if (info->attr->mp_nexthop_len == 32)
828 nexthop = &info->attr->mp_nexthop_local;
829 if (info->peer->nexthop.ifp)
830 ifindex = info->peer->nexthop.ifp->ifindex;
833 if (nexthop == NULL)
834 return;
836 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
837 if (info->peer->ifname)
838 ifindex = if_nametoindex (info->peer->ifname);
840 api.flags = flags;
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 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
847 api.ifindex_num = 1;
848 api.ifindex = &ifindex;
849 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
850 api.metric = info->attr->med;
852 zapi_ipv6_delete (zclient, (struct prefix_ipv6 *) p, &api);
854 #endif /* HAVE_IPV6 */
857 /* Other routes redistribution into BGP. */
859 bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
861 /* Set flag to BGP instance. */
862 bgp->redist[afi][type] = 1;
864 /* Return if already redistribute flag is set. */
865 if (zclient->redist[type])
866 return CMD_WARNING;
868 zclient->redist[type] = 1;
870 /* Return if zebra connection is not established. */
871 if (zclient->sock < 0)
872 return CMD_WARNING;
874 /* Send distribute add message to zebra. */
875 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
877 return CMD_SUCCESS;
880 /* Redistribute with route-map specification. */
882 bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type, char *name)
884 if (bgp->rmap[afi][type].name
885 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
886 return 0;
888 if (bgp->rmap[afi][type].name)
889 free (bgp->rmap[afi][type].name);
890 bgp->rmap[afi][type].name = strdup (name);
891 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
893 return 1;
896 /* Redistribute with metric specification. */
898 bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
899 u_int32_t metric)
901 if (bgp->redist_metric_flag[afi][type]
902 && bgp->redist_metric[afi][type] == metric)
903 return 0;
905 bgp->redist_metric_flag[afi][type] = 1;
906 bgp->redist_metric[afi][type] = metric;
908 return 1;
911 /* Unset redistribution. */
913 bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
915 /* Unset flag from BGP instance. */
916 bgp->redist[afi][type] = 0;
918 /* Unset route-map. */
919 if (bgp->rmap[afi][type].name)
920 free (bgp->rmap[afi][type].name);
921 bgp->rmap[afi][type].name = NULL;
922 bgp->rmap[afi][type].map = NULL;
924 /* Unset metric. */
925 bgp->redist_metric_flag[afi][type] = 0;
926 bgp->redist_metric[afi][type] = 0;
928 /* Return if zebra connection is disabled. */
929 if (! zclient->redist[type])
930 return CMD_WARNING;
931 zclient->redist[type] = 0;
933 if (bgp->redist[AFI_IP][type] == 0
934 && bgp->redist[AFI_IP6][type] == 0
935 && zclient->sock >= 0)
936 /* Send distribute delete message to zebra. */
937 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
939 /* Withdraw redistributed routes from current BGP's routing table. */
940 bgp_redistribute_withdraw (bgp, afi, type);
942 return CMD_SUCCESS;
945 /* Unset redistribution route-map configuration. */
947 bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
949 if (! bgp->rmap[afi][type].name)
950 return 0;
952 /* Unset route-map. */
953 free (bgp->rmap[afi][type].name);
954 bgp->rmap[afi][type].name = NULL;
955 bgp->rmap[afi][type].map = NULL;
957 return 1;
960 /* Unset redistribution metric configuration. */
962 bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
964 if (! bgp->redist_metric_flag[afi][type])
965 return 0;
967 /* Unset metric. */
968 bgp->redist_metric_flag[afi][type] = 0;
969 bgp->redist_metric[afi][type] = 0;
971 return 1;
974 void
975 bgp_zclient_reset ()
977 zclient_reset (zclient);
980 void
981 bgp_zebra_init (int enable)
983 /* Set default values. */
984 zclient = zclient_new ();
985 zclient_init (zclient, ZEBRA_ROUTE_BGP);
986 zclient->interface_add = bgp_interface_add;
987 zclient->interface_delete = bgp_interface_delete;
988 zclient->interface_address_add = bgp_interface_address_add;
989 zclient->interface_address_delete = bgp_interface_address_delete;
990 zclient->ipv4_route_add = zebra_read_ipv4;
991 zclient->ipv4_route_delete = zebra_read_ipv4;
992 zclient->interface_up = bgp_interface_up;
993 zclient->interface_down = bgp_interface_down;
994 #ifdef HAVE_IPV6
995 zclient->ipv6_route_add = zebra_read_ipv6;
996 zclient->ipv6_route_delete = zebra_read_ipv6;
997 #endif /* HAVE_IPV6 */
999 /* Interface related init. */
1000 if_init ();