File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / zserv.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:41 2013 UTC (11 years ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

    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_storage));
  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_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;
  783: 	    case ZEBRA_NEXTHOP_IPV6:
  784: 	      stream_forward_getp (s, IPV6_MAX_BYTELEN);
  785: 	      break;
  786:             case ZEBRA_NEXTHOP_BLACKHOLE:
  787:               nexthop_blackhole_add (rib);
  788:               break;
  789:             }
  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;
  803:   rib_add_ipv4_multipath (&p, rib, safi);
  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;
  814:   struct in_addr nexthop, *nexthop_p;
  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;
  824:   nexthop_p = NULL;
  825: 
  826:   /* Type, flags, message. */
  827:   api.type = stream_getc (s);
  828:   api.flags = stream_getc (s);
  829:   api.message = stream_getc (s);
  830:   api.safi = stream_getw (s);
  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);
  858: 	      nexthop_p = &nexthop;
  859: 	      break;
  860: 	    case ZEBRA_NEXTHOP_IPV4_IFINDEX:
  861: 	      nexthop.s_addr = stream_get_ipv4 (s);
  862: 	      ifindex = stream_getl (s);
  863: 	      break;
  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:     
  883:   rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
  884: 		   client->rtm_table, api.safi);
  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);
  931:   api.safi = stream_getw (s);
  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,
  973: 		  api.distance, api.safi);
  974:   else
  975:     rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, zebrad.rtm_table_default, api.metric,
  976: 		  api.distance, api.safi);
  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);
  999:   api.safi = stream_getw (s);
 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))
 1039:     rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
 1040:   else
 1041:     rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
 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: 
 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: 
 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);
 1131:       zebra_score_rib (client->sock);
 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;
 1336:     case ZEBRA_HELLO:
 1337:       zread_hello (client);
 1338:       break;
 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: 
 1408:   memset (&route_type_oaths, 0, sizeof (route_type_oaths));
 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: 
 1479:   memset (&route_type_oaths, 0, sizeof (route_type_oaths));
 1480: 
 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
 1792: zebra_zserv_socket_init (char *path)
 1793: {
 1794: #ifdef HAVE_TCP_ZEBRA
 1795:   zebra_serv ();
 1796: #else
 1797:   zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
 1798: #endif /* HAVE_TCP_ZEBRA */
 1799: }

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