1 /* Zebra's client library.
 
   2  * Copyright (C) 1999 Kunihiro Ishiguro
 
   3  * Copyright (C) 2005 Andrew J. Schorr
 
   5  * This file is part of GNU Zebra.
 
   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.
 
  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.
 
  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,
 
  36 /* Zebra client events. */
 
  37 enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
 
  39 /* Prototype for event manager. */
 
  40 static void zclient_event (enum event, struct zclient *);
 
  42 const char *zclient_serv_path = NULL;
 
  44 /* This file local debug flag. */
 
  45 int zclient_debug = 0;
 
  47 /* Allocate zclient structure. */
 
  49 zclient_new (struct thread_master *master)
 
  51   struct zclient *zclient;
 
  52   zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
 
  54   zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
 
  55   zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
 
  56   zclient->wb = buffer_new(0);
 
  57   zclient->master = master;
 
  62 /* This function is only called when exiting, because
 
  63    many parts of the code do not check for I/O errors, so they could
 
  64    reference an invalid pointer if the structure was ever freed.
 
  66    Free zclient structure. */
 
  68 zclient_free (struct zclient *zclient)
 
  71     stream_free(zclient->ibuf);
 
  73     stream_free(zclient->obuf);
 
  75     buffer_free(zclient->wb);
 
  77   XFREE (MTYPE_ZCLIENT, zclient);
 
  80 /* Initialize zebra client.  Argument redist_default is unwanted
 
  81    redistribute route type. */
 
  83 zclient_init (struct zclient *zclient, int redist_default)
 
  87   /* Enable zebra client connection by default. */
 
  90   /* Set -1 to the default socket value. */
 
  93   /* Clear redistribution flags. */
 
  94   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 
  95     zclient->redist[i] = vrf_bitmap_init ();
 
  97   /* Set unwanted redistribute route.  bgpd does not need BGP route
 
  99   zclient->redist_default = redist_default;
 
 101   /* Set default-information redistribute to zero. */
 
 102   zclient->default_information = vrf_bitmap_init ();
 
 104   /* Schedule first zclient connection. */
 
 106     zlog_debug ("zclient start scheduled");
 
 108   zclient_event (ZCLIENT_SCHEDULE, zclient);
 
 111 /* Stop zebra client services. */
 
 113 zclient_stop (struct zclient *zclient)
 
 118     zlog_debug ("zclient stopped");
 
 121   THREAD_OFF(zclient->t_read);
 
 122   THREAD_OFF(zclient->t_connect);
 
 123   THREAD_OFF(zclient->t_write);
 
 126   stream_reset(zclient->ibuf);
 
 127   stream_reset(zclient->obuf);
 
 129   /* Empty the write buffer. */
 
 130   buffer_reset(zclient->wb);
 
 133   if (zclient->sock >= 0)
 
 135       close (zclient->sock);
 
 140   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 
 142       vrf_bitmap_free(zclient->redist[i]);
 
 143       zclient->redist[i] = VRF_BITMAP_NULL;
 
 145   vrf_bitmap_free(zclient->default_information);
 
 146   zclient->default_information = VRF_BITMAP_NULL;
 
 150 zclient_reset (struct zclient *zclient)
 
 152   zclient_stop (zclient);
 
 153   zclient_init (zclient, zclient->redist_default);
 
 156 #ifdef HAVE_TCP_ZEBRA
 
 158 /* Make socket to zebra daemon. Return zebra socket. */
 
 164   struct sockaddr_in serv;
 
 166   /* We should think about IPv6 connection. */
 
 167   sock = socket (AF_INET, SOCK_STREAM, 0);
 
 171   /* Make server socket. */ 
 
 172   memset (&serv, 0, sizeof (struct sockaddr_in));
 
 173   serv.sin_family = AF_INET;
 
 174   serv.sin_port = htons (ZEBRA_PORT);
 
 175 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
 
 176   serv.sin_len = sizeof (struct sockaddr_in);
 
 177 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
 
 178   serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
 
 180   /* Connect to zebra. */
 
 181   ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
 
 184       zlog_warn ("%s connect failure: %d", __PRETTY_FUNCTION__, errno);
 
 193 /* For sockaddr_un. */
 
 197 zclient_socket_un (const char *path)
 
 201   struct sockaddr_un addr;
 
 203   sock = socket (AF_UNIX, SOCK_STREAM, 0);
 
 207   /* Make server socket. */ 
 
 208   memset (&addr, 0, sizeof (struct sockaddr_un));
 
 209   addr.sun_family = AF_UNIX;
 
 210   strncpy (addr.sun_path, path, strlen (path));
 
 211 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
 
 212   len = addr.sun_len = SUN_LEN(&addr);
 
 214   len = sizeof (addr.sun_family) + strlen (addr.sun_path);
 
 215 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
 
 217   ret = connect (sock, (struct sockaddr *) &addr, len);
 
 220       zlog_warn ("%s connect failure: %d", __PRETTY_FUNCTION__, errno);
 
 227 #endif /* HAVE_TCP_ZEBRA */
 
 230  * Connect to zebra daemon.
 
 231  * @param zclient a pointer to zclient structure
 
 232  * @return socket fd just to make sure that connection established
 
 237 zclient_socket_connect (struct zclient *zclient)
 
 239 #ifdef HAVE_TCP_ZEBRA
 
 240   zclient->sock = zclient_socket ();
 
 242   zclient->sock = zclient_socket_un (zclient_serv_path_get());
 
 244   return zclient->sock;
 
 248 zclient_failed(struct zclient *zclient)
 
 251   zclient_stop(zclient);
 
 252   zclient_event(ZCLIENT_CONNECT, zclient);
 
 257 zclient_flush_data(struct thread *thread)
 
 259   struct zclient *zclient = THREAD_ARG(thread);
 
 261   zclient->t_write = NULL;
 
 262   if (zclient->sock < 0)
 
 264   switch (buffer_flush_available(zclient->wb, zclient->sock))
 
 267       zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
 
 268                 __func__, zclient->sock);
 
 269       return zclient_failed(zclient);
 
 272       zclient->t_write = thread_add_write (zclient->master, zclient_flush_data,
 
 273                                            zclient, zclient->sock);
 
 282 zclient_send_message(struct zclient *zclient)
 
 284   if (zclient->sock < 0)
 
 286   switch (buffer_write(zclient->wb, zclient->sock, STREAM_DATA(zclient->obuf),
 
 287                        stream_get_endp(zclient->obuf)))
 
 290       zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
 
 291                  __func__, zclient->sock);
 
 292       return zclient_failed(zclient);
 
 295       THREAD_OFF(zclient->t_write);
 
 298       THREAD_WRITE_ON (zclient->master, zclient->t_write,
 
 299                        zclient_flush_data, zclient, zclient->sock);
 
 306 zclient_create_header (struct stream *s, uint16_t command, vrf_id_t vrf_id)
 
 308   /* length placeholder, caller can update */
 
 309   stream_putw (s, ZEBRA_HEADER_SIZE);
 
 310   stream_putc (s, ZEBRA_HEADER_MARKER);
 
 311   stream_putc (s, ZSERV_VERSION);
 
 312   stream_putw (s, vrf_id);
 
 313   stream_putw (s, command);
 
 317 zclient_read_header (struct stream *s, int sock, u_int16_t *size, u_char *marker,
 
 318                      u_char *version, u_int16_t *vrf_id, u_int16_t *cmd)
 
 320   if (stream_read (s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
 
 323   *size = stream_getw (s) - ZEBRA_HEADER_SIZE;
 
 324   *marker = stream_getc (s);
 
 325   *version = stream_getc (s);
 
 326   *vrf_id = stream_getw (s);
 
 327   *cmd = stream_getw (s);
 
 329   if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER)
 
 331       zlog_err("%s: socket %d version mismatch, marker %d, version %d",
 
 332                __func__, sock, *marker, *version);
 
 336   if (*size && stream_read (s, sock, *size) != *size)
 
 342 /* Send simple Zebra message. */
 
 344 zebra_message_send (struct zclient *zclient, int command, vrf_id_t vrf_id)
 
 348   /* Get zclient output buffer. */
 
 352   /* Send very simple command only Zebra message. */
 
 353   zclient_create_header (s, command, vrf_id);
 
 355   return zclient_send_message(zclient);
 
 359 zebra_hello_send (struct zclient *zclient)
 
 363   if (zclient->redist_default)
 
 368       /* The VRF ID in the HELLO message is always 0. */
 
 369       zclient_create_header (s, ZEBRA_HELLO, VRF_DEFAULT);
 
 370       stream_putc (s, zclient->redist_default);
 
 371       stream_putw_at (s, 0, stream_get_endp (s));
 
 372       return zclient_send_message(zclient);
 
 378 /* Send requests to zebra daemon for the information in a VRF. */
 
 380 zclient_send_requests (struct zclient *zclient, vrf_id_t vrf_id)
 
 384   /* zclient is disabled. */
 
 385   if (! zclient->enable)
 
 388   /* If not connected to the zebra yet. */
 
 389   if (zclient->sock < 0)
 
 393     zlog_debug ("%s: send messages for VRF %u", __func__, vrf_id);
 
 395   /* We need router-id information. */
 
 396   zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD, vrf_id);
 
 398   /* We need interface information. */
 
 399   zebra_message_send (zclient, ZEBRA_INTERFACE_ADD, vrf_id);
 
 401   /* Set unwanted redistribute route. */
 
 402   vrf_bitmap_set (zclient->redist[zclient->redist_default], vrf_id);
 
 404   /* Flush all redistribute request. */
 
 405   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 
 406     if (i != zclient->redist_default &&
 
 407         vrf_bitmap_check (zclient->redist[i], vrf_id))
 
 408       zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i, vrf_id);
 
 410   /* If default information is needed. */
 
 411   if (vrf_bitmap_check (zclient->default_information, VRF_DEFAULT))
 
 412     zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD, vrf_id);
 
 415 /* Make connection to zebra daemon. */
 
 417 zclient_start (struct zclient *zclient)
 
 420     zlog_debug ("zclient_start is called");
 
 422   /* zclient is disabled. */
 
 423   if (! zclient->enable)
 
 426   /* If already connected to the zebra. */
 
 427   if (zclient->sock >= 0)
 
 430   /* Check connect thread. */
 
 431   if (zclient->t_connect)
 
 435    * If we fail to connect to the socket on initialization,
 
 436    * Let's wait a second and see if we can reconnect.
 
 437    * Cause if we don't connect, we never attempt to
 
 438    * reconnect.  On startup if zebra is slow we
 
 439    * can get into this situation.
 
 441   while (zclient_socket_connect(zclient) < 0 && zclient->fail < 5)
 
 444         zlog_debug ("zclient connection fail");
 
 449   if (zclient->sock < 0)
 
 451       zclient_event (ZCLIENT_CONNECT, zclient);
 
 455   if (set_nonblocking(zclient->sock) < 0)
 
 456     zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock);
 
 458   /* Clear fail count. */
 
 461     zlog_debug ("zclient connect success with socket [%d]", zclient->sock);
 
 463   /* Create read thread. */
 
 464   zclient_event (ZCLIENT_READ, zclient);
 
 466   zebra_hello_send (zclient);
 
 468   /* Inform the successful connection. */
 
 469   if (zclient->zebra_connected)
 
 470     (*zclient->zebra_connected) (zclient);
 
 475 /* This function is a wrapper function for calling zclient_start from
 
 476    timer or event thread. */
 
 478 zclient_connect (struct thread *t)
 
 480   struct zclient *zclient;
 
 482   zclient = THREAD_ARG (t);
 
 483   zclient->t_connect = NULL;
 
 486     zlog_debug ("zclient_connect is called");
 
 488   return zclient_start (zclient);
 
 492   * "xdr_encode"-like interface that allows daemon (client) to send
 
 493   * a message to zebra server for a route that needs to be
 
 494   * added/deleted to the kernel. Info about the route is specified
 
 495   * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
 
 496   * the info down the zclient socket using the stream_* functions.
 
 498   * The corresponding read ("xdr_decode") function on the server
 
 499   * side is zread_ipv4_add()/zread_ipv4_delete().
 
 501   *  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
 
 502   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 503   * |            Length (2)         |    Command    | Route Type    |
 
 504   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 505   * | ZEBRA Flags   | Message Flags | Prefix length |
 
 506   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 507   * | Destination IPv4 Prefix for route                             |
 
 508   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 513   * A number of IPv4 nexthop(s) or nexthop interface index(es) are then 
 
 514   * described, as per the Nexthop count. Each nexthop described as:
 
 517   * | Nexthop Type  |  Set to one of ZEBRA_NEXTHOP_*
 
 518   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 519   * |       IPv4 Nexthop address or Interface Index number          |
 
 520   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 522   * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
 
 523   * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_ 
 
 524   * nexthop information is provided, and the message describes a prefix
 
 525   * to blackhole or reject route.
 
 527   * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
 
 530   * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
 
 533   * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
 
 535   * XXX: No attention paid to alignment.
 
 538 zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
 
 539                  struct zapi_ipv4 *api)
 
 549   zclient_create_header (s, cmd, api->vrf_id);
 
 551   /* Put type and nexthop. */
 
 552   stream_putc (s, api->type);
 
 553   stream_putc (s, api->flags);
 
 554   stream_putc (s, api->message);
 
 555   stream_putw (s, api->safi);
 
 557   /* Put prefix information. */
 
 558   psize = PSIZE (p->prefixlen);
 
 559   stream_putc (s, p->prefixlen);
 
 560   stream_write (s, (u_char *) & p->prefix, psize);
 
 562   /* Nexthop, ifindex, distance and metric information. */
 
 563   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
 
 565       if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
 
 568           stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
 
 569           /* XXX assert(api->nexthop_num == 0); */
 
 570           /* XXX assert(api->ifindex_num == 0); */
 
 573         stream_putc (s, api->nexthop_num + api->ifindex_num);
 
 575       for (i = 0; i < api->nexthop_num; i++)
 
 577           stream_putc (s, ZEBRA_NEXTHOP_IPV4);
 
 578           stream_put_in_addr (s, api->nexthop[i]);
 
 580       for (i = 0; i < api->ifindex_num; i++)
 
 582           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
 
 583           stream_putl (s, api->ifindex[i]);
 
 587   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
 
 588     stream_putc (s, api->distance);
 
 589   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
 
 590     stream_putl (s, api->metric);
 
 591   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
 
 592     stream_putl (s, api->mtu);
 
 593   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
 
 594     stream_putl (s, api->tag);
 
 596   /* Put length at the first point of the stream. */
 
 597   stream_putw_at (s, 0, stream_get_endp (s));
 
 599   return zclient_send_message(zclient);
 
 604 zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
 
 605                struct zapi_ipv6 *api)
 
 615   zclient_create_header (s, cmd, api->vrf_id);
 
 617   /* Put type and nexthop. */
 
 618   stream_putc (s, api->type);
 
 619   stream_putc (s, api->flags);
 
 620   stream_putc (s, api->message);
 
 621   stream_putw (s, api->safi);
 
 623   /* Put prefix information. */
 
 624   psize = PSIZE (p->prefixlen);
 
 625   stream_putc (s, p->prefixlen);
 
 626   stream_write (s, (u_char *)&p->prefix, psize);
 
 628   /* Nexthop, ifindex, distance and metric information. */
 
 629   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
 
 631       stream_putc (s, api->nexthop_num + api->ifindex_num);
 
 633       for (i = 0; i < api->nexthop_num; i++)
 
 635           stream_putc (s, ZEBRA_NEXTHOP_IPV6);
 
 636           stream_write (s, (u_char *)api->nexthop[i], 16);
 
 638       for (i = 0; i < api->ifindex_num; i++)
 
 640           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
 
 641           stream_putl (s, api->ifindex[i]);
 
 645   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
 
 646     stream_putc (s, api->distance);
 
 647   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
 
 648     stream_putl (s, api->metric);
 
 649   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
 
 650     stream_putl (s, api->mtu);
 
 651   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
 
 652     stream_putl (s, api->tag);
 
 654   /* Put length at the first point of the stream. */
 
 655   stream_putw_at (s, 0, stream_get_endp (s));
 
 657   return zclient_send_message(zclient);
 
 659 #endif /* HAVE_IPV6 */
 
 662  * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
 
 663  * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
 
 664  * then set/unset redist[type] in the client handle (a struct zserv) for the 
 
 668 zebra_redistribute_send (int command, struct zclient *zclient, int type,
 
 676   zclient_create_header (s, command, vrf_id);
 
 677   stream_putc (s, type);
 
 679   stream_putw_at (s, 0, stream_get_endp (s));
 
 681   return zclient_send_message(zclient);
 
 684 /* Get prefix in ZServ format; family should be filled in on prefix */
 
 686 zclient_stream_get_prefix (struct stream *s, struct prefix *p)
 
 688   size_t plen = prefix_blen (p);
 
 695   stream_get (&p->u.prefix, s, plen);
 
 697   p->prefixlen = MIN(plen * 8, c);
 
 700 /* Router-id update from zebra daemon. */
 
 702 zebra_router_id_update_read (struct stream *s, struct prefix *rid)
 
 704   /* Fetch interface address. */
 
 705   rid->family = stream_getc (s);
 
 707   zclient_stream_get_prefix (s, rid);
 
 710 /* Interface addition from zebra daemon. */
 
 712  * The format of the message sent with type ZEBRA_INTERFACE_ADD or
 
 713  * ZEBRA_INTERFACE_DELETE from zebra to the client is:
 
 715  *  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
 
 716  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 722  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 724  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 726  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 729  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 731  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 733  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 735  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 737  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 738  * |  Link Layer Type                                              |
 
 739  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 740  * |  Harware Address Length                                       |
 
 741  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 742  * |  Hardware Address      if HW lenght different from 0          |
 
 743  * |   ...                  max INTERFACE_HWADDR_MAX               |
 
 744  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 745  * |  Link_params? |  Whether a link-params follows: 1 or 0.       
 
 746  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 747  * |  Link_params    0 or 1 INTERFACE_LINK_PARAMS_SIZE sized       |
 
 748  * |   ....          (struct if_link_params).                      |
 
 749  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 753 zebra_interface_add_read (struct stream *s, vrf_id_t vrf_id)
 
 755   struct interface *ifp;
 
 756   char ifname_tmp[INTERFACE_NAMSIZ];
 
 758   /* Read interface name. */
 
 759   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
 
 761   /* Lookup/create interface by name. */
 
 762   ifp = if_get_by_name_len_vrf (ifname_tmp,
 
 763                                 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
 
 766   zebra_interface_if_set_value (s, ifp);
 
 772  * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
 
 773  * from zebra server.  The format of this message is the same as
 
 774  * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
 
 775  * comments for zebra_interface_add_read), except that no sockaddr_dl
 
 776  * is sent at the tail of the message.
 
 779 zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
 
 781   struct interface *ifp;
 
 782   char ifname_tmp[INTERFACE_NAMSIZ];
 
 784   /* Read interface name. */
 
 785   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
 
 787   /* Lookup this by interface index. */
 
 788   ifp = if_lookup_by_name_len_vrf (ifname_tmp,
 
 789                                    strnlen (ifname_tmp, INTERFACE_NAMSIZ),
 
 792   /* If such interface does not exist, indicate an error */
 
 796   zebra_interface_if_set_value (s, ifp);
 
 802 link_params_set_value(struct stream *s, struct if_link_params *iflp)
 
 808   iflp->lp_status = stream_getl (s);
 
 809   iflp->te_metric = stream_getl (s);
 
 810   iflp->max_bw = stream_getf (s);
 
 811   iflp->max_rsv_bw = stream_getf (s);
 
 812   uint32_t bwclassnum = stream_getl (s);
 
 815     for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
 
 816       iflp->unrsv_bw[i] = stream_getf (s);
 
 818       zlog_err ("%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
 
 819                 " - outdated library?",
 
 820                 __func__, bwclassnum, MAX_CLASS_TYPE);
 
 822   iflp->admin_grp = stream_getl (s);
 
 823   iflp->rmt_as = stream_getl (s);
 
 824   iflp->rmt_ip.s_addr = stream_get_ipv4 (s);
 
 826   iflp->av_delay = stream_getl (s);
 
 827   iflp->min_delay = stream_getl (s);
 
 828   iflp->max_delay = stream_getl (s);
 
 829   iflp->delay_var = stream_getl (s);
 
 831   iflp->pkt_loss = stream_getf (s);
 
 832   iflp->res_bw = stream_getf (s);
 
 833   iflp->ava_bw = stream_getf (s);
 
 834   iflp->use_bw = stream_getf (s);
 
 838 zebra_interface_link_params_read (struct stream *s)
 
 840   struct if_link_params *iflp;
 
 841   uint32_t ifindex = stream_getl (s);
 
 843   struct interface *ifp = if_lookup_by_index (ifindex);
 
 845   if (ifp == NULL || s == NULL)
 
 847       zlog_err ("%s: unknown ifindex %u, shouldn't happen",
 
 852   if ((iflp = if_link_params_get (ifp)) == NULL)
 
 855   link_params_set_value(s, iflp);
 
 861 zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
 
 863   u_char link_params_status = 0;
 
 865   /* Read interface's index. */
 
 866   ifp->ifindex = stream_getl (s);
 
 867   ifp->status = stream_getc (s);
 
 869   /* Read interface's value. */
 
 870   ifp->flags = stream_getq (s);
 
 871   ifp->metric = stream_getl (s);
 
 872   ifp->mtu = stream_getl (s);
 
 873   ifp->mtu6 = stream_getl (s);
 
 874   ifp->bandwidth = stream_getl (s);
 
 875   ifp->ll_type = stream_getl (s);
 
 876   ifp->hw_addr_len = stream_getl (s);
 
 877   if (ifp->hw_addr_len)
 
 878     stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
 
 880   /* Read Traffic Engineering status */
 
 881   link_params_status = stream_getc (s);
 
 882   /* Then, Traffic Engineering parameters if any */
 
 883   if (link_params_status)
 
 885       struct if_link_params *iflp = if_link_params_get (ifp);
 
 886       link_params_set_value(s, iflp);
 
 891 zebra_interface_link_params_write (struct stream *s, struct interface *ifp)
 
 894   struct if_link_params *iflp;
 
 897   if (s == NULL || ifp == NULL || ifp->link_params == NULL)
 
 900   iflp = ifp->link_params;
 
 903   w += stream_putl (s, iflp->lp_status);
 
 905   w += stream_putl (s, iflp->te_metric);
 
 906   w += stream_putf (s, iflp->max_bw);
 
 907   w += stream_putf (s, iflp->max_rsv_bw);
 
 909   w += stream_putl (s, MAX_CLASS_TYPE);
 
 910   for (i = 0; i < MAX_CLASS_TYPE; i++)
 
 911     w += stream_putf (s, iflp->unrsv_bw[i]);
 
 913   w += stream_putl (s, iflp->admin_grp);
 
 914   w += stream_putl (s, iflp->rmt_as);
 
 915   w += stream_put_in_addr (s, &iflp->rmt_ip);
 
 917   w += stream_putl (s, iflp->av_delay);
 
 918   w += stream_putl (s, iflp->min_delay);
 
 919   w += stream_putl (s, iflp->max_delay);
 
 920   w += stream_putl (s, iflp->delay_var);
 
 922   w += stream_putf (s, iflp->pkt_loss);
 
 923   w += stream_putf (s, iflp->res_bw);
 
 924   w += stream_putf (s, iflp->ava_bw);
 
 925   w += stream_putf (s, iflp->use_bw);
 
 931  * format of message for address additon is:
 
 935  * |   type        |  ZEBRA_INTERFACE_ADDRESS_ADD or
 
 936  * +-+-+-+-+-+-+-+-+  ZEBRA_INTERFACE_ADDRES_DELETE
 
 945  * |   ifc_flags   |  flags for connected address
 
 953  * |    addr_len   |  len of addr. E.g., addr_len = 4 for ipv4 addrs.
 
 962 memconstant(const void *s, int c, size_t n)
 
 973 zebra_interface_address_read (int type, struct stream *s, vrf_id_t vrf_id)
 
 976   struct interface *ifp;
 
 977   struct connected *ifc;
 
 978   struct prefix p, d, *dp;
 
 982   memset (&p, 0, sizeof(p));
 
 983   memset (&d, 0, sizeof(d));
 
 985   /* Get interface index. */
 
 986   ifindex = stream_getl (s);
 
 989   ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
 
 992       zlog_warn ("zebra_interface_address_read(%s): "
 
 993                  "Can't find interface by ifindex: %d ",
 
 994                  (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
 
1000   ifc_flags = stream_getc (s);
 
1002   /* Fetch interface address. */
 
1003   d.family = p.family = stream_getc (s);
 
1004   plen = prefix_blen (&d);
 
1006   zclient_stream_get_prefix (s, &p);
 
1008   /* Fetch destination address. */
 
1009   stream_get (&d.u.prefix, s, plen);
 
1011   /* N.B. NULL destination pointers are encoded as all zeroes */
 
1012   dp = memconstant(&d.u.prefix,0,plen) ? NULL : &d;
 
1014   if (type == ZEBRA_INTERFACE_ADDRESS_ADD) 
 
1016        /* N.B. NULL destination pointers are encoded as all zeroes */
 
1017        ifc = connected_add_by_prefix(ifp, &p, dp);
 
1020            ifc->flags = ifc_flags;
 
1021            if (ifc->destination)
 
1022              ifc->destination->prefixlen = ifc->address->prefixlen;
 
1023            else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
 
1025                /* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */
 
1026                char buf[PREFIX_STRLEN];
 
1027                zlog_warn("warning: interface %s address %s "
 
1028                     "with peer flag set, but no peer address!",
 
1030                     prefix2str (ifc->address, buf, sizeof buf));
 
1031                UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
 
1037       assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
 
1038       ifc = connected_delete_by_prefix(ifp, &p);
 
1045 /* Zebra client message read function. */
 
1047 zclient_read (struct thread *thread)
 
1050   uint16_t length, command;
 
1051   uint8_t marker, version;
 
1053   struct zclient *zclient;
 
1055   /* Get socket to zebra. */
 
1056   zclient = THREAD_ARG (thread);
 
1057   zclient->t_read = NULL;
 
1059   /* Read zebra header (if we don't have it already). */
 
1060   if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
 
1063       if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
 
1064                                      ZEBRA_HEADER_SIZE-already)) == 0) ||
 
1068            zlog_debug ("zclient connection closed socket [%d].", zclient->sock);
 
1069           return zclient_failed(zclient);
 
1071       if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
 
1073           /* Try again later. */
 
1074           zclient_event (ZCLIENT_READ, zclient);
 
1077       already = ZEBRA_HEADER_SIZE;
 
1080   /* Reset to read from the beginning of the incoming packet. */
 
1081   stream_set_getp(zclient->ibuf, 0);
 
1083   /* Fetch header values. */
 
1084   length = stream_getw (zclient->ibuf);
 
1085   marker = stream_getc (zclient->ibuf);
 
1086   version = stream_getc (zclient->ibuf);
 
1087   vrf_id = stream_getw (zclient->ibuf);
 
1088   command = stream_getw (zclient->ibuf);
 
1090   if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
 
1092       zlog_err("%s: socket %d version mismatch, marker %d, version %d",
 
1093                __func__, zclient->sock, marker, version);
 
1094       return zclient_failed(zclient);
 
1097   if (length < ZEBRA_HEADER_SIZE) 
 
1099       zlog_err("%s: socket %d message length %u is less than %d ",
 
1100                __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
 
1101       return zclient_failed(zclient);
 
1105   if (length > STREAM_SIZE(zclient->ibuf))
 
1108       zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
 
1109                 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
 
1110       ns = stream_new(length);
 
1111       stream_copy(ns, zclient->ibuf);
 
1112       stream_free (zclient->ibuf);
 
1116   /* Read rest of zebra packet. */
 
1117   if (already < length)
 
1120       if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
 
1121                                      length-already)) == 0) ||
 
