Annotation of embedaddon/quagga/zebra/zserv.c, revision 1.1.1.2

1.1       misho       1: /* Zebra daemon server routine.
                      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: 
                     22: #include <zebra.h>
                     23: 
                     24: #include "prefix.h"
                     25: #include "command.h"
                     26: #include "if.h"
                     27: #include "thread.h"
                     28: #include "stream.h"
                     29: #include "memory.h"
                     30: #include "table.h"
                     31: #include "rib.h"
                     32: #include "network.h"
                     33: #include "sockunion.h"
                     34: #include "log.h"
                     35: #include "zclient.h"
                     36: #include "privs.h"
                     37: #include "network.h"
                     38: #include "buffer.h"
                     39: 
                     40: #include "zebra/zserv.h"
                     41: #include "zebra/router-id.h"
                     42: #include "zebra/redistribute.h"
                     43: #include "zebra/debug.h"
                     44: #include "zebra/ipforward.h"
                     45: 
                     46: /* Event list of zebra. */
                     47: enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
                     48: 
                     49: extern struct zebra_t zebrad;
                     50: 
                     51: static void zebra_event (enum event event, int sock, struct zserv *client);
                     52: 
                     53: extern struct zebra_privs_t zserv_privs;
                     54: 
                     55: static void zebra_client_close (struct zserv *client);
                     56: 
                     57: static int
                     58: zserv_delayed_close(struct thread *thread)
                     59: {
                     60:   struct zserv *client = THREAD_ARG(thread);
                     61: 
                     62:   client->t_suicide = NULL;
                     63:   zebra_client_close(client);
                     64:   return 0;
                     65: }
                     66: 
1.1.1.2 ! misho      67: /* When client connects, it sends hello message
        !            68:  * with promise to send zebra routes of specific type.
        !            69:  * Zebra stores a socket fd of the client into
        !            70:  * this array. And use it to clean up routes that
        !            71:  * client didn't remove for some reasons after closing
        !            72:  * connection.
        !            73:  */
        !            74: static int route_type_oaths[ZEBRA_ROUTE_MAX];
        !            75: 
1.1       misho      76: static int
                     77: zserv_flush_data(struct thread *thread)
                     78: {
                     79:   struct zserv *client = THREAD_ARG(thread);
                     80: 
                     81:   client->t_write = NULL;
                     82:   if (client->t_suicide)
                     83:     {
                     84:       zebra_client_close(client);
                     85:       return -1;
                     86:     }
                     87:   switch (buffer_flush_available(client->wb, client->sock))
                     88:     {
                     89:     case BUFFER_ERROR:
                     90:       zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
                     91:                "closing", __func__, client->sock);
                     92:       zebra_client_close(client);
                     93:       break;
                     94:     case BUFFER_PENDING:
                     95:       client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
                     96:                                         client, client->sock);
                     97:       break;
                     98:     case BUFFER_EMPTY:
                     99:       break;
                    100:     }
                    101:   return 0;
                    102: }
                    103: 
                    104: static int
                    105: zebra_server_send_message(struct zserv *client)
                    106: {
                    107:   if (client->t_suicide)
                    108:     return -1;
                    109:   switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
                    110:                       stream_get_endp(client->obuf)))
                    111:     {
                    112:     case BUFFER_ERROR:
                    113:       zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
                    114:                 __func__, client->sock);
                    115:       /* Schedule a delayed close since many of the functions that call this
                    116:          one do not check the return code.  They do not allow for the
                    117:         possibility that an I/O error may have caused the client to be
                    118:         deleted. */
                    119:       client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
                    120:                                           client, 0);
                    121:       return -1;
                    122:     case BUFFER_EMPTY:
                    123:       THREAD_OFF(client->t_write);
                    124:       break;
                    125:     case BUFFER_PENDING:
                    126:       THREAD_WRITE_ON(zebrad.master, client->t_write,
                    127:                      zserv_flush_data, client, client->sock);
                    128:       break;
                    129:     }
                    130:   return 0;
                    131: }
                    132: 
                    133: static void
                    134: zserv_create_header (struct stream *s, uint16_t cmd)
                    135: {
                    136:   /* length placeholder, caller can update */
                    137:   stream_putw (s, ZEBRA_HEADER_SIZE);
                    138:   stream_putc (s, ZEBRA_HEADER_MARKER);
                    139:   stream_putc (s, ZSERV_VERSION);
                    140:   stream_putw (s, cmd);
                    141: }
                    142: 
1.1.1.2 ! misho     143: static void
        !           144: zserv_encode_interface (struct stream *s, struct interface *ifp)
        !           145: {
        !           146:   /* Interface information. */
        !           147:   stream_put (s, ifp->name, INTERFACE_NAMSIZ);
        !           148:   stream_putl (s, ifp->ifindex);
        !           149:   stream_putc (s, ifp->status);
        !           150:   stream_putq (s, ifp->flags);
        !           151:   stream_putl (s, ifp->metric);
        !           152:   stream_putl (s, ifp->mtu);
        !           153:   stream_putl (s, ifp->mtu6);
        !           154:   stream_putl (s, ifp->bandwidth);
        !           155: #ifdef HAVE_STRUCT_SOCKADDR_DL
        !           156:   stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
        !           157: #else
        !           158:   stream_putl (s, ifp->hw_addr_len);
        !           159:   if (ifp->hw_addr_len)
        !           160:     stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
        !           161: #endif /* HAVE_STRUCT_SOCKADDR_DL */
        !           162: 
        !           163:   /* Write packet size. */
        !           164:   stream_putw_at (s, 0, stream_get_endp (s));
        !           165: }
        !           166: 
