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

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
1.1.1.3 ! misho     156:   stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
1.1.1.2   misho     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;
1.1.1.3 ! misho     778:            case ZEBRA_NEXTHOP_IPV4_IFINDEX:
        !           779:              nexthop.s_addr = stream_get_ipv4 (s);
        !           780:              ifindex = stream_getl (s);
        !           781:              nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
        !           782:              break;
1.1       misho     783:            case ZEBRA_NEXTHOP_IPV6:
                    784:              stream_forward_getp (s, IPV6_MAX_BYTELEN);
                    785:              break;
1.1.1.2   misho     786:             case ZEBRA_NEXTHOP_BLACKHOLE:
                    787:               nexthop_blackhole_add (rib);
                    788:               break;
                    789:             }
1.1       misho     790:        }
                    791:     }
                    792: 
                    793:   /* Distance. */
                    794:   if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
                    795:     rib->distance = stream_getc (s);
                    796: 
                    797:   /* Metric. */
                    798:   if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
                    799:     rib->metric = stream_getl (s);
                    800:     
                    801:   /* Table */
                    802:   rib->table=zebrad.rtm_table_default;
1.1.1.2   misho     803:   rib_add_ipv4_multipath (&p, rib, safi);
1.1       misho     804:   return 0;
                    805: }
                    806: 
                    807: /* Zebra server IPv4 prefix delete function. */
                    808: static int
                    809: zread_ipv4_delete (struct zserv *client, u_short length)
                    810: {
                    811:   int i;
                    812:   struct stream *s;
                    813:   struct zapi_ipv4 api;
1.1.1.2   misho     814:   struct in_addr nexthop, *nexthop_p;
1.1       misho     815:   unsigned long ifindex;
                    816:   struct prefix_ipv4 p;
                    817:   u_char nexthop_num;
                    818:   u_char nexthop_type;
                    819:   u_char ifname_len;
                    820:   
                    821:   s = client->ibuf;
                    822:   ifindex = 0;
                    823:   nexthop.s_addr = 0;
1.1.1.2   misho     824:   nexthop_p = NULL;
1.1       misho     825: 
                    826:   /* Type, flags, message. */
                    827:   api.type = stream_getc (s);
                    828:   api.flags = stream_getc (s);
                    829:   api.message = stream_getc (s);
1.1.1.2   misho     830:   api.safi = stream_getw (s);
1.1       misho     831: 
                    832:   /* IPv4 prefix. */
                    833:   memset (&p, 0, sizeof (struct prefix_ipv4));
                    834:   p.family = AF_INET;
                    835:   p.prefixlen = stream_getc (s);
                    836:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    837: 
                    838:   /* Nexthop, ifindex, distance, metric. */
                    839:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                    840:     {
                    841:       nexthop_num = stream_getc (s);
                    842: 
                    843:       for (i = 0; i < nexthop_num; i++)
                    844:        {
                    845:          nexthop_type = stream_getc (s);
                    846: 
                    847:          switch (nexthop_type)
                    848:            {
                    849:            case ZEBRA_NEXTHOP_IFINDEX:
                    850:              ifindex = stream_getl (s);
                    851:              break;
                    852:            case ZEBRA_NEXTHOP_IFNAME:
                    853:              ifname_len = stream_getc (s);
                    854:              stream_forward_getp (s, ifname_len);
                    855:              break;
                    856:            case ZEBRA_NEXTHOP_IPV4:
                    857:              nexthop.s_addr = stream_get_ipv4 (s);
1.1.1.2   misho     858:              nexthop_p = &nexthop;
1.1       misho     859:              break;
1.1.1.3 ! misho     860:            case ZEBRA_NEXTHOP_IPV4_IFINDEX:
        !           861:              nexthop.s_addr = stream_get_ipv4 (s);
        !           862:              ifindex = stream_getl (s);
        !           863:              break;
1.1       misho     864:            case ZEBRA_NEXTHOP_IPV6:
                    865:              stream_forward_getp (s, IPV6_MAX_BYTELEN);
                    866:              break;
                    867:            }
                    868:        }
                    869:     }
                    870: 
                    871:   /* Distance. */
                    872:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    873:     api.distance = stream_getc (s);
                    874:   else
                    875:     api.distance = 0;
                    876: 
                    877:   /* Metric. */
                    878:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    879:     api.metric = stream_getl (s);
                    880:   else
                    881:     api.metric = 0;
                    882:     
1.1.1.2   misho     883:   rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
                    884:                   client->rtm_table, api.safi);
