bgp_zebra.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:23k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* zebra client
  2.    Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
  3. This file is part of GNU Zebra.
  4. GNU Zebra is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. GNU Zebra is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Zebra; see the file COPYING.  If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.  */
  16. #include <zebra.h>
  17. #include "command.h"
  18. #include "stream.h"
  19. #include "network.h"
  20. #include "prefix.h"
  21. #include "log.h"
  22. #include "sockunion.h"
  23. #include "zclient.h"
  24. #include "routemap.h"
  25. #include "thread.h"
  26. #include "bgpd/bgpd.h"
  27. #include "bgpd/bgp_route.h"
  28. #include "bgpd/bgp_attr.h"
  29. #include "bgpd/bgp_nexthop.h"
  30. #include "bgpd/bgp_zebra.h"
  31. #include "bgpd/bgp_fsm.h"
  32. /* All information about zebra. */
  33. static struct zclient *zclient = NULL;
  34. /* Update default router id. */
  35. int
  36. bgp_if_update (struct interface *ifp)
  37. {
  38.   struct bgp *bgp;
  39.   listnode cn;
  40.   struct listnode *nn;
  41.   struct listnode *nm;
  42.   struct peer *peer;
  43.   for (cn = listhead (ifp->connected); cn; nextnode (cn))
  44.     {
  45.       struct connected *co;
  46.       struct in_addr addr;
  47.       co = getdata (cn);
  48.       if (co->address->family == AF_INET)
  49. {
  50.   addr = co->address->u.prefix4;
  51.   /* Ignore NET127. */
  52.   if (IPV4_NET127 (ntohl (addr.s_addr)))
  53.     continue;
  54.   LIST_LOOP (bm->bgp, bgp, nn)
  55.     {
  56.       /* Respect configured router id */
  57.       if (! (bgp->config & BGP_CONFIG_ROUTER_ID))
  58. if (ntohl (bgp->router_id.s_addr) < ntohl (addr.s_addr))
  59.   {
  60.     bgp->router_id = addr;
  61.     LIST_LOOP (bgp->peer, peer, nm)
  62.       {
  63. peer->local_id = addr;
  64.       }
  65.   }
  66.     }
  67. }
  68.     }
  69.   return 0;
  70. }
  71. int
  72. bgp_if_update_all ()
  73. {
  74.   listnode node;
  75.   struct interface *ifp;
  76.   for (node = listhead (iflist); node; node = nextnode (node))
  77.     {
  78.       ifp = getdata (node);
  79.       bgp_if_update (ifp);
  80.     }
  81.   return 0;
  82. }
  83. /* Inteface addition message from zebra. */
  84. int
  85. bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
  86. {
  87.   struct interface *ifp;
  88.   ifp = zebra_interface_add_read (zclient->ibuf);
  89.   bgp_if_update (ifp);
  90.   return 0;
  91. }
  92. int
  93. bgp_interface_delete (int command, struct zclient *zclient,
  94.       zebra_size_t length)
  95. {
  96.   struct stream *s;
  97.   struct interface *ifp;
  98.   s = zclient->ibuf;
  99.   ifp = zebra_interface_state_read (s);
  100.   return 0;
  101. }
  102. int
  103. bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
  104. {
  105.   struct stream *s;
  106.   struct interface *ifp;
  107.   struct connected *c;
  108.   listnode node;
  109.   s = zclient->ibuf;
  110.   ifp = zebra_interface_state_read (s);
  111.   if (! ifp)
  112.     return 0;
  113.   for (node = listhead (ifp->connected); node; nextnode (node))
  114.     {
  115.       c = getdata (node);
  116.       bgp_connected_add (c);
  117.     }
  118.   return 0;
  119. }
  120. int
  121. bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
  122. {
  123.   struct stream *s;
  124.   struct interface *ifp;
  125.   struct connected *c;
  126.   listnode node;
  127.   s = zclient->ibuf;
  128.   ifp = zebra_interface_state_read (s);
  129.   if (! ifp)
  130.     return 0;
  131.   for (node = listhead (ifp->connected); node; nextnode (node))
  132.     {
  133.       c = getdata (node);
  134.       bgp_connected_delete (c);
  135.     }
  136.   /* Fast external-failover (Currently IPv4 only) */
  137.   {
  138.     struct listnode *nn, *nm;
  139.     struct bgp *bgp;
  140.     struct peer *peer;
  141.     struct interface *peer_if;
  142.     LIST_LOOP (bm->bgp, bgp, nn)
  143.       {
  144. if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
  145.   continue;
  146. LIST_LOOP (bgp->peer, peer, nm)
  147.   {
  148.     if (peer->ttl != 1)
  149.       continue;
  150.     if (peer->su.sa.sa_family == AF_INET)
  151.       peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);
  152.     else
  153.       continue;
  154.     if (ifp == peer_if)
  155.       BGP_EVENT_ADD (peer, BGP_Stop);
  156.   }
  157.       }
  158.   }
  159.   return 0;
  160. }
  161. int
  162. bgp_interface_address_add (int command, struct zclient *zclient,
  163.    zebra_size_t length)
  164. {
  165.   struct connected *ifc;
  166.   ifc = zebra_interface_address_add_read (zclient->ibuf);
  167.   if (ifc == NULL)
  168.     return 0;
  169.   bgp_if_update (ifc->ifp);
  170.   if (if_is_up (ifc->ifp))
  171.     bgp_connected_add (ifc);
  172.   return 0;
  173. }
  174. int
  175. bgp_interface_address_delete (int command, struct zclient *zclient,
  176.       zebra_size_t length)
  177. {
  178.   struct connected *ifc;
  179.   ifc = zebra_interface_address_delete_read (zclient->ibuf);
  180.   if (ifc == NULL)
  181.     return 0;
  182.   bgp_if_update (ifc->ifp);
  183.   if (if_is_up (ifc->ifp))
  184.     bgp_connected_delete (ifc);
  185.   connected_free (ifc);
  186.   return 0;
  187. }
  188. /* Zebra route add and delete treatment. */
  189. int
  190. zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
  191. {
  192.   struct stream *s;
  193.   struct zapi_ipv4 api;
  194.   unsigned long ifindex;
  195.   struct in_addr nexthop;
  196.   struct prefix_ipv4 p;
  197.   s = zclient->ibuf;
  198.   ifindex = 0;
  199.   nexthop.s_addr = 0;
  200.   /* Type, flags, message. */
  201.   api.type = stream_getc (s);
  202.   api.flags = stream_getc (s);
  203.   api.message = stream_getc (s);
  204.   /* IPv4 prefix. */
  205.   memset (&p, 0, sizeof (struct prefix_ipv4));
  206.   p.family = AF_INET;
  207.   p.prefixlen = stream_getc (s);
  208.   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  209.   /* Nexthop, ifindex, distance, metric. */
  210.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  211.     {
  212.       api.nexthop_num = stream_getc (s);
  213.       nexthop.s_addr = stream_get_ipv4 (s);
  214.     }
  215.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  216.     {
  217.       api.ifindex_num = stream_getc (s);
  218.       ifindex = stream_getl (s);
  219.     }
  220.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  221.     api.distance = stream_getc (s);
  222.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  223.     api.metric = stream_getl (s);
  224.   else
  225.     api.metric = 0;
  226.   if (command == ZEBRA_IPV4_ROUTE_ADD)
  227.     bgp_redistribute_add ((struct prefix *)&p, &nexthop, api.metric, api.type);
  228.   else
  229.     bgp_redistribute_delete ((struct prefix *)&p, api.type);
  230.   return 0;
  231. }
  232. #ifdef HAVE_IPV6
  233. /* Zebra route add and delete treatment. */
  234. int
  235. zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
  236. {
  237.   struct stream *s;
  238.   struct zapi_ipv6 api;
  239.   unsigned long ifindex;
  240.   struct in6_addr nexthop;
  241.   struct prefix_ipv6 p;
  242.   s = zclient->ibuf;
  243.   ifindex = 0;
  244.   memset (&nexthop, 0, sizeof (struct in6_addr));
  245.   /* Type, flags, message. */
  246.   api.type = stream_getc (s);
  247.   api.flags = stream_getc (s);
  248.   api.message = stream_getc (s);
  249.   /* IPv6 prefix. */
  250.   memset (&p, 0, sizeof (struct prefix_ipv6));
  251.   p.family = AF_INET6;
  252.   p.prefixlen = stream_getc (s);
  253.   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  254.   /* Nexthop, ifindex, distance, metric. */
  255.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  256.     {
  257.       api.nexthop_num = stream_getc (s);
  258.       stream_get (&nexthop, s, 16);
  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.   else
  268.     api.distance = 0;
  269.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  270.     api.metric = stream_getl (s);
  271.   else
  272.     api.metric = 0;
  273.   /* Simply ignore link-local address. */
  274.   if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
  275.     return 0;
  276.   if (command == ZEBRA_IPV6_ROUTE_ADD)
  277.     bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);
  278.   else
  279.     bgp_redistribute_delete ((struct prefix *) &p, api.type);
  280.   
  281.   return 0;
  282. }
  283. #endif /* HAVE_IPV6 */
  284. struct interface *
  285. if_lookup_by_ipv4 (struct in_addr *addr)
  286. {
  287.   listnode ifnode;
  288.   listnode cnode;
  289.   struct interface *ifp;
  290.   struct connected *connected;
  291.   struct prefix_ipv4 p;
  292.   struct prefix *cp; 
  293.   
  294.   p.family = AF_INET;
  295.   p.prefix = *addr;
  296.   p.prefixlen = IPV4_MAX_BITLEN;
  297.   for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
  298.     {
  299.       ifp = getdata (ifnode);
  300.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  301. {
  302.   connected = getdata (cnode);
  303.   cp = connected->address;
  304.     
  305.   if (cp->family == AF_INET)
  306.     if (prefix_match (cp, (struct prefix *)&p))
  307.       return ifp;
  308. }
  309.     }
  310.   return NULL;
  311. }
  312. struct interface *
  313. if_lookup_by_ipv4_exact (struct in_addr *addr)
  314. {
  315.   listnode ifnode;
  316.   listnode cnode;
  317.   struct interface *ifp;
  318.   struct connected *connected;
  319.   struct prefix *cp; 
  320.   
  321.   for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
  322.     {
  323.       ifp = getdata (ifnode);
  324.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  325. {
  326.   connected = getdata (cnode);
  327.   cp = connected->address;
  328.     
  329.   if (cp->family == AF_INET)
  330.     if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
  331.       return ifp;
  332. }
  333.     }
  334.   return NULL;
  335. }
  336. #ifdef HAVE_IPV6
  337. struct interface *
  338. if_lookup_by_ipv6 (struct in6_addr *addr)
  339. {
  340.   listnode ifnode;
  341.   listnode cnode;
  342.   struct interface *ifp;
  343.   struct connected *connected;
  344.   struct prefix_ipv6 p;
  345.   struct prefix *cp; 
  346.   
  347.   p.family = AF_INET6;
  348.   p.prefix = *addr;
  349.   p.prefixlen = IPV6_MAX_BITLEN;
  350.   for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
  351.     {
  352.       ifp = getdata (ifnode);
  353.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  354. {
  355.   connected = getdata (cnode);
  356.   cp = connected->address;
  357.     
  358.   if (cp->family == AF_INET6)
  359.     if (prefix_match (cp, (struct prefix *)&p))
  360.       return ifp;
  361. }
  362.     }
  363.   return NULL;
  364. }
  365. struct interface *
  366. if_lookup_by_ipv6_exact (struct in6_addr *addr)
  367. {
  368.   listnode ifnode;
  369.   listnode cnode;
  370.   struct interface *ifp;
  371.   struct connected *connected;
  372.   struct prefix *cp; 
  373.   for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
  374.     {
  375.       ifp = getdata (ifnode);
  376.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  377. {
  378.   connected = getdata (cnode);
  379.   cp = connected->address;
  380.     
  381.   if (cp->family == AF_INET6)
  382.     if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
  383.       return ifp;
  384. }
  385.     }
  386.   return NULL;
  387. }
  388. int
  389. if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
  390. {
  391.   listnode cnode;
  392.   struct connected *connected;
  393.   struct prefix *cp; 
  394.   
  395.   for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  396.     {
  397.       connected = getdata (cnode);
  398.       cp = connected->address;
  399.     
  400.       if (cp->family == AF_INET6)
  401. if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
  402.   {
  403.     memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
  404.     return 1;
  405.   }
  406.     }
  407.   return 0;
  408. }
  409. int
  410. if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
  411. {
  412.   listnode cnode;
  413.   struct connected *connected;
  414.   struct prefix *cp; 
  415.   
  416.   for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  417.     {
  418.       connected = getdata (cnode);
  419.       cp = connected->address;
  420.     
  421.       if (cp->family == AF_INET6)
  422. if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
  423.   {
  424.     memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
  425.     return 1;
  426.   }
  427.     }
  428.   return 0;
  429. }
  430. #endif /* HAVE_IPV6 */
  431. int
  432. bgp_nexthop_set (union sockunion *local, union sockunion *remote, 
  433.  struct bgp_nexthop *nexthop, struct peer *peer)
  434. {
  435.   int ret = 0;
  436.   struct interface *ifp = NULL;
  437.   memset (nexthop, 0, sizeof (struct bgp_nexthop));
  438.   if (!local)
  439.     return -1;
  440.   if (!remote)
  441.     return -1;
  442.   if (local->sa.sa_family == AF_INET)
  443.     {
  444.       nexthop->v4 = local->sin.sin_addr;
  445.       ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
  446.     }
  447. #ifdef HAVE_IPV6
  448.   if (local->sa.sa_family == AF_INET6)
  449.     {
  450.       if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
  451. {
  452.   if (peer->ifname)
  453.     ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
  454. }
  455.       else
  456. ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
  457.     }
  458. #endif /* HAVE_IPV6 */
  459.   if (!ifp)
  460.     return -1;
  461.   nexthop->ifp = ifp;
  462.   /* IPv4 connection. */
  463.   if (local->sa.sa_family == AF_INET)
  464.     {
  465. #ifdef HAVE_IPV6
  466.       /* IPv6 nexthop*/
  467.       ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
  468.       /* There is no global nexthop. */
  469.       if (!ret)
  470. if_get_ipv6_local (ifp, &nexthop->v6_global);
  471.       else
  472. if_get_ipv6_local (ifp, &nexthop->v6_local);
  473. #endif /* HAVE_IPV6 */
  474.     }
  475. #ifdef HAVE_IPV6
  476.   /* IPv6 connection. */
  477.   if (local->sa.sa_family == AF_INET6)
  478.     {
  479.       struct interface *direct = NULL;
  480.       /* IPv4 nexthop.  I don't care about it. */
  481.       if (peer->local_id.s_addr)
  482. nexthop->v4 = peer->local_id;
  483.       /* Global address*/
  484.       if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
  485. {
  486.   memcpy (&nexthop->v6_global, &local->sin6.sin6_addr, 
  487.   IPV6_MAX_BYTELEN);
  488.   /* If directory connected set link-local address. */
  489.   direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
  490.   if (direct)
  491.     if_get_ipv6_local (ifp, &nexthop->v6_local);
  492. }
  493.       else
  494. /* Link-local address. */
  495. {
  496.   ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
  497.   /* If there is no global address.  Set link-local address as
  498.              global.  I know this break RFC specification... */
  499.   if (!ret)
  500.     memcpy (&nexthop->v6_global, &local->sin6.sin6_addr, 
  501.     IPV6_MAX_BYTELEN);
  502.   else
  503.     memcpy (&nexthop->v6_local, &local->sin6.sin6_addr, 
  504.     IPV6_MAX_BYTELEN);
  505. }
  506.     }
  507.   if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
  508.       if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
  509.     peer->shared_network = 1;
  510.   else
  511.     peer->shared_network = 0;
  512.   /* KAME stack specific treatment.  */
  513. #ifdef KAME
  514.   if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
  515.       && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
  516.     {
  517.       SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
  518.     }
  519.   if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
  520.       && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
  521.     {
  522.       SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
  523.     }
  524. #endif /* KAME */
  525. #endif /* HAVE_IPV6 */
  526.   return ret;
  527. }
  528. #ifdef HAVE_IPV6
  529. unsigned int
  530. bgp_ifindex_by_nexthop (struct in6_addr *addr)
  531. {
  532.   listnode ifnode;
  533.   listnode cnode;
  534.   struct interface *ifp;
  535.   struct connected *connected;
  536.   struct prefix_ipv6 p;
  537.   
  538.   p.family = AF_INET6;
  539.   p.prefix = *addr;
  540.   p.prefixlen = IPV6_MAX_BITLEN;
  541.   for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))
  542.     {
  543.       ifp = getdata (ifnode);
  544.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  545. {
  546.   struct prefix *cp; 
  547.   connected = getdata (cnode);
  548.   cp = connected->address;
  549.     
  550.   if (cp->family == AF_INET6)
  551.     {
  552.       if (prefix_match (cp, (struct prefix *)&p))
  553. return ifp->ifindex;
  554.     }
  555. }
  556.     }
  557.   return 0;
  558. }
  559. #endif /* HAVE_IPV6 */
  560. void
  561. bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp)
  562. {
  563.   int flags;
  564.   u_char distance;
  565.   struct peer *peer;
  566.   if (zclient->sock < 0)
  567.     return;
  568.   if (! zclient->redist[ZEBRA_ROUTE_BGP])
  569.     return;
  570.   flags = 0;
  571.   peer = info->peer;
  572.   if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
  573.     {
  574.       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
  575.       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
  576.     }
  577.   if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
  578.       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
  579.     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
  580.   if (p->family == AF_INET)
  581.     {
  582.       struct zapi_ipv4 api;
  583.       struct in_addr *nexthop;
  584.       api.flags = flags;
  585.       nexthop = &info->attr->nexthop;
  586.       api.type = ZEBRA_ROUTE_BGP;
  587.       api.message = 0;
  588.       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  589.       api.nexthop_num = 1;
  590.       api.nexthop = &nexthop;
  591.       api.ifindex_num = 0;
  592.       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  593.       api.metric = info->attr->med;
  594.       distance = bgp_distance_apply (p, info, bgp);
  595.       if (distance)
  596. {
  597.   SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
  598.   api.distance = distance;
  599. }
  600.       zapi_ipv4_add (zclient, (struct prefix_ipv4 *) p, &api);
  601.     }
  602. #ifdef HAVE_IPV6
  603.   /* We have to think about a IPv6 link-local address curse. */
  604.   if (p->family == AF_INET6)
  605.     {
  606.       unsigned int ifindex;
  607.       struct in6_addr *nexthop;
  608.       struct zapi_ipv6 api;
  609.       ifindex = 0;
  610.       nexthop = NULL;
  611.       /* Only global address nexthop exists. */
  612.       if (info->attr->mp_nexthop_len == 16)
  613. nexthop = &info->attr->mp_nexthop_global;
  614.       
  615.       /* If both global and link-local address present. */
  616.       if (info->attr->mp_nexthop_len == 32)
  617. {
  618.   /* Workaround for Cisco's nexthop bug.  */
  619.   if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->mp_nexthop_global)
  620.       && peer->su_remote->sa.sa_family == AF_INET6)
  621.     nexthop = &peer->su_remote->sin6.sin6_addr;
  622.   else
  623.     nexthop = &info->attr->mp_nexthop_local;
  624.   if (info->peer->nexthop.ifp)
  625.     ifindex = info->peer->nexthop.ifp->ifindex;
  626. }
  627.       if (nexthop == NULL)
  628. return;
  629.       if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
  630. {
  631.   if (info->peer->ifname)
  632.     ifindex = if_nametoindex (info->peer->ifname);
  633.   else if (info->peer->nexthop.ifp)
  634.     ifindex = info->peer->nexthop.ifp->ifindex;
  635. }
  636.       /* Make Zebra API structure. */
  637.       api.flags = flags;
  638.       api.type = ZEBRA_ROUTE_BGP;
  639.       api.message = 0;
  640.       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  641.       api.nexthop_num = 1;
  642.       api.nexthop = &nexthop;
  643.       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  644.       api.ifindex_num = 1;
  645.       api.ifindex = &ifindex;
  646.       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  647.       api.metric = info->attr->med;
  648.       zapi_ipv6_add (zclient, (struct prefix_ipv6 *) p, &api);
  649.     }
  650. #endif /* HAVE_IPV6 */
  651. }
  652. void
  653. bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info)
  654. {
  655.   int flags;
  656.   struct peer *peer;
  657.   if (zclient->sock < 0)
  658.     return;
  659.   if (! zclient->redist[ZEBRA_ROUTE_BGP])
  660.     return;
  661.   peer = info->peer;
  662.   flags = 0;
  663.   if (peer_sort (peer) == BGP_PEER_IBGP)
  664.     {
  665.       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
  666.       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
  667.     }
  668.   if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
  669.       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
  670.     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
  671.   if (p->family == AF_INET)
  672.     {
  673.       struct zapi_ipv4 api;
  674.       struct in_addr *nexthop;
  675.       api.flags = flags;
  676.       nexthop = &info->attr->nexthop;
  677.       api.type = ZEBRA_ROUTE_BGP;
  678.       api.message = 0;
  679.       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  680.       api.nexthop_num = 1;
  681.       api.nexthop = &nexthop;
  682.       api.ifindex_num = 0;
  683.       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  684.       api.metric = info->attr->med;
  685.       zapi_ipv4_delete (zclient, (struct prefix_ipv4 *) p, &api);
  686.     }
  687. #ifdef HAVE_IPV6
  688.   /* We have to think about a IPv6 link-local address curse. */
  689.   if (p->family == AF_INET6)
  690.     {
  691.       struct zapi_ipv6 api;
  692.       unsigned int ifindex;
  693.       struct in6_addr *nexthop;
  694.       ifindex = 0;
  695.       nexthop = NULL;
  696.       /* Only global address nexthop exists. */
  697.       if (info->attr->mp_nexthop_len == 16)
  698. nexthop = &info->attr->mp_nexthop_global;
  699.       /* If both global and link-local address present. */
  700.       if (info->attr->mp_nexthop_len == 32)
  701. {
  702.   nexthop = &info->attr->mp_nexthop_local;
  703.   if (info->peer->nexthop.ifp)
  704.     ifindex = info->peer->nexthop.ifp->ifindex;
  705. }
  706.       if (nexthop == NULL)
  707. return;
  708.       if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
  709. if (info->peer->ifname)
  710.   ifindex = if_nametoindex (info->peer->ifname);
  711.       api.flags = flags;
  712.       api.type = ZEBRA_ROUTE_BGP;
  713.       api.message = 0;
  714.       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  715.       api.nexthop_num = 1;
  716.       api.nexthop = &nexthop;
  717.       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  718.       api.ifindex_num = 1;
  719.       api.ifindex = &ifindex;
  720.       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  721.       api.metric = info->attr->med;
  722.       zapi_ipv6_delete (zclient, (struct prefix_ipv6 *) p, &api);
  723.     }
  724. #endif /* HAVE_IPV6 */
  725. }
  726. /* Other routes redistribution into BGP. */
  727. int
  728. bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
  729. {
  730.   /* Set flag to BGP instance. */
  731.   bgp->redist[afi][type] = 1;
  732.   /* Return if already redistribute flag is set. */
  733.   if (zclient->redist[type])
  734.     return CMD_WARNING;
  735.   zclient->redist[type] = 1;
  736.   /* Return if zebra connection is not established. */
  737.   if (zclient->sock < 0)
  738.     return CMD_WARNING;
  739.     
  740.   /* Send distribute add message to zebra. */
  741.   zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
  742.   return CMD_SUCCESS;
  743. }
  744. /* Redistribute with route-map specification.  */
  745. int
  746. bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type, char *name)
  747. {
  748.   if (bgp->rmap[afi][type].name
  749.       && (strcmp (bgp->rmap[afi][type].name, name) == 0))
  750.     return 0;
  751.   if (bgp->rmap[afi][type].name)
  752.     free (bgp->rmap[afi][type].name);
  753.   bgp->rmap[afi][type].name = strdup (name);
  754.   bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
  755.   return 1;
  756. }
  757. /* Redistribute with metric specification.  */
  758. int
  759. bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
  760.      u_int32_t metric)
  761. {
  762.   if (bgp->redist_metric_flag[afi][type]
  763.       && bgp->redist_metric[afi][type] == metric)
  764.     return 0;
  765.   bgp->redist_metric_flag[afi][type] = 1;
  766.   bgp->redist_metric[afi][type] = metric;
  767.   return 1;
  768. }
  769. /* Unset redistribution.  */
  770. int
  771. bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
  772. {
  773.   /* Unset flag from BGP instance. */
  774.   bgp->redist[afi][type] = 0;
  775.   /* Unset route-map. */
  776.   if (bgp->rmap[afi][type].name)
  777.     free (bgp->rmap[afi][type].name);
  778.   bgp->rmap[afi][type].name = NULL;
  779.   bgp->rmap[afi][type].map = NULL;
  780.   /* Unset metric. */
  781.   bgp->redist_metric_flag[afi][type] = 0;
  782.   bgp->redist_metric[afi][type] = 0;
  783.   /* Return if zebra connection is disabled. */
  784.   if (! zclient->redist[type])
  785.     return CMD_WARNING;
  786.   zclient->redist[type] = 0;
  787.   if (bgp->redist[AFI_IP][type] == 0 
  788.       && bgp->redist[AFI_IP6][type] == 0 
  789.       && zclient->sock >= 0)
  790.     /* Send distribute delete message to zebra. */
  791.     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
  792.   
  793.   /* Withdraw redistributed routes from current BGP's routing table. */
  794.   bgp_redistribute_withdraw (bgp, afi, type);
  795.   return CMD_SUCCESS;
  796. }
  797. /* Unset redistribution route-map configuration.  */
  798. int
  799. bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
  800. {
  801.   if (! bgp->rmap[afi][type].name)
  802.     return 0;
  803.   /* Unset route-map. */
  804.   free (bgp->rmap[afi][type].name);
  805.   bgp->rmap[afi][type].name = NULL;
  806.   bgp->rmap[afi][type].map = NULL;
  807.   return 1;
  808. }
  809. /* Unset redistribution metric configuration.  */
  810. int
  811. bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
  812. {
  813.   if (! bgp->redist_metric_flag[afi][type])
  814.     return 0;
  815.   /* Unset metric. */
  816.   bgp->redist_metric_flag[afi][type] = 0;
  817.   bgp->redist_metric[afi][type] = 0;
  818.   return 1;
  819. }
  820. void
  821. bgp_zclient_reset ()
  822. {
  823.   zclient_reset (zclient);
  824. }
  825. void
  826. bgp_zebra_init (int enable)
  827. {
  828.   /* Set default values. */
  829.   zclient = zclient_new ();
  830.   zclient_init (zclient, ZEBRA_ROUTE_BGP);
  831.   zclient->interface_add = bgp_interface_add;
  832.   zclient->interface_delete = bgp_interface_delete;
  833.   zclient->interface_address_add = bgp_interface_address_add;
  834.   zclient->interface_address_delete = bgp_interface_address_delete;
  835.   zclient->ipv4_route_add = zebra_read_ipv4;
  836.   zclient->ipv4_route_delete = zebra_read_ipv4;
  837.   zclient->interface_up = bgp_interface_up;
  838.   zclient->interface_down = bgp_interface_down;
  839. #ifdef HAVE_IPV6
  840.   zclient->ipv6_route_add = zebra_read_ipv6;
  841.   zclient->ipv6_route_delete = zebra_read_ipv6;
  842. #endif /* HAVE_IPV6 */
  843.   /* Interface related init. */
  844.   if_init ();
  845. }