1125             zlog_debug("zclient connection closed socket [%d].", zclient->sock);
 
1126           return zclient_failed(zclient);
 
1128       if (nbyte != (ssize_t)(length-already))
 
1130           /* Try again later. */
 
1131           zclient_event (ZCLIENT_READ, zclient);
 
1136   length -= ZEBRA_HEADER_SIZE;
 
1139     zlog_debug("zclient 0x%p command 0x%x VRF %u\n", (void *)zclient, command, vrf_id);
 
1143     case ZEBRA_ROUTER_ID_UPDATE:
 
1144       if (zclient->router_id_update)
 
1145         (*zclient->router_id_update) (command, zclient, length, vrf_id);
 
1147     case ZEBRA_INTERFACE_ADD:
 
1148       if (zclient->interface_add)
 
1149         (*zclient->interface_add) (command, zclient, length, vrf_id);
 
1151     case ZEBRA_INTERFACE_DELETE:
 
1152       if (zclient->interface_delete)
 
1153         (*zclient->interface_delete) (command, zclient, length, vrf_id);
 
1155     case ZEBRA_INTERFACE_ADDRESS_ADD:
 
1156       if (zclient->interface_address_add)
 
1157         (*zclient->interface_address_add) (command, zclient, length, vrf_id);
 
1159     case ZEBRA_INTERFACE_ADDRESS_DELETE:
 
