Annotation of embedaddon/quagga/bgpd/bgp_zebra.c, revision 1.1.1.1

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

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