1.1       misho     885:   return 0;
                    886: }
                    887: 
                    888: /* Nexthop lookup for IPv4. */
                    889: static int
                    890: zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
                    891: {
                    892:   struct in_addr addr;
                    893: 
                    894:   addr.s_addr = stream_get_ipv4 (client->ibuf);
                    895:   return zsend_ipv4_nexthop_lookup (client, addr);
                    896: }
                    897: 
                    898: /* Nexthop lookup for IPv4. */
                    899: static int
                    900: zread_ipv4_import_lookup (struct zserv *client, u_short length)
                    901: {
                    902:   struct prefix_ipv4 p;
                    903: 
                    904:   p.family = AF_INET;
                    905:   p.prefixlen = stream_getc (client->ibuf);
                    906:   p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
                    907: 
                    908:   return zsend_ipv4_import_lookup (client, &p);
                    909: }
                    910: 
                    911: #ifdef HAVE_IPV6
                    912: /* Zebra server IPv6 prefix add function. */
                    913: static int
                    914: zread_ipv6_add (struct zserv *client, u_short length)
                    915: {
                    916:   int i;
                    917:   struct stream *s;
                    918:   struct zapi_ipv6 api;
                    919:   struct in6_addr nexthop;
                    920:   unsigned long ifindex;
                    921:   struct prefix_ipv6 p;
                    922:   
                    923:   s = client->ibuf;
                    924:   ifindex = 0;
                    925:   memset (&nexthop, 0, sizeof (struct in6_addr));
                    926: 
                    927:   /* Type, flags, message. */
                    928:   api.type = stream_getc (s);
                    929:   api.flags = stream_getc (s);
                    930:   api.message = stream_getc (s);
1.1.1.2   misho     931:   api.safi = stream_getw (s);
1.1       misho     932: 
                    933:   /* IPv4 prefix. */
                    934:   memset (&p, 0, sizeof (struct prefix_ipv6));
                    935:   p.family = AF_INET6;
                    936:   p.prefixlen = stream_getc (s);
                    937:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    938: 
                    939:   /* Nexthop, ifindex, distance, metric. */
                    940:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                    941:     {
                    942:       u_char nexthop_type;
                    943: 
                    944:       api.nexthop_num = stream_getc (s);
                    945:       for (i = 0; i < api.nexthop_num; i++)
                    946:        {
                    947:          nexthop_type = stream_getc (s);
                    948: 
                    949:          switch (nexthop_type)
                    950:            {
                    951:            case ZEBRA_NEXTHOP_IPV6:
                    952:              stream_get (&nexthop, s, 16);
                    953:              break;
                    954:            case ZEBRA_NEXTHOP_IFINDEX:
                    955:              ifindex = stream_getl (s);
                    956:              break;
                    957:            }
                    958:        }
                    959:     }
                    960: 
                    961:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    962:     api.distance = stream_getc (s);
                    963:   else
                    964:     api.distance = 0;
                    965: 
                    966:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    967:     api.metric = stream_getl (s);
                    968:   else
                    969:     api.metric = 0;
                    970:     
                    971:   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
                    972:     rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, zebrad.rtm_table_default, api.metric,
1.1.1.2   misho     973:                  api.distance, api.safi);
1.1       misho     974:   else
                    975:     rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, zebrad.rtm_table_default, api.metric,
1.1.1.2   misho     976:                  api.distance, api.safi);
1.1       misho     977:   return 0;
                    978: }
                    979: 
                    980: /* Zebra server IPv6 prefix delete function. */
                    981: static int
                    982: zread_ipv6_delete (struct zserv *client, u_short length)
                    983: {
                    984:   int i;
                    985:   struct stream *s;
                    986:   struct zapi_ipv6 api;
                    987:   struct in6_addr nexthop;
                    988:   unsigned long ifindex;
                    989:   struct prefix_ipv6 p;
                    990:   
                    991:   s = client->ibuf;
                    992:   ifindex = 0;
                    993:   memset (&nexthop, 0, sizeof (struct in6_addr));
                    994: 
                    995:   /* Type, flags, message. */
                    996:   api.type = stream_getc (s);
                    997:   api.flags = stream_getc (s);
                    998:   api.message = stream_getc (s);
1.1.1.2   misho     999:   api.safi = stream_getw (s);
1.1       misho    1000: 
                   1001:   /* IPv4 prefix. */
                   1002:   memset (&p, 0, sizeof (struct prefix_ipv6));
                   1003:   p.family = AF_INET6;
                   1004:   p.prefixlen = stream_getc (s);
                   1005:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                   1006: 
                   1007:   /* Nexthop, ifindex, distance, metric. */
                   1008:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                   1009:     {
                   1010:       u_char nexthop_type;
                   1011: 
                   1012:       api.nexthop_num = stream_getc (s);
                   1013:       for (i = 0; i < api.nexthop_num; i++)
                   1014:        {
                   1015:          nexthop_type = stream_getc (s);
                   1016: 
                   1017:          switch (nexthop_type)
                   1018:            {
                   1019:            case ZEBRA_NEXTHOP_IPV6:
                   1020:              stream_get (&nexthop, s, 16);
                   1021:              break;
                   1022:            case ZEBRA_NEXTHOP_IFINDEX:
                   1023:              ifindex = stream_getl (s);
                   1024:              break;
                   1025:            }
                   1026:        }
                   1027:     }
                   1028: 
                   1029:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                   1030:     api.distance = stream_getc (s);
                   1031:   else
                   1032:     api.distance = 0;
                   1033:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                   1034:     api.metric = stream_getl (s);
                   1035:   else
                   1036:     api.metric = 0;
                   1037:     
                   1038:   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1.1.1.2   misho    1039:     rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
1.1       misho    1040:   else
1.1.1.2   misho    1041:     rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
1.1       misho    1042:   return 0;
                   1043: }
                   1044: 
                   1045: static int
                   1046: zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
                   1047: {
                   1048:   struct in6_addr addr;
                   1049:   char buf[BUFSIZ];
                   1050: 
                   1051:   stream_get (&addr, client->ibuf, 16);
                   1052:   printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
                   1053: 
                   1054:   return zsend_ipv6_nexthop_lookup (client, &addr);
                   1055: }
                   1056: #endif /* HAVE_IPV6 */
                   1057: 
                   1058: /* Register zebra server router-id information.  Send current router-id */
                   1059: static int
                   1060: zread_router_id_add (struct zserv *client, u_short length)
                   1061: {
                   1062:   struct prefix p;
                   1063: 
                   1064:   /* Router-id information is needed. */
                   1065:   client->ridinfo = 1;
                   1066: 
                   1067:   router_id_get (&p);
                   1068: 
                   1069:   return zsend_router_id_update (client,&p);
                   1070: }
                   1071: 
                   1072: /* Unregister zebra server router-id information. */
                   1073: static int
                   1074: zread_router_id_delete (struct zserv *client, u_short length)
                   1075: {
                   1076:   client->ridinfo = 0;
                   1077:   return 0;
                   1078: }
                   1079: 
