LCOV - code coverage report
Current view: top level - lib - zclient.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 15 400 3.8 %
Date: 2015-11-19 Functions: 2 29 6.9 %

          Line data    Source code
       1             : /* Zebra's client library.
       2             :  * Copyright (C) 1999 Kunihiro Ishiguro
       3             :  * Copyright (C) 2005 Andrew J. Schorr
       4             :  *
       5             :  * This file is part of GNU Zebra.
       6             :  *
       7             :  * GNU Zebra is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published
       9             :  * by the Free Software Foundation; either version 2, or (at your
      10             :  * option) any later version.
      11             :  *
      12             :  * GNU Zebra is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with GNU Zebra; see the file COPYING.  If not, write to the
      19             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
      20             :  * MA 02111-1307, USA.
      21             :  */
      22             : 
      23             : #include <zebra.h>
      24             : 
      25             : #include "prefix.h"
      26             : #include "stream.h"
      27             : #include "buffer.h"
      28             : #include "network.h"
      29             : #include "if.h"
      30             : #include "log.h"
      31             : #include "thread.h"
      32             : #include "zclient.h"
      33             : #include "memory.h"
      34             : #include "table.h"
      35             : 
      36             : /* Zebra client events. */
      37             : enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
      38             : 
      39             : /* Prototype for event manager. */
      40             : static void zclient_event (enum event, struct zclient *);
      41             : 
      42             : extern struct thread_master *master;
      43             : 
      44             : char *zclient_serv_path = NULL;
      45             : 
      46             : /* This file local debug flag. */
      47             : int zclient_debug = 0;
      48             : 
      49             : /* Allocate zclient structure. */
      50             : struct zclient *
      51           1 : zclient_new ()
      52             : {
      53             :   struct zclient *zclient;
      54           1 :   zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
      55             : 
      56           1 :   zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
      57           1 :   zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
      58           1 :   zclient->wb = buffer_new(0);
      59             : 
      60           1 :   return zclient;
      61             : }
      62             : 
      63             : /* This function is only called when exiting, because
      64             :    many parts of the code do not check for I/O errors, so they could
      65             :    reference an invalid pointer if the structure was ever freed.
      66             : 
      67             :    Free zclient structure. */
      68             : void
      69           1 : zclient_free (struct zclient *zclient)
      70             : {
      71           1 :   if (zclient->ibuf)
      72           1 :     stream_free(zclient->ibuf);
      73           1 :   if (zclient->obuf)
      74           1 :     stream_free(zclient->obuf);
      75           1 :   if (zclient->wb)
      76           1 :     buffer_free(zclient->wb);
      77             : 
      78           1 :   XFREE (MTYPE_ZCLIENT, zclient);
      79           1 : }
      80             : 
      81             : /* Initialize zebra client.  Argument redist_default is unwanted
      82             :    redistribute route type. */
      83             : void
      84           0 : zclient_init (struct zclient *zclient, int redist_default)
      85             : {
      86             :   int i;
      87             :   
      88             :   /* Enable zebra client connection by default. */
      89           0 :   zclient->enable = 1;
      90             : 
      91             :   /* Set -1 to the default socket value. */
      92           0 :   zclient->sock = -1;
      93             : 
      94             :   /* Clear redistribution flags. */
      95           0 :   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
      96           0 :     zclient->redist[i] = 0;
      97             : 
      98             :   /* Set unwanted redistribute route.  bgpd does not need BGP route
      99             :      redistribution. */
     100           0 :   zclient->redist_default = redist_default;
     101           0 :   zclient->redist[redist_default] = 1;
     102             : 
     103             :   /* Set default-information redistribute to zero. */
     104           0 :   zclient->default_information = 0;
     105             : 
     106             :   /* Schedule first zclient connection. */
     107           0 :   if (zclient_debug)
     108           0 :     zlog_debug ("zclient start scheduled");
     109             : 
     110           0 :   zclient_event (ZCLIENT_SCHEDULE, zclient);
     111           0 : }
     112             : 
     113             : /* Stop zebra client services. */
     114             : void
     115           0 : zclient_stop (struct zclient *zclient)
     116             : {
     117           0 :   if (zclient_debug)
     118           0 :     zlog_debug ("zclient stopped");
     119             : 
     120             :   /* Stop threads. */
     121           0 :   THREAD_OFF(zclient->t_read);
     122           0 :   THREAD_OFF(zclient->t_connect);
     123           0 :   THREAD_OFF(zclient->t_write);
     124             : 
     125             :   /* Reset streams. */
     126           0 :   stream_reset(zclient->ibuf);
     127           0 :   stream_reset(zclient->obuf);
     128             : 
     129             :   /* Empty the write buffer. */
     130           0 :   buffer_reset(zclient->wb);
     131             : 
     132             :   /* Close socket. */
     133           0 :   if (zclient->sock >= 0)
     134             :     {
     135           0 :       close (zclient->sock);
     136           0 :       zclient->sock = -1;
     137             :     }
     138           0 :   zclient->fail = 0;
     139           0 : }
     140             : 
     141             : void
     142           0 : zclient_reset (struct zclient *zclient)
     143             : {
     144           0 :   zclient_stop (zclient);
     145           0 :   zclient_init (zclient, zclient->redist_default);
     146           0 : }
     147             : 
     148             : #ifdef HAVE_TCP_ZEBRA
     149             : 
     150             : /* Make socket to zebra daemon. Return zebra socket. */
     151             : static int
     152             : zclient_socket(void)
     153             : {
     154             :   int sock;
     155             :   int ret;
     156             :   struct sockaddr_in serv;
     157             : 
     158             :   /* We should think about IPv6 connection. */
     159             :   sock = socket (AF_INET, SOCK_STREAM, 0);
     160             :   if (sock < 0)
     161             :     return -1;
     162             :   
     163             :   /* Make server socket. */ 
     164             :   memset (&serv, 0, sizeof (struct sockaddr_in));
     165             :   serv.sin_family = AF_INET;
     166             :   serv.sin_port = htons (ZEBRA_PORT);
     167             : #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
     168             :   serv.sin_len = sizeof (struct sockaddr_in);
     169             : #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
     170             :   serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
     171             : 
     172             :   /* Connect to zebra. */
     173             :   ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
     174             :   if (ret < 0)
     175             :     {
     176             :       close (sock);
     177             :       return -1;
     178             :     }
     179             :   return sock;
     180             : }
     181             : 
     182             : #else
     183             : 
     184             : /* For sockaddr_un. */
     185             : #include <sys/un.h>
     186             : 
     187             : static int
     188           0 : zclient_socket_un (const char *path)
     189             : {
     190             :   int ret;
     191             :   int sock, len;
     192             :   struct sockaddr_un addr;
     193             : 
     194           0 :   sock = socket (AF_UNIX, SOCK_STREAM, 0);
     195           0 :   if (sock < 0)
     196           0 :     return -1;
     197             :   
     198             :   /* Make server socket. */ 
     199           0 :   memset (&addr, 0, sizeof (struct sockaddr_un));
     200           0 :   addr.sun_family = AF_UNIX;
     201           0 :   strncpy (addr.sun_path, path, strlen (path));
     202             : #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
     203             :   len = addr.sun_len = SUN_LEN(&addr);
     204             : #else
     205           0 :   len = sizeof (addr.sun_family) + strlen (addr.sun_path);
     206             : #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
     207             : 
     208           0 :   ret = connect (sock, (struct sockaddr *) &addr, len);
     209           0 :   if (ret < 0)
     210             :     {
     211           0 :       close (sock);
     212           0 :       return -1;
     213             :     }
     214           0 :   return sock;
     215             : }
     216             : 
     217             : #endif /* HAVE_TCP_ZEBRA */
     218             : 
     219             : /**
     220             :  * Connect to zebra daemon.
     221             :  * @param zclient a pointer to zclient structure
     222             :  * @return socket fd just to make sure that connection established
     223             :  * @see zclient_init
     224             :  * @see zclient_new
     225             :  */
     226             : int
     227           0 : zclient_socket_connect (struct zclient *zclient)
     228             : {
     229             : #ifdef HAVE_TCP_ZEBRA
     230             :   zclient->sock = zclient_socket ();
     231             : #else
     232           0 :   zclient->sock = zclient_socket_un (zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH);
     233             : #endif
     234           0 :   return zclient->sock;
     235             : }
     236             : 
     237             : static int
     238           0 : zclient_failed(struct zclient *zclient)
     239             : {
     240           0 :   zclient->fail++;
     241           0 :   zclient_stop(zclient);
     242           0 :   zclient_event(ZCLIENT_CONNECT, zclient);
     243           0 :   return -1;
     244             : }
     245             : 
     246             : static int
     247           0 : zclient_flush_data(struct thread *thread)
     248             : {
     249           0 :   struct zclient *zclient = THREAD_ARG(thread);
     250             : 
     251           0 :   zclient->t_write = NULL;
     252           0 :   if (zclient->sock < 0)
     253           0 :     return -1;
     254           0 :   switch (buffer_flush_available(zclient->wb, zclient->sock))
     255             :     {
     256             :     case BUFFER_ERROR:
     257           0 :       zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
     258             :                 __func__, zclient->sock);
     259           0 :       return zclient_failed(zclient);
     260             :       break;
     261             :     case BUFFER_PENDING:
     262           0 :       zclient->t_write = thread_add_write(master, zclient_flush_data,
     263             :                                           zclient, zclient->sock);
     264           0 :       break;
     265             :     case BUFFER_EMPTY:
     266           0 :       break;
     267             :     }
     268           0 :   return 0;
     269             : }
     270             : 
     271             : int
     272           0 : zclient_send_message(struct zclient *zclient)
     273             : {
     274           0 :   if (zclient->sock < 0)
     275           0 :     return -1;
     276           0 :   switch (buffer_write(zclient->wb, zclient->sock, STREAM_DATA(zclient->obuf),
     277             :                        stream_get_endp(zclient->obuf)))
     278             :     {
     279             :     case BUFFER_ERROR:
     280           0 :       zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
     281             :                  __func__, zclient->sock);
     282           0 :       return zclient_failed(zclient);
     283             :       break;
     284             :     case BUFFER_EMPTY:
     285           0 :       THREAD_OFF(zclient->t_write);
     286           0 :       break;
     287             :     case BUFFER_PENDING:
     288           0 :       THREAD_WRITE_ON(master, zclient->t_write,
     289             :                       zclient_flush_data, zclient, zclient->sock);
     290           0 :       break;
     291             :     }
     292           0 :   return 0;
     293             : }
     294             : 
     295             : void
     296           0 : zclient_create_header (struct stream *s, uint16_t command)
     297             : {
     298             :   /* length placeholder, caller can update */
     299           0 :   stream_putw (s, ZEBRA_HEADER_SIZE);
     300           0 :   stream_putc (s, ZEBRA_HEADER_MARKER);
     301           0 :   stream_putc (s, ZSERV_VERSION);
     302           0 :   stream_putw (s, command);
     303           0 : }
     304             : 
     305             : /* Send simple Zebra message. */
     306             : static int
     307           0 : zebra_message_send (struct zclient *zclient, int command)
     308             : {
     309             :   struct stream *s;
     310             : 
     311             :   /* Get zclient output buffer. */
     312           0 :   s = zclient->obuf;
     313           0 :   stream_reset (s);
     314             : 
     315             :   /* Send very simple command only Zebra message. */
     316           0 :   zclient_create_header (s, command);
     317             :   
     318           0 :   return zclient_send_message(zclient);
     319             : }
     320             : 
     321             : static int
     322           0 : zebra_hello_send (struct zclient *zclient)
     323             : {
     324             :   struct stream *s;
     325             : 
     326           0 :   if (zclient->redist_default)
     327             :     {
     328           0 :       s = zclient->obuf;
     329           0 :       stream_reset (s);
     330             : 
     331           0 :       zclient_create_header (s, ZEBRA_HELLO);
     332           0 :       stream_putc (s, zclient->redist_default);
     333           0 :       stream_putw_at (s, 0, stream_get_endp (s));
     334           0 :       return zclient_send_message(zclient);
     335             :     }
     336             : 
     337           0 :   return 0;
     338             : }
     339             : 
     340             : /* Make connection to zebra daemon. */
     341             : int
     342           0 : zclient_start (struct zclient *zclient)
     343             : {
     344             :   int i;
     345             : 
     346           0 :   if (zclient_debug)
     347           0 :     zlog_debug ("zclient_start is called");
     348             : 
     349             :   /* zclient is disabled. */
     350           0 :   if (! zclient->enable)
     351           0 :     return 0;
     352             : 
     353             :   /* If already connected to the zebra. */
     354           0 :   if (zclient->sock >= 0)
     355           0 :     return 0;
     356             : 
     357             :   /* Check connect thread. */
     358           0 :   if (zclient->t_connect)
     359           0 :     return 0;
     360             : 
     361           0 :   if (zclient_socket_connect(zclient) < 0)
     362             :     {
     363           0 :       if (zclient_debug)
     364           0 :         zlog_debug ("zclient connection fail");
     365           0 :       zclient->fail++;
     366           0 :       zclient_event (ZCLIENT_CONNECT, zclient);
     367           0 :       return -1;
     368             :     }
     369             : 
     370           0 :   if (set_nonblocking(zclient->sock) < 0)
     371           0 :     zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock);
     372             : 
     373             :   /* Clear fail count. */
     374           0 :   zclient->fail = 0;
     375           0 :   if (zclient_debug)
     376           0 :     zlog_debug ("zclient connect success with socket [%d]", zclient->sock);
     377             :       
     378             :   /* Create read thread. */
     379           0 :   zclient_event (ZCLIENT_READ, zclient);
     380             : 
     381           0 :   zebra_hello_send (zclient);
     382             : 
     383             :   /* We need router-id information. */
     384           0 :   zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
     385             : 
     386             :   /* We need interface information. */
     387           0 :   zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
     388             : 
     389             :   /* Flush all redistribute request. */
     390           0 :   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
     391           0 :     if (i != zclient->redist_default && zclient->redist[i])
     392           0 :       zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i);
     393             : 
     394             :   /* If default information is needed. */
     395           0 :   if (zclient->default_information)
     396           0 :     zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
     397             : 
     398           0 :   return 0;
     399             : }
     400             : 
     401             : /* This function is a wrapper function for calling zclient_start from
     402             :    timer or event thread. */
     403             : static int
     404           0 : zclient_connect (struct thread *t)
     405             : {
     406             :   struct zclient *zclient;
     407             : 
     408           0 :   zclient = THREAD_ARG (t);
     409           0 :   zclient->t_connect = NULL;
     410             : 
     411           0 :   if (zclient_debug)
     412           0 :     zlog_debug ("zclient_connect is called");
     413             : 
     414           0 :   return zclient_start (zclient);
     415             : }
     416             : 
     417             :  /* 
     418             :   * "xdr_encode"-like interface that allows daemon (client) to send
     419             :   * a message to zebra server for a route that needs to be
     420             :   * added/deleted to the kernel. Info about the route is specified
     421             :   * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
     422             :   * the info down the zclient socket using the stream_* functions.
     423             :   * 
     424             :   * The corresponding read ("xdr_decode") function on the server
     425             :   * side is zread_ipv4_add()/zread_ipv4_delete().
     426             :   *
     427             :   *  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
     428             :   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     429             :   * |            Length (2)         |    Command    | Route Type    |
     430             :   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     431             :   * | ZEBRA Flags   | Message Flags | Prefix length |
     432             :   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     433             :   * | Destination IPv4 Prefix for route                             |
     434             :   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     435             :   * | Nexthop count | 
     436             :   * +-+-+-+-+-+-+-+-+
     437             :   *
     438             :   * 
     439             :   * A number of IPv4 nexthop(s) or nexthop interface index(es) are then 
     440             :   * described, as per the Nexthop count. Each nexthop described as:
     441             :   *
     442             :   * +-+-+-+-+-+-+-+-+
     443             :   * | Nexthop Type  |  Set to one of ZEBRA_NEXTHOP_*
     444             :   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     445             :   * |       IPv4 Nexthop address or Interface Index number          |
     446             :   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     447             :   *
     448             :   * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
     449             :   * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_ 
     450             :   * nexthop information is provided, and the message describes a prefix
     451             :   * to blackhole or reject route.
     452             :   *
     453             :   * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
     454             :   * byte value.
     455             :   * 
     456             :   * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
     457             :   * byte value.
     458             :   *
     459             :   * XXX: No attention paid to alignment.
     460             :   */ 
     461             : int
     462           0 : zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
     463             :                  struct zapi_ipv4 *api)
     464             : {
     465             :   int i;
     466             :   int psize;
     467             :   struct stream *s;
     468             : 
     469             :   /* Reset stream. */
     470           0 :   s = zclient->obuf;
     471           0 :   stream_reset (s);
     472             :   
     473           0 :   zclient_create_header (s, cmd);
     474             :   
     475             :   /* Put type and nexthop. */
     476           0 :   stream_putc (s, api->type);
     477           0 :   stream_putc (s, api->flags);
     478           0 :   stream_putc (s, api->message);
     479           0 :   stream_putw (s, api->safi);
     480             : 
     481             :   /* Put prefix information. */
     482           0 :   psize = PSIZE (p->prefixlen);
     483           0 :   stream_putc (s, p->prefixlen);
     484           0 :   stream_write (s, (u_char *) & p->prefix, psize);
     485             : 
     486             :   /* Nexthop, ifindex, distance and metric information. */
     487           0 :   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
     488             :     {
     489           0 :       if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
     490             :         {
     491           0 :           stream_putc (s, 1);
     492           0 :           stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
     493             :           /* XXX assert(api->nexthop_num == 0); */
     494             :           /* XXX assert(api->ifindex_num == 0); */
     495             :         }
     496             :       else
     497           0 :         stream_putc (s, api->nexthop_num + api->ifindex_num);
     498             : 
     499           0 :       for (i = 0; i < api->nexthop_num; i++)
     500             :         {
     501           0 :           stream_putc (s, ZEBRA_NEXTHOP_IPV4);
     502           0 :           stream_put_in_addr (s, api->nexthop[i]);
     503             :         }
     504           0 :       for (i = 0; i < api->ifindex_num; i++)
     505             :         {
     506           0 :           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
     507           0 :           stream_putl (s, api->ifindex[i]);
     508             :         }
     509             :     }
     510             : 
     511           0 :   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
     512           0 :     stream_putc (s, api->distance);
     513           0 :   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
     514           0 :     stream_putl (s, api->metric);
     515             : 
     516             :   /* Put length at the first point of the stream. */
     517           0 :   stream_putw_at (s, 0, stream_get_endp (s));
     518             : 
     519           0 :   return zclient_send_message(zclient);
     520             : }
     521             : 
     522             : #ifdef HAVE_IPV6
     523             : int
     524           0 : zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
     525             :                  struct prefix_ipv6 *src_p, struct zapi_ipv6 *api)
     526             : {
     527             :   int i;
     528             :   int psize;
     529             :   struct stream *s;
     530             : 
     531             :   /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL */
     532           0 :   assert (!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p);
     533             : 
     534             :   /* Reset stream. */
     535           0 :   s = zclient->obuf;
     536           0 :   stream_reset (s);
     537             : 
     538           0 :   zclient_create_header (s, cmd);
     539             : 
     540             :   /* Put type and nexthop. */
     541           0 :   stream_putc (s, api->type);
     542           0 :   stream_putc (s, api->flags);
     543           0 :   stream_putc (s, api->message);
     544           0 :   stream_putw (s, api->safi);
     545             :   
     546             :   /* Put prefix information. */
     547           0 :   psize = PSIZE (p->prefixlen);
     548           0 :   stream_putc (s, p->prefixlen);
     549           0 :   stream_write (s, (u_char *)&p->prefix, psize);
     550             : 
     551           0 :   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_SRCPFX))
     552             :     {
     553           0 :       psize = PSIZE (src_p->prefixlen);
     554           0 :       stream_putc (s, src_p->prefixlen);
     555           0 :       stream_write (s, (u_char *)&src_p->prefix, psize);
     556             :     }
     557             : 
     558             :   /* Nexthop, ifindex, distance and metric information. */
     559           0 :   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
     560             :     {
     561           0 :       stream_putc (s, api->nexthop_num + api->ifindex_num);
     562             : 
     563           0 :       for (i = 0; i < api->nexthop_num; i++)
     564             :         {
     565           0 :           stream_putc (s, ZEBRA_NEXTHOP_IPV6);
     566           0 :           stream_write (s, (u_char *)api->nexthop[i], 16);
     567             :         }
     568           0 :       for (i = 0; i < api->ifindex_num; i++)
     569             :         {
     570           0 :           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
     571           0 :           stream_putl (s, api->ifindex[i]);
     572             :         }
     573             :     }
     574             : 
     575           0 :   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
     576           0 :     stream_putc (s, api->distance);
     577           0 :   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
     578           0 :     stream_putl (s, api->metric);
     579             : 
     580             :   /* Put length at the first point of the stream. */
     581           0 :   stream_putw_at (s, 0, stream_get_endp (s));
     582             : 
     583           0 :   return zclient_send_message(zclient);
     584             : }
     585             : #endif /* HAVE_IPV6 */
     586             : 
     587             : /* 
     588             :  * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
     589             :  * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
     590             :  * then set/unset redist[type] in the client handle (a struct zserv) for the 
     591             :  * sending client
     592             :  */
     593             : int
     594           0 : zebra_redistribute_send (int command, struct zclient *zclient, int type)
     595             : {
     596             :   struct stream *s;
     597             : 
     598           0 :   s = zclient->obuf;
     599           0 :   stream_reset(s);
     600             :   
     601           0 :   zclient_create_header (s, command);
     602           0 :   stream_putc (s, type);
     603             :   
     604           0 :   stream_putw_at (s, 0, stream_get_endp (s));
     605             :   
     606           0 :   return zclient_send_message(zclient);
     607             : }
     608             : 
     609             : /* Router-id update from zebra daemon. */
     610             : void
     611           0 : zebra_router_id_update_read (struct stream *s, struct prefix *rid)
     612             : {
     613             :   int plen;
     614             : 
     615             :   /* Fetch interface address. */
     616           0 :   rid->family = stream_getc (s);
     617             : 
     618           0 :   plen = prefix_blen (rid);
     619           0 :   stream_get (&rid->u.prefix, s, plen);
     620           0 :   rid->prefixlen = stream_getc (s);
     621           0 : }
     622             : 
     623             : /* Interface addition from zebra daemon. */
     624             : /*  
     625             :  * The format of the message sent with type ZEBRA_INTERFACE_ADD or
     626             :  * ZEBRA_INTERFACE_DELETE from zebra to the client is:
     627             :  *     0                   1                   2                   3
     628             :  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     629             :  * +-+-+-+-+-+-+-+-+
     630             :  * |   type        |
     631             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     632             :  * |  ifname                                                       |
     633             :  * |                                                               |
     634             :  * |                                                               |
     635             :  * |                                                               |
     636             :  * |                                                               |
     637             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     638             :  * |         ifindex                                               |
     639             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     640             :  * |         if_flags                                              |
     641             :  * |                                                               |
     642             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     643             :  * |         metric                                                |
     644             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     645             :  * |         ifmtu                                                 |
     646             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     647             :  * |         ifmtu6                                                |
     648             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     649             :  * |         bandwidth                                             |
     650             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     651             :  * |         sockaddr_dl                                           |
     652             :  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     653             :  */
     654             : 
     655             : struct interface *
     656           0 : zebra_interface_add_read (struct stream *s)
     657             : {
     658             :   struct interface *ifp;
     659             :   char ifname_tmp[INTERFACE_NAMSIZ];
     660             : 
     661             :   /* Read interface name. */
     662           0 :   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
     663             : 
     664             :   /* Lookup/create interface by name. */
     665           0 :   ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ));
     666             : 
     667           0 :   zebra_interface_if_set_value (s, ifp);
     668             : 
     669           0 :   return ifp;
     670             : }
     671             : 
     672             : /* 
     673             :  * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
     674             :  * from zebra server.  The format of this message is the same as
     675             :  * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
     676             :  * comments for zebra_interface_add_read), except that no sockaddr_dl
     677             :  * is sent at the tail of the message.
     678             :  */
     679             : struct interface *
     680           0 : zebra_interface_state_read (struct stream *s)
     681             : {
     682             :   struct interface *ifp;
     683             :   char ifname_tmp[INTERFACE_NAMSIZ];
     684             : 
     685             :   /* Read interface name. */
     686           0 :   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
     687             : 
     688             :   /* Lookup this by interface index. */
     689           0 :   ifp = if_lookup_by_name_len (ifname_tmp,
     690             :                                strnlen(ifname_tmp, INTERFACE_NAMSIZ));
     691             : 
     692             :   /* If such interface does not exist, indicate an error */
     693           0 :   if (! ifp)
     694           0 :      return NULL;
     695             : 
     696           0 :   zebra_interface_if_set_value (s, ifp);
     697             : 
     698           0 :   return ifp;
     699             : }
     700             : 
     701             : /* 
     702             :  * format of message for address additon is:
     703             :  *    0
     704             :  *  0 1 2 3 4 5 6 7
     705             :  * +-+-+-+-+-+-+-+-+
     706             :  * |   type        |  ZEBRA_INTERFACE_ADDRESS_ADD or
     707             :  * +-+-+-+-+-+-+-+-+  ZEBRA_INTERFACE_ADDRES_DELETE
     708             :  * |               |
     709             :  * +               +
     710             :  * |   ifindex     |
     711             :  * +               +
     712             :  * |               |
     713             :  * +               +
     714             :  * |               |
     715             :  * +-+-+-+-+-+-+-+-+
     716             :  * |   ifc_flags   |  flags for connected address
     717             :  * +-+-+-+-+-+-+-+-+
     718             :  * |  addr_family  |
     719             :  * +-+-+-+-+-+-+-+-+
     720             :  * |    addr...    |
     721             :  * :               :
     722             :  * |               |
     723             :  * +-+-+-+-+-+-+-+-+
     724             :  * |    addr_len   |  len of addr. E.g., addr_len = 4 for ipv4 addrs.
     725             :  * +-+-+-+-+-+-+-+-+
     726             :  * |     daddr..   |
     727             :  * :               :
     728             :  * |               |
     729             :  * +-+-+-+-+-+-+-+-+
     730             :  *
     731             :  */
     732             : 
     733             : void
     734           0 : zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
     735             : {
     736             :   /* Read interface's index. */
     737           0 :   ifp->ifindex = stream_getl (s);
     738           0 :   ifp->status = stream_getc (s);
     739             : 
     740             :   /* Read interface's value. */
     741           0 :   ifp->flags = stream_getq (s);
     742           0 :   ifp->metric = stream_getl (s);
     743           0 :   ifp->mtu = stream_getl (s);
     744           0 :   ifp->mtu6 = stream_getl (s);
     745           0 :   ifp->bandwidth = stream_getl (s);
     746             : #ifdef HAVE_STRUCT_SOCKADDR_DL
     747             :   stream_get (&ifp->sdl, s, sizeof (ifp->sdl_storage));
     748             : #else
     749           0 :   ifp->hw_addr_len = stream_getl (s);
     750           0 :   if (ifp->hw_addr_len)
     751           0 :     stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
     752             : #endif /* HAVE_STRUCT_SOCKADDR_DL */
     753           0 : }
     754             : 
     755             : static int
     756           0 : memconstant(const void *s, int c, size_t n)
     757             : {
     758           0 :   const u_char *p = s;
     759             : 
     760           0 :   while (n-- > 0)
     761           0 :     if (*p++ != c)
     762           0 :       return 0;
     763           0 :   return 1;
     764             : }
     765             : 
     766             : struct connected *
     767           0 : zebra_interface_address_read (int type, struct stream *s)
     768             : {
     769             :   unsigned int ifindex;
     770             :   struct interface *ifp;
     771             :   struct connected *ifc;
     772             :   struct prefix p, d;
     773             :   int family;
     774             :   int plen;
     775             :   u_char ifc_flags;
     776             : 
     777           0 :   memset (&p, 0, sizeof(p));
     778           0 :   memset (&d, 0, sizeof(d));
     779             : 
     780             :   /* Get interface index. */
     781           0 :   ifindex = stream_getl (s);
     782             : 
     783             :   /* Lookup index. */
     784           0 :   ifp = if_lookup_by_index (ifindex);
     785           0 :   if (ifp == NULL)
     786             :     {
     787           0 :       zlog_warn ("zebra_interface_address_read(%s): "
     788             :                  "Can't find interface by ifindex: %d ",
     789             :                  (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
     790             :                  ifindex);
     791           0 :       return NULL;
     792             :     }
     793             : 
     794             :   /* Fetch flag. */
     795           0 :   ifc_flags = stream_getc (s);
     796             : 
     797             :   /* Fetch interface address. */
     798           0 :   family = p.family = stream_getc (s);
     799             : 
     800           0 :   plen = prefix_blen (&p);
     801           0 :   stream_get (&p.u.prefix, s, plen);
     802           0 :   p.prefixlen = stream_getc (s);
     803             : 
     804             :   /* Fetch destination address. */
     805           0 :   stream_get (&d.u.prefix, s, plen);
     806           0 :   d.family = family;
     807             : 
     808           0 :   if (type == ZEBRA_INTERFACE_ADDRESS_ADD) 
     809             :     {
     810             :        /* N.B. NULL destination pointers are encoded as all zeroes */
     811           0 :        ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ?
     812             :                                               NULL : &d));
     813           0 :        if (ifc != NULL)
     814             :          {
     815           0 :            ifc->flags = ifc_flags;
     816           0 :            if (ifc->destination)
     817           0 :              ifc->destination->prefixlen = ifc->address->prefixlen;
     818             :          }
     819             :     }
     820             :   else
     821             :     {
     822           0 :       assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
     823           0 :       ifc = connected_delete_by_prefix(ifp, &p);
     824             :     }
     825             : 
     826           0 :   return ifc;
     827             : }
     828             : 
     829             : 
     830             : /* Zebra client message read function. */
     831             : static int
     832           0 : zclient_read (struct thread *thread)
     833             : {
     834             :   size_t already;
     835             :   uint16_t length, command;
     836             :   uint8_t marker, version;
     837             :   struct zclient *zclient;
     838             : 
     839             :   /* Get socket to zebra. */
     840           0 :   zclient = THREAD_ARG (thread);
     841           0 :   zclient->t_read = NULL;
     842             : 
     843             :   /* Read zebra header (if we don't have it already). */
     844           0 :   if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
     845             :     {
     846             :       ssize_t nbyte;
     847           0 :       if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
     848           0 :                                      ZEBRA_HEADER_SIZE-already)) == 0) ||
     849             :           (nbyte == -1))
     850             :         {
     851           0 :           if (zclient_debug)
     852           0 :            zlog_debug ("zclient connection closed socket [%d].", zclient->sock);
     853           0 :           return zclient_failed(zclient);
     854             :         }
     855           0 :       if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
     856             :         {
     857             :           /* Try again later. */
     858           0 :           zclient_event (ZCLIENT_READ, zclient);
     859           0 :           return 0;
     860             :         }
     861           0 :       already = ZEBRA_HEADER_SIZE;
     862             :     }
     863             : 
     864             :   /* Reset to read from the beginning of the incoming packet. */
     865           0 :   stream_set_getp(zclient->ibuf, 0);
     866             : 
     867             :   /* Fetch header values. */
     868           0 :   length = stream_getw (zclient->ibuf);
     869           0 :   marker = stream_getc (zclient->ibuf);
     870           0 :   version = stream_getc (zclient->ibuf);
     871           0 :   command = stream_getw (zclient->ibuf);
     872             :   
     873           0 :   if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
     874             :     {
     875           0 :       zlog_err("%s: socket %d version mismatch, marker %d, version %d",
     876             :                __func__, zclient->sock, marker, version);
     877           0 :       return zclient_failed(zclient);
     878             :     }
     879             :   
     880           0 :   if (length < ZEBRA_HEADER_SIZE) 
     881             :     {
     882           0 :       zlog_err("%s: socket %d message length %u is less than %d ",
     883             :                __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
     884           0 :       return zclient_failed(zclient);
     885             :     }
     886             : 
     887             :   /* Length check. */
     888           0 :   if (length > STREAM_SIZE(zclient->ibuf))
     889             :     {
     890             :       struct stream *ns;
     891           0 :       zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
     892           0 :                 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
     893           0 :       ns = stream_new(length);
     894           0 :       stream_copy(ns, zclient->ibuf);
     895           0 :       stream_free (zclient->ibuf);
     896           0 :       zclient->ibuf = ns;
     897             :     }
     898             : 
     899             :   /* Read rest of zebra packet. */
     900           0 :   if (already < length)
     901             :     {
     902             :       ssize_t nbyte;
     903           0 :       if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
     904           0 :                                      length-already)) == 0) ||
     905             :           (nbyte == -1))
     906             :         {
     907           0 :           if (zclient_debug)
     908           0 :             zlog_debug("zclient connection closed socket [%d].", zclient->sock);
     909           0 :           return zclient_failed(zclient);
     910             :         }
     911           0 :       if (nbyte != (ssize_t)(length-already))
     912             :         {
     913             :           /* Try again later. */
     914           0 :           zclient_event (ZCLIENT_READ, zclient);
     915           0 :           return 0;
     916             :         }
     917             :     }
     918             : 
     919           0 :   length -= ZEBRA_HEADER_SIZE;
     920             : 
     921           0 :   if (zclient_debug)
     922           0 :     zlog_debug("zclient 0x%p command 0x%x \n", zclient, command);
     923             : 
     924           0 :   switch (command)
     925             :     {
     926             :     case ZEBRA_ROUTER_ID_UPDATE:
     927           0 :       if (zclient->router_id_update)
     928           0 :         (*zclient->router_id_update) (command, zclient, length);
     929           0 :       break;
     930             :     case ZEBRA_INTERFACE_ADD:
     931           0 :       if (zclient->interface_add)
     932           0 :         (*zclient->interface_add) (command, zclient, length);
     933           0 :       break;
     934             :     case ZEBRA_INTERFACE_DELETE:
     935           0 :       if (zclient->interface_delete)
     936           0 :         (*zclient->interface_delete) (command, zclient, length);
     937           0 :       break;
     938             :     case ZEBRA_INTERFACE_ADDRESS_ADD:
     939           0 :       if (zclient->interface_address_add)
     940           0 :         (*zclient->interface_address_add) (command, zclient, length);
     941           0 :       break;
     942             :     case ZEBRA_INTERFACE_ADDRESS_DELETE:
     943           0 :       if (zclient->interface_address_delete)
     944           0 :         (*zclient->interface_address_delete) (command, zclient, length);
     945           0 :       break;
     946             :     case ZEBRA_INTERFACE_UP:
     947           0 :       if (zclient->interface_up)
     948           0 :         (*zclient->interface_up) (command, zclient, length);
     949           0 :       break;
     950             :     case ZEBRA_INTERFACE_DOWN:
     951           0 :       if (zclient->interface_down)
     952           0 :         (*zclient->interface_down) (command, zclient, length);
     953           0 :       break;
     954             :     case ZEBRA_IPV4_ROUTE_ADD:
     955           0 :       if (zclient->ipv4_route_add)
     956           0 :         (*zclient->ipv4_route_add) (command, zclient, length);
     957           0 :       break;
     958             :     case ZEBRA_IPV4_ROUTE_DELETE:
     959           0 :       if (zclient->ipv4_route_delete)
     960           0 :         (*zclient->ipv4_route_delete) (command, zclient, length);
     961           0 :       break;
     962             :     case ZEBRA_IPV6_ROUTE_ADD:
     963           0 :       if (zclient->ipv6_route_add)
     964           0 :         (*zclient->ipv6_route_add) (command, zclient, length);
     965           0 :       break;
     966             :     case ZEBRA_IPV6_ROUTE_DELETE:
     967           0 :       if (zclient->ipv6_route_delete)
     968           0 :         (*zclient->ipv6_route_delete) (command, zclient, length);
     969           0 :       break;
     970             :     default:
     971           0 :       break;
     972             :     }
     973             : 
     974           0 :   if (zclient->sock < 0)
     975             :     /* Connection was closed during packet processing. */
     976           0 :     return -1;
     977             : 
     978             :   /* Register read thread. */
     979           0 :   stream_reset(zclient->ibuf);
     980           0 :   zclient_event (ZCLIENT_READ, zclient);
     981             : 
     982           0 :   return 0;
     983             : }
     984             : 
     985             : void
     986           0 : zclient_redistribute (int command, struct zclient *zclient, int type)
     987             : {
     988             : 
     989           0 :   if (command == ZEBRA_REDISTRIBUTE_ADD) 
     990             :     {
     991           0 :       if (zclient->redist[type])
     992           0 :          return;
     993           0 :       zclient->redist[type] = 1;
     994             :     }
     995             :   else
     996             :     {
     997           0 :       if (!zclient->redist[type])
     998           0 :          return;
     999           0 :       zclient->redist[type] = 0;
    1000             :     }
    1001             : 
    1002           0 :   if (zclient->sock > 0)
    1003           0 :     zebra_redistribute_send (command, zclient, type);
    1004             : }
    1005             : 
    1006             : 
    1007             : void
    1008           0 : zclient_redistribute_default (int command, struct zclient *zclient)
    1009             : {
    1010             : 
    1011           0 :   if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
    1012             :     {
    1013           0 :       if (zclient->default_information)
    1014           0 :         return;
    1015           0 :       zclient->default_information = 1;
    1016             :     }
    1017             :   else 
    1018             :     {
    1019           0 :       if (!zclient->default_information)
    1020           0 :         return;
    1021           0 :       zclient->default_information = 0;
    1022             :     }
    1023             : 
    1024           0 :   if (zclient->sock > 0)
    1025           0 :     zebra_message_send (zclient, command);
    1026             : }
    1027             : 
    1028             : static void
    1029           0 : zclient_event (enum event event, struct zclient *zclient)
    1030             : {
    1031           0 :   switch (event)
    1032             :     {
    1033             :     case ZCLIENT_SCHEDULE:
    1034           0 :       if (! zclient->t_connect)
    1035           0 :         zclient->t_connect =
    1036           0 :           thread_add_event (master, zclient_connect, zclient, 0);
    1037           0 :       break;
    1038             :     case ZCLIENT_CONNECT:
    1039           0 :       if (zclient->fail >= 10)
    1040           0 :         return;
    1041           0 :       if (zclient_debug)
    1042           0 :         zlog_debug ("zclient connect schedule interval is %d", 
    1043           0 :                    zclient->fail < 3 ? 10 : 60);
    1044           0 :       if (! zclient->t_connect)
    1045           0 :         zclient->t_connect = 
    1046           0 :           thread_add_timer (master, zclient_connect, zclient,
    1047             :                             zclient->fail < 3 ? 10 : 60);
    1048           0 :       break;
    1049             :     case ZCLIENT_READ:
    1050           0 :       zclient->t_read = 
    1051           0 :         thread_add_read (master, zclient_read, zclient, zclient->sock);
    1052           0 :       break;
    1053             :     }
    1054             : }
    1055             : 
    1056             : void
    1057           0 : zclient_serv_path_set (char *path)
    1058             : {
    1059             :   struct stat sb;
    1060             : 
    1061             :   /* reset */
    1062           0 :   zclient_serv_path = NULL;
    1063             : 
    1064             :   /* test if `path' is socket. don't set it otherwise. */
    1065           0 :   if (stat(path, &sb) == -1)
    1066             :     {
    1067           0 :       zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
    1068           0 :       return;
    1069             :     }
    1070             : 
    1071           0 :   if ((sb.st_mode & S_IFMT) != S_IFSOCK)
    1072             :     {
    1073           0 :       zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
    1074           0 :       return;
    1075             :     }
    1076             : 
    1077             :   /* it seems that path is unix socket */
    1078           0 :   zclient_serv_path = path;
    1079             : }
    1080             : 

Generated by: LCOV version 1.10