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

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"
1.1.1.2 ! misho      40: #include "bgpd/bgp_mpath.h"
1.1       misho      41: 
                     42: /* All information about zebra. */
                     43: struct zclient *zclient = NULL;
                     44: struct in_addr router_id_zebra;
                     45: 
1.1.1.2 ! misho      46: /* Growable buffer for nexthops sent to zebra */
        !            47: struct stream *bgp_nexthop_buf = NULL;
        !            48: 
1.1       misho      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);
1.1.1.2 ! misho     265:       stream_getl (s); /* ifindex, unused */
1.1       misho     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:        }
1.1.1.2 ! misho     286:       bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
        !           287:                           api.metric, api.type);
1.1       misho     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);
1.1.1.2 ! misho     341:       stream_getl (s); /* ifindex, unused */
1.1       misho     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:        {
1.1.1.2 ! misho     360:          char buf[2][INET6_ADDRSTRLEN];
        !           361:          zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
1.1       misho     362:                     zebra_route_string(api.type),
1.1.1.2 ! misho     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);
1.1       misho     367:        }
1.1.1.2 ! misho     368:       bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
        !           369:                            api.metric, api.type);
1.1       misho     370:     }
                    371:   else
                    372:     {
                    373:       if (BGP_DEBUG(zebra, ZEBRA))
                    374:        {
1.1.1.2 ! misho     375:          char buf[2][INET6_ADDRSTRLEN];
        !           376:          zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
        !           377:                     "nexthop %s metric %u",
1.1       misho     378:                     zebra_route_string(api.type),
1.1.1.2 ! misho     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);
1.1       misho     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
1.1.1.2 ! misho     650: bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
1.1       misho     651: {
                    652:   int flags;
                    653:   u_char distance;
                    654:   struct peer *peer;
1.1.1.2 ! misho     655:   struct bgp_info *mpinfo;
        !           656:   size_t oldsize, newsize;
1.1       misho     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 (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
                    668:     {
                    669:       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
                    670:       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
                    671:     }
                    672: 
                    673:   if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
                    674:       || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
                    675:     SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
                    676: 
1.1.1.2 ! misho     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: 
1.1       misho     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;
1.1.1.2 ! misho     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:        }
1.1       misho     706: 
                    707:       api.type = ZEBRA_ROUTE_BGP;
                    708:       api.message = 0;
1.1.1.2 ! misho     709:       api.safi = safi;
1.1       misho     710:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
1.1.1.2 ! misho     711:       api.nexthop_num = 1 + bgp_info_mpath_count (info);
        !           712:       api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
1.1       misho     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:        {
1.1.1.2 ! misho     727:          int i;
1.1       misho     728:          char buf[2][INET_ADDRSTRLEN];
1.1.1.2 ! misho     729:          zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
        !           730:                     " count %d",
1.1       misho     731:                     inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
                    732:                     p->prefixlen,
1.1.1.2 ! misho     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])));
1.1       misho     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;
1.1.1.2 ! misho     790:       api.safi = safi;
1.1       misho     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
1.1.1.2 ! misho     817: bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
1.1       misho     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 (peer) == BGP_PEER_IBGP)
                    832:     {
                    833:       SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
                    834:       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
                    835:     }
                    836: 
                    837:   if ((peer_sort (peer) == 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;
1.1.1.2 ! misho     851:       api.safi = safi;
1.1       misho     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;
1.1.1.2 ! misho     907:       api.safi = safi;
1.1       misho     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 ();
1.1.1.2 ! misho    1087: 
        !          1088:   bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
1.1       misho    1089: }

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