1.1.1.2   misho    1080: /* Tie up route-type and client->sock */
                   1081: static void
                   1082: zread_hello (struct zserv *client)
                   1083: {
                   1084:   /* type of protocol (lib/zebra.h) */
                   1085:   u_char proto;
                   1086:   proto = stream_getc (client->ibuf);
                   1087: 
                   1088:   /* accept only dynamic routing protocols */
                   1089:   if ((proto < ZEBRA_ROUTE_MAX)
                   1090:   &&  (proto > ZEBRA_ROUTE_STATIC))
                   1091:     {
                   1092:       zlog_notice ("client %d says hello and bids fair to announce only %s routes",
                   1093:                     client->sock, zebra_route_string(proto));
                   1094: 
                   1095:       /* if route-type was binded by other client */
                   1096:       if (route_type_oaths[proto])
                   1097:         zlog_warn ("sender of %s routes changed %c->%c",
                   1098:                     zebra_route_string(proto), route_type_oaths[proto],
                   1099:                     client->sock);
                   1100: 
                   1101:       route_type_oaths[proto] = client->sock;
                   1102:     }
                   1103: }
                   1104: 
                   1105: /* If client sent routes of specific type, zebra removes it
                   1106:  * and returns number of deleted routes.
                   1107:  */
                   1108: static void
                   1109: zebra_score_rib (int client_sock)
                   1110: {
                   1111:   int i;
                   1112: 
                   1113:   for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
                   1114:     if (client_sock == route_type_oaths[i])
                   1115:       {
                   1116:         zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
                   1117:                       client_sock, rib_score_proto (i), zebra_route_string (i));
                   1118:         route_type_oaths[i] = 0;
                   1119:         break;
                   1120:       }
                   1121: }
                   1122: 
