File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / zserv.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:22:29 2012 UTC (11 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_21, HEAD
quagga

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

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