1160       if (zclient->interface_address_delete)
 
1161         (*zclient->interface_address_delete) (command, zclient, length, vrf_id);
 
1163     case ZEBRA_INTERFACE_UP:
 
1164       if (zclient->interface_up)
 
1165         (*zclient->interface_up) (command, zclient, length, vrf_id);
 
1167     case ZEBRA_INTERFACE_DOWN:
 
1168       if (zclient->interface_down)
 
1169         (*zclient->interface_down) (command, zclient, length, vrf_id);
 
1171     case ZEBRA_IPV4_ROUTE_ADD:
 
1172       if (zclient->ipv4_route_add)
 
1173         (*zclient->ipv4_route_add) (command, zclient, length, vrf_id);
 
1175     case ZEBRA_IPV4_ROUTE_DELETE:
 
1176       if (zclient->ipv4_route_delete)
 
1177         (*zclient->ipv4_route_delete) (command, zclient, length, vrf_id);
 
1179     case ZEBRA_IPV6_ROUTE_ADD:
 
1180       if (zclient->ipv6_route_add)
 
1181         (*zclient->ipv6_route_add) (command, zclient, length, vrf_id);
 
1183     case ZEBRA_IPV6_ROUTE_DELETE:
 
1184       if (zclient->ipv6_route_delete)
 