1.1       misho    1123: /* Close zebra client. */
                   1124: static void
                   1125: zebra_client_close (struct zserv *client)
                   1126: {
                   1127:   /* Close file descriptor. */
                   1128:   if (client->sock)
                   1129:     {
                   1130:       close (client->sock);
1.1.1.2   misho    1131:       zebra_score_rib (client->sock);
1.1       misho    1132:       client->sock = -1;
                   1133:     }
                   1134: 
                   1135:   /* Free stream buffers. */
                   1136:   if (client->ibuf)
                   1137:     stream_free (client->ibuf);
                   1138:   if (client->obuf)
                   1139:     stream_free (client->obuf);
                   1140:   if (client->wb)
                   1141:     buffer_free(client->wb);
                   1142: 
                   1143:   /* Release threads. */
                   1144:   if (client->t_read)
                   1145:     thread_cancel (client->t_read);
                   1146:   if (client->t_write)
                   1147:     thread_cancel (client->t_write);
                   1148:   if (client->t_suicide)
                   1149:     thread_cancel (client->t_suicide);
                   1150: 
                   1151:   /* Free client structure. */
                   1152:   listnode_delete (zebrad.client_list, client);
                   1153:   XFREE (0, client);
                   1154: }
                   1155: 
                   1156: /* Make new client. */
                   1157: static void
                   1158: zebra_client_create (int sock)
                   1159: {
                   1160:   struct zserv *client;
                   1161: 
                   1162:   client = XCALLOC (0, sizeof (struct zserv));
                   1163: 
                   1164:   /* Make client input/output buffer. */
                   1165:   client->sock = sock;
                   1166:   client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
                   1167:   client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
                   1168:   client->wb = buffer_new(0);
                   1169: 
                   1170:   /* Set table number. */
                   1171:   client->rtm_table = zebrad.rtm_table_default;
                   1172: 
                   1173:   /* Add this client to linked list. */
                   1174:   listnode_add (zebrad.client_list, client);
                   1175:   
                   1176:   /* Make new read thread. */
                   1177:   zebra_event (ZEBRA_READ, sock, client);
                   1178: }
                   1179: 
                   1180: /* Handler of zebra service request. */
                   1181: static int
                   1182: zebra_client_read (struct thread *thread)
                   1183: {
                   1184:   int sock;
                   1185:   struct zserv *client;
                   1186:   size_t already;
                   1187:   uint16_t length, command;
                   1188:   uint8_t marker, version;
                   1189: 
                   1190:   /* Get thread data.  Reset reading thread because I'm running. */
                   1191:   sock = THREAD_FD (thread);
                   1192:   client = THREAD_ARG (thread);
                   1193:   client->t_read = NULL;
                   1194: 
                   1195:   if (client->t_suicide)
                   1196:     {
                   1197:       zebra_client_close(client);
                   1198:       return -1;
                   1199:     }
                   1200: 
                   1201:   /* Read length and command (if we don't have it already). */
                   1202:   if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
                   1203:     {
                   1204:       ssize_t nbyte;
                   1205:       if (((nbyte = stream_read_try (client->ibuf, sock,
                   1206:                                     ZEBRA_HEADER_SIZE-already)) == 0) ||
                   1207:          (nbyte == -1))
                   1208:        {
                   1209:          if (IS_ZEBRA_DEBUG_EVENT)
                   1210:            zlog_debug ("connection closed socket [%d]", sock);
                   1211:          zebra_client_close (client);
                   1212:          return -1;
                   1213:        }
                   1214:       if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
                   1215:        {
                   1216:          /* Try again later. */
                   1217:          zebra_event (ZEBRA_READ, sock, client);
                   1218:          return 0;
                   1219:        }
                   1220:       already = ZEBRA_HEADER_SIZE;
                   1221:     }
                   1222: 
                   1223:   /* Reset to read from the beginning of the incoming packet. */
                   1224:   stream_set_getp(client->ibuf, 0);
                   1225: 
                   1226:   /* Fetch header values */
                   1227:   length = stream_getw (client->ibuf);
                   1228:   marker = stream_getc (client->ibuf);
                   1229:   version = stream_getc (client->ibuf);
                   1230:   command = stream_getw (client->ibuf);
                   1231: 
                   1232:   if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
                   1233:     {
                   1234:       zlog_err("%s: socket %d version mismatch, marker %d, version %d",
                   1235:                __func__, sock, marker, version);
                   1236:       zebra_client_close (client);
                   1237:       return -1;
                   1238:     }
                   1239:   if (length < ZEBRA_HEADER_SIZE) 
                   1240:     {
                   1241:       zlog_warn("%s: socket %d message length %u is less than header size %d",
                   1242:                __func__, sock, length, ZEBRA_HEADER_SIZE);
                   1243:       zebra_client_close (client);
                   1244:       return -1;
                   1245:     }
                   1246:   if (length > STREAM_SIZE(client->ibuf))
                   1247:     {
                   1248:       zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
                   1249:                __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
                   1250:       zebra_client_close (client);
                   1251:       return -1;
                   1252:     }
                   1253: 
                   1254:   /* Read rest of data. */
                   1255:   if (already < length)
                   1256:     {
                   1257:       ssize_t nbyte;
                   1258:       if (((nbyte = stream_read_try (client->ibuf, sock,
                   1259:                                     length-already)) == 0) ||
                   1260:          (nbyte == -1))
                   1261:        {
                   1262:          if (IS_ZEBRA_DEBUG_EVENT)
                   1263:            zlog_debug ("connection closed [%d] when reading zebra data", sock);
                   1264:          zebra_client_close (client);
                   1265:          return -1;
                   1266:        }
                   1267:       if (nbyte != (ssize_t)(length-already))
                   1268:         {
                   1269:          /* Try again later. */
                   1270:          zebra_event (ZEBRA_READ, sock, client);
                   1271:          return 0;
                   1272:        }
                   1273:     }
                   1274: 
                   1275:   length -= ZEBRA_HEADER_SIZE;
                   1276: 
                   1277:   /* Debug packet information. */
                   1278:   if (IS_ZEBRA_DEBUG_EVENT)
                   1279:     zlog_debug ("zebra message comes from socket [%d]", sock);
                   1280: 
                   1281:   if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
                   1282:     zlog_debug ("zebra message received [%s] %d", 
                   1283:               zserv_command_string (command), length);
                   1284: 
                   1285:   switch (command) 
                   1286:     {
                   1287:     case ZEBRA_ROUTER_ID_ADD:
                   1288:       zread_router_id_add (client, length);
                   1289:       break;
                   1290:     case ZEBRA_ROUTER_ID_DELETE:
                   1291:       zread_router_id_delete (client, length);
                   1292:       break;
                   1293:     case ZEBRA_INTERFACE_ADD:
                   1294:       zread_interface_add (client, length);
                   1295:       break;
                   1296:     case ZEBRA_INTERFACE_DELETE:
                   1297:       zread_interface_delete (client, length);
                   1298:       break;
                   1299:     case ZEBRA_IPV4_ROUTE_ADD:
                   1300:       zread_ipv4_add (client, length);
                   1301:       break;
                   1302:     case ZEBRA_IPV4_ROUTE_DELETE:
                   1303:       zread_ipv4_delete (client, length);
                   1304:       break;
                   1305: #ifdef HAVE_IPV6
                   1306:     case ZEBRA_IPV6_ROUTE_ADD:
                   1307:       zread_ipv6_add (client, length);
                   1308:       break;
                   1309:     case ZEBRA_IPV6_ROUTE_DELETE:
                   1310:       zread_ipv6_delete (client, length);
                   1311:       break;
                   1312: #endif /* HAVE_IPV6 */
                   1313:     case ZEBRA_REDISTRIBUTE_ADD:
                   1314:       zebra_redistribute_add (command, client, length);
                   1315:       break;
                   1316:     case ZEBRA_REDISTRIBUTE_DELETE:
                   1317:       zebra_redistribute_delete (command, client, length);
                   1318:       break;
                   1319:     case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
                   1320:       zebra_redistribute_default_add (command, client, length);
                   1321:       break;
                   1322:     case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
                   1323:       zebra_redistribute_default_delete (command, client, length);
                   1324:       break;
                   1325:     case ZEBRA_IPV4_NEXTHOP_LOOKUP:
                   1326:       zread_ipv4_nexthop_lookup (client, length);
                   1327:       break;
                   1328: #ifdef HAVE_IPV6
                   1329:     case ZEBRA_IPV6_NEXTHOP_LOOKUP:
                   1330:       zread_ipv6_nexthop_lookup (client, length);
                   1331:       break;
                   1332: #endif /* HAVE_IPV6 */
                   1333:     case ZEBRA_IPV4_IMPORT_LOOKUP:
                   1334:       zread_ipv4_import_lookup (client, length);
                   1335:       break;
1.1.1.2   misho    1336:     case ZEBRA_HELLO:
                   1337:       zread_hello (client);
                   1338:       break;
1.1       misho    1339:     default:
                   1340:       zlog_info ("Zebra received unknown command %d", command);
                   1341:       break;
                   1342:     }
                   1343: 
                   1344:   if (client->t_suicide)
                   1345:     {
                   1346:       /* No need to wait for thread callback, just kill immediately. */
                   1347:       zebra_client_close(client);
                   1348:       return -1;
                   1349:     }
                   1350: 
                   1351:   stream_reset (client->ibuf);
                   1352:   zebra_event (ZEBRA_READ, sock, client);
                   1353:   return 0;
                   1354: }
                   1355: 
                   1356: 
                   1357: /* Accept code of zebra server socket. */
                   1358: static int
                   1359: zebra_accept (struct thread *thread)
                   1360: {
                   1361:   int accept_sock;
                   1362:   int client_sock;
                   1363:   struct sockaddr_in client;
                   1364:   socklen_t len;
                   1365: 
                   1366:   accept_sock = THREAD_FD (thread);
                   1367: 
                   1368:   /* Reregister myself. */
                   1369:   zebra_event (ZEBRA_SERV, accept_sock, NULL);
                   1370: 
                   1371:   len = sizeof (struct sockaddr_in);
                   1372:   client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
                   1373: 
                   1374:   if (client_sock < 0)
                   1375:     {
                   1376:       zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
                   1377:       return -1;
                   1378:     }
                   1379: 
                   1380:   /* Make client socket non-blocking.  */
                   1381:   set_nonblocking(client_sock);
                   1382:   
                   1383:   /* Create new zebra client. */
                   1384:   zebra_client_create (client_sock);
                   1385: 
                   1386:   return 0;
                   1387: }
                   1388: 
                   1389: #ifdef HAVE_TCP_ZEBRA
                   1390: /* Make zebra's server socket. */
                   1391: static void
                   1392: zebra_serv ()
                   1393: {
                   1394:   int ret;
                   1395:   int accept_sock;
                   1396:   struct sockaddr_in addr;
                   1397: 
                   1398:   accept_sock = socket (AF_INET, SOCK_STREAM, 0);
                   1399: 
                   1400:   if (accept_sock < 0) 
                   1401:     {
                   1402:       zlog_warn ("Can't create zserv stream socket: %s", 
                   1403:                  safe_strerror (errno));
                   1404:       zlog_warn ("zebra can't provice full functionality due to above error");
                   1405:       return;
                   1406:     }
                   1407: 
1.1.1.2   misho    1408:   memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1.1       misho    1409:   memset (&addr, 0, sizeof (struct sockaddr_in));
                   1410:   addr.sin_family = AF_INET;
                   1411:   addr.sin_port = htons (ZEBRA_PORT);
                   1412: #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                   1413:   addr.sin_len = sizeof (struct sockaddr_in);
                   1414: #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
                   1415:   addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
                   1416: 
                   1417:   sockopt_reuseaddr (accept_sock);
                   1418:   sockopt_reuseport (accept_sock);
                   1419: 
                   1420:   if ( zserv_privs.change(ZPRIVS_RAISE) )
                   1421:     zlog (NULL, LOG_ERR, "Can't raise privileges");
                   1422:     
                   1423:   ret  = bind (accept_sock, (struct sockaddr *)&addr, 
                   1424:               sizeof (struct sockaddr_in));
                   1425:   if (ret < 0)
                   1426:     {
                   1427:       zlog_warn ("Can't bind to stream socket: %s", 
                   1428:                  safe_strerror (errno));
                   1429:       zlog_warn ("zebra can't provice full functionality due to above error");
                   1430:       close (accept_sock);      /* Avoid sd leak. */
                   1431:       return;
                   1432:     }
                   1433:     
                   1434:   if ( zserv_privs.change(ZPRIVS_LOWER) )
                   1435:     zlog (NULL, LOG_ERR, "Can't lower privileges");
                   1436: 
                   1437:   ret = listen (accept_sock, 1);
                   1438:   if (ret < 0)
                   1439:     {
                   1440:       zlog_warn ("Can't listen to stream socket: %s", 
                   1441:                  safe_strerror (errno));
                   1442:       zlog_warn ("zebra can't provice full functionality due to above error");
                   1443:       close (accept_sock);     /* Avoid sd leak. */
                   1444:       return;
                   1445:     }
                   1446: 
                   1447:   zebra_event (ZEBRA_SERV, accept_sock, NULL);
                   1448: }
                   1449: #endif /* HAVE_TCP_ZEBRA */
                   1450: 
                   1451: /* For sockaddr_un. */
                   1452: #include <sys/un.h>
                   1453: 
                   1454: /* zebra server UNIX domain socket. */
                   1455: static void
                   1456: zebra_serv_un (const char *path)
                   1457: {
                   1458:   int ret;
                   1459:   int sock, len;
                   1460:   struct sockaddr_un serv;
                   1461:   mode_t old_mask;
                   1462: 
                   1463:   /* First of all, unlink existing socket */
                   1464:   unlink (path);
                   1465: 
                   1466:   /* Set umask */
                   1467:   old_mask = umask (0077);
                   1468: 
                   1469:   /* Make UNIX domain socket. */
                   1470:   sock = socket (AF_UNIX, SOCK_STREAM, 0);
                   1471:   if (sock < 0)
                   1472:     {
                   1473:       zlog_warn ("Can't create zserv unix socket: %s", 
                   1474:                  safe_strerror (errno));
                   1475:       zlog_warn ("zebra can't provide full functionality due to above error");
                   1476:       return;
                   1477:     }
                   1478: 
1.1.1.2   misho    1479:   memset (&route_type_oaths, 0, sizeof (route_type_oaths));
                   1480: 
1.1       misho    1481:   /* Make server socket. */
                   1482:   memset (&serv, 0, sizeof (struct sockaddr_un));
                   1483:   serv.sun_family = AF_UNIX;
                   1484:   strncpy (serv.sun_path, path, strlen (path));
                   1485: #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
                   1486:   len = serv.sun_len = SUN_LEN(&serv);
                   1487: #else
                   1488:   len = sizeof (serv.sun_family) + strlen (serv.sun_path);
                   1489: #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
                   1490: 
                   1491:   ret = bind (sock, (struct sockaddr *) &serv, len);
                   1492:   if (ret < 0)
                   1493:     {
                   1494:       zlog_warn ("Can't bind to unix socket %s: %s", 
                   1495:                  path, safe_strerror (errno));
                   1496:       zlog_warn ("zebra can't provide full functionality due to above error");
                   1497:       close (sock);
                   1498:       return;
                   1499:     }
                   1500: 
                   1501:   ret = listen (sock, 5);
                   1502:   if (ret < 0)
                   1503:     {
                   1504:       zlog_warn ("Can't listen to unix socket %s: %s", 
                   1505:                  path, safe_strerror (errno));
                   1506:       zlog_warn ("zebra can't provide full functionality due to above error");
                   1507:       close (sock);
                   1508:       return;
                   1509:     }
                   1510: 
                   1511:   umask (old_mask);
                   1512: 
                   1513:   zebra_event (ZEBRA_SERV, sock, NULL);
                   1514: }
                   1515: 
                   1516: 
                   1517: static void
                   1518: zebra_event (enum event event, int sock, struct zserv *client)
                   1519: {
                   1520:   switch (event)
                   1521:     {
                   1522:     case ZEBRA_SERV:
                   1523:       thread_add_read (zebrad.master, zebra_accept, client, sock);
                   1524:       break;
                   1525:     case ZEBRA_READ:
                   1526:       client->t_read = 
                   1527:        thread_add_read (zebrad.master, zebra_client_read, client, sock);
                   1528:       break;
                   1529:     case ZEBRA_WRITE:
                   1530:       /**/
                   1531:       break;
                   1532:     }
                   1533: }
                   1534: 
                   1535: /* Display default rtm_table for all clients. */
                   1536: DEFUN (show_table,
                   1537:        show_table_cmd,
                   1538:        "show table",
                   1539:        SHOW_STR
                   1540:        "default routing table to use for all clients\n")
                   1541: {
                   1542:   vty_out (vty, "table %d%s", zebrad.rtm_table_default,
                   1543:           VTY_NEWLINE);
                   1544:   return CMD_SUCCESS;
                   1545: }
                   1546: 
                   1547: DEFUN (config_table, 
                   1548:        config_table_cmd,
                   1549:        "table TABLENO",
                   1550:        "Configure target kernel routing table\n"
                   1551:        "TABLE integer\n")
                   1552: {
                   1553:   zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
                   1554:   return CMD_SUCCESS;
                   1555: }
                   1556: 
                   1557: DEFUN (ip_forwarding,
                   1558:        ip_forwarding_cmd,
                   1559:        "ip forwarding",
                   1560:        IP_STR
                   1561:        "Turn on IP forwarding")
                   1562: {
                   1563:   int ret;
                   1564: 
                   1565:   ret = ipforward ();
                   1566:   if (ret == 0)
                   1567:     ret = ipforward_on ();
                   1568: 
                   1569:   if (ret == 0)
                   1570:     {
                   1571:       vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
                   1572:       return CMD_WARNING;
                   1573:     }
                   1574: 
                   1575:   return CMD_SUCCESS;
                   1576: }
                   1577: 
                   1578: DEFUN (no_ip_forwarding,
                   1579:        no_ip_forwarding_cmd,
                   1580:        "no ip forwarding",
                   1581:        NO_STR
                   1582:        IP_STR
                   1583:        "Turn off IP forwarding")
                   1584: {
                   1585:   int ret;
                   1586: 
                   1587:   ret = ipforward ();
                   1588:   if (ret != 0)
                   1589:     ret = ipforward_off ();
                   1590: 
                   1591:   if (ret != 0)
                   1592:     {
                   1593:       vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
                   1594:       return CMD_WARNING;
                   1595:     }
                   1596: 
                   1597:   return CMD_SUCCESS;
                   1598: }
                   1599: 
                   1600: /* This command is for debugging purpose. */
                   1601: DEFUN (show_zebra_client,
                   1602:        show_zebra_client_cmd,
                   1603:        "show zebra client",
                   1604:        SHOW_STR
                   1605:        "Zebra information"
                   1606:        "Client information")
                   1607: {
                   1608:   struct listnode *node;
                   1609:   struct zserv *client;
                   1610: 
                   1611:   for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
                   1612:     vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
                   1613:   
                   1614:   return CMD_SUCCESS;
                   1615: }
                   1616: 
                   1617: /* Table configuration write function. */
                   1618: static int
                   1619: config_write_table (struct vty *vty)
                   1620: {
                   1621:   if (zebrad.rtm_table_default)
                   1622:     vty_out (vty, "table %d%s", zebrad.rtm_table_default,
                   1623:             VTY_NEWLINE);
                   1624:   return 0;
                   1625: }
                   1626: 
                   1627: /* table node for routing tables. */
                   1628: static struct cmd_node table_node =
                   1629: {
                   1630:   TABLE_NODE,
                   1631:   "",                          /* This node has no interface. */
                   1632:   1
                   1633: };
                   1634: 
                   1635: /* Only display ip forwarding is enabled or not. */
                   1636: DEFUN (show_ip_forwarding,
                   1637:        show_ip_forwarding_cmd,
                   1638:        "show ip forwarding",
                   1639:        SHOW_STR
                   1640:        IP_STR
                   1641:        "IP forwarding status\n")
                   1642: {
                   1643:   int ret;
                   1644: 
                   1645:   ret = ipforward ();
                   1646: 
                   1647:   if (ret == 0)
                   1648:     vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
                   1649:   else
                   1650:     vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
                   1651:   return CMD_SUCCESS;
                   1652: }
                   1653: 
                   1654: #ifdef HAVE_IPV6
                   1655: /* Only display ipv6 forwarding is enabled or not. */
                   1656: DEFUN (show_ipv6_forwarding,
                   1657:        show_ipv6_forwarding_cmd,
                   1658:        "show ipv6 forwarding",
                   1659:        SHOW_STR
                   1660:        "IPv6 information\n"
                   1661:        "Forwarding status\n")
                   1662: {
                   1663:   int ret;
                   1664: 
                   1665:   ret = ipforward_ipv6 ();
                   1666: 
                   1667:   switch (ret)
                   1668:     {
                   1669:     case -1:
                   1670:       vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
                   1671:       break;
                   1672:     case 0:
                   1673:       vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
                   1674:       break;
                   1675:     case 1:
                   1676:       vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
                   1677:       break;
                   1678:     default:
                   1679:       vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
                   1680:       break;
                   1681:     }
                   1682:   return CMD_SUCCESS;
                   1683: }
                   1684: 
                   1685: DEFUN (ipv6_forwarding,
                   1686:        ipv6_forwarding_cmd,
                   1687:        "ipv6 forwarding",
                   1688:        IPV6_STR
                   1689:        "Turn on IPv6 forwarding")
                   1690: {
                   1691:   int ret;
                   1692: 
                   1693:   ret = ipforward_ipv6 ();
                   1694:   if (ret == 0)
                   1695:     ret = ipforward_ipv6_on ();
                   1696: 
                   1697:   if (ret == 0)
                   1698:     {
                   1699:       vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
                   1700:       return CMD_WARNING;
                   1701:     }
                   1702: 
                   1703:   return CMD_SUCCESS;
                   1704: }
                   1705: 
                   1706: DEFUN (no_ipv6_forwarding,
                   1707:        no_ipv6_forwarding_cmd,
                   1708:        "no ipv6 forwarding",
                   1709:        NO_STR
                   1710:        IPV6_STR
                   1711:        "Turn off IPv6 forwarding")
                   1712: {
                   1713:   int ret;
                   1714: 
                   1715:   ret = ipforward_ipv6 ();
                   1716:   if (ret != 0)
                   1717:     ret = ipforward_ipv6_off ();
                   1718: 
                   1719:   if (ret != 0)
                   1720:     {
                   1721:       vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
                   1722:       return CMD_WARNING;
                   1723:     }
                   1724: 
                   1725:   return CMD_SUCCESS;
                   1726: }
                   1727: 
                   1728: #endif /* HAVE_IPV6 */
                   1729: 
                   1730: /* IPForwarding configuration write function. */
                   1731: static int
                   1732: config_write_forwarding (struct vty *vty)
                   1733: {
                   1734:   /* FIXME: Find better place for that. */
                   1735:   router_id_write (vty);
                   1736: 
                   1737:   if (ipforward ())
                   1738:     vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
                   1739: #ifdef HAVE_IPV6
                   1740:   if (ipforward_ipv6 ())
                   1741:     vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
                   1742: #endif /* HAVE_IPV6 */
                   1743:   vty_out (vty, "!%s", VTY_NEWLINE);
                   1744:   return 0;
                   1745: }
                   1746: 
                   1747: /* table node for routing tables. */
                   1748: static struct cmd_node forwarding_node =
                   1749: {
                   1750:   FORWARDING_NODE,
                   1751:   "",                          /* This node has no interface. */
                   1752:   1
                   1753: };
                   1754: 
                   1755: 
                   1756: /* Initialisation of zebra and installation of commands. */
                   1757: void
                   1758: zebra_init (void)
                   1759: {
                   1760:   /* Client list init. */
                   1761:   zebrad.client_list = list_new ();
                   1762: 
                   1763:   /* Install configuration write function. */
                   1764:   install_node (&table_node, config_write_table);
                   1765:   install_node (&forwarding_node, config_write_forwarding);
                   1766: 
                   1767:   install_element (VIEW_NODE, &show_ip_forwarding_cmd);
                   1768:   install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
                   1769:   install_element (CONFIG_NODE, &ip_forwarding_cmd);
                   1770:   install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
                   1771:   install_element (ENABLE_NODE, &show_zebra_client_cmd);
                   1772: 
                   1773: #ifdef HAVE_NETLINK
                   1774:   install_element (VIEW_NODE, &show_table_cmd);
                   1775:   install_element (ENABLE_NODE, &show_table_cmd);
                   1776:   install_element (CONFIG_NODE, &config_table_cmd);
                   1777: #endif /* HAVE_NETLINK */
                   1778: 
                   1779: #ifdef HAVE_IPV6
                   1780:   install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
                   1781:   install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
                   1782:   install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
                   1783:   install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
                   1784: #endif /* HAVE_IPV6 */
                   1785: 
                   1786:   /* Route-map */
                   1787:   zebra_route_map_init ();
                   1788: }
                   1789: 
                   1790: /* Make zebra server socket, wiping any existing one (see bug #403). */
                   1791: void
1.1.1.2   misho    1792: zebra_zserv_socket_init (char *path)
1.1       misho    1793: {
                   1794: #ifdef HAVE_TCP_ZEBRA
                   1795:   zebra_serv ();
                   1796: #else
1.1.1.2   misho    1797:   zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
1.1       misho    1798: #endif /* HAVE_TCP_ZEBRA */
                   1799: }

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