1.1       misho     167: /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
                    168: /*
                    169:  * This function is called in the following situations:
                    170:  * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
                    171:  *   from the client.
                    172:  * - at startup, when zebra figures out the available interfaces
                    173:  * - when an interface is added (where support for
                    174:  *   RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
                    175:  *   an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
                    176:  *   received)
                    177:  */
                    178: int
                    179: zsend_interface_add (struct zserv *client, struct interface *ifp)
                    180: {
                    181:   struct stream *s;
                    182: 
                    183:   /* Check this client need interface information. */
                    184:   if (! client->ifinfo)
                    185:     return 0;
                    186: 
                    187:   s = client->obuf;
                    188:   stream_reset (s);
                    189: 
                    190:   zserv_create_header (s, ZEBRA_INTERFACE_ADD);
1.1.1.2 ! misho     191:   zserv_encode_interface (s, ifp);
1.1       misho     192: 
                    193:   return zebra_server_send_message(client);
                    194: }
                    195: 
                    196: /* Interface deletion from zebra daemon. */
                    197: int
                    198: zsend_interface_delete (struct zserv *client, struct interface *ifp)
                    199: {
                    200:   struct stream *s;
                    201: 
                    202:   /* Check this client need interface information. */
                    203:   if (! client->ifinfo)
                    204:     return 0;
                    205: 
                    206:   s = client->obuf;
                    207:   stream_reset (s);
                    208: 
1.1.1.2 ! misho     209:   zserv_create_header (s, ZEBRA_INTERFACE_DELETE);
        !           210:   zserv_encode_interface (s, ifp);
1.1       misho     211: 
                    212:   return zebra_server_send_message (client);
                    213: }
                    214: 
                    215: /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
                    216:  * ZEBRA_INTERFACE_ADDRESS_DELETE to the client. 
                    217:  *
                    218:  * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
                    219:  * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
                    220:  *   from the client, after the ZEBRA_INTERFACE_ADD has been
                    221:  *   sent from zebra to the client
                    222:  * - redistribute new address info to all clients in the following situations
                    223:  *    - at startup, when zebra figures out the available interfaces
                    224:  *    - when an interface is added (where support for
                    225:  *      RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
                    226:  *      an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
                    227:  *      received)
                    228:  *    - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
                    229:  *      and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
                    230:  *    - when an RTM_NEWADDR message is received from the kernel,
                    231:  * 
                    232:  * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE: 
                    233:  *
                    234:  *                   zsend_interface_address(DELETE)
                    235:  *                           ^                         
                    236:  *                           |                        
                    237:  *          zebra_interface_address_delete_update    
                    238:  *             ^                        ^      ^
                    239:  *             |                        |      if_delete_update
                    240:  *             |                        |
                    241:  *         ip_address_uninstall        connected_delete_ipv4
                    242:  *         [ipv6_addresss_uninstall]   [connected_delete_ipv6]
                    243:  *             ^                        ^
                    244:  *             |                        |
                    245:  *             |                  RTM_NEWADDR on routing/netlink socket
                    246:  *             |
                    247:  *         vty commands:
                    248:  *     "no ip address A.B.C.D/M [label LINE]"
                    249:  *     "no ip address A.B.C.D/M secondary"
                    250:  *     ["no ipv6 address X:X::X:X/M"]
                    251:  *
                    252:  */
                    253: int
                    254: zsend_interface_address (int cmd, struct zserv *client, 
                    255:                          struct interface *ifp, struct connected *ifc)
                    256: {
                    257:   int blen;
                    258:   struct stream *s;
                    259:   struct prefix *p;
                    260: 
                    261:   /* Check this client need interface information. */
                    262:   if (! client->ifinfo)
                    263:     return 0;
                    264: 
                    265:   s = client->obuf;
                    266:   stream_reset (s);
                    267:   
                    268:   zserv_create_header (s, cmd);
                    269:   stream_putl (s, ifp->ifindex);
                    270: 
                    271:   /* Interface address flag. */
                    272:   stream_putc (s, ifc->flags);
                    273: 
                    274:   /* Prefix information. */
                    275:   p = ifc->address;
                    276:   stream_putc (s, p->family);
                    277:   blen = prefix_blen (p);
                    278:   stream_put (s, &p->u.prefix, blen);
                    279: 
                    280:   /* 
                    281:    * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
                    282:    * but zebra_interface_address_delete_read() in the gnu version 
                    283:    * expects to find it
                    284:    */
                    285:   stream_putc (s, p->prefixlen);
                    286: 
                    287:   /* Destination. */
                    288:   p = ifc->destination;
                    289:   if (p)
                    290:     stream_put (s, &p->u.prefix, blen);
                    291:   else
                    292:     stream_put (s, NULL, blen);
                    293: 
                    294:   /* Write packet size. */
                    295:   stream_putw_at (s, 0, stream_get_endp (s));
                    296: 
                    297:   return zebra_server_send_message(client);
                    298: }
                    299: 
                    300: /*
                    301:  * The cmd passed to zsend_interface_update  may be ZEBRA_INTERFACE_UP or
                    302:  * ZEBRA_INTERFACE_DOWN.
                    303:  *
                    304:  * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
                    305:  * the clients in one of 2 situations:
                    306:  *   - an if_up is detected e.g., as a result of an RTM_IFINFO message
                    307:  *   - a vty command modifying the bandwidth of an interface is received.
                    308:  * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
                    309:  */
                    310: int
                    311: zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
                    312: {
                    313:   struct stream *s;
                    314: 
                    315:   /* Check this client need interface information. */
                    316:   if (! client->ifinfo)
                    317:     return 0;
                    318: 
                    319:   s = client->obuf;
                    320:   stream_reset (s);
                    321: 
                    322:   zserv_create_header (s, cmd);
1.1.1.2 ! misho     323:   zserv_encode_interface (s, ifp);
1.1       misho     324: 
                    325:   return zebra_server_send_message(client);
                    326: }
                    327: 
                    328: /*
                    329:  * The zebra server sends the clients  a ZEBRA_IPV4_ROUTE_ADD or a
                    330:  * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
                    331:  * situations:
                    332:  * - when the client starts up, and requests default information
                    333:  *   by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
                    334:  * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
                    335:  *   ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
                    336:  * - when the zebra server redistributes routes after it updates its rib
                    337:  *
                    338:  * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
                    339:  * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
                    340:  * - a "ip route"  or "ipv6 route" vty command is issued, a prefix is
                    341:  * - deleted from zebra's rib, and this info
                    342:  *   has to be redistributed to the clients 
                    343:  * 
                    344:  * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
                    345:  * zebra server when the client wants to tell the zebra server to add a
                    346:  * route to the kernel (zapi_ipv4_add etc. ).  Since it's essentially the
                    347:  * same message being sent back and forth, this function and
                    348:  * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
                    349:  * duplication.
                    350:  */
                    351: int
                    352: zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
                    353:                        struct rib *rib)
                    354: {
                    355:   int psize;
                    356:   struct stream *s;
                    357:   struct nexthop *nexthop;
                    358:   unsigned long nhnummark = 0, messmark = 0;
                    359:   int nhnum = 0;
                    360:   u_char zapi_flags = 0;
                    361:   
                    362:   s = client->obuf;
                    363:   stream_reset (s);
                    364:   
                    365:   zserv_create_header (s, cmd);
                    366:   
                    367:   /* Put type and nexthop. */
                    368:   stream_putc (s, rib->type);
                    369:   stream_putc (s, rib->flags);
                    370:   
                    371:   /* marker for message flags field */
                    372:   messmark = stream_get_endp (s);
                    373:   stream_putc (s, 0);
                    374: 
                    375:   /* Prefix. */
                    376:   psize = PSIZE (p->prefixlen);
                    377:   stream_putc (s, p->prefixlen);
                    378:   stream_write (s, (u_char *) & p->u.prefix, psize);
                    379: 
                    380:   /* 
                    381:    * XXX The message format sent by zebra below does not match the format
                    382:    * of the corresponding message expected by the zebra server
                    383:    * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
                    384:    * (is there a bug on the client side if more than one segment is sent?)
                    385:    * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX 
                    386:    * is hard-coded.
                    387:    */
                    388:   /* Nexthop */
                    389:   
                    390:   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                    391:     {
                    392:       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                    393:         {
                    394:           SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
                    395:           SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
                    396:           
                    397:           if (nhnummark == 0)
                    398:             {
                    399:               nhnummark = stream_get_endp (s);
                    400:               stream_putc (s, 1); /* placeholder */
                    401:             }
                    402:           
                    403:           nhnum++;
                    404: 
                    405:           switch(nexthop->type) 
                    406:             {
                    407:               case NEXTHOP_TYPE_IPV4:
                    408:               case NEXTHOP_TYPE_IPV4_IFINDEX:
                    409:                 stream_put_in_addr (s, &nexthop->gate.ipv4);
                    410:                 break;
                    411: #ifdef HAVE_IPV6
                    412:               case NEXTHOP_TYPE_IPV6:
                    413:               case NEXTHOP_TYPE_IPV6_IFINDEX:
                    414:               case NEXTHOP_TYPE_IPV6_IFNAME:
                    415:                 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
                    416:                 break;
                    417: #endif
                    418:               default:
                    419:                 if (cmd == ZEBRA_IPV4_ROUTE_ADD 
                    420:                     || cmd == ZEBRA_IPV4_ROUTE_DELETE)
                    421:                   {
                    422:                     struct in_addr empty;
                    423:                     memset (&empty, 0, sizeof (struct in_addr));
                    424:                     stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
                    425:                   }
                    426:                 else
                    427:                   {
                    428:                     struct in6_addr empty;
                    429:                     memset (&empty, 0, sizeof (struct in6_addr));
                    430:                     stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
                    431:                   }
                    432:               }
                    433: 
                    434:           /* Interface index. */
                    435:           stream_putc (s, 1);
                    436:           stream_putl (s, nexthop->ifindex);
                    437: 
                    438:           break;
                    439:         }
                    440:     }
                    441: 
                    442:   /* Metric */
                    443:   if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
                    444:     {
                    445:       SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
                    446:       stream_putc (s, rib->distance);
                    447:       SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
                    448:       stream_putl (s, rib->metric);
                    449:     }
                    450:   
                    451:   /* write real message flags value */
                    452:   stream_putc_at (s, messmark, zapi_flags);
                    453:   
                    454:   /* Write next-hop number */
                    455:   if (nhnummark)
                    456:     stream_putc_at (s, nhnummark, nhnum);
                    457:   
                    458:   /* Write packet size. */
                    459:   stream_putw_at (s, 0, stream_get_endp (s));
                    460: 
                    461:   return zebra_server_send_message(client);
                    462: }
                    463: 
                    464: #ifdef HAVE_IPV6
                    465: static int
                    466: zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
                    467: {
                    468:   struct stream *s;
                    469:   struct rib *rib;
                    470:   unsigned long nump;
                    471:   u_char num;
                    472:   struct nexthop *nexthop;
                    473: 
                    474:   /* Lookup nexthop. */
                    475:   rib = rib_match_ipv6 (addr);
                    476: 
                    477:   /* Get output stream. */
                    478:   s = client->obuf;
                    479:   stream_reset (s);
                    480: 
                    481:   /* Fill in result. */
                    482:   zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
                    483:   stream_put (s, &addr, 16);
                    484: 
                    485:   if (rib)
                    486:     {
                    487:       stream_putl (s, rib->metric);
                    488:       num = 0;
                    489:       nump = stream_get_endp(s);
                    490:       stream_putc (s, 0);
                    491:       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                    492:        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                    493:          {
                    494:            stream_putc (s, nexthop->type);
                    495:            switch (nexthop->type)
                    496:              {
                    497:              case ZEBRA_NEXTHOP_IPV6:
                    498:                stream_put (s, &nexthop->gate.ipv6, 16);
                    499:                break;
                    500:              case ZEBRA_NEXTHOP_IPV6_IFINDEX:
                    501:              case ZEBRA_NEXTHOP_IPV6_IFNAME:
                    502:                stream_put (s, &nexthop->gate.ipv6, 16);
                    503:                stream_putl (s, nexthop->ifindex);
                    504:                break;
                    505:              case ZEBRA_NEXTHOP_IFINDEX:
                    506:              case ZEBRA_NEXTHOP_IFNAME:
                    507:                stream_putl (s, nexthop->ifindex);
                    508:                break;
                    509:              default:
                    510:                 /* do nothing */
                    511:                break;
                    512:              }
                    513:            num++;
                    514:          }
                    515:       stream_putc_at (s, nump, num);
                    516:     }
                    517:   else
                    518:     {
                    519:       stream_putl (s, 0);
                    520:       stream_putc (s, 0);
                    521:     }
                    522: 
                    523:   stream_putw_at (s, 0, stream_get_endp (s));
                    524:   
                    525:   return zebra_server_send_message(client);
                    526: }
                    527: #endif /* HAVE_IPV6 */
                    528: 
                    529: static int
                    530: zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
                    531: {
                    532:   struct stream *s;
                    533:   struct rib *rib;
                    534:   unsigned long nump;
                    535:   u_char num;
                    536:   struct nexthop *nexthop;
                    537: 
                    538:   /* Lookup nexthop. */
                    539:   rib = rib_match_ipv4 (addr);
                    540: 
                    541:   /* Get output stream. */
                    542:   s = client->obuf;
                    543:   stream_reset (s);
                    544: 
                    545:   /* Fill in result. */
                    546:   zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
                    547:   stream_put_in_addr (s, &addr);
                    548: 
                    549:   if (rib)
                    550:     {
                    551:       stream_putl (s, rib->metric);
                    552:       num = 0;
                    553:       nump = stream_get_endp(s);
                    554:       stream_putc (s, 0);
                    555:       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                    556:        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                    557:          {
                    558:            stream_putc (s, nexthop->type);
                    559:            switch (nexthop->type)
                    560:              {
                    561:              case ZEBRA_NEXTHOP_IPV4:
                    562:                stream_put_in_addr (s, &nexthop->gate.ipv4);
                    563:                break;
                    564:              case ZEBRA_NEXTHOP_IFINDEX:
                    565:              case ZEBRA_NEXTHOP_IFNAME:
                    566:                stream_putl (s, nexthop->ifindex);
                    567:                break;
                    568:              default:
                    569:                 /* do nothing */
                    570:                break;
                    571:              }
                    572:            num++;
                    573:          }
                    574:       stream_putc_at (s, nump, num);
                    575:     }
                    576:   else
                    577:     {
                    578:       stream_putl (s, 0);
                    579:       stream_putc (s, 0);
                    580:     }
                    581: 
                    582:   stream_putw_at (s, 0, stream_get_endp (s));
                    583:   
                    584:   return zebra_server_send_message(client);
                    585: }
                    586: 
                    587: static int
                    588: zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
                    589: {
                    590:   struct stream *s;
                    591:   struct rib *rib;
                    592:   unsigned long nump;
                    593:   u_char num;
                    594:   struct nexthop *nexthop;
                    595: 
                    596:   /* Lookup nexthop. */
                    597:   rib = rib_lookup_ipv4 (p);
                    598: 
                    599:   /* Get output stream. */
                    600:   s = client->obuf;
                    601:   stream_reset (s);
                    602: 
                    603:   /* Fill in result. */
                    604:   zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP);
                    605:   stream_put_in_addr (s, &p->prefix);
                    606: 
                    607:   if (rib)
                    608:     {
                    609:       stream_putl (s, rib->metric);
                    610:       num = 0;
                    611:       nump = stream_get_endp(s);
                    612:       stream_putc (s, 0);
                    613:       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
                    614:        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
                    615:          {
                    616:            stream_putc (s, nexthop->type);
                    617:            switch (nexthop->type)
                    618:              {
                    619:              case ZEBRA_NEXTHOP_IPV4:
                    620:                stream_put_in_addr (s, &nexthop->gate.ipv4);
                    621:                break;
                    622:              case ZEBRA_NEXTHOP_IFINDEX:
                    623:              case ZEBRA_NEXTHOP_IFNAME:
                    624:                stream_putl (s, nexthop->ifindex);
                    625:                break;
                    626:              default:
                    627:                 /* do nothing */
                    628:                break;
                    629:              }
                    630:            num++;
                    631:          }
                    632:       stream_putc_at (s, nump, num);
                    633:     }
                    634:   else
                    635:     {
                    636:       stream_putl (s, 0);
                    637:       stream_putc (s, 0);
                    638:     }
                    639: 
                    640:   stream_putw_at (s, 0, stream_get_endp (s));
                    641:   
                    642:   return zebra_server_send_message(client);
                    643: }
                    644: 
                    645: /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
                    646: int
                    647: zsend_router_id_update (struct zserv *client, struct prefix *p)
                    648: {
                    649:   struct stream *s;
                    650:   int blen;
                    651: 
                    652:   /* Check this client need interface information. */
                    653:   if (!client->ridinfo)
                    654:     return 0;
                    655: 
                    656:   s = client->obuf;
                    657:   stream_reset (s);
                    658: 
                    659:   /* Message type. */
                    660:   zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE);
                    661: 
                    662:   /* Prefix information. */
                    663:   stream_putc (s, p->family);
                    664:   blen = prefix_blen (p);
                    665:   stream_put (s, &p->u.prefix, blen);
                    666:   stream_putc (s, p->prefixlen);
                    667: 
                    668:   /* Write packet size. */
                    669:   stream_putw_at (s, 0, stream_get_endp (s));
                    670: 
                    671:   return zebra_server_send_message(client);
                    672: }
                    673: 
                    674: /* Register zebra server interface information.  Send current all
                    675:    interface and address information. */
                    676: static int
                    677: zread_interface_add (struct zserv *client, u_short length)
                    678: {
                    679:   struct listnode *ifnode, *ifnnode;
                    680:   struct listnode *cnode, *cnnode;
                    681:   struct interface *ifp;
                    682:   struct connected *c;
                    683: 
                    684:   /* Interface information is needed. */
                    685:   client->ifinfo = 1;
                    686: 
                    687:   for (ALL_LIST_ELEMENTS (iflist, ifnode, ifnnode, ifp))
                    688:     {
                    689:       /* Skip pseudo interface. */
                    690:       if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
                    691:        continue;
                    692: 
                    693:       if (zsend_interface_add (client, ifp) < 0)
                    694:         return -1;
                    695: 
                    696:       for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
                    697:        {
                    698:          if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
                    699:              (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, 
                    700:                                        ifp, c) < 0))
                    701:            return -1;
                    702:        }
                    703:     }
                    704:   return 0;
                    705: }
                    706: 
                    707: /* Unregister zebra server interface information. */
                    708: static int
                    709: zread_interface_delete (struct zserv *client, u_short length)
                    710: {
                    711:   client->ifinfo = 0;
                    712:   return 0;
                    713: }
                    714: 
                    715: /* This function support multiple nexthop. */
                    716: /* 
                    717:  * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
                    718:  * add kernel route. 
                    719:  */
                    720: static int
                    721: zread_ipv4_add (struct zserv *client, u_short length)
                    722: {
                    723:   int i;
                    724:   struct rib *rib;
                    725:   struct prefix_ipv4 p;
                    726:   u_char message;
                    727:   struct in_addr nexthop;
                    728:   u_char nexthop_num;
                    729:   u_char nexthop_type;
                    730:   struct stream *s;
                    731:   unsigned int ifindex;
                    732:   u_char ifname_len;
1.1.1.2 ! misho     733:   safi_t safi; 
        !           734: 
1.1       misho     735: 
                    736:   /* Get input stream.  */
                    737:   s = client->ibuf;
                    738: 
                    739:   /* Allocate new rib. */
                    740:   rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
                    741:   
                    742:   /* Type, flags, message. */
                    743:   rib->type = stream_getc (s);
                    744:   rib->flags = stream_getc (s);
                    745:   message = stream_getc (s); 
1.1.1.2 ! misho     746:   safi = stream_getw (s);
1.1       misho     747:   rib->uptime = time (NULL);
                    748: 
                    749:   /* IPv4 prefix. */
                    750:   memset (&p, 0, sizeof (struct prefix_ipv4));
                    751:   p.family = AF_INET;
                    752:   p.prefixlen = stream_getc (s);
                    753:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    754: 
                    755:   /* Nexthop parse. */
                    756:   if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
                    757:     {
                    758:       nexthop_num = stream_getc (s);
                    759: 
                    760:       for (i = 0; i < nexthop_num; i++)
                    761:        {
                    762:          nexthop_type = stream_getc (s);
                    763: 
                    764:          switch (nexthop_type)
                    765:            {
                    766:            case ZEBRA_NEXTHOP_IFINDEX:
                    767:              ifindex = stream_getl (s);
                    768:              nexthop_ifindex_add (rib, ifindex);
                    769:              break;
                    770:            case ZEBRA_NEXTHOP_IFNAME:
                    771:              ifname_len = stream_getc (s);
                    772:              stream_forward_getp (s, ifname_len);
                    773:              break;
                    774:            case ZEBRA_NEXTHOP_IPV4:
                    775:              nexthop.s_addr = stream_get_ipv4 (s);
                    776:              nexthop_ipv4_add (rib, &nexthop, NULL);
                    777:              break;
                    778:            case ZEBRA_NEXTHOP_IPV6:
                    779:              stream_forward_getp (s, IPV6_MAX_BYTELEN);
                    780:              break;
1.1.1.2 ! misho     781:             case ZEBRA_NEXTHOP_BLACKHOLE:
        !           782:               nexthop_blackhole_add (rib);
        !           783:               break;
        !           784:             }
1.1       misho     785:        }
                    786:     }
                    787: 
                    788:   /* Distance. */
                    789:   if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
                    790:     rib->distance = stream_getc (s);
                    791: 
                    792:   /* Metric. */
                    793:   if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
                    794:     rib->metric = stream_getl (s);
                    795:     
                    796:   /* Table */
                    797:   rib->table=zebrad.rtm_table_default;
1.1.1.2 ! misho     798:   rib_add_ipv4_multipath (&p, rib, safi);
1.1       misho     799:   return 0;
                    800: }
                    801: 
                    802: /* Zebra server IPv4 prefix delete function. */
                    803: static int
                    804: zread_ipv4_delete (struct zserv *client, u_short length)
                    805: {
                    806:   int i;
                    807:   struct stream *s;
                    808:   struct zapi_ipv4 api;
1.1.1.2 ! misho     809:   struct in_addr nexthop, *nexthop_p;
1.1       misho     810:   unsigned long ifindex;
                    811:   struct prefix_ipv4 p;
                    812:   u_char nexthop_num;
                    813:   u_char nexthop_type;
                    814:   u_char ifname_len;
                    815:   
                    816:   s = client->ibuf;
                    817:   ifindex = 0;
                    818:   nexthop.s_addr = 0;
1.1.1.2 ! misho     819:   nexthop_p = NULL;
1.1       misho     820: 
                    821:   /* Type, flags, message. */
                    822:   api.type = stream_getc (s);
                    823:   api.flags = stream_getc (s);
                    824:   api.message = stream_getc (s);
1.1.1.2 ! misho     825:   api.safi = stream_getw (s);
1.1       misho     826: 
                    827:   /* IPv4 prefix. */
                    828:   memset (&p, 0, sizeof (struct prefix_ipv4));
                    829:   p.family = AF_INET;
                    830:   p.prefixlen = stream_getc (s);
                    831:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    832: 
                    833:   /* Nexthop, ifindex, distance, metric. */
                    834:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                    835:     {
                    836:       nexthop_num = stream_getc (s);
                    837: 
                    838:       for (i = 0; i < nexthop_num; i++)
                    839:        {
                    840:          nexthop_type = stream_getc (s);
                    841: 
                    842:          switch (nexthop_type)
                    843:            {
                    844:            case ZEBRA_NEXTHOP_IFINDEX:
                    845:              ifindex = stream_getl (s);
                    846:              break;
                    847:            case ZEBRA_NEXTHOP_IFNAME:
                    848:              ifname_len = stream_getc (s);
                    849:              stream_forward_getp (s, ifname_len);
                    850:              break;
                    851:            case ZEBRA_NEXTHOP_IPV4:
                    852:              nexthop.s_addr = stream_get_ipv4 (s);
1.1.1.2 ! misho     853:              nexthop_p = &nexthop;
1.1       misho     854:              break;
                    855:            case ZEBRA_NEXTHOP_IPV6:
                    856:              stream_forward_getp (s, IPV6_MAX_BYTELEN);
                    857:              break;
                    858:            }
                    859:        }
                    860:     }
                    861: 
                    862:   /* Distance. */
                    863:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    864:     api.distance = stream_getc (s);
                    865:   else
                    866:     api.distance = 0;
                    867: 
                    868:   /* Metric. */
                    869:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    870:     api.metric = stream_getl (s);
                    871:   else
                    872:     api.metric = 0;
                    873:     
1.1.1.2 ! misho     874:   rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
        !           875:                   client->rtm_table, api.safi);
