Diff for /embedaddon/quagga/lib/zclient.c between versions 1.1 and 1.1.1.4

version 1.1, 2012/02/21 17:26:12 version 1.1.1.4, 2016/11/02 10:09:10
Line 32 Line 32
 #include "zclient.h"  #include "zclient.h"
 #include "memory.h"  #include "memory.h"
 #include "table.h"  #include "table.h"
 /* Zebra client events. */  /* Zebra client events. */
 enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};  enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
   
 /* Prototype for event manager. */  /* Prototype for event manager. */
 static void zclient_event (enum event, struct zclient *);  static void zclient_event (enum event, struct zclient *);
   
extern struct thread_master *master;const char *zclient_serv_path = NULL;
   
 /* This file local debug flag. */  /* This file local debug flag. */
 int zclient_debug = 0;  int zclient_debug = 0;
 /* Allocate zclient structure. */  /* Allocate zclient structure. */
 struct zclient *  struct zclient *
zclient_new ()zclient_new (struct thread_master *master)
 {  {
   struct zclient *zclient;    struct zclient *zclient;
   zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));    zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
Line 54  zclient_new () Line 54  zclient_new ()
   zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);    zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
   zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);    zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
   zclient->wb = buffer_new(0);    zclient->wb = buffer_new(0);
     zclient->master = master;
   
   return zclient;    return zclient;
 }  }
Line 91  zclient_init (struct zclient *zclient, int redist_defa Line 92  zclient_init (struct zclient *zclient, int redist_defa
   
   /* Clear redistribution flags. */    /* Clear redistribution flags. */
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
    zclient->redist[i] = 0;    zclient->redist[i] = vrf_bitmap_init ();
   
   /* Set unwanted redistribute route.  bgpd does not need BGP route    /* Set unwanted redistribute route.  bgpd does not need BGP route
      redistribution. */       redistribution. */
   zclient->redist_default = redist_default;    zclient->redist_default = redist_default;
   zclient->redist[redist_default] = 1;  
   
   /* Set default-information redistribute to zero. */    /* Set default-information redistribute to zero. */
  zclient->default_information = 0;  zclient->default_information = vrf_bitmap_init ();
   
   /* Schedule first zclient connection. */    /* Schedule first zclient connection. */
   if (zclient_debug)    if (zclient_debug)
Line 112  zclient_init (struct zclient *zclient, int redist_defa Line 112  zclient_init (struct zclient *zclient, int redist_defa
 void  void
 zclient_stop (struct zclient *zclient)  zclient_stop (struct zclient *zclient)
 {  {
     int i;
   
   if (zclient_debug)    if (zclient_debug)
     zlog_debug ("zclient stopped");      zlog_debug ("zclient stopped");
   
Line 134  zclient_stop (struct zclient *zclient) Line 136  zclient_stop (struct zclient *zclient)
       zclient->sock = -1;        zclient->sock = -1;
     }      }
   zclient->fail = 0;    zclient->fail = 0;
   
     for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
       {
         vrf_bitmap_free(zclient->redist[i]);
         zclient->redist[i] = VRF_BITMAP_NULL;
       }
     vrf_bitmap_free(zclient->default_information);
     zclient->default_information = VRF_BITMAP_NULL;
 }  }
   
 void  void
Line 143  zclient_reset (struct zclient *zclient) Line 153  zclient_reset (struct zclient *zclient)
   zclient_init (zclient, zclient->redist_default);    zclient_init (zclient, zclient->redist_default);
 }  }
   
   #ifdef HAVE_TCP_ZEBRA
   
 /* Make socket to zebra daemon. Return zebra socket. */  /* Make socket to zebra daemon. Return zebra socket. */
intstatic int
 zclient_socket(void)  zclient_socket(void)
 {  {
   int sock;    int sock;
Line 175  zclient_socket(void) Line 187  zclient_socket(void)
   return sock;    return sock;
 }  }
   
   #else
   
 /* For sockaddr_un. */  /* For sockaddr_un. */
 #include <sys/un.h>  #include <sys/un.h>
   