1185         (*zclient->ipv6_route_delete) (command, zclient, length, vrf_id);
 
1187     case ZEBRA_INTERFACE_LINK_PARAMS:
 
1188       if (zclient->interface_link_params)
 
1189         (*zclient->interface_link_params) (command, zclient, length);
 
1190     case ZEBRA_NEXTHOP_UPDATE:
 
1191       if (zclient->nexthop_update)
 
1192         (*zclient->nexthop_update) (command, zclient, length, vrf_id);
 
1198   if (zclient->sock < 0)
 
1199     /* Connection was closed during packet processing. */
 
1202   /* Register read thread. */
 
1203   stream_reset(zclient->ibuf);
 
1204   zclient_event (ZCLIENT_READ, zclient);
 
1210 zclient_redistribute (int command, struct zclient *zclient, int type,
 
1214   if (command == ZEBRA_REDISTRIBUTE_ADD) 
 
1216       if (vrf_bitmap_check (zclient->redist[type], vrf_id))
 
1218       vrf_bitmap_set (zclient->redist[type], vrf_id);
 
1222       if (!vrf_bitmap_check (zclient->redist[type], vrf_id))
 
1224       vrf_bitmap_unset (zclient->redist[type], vrf_id);
 
1227   if (zclient->sock > 0)
 
1228     zebra_redistribute_send (command, zclient, type, vrf_id);
 
1233 zclient_redistribute_default (int command, struct zclient *zclient,
 
1237   if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
 
1239       if (vrf_bitmap_check (zclient->default_information, vrf_id))
 
1241       vrf_bitmap_set (zclient->default_information, vrf_id);
 
1245       if (!vrf_bitmap_check (zclient->default_information, vrf_id))
 
1247       vrf_bitmap_unset (zclient->default_information, vrf_id);
 
1250   if (zclient->sock > 0)
 
1251     zebra_message_send (zclient, command, vrf_id);
 
1255 zclient_event (enum event event, struct zclient *zclient)
 
1259     case ZCLIENT_SCHEDULE:
 
1260       if (! zclient->t_connect)
 
1261         zclient->t_connect =
 
1262           thread_add_event (zclient->master, zclient_connect, zclient, 0);
 
1264     case ZCLIENT_CONNECT:
 
1265       if (zclient->fail >= 10)
 
1268         zlog_debug ("zclient connect schedule interval is %d", 
 
1269                    zclient->fail < 3 ? 10 : 60);
 
1270       if (! zclient->t_connect)
 
1271         zclient->t_connect = 
 
1272           thread_add_timer (zclient->master, zclient_connect, zclient,
 
1273                             zclient->fail < 3 ? 10 : 60);
 
1277         thread_add_read (zclient->master, zclient_read, zclient, zclient->sock);
 
1282 const char *zclient_serv_path_get()
 
1284   return zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH;
 
1288 zclient_serv_path_set (char *path)
 
1293   zclient_serv_path = NULL;
 
1295   /* test if `path' is socket. don't set it otherwise. */
 
1296   if (stat(path, &sb) == -1)
 
1298       zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
 
1302   if ((sb.st_mode & S_IFMT) != S_IFSOCK)
 
1304       zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
 
1308   /* it seems that path is unix socket */
 
1309   zclient_serv_path = path;