File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / zserv.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

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