intstatic int
 zclient_socket_un (const char *path)  zclient_socket_un (const char *path)
 {  {
   int ret;    int ret;
Line 208  zclient_socket_un (const char *path) Line 222  zclient_socket_un (const char *path)
   return sock;    return sock;
 }  }
   
   #endif /* HAVE_TCP_ZEBRA */
   
   /**
    * Connect to zebra daemon.
    * @param zclient a pointer to zclient structure
    * @return socket fd just to make sure that connection established
    * @see zclient_init
    * @see zclient_new
    */
   int
   zclient_socket_connect (struct zclient *zclient)
   {
   #ifdef HAVE_TCP_ZEBRA
     zclient->sock = zclient_socket ();
   #else
     zclient->sock = zclient_socket_un (zclient_serv_path_get());
   #endif
     return zclient->sock;
   }
   
 static int  static int
 zclient_failed(struct zclient *zclient)  zclient_failed(struct zclient *zclient)
 {  {
Line 233  zclient_flush_data(struct thread *thread) Line 267  zclient_flush_data(struct thread *thread)
       return zclient_failed(zclient);        return zclient_failed(zclient);
       break;        break;
     case BUFFER_PENDING:      case BUFFER_PENDING:
      zclient->t_write = thread_add_write(master, zclient_flush_data,      zclient->t_write = thread_add_write (zclient->master, zclient_flush_data,
                                          zclient, zclient->sock);                                           zclient, zclient->sock);
       break;        break;
     case BUFFER_EMPTY:      case BUFFER_EMPTY:
       break;        break;
Line 259  zclient_send_message(struct zclient *zclient) Line 293  zclient_send_message(struct zclient *zclient)
       THREAD_OFF(zclient->t_write);        THREAD_OFF(zclient->t_write);
       break;        break;
     case BUFFER_PENDING:      case BUFFER_PENDING:
      THREAD_WRITE_ON(master, zclient->t_write,      THREAD_WRITE_ON (zclient->master, zclient->t_write,
                      zclient_flush_data, zclient, zclient->sock);                       zclient_flush_data, zclient, zclient->sock);
       break;        break;
     }      }
   return 0;    return 0;
 }  }
   
 void  void