1.1       misho     876:   return 0;
                    877: }
                    878: 
                    879: /* Nexthop lookup for IPv4. */
                    880: static int
                    881: zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
                    882: {
                    883:   struct in_addr addr;
                    884: 
                    885:   addr.s_addr = stream_get_ipv4 (client->ibuf);
                    886:   return zsend_ipv4_nexthop_lookup (client, addr);
                    887: }
                    888: 
                    889: /* Nexthop lookup for IPv4. */
                    890: static int
                    891: zread_ipv4_import_lookup (struct zserv *client, u_short length)
                    892: {
                    893:   struct prefix_ipv4 p;
                    894: 
                    895:   p.family = AF_INET;
                    896:   p.prefixlen = stream_getc (client->ibuf);
                    897:   p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
                    898: 
                    899:   return zsend_ipv4_import_lookup (client, &p);
                    900: }
                    901: 
                    902: #ifdef HAVE_IPV6
                    903: /* Zebra server IPv6 prefix add function. */
                    904: static int
                    905: zread_ipv6_add (struct zserv *client, u_short length)
                    906: {
                    907:   int i;
                    908:   struct stream *s;
                    909:   struct zapi_ipv6 api;
                    910:   struct in6_addr nexthop;
                    911:   unsigned long ifindex;
                    912:   struct prefix_ipv6 p;
                    913:   
                    914:   s = client->ibuf;
                    915:   ifindex = 0;
                    916:   memset (&nexthop, 0, sizeof (struct in6_addr));
                    917: 
                    918:   /* Type, flags, message. */
                    919:   api.type = stream_getc (s);
                    920:   api.flags = stream_getc (s);
                    921:   api.message = stream_getc (s);
1.1.1.2 ! misho     922:   api.safi = stream_getw (s);
1.1       misho     923: 
                    924:   /* IPv4 prefix. */
                    925:   memset (&p, 0, sizeof (struct prefix_ipv6));
                    926:   p.family = AF_INET6;
                    927:   p.prefixlen = stream_getc (s);
                    928:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    929: 
                    930:   /* Nexthop, ifindex, distance, metric. */
                    931:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                    932:     {
                    933:       u_char nexthop_type;
                    934: 
                    935:       api.nexthop_num = stream_getc (s);
                    936:       for (i = 0; i < api.nexthop_num; i++)
                    937:        {
                    938:          nexthop_type = stream_getc (s);
                    939: 
                    940:          switch (nexthop_type)
                    941:            {
                    942:            case ZEBRA_NEXTHOP_IPV6:
                    943:              stream_get (&nexthop, s, 16);
                    944:              break;
                    945:            case ZEBRA_NEXTHOP_IFINDEX:
                    946:              ifindex = stream_getl (s);
                    947:              break;
                    948:            }
                    949:        }
                    950:     }
                    951: 
                    952:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    953:     api.distance = stream_getc (s);
                    954:   else
                    955:     api.distance = 0;
                    956: 
                    957:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    958:     api.metric = stream_getl (s);
                    959:   else
                    960:     api.metric = 0;
                    961:     
                    962:   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
                    963:     rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, zebrad.rtm_table_default, api.metric,
1.1.1.2 ! misho     964:                  api.distance, api.safi);
1.1       misho     965:   else
                    966:     rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, zebrad.rtm_table_default, api.metric,
