File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgp_zebra.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:38 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

    1: /* zebra client
    2:    Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
    3: 
    4: This file is part of GNU Zebra.
    5: 
    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.
   10: 
   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.
   15: 
   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.  */
   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"
   39: #include "bgpd/bgp_debug.h"
   40: #include "bgpd/bgp_mpath.h"
   41: 
   42: /* All information about zebra. */
   43: struct zclient *zclient = NULL;
   44: struct in_addr router_id_zebra;
   45: 
   46: /* Growable buffer for nexthops sent to zebra */
   47: struct stream *bgp_nexthop_buf = NULL;
   48: 
   49: /* Router-id update message from zebra. */
   50: static int
   51: bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
   52: {
   53:   struct prefix router_id;
   54:   struct listnode *node, *nnode;
   55:   struct bgp *bgp;
   56: 
   57:   zebra_router_id_update_read(zclient->ibuf,&router_id);
   58: 
   59:   if (BGP_DEBUG(zebra, ZEBRA))
   60:     {
   61:       char buf[128];
   62:       prefix2str(&router_id, buf, sizeof(buf));
   63:       zlog_debug("Zebra rcvd: router id update %s", buf);
   64:     }
   65: 
   66:   router_id_zebra = router_id.u.prefix4;
   67: 
   68:   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
   69:     {
   70:       if (!bgp->router_id_static.s_addr)
   71:         bgp_router_id_set (bgp, &router_id.u.prefix4);
   72:     }
   73: 
   74:   return 0;
   75: }
   76: 
   77: /* Inteface addition message from zebra. */
   78: static int
   79: bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
   80: {
   81:   struct interface *ifp;
   82: 
   83:   ifp = zebra_interface_add_read (zclient->ibuf);
   84: 
   85:   if (BGP_DEBUG(zebra, ZEBRA) && ifp)
   86:     zlog_debug("Zebra rcvd: interface add %s", ifp->name);
   87: 
   88:   return 0;
   89: }
   90: 
   91: static int
   92: bgp_interface_delete (int command, struct zclient *zclient,
   93: 		      zebra_size_t length)
   94: {
   95:   struct stream *s;
   96:   struct interface *ifp;
   97: 
   98:   s = zclient->ibuf;
   99:   ifp = zebra_interface_state_read (s);
  100:   ifp->ifindex = IFINDEX_INTERNAL;
  101: 
  102:   if (BGP_DEBUG(zebra, ZEBRA))
  103:     zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
  104: 
  105:   return 0;
  106: }
  107: 
  108: static int
  109: bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
  110: {
  111:   struct stream *s;
  112:   struct interface *ifp;
  113:   struct connected *c;
  114:   struct listnode *node, *nnode;
  115: 
  116:   s = zclient->ibuf;
  117:   ifp = zebra_interface_state_read (s);
  118: 
  119:   if (! ifp)
  120:     return 0;
  121: 
  122:   if (BGP_DEBUG(zebra, ZEBRA))
  123:     zlog_debug("Zebra rcvd: interface %s up", ifp->name);
  124: 
  125:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
  126:     bgp_connected_add (c);
  127: 
  128:   return 0;
  129: }
  130: 
  131: static int
  132: bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
  133: {
  134:   struct stream *s;
  135:   struct interface *ifp;
  136:   struct connected *c;
  137:   struct listnode *node, *nnode;
  138: 
  139:   s = zclient->ibuf;
  140:   ifp = zebra_interface_state_read (s);
  141:   if (! ifp)
  142:     return 0;
  143: 
  144:   if (BGP_DEBUG(zebra, ZEBRA))
  145:     zlog_debug("Zebra rcvd: interface %s down", ifp->name);
  146: 
  147:   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
  148:     bgp_connected_delete (c);
  149: 
  150:   /* Fast external-failover (Currently IPv4 only) */
  151:   {
  152:     struct listnode *mnode;
  153:     struct bgp *bgp;
  154:     struct peer *peer;
  155:     struct interface *peer_if;
  156: 
  157:     for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
  158:       {
  159: 	if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
  160: 	  continue;
  161: 
  162: 	for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  163: 	  {
  164: 	    if (peer->ttl != 1)
  165: 	      continue;
  166: 
  167: 	    if (peer->su.sa.sa_family == AF_INET)
  168: 	      peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);
  169: 	    else
  170: 	      continue;
  171: 
  172: 	    if (ifp == peer_if)
  173: 	      BGP_EVENT_ADD (peer, BGP_Stop);
  174: 	  }
  175:       }
  176:   }
  177: 
  178:   return 0;
  179: }
  180: 
  181: static int
  182: bgp_interface_address_add (int command, struct zclient *zclient,
  183: 			   zebra_size_t length)
  184: {
  185:   struct connected *ifc;
  186: 
  187:   ifc = zebra_interface_address_read (command, zclient->ibuf);
  188: 
  189:   if (ifc == NULL)
  190:     return 0;
  191: 
  192:   if (BGP_DEBUG(zebra, ZEBRA))
  193:     {
  194:       char buf[128];
  195:       prefix2str(ifc->address, buf, sizeof(buf));
  196:       zlog_debug("Zebra rcvd: interface %s address add %s",
  197: 		 ifc->ifp->name, buf);
  198:     }
  199: 
  200:   if (if_is_operative (ifc->ifp))
  201:     bgp_connected_add (ifc);
  202: 
  203:   return 0;
  204: }
  205: 
  206: static int
  207: bgp_interface_address_delete (int command, struct zclient *zclient,
  208: 			      zebra_size_t length)
  209: {
  210:   struct connected *ifc;
  211: 
  212:   ifc = zebra_interface_address_read (command, zclient->ibuf);
  213: 
  214:   if (ifc == NULL)
  215:     return 0;
  216: 
  217:   if (BGP_DEBUG(zebra, ZEBRA))
  218:     {
  219:       char buf[128];
  220:       prefix2str(ifc->address, buf, sizeof(buf));
  221:       zlog_debug("Zebra rcvd: interface %s address delete %s",
  222: 		 ifc->ifp->name, buf);
  223:     }
  224: 
  225:   if (if_is_operative (ifc->ifp))
  226:     bgp_connected_delete (ifc);
  227: 
  228:   connected_free (ifc);
  229: 
  230:   return 0;
  231: }
  232: 
  233: /* Zebra route add and delete treatment. */
  234: static int
  235: zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
  236: {
  237:   struct stream *s;
  238:   struct zapi_ipv4 api;
  239:   struct in_addr nexthop;
  240:   struct prefix_ipv4 p;
  241: 
  242:   s = zclient->ibuf;
  243:   nexthop.s_addr = 0;
  244: 
  245:   /* Type, flags, message. */
  246:   api.type = stream_getc (s);
  247:   api.flags = stream_getc (s);
  248:   api.message = stream_getc (s);
  249: 
  250:   /* IPv4 prefix. */
  251:   memset (&p, 0, sizeof (struct prefix_ipv4));
  252:   p.family = AF_INET;
  253:   p.prefixlen = stream_getc (s);
  254:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  255: 
  256:   /* Nexthop, ifindex, distance, metric. */
  257:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  258:     {
  259:       api.nexthop_num = stream_getc (s);
  260:       nexthop.s_addr = stream_get_ipv4 (s);
  261:     }
  262:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  263:     {
  264:       api.ifindex_num = stream_getc (s);
  265:       stream_getl (s); /* ifindex, unused */
  266:     }
  267:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  268:     api.distance = stream_getc (s);
  269:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  270:     api.metric = stream_getl (s);
  271:   else
  272:     api.metric = 0;
  273: 
  274:   if (command == ZEBRA_IPV4_ROUTE_ADD)
  275:     {
  276:       if (BGP_DEBUG(zebra, ZEBRA))
  277: 	{
  278: 	  char buf[2][INET_ADDRSTRLEN];
  279: 	  zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
  280: 		     zebra_route_string(api.type),
  281: 		     inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
  282: 		     p.prefixlen,
  283: 		     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
  284: 		     api.metric);
  285: 	}
  286:       bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
  287: 			   api.metric, api.type);
  288:     }
  289:   else
  290:     {
  291:       if (BGP_DEBUG(zebra, ZEBRA))
  292: 	{
  293: 	  char buf[2][INET_ADDRSTRLEN];
  294: 	  zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
  295: 		     "nexthop %s metric %u",
  296: 		     zebra_route_string(api.type),
  297: 		     inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
  298: 		     p.prefixlen,
  299: 		     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
  300: 		     api.metric);
  301: 	}
  302:       bgp_redistribute_delete((struct prefix *)&p, api.type);
  303:     }
  304: 
  305:   return 0;
  306: }
  307: 
  308: #ifdef HAVE_IPV6
  309: /* Zebra route add and delete treatment. */
  310: static int
  311: zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
  312: {
  313:   struct stream *s;
  314:   struct zapi_ipv6 api;
  315:   struct in6_addr nexthop;
  316:   struct prefix_ipv6 p;
  317: 
  318:   s = zclient->ibuf;
  319:   memset (&nexthop, 0, sizeof (struct in6_addr));
  320: 
  321:   /* Type, flags, message. */
  322:   api.type = stream_getc (s);
  323:   api.flags = stream_getc (s);
  324:   api.message = stream_getc (s);
  325: 
  326:   /* IPv6 prefix. */
  327:   memset (&p, 0, sizeof (struct prefix_ipv6));
  328:   p.family = AF_INET6;
  329:   p.prefixlen = stream_getc (s);
  330:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  331: 
  332:   /* Nexthop, ifindex, distance, metric. */
  333:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  334:     {
  335:       api.nexthop_num = stream_getc (s);
  336:       stream_get (&nexthop, s, 16);
  337:     }
  338:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  339:     {
  340:       api.ifindex_num = stream_getc (s);
  341:       stream_getl (s); /* ifindex, unused */
  342:     }
  343:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  344:     api.distance = stream_getc (s);
  345:   else
  346:     api.distance = 0;
  347:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  348:     api.metric = stream_getl (s);
  349:   else
  350:     api.metric = 0;
  351: 
  352:   /* Simply ignore link-local address. */
  353:   if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
  354:     return 0;
  355: 
  356:   if (command == ZEBRA_IPV6_ROUTE_ADD)
  357:     {
  358:       if (BGP_DEBUG(zebra, ZEBRA))
  359: 	{
  360: 	  char buf[2][INET6_ADDRSTRLEN];
  361: 	  zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
  362: 		     zebra_route_string(api.type),
  363: 		     inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
  364: 		     p.prefixlen,
  365: 		     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
  366: 		     api.metric);
  367: 	}
  368:       bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
  369: 			    api.metric, api.type);
  370:     }
  371:   else
  372:     {
  373:       if (BGP_DEBUG(zebra, ZEBRA))
  374: 	{
  375: 	  char buf[2][INET6_ADDRSTRLEN];
  376: 	  zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
  377: 		     "nexthop %s metric %u",
  378: 		     zebra_route_string(api.type),
  379: 		     inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
  380: 		     p.prefixlen,
  381: 		     inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
  382: 		     api.metric);
  383: 	}
  384:       bgp_redistribute_delete ((struct prefix *) &p, api.type);
  385:     }
  386:   
  387:   return 0;
  388: }
  389: #endif /* HAVE_IPV6 */
  390: 
  391: struct interface *
  392: if_lookup_by_ipv4 (struct in_addr *addr)
  393: {
  394:   struct listnode *ifnode;
  395:   struct listnode *cnode;
  396:   struct interface *ifp;
  397:   struct connected *connected;
  398:   struct prefix_ipv4 p;
  399:   struct prefix *cp; 
  400:   
  401:   p.family = AF_INET;
  402:   p.prefix = *addr;
  403:   p.prefixlen = IPV4_MAX_BITLEN;
  404: 
  405:   for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
  406:     {
  407:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
  408: 	{
  409: 	  cp = connected->address;
  410: 	    
  411: 	  if (cp->family == AF_INET)
  412: 	    if (prefix_match (cp, (struct prefix *)&p))
  413: 	      return ifp;
  414: 	}
  415:     }
  416:   return NULL;
  417: }
  418: 
  419: struct interface *
  420: if_lookup_by_ipv4_exact (struct in_addr *addr)
  421: {
  422:   struct listnode *ifnode;
  423:   struct listnode *cnode;
  424:   struct interface *ifp;
  425:   struct connected *connected;
  426:   struct prefix *cp; 
  427:   
  428:   for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
  429:     {
  430:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
  431: 	{
  432: 	  cp = connected->address;
  433: 	    
  434: 	  if (cp->family == AF_INET)
  435: 	    if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
  436: 	      return ifp;
  437: 	}
  438:     }
  439:   return NULL;
  440: }
  441: 
  442: #ifdef HAVE_IPV6
  443: struct interface *
  444: if_lookup_by_ipv6 (struct in6_addr *addr)
  445: {
  446:   struct listnode *ifnode;
  447:   struct listnode *cnode;
  448:   struct interface *ifp;
  449:   struct connected *connected;
  450:   struct prefix_ipv6 p;
  451:   struct prefix *cp; 
  452:   
  453:   p.family = AF_INET6;
  454:   p.prefix = *addr;
  455:   p.prefixlen = IPV6_MAX_BITLEN;
  456: 
  457:   for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
  458:     {
  459:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
  460: 	{
  461: 	  cp = connected->address;
  462: 	    
  463: 	  if (cp->family == AF_INET6)
  464: 	    if (prefix_match (cp, (struct prefix *)&p))
  465: 	      return ifp;
  466: 	}
  467:     }
  468:   return NULL;
  469: }
  470: 
  471: struct interface *
  472: if_lookup_by_ipv6_exact (struct in6_addr *addr)
  473: {
  474:   struct listnode *ifnode;
  475:   struct listnode *cnode;
  476:   struct interface *ifp;
  477:   struct connected *connected;
  478:   struct prefix *cp; 
  479: 
  480:   for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
  481:     {
  482:       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
  483: 	{
  484: 	  cp = connected->address;
  485: 	    
  486: 	  if (cp->family == AF_INET6)
  487: 	    if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
  488: 	      return ifp;
  489: 	}
  490:     }
  491:   return NULL;
  492: }
  493: 
  494: static int
  495: if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
  496: {
  497:   struct listnode *cnode;
  498:   struct connected *connected;
  499:   struct prefix *cp; 
  500:   
  501:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
  502:     {
  503:       cp = connected->address;
  504: 	    
  505:       if (cp->family == AF_INET6)
  506: 	if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
  507: 	  {
  508: 	    memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
  509: 	    return 1;
  510: 	  }
  511:     }
  512:   return 0;
  513: }
  514: 
  515: static int
  516: if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
  517: {
  518:   struct listnode *cnode;
  519:   struct connected *connected;
  520:   struct prefix *cp; 
  521:   
  522:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
  523:     {
  524:       cp = connected->address;
  525: 	    
  526:       if (cp->family == AF_INET6)
  527: 	if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
  528: 	  {
  529: 	    memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
  530: 	    return 1;
  531: 	  }
  532:     }
  533:   return 0;
  534: }
  535: #endif /* HAVE_IPV6 */
  536: 
  537: int
  538: bgp_nexthop_set (union sockunion *local, union sockunion *remote, 
  539: 		 struct bgp_nexthop *nexthop, struct peer *peer)
  540: {
  541:   int ret = 0;
  542:   struct interface *ifp = NULL;
  543: 
  544:   memset (nexthop, 0, sizeof (struct bgp_nexthop));
  545: 
  546:   if (!local)
  547:     return -1;
  548:   if (!remote)
  549:     return -1;
  550: 
  551:   if (local->sa.sa_family == AF_INET)
  552:     {
  553:       nexthop->v4 = local->sin.sin_addr;
  554:       ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
  555:     }
  556: #ifdef HAVE_IPV6
  557:   if (local->sa.sa_family == AF_INET6)
  558:     {
  559:       if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
  560: 	{
  561: 	  if (peer->ifname)
  562: 	    ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
  563: 	}
  564:       else
  565: 	ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
  566:     }
  567: #endif /* HAVE_IPV6 */
  568: 
  569:   if (!ifp)
  570:     return -1;
  571: 
  572:   nexthop->ifp = ifp;
  573: 
  574:   /* IPv4 connection. */
  575:   if (local->sa.sa_family == AF_INET)
  576:     {
  577: #ifdef HAVE_IPV6
  578:       /* IPv6 nexthop*/
  579:       ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
  580: 
  581:       /* There is no global nexthop. */
  582:       if (!ret)
  583: 	if_get_ipv6_local (ifp, &nexthop->v6_global);
  584:       else
  585: 	if_get_ipv6_local (ifp, &nexthop->v6_local);
  586: #endif /* HAVE_IPV6 */
  587:     }
  588: 
  589: #ifdef HAVE_IPV6
  590:   /* IPv6 connection. */
  591:   if (local->sa.sa_family == AF_INET6)
  592:     {
  593:       struct interface *direct = NULL;
  594: 
  595:       /* IPv4 nexthop.  I don't care about it. */
  596:       if (peer->local_id.s_addr)
  597: 	nexthop->v4 = peer->local_id;
  598: 
  599:       /* Global address*/
  600:       if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
  601: 	{
  602: 	  memcpy (&nexthop->v6_global, &local->sin6.sin6_addr, 
  603: 		  IPV6_MAX_BYTELEN);
  604: 
  605: 	  /* If directory connected set link-local address. */
  606: 	  direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
  607: 	  if (direct)
  608: 	    if_get_ipv6_local (ifp, &nexthop->v6_local);
  609: 	}
  610:       else
  611: 	/* Link-local address. */
  612: 	{
  613: 	  ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
  614: 
  615: 	  /* If there is no global address.  Set link-local address as
  616:              global.  I know this break RFC specification... */
  617: 	  if (!ret)
  618: 	    memcpy (&nexthop->v6_global, &local->sin6.sin6_addr, 
  619: 		    IPV6_MAX_BYTELEN);
  620: 	  else
  621: 	    memcpy (&nexthop->v6_local, &local->sin6.sin6_addr, 
  622: 		    IPV6_MAX_BYTELEN);
  623: 	}
  624:     }
  625: 
  626:   if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
  627:       if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
  628:     peer->shared_network = 1;
  629:   else
  630:     peer->shared_network = 0;
  631: 
  632:   /* KAME stack specific treatment.  */
  633: #ifdef KAME
  634:   if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
  635:       && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
  636:     {
  637:       SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
  638:     }
  639:   if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
  640:       && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
  641:     {
  642:       SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
  643:     }
  644: #endif /* KAME */
  645: #endif /* HAVE_IPV6 */
  646:   return ret;
  647: }
  648: 
  649: void
  650: bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
  651: {
  652:   int flags;
  653:   u_char distance;
  654:   struct peer *peer;
  655:   struct bgp_info *mpinfo;
  656:   size_t oldsize, newsize;
  657: 
  658:   if (zclient->sock < 0)
  659:     return;
  660: 
  661:   if (! zclient->redist[ZEBRA_ROUTE_BGP])
  662:     return;
  663: 
  664:   flags = 0;
  665:   peer = info->peer;
  666: 
  667:   if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
  668:     {
  669:       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
  670:       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
  671:     }
  672: 
  673:   if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
  674:       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
  675:     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
  676: 
  677:   /* resize nexthop buffer size if necessary */
  678:   if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
  679:       (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
  680:     {
  681:       newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
  682:       newsize = stream_resize (bgp_nexthop_buf, newsize);
  683:       if (newsize == oldsize)
  684: 	{
  685: 	  zlog_err ("can't resize nexthop buffer");
  686: 	  return;
  687: 	}
  688:     }
  689: 
  690:   stream_reset (bgp_nexthop_buf);
  691: 
  692:   if (p->family == AF_INET)
  693:     {
  694:       struct zapi_ipv4 api;
  695:       struct in_addr *nexthop;
  696: 
  697:       api.flags = flags;
  698:       nexthop = &info->attr->nexthop;
  699:       stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
  700:       for (mpinfo = bgp_info_mpath_first (info); mpinfo;
  701: 	   mpinfo = bgp_info_mpath_next (mpinfo))
  702: 	{
  703: 	  nexthop = &mpinfo->attr->nexthop;
  704: 	  stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
  705: 	}
  706: 
  707:       api.type = ZEBRA_ROUTE_BGP;
  708:       api.message = 0;
  709:       api.safi = safi;
  710:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  711:       api.nexthop_num = 1 + bgp_info_mpath_count (info);
  712:       api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
  713:       api.ifindex_num = 0;
  714:       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  715:       api.metric = info->attr->med;
  716: 
  717:       distance = bgp_distance_apply (p, info, bgp);
  718: 
  719:       if (distance)
  720: 	{
  721: 	  SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
  722: 	  api.distance = distance;
  723: 	}
  724: 
  725:       if (BGP_DEBUG(zebra, ZEBRA))
  726: 	{
  727: 	  int i;
  728: 	  char buf[2][INET_ADDRSTRLEN];
  729: 	  zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
  730: 		     " count %d",
  731: 		     inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
  732: 		     p->prefixlen,
  733: 		     inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
  734: 		     api.metric, api.nexthop_num);
  735: 	  for (i = 1; i < api.nexthop_num; i++)
  736: 	    zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
  737: 		       i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
  738: 				    sizeof(buf[1])));
  739: 	}
  740: 
  741:       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, 
  742:                        (struct prefix_ipv4 *) p, &api);
  743:     }
  744: #ifdef HAVE_IPV6
  745:   /* We have to think about a IPv6 link-local address curse. */
  746:   if (p->family == AF_INET6)
  747:     {
  748:       unsigned int ifindex;
  749:       struct in6_addr *nexthop;
  750:       struct zapi_ipv6 api;
  751: 
  752:       ifindex = 0;
  753:       nexthop = NULL;
  754:       
  755:       assert (info->attr->extra);
  756:       
  757:       /* Only global address nexthop exists. */
  758:       if (info->attr->extra->mp_nexthop_len == 16)
  759: 	nexthop = &info->attr->extra->mp_nexthop_global;
  760:       
  761:       /* If both global and link-local address present. */
  762:       if (info->attr->extra->mp_nexthop_len == 32)
  763: 	{
  764: 	  /* Workaround for Cisco's nexthop bug.  */
  765: 	  if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
  766: 	      && peer->su_remote->sa.sa_family == AF_INET6)
  767: 	    nexthop = &peer->su_remote->sin6.sin6_addr;
  768: 	  else
  769: 	    nexthop = &info->attr->extra->mp_nexthop_local;
  770: 
  771: 	  if (info->peer->nexthop.ifp)
  772: 	    ifindex = info->peer->nexthop.ifp->ifindex;
  773: 	}
  774: 
  775:       if (nexthop == NULL)
  776: 	return;
  777: 
  778:       if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
  779: 	{
  780: 	  if (info->peer->ifname)
  781: 	    ifindex = if_nametoindex (info->peer->ifname);
  782: 	  else if (info->peer->nexthop.ifp)
  783: 	    ifindex = info->peer->nexthop.ifp->ifindex;
  784: 	}
  785: 
  786:       /* Make Zebra API structure. */
  787:       api.flags = flags;
  788:       api.type = ZEBRA_ROUTE_BGP;
  789:       api.message = 0;
  790:       api.safi = safi;
  791:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  792:       api.nexthop_num = 1;
  793:       api.nexthop = &nexthop;
  794:       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  795:       api.ifindex_num = 1;
  796:       api.ifindex = &ifindex;
  797:       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  798:       api.metric = info->attr->med;
  799: 
  800:       if (BGP_DEBUG(zebra, ZEBRA))
  801: 	{
  802: 	  char buf[2][INET6_ADDRSTRLEN];
  803: 	  zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
  804: 		     inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
  805: 		     p->prefixlen,
  806: 		     inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
  807: 		     api.metric);
  808: 	}
  809: 
  810:       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, 
  811:                        (struct prefix_ipv6 *) p, &api);
  812:     }
  813: #endif /* HAVE_IPV6 */
  814: }
  815: 
  816: void
  817: bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
  818: {
  819:   int flags;
  820:   struct peer *peer;
  821: 
  822:   if (zclient->sock < 0)
  823:     return;
  824: 
  825:   if (! zclient->redist[ZEBRA_ROUTE_BGP])
  826:     return;
  827: 
  828:   peer = info->peer;
  829:   flags = 0;
  830: 
  831:   if (peer->sort == BGP_PEER_IBGP)
  832:     {
  833:       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
  834:       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
  835:     }
  836: 
  837:   if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
  838:       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
  839:     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
  840: 
  841:   if (p->family == AF_INET)
  842:     {
  843:       struct zapi_ipv4 api;
  844:       struct in_addr *nexthop;
  845: 
  846:       api.flags = flags;
  847:       nexthop = &info->attr->nexthop;
  848: 
  849:       api.type = ZEBRA_ROUTE_BGP;
  850:       api.message = 0;
  851:       api.safi = safi;
  852:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  853:       api.nexthop_num = 1;
  854:       api.nexthop = &nexthop;
  855:       api.ifindex_num = 0;
  856:       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  857:       api.metric = info->attr->med;
  858: 
  859:       if (BGP_DEBUG(zebra, ZEBRA))
  860: 	{
  861: 	  char buf[2][INET_ADDRSTRLEN];
  862: 	  zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
  863: 		     inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
  864: 		     p->prefixlen,
  865: 		     inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
  866: 		     api.metric);
  867: 	}
  868: 
  869:       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, 
  870:                        (struct prefix_ipv4 *) p, &api);
  871:     }
  872: #ifdef HAVE_IPV6
  873:   /* We have to think about a IPv6 link-local address curse. */
  874:   if (p->family == AF_INET6)
  875:     {
  876:       struct zapi_ipv6 api;
  877:       unsigned int ifindex;
  878:       struct in6_addr *nexthop;
  879:       
  880:       assert (info->attr->extra);
  881:       
  882:       ifindex = 0;
  883:       nexthop = NULL;
  884: 
  885:       /* Only global address nexthop exists. */
  886:       if (info->attr->extra->mp_nexthop_len == 16)
  887: 	nexthop = &info->attr->extra->mp_nexthop_global;
  888: 
  889:       /* If both global and link-local address present. */
  890:       if (info->attr->extra->mp_nexthop_len == 32)
  891: 	{
  892: 	  nexthop = &info->attr->extra->mp_nexthop_local;
  893: 	  if (info->peer->nexthop.ifp)
  894: 	    ifindex = info->peer->nexthop.ifp->ifindex;
  895: 	}
  896: 
  897:       if (nexthop == NULL)
  898: 	return;
  899: 
  900:       if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
  901: 	if (info->peer->ifname)
  902: 	  ifindex = if_nametoindex (info->peer->ifname);
  903: 
  904:       api.flags = flags;
  905:       api.type = ZEBRA_ROUTE_BGP;
  906:       api.message = 0;
  907:       api.safi = safi;
  908:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  909:       api.nexthop_num = 1;
  910:       api.nexthop = &nexthop;
  911:       SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  912:       api.ifindex_num = 1;
  913:       api.ifindex = &ifindex;
  914:       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  915:       api.metric = info->attr->med;
  916: 
  917:       if (BGP_DEBUG(zebra, ZEBRA))
  918: 	{
  919: 	  char buf[2][INET6_ADDRSTRLEN];
  920: 	  zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
  921: 		     inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
  922: 		     p->prefixlen,
  923: 		     inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
  924: 		     api.metric);
  925: 	}
  926: 
  927:       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, 
  928:                        (struct prefix_ipv6 *) p, &api);
  929:     }
  930: #endif /* HAVE_IPV6 */
  931: }
  932: 
  933: /* Other routes redistribution into BGP. */
  934: int
  935: bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
  936: {
  937:   /* Set flag to BGP instance. */
  938:   bgp->redist[afi][type] = 1;
  939: 
  940:   /* Return if already redistribute flag is set. */
  941:   if (zclient->redist[type])
  942:     return CMD_WARNING;
  943: 
  944:   zclient->redist[type] = 1;
  945: 
  946:   /* Return if zebra connection is not established. */
  947:   if (zclient->sock < 0)
  948:     return CMD_WARNING;
  949: 
  950:   if (BGP_DEBUG(zebra, ZEBRA))
  951:     zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
  952:     
  953:   /* Send distribute add message to zebra. */
  954:   zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
  955: 
  956:   return CMD_SUCCESS;
  957: }
  958: 
  959: /* Redistribute with route-map specification.  */
  960: int
  961: bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type, 
  962:                            const char *name)
  963: {
  964:   if (bgp->rmap[afi][type].name
  965:       && (strcmp (bgp->rmap[afi][type].name, name) == 0))
  966:     return 0;
  967: 
  968:   if (bgp->rmap[afi][type].name)
  969:     free (bgp->rmap[afi][type].name);
  970:   bgp->rmap[afi][type].name = strdup (name);
  971:   bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
  972: 
  973:   return 1;
  974: }
  975: 
  976: /* Redistribute with metric specification.  */
  977: int
  978: bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
  979: 			     u_int32_t metric)
  980: {
  981:   if (bgp->redist_metric_flag[afi][type]
  982:       && bgp->redist_metric[afi][type] == metric)
  983:     return 0;
  984: 
  985:   bgp->redist_metric_flag[afi][type] = 1;
  986:   bgp->redist_metric[afi][type] = metric;
  987: 
  988:   return 1;
  989: }
  990: 
  991: /* Unset redistribution.  */
  992: int
  993: bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
  994: {
  995:   /* Unset flag from BGP instance. */
  996:   bgp->redist[afi][type] = 0;
  997: 
  998:   /* Unset route-map. */
  999:   if (bgp->rmap[afi][type].name)
 1000:     free (bgp->rmap[afi][type].name);
 1001:   bgp->rmap[afi][type].name = NULL;
 1002:   bgp->rmap[afi][type].map = NULL;
 1003: 
 1004:   /* Unset metric. */
 1005:   bgp->redist_metric_flag[afi][type] = 0;
 1006:   bgp->redist_metric[afi][type] = 0;
 1007: 
 1008:   /* Return if zebra connection is disabled. */
 1009:   if (! zclient->redist[type])
 1010:     return CMD_WARNING;
 1011:   zclient->redist[type] = 0;
 1012: 
 1013:   if (bgp->redist[AFI_IP][type] == 0 
 1014:       && bgp->redist[AFI_IP6][type] == 0 
 1015:       && zclient->sock >= 0)
 1016:     {
 1017:       /* Send distribute delete message to zebra. */
 1018:       if (BGP_DEBUG(zebra, ZEBRA))
 1019: 	zlog_debug("Zebra send: redistribute delete %s",
 1020: 		   zebra_route_string(type));
 1021:       zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
 1022:     }
 1023:   
 1024:   /* Withdraw redistributed routes from current BGP's routing table. */
 1025:   bgp_redistribute_withdraw (bgp, afi, type);
 1026: 
 1027:   return CMD_SUCCESS;
 1028: }
 1029: 
 1030: /* Unset redistribution route-map configuration.  */
 1031: int
 1032: bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
 1033: {
 1034:   if (! bgp->rmap[afi][type].name)
 1035:     return 0;
 1036: 
 1037:   /* Unset route-map. */
 1038:   free (bgp->rmap[afi][type].name);
 1039:   bgp->rmap[afi][type].name = NULL;
 1040:   bgp->rmap[afi][type].map = NULL;
 1041: 
 1042:   return 1;
 1043: }
 1044: 
 1045: /* Unset redistribution metric configuration.  */
 1046: int
 1047: bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
 1048: {
 1049:   if (! bgp->redist_metric_flag[afi][type])
 1050:     return 0;
 1051: 
 1052:   /* Unset metric. */
 1053:   bgp->redist_metric_flag[afi][type] = 0;
 1054:   bgp->redist_metric[afi][type] = 0;
 1055: 
 1056:   return 1;
 1057: }
 1058: 
 1059: void
 1060: bgp_zclient_reset (void)
 1061: {
 1062:   zclient_reset (zclient);
 1063: }
 1064: 
 1065: void
 1066: bgp_zebra_init (void)
 1067: {
 1068:   /* Set default values. */
 1069:   zclient = zclient_new ();
 1070:   zclient_init (zclient, ZEBRA_ROUTE_BGP);
 1071:   zclient->router_id_update = bgp_router_id_update;
 1072:   zclient->interface_add = bgp_interface_add;
 1073:   zclient->interface_delete = bgp_interface_delete;
 1074:   zclient->interface_address_add = bgp_interface_address_add;
 1075:   zclient->interface_address_delete = bgp_interface_address_delete;
 1076:   zclient->ipv4_route_add = zebra_read_ipv4;
 1077:   zclient->ipv4_route_delete = zebra_read_ipv4;
 1078:   zclient->interface_up = bgp_interface_up;
 1079:   zclient->interface_down = bgp_interface_down;
 1080: #ifdef HAVE_IPV6
 1081:   zclient->ipv6_route_add = zebra_read_ipv6;
 1082:   zclient->ipv6_route_delete = zebra_read_ipv6;
 1083: #endif /* HAVE_IPV6 */
 1084: 
 1085:   /* Interface related init. */
 1086:   if_init ();
 1087: 
 1088:   bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
 1089: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>