zclient_create_header (struct stream *s, uint16_t command)zclient_create_header (struct stream *s, uint16_t command, vrf_id_t vrf_id)
 {  {
   /* length placeholder, caller can update */    /* length placeholder, caller can update */
   stream_putw (s, ZEBRA_HEADER_SIZE);    stream_putw (s, ZEBRA_HEADER_SIZE);
   stream_putc (s, ZEBRA_HEADER_MARKER);    stream_putc (s, ZEBRA_HEADER_MARKER);
   stream_putc (s, ZSERV_VERSION);    stream_putc (s, ZSERV_VERSION);
     stream_putw (s, vrf_id);
   stream_putw (s, command);    stream_putw (s, command);
 }  }
   
   int
   zclient_read_header (struct stream *s, int sock, u_int16_t *size, u_char *marker,
                        u_char *version, u_int16_t *vrf_id, u_int16_t *cmd)
   {
     if (stream_read (s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
       return -1;
   
     *size = stream_getw (s) - ZEBRA_HEADER_SIZE;
     *marker = stream_getc (s);
     *version = stream_getc (s);
     *vrf_id = stream_getw (s);
     *cmd = stream_getw (s);
   
     if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER)
       {
         zlog_err("%s: socket %d version mismatch, marker %d, version %d",
                  __func__, sock, *marker, *version);
         return -1;
       }
   
     if (*size && stream_read (s, sock, *size) != *size)
       return -1;
   
     return 0;
   }
   
 /* Send simple Zebra message. */  /* Send simple Zebra message. */
 static int  static int
zebra_message_send (struct zclient *zclient, int command)zebra_message_send (struct zclient *zclient, int command, vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   
Line 287  zebra_message_send (struct zclient *zclient, int comma Line 348  zebra_message_send (struct zclient *zclient, int comma
   stream_reset (s);    stream_reset (s);
   
   /* Send very simple command only Zebra message. */    /* Send very simple command only Zebra message. */
  zclient_create_header (s, command);  zclient_create_header (s, command, vrf_id);
       
   return zclient_send_message(zclient);    return zclient_send_message(zclient);
 }  }
   
   static int
   zebra_hello_send (struct zclient *zclient)
   {
     struct stream *s;
   
     if (zclient->redist_default)
       {
         s = zclient->obuf;
         stream_reset (s);
   
         /* The VRF ID in the HELLO message is always 0. */
         zclient_create_header (s, ZEBRA_HELLO, VRF_DEFAULT);
         stream_putc (s, zclient->redist_default);
         stream_putw_at (s, 0, stream_get_endp (s));
         return zclient_send_message(zclient);
       }
   
     return 0;
   }
   
   /* Send requests to zebra daemon for the information in a VRF. */
   void
   zclient_send_requests (struct zclient *zclient, vrf_id_t vrf_id)
   {
     int i;
   
     /* zclient is disabled. */
     if (! zclient->enable)
       return;
   
     /* If not connected to the zebra yet. */
     if (zclient->sock < 0)
       return;
   
     if (zclient_debug)
       zlog_debug ("%s: send messages for VRF %u", __func__, vrf_id);
   
     /* We need router-id information. */
     zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD, vrf_id);
   
     /* We need interface information. */
     zebra_message_send (zclient, ZEBRA_INTERFACE_ADD, vrf_id);
   
     /* Set unwanted redistribute route. */
     vrf_bitmap_set (zclient->redist[zclient->redist_default], vrf_id);
   
     /* Flush all redistribute request. */
     for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
       if (i != zclient->redist_default &&
           vrf_bitmap_check (zclient->redist[i], vrf_id))
         zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i, vrf_id);
   
     /* If default information is needed. */
     if (vrf_bitmap_check (zclient->default_information, VRF_DEFAULT))
       zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD, vrf_id);
   }
   
 /* Make connection to zebra daemon. */  /* Make connection to zebra daemon. */
 int  int
 zclient_start (struct zclient *zclient)  zclient_start (struct zclient *zclient)
 {  {
   int i;  
   
   if (zclient_debug)    if (zclient_debug)
     zlog_debug ("zclient_start is called");      zlog_debug ("zclient_start is called");
   
Line 313  zclient_start (struct zclient *zclient) Line 429  zclient_start (struct zclient *zclient)
   if (zclient->t_connect)    if (zclient->t_connect)
     return 0;      return 0;
   
  /* Make socket. */  if (zclient_socket_connect(zclient) < 0)
#ifdef HAVE_TCP_ZEBRA 
  zclient->sock = zclient_socket (); 
#else 
  zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH); 
#endif /* HAVE_TCP_ZEBRA */ 
  if (zclient->sock < 0) 
     {      {
       if (zclient_debug)        if (zclient_debug)
         zlog_debug ("zclient connection fail");          zlog_debug ("zclient connection fail");
Line 339  zclient_start (struct zclient *zclient) Line 449  zclient_start (struct zclient *zclient)
   /* Create read thread. */    /* Create read thread. */
   zclient_event (ZCLIENT_READ, zclient);    zclient_event (ZCLIENT_READ, zclient);
   
  /* We need router-id information. */  zebra_hello_send (zclient);
  zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD); 
   
  /* We need interface information. */  /* Inform the successful connection. */
  zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);  if (zclient->zebra_connected)
     (*zclient->zebra_connected) (zclient);
   
   /* Flush all redistribute request. */  
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)  
     if (i != zclient->redist_default && zclient->redist[i])  
       zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i);  
   
   /* If default information is needed. */  
   if (zclient->default_information)  
     zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);  
   
   return 0;    return 0;
 }  }
   
Line 372  zclient_connect (struct thread *t) Line 473  zclient_connect (struct thread *t)
   
   return zclient_start (zclient);    return zclient_start (zclient);
 }  }
  /*    /* 
   * "xdr_encode"-like interface that allows daemon (client) to send    * "xdr_encode"-like interface that allows daemon (client) to send
   * a message to zebra server for a route that needs to be    * a message to zebra server for a route that needs to be
Line 428  zapi_ipv4_route (u_char cmd, struct zclient *zclient,  Line 529  zapi_ipv4_route (u_char cmd, struct zclient *zclient, 
   /* Reset stream. */    /* Reset stream. */
   s = zclient->obuf;    s = zclient->obuf;
   stream_reset (s);    stream_reset (s);
   
     zclient_create_header (s, cmd, api->vrf_id);
       
   zclient_create_header (s, cmd);  
     
   /* Put type and nexthop. */    /* Put type and nexthop. */
   stream_putc (s, api->type);    stream_putc (s, api->type);
   stream_putc (s, api->flags);    stream_putc (s, api->flags);
   stream_putc (s, api->message);    stream_putc (s, api->message);
     stream_putw (s, api->safi);
   
   /* Put prefix information. */    /* Put prefix information. */
   psize = PSIZE (p->prefixlen);    psize = PSIZE (p->prefixlen);