1.1.1.2 ! misho     967:                  api.distance, api.safi);
1.1       misho     968:   return 0;
                    969: }
                    970: 
                    971: /* Zebra server IPv6 prefix delete function. */
                    972: static int
                    973: zread_ipv6_delete (struct zserv *client, u_short length)
                    974: {
                    975:   int i;
                    976:   struct stream *s;
                    977:   struct zapi_ipv6 api;
                    978:   struct in6_addr nexthop;
                    979:   unsigned long ifindex;
                    980:   struct prefix_ipv6 p;
                    981:   
                    982:   s = client->ibuf;
                    983:   ifindex = 0;
                    984:   memset (&nexthop, 0, sizeof (struct in6_addr));
                    985: 
                    986:   /* Type, flags, message. */
                    987:   api.type = stream_getc (s);
                    988:   api.flags = stream_getc (s);
                    989:   api.message = stream_getc (s);
1.1.1.2 ! misho     990:   api.safi = stream_getw (s);
1.1       misho     991: 
                    992:   /* IPv4 prefix. */
                    993:   memset (&p, 0, sizeof (struct prefix_ipv6));
                    994:   p.family = AF_INET6;
                    995:   p.prefixlen = stream_getc (s);
                    996:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    997: 
                    998:   /* Nexthop, ifindex, distance, metric. */
                    999:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                   1000:     {
                   1001:       u_char nexthop_type;
                   1002: 
                   1003:       api.nexthop_num = stream_getc (s);
                   1004:       for (i = 0; i < api.nexthop_num; i++)
                   1005:        {
                   1006:          nexthop_type = stream_getc (s);
                   1007: 
                   1008:          switch (nexthop_type)
                   1009:            {
                   1010:            case ZEBRA_NEXTHOP_IPV6:
                   1011:              stream_get (&nexthop, s, 16);
                   1012:              break;
                   1013:            case ZEBRA_NEXTHOP_IFINDEX:
                   1014:              ifindex = stream_getl (s);
                   1015:              break;
                   1016:            }
                   1017:        }
                   1018:     }
                   1019: 
                   1020:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                   1021:     api.distance = stream_getc (s);
                   1022:   else
                   1023:     api.distance = 0;
                   1024:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                   1025:     api.metric = stream_getl (s);
                   1026:   else
                   1027:     api.metric = 0;
                   1028:     
                   1029:   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1.1.1.2 ! misho    1030:     rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
1.1       misho    1031:   else
1.1.1.2 ! misho    1032:     rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
1.1       misho    1033:   return 0;
                   1034: }
                   1035: 
                   1036: static int
                   1037: zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
                   1038: {
                   1039:   struct in6_addr addr;
                   1040:   char buf[BUFSIZ];
                   1041: 
                   1042:   stream_get (&addr, client->ibuf, 16);
                   1043:   printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
                   1044: 
                   1045:   return zsend_ipv6_nexthop_lookup (client, &addr);
                   1046: }
                   1047: #endif /* HAVE_IPV6 */
                   1048: 
                   1049: /* Register zebra server router-id information.  Send current router-id */
                   1050: static int
                   1051: zread_router_id_add (struct zserv *client, u_short length)
                   1052: {
                   1053:   struct prefix p;
                   1054: 
                   1055:   /* Router-id information is needed. */
                   1056:   client->ridinfo = 1;
                   1057: 
                   1058:   router_id_get (&p);
                   1059: 
                   1060:   return zsend_router_id_update (client,&p);
                   1061: }
                   1062: 
                   1063: /* Unregister zebra server router-id information. */
                   1064: static int
                   1065: zread_router_id_delete (struct zserv *client, u_short length)
                   1066: {
                   1067:   client->ridinfo = 0;
                   1068:   return 0;
                   1069: }
                   1070: 
