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

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