Line 470  zapi_ipv4_route (u_char cmd, struct zclient *zclient,  Line 572  zapi_ipv4_route (u_char cmd, struct zclient *zclient, 
     stream_putc (s, api->distance);      stream_putc (s, api->distance);
   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))    if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
     stream_putl (s, api->metric);      stream_putl (s, api->metric);
     if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
       stream_putl (s, api->mtu);
   
   /* Put length at the first point of the stream. */    /* Put length at the first point of the stream. */
   stream_putw_at (s, 0, stream_get_endp (s));    stream_putw_at (s, 0, stream_get_endp (s));
Line 490  zapi_ipv6_route (u_char cmd, struct zclient *zclient,  Line 594  zapi_ipv6_route (u_char cmd, struct zclient *zclient, 
   s = zclient->obuf;    s = zclient->obuf;
   stream_reset (s);    stream_reset (s);
   
  zclient_create_header (s, cmd);  zclient_create_header (s, cmd, api->vrf_id);
   
   /* Put type and nexthop. */    /* Put type and nexthop. */
   stream_putc (s, api->type);    stream_putc (s, api->type);
   stream_putc (s, api->flags);    stream_putc (s, api->flags);
   stream_putc (s, api->message);    stream_putc (s, api->message);
     stream_putw (s, api->safi);
       
   /* Put prefix information. */    /* Put prefix information. */
   psize = PSIZE (p->prefixlen);    psize = PSIZE (p->prefixlen);
Line 523  zapi_ipv6_route (u_char cmd, struct zclient *zclient,  Line 628  zapi_ipv6_route (u_char cmd, struct zclient *zclient, 
     stream_putc (s, api->distance);      stream_putc (s, api->distance);
   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))    if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
     stream_putl (s, api->metric);      stream_putl (s, api->metric);
     if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
       stream_putl (s, api->mtu);
   
   /* Put length at the first point of the stream. */    /* Put length at the first point of the stream. */
   stream_putw_at (s, 0, stream_get_endp (s));    stream_putw_at (s, 0, stream_get_endp (s));
Line 538  zapi_ipv6_route (u_char cmd, struct zclient *zclient,  Line 645  zapi_ipv6_route (u_char cmd, struct zclient *zclient, 
  * sending client   * sending client
  */   */
 int  int
zebra_redistribute_send (int command, struct zclient *zclient, int type)zebra_redistribute_send (int command, struct zclient *zclient, int type,
     vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   
   s = zclient->obuf;    s = zclient->obuf;
   stream_reset(s);    stream_reset(s);
       
  zclient_create_header (s, command);  zclient_create_header (s, command, vrf_id);
   stream_putc (s, type);    stream_putc (s, type);
       
   stream_putw_at (s, 0, stream_get_endp (s));    stream_putw_at (s, 0, stream_get_endp (s));
Line 553  zebra_redistribute_send (int command, struct zclient * Line 661  zebra_redistribute_send (int command, struct zclient *
   return zclient_send_message(zclient);    return zclient_send_message(zclient);
 }  }
   
   /* Get prefix in ZServ format; family should be filled in on prefix */
   static void
   zclient_stream_get_prefix (struct stream *s, struct prefix *p)
   {
     size_t plen = prefix_blen (p);
     u_char c;
     p->prefixlen = 0;
     
     if (plen == 0)
       return;
     
     stream_get (&p->u.prefix, s, plen);
     c = stream_getc(s);
     p->prefixlen = MIN(plen * 8, c);
   }
   
 /* Router-id update from zebra daemon. */  /* Router-id update from zebra daemon. */
 void  void
 zebra_router_id_update_read (struct stream *s, struct prefix *rid)  zebra_router_id_update_read (struct stream *s, struct prefix *rid)
 {  {
   int plen;  
   
   /* Fetch interface address. */    /* Fetch interface address. */
   rid->family = stream_getc (s);    rid->family = stream_getc (s);
  
  plen = prefix_blen (rid);  zclient_stream_get_prefix (s, rid);
  stream_get (&rid->u.prefix, s, plen); 
  rid->prefixlen = stream_getc (s); 
 }  }
   
 /* Interface addition from zebra daemon. */  /* Interface addition from zebra daemon. */
Line 600  zebra_router_id_update_read (struct stream *s, struct  Line 720  zebra_router_id_update_read (struct stream *s, struct 
  */   */
   
 struct interface *  struct interface *
zebra_interface_add_read (struct stream *s)zebra_interface_add_read (struct stream *s, vrf_id_t vrf_id)
 {  {
   struct interface *ifp;    struct interface *ifp;
   char ifname_tmp[INTERFACE_NAMSIZ];    char ifname_tmp[INTERFACE_NAMSIZ];
Line 609  zebra_interface_add_read (struct stream *s) Line 729  zebra_interface_add_read (struct stream *s)
   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);    stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
   
   /* Lookup/create interface by name. */    /* Lookup/create interface by name. */
  ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ));  ifp = if_get_by_name_len_vrf (ifname_tmp,
                                 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
                                 vrf_id);
   
  /* Read interface's index. */  zebra_interface_if_set_value (s, ifp);
  ifp->ifindex = stream_getl (s); 
   
   /* Read interface's value. */  
   ifp->status = stream_getc (s);  
   ifp->flags = stream_getq (s);  
   ifp->metric = stream_getl (s);  
   ifp->mtu = stream_getl (s);  
   ifp->mtu6 = stream_getl (s);  
   ifp->bandwidth = stream_getl (s);  
 #ifdef HAVE_STRUCT_SOCKADDR_DL  
   stream_get (&ifp->sdl, s, sizeof (ifp->sdl));  
 #else  
   ifp->hw_addr_len = stream_getl (s);  
   if (ifp->hw_addr_len)  
     stream_get (ifp->hw_addr, s, ifp->hw_addr_len);  
 #endif /* HAVE_STRUCT_SOCKADDR_DL */  
     
   return ifp;    return ifp;
 }  }
   
Line 640  zebra_interface_add_read (struct stream *s) Line 746  zebra_interface_add_read (struct stream *s)
  * is sent at the tail of the message.   * is sent at the tail of the message.
  */   */
 struct interface *  struct interface *
zebra_interface_state_read (struct stream *s)zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
 {  {
   struct interface *ifp;    struct interface *ifp;
   char ifname_tmp[INTERFACE_NAMSIZ];    char ifname_tmp[INTERFACE_NAMSIZ];
Line 649  zebra_interface_state_read (struct stream *s) Line 755  zebra_interface_state_read (struct stream *s)
   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);    stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
   
   /* Lookup this by interface index. */    /* Lookup this by interface index. */
  ifp = if_lookup_by_name_len (ifname_tmp,  ifp = if_lookup_by_name_len_vrf (ifname_tmp,
                               strnlen(ifname_tmp, INTERFACE_NAMSIZ));                                   strnlen (ifname_tmp, INTERFACE_NAMSIZ),
                                    vrf_id);
   
   /* If such interface does not exist, indicate an error */    /* If such interface does not exist, indicate an error */
   if (! ifp)    if (! ifp)
      return NULL;       return NULL;
   
  /* Read interface's index. */  zebra_interface_if_set_value (s, ifp);
  ifp->ifindex = stream_getl (s); 
   
   /* Read interface's value. */  
   ifp->status = stream_getc (s);  
   ifp->flags = stream_getq (s);  
   ifp->metric = stream_getl (s);  
   ifp->mtu = stream_getl (s);  
   ifp->mtu6 = stream_getl (s);  
   ifp->bandwidth = stream_getl (s);  
   
   return ifp;    return ifp;
 }  }
   
Line 715  zebra_interface_if_set_value (struct stream *s, struct Line 813  zebra_interface_if_set_value (struct stream *s, struct
   ifp->mtu = stream_getl (s);    ifp->mtu = stream_getl (s);
   ifp->mtu6 = stream_getl (s);    ifp->mtu6 = stream_getl (s);
   ifp->bandwidth = stream_getl (s);    ifp->bandwidth = stream_getl (s);
     ifp->ll_type = stream_getl (s);
     ifp->hw_addr_len = stream_getl (s);
     if (ifp->hw_addr_len)
       stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
 }  }
   
 static int  static int
Line 729  memconstant(const void *s, int c, size_t n) Line 831  memconstant(const void *s, int c, size_t n)
 }  }
   
 struct connected *  struct connected *
zebra_interface_address_read (int type, struct stream *s)zebra_interface_address_read (int type, struct stream *s, vrf_id_t vrf_id)
 {  {
  unsigned int ifindex;  ifindex_t ifindex;
   struct interface *ifp;    struct interface *ifp;
   struct connected *ifc;    struct connected *ifc;
  struct prefix p, d;  struct prefix p, d, *dp;
  int family; 
   int plen;    int plen;
   u_char ifc_flags;    u_char ifc_flags;
   
Line 746  zebra_interface_address_read (int type, struct stream  Line 847  zebra_interface_address_read (int type, struct stream 
   ifindex = stream_getl (s);    ifindex = stream_getl (s);
   
   /* Lookup index. */    /* Lookup index. */
  ifp = if_lookup_by_index (ifindex);  ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
   if (ifp == NULL)    if (ifp == NULL)
     {      {
       zlog_warn ("zebra_interface_address_read(%s): "        zlog_warn ("zebra_interface_address_read(%s): "
Line 760  zebra_interface_address_read (int type, struct stream  Line 861  zebra_interface_address_read (int type, struct stream 
   ifc_flags = stream_getc (s);    ifc_flags = stream_getc (s);
   
   /* Fetch interface address. */    /* Fetch interface address. */
  family = p.family = stream_getc (s);  d.family = p.family = stream_getc (s);
   plen = prefix_blen (&d);
   
   zclient_stream_get_prefix (s, &p);
   
   plen = prefix_blen (&p);  
   stream_get (&p.u.prefix, s, plen);  
   p.prefixlen = stream_getc (s);  
   
   /* Fetch destination address. */    /* Fetch destination address. */
   stream_get (&d.u.prefix, s, plen);    stream_get (&d.u.prefix, s, plen);
  d.family = family;  
  /* N.B. NULL destination pointers are encoded as all zeroes */
   dp = memconstant(&d.u.prefix,0,plen) ? NULL : &d;
   
   if (type == ZEBRA_INTERFACE_ADDRESS_ADD)     if (type == ZEBRA_INTERFACE_ADDRESS_ADD) 
     {      {
        /* N.B. NULL destination pointers are encoded as all zeroes */         /* N.B. NULL destination pointers are encoded as all zeroes */
       ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ?       ifc = connected_add_by_prefix(ifp, &p, dp);
                                              NULL : &d)); 
        if (ifc != NULL)         if (ifc != NULL)
          {           {
            ifc->flags = ifc_flags;             ifc->flags = ifc_flags;
            if (ifc->destination)             if (ifc->destination)
              ifc->destination->prefixlen = ifc->address->prefixlen;               ifc->destination->prefixlen = ifc->address->prefixlen;
              else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
                {
                  /* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */
                  char buf[PREFIX_STRLEN];
                  zlog_warn("warning: interface %s address %s "
                       "with peer flag set, but no peer address!",
                       ifp->name,
                       prefix2str (ifc->address, buf, sizeof buf));
                  UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
                }
          }           }
     }      }
   else    else
Line 791  zebra_interface_address_read (int type, struct stream  Line 902  zebra_interface_address_read (int type, struct stream 
   return ifc;    return ifc;
 }  }
   
 /* Zebra client message read function. */  /* Zebra client message read function. */
 static int  static int
 zclient_read (struct thread *thread)  zclient_read (struct thread *thread)
 {  {
   int ret;  
   size_t already;    size_t already;
   uint16_t length, command;    uint16_t length, command;
   uint8_t marker, version;    uint8_t marker, version;
     vrf_id_t vrf_id;
   struct zclient *zclient;    struct zclient *zclient;
   
   /* Get socket to zebra. */    /* Get socket to zebra. */
Line 834  zclient_read (struct thread *thread) Line 945  zclient_read (struct thread *thread)
   length = stream_getw (zclient->ibuf);    length = stream_getw (zclient->ibuf);
   marker = stream_getc (zclient->ibuf);    marker = stream_getc (zclient->ibuf);
   version = stream_getc (zclient->ibuf);    version = stream_getc (zclient->ibuf);
     vrf_id = stream_getw (zclient->ibuf);
   command = stream_getw (zclient->ibuf);    command = stream_getw (zclient->ibuf);
       
   if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)    if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
Line 885  zclient_read (struct thread *thread) Line 997  zclient_read (struct thread *thread)
   length -= ZEBRA_HEADER_SIZE;    length -= ZEBRA_HEADER_SIZE;
   
   if (zclient_debug)    if (zclient_debug)
    zlog_debug("zclient 0x%p command 0x%x \n", zclient, command);    zlog_debug("zclient 0x%p command 0x%x VRF %u\n", (void *)zclient, command, vrf_id);
   
   switch (command)    switch (command)
     {      {
     case ZEBRA_ROUTER_ID_UPDATE:      case ZEBRA_ROUTER_ID_UPDATE:
       if (zclient->router_id_update)        if (zclient->router_id_update)
        ret = (*zclient->router_id_update) (command, zclient, length);        (*zclient->router_id_update) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_INTERFACE_ADD:      case ZEBRA_INTERFACE_ADD:
       if (zclient->interface_add)        if (zclient->interface_add)
        ret = (*zclient->interface_add) (command, zclient, length);        (*zclient->interface_add) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_INTERFACE_DELETE:      case ZEBRA_INTERFACE_DELETE:
       if (zclient->interface_delete)        if (zclient->interface_delete)
        ret = (*zclient->interface_delete) (command, zclient, length);        (*zclient->interface_delete) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_INTERFACE_ADDRESS_ADD:      case ZEBRA_INTERFACE_ADDRESS_ADD:
       if (zclient->interface_address_add)        if (zclient->interface_address_add)
        ret = (*zclient->interface_address_add) (command, zclient, length);        (*zclient->interface_address_add) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_INTERFACE_ADDRESS_DELETE:      case ZEBRA_INTERFACE_ADDRESS_DELETE:
       if (zclient->interface_address_delete)        if (zclient->interface_address_delete)
        ret = (*zclient->interface_address_delete) (command, zclient, length);        (*zclient->interface_address_delete) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_INTERFACE_UP:      case ZEBRA_INTERFACE_UP:
       if (zclient->interface_up)        if (zclient->interface_up)
        ret = (*zclient->interface_up) (command, zclient, length);        (*zclient->interface_up) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_INTERFACE_DOWN:      case ZEBRA_INTERFACE_DOWN:
       if (zclient->interface_down)        if (zclient->interface_down)
        ret = (*zclient->interface_down) (command, zclient, length);        (*zclient->interface_down) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_IPV4_ROUTE_ADD:      case ZEBRA_IPV4_ROUTE_ADD:
       if (zclient->ipv4_route_add)        if (zclient->ipv4_route_add)
        ret = (*zclient->ipv4_route_add) (command, zclient, length);        (*zclient->ipv4_route_add) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_IPV4_ROUTE_DELETE:      case ZEBRA_IPV4_ROUTE_DELETE:
       if (zclient->ipv4_route_delete)        if (zclient->ipv4_route_delete)
        ret = (*zclient->ipv4_route_delete) (command, zclient, length);        (*zclient->ipv4_route_delete) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_IPV6_ROUTE_ADD:      case ZEBRA_IPV6_ROUTE_ADD:
       if (zclient->ipv6_route_add)        if (zclient->ipv6_route_add)
        ret = (*zclient->ipv6_route_add) (command, zclient, length);        (*zclient->ipv6_route_add) (command, zclient, length, vrf_id);
       break;        break;
     case ZEBRA_IPV6_ROUTE_DELETE:      case ZEBRA_IPV6_ROUTE_DELETE:
       if (zclient->ipv6_route_delete)        if (zclient->ipv6_route_delete)
        ret = (*zclient->ipv6_route_delete) (command, zclient, length);        (*zclient->ipv6_route_delete) (command, zclient, length, vrf_id);
       break;        break;
     default:      default:
       break;        break;
Line 949  zclient_read (struct thread *thread) Line 1061  zclient_read (struct thread *thread)
 }  }
   
 void  void
zclient_redistribute (int command, struct zclient *zclient, int type)zclient_redistribute (int command, struct zclient *zclient, int type,
     vrf_id_t vrf_id)
 {  {
   
   if (command == ZEBRA_REDISTRIBUTE_ADD)     if (command == ZEBRA_REDISTRIBUTE_ADD) 
     {      {
      if (zclient->redist[type])      if (vrf_bitmap_check (zclient->redist[type], vrf_id))
          return;           return;
      zclient->redist[type] = 1;      vrf_bitmap_set (zclient->redist[type], vrf_id);
     }      }
   else    else
     {      {
      if (!zclient->redist[type])      if (!vrf_bitmap_check (zclient->redist[type], vrf_id))
          return;           return;
      zclient->redist[type] = 0;      vrf_bitmap_unset (zclient->redist[type], vrf_id);
     }      }
   
   if (zclient->sock > 0)    if (zclient->sock > 0)
    zebra_redistribute_send (command, zclient, type);    zebra_redistribute_send (command, zclient, type, vrf_id);
 }  }
   
   
 void  void
zclient_redistribute_default (int command, struct zclient *zclient)zclient_redistribute_default (int command, struct zclient *zclient,
     vrf_id_t vrf_id)
 {  {
   
   if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)    if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
     {      {
      if (zclient->default_information)      if (vrf_bitmap_check (zclient->default_information, vrf_id))
         return;          return;
      zclient->default_information = 1;      vrf_bitmap_set (zclient->default_information, vrf_id);
     }      }
   else     else 
     {      {
      if (!zclient->default_information)      if (!vrf_bitmap_check (zclient->default_information, vrf_id))
         return;          return;
      zclient->default_information = 0;      vrf_bitmap_unset (zclient->default_information, vrf_id);
     }      }
   
   if (zclient->sock > 0)    if (zclient->sock > 0)
    zebra_message_send (zclient, command);    zebra_message_send (zclient, command, vrf_id);
 }  }
   
 static void  static void
Line 999  zclient_event (enum event event, struct zclient *zclie Line 1113  zclient_event (enum event event, struct zclient *zclie
     case ZCLIENT_SCHEDULE:      case ZCLIENT_SCHEDULE:
       if (! zclient->t_connect)        if (! zclient->t_connect)
         zclient->t_connect =          zclient->t_connect =
          thread_add_event (master, zclient_connect, zclient, 0);          thread_add_event (zclient->master, zclient_connect, zclient, 0);
       break;        break;
     case ZCLIENT_CONNECT:      case ZCLIENT_CONNECT:
       if (zclient->fail >= 10)        if (zclient->fail >= 10)
Line 1009  zclient_event (enum event event, struct zclient *zclie Line 1123  zclient_event (enum event event, struct zclient *zclie
                    zclient->fail < 3 ? 10 : 60);                     zclient->fail < 3 ? 10 : 60);
       if (! zclient->t_connect)        if (! zclient->t_connect)
         zclient->t_connect =           zclient->t_connect = 
          thread_add_timer (master, zclient_connect, zclient,          thread_add_timer (zclient->master, zclient_connect, zclient,
                             zclient->fail < 3 ? 10 : 60);                              zclient->fail < 3 ? 10 : 60);
       break;        break;
     case ZCLIENT_READ:      case ZCLIENT_READ:
       zclient->t_read =         zclient->t_read = 
        thread_add_read (master, zclient_read, zclient, zclient->sock);        thread_add_read (zclient->master, zclient_read, zclient, zclient->sock);
       break;        break;
     }      }
 }  }
   
   const char *zclient_serv_path_get()
   {
     return zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH;
   }
   
   void
   zclient_serv_path_set (char *path)
   {
     struct stat sb;
   
     /* reset */
     zclient_serv_path = NULL;
   
     /* test if `path' is socket. don't set it otherwise. */
     if (stat(path, &sb) == -1)
       {
         zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
         return;
       }
   
     if ((sb.st_mode & S_IFMT) != S_IFSOCK)
       {
         zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
         return;
       }
   
     /* it seems that path is unix socket */
     zclient_serv_path = path;
   }
   

Removed from v.1.1  
changed lines
  Added in v.1.1.1.4


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