1.1.1.2 ! misho    1071: /* Tie up route-type and client->sock */
        !          1072: static void
        !          1073: zread_hello (struct zserv *client)
        !          1074: {
        !          1075:   /* type of protocol (lib/zebra.h) */
        !          1076:   u_char proto;
        !          1077:   proto = stream_getc (client->ibuf);
        !          1078: 
        !          1079:   /* accept only dynamic routing protocols */
        !          1080:   if ((proto < ZEBRA_ROUTE_MAX)
        !          1081:   &&  (proto > ZEBRA_ROUTE_STATIC))
        !          1082:     {
        !          1083:       zlog_notice ("client %d says hello and bids fair to announce only %s routes",
        !          1084:                     client->sock, zebra_route_string(proto));
        !          1085: 
        !          1086:       /* if route-type was binded by other client */
        !          1087:       if (route_type_oaths[proto])
        !          1088:         zlog_warn ("sender of %s routes changed %c->%c",
        !          1089:                     zebra_route_string(proto), route_type_oaths[proto],
        !          1090:                     client->sock);
        !          1091: 
        !          1092:       route_type_oaths[proto] = client->sock;
        !          1093:     }
        !          1094: }
        !          1095: 
        !          1096: /* If client sent routes of specific type, zebra removes it
        !          1097:  * and returns number of deleted routes.
        !          1098:  */
        !          1099: static void
        !          1100: zebra_score_rib (int client_sock)
        !          1101: {
        !          1102:   int i;
        !          1103: 
        !          1104:   for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
        !          1105:     if (client_sock == route_type_oaths[i])
        !          1106:       {
        !          1107:         zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
        !          1108:                       client_sock, rib_score_proto (i), zebra_route_string (i));
        !          1109:         route_type_oaths[i] = 0;
        !          1110:         break;
        !          1111:       }
        !          1112: }
        !          1113: 
1.1       misho    1114: /* Close zebra client. */
                   1115: static void
                   1116: zebra_client_close (struct zserv *client)
                   1117: {
                   1118:   /* Close file descriptor. */
                   1119:   if (client->sock)
                   1120:     {
                   1121:       close (client->sock);
1.1.1.2 ! misho    1122:       zebra_score_rib (client->sock);
1.1       misho    1123:       client->sock = -1;
                   1124:     }
                   1125: 
                   1126:   /* Free stream buffers. */
                   1127:   if (client->ibuf)
                   1128:     stream_free (client->ibuf);
                   1129:   if (client->obuf)
                   1130:     stream_free (client->obuf);
                   1131:   if (client->wb)
                   1132:     buffer_free(client->wb);
                   1133: 
                   1134:   /* Release threads. */
                   1135:   if (client->t_read)
                   1136:     thread_cancel (client->t_read);
                   1137:   if (client->t_write)
                   1138:     thread_cancel (client->t_write);
                   1139:   if (client->t_suicide)
                   1140:     thread_cancel (client->t_suicide);
                   1141: 
                   1142:   /* Free client structure. */
                   1143:   listnode_delete (zebrad.client_list, client);
                   1144:   XFREE (0, client);
                   1145: }
                   1146: 
                   1147: /* Make new client. */
                   1148: static void
                   1149: zebra_client_create (int sock)
                   1150: {
                   1151:   struct zserv *client;
                   1152: 
                   1153:   client = XCALLOC (0, sizeof (struct zserv));
                   1154: 
                   1155:   /* Make client input/output buffer. */
                   1156:   client->sock = sock;
                   1157:   client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
                   1158:   client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
                   1159:   client->wb = buffer_new(0);
                   1160: 
                   1161:   /* Set table number. */
                   1162:   client->rtm_table = zebrad.rtm_table_default;
                   1163: 
                   1164:   /* Add this client to linked list. */
                   1165:   listnode_add (zebrad.client_list, client);
                   1166:   
                   1167:   /* Make new read thread. */
                   1168:   zebra_event (ZEBRA_READ, sock, client);
                   1169: }
                   1170: 
                   1171: /* Handler of zebra service request. */
                   1172: static int
                   1173: zebra_client_read (struct thread *thread)
                   1174: {
                   1175:   int sock;
                   1176:   struct zserv *client;
                   1177:   size_t already;
                   1178:   uint16_t length, command;
                   1179:   uint8_t marker, version;
                   1180: 
                   1181:   /* Get thread data.  Reset reading thread because I'm running. */
                   1182:   sock = THREAD_FD (thread);
                   1183:   client = THREAD_ARG (thread);
                   1184:   client->t_read = NULL;
                   1185: 
                   1186:   if (client->t_suicide)
                   1187:     {
                   1188:       zebra_client_close(client);
                   1189:       return -1;
                   1190:     }
                   1191: 
                   1192:   /* Read length and command (if we don't have it already). */
                   1193:   if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
                   1194:     {
                   1195:       ssize_t nbyte;
                   1196:       if (((nbyte = stream_read_try (client->ibuf, sock,
                   1197:                                     ZEBRA_HEADER_SIZE-already)) == 0) ||
                   1198:          (nbyte == -1))
                   1199:        {
                   1200:          if (IS_ZEBRA_DEBUG_EVENT)
                   1201:            zlog_debug ("connection closed socket [%d]", sock);
                   1202:          zebra_client_close (client);
                   1203:          return -1;
                   1204:        }
                   1205:       if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
                   1206:        {
                   1207:          /* Try again later. */
                   1208:          zebra_event (ZEBRA_READ, sock, client);
                   1209:          return 0;
                   1210:        }
                   1211:       already = ZEBRA_HEADER_SIZE;
                   1212:     }
                   1213: 
                   1214:   /* Reset to read from the beginning of the incoming packet. */
                   1215:   stream_set_getp(client->ibuf, 0);
                   1216: 
                   1217:   /* Fetch header values */
                   1218:   length = stream_getw (client->ibuf);
                   1219:   marker = stream_getc (client->ibuf);
                   1220:   version = stream_getc (client->ibuf);
                   1221:   command = stream_getw (client->ibuf);
                   1222: 
                   1223:   if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
                   1224:     {
                   1225:       zlog_err("%s: socket %d version mismatch, marker %d, version %d",
                   1226:                __func__, sock, marker, version);
                   1227:       zebra_client_close (client);
                   1228:       return -1;
                   1229:     }
                   1230:   if (length < ZEBRA_HEADER_SIZE) 
                   1231:     {
                   1232:       zlog_warn("%s: socket %d message length %u is less than header size %d",
                   1233:                __func__, sock, length, ZEBRA_HEADER_SIZE);
                   1234:       zebra_client_close (client);
                   1235:       return -1;
                   1236:     }
                   1237:   if (length > STREAM_SIZE(client->ibuf))
                   1238:     {
                   1239:       zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
                   1240:                __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
                   1241:       zebra_client_close (client);
                   1242:       return -1;
                   1243:     }
                   1244: 
                   1245:   /* Read rest of data. */
                   1246:   if (already < length)
                   1247:     {
                   1248:       ssize_t nbyte;
                   1249:       if (((nbyte = stream_read_try (client->ibuf, sock,
                   1250:                                     length-already)) == 0) ||
                   1251:          (nbyte == -1))
                   1252:        {
                   1253:          if (IS_ZEBRA_DEBUG_EVENT)
                   1254:            zlog_debug ("connection closed [%d] when reading zebra data", sock);
                   1255:          zebra_client_close (client);
                   1256:          return -1;
                   1257:        }
                   1258:       if (nbyte != (ssize_t)(length-already))
                   1259:         {
                   1260:          /* Try again later. */
                   1261:          zebra_event (ZEBRA_READ, sock, client);
                   1262:          return 0;
                   1263:        }
                   1264:     }
                   1265: 
                   1266:   length -= ZEBRA_HEADER_SIZE;
                   1267: 
                   1268:   /* Debug packet information. */
                   1269:   if (IS_ZEBRA_DEBUG_EVENT)
                   1270:     zlog_debug ("zebra message comes from socket [%d]", sock);
                   1271: 
                   1272:   if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
                   1273:     zlog_debug ("zebra message received [%s] %d", 
                   1274:               zserv_command_string (command), length);
                   1275: 
                   1276:   switch (command) 
                   1277:     {
                   1278:     case ZEBRA_ROUTER_ID_ADD:
                   1279:       zread_router_id_add (client, length);
                   1280:       break;
                   1281:     case ZEBRA_ROUTER_ID_DELETE:
                   1282:       zread_router_id_delete (client, length);
                   1283:       break;
                   1284:     case ZEBRA_INTERFACE_ADD:
                   1285:       zread_interface_add (client, length);
                   1286:       break;
                   1287:     case ZEBRA_INTERFACE_DELETE:
                   1288:       zread_interface_delete (client, length);
                   1289:       break;
                   1290:     case ZEBRA_IPV4_ROUTE_ADD:
                   1291:       zread_ipv4_add (client, length);
                   1292:       break;
                   1293:     case ZEBRA_IPV4_ROUTE_DELETE:
                   1294:       zread_ipv4_delete (client, length);
                   1295:       break;
                   1296: #ifdef HAVE_IPV6
                   1297:     case ZEBRA_IPV6_ROUTE_ADD:
                   1298:       zread_ipv6_add (client, length);
                   1299:       break;
                   1300:     case ZEBRA_IPV6_ROUTE_DELETE:
                   1301:       zread_ipv6_delete (client, length);
                   1302:       break;
                   1303: #endif /* HAVE_IPV6 */
                   1304:     case ZEBRA_REDISTRIBUTE_ADD:
                   1305:       zebra_redistribute_add (command, client, length);
                   1306:       break;
                   1307:     case ZEBRA_REDISTRIBUTE_DELETE:
                   1308:       zebra_redistribute_delete (command, client, length);
                   1309:       break;
                   1310:     case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
                   1311:       zebra_redistribute_default_add (command, client, length);
                   1312:       break;
                   1313:     case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
                   1314:       zebra_redistribute_default_delete (command, client, length);
                   1315:       break;
                   1316:     case ZEBRA_IPV4_NEXTHOP_LOOKUP:
                   1317:       zread_ipv4_nexthop_lookup (client, length);
                   1318:       break;
                   1319: #ifdef HAVE_IPV6
                   1320:     case ZEBRA_IPV6_NEXTHOP_LOOKUP:
                   1321:       zread_ipv6_nexthop_lookup (client, length);
                   1322:       break;
                   1323: #endif /* HAVE_IPV6 */
                   1324:     case ZEBRA_IPV4_IMPORT_LOOKUP:
                   1325:       zread_ipv4_import_lookup (client, length);
                   1326:       break;
1.1.1.2 ! misho    1327:     case ZEBRA_HELLO:
        !          1328:       zread_hello (client);
        !          1329:       break;
1.1       misho    1330:     default:
                   1331:       zlog_info ("Zebra received unknown command %d", command);
                   1332:       break;
                   1333:     }
                   1334: 
                   1335:   if (client->t_suicide)
                   1336:     {
                   1337:       /* No need to wait for thread callback, just kill immediately. */
                   1338:       zebra_client_close(client);
                   1339:       return -1;
                   1340:     }
                   1341: 
                   1342:   stream_reset (client->ibuf);
                   1343:   zebra_event (ZEBRA_READ, sock, client);
                   1344:   return 0;
                   1345: }
                   1346: 
                   1347: 
                   1348: /* Accept code of zebra server socket. */
                   1349: static int
                   1350: zebra_accept (struct thread *thread)
                   1351: {
                   1352:   int accept_sock;
                   1353:   int client_sock;
                   1354:   struct sockaddr_in client;
                   1355:   socklen_t len;
                   1356: 
                   1357:   accept_sock = THREAD_FD (thread);
                   1358: 
                   1359:   /* Reregister myself. */
                   1360:   zebra_event (ZEBRA_SERV, accept_sock, NULL);
                   1361: 
                   1362:   len = sizeof (struct sockaddr_in);
                   1363:   client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
                   1364: 
                   1365:   if (client_sock < 0)
                   1366:     {
                   1367:       zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
                   1368:       return -1;
                   1369:     }
                   1370: 
                   1371:   /* Make client socket non-blocking.  */
                   1372:   set_nonblocking(client_sock);
                   1373:   
                   1374:   /* Create new zebra client. */
                   1375:   zebra_client_create (client_sock);
                   1376: 
                   1377:   return 0;
                   1378: }
                   1379: 
                   1380: #ifdef HAVE_TCP_ZEBRA
                   1381: /* Make zebra's server socket. */
                   1382: static void
                   1383: zebra_serv ()
                   1384: {
                   1385:   int ret;
                   1386:   int accept_sock;
                   1387:   struct sockaddr_in addr;
                   1388: 
                   1389:   accept_sock = socket (AF_INET, SOCK_STREAM, 0);
                   1390: 
                   1391:   if (accept_sock < 0) 
                   1392:     {
                   1393:       zlog_warn ("Can't create zserv stream socket: %s", 
                   1394:                  safe_strerror (errno));
                   1395:       zlog_warn ("zebra can't provice full functionality due to above error");
                   1396:       return;
                   1397:     }
                   1398: 
1.1.1.2 ! misho    1399:   memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1.1       misho    1400:   memset (&addr, 0, sizeof (struct sockaddr_in));
                   1401:   addr.sin_family = AF_INET;
                   1402:   addr.sin_port = htons (ZEBRA_PORT);
                   1403: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                   1404:   addr.sin_len = sizeof (struct sockaddr_in);
                   1405: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
                   1406:   addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
                   1407: 
                   1408:   sockopt_reuseaddr (accept_sock);
                   1409:   sockopt_reuseport (accept_sock);
                   1410: 
                   1411:   if ( zserv_privs.change(ZPRIVS_RAISE) )
                   1412:     zlog (NULL, LOG_ERR, "Can't raise privileges");
                   1413:     
                   1414:   ret  = bind (accept_sock, (struct sockaddr *)&addr, 
                   1415:               sizeof (struct sockaddr_in));
                   1416:   if (ret < 0)
                   1417:     {
                   1418:       zlog_warn ("Can't bind to stream socket: %s", 
                   1419:                  safe_strerror (errno));
                   1420:       zlog_warn ("zebra can't provice full functionality due to above error");
                   1421:       close (accept_sock);      /* Avoid sd leak. */
                   1422:       return;
                   1423:     }
                   1424:     
                   1425:   if ( zserv_privs.change(ZPRIVS_LOWER) )
                   1426:     zlog (NULL, LOG_ERR, "Can't lower privileges");
                   1427: 
                   1428:   ret = listen (accept_sock, 1);
                   1429:   if (ret < 0)
                   1430:     {
                   1431:       zlog_warn ("Can't listen to stream socket: %s", 
                   1432:                  safe_strerror (errno));
                   1433:       zlog_warn ("zebra can't provice full functionality due to above error");
                   1434:       close (accept_sock);     /* Avoid sd leak. */
                   1435:       return;
                   1436:     }
                   1437: 
                   1438:   zebra_event (ZEBRA_SERV, accept_sock, NULL);
                   1439: }
                   1440: #endif /* HAVE_TCP_ZEBRA */
                   1441: 
                   1442: /* For sockaddr_un. */
                   1443: #include <sys/un.h>
                   1444: 
                   1445: /* zebra server UNIX domain socket. */
                   1446: static void
                   1447: zebra_serv_un (const char *path)
                   1448: {
                   1449:   int ret;
                   1450:   int sock, len;
                   1451:   struct sockaddr_un serv;
                   1452:   mode_t old_mask;
                   1453: 
                   1454:   /* First of all, unlink existing socket */
                   1455:   unlink (path);
                   1456: 
                   1457:   /* Set umask */
                   1458:   old_mask = umask (0077);
                   1459: 
                   1460:   /* Make UNIX domain socket. */
                   1461:   sock = socket (AF_UNIX, SOCK_STREAM, 0);
                   1462:   if (sock < 0)
                   1463:     {
                   1464:       zlog_warn ("Can't create zserv unix socket: %s", 
                   1465:                  safe_strerror (errno));
                   1466:       zlog_warn ("zebra can't provide full functionality due to above error");
                   1467:       return;
                   1468:     }
                   1469: 
1.1.1.2 ! misho    1470:   memset (&route_type_oaths, 0, sizeof (route_type_oaths));
        !          1471: 
1.1       misho    1472:   /* Make server socket. */
                   1473:   memset (&serv, 0, sizeof (struct sockaddr_un));
                   1474:   serv.sun_family = AF_UNIX;
                   1475:   strncpy (serv.sun_path, path, strlen (path));
                   1476: #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
                   1477:   len = serv.sun_len = SUN_LEN(&serv);
                   1478: #else
                   1479:   len = sizeof (serv.sun_family) + strlen (serv.sun_path);
                   1480: #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
                   1481: 
                   1482:   ret = bind (sock, (struct sockaddr *) &serv, len);
                   1483:   if (ret < 0)
                   1484:     {
                   1485:       zlog_warn ("Can't bind to unix socket %s: %s", 
                   1486:                  path, safe_strerror (errno));
                   1487:       zlog_warn ("zebra can't provide full functionality due to above error");
                   1488:       close (sock);
                   1489:       return;
                   1490:     }
                   1491: 
                   1492:   ret = listen (sock, 5);
                   1493:   if (ret < 0)
                   1494:     {
                   1495:       zlog_warn ("Can't listen to unix socket %s: %s", 
                   1496:                  path, safe_strerror (errno));
                   1497:       zlog_warn ("zebra can't provide full functionality due to above error");
                   1498:       close (sock);
                   1499:       return;
                   1500:     }
                   1501: 
                   1502:   umask (old_mask);
                   1503: 
                   1504:   zebra_event (ZEBRA_SERV, sock, NULL);
                   1505: }
                   1506: 
                   1507: 
                   1508: static void
                   1509: zebra_event (enum event event, int sock, struct zserv *client)
                   1510: {
                   1511:   switch (event)
                   1512:     {
                   1513:     case ZEBRA_SERV:
                   1514:       thread_add_read (zebrad.master, zebra_accept, client, sock);
                   1515:       break;
                   1516:     case ZEBRA_READ:
                   1517:       client->t_read = 
                   1518:        thread_add_read (zebrad.master, zebra_client_read, client, sock);
                   1519:       break;
                   1520:     case ZEBRA_WRITE:
                   1521:       /**/
                   1522:       break;
                   1523:     }
                   1524: }
                   1525: 
                   1526: /* Display default rtm_table for all clients. */
                   1527: DEFUN (show_table,
                   1528:        show_table_cmd,
                   1529:        "show table",
                   1530:        SHOW_STR
                   1531:        "default routing table to use for all clients\n")
                   1532: {
                   1533:   vty_out (vty, "table %d%s", zebrad.rtm_table_default,
                   1534:           VTY_NEWLINE);
                   1535:   return CMD_SUCCESS;
                   1536: }
                   1537: 
                   1538: DEFUN (config_table, 
                   1539:        config_table_cmd,
                   1540:        "table TABLENO",
                   1541:        "Configure target kernel routing table\n"
                   1542:        "TABLE integer\n")
                   1543: {
                   1544:   zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
                   1545:   return CMD_SUCCESS;
                   1546: }
                   1547: 
                   1548: DEFUN (ip_forwarding,
                   1549:        ip_forwarding_cmd,
                   1550:        "ip forwarding",
                   1551:        IP_STR
                   1552:        "Turn on IP forwarding")
                   1553: {
                   1554:   int ret;
                   1555: 
                   1556:   ret = ipforward ();
                   1557:   if (ret == 0)
                   1558:     ret = ipforward_on ();
                   1559: 
                   1560:   if (ret == 0)
                   1561:     {
                   1562:       vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
                   1563:       return CMD_WARNING;
                   1564:     }
                   1565: 
                   1566:   return CMD_SUCCESS;
                   1567: }
                   1568: 
                   1569: DEFUN (no_ip_forwarding,
                   1570:        no_ip_forwarding_cmd,
                   1571:        "no ip forwarding",
                   1572:        NO_STR
                   1573:        IP_STR
                   1574:        "Turn off IP forwarding")
                   1575: {
                   1576:   int ret;
                   1577: 
                   1578:   ret = ipforward ();
                   1579:   if (ret != 0)
                   1580:     ret = ipforward_off ();
                   1581: 
                   1582:   if (ret != 0)
                   1583:     {
                   1584:       vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
                   1585:       return CMD_WARNING;
                   1586:     }
                   1587: 
                   1588:   return CMD_SUCCESS;
                   1589: }
                   1590: 
                   1591: /* This command is for debugging purpose. */
                   1592: DEFUN (show_zebra_client,
                   1593:        show_zebra_client_cmd,
                   1594:        "show zebra client",
                   1595:        SHOW_STR
                   1596:        "Zebra information"
                   1597:        "Client information")
                   1598: {
                   1599:   struct listnode *node;
                   1600:   struct zserv *client;
                   1601: 
                   1602:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
                   1603:     vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
                   1604:   
                   1605:   return CMD_SUCCESS;
                   1606: }
                   1607: 
                   1608: /* Table configuration write function. */
                   1609: static int
                   1610: config_write_table (struct vty *vty)
                   1611: {
                   1612:   if (zebrad.rtm_table_default)
                   1613:     vty_out (vty, "table %d%s", zebrad.rtm_table_default,
                   1614:             VTY_NEWLINE);
                   1615:   return 0;
                   1616: }
                   1617: 
                   1618: /* table node for routing tables. */
                   1619: static struct cmd_node table_node =
                   1620: {
                   1621:   TABLE_NODE,
                   1622:   "",                          /* This node has no interface. */
                   1623:   1
                   1624: };
                   1625: 
                   1626: /* Only display ip forwarding is enabled or not. */
                   1627: DEFUN (show_ip_forwarding,
                   1628:        show_ip_forwarding_cmd,
                   1629:        "show ip forwarding",
                   1630:        SHOW_STR
                   1631:        IP_STR
                   1632:        "IP forwarding status\n")
                   1633: {
                   1634:   int ret;
                   1635: 
                   1636:   ret = ipforward ();
                   1637: 
                   1638:   if (ret == 0)
                   1639:     vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
                   1640:   else
                   1641:     vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
                   1642:   return CMD_SUCCESS;
                   1643: }
                   1644: 
                   1645: #ifdef HAVE_IPV6
                   1646: /* Only display ipv6 forwarding is enabled or not. */
                   1647: DEFUN (show_ipv6_forwarding,
                   1648:        show_ipv6_forwarding_cmd,
                   1649:        "show ipv6 forwarding",
                   1650:        SHOW_STR
                   1651:        "IPv6 information\n"
                   1652:        "Forwarding status\n")
                   1653: {
                   1654:   int ret;
                   1655: 
                   1656:   ret = ipforward_ipv6 ();
                   1657: 
                   1658:   switch (ret)
                   1659:     {
                   1660:     case -1:
                   1661:       vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
                   1662:       break;
                   1663:     case 0:
                   1664:       vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
                   1665:       break;
                   1666:     case 1:
                   1667:       vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
                   1668:       break;
                   1669:     default:
                   1670:       vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
                   1671:       break;
                   1672:     }
                   1673:   return CMD_SUCCESS;
                   1674: }
                   1675: 
                   1676: DEFUN (ipv6_forwarding,
                   1677:        ipv6_forwarding_cmd,
                   1678:        "ipv6 forwarding",
                   1679:        IPV6_STR
                   1680:        "Turn on IPv6 forwarding")
                   1681: {
                   1682:   int ret;
                   1683: 
                   1684:   ret = ipforward_ipv6 ();
                   1685:   if (ret == 0)
                   1686:     ret = ipforward_ipv6_on ();
                   1687: 
                   1688:   if (ret == 0)
                   1689:     {
                   1690:       vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
                   1691:       return CMD_WARNING;
                   1692:     }
                   1693: 
                   1694:   return CMD_SUCCESS;
                   1695: }
                   1696: 
                   1697: DEFUN (no_ipv6_forwarding,
                   1698:        no_ipv6_forwarding_cmd,
                   1699:        "no ipv6 forwarding",
                   1700:        NO_STR
                   1701:        IPV6_STR
                   1702:        "Turn off IPv6 forwarding")
                   1703: {
                   1704:   int ret;
                   1705: 
                   1706:   ret = ipforward_ipv6 ();
                   1707:   if (ret != 0)
                   1708:     ret = ipforward_ipv6_off ();
                   1709: 
                   1710:   if (ret != 0)
                   1711:     {
                   1712:       vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
                   1713:       return CMD_WARNING;
                   1714:     }
                   1715: 
                   1716:   return CMD_SUCCESS;
                   1717: }
                   1718: 
                   1719: #endif /* HAVE_IPV6 */
                   1720: 
                   1721: /* IPForwarding configuration write function. */
                   1722: static int
                   1723: config_write_forwarding (struct vty *vty)
                   1724: {
                   1725:   /* FIXME: Find better place for that. */
                   1726:   router_id_write (vty);
                   1727: 
                   1728:   if (ipforward ())
                   1729:     vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
                   1730: #ifdef HAVE_IPV6
                   1731:   if (ipforward_ipv6 ())
                   1732:     vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
                   1733: #endif /* HAVE_IPV6 */
                   1734:   vty_out (vty, "!%s", VTY_NEWLINE);
                   1735:   return 0;
                   1736: }
                   1737: 
                   1738: /* table node for routing tables. */
                   1739: static struct cmd_node forwarding_node =
                   1740: {
                   1741:   FORWARDING_NODE,
                   1742:   "",                          /* This node has no interface. */
                   1743:   1
                   1744: };
                   1745: 
                   1746: 
                   1747: /* Initialisation of zebra and installation of commands. */
                   1748: void
                   1749: zebra_init (void)
                   1750: {
                   1751:   /* Client list init. */
                   1752:   zebrad.client_list = list_new ();
                   1753: 
                   1754:   /* Install configuration write function. */
                   1755:   install_node (&table_node, config_write_table);
                   1756:   install_node (&forwarding_node, config_write_forwarding);
                   1757: 
                   1758:   install_element (VIEW_NODE, &show_ip_forwarding_cmd);
                   1759:   install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
                   1760:   install_element (CONFIG_NODE, &ip_forwarding_cmd);
                   1761:   install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
                   1762:   install_element (ENABLE_NODE, &show_zebra_client_cmd);
                   1763: 
                   1764: #ifdef HAVE_NETLINK
                   1765:   install_element (VIEW_NODE, &show_table_cmd);
                   1766:   install_element (ENABLE_NODE, &show_table_cmd);
                   1767:   install_element (CONFIG_NODE, &config_table_cmd);
                   1768: #endif /* HAVE_NETLINK */
                   1769: 
                   1770: #ifdef HAVE_IPV6
                   1771:   install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
                   1772:   install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
                   1773:   install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
                   1774:   install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
                   1775: #endif /* HAVE_IPV6 */
                   1776: 
                   1777:   /* Route-map */
                   1778:   zebra_route_map_init ();
                   1779: }
                   1780: 
                   1781: /* Make zebra server socket, wiping any existing one (see bug #403). */
                   1782: void
1.1.1.2 ! misho    1783: zebra_zserv_socket_init (char *path)
1.1       misho    1784: {
                   1785: #ifdef HAVE_TCP_ZEBRA
                   1786:   zebra_serv ();
                   1787: #else
1.1.1.2 ! misho    1788:   zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
1.1       misho    1789: #endif /* HAVE_TCP_ZEBRA */
                   1790: }

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