Diff for /embedaddon/quagga/zebra/zserv.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2012/02/21 17:26:11 version 1.1.1.4, 2016/11/02 10:09:10
Line 36 Line 36
 #include "privs.h"  #include "privs.h"
 #include "network.h"  #include "network.h"
 #include "buffer.h"  #include "buffer.h"
   #include "vrf.h"
   
 #include "zebra/zserv.h"  #include "zebra/zserv.h"
 #include "zebra/router-id.h"  #include "zebra/router-id.h"
 #include "zebra/redistribute.h"  #include "zebra/redistribute.h"
 #include "zebra/debug.h"  #include "zebra/debug.h"
 #include "zebra/ipforward.h"  #include "zebra/ipforward.h"
 /* Event list of zebra. */  /* Event list of zebra. */
 enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };  enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
   
Line 51  extern struct zebra_t zebrad; Line 52  extern struct zebra_t zebrad;
 static void zebra_event (enum event event, int sock, struct zserv *client);  static void zebra_event (enum event event, int sock, struct zserv *client);
   
 extern struct zebra_privs_t zserv_privs;  extern struct zebra_privs_t zserv_privs;
 static void zebra_client_close (struct zserv *client);  static void zebra_client_close (struct zserv *client);
   
 static int  static int
Line 64  zserv_delayed_close(struct thread *thread) Line 65  zserv_delayed_close(struct thread *thread)
   return 0;    return 0;
 }  }
   
   /* When client connects, it sends hello message
    * with promise to send zebra routes of specific type.
    * Zebra stores a socket fd of the client into
    * this array. And use it to clean up routes that
    * client didn't remove for some reasons after closing
    * connection.
    */
   static int route_type_oaths[ZEBRA_ROUTE_MAX];
   
 static int  static int
 zserv_flush_data(struct thread *thread)  zserv_flush_data(struct thread *thread)
 {  {
Line 122  zebra_server_send_message(struct zserv *client) Line 132  zebra_server_send_message(struct zserv *client)
 }  }
   
 static void  static void
zserv_create_header (struct stream *s, uint16_t cmd)zserv_create_header (struct stream *s, uint16_t cmd, 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, cmd);    stream_putw (s, cmd);
 }  }
   
   static void
   zserv_encode_interface (struct stream *s, struct interface *ifp)
   {
     /* Interface information. */
     stream_put (s, ifp->name, INTERFACE_NAMSIZ);
     stream_putl (s, ifp->ifindex);
     stream_putc (s, ifp->status);
     stream_putq (s, ifp->flags);
     stream_putl (s, ifp->metric);
     stream_putl (s, ifp->mtu);
     stream_putl (s, ifp->mtu6);
     stream_putl (s, ifp->bandwidth);
     stream_putl (s, ifp->ll_type);
     stream_putl (s, ifp->hw_addr_len);
     if (ifp->hw_addr_len)
       stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
   
     /* Write packet size. */
     stream_putw_at (s, 0, stream_get_endp (s));
   }
   
 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */  /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
 /*  /*
  * This function is called in the following situations:   * This function is called in the following situations:
Line 148  zsend_interface_add (struct zserv *client, struct inte Line 180  zsend_interface_add (struct zserv *client, struct inte
   struct stream *s;    struct stream *s;
   
   /* Check this client need interface information. */    /* Check this client need interface information. */
  if (! client->ifinfo)  if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
     return 0;      return 0;
   
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
   
  /* Message type. */  zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
  zserv_create_header (s, ZEBRA_INTERFACE_ADD);  zserv_encode_interface (s, ifp);
   
   /* Interface information. */  
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);  
   stream_putl (s, ifp->ifindex);  
   stream_putc (s, ifp->status);  
   stream_putq (s, ifp->flags);  
   stream_putl (s, ifp->metric);  
   stream_putl (s, ifp->mtu);  
   stream_putl (s, ifp->mtu6);  
   stream_putl (s, ifp->bandwidth);  
 #ifdef HAVE_STRUCT_SOCKADDR_DL  
   stream_put (s, &ifp->sdl, sizeof (ifp->sdl));  
 #else  
   stream_putl (s, ifp->hw_addr_len);  
   if (ifp->hw_addr_len)  
     stream_put (s, ifp->hw_addr, ifp->hw_addr_len);  
 #endif /* HAVE_STRUCT_SOCKADDR_DL */  
   
   /* Write packet size. */  
   stream_putw_at (s, 0, stream_get_endp (s));  
   
   return zebra_server_send_message(client);    return zebra_server_send_message(client);
 }  }
   
Line 187  zsend_interface_delete (struct zserv *client, struct i Line 199  zsend_interface_delete (struct zserv *client, struct i
   struct stream *s;    struct stream *s;
   
   /* Check this client need interface information. */    /* Check this client need interface information. */
  if (! client->ifinfo)  if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
     return 0;      return 0;
   
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
     
   zserv_create_header (s, ZEBRA_INTERFACE_DELETE);  
     
   /* Interface information. */  
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);  
   stream_putl (s, ifp->ifindex);  
   stream_putc (s, ifp->status);  
   stream_putq (s, ifp->flags);  
   stream_putl (s, ifp->metric);  
   stream_putl (s, ifp->mtu);  
   stream_putl (s, ifp->mtu6);  
   stream_putl (s, ifp->bandwidth);  
   
  /* Write packet length. */  zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
  stream_putw_at (s, 0, stream_get_endp (s));  zserv_encode_interface (s, ifp);
   
   return zebra_server_send_message (client);    return zebra_server_send_message (client);
 }  }
Line 258  zsend_interface_address (int cmd, struct zserv *client Line 258  zsend_interface_address (int cmd, struct zserv *client
   struct prefix *p;    struct prefix *p;
   
   /* Check this client need interface information. */    /* Check this client need interface information. */
  if (! client->ifinfo)  if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
     return 0;      return 0;
   
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
       
  zserv_create_header (s, cmd);  zserv_create_header (s, cmd, ifp->vrf_id);
   stream_putl (s, ifp->ifindex);    stream_putl (s, ifp->ifindex);
   
   /* Interface address flag. */    /* Interface address flag. */
Line 312  zsend_interface_update (int cmd, struct zserv *client, Line 312  zsend_interface_update (int cmd, struct zserv *client,
   struct stream *s;    struct stream *s;
   
   /* Check this client need interface information. */    /* Check this client need interface information. */
  if (! client->ifinfo)  if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
     return 0;      return 0;
   
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
   
  zserv_create_header (s, cmd);  zserv_create_header (s, cmd, ifp->vrf_id);
   zserv_encode_interface (s, ifp);
   
   /* Interface information. */  
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);  
   stream_putl (s, ifp->ifindex);  
   stream_putc (s, ifp->status);  
   stream_putq (s, ifp->flags);  
   stream_putl (s, ifp->metric);  
   stream_putl (s, ifp->mtu);  
   stream_putl (s, ifp->mtu6);  
   stream_putl (s, ifp->bandwidth);  
   
   /* Write packet size. */  
   stream_putw_at (s, 0, stream_get_endp (s));  
   
   return zebra_server_send_message(client);    return zebra_server_send_message(client);
 }  }
   
Line 369  zsend_route_multipath (int cmd, struct zserv *client,  Line 357  zsend_route_multipath (int cmd, struct zserv *client, 
   unsigned long nhnummark = 0, messmark = 0;    unsigned long nhnummark = 0, messmark = 0;
   int nhnum = 0;    int nhnum = 0;
   u_char zapi_flags = 0;    u_char zapi_flags = 0;
  
   /* Check this client need this route. */
   if (!vrf_bitmap_check (client->redist[rib->type], rib->vrf_id) &&
       !(is_default (p) &&
         vrf_bitmap_check (client->redist_default, rib->vrf_id)))
     return 0;
 
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
       
  zserv_create_header (s, cmd);  zserv_create_header (s, cmd, rib->vrf_id);
       
   /* Put type and nexthop. */    /* Put type and nexthop. */
   stream_putc (s, rib->type);    stream_putc (s, rib->type);
Line 400  zsend_route_multipath (int cmd, struct zserv *client,  Line 394  zsend_route_multipath (int cmd, struct zserv *client, 
       
   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)    for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
     {      {
      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))      if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
         {          {
           SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);            SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
           SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);            SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
Line 457  zsend_route_multipath (int cmd, struct zserv *client,  Line 451  zsend_route_multipath (int cmd, struct zserv *client, 
       stream_putc (s, rib->distance);        stream_putc (s, rib->distance);
       SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);        SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
       stream_putl (s, rib->metric);        stream_putl (s, rib->metric);
         SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
         stream_putl (s, rib->mtu);
     }      }
       
   /* write real message flags value */    /* write real message flags value */
Line 474  zsend_route_multipath (int cmd, struct zserv *client,  Line 470  zsend_route_multipath (int cmd, struct zserv *client, 
   
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
 static int  static int
zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
     vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   struct rib *rib;    struct rib *rib;
Line 483  zsend_ipv6_nexthop_lookup (struct zserv *client, struc Line 480  zsend_ipv6_nexthop_lookup (struct zserv *client, struc
   struct nexthop *nexthop;    struct nexthop *nexthop;
   
   /* Lookup nexthop. */    /* Lookup nexthop. */
  rib = rib_match_ipv6 (addr);  rib = rib_match_ipv6 (addr, vrf_id);
   
   /* Get output stream. */    /* Get output stream. */
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
   
   /* Fill in result. */    /* Fill in result. */
  zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);  zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
  stream_put (s, &addr, 16);  stream_put (s, addr, 16);
   
   if (rib)    if (rib)
     {      {
Line 499  zsend_ipv6_nexthop_lookup (struct zserv *client, struc Line 496  zsend_ipv6_nexthop_lookup (struct zserv *client, struc
       num = 0;        num = 0;
       nump = stream_get_endp(s);        nump = stream_get_endp(s);
       stream_putc (s, 0);        stream_putc (s, 0);
         /* Only non-recursive routes are elegible to resolve nexthop we
          * are looking up. Therefore, we will just iterate over the top
          * chain of nexthops. */
       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)        for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
           {            {
             stream_putc (s, nexthop->type);              stream_putc (s, nexthop->type);
             switch (nexthop->type)              switch (nexthop->type)
Line 538  zsend_ipv6_nexthop_lookup (struct zserv *client, struc Line 538  zsend_ipv6_nexthop_lookup (struct zserv *client, struc
 #endif /* HAVE_IPV6 */  #endif /* HAVE_IPV6 */
   
 static int  static int
zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
     vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   struct rib *rib;    struct rib *rib;
Line 546  zsend_ipv4_nexthop_lookup (struct zserv *client, struc Line 547  zsend_ipv4_nexthop_lookup (struct zserv *client, struc
   u_char num;    u_char num;
   struct nexthop *nexthop;    struct nexthop *nexthop;
   
  /* Lookup nexthop. */  /* Lookup nexthop - eBGP excluded */
  rib = rib_match_ipv4 (addr);  rib = rib_match_ipv4_safi (addr, SAFI_UNICAST, 1, NULL, vrf_id);
   
   /* Get output stream. */    /* Get output stream. */
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
   
   /* Fill in result. */    /* Fill in result. */
  zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);  zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
   stream_put_in_addr (s, &addr);    stream_put_in_addr (s, &addr);
   
   if (rib)    if (rib)
     {      {
         if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
           zlog_debug("%s: Matching rib entry found.", __func__);
       stream_putl (s, rib->metric);        stream_putl (s, rib->metric);
       num = 0;        num = 0;
       nump = stream_get_endp(s);        nump = stream_get_endp(s);
       stream_putc (s, 0);        stream_putc (s, 0);
         /* Only non-recursive routes are elegible to resolve the nexthop we
          * are looking up. Therefore, we will just iterate over the top
          * chain of nexthops. */
       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)        for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
           {            {
             stream_putc (s, nexthop->type);              stream_putc (s, nexthop->type);
             switch (nexthop->type)              switch (nexthop->type)
Line 572  zsend_ipv4_nexthop_lookup (struct zserv *client, struc Line 578  zsend_ipv4_nexthop_lookup (struct zserv *client, struc
               case ZEBRA_NEXTHOP_IPV4:                case ZEBRA_NEXTHOP_IPV4:
                 stream_put_in_addr (s, &nexthop->gate.ipv4);                  stream_put_in_addr (s, &nexthop->gate.ipv4);
                 break;                  break;
                 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
                   stream_put_in_addr (s, &nexthop->gate.ipv4);
                   stream_putl (s, nexthop->ifindex);
                   break;
               case ZEBRA_NEXTHOP_IFINDEX:                case ZEBRA_NEXTHOP_IFINDEX:
               case ZEBRA_NEXTHOP_IFNAME:                case ZEBRA_NEXTHOP_IFNAME:
                 stream_putl (s, nexthop->ifindex);                  stream_putl (s, nexthop->ifindex);
Line 586  zsend_ipv4_nexthop_lookup (struct zserv *client, struc Line 596  zsend_ipv4_nexthop_lookup (struct zserv *client, struc
     }      }
   else    else
     {      {
         if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
           zlog_debug("%s: No matching rib entry found.", __func__);
       stream_putl (s, 0);        stream_putl (s, 0);
       stream_putc (s, 0);        stream_putc (s, 0);
     }      }
Line 595  zsend_ipv4_nexthop_lookup (struct zserv *client, struc Line 607  zsend_ipv4_nexthop_lookup (struct zserv *client, struc
   return zebra_server_send_message(client);    return zebra_server_send_message(client);
 }  }
   
   /*
     Modified version of zsend_ipv4_nexthop_lookup():
     Query unicast rib if nexthop is not found on mrib.
     Returns both route metric and protocol distance.
   */
 static int  static int
zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr,
                                 struct rib *rib)
 {  {
   struct stream *s;    struct stream *s;
     unsigned long nump;
     u_char num;
     struct nexthop *nexthop;
   
     /* Get output stream. */
     s = client->obuf;
     stream_reset (s);
   
     /* Fill in result. */
     zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, rib->vrf_id);
     stream_put_in_addr (s, &addr);
   
     if (rib)
       {
         stream_putc (s, rib->distance);
         stream_putl (s, rib->metric);
         num = 0;
         nump = stream_get_endp(s); /* remember position for nexthop_num */
         stream_putc (s, 0);        /* reserve room for nexthop_num */
         /* Only non-recursive routes are elegible to resolve the nexthop we
          * are looking up. Therefore, we will just iterate over the top
          * chain of nexthops. */
         for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
           if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
             {
               stream_putc (s, nexthop->type);
               switch (nexthop->type)
                 {
                 case ZEBRA_NEXTHOP_IPV4:
                   stream_put_in_addr (s, &nexthop->gate.ipv4);
                   break;
                 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
                   stream_put_in_addr (s, &nexthop->gate.ipv4);
                   stream_putl (s, nexthop->ifindex);
                   break;
                 case ZEBRA_NEXTHOP_IFINDEX:
                 case ZEBRA_NEXTHOP_IFNAME:
                   stream_putl (s, nexthop->ifindex);
                   break;
                 default:
                   /* do nothing */
                   break;
                 }
               num++;
             }
       
         stream_putc_at (s, nump, num); /* store nexthop_num */
       }
     else
       {
         stream_putc (s, 0); /* distance */
         stream_putl (s, 0); /* metric */
         stream_putc (s, 0); /* nexthop_num */
       }
   
     stream_putw_at (s, 0, stream_get_endp (s));
     
     return zebra_server_send_message(client);
   }
   
   static int
   zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
       vrf_id_t vrf_id)
   {
     struct stream *s;
   struct rib *rib;    struct rib *rib;
   unsigned long nump;    unsigned long nump;
   u_char num;    u_char num;
   struct nexthop *nexthop;    struct nexthop *nexthop;
   
   /* Lookup nexthop. */    /* Lookup nexthop. */
  rib = rib_lookup_ipv4 (p);  rib = rib_lookup_ipv4 (p, vrf_id);
   
   /* Get output stream. */    /* Get output stream. */
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
   
   /* Fill in result. */    /* Fill in result. */
  zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP);  zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
   stream_put_in_addr (s, &p->prefix);    stream_put_in_addr (s, &p->prefix);
   
   if (rib)    if (rib)
Line 622  zsend_ipv4_import_lookup (struct zserv *client, struct Line 705  zsend_ipv4_import_lookup (struct zserv *client, struct
       nump = stream_get_endp(s);        nump = stream_get_endp(s);
       stream_putc (s, 0);        stream_putc (s, 0);
       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)        for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
           {            {
             stream_putc (s, nexthop->type);              stream_putc (s, nexthop->type);
             switch (nexthop->type)              switch (nexthop->type)
Line 630  zsend_ipv4_import_lookup (struct zserv *client, struct Line 713  zsend_ipv4_import_lookup (struct zserv *client, struct
               case ZEBRA_NEXTHOP_IPV4:                case ZEBRA_NEXTHOP_IPV4:
                 stream_put_in_addr (s, &nexthop->gate.ipv4);                  stream_put_in_addr (s, &nexthop->gate.ipv4);
                 break;                  break;
                 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
                   stream_put_in_addr (s, &nexthop->gate.ipv4);
                   stream_putl (s, nexthop->ifindex);
                   break;
               case ZEBRA_NEXTHOP_IFINDEX:                case ZEBRA_NEXTHOP_IFINDEX:
               case ZEBRA_NEXTHOP_IFNAME:                case ZEBRA_NEXTHOP_IFNAME:
                 stream_putl (s, nexthop->ifindex);                  stream_putl (s, nexthop->ifindex);
Line 652  zsend_ipv4_import_lookup (struct zserv *client, struct Line 739  zsend_ipv4_import_lookup (struct zserv *client, struct
       
   return zebra_server_send_message(client);    return zebra_server_send_message(client);
 }  }
 /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */  /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
 int  int
zsend_router_id_update (struct zserv *client, struct prefix *p)zsend_router_id_update (struct zserv *client, struct prefix *p,
     vrf_id_t vrf_id)
 {  {
   struct stream *s;    struct stream *s;
   int blen;    int blen;
   
   /* Check this client need interface information. */    /* Check this client need interface information. */
  if (!client->ridinfo)  if (! vrf_bitmap_check (client->ridinfo, vrf_id))
     return 0;      return 0;
   
   s = client->obuf;    s = client->obuf;
   stream_reset (s);    stream_reset (s);
   
   /* Message type. */    /* Message type. */
  zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE);  zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
   
   /* Prefix information. */    /* Prefix information. */
   stream_putc (s, p->family);    stream_putc (s, p->family);
Line 681  zsend_router_id_update (struct zserv *client, struct p Line 769  zsend_router_id_update (struct zserv *client, struct p
   
   return zebra_server_send_message(client);    return zebra_server_send_message(client);
 }  }
 /* Register zebra server interface information.  Send current all  /* Register zebra server interface information.  Send current all
    interface and address information. */     interface and address information. */
 static int  static int
zread_interface_add (struct zserv *client, u_short length)zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
 {  {
   struct listnode *ifnode, *ifnnode;    struct listnode *ifnode, *ifnnode;
   struct listnode *cnode, *cnnode;    struct listnode *cnode, *cnnode;
Line 693  zread_interface_add (struct zserv *client, u_short len Line 781  zread_interface_add (struct zserv *client, u_short len
   struct connected *c;    struct connected *c;
   
   /* Interface information is needed. */    /* Interface information is needed. */
  client->ifinfo = 1;  vrf_bitmap_set (client->ifinfo, vrf_id);
   
  for (ALL_LIST_ELEMENTS (iflist, ifnode, ifnnode, ifp))  for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
     {      {
       /* Skip pseudo interface. */        /* Skip pseudo interface. */
       if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))        if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
Line 717  zread_interface_add (struct zserv *client, u_short len Line 805  zread_interface_add (struct zserv *client, u_short len
   
 /* Unregister zebra server interface information. */  /* Unregister zebra server interface information. */
 static int  static int
zread_interface_delete (struct zserv *client, u_short length)zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
 {  {
  client->ifinfo = 0;  vrf_bitmap_unset (client->ifinfo, vrf_id);
   return 0;    return 0;
 }  }
   
Line 729  zread_interface_delete (struct zserv *client, u_short  Line 817  zread_interface_delete (struct zserv *client, u_short 
  * add kernel route.    * add kernel route. 
  */   */
 static int  static int
zread_ipv4_add (struct zserv *client, u_short length)zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
 {  {
   int i;    int i;
   struct rib *rib;    struct rib *rib;
Line 739  zread_ipv4_add (struct zserv *client, u_short length) Line 827  zread_ipv4_add (struct zserv *client, u_short length)
   u_char nexthop_num;    u_char nexthop_num;
   u_char nexthop_type;    u_char nexthop_type;
   struct stream *s;    struct stream *s;
  unsigned int ifindex;  ifindex_t ifindex;
   u_char ifname_len;    u_char ifname_len;
     safi_t safi;  
   
   
   /* Get input stream.  */    /* Get input stream.  */
   s = client->ibuf;    s = client->ibuf;
   
Line 752  zread_ipv4_add (struct zserv *client, u_short length) Line 842  zread_ipv4_add (struct zserv *client, u_short length)
   rib->type = stream_getc (s);    rib->type = stream_getc (s);
   rib->flags = stream_getc (s);    rib->flags = stream_getc (s);
   message = stream_getc (s);     message = stream_getc (s); 
     safi = stream_getw (s);
   rib->uptime = time (NULL);    rib->uptime = time (NULL);
   
   /* IPv4 prefix. */    /* IPv4 prefix. */
Line 760  zread_ipv4_add (struct zserv *client, u_short length) Line 851  zread_ipv4_add (struct zserv *client, u_short length)
   p.prefixlen = stream_getc (s);    p.prefixlen = stream_getc (s);
   stream_get (&p.prefix, s, PSIZE (p.prefixlen));    stream_get (&p.prefix, s, PSIZE (p.prefixlen));
   
     /* VRF ID */
     rib->vrf_id = vrf_id;
   
   /* Nexthop parse. */    /* Nexthop parse. */
   if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))    if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
     {      {
Line 783  zread_ipv4_add (struct zserv *client, u_short length) Line 877  zread_ipv4_add (struct zserv *client, u_short length)
               nexthop.s_addr = stream_get_ipv4 (s);                nexthop.s_addr = stream_get_ipv4 (s);
               nexthop_ipv4_add (rib, &nexthop, NULL);                nexthop_ipv4_add (rib, &nexthop, NULL);
               break;                break;
               case ZEBRA_NEXTHOP_IPV4_IFINDEX:
                 nexthop.s_addr = stream_get_ipv4 (s);
                 ifindex = stream_getl (s);
                 nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
                 break;
             case ZEBRA_NEXTHOP_IPV6:              case ZEBRA_NEXTHOP_IPV6:
               stream_forward_getp (s, IPV6_MAX_BYTELEN);                stream_forward_getp (s, IPV6_MAX_BYTELEN);
               break;                break;
      case ZEBRA_NEXTHOP_BLACKHOLE:            case ZEBRA_NEXTHOP_BLACKHOLE:
        nexthop_blackhole_add (rib);              nexthop_blackhole_add (rib);
        break;              break;
            }            }
         }          }
     }      }
   
Line 801  zread_ipv4_add (struct zserv *client, u_short length) Line 900  zread_ipv4_add (struct zserv *client, u_short length)
   if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))    if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
     rib->metric = stream_getl (s);      rib->metric = stream_getl (s);
           
     if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
       rib->mtu = stream_getl (s);
   
   /* Table */    /* Table */
   rib->table=zebrad.rtm_table_default;    rib->table=zebrad.rtm_table_default;
  rib_add_ipv4_multipath (&p, rib);  rib_add_ipv4_multipath (&p, rib, safi);
   return 0;    return 0;
 }  }
   
 /* Zebra server IPv4 prefix delete function. */  /* Zebra server IPv4 prefix delete function. */
 static int  static int
zread_ipv4_delete (struct zserv *client, u_short length)zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
 {  {
   int i;    int i;
   struct stream *s;    struct stream *s;
   struct zapi_ipv4 api;    struct zapi_ipv4 api;
  struct in_addr nexthop;  struct in_addr nexthop, *nexthop_p;
   unsigned long ifindex;    unsigned long ifindex;
   struct prefix_ipv4 p;    struct prefix_ipv4 p;
   u_char nexthop_num;    u_char nexthop_num;
Line 824  zread_ipv4_delete (struct zserv *client, u_short lengt Line 926  zread_ipv4_delete (struct zserv *client, u_short lengt
   s = client->ibuf;    s = client->ibuf;
   ifindex = 0;    ifindex = 0;
   nexthop.s_addr = 0;    nexthop.s_addr = 0;
     nexthop_p = NULL;
   
   /* Type, flags, message. */    /* Type, flags, message. */
   api.type = stream_getc (s);    api.type = stream_getc (s);
   api.flags = stream_getc (s);    api.flags = stream_getc (s);
   api.message = stream_getc (s);    api.message = stream_getc (s);
     api.safi = stream_getw (s);
   
   /* IPv4 prefix. */    /* IPv4 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv4));    memset (&p, 0, sizeof (struct prefix_ipv4));
Line 856  zread_ipv4_delete (struct zserv *client, u_short lengt Line 960  zread_ipv4_delete (struct zserv *client, u_short lengt
               break;                break;
             case ZEBRA_NEXTHOP_IPV4:              case ZEBRA_NEXTHOP_IPV4:
               nexthop.s_addr = stream_get_ipv4 (s);                nexthop.s_addr = stream_get_ipv4 (s);
                 nexthop_p = &nexthop;
               break;                break;
               case ZEBRA_NEXTHOP_IPV4_IFINDEX:
                 nexthop.s_addr = stream_get_ipv4 (s);
                 nexthop_p = &nexthop;
                 ifindex = stream_getl (s);
                 break;
             case ZEBRA_NEXTHOP_IPV6:              case ZEBRA_NEXTHOP_IPV6:
               stream_forward_getp (s, IPV6_MAX_BYTELEN);                stream_forward_getp (s, IPV6_MAX_BYTELEN);
               break;                break;
Line 876  zread_ipv4_delete (struct zserv *client, u_short lengt Line 986  zread_ipv4_delete (struct zserv *client, u_short lengt
   else    else
     api.metric = 0;      api.metric = 0;
           
  rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,  rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
                   client->rtm_table);                   vrf_id, api.safi);
   return 0;    return 0;
 }  }
   
 /* Nexthop lookup for IPv4. */  /* Nexthop lookup for IPv4. */
 static int  static int
zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
     vrf_id_t vrf_id)
 {  {
   struct in_addr addr;    struct in_addr addr;
     char buf[BUFSIZ];
   
   addr.s_addr = stream_get_ipv4 (client->ibuf);    addr.s_addr = stream_get_ipv4 (client->ibuf);
  return zsend_ipv4_nexthop_lookup (client, addr);  if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
     zlog_debug("%s: looking up %s", __func__,
                inet_ntop (AF_INET, &addr, buf, BUFSIZ));
   return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
 }  }
   
   /* MRIB Nexthop lookup for IPv4. */
   static int
   zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length,
       vrf_id_t vrf_id)
   {
     struct in_addr addr;
     struct rib *rib;
   
     addr.s_addr = stream_get_ipv4 (client->ibuf);
     rib = rib_match_ipv4_multicast (addr, NULL, vrf_id);
     return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib);
   }
   
 /* Nexthop lookup for IPv4. */  /* Nexthop lookup for IPv4. */
 static int  static int
zread_ipv4_import_lookup (struct zserv *client, u_short length)zread_ipv4_import_lookup (struct zserv *client, u_short length,
     vrf_id_t vrf_id)
 {  {
   struct prefix_ipv4 p;    struct prefix_ipv4 p;
   
Line 901  zread_ipv4_import_lookup (struct zserv *client, u_shor Line 1030  zread_ipv4_import_lookup (struct zserv *client, u_shor
   p.prefixlen = stream_getc (client->ibuf);    p.prefixlen = stream_getc (client->ibuf);
   p.prefix.s_addr = stream_get_ipv4 (client->ibuf);    p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
   
  return zsend_ipv4_import_lookup (client, &p);  return zsend_ipv4_import_lookup (client, &p, vrf_id);
 }  }
   
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
 /* Zebra server IPv6 prefix add function. */  /* Zebra server IPv6 prefix add function. */
 static int  static int
zread_ipv6_add (struct zserv *client, u_short length)zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
 {  {
   int i;    int i;
   struct stream *s;    struct stream *s;
Line 924  zread_ipv6_add (struct zserv *client, u_short length) Line 1053  zread_ipv6_add (struct zserv *client, u_short length)
   api.type = stream_getc (s);    api.type = stream_getc (s);
   api.flags = stream_getc (s);    api.flags = stream_getc (s);
   api.message = stream_getc (s);    api.message = stream_getc (s);
     api.safi = stream_getw (s);
   
   /* IPv4 prefix. */    /* IPv4 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv6));    memset (&p, 0, sizeof (struct prefix_ipv6));
Line 962  zread_ipv6_add (struct zserv *client, u_short length) Line 1092  zread_ipv6_add (struct zserv *client, u_short length)
     api.metric = stream_getl (s);      api.metric = stream_getl (s);
   else    else
     api.metric = 0;      api.metric = 0;
   
     if (CHECK_FLAG (api.message, ZAPI_MESSAGE_MTU))
       api.mtu = stream_getl (s);
     else
       api.mtu = 0;
           
   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))    if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
    rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, zebrad.rtm_table_default, api.metric,    rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex,
                  api.distance);                  vrf_id, zebrad.rtm_table_default, api.metric,
                   api.mtu, api.distance, api.safi);
   else    else
    rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, zebrad.rtm_table_default, api.metric,    rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex,
                  api.distance);                  vrf_id, zebrad.rtm_table_default, api.metric,
                   api.mtu, api.distance, api.safi);
   return 0;    return 0;
 }  }
   
 /* Zebra server IPv6 prefix delete function. */  /* Zebra server IPv6 prefix delete function. */
 static int  static int
zread_ipv6_delete (struct zserv *client, u_short length)zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
 {  {
   int i;    int i;
   struct stream *s;    struct stream *s;
Line 991  zread_ipv6_delete (struct zserv *client, u_short lengt Line 1128  zread_ipv6_delete (struct zserv *client, u_short lengt
   api.type = stream_getc (s);    api.type = stream_getc (s);
   api.flags = stream_getc (s);    api.flags = stream_getc (s);
   api.message = stream_getc (s);    api.message = stream_getc (s);
     api.safi = stream_getw (s);
   
   /* IPv4 prefix. */    /* IPv4 prefix. */
   memset (&p, 0, sizeof (struct prefix_ipv6));    memset (&p, 0, sizeof (struct prefix_ipv6));
Line 1030  zread_ipv6_delete (struct zserv *client, u_short lengt Line 1168  zread_ipv6_delete (struct zserv *client, u_short lengt
     api.metric = 0;      api.metric = 0;
           
   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))    if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
    rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table);    rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, vrf_id,
                      api.safi);
   else    else
    rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table);    rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, vrf_id,
                      api.safi);
   return 0;    return 0;
 }  }
   
 static int  static int
zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
     vrf_id_t vrf_id)
 {  {
   struct in6_addr addr;    struct in6_addr addr;
   char buf[BUFSIZ];    char buf[BUFSIZ];
   
   stream_get (&addr, client->ibuf, 16);    stream_get (&addr, client->ibuf, 16);
  printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));  if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
     zlog_debug("%s: looking up %s", __func__,
                inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
   
  return zsend_ipv6_nexthop_lookup (client, &addr);  return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
 }  }
 #endif /* HAVE_IPV6 */  #endif /* HAVE_IPV6 */
   
 /* Register zebra server router-id information.  Send current router-id */  /* Register zebra server router-id information.  Send current router-id */
 static int  static int
zread_router_id_add (struct zserv *client, u_short length)zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
 {  {
   struct prefix p;    struct prefix p;
   
   /* Router-id information is needed. */    /* Router-id information is needed. */
  client->ridinfo = 1;  vrf_bitmap_set (client->ridinfo, vrf_id);
   
  router_id_get (&p);  router_id_get (&p, vrf_id);
   
  return zsend_router_id_update (client,&p);  return zsend_router_id_update (client, &p, vrf_id);
 }  }
   
 /* Unregister zebra server router-id information. */  /* Unregister zebra server router-id information. */
 static int  static int
zread_router_id_delete (struct zserv *client, u_short length)zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
 {  {
  client->ridinfo = 0;  vrf_bitmap_unset (client->ridinfo, vrf_id);
   return 0;    return 0;
 }  }
   
   /* Tie up route-type and client->sock */
   static void
   zread_hello (struct zserv *client)
   {
     /* type of protocol (lib/zebra.h) */
     u_char proto;
     proto = stream_getc (client->ibuf);
   
     /* accept only dynamic routing protocols */
     if ((proto < ZEBRA_ROUTE_MAX)
     &&  (proto > ZEBRA_ROUTE_STATIC))
       {
         zlog_notice ("client %d says hello and bids fair to announce only %s routes",
                       client->sock, zebra_route_string(proto));
   
         /* if route-type was binded by other client */
         if (route_type_oaths[proto])
           zlog_warn ("sender of %s routes changed %c->%c",
                       zebra_route_string(proto), route_type_oaths[proto],
                       client->sock);
   
         route_type_oaths[proto] = client->sock;
       }
   }
   
   /* Unregister all information in a VRF. */
   static int
   zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
   {
     int i;
   
     for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
       vrf_bitmap_unset (client->redist[i], vrf_id);
     vrf_bitmap_unset (client->redist_default, vrf_id);
     vrf_bitmap_unset (client->ifinfo, vrf_id);
     vrf_bitmap_unset (client->ridinfo, vrf_id);
   
     return 0;
   }
   
   /* If client sent routes of specific type, zebra removes it
    * and returns number of deleted routes.
    */
   static void
   zebra_score_rib (int client_sock)
   {
     int i;
   
     for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
       if (client_sock == route_type_oaths[i])
         {
           zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
                         client_sock, rib_score_proto (i), zebra_route_string (i));
           route_type_oaths[i] = 0;
           break;
         }
   }
   
 /* Close zebra client. */  /* Close zebra client. */
 static void  static void
 zebra_client_close (struct zserv *client)  zebra_client_close (struct zserv *client)
Line 1079  zebra_client_close (struct zserv *client) Line 1280  zebra_client_close (struct zserv *client)
   if (client->sock)    if (client->sock)
     {      {
       close (client->sock);        close (client->sock);
         zebra_score_rib (client->sock);
       client->sock = -1;        client->sock = -1;
     }      }
   
Line 1108  static void Line 1310  static void
 zebra_client_create (int sock)  zebra_client_create (int sock)
 {  {
   struct zserv *client;    struct zserv *client;
     int i;
   
   client = XCALLOC (0, sizeof (struct zserv));    client = XCALLOC (0, sizeof (struct zserv));
   
Line 1120  zebra_client_create (int sock) Line 1323  zebra_client_create (int sock)
   /* Set table number. */    /* Set table number. */
   client->rtm_table = zebrad.rtm_table_default;    client->rtm_table = zebrad.rtm_table_default;
   
     /* Initialize flags */
     for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
       client->redist[i] = vrf_bitmap_init ();
     client->redist_default = vrf_bitmap_init ();
     client->ifinfo = vrf_bitmap_init ();
     client->ridinfo = vrf_bitmap_init ();
   
   /* Add this client to linked list. */    /* Add this client to linked list. */
   listnode_add (zebrad.client_list, client);    listnode_add (zebrad.client_list, client);
       
Line 1136  zebra_client_read (struct thread *thread) Line 1346  zebra_client_read (struct thread *thread)
   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;
   
   /* Get thread data.  Reset reading thread because I'm running. */    /* Get thread data.  Reset reading thread because I'm running. */
   sock = THREAD_FD (thread);    sock = THREAD_FD (thread);
Line 1177  zebra_client_read (struct thread *thread) Line 1388  zebra_client_read (struct thread *thread)
   length = stream_getw (client->ibuf);    length = stream_getw (client->ibuf);
   marker = stream_getc (client->ibuf);    marker = stream_getc (client->ibuf);
   version = stream_getc (client->ibuf);    version = stream_getc (client->ibuf);
     vrf_id = stream_getw (client->ibuf);
   command = stream_getw (client->ibuf);    command = stream_getw (client->ibuf);
   
   if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)    if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
Line 1229  zebra_client_read (struct thread *thread) Line 1441  zebra_client_read (struct thread *thread)
     zlog_debug ("zebra message comes from socket [%d]", sock);      zlog_debug ("zebra message comes from socket [%d]", sock);
   
   if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)    if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
    zlog_debug ("zebra message received [%s] %d",     zlog_debug ("zebra message received [%s] %d in VRF %u",
               zserv_command_string (command), length);               zserv_command_string (command), length, vrf_id);
   
   switch (command)     switch (command) 
     {      {
     case ZEBRA_ROUTER_ID_ADD:      case ZEBRA_ROUTER_ID_ADD:
      zread_router_id_add (client, length);      zread_router_id_add (client, length, vrf_id);
       break;        break;
     case ZEBRA_ROUTER_ID_DELETE:      case ZEBRA_ROUTER_ID_DELETE:
      zread_router_id_delete (client, length);      zread_router_id_delete (client, length, vrf_id);
       break;        break;
     case ZEBRA_INTERFACE_ADD:      case ZEBRA_INTERFACE_ADD:
      zread_interface_add (client, length);      zread_interface_add (client, length, vrf_id);
       break;        break;
     case ZEBRA_INTERFACE_DELETE:      case ZEBRA_INTERFACE_DELETE:
      zread_interface_delete (client, length);      zread_interface_delete (client, length, vrf_id);
       break;        break;
     case ZEBRA_IPV4_ROUTE_ADD:      case ZEBRA_IPV4_ROUTE_ADD:
      zread_ipv4_add (client, length);      zread_ipv4_add (client, length, vrf_id);
       break;        break;
     case ZEBRA_IPV4_ROUTE_DELETE:      case ZEBRA_IPV4_ROUTE_DELETE:
      zread_ipv4_delete (client, length);      zread_ipv4_delete (client, length, vrf_id);
       break;        break;
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
     case ZEBRA_IPV6_ROUTE_ADD:      case ZEBRA_IPV6_ROUTE_ADD:
      zread_ipv6_add (client, length);      zread_ipv6_add (client, length, vrf_id);
       break;        break;
     case ZEBRA_IPV6_ROUTE_DELETE:      case ZEBRA_IPV6_ROUTE_DELETE:
      zread_ipv6_delete (client, length);      zread_ipv6_delete (client, length, vrf_id);
       break;        break;
 #endif /* HAVE_IPV6 */  #endif /* HAVE_IPV6 */
     case ZEBRA_REDISTRIBUTE_ADD:      case ZEBRA_REDISTRIBUTE_ADD:
      zebra_redistribute_add (command, client, length);      zebra_redistribute_add (command, client, length, vrf_id);
       break;        break;
     case ZEBRA_REDISTRIBUTE_DELETE:      case ZEBRA_REDISTRIBUTE_DELETE:
      zebra_redistribute_delete (command, client, length);      zebra_redistribute_delete (command, client, length, vrf_id);
       break;        break;
     case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:      case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
      zebra_redistribute_default_add (command, client, length);      zebra_redistribute_default_add (command, client, length, vrf_id);
       break;        break;
     case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:      case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
      zebra_redistribute_default_delete (command, client, length);      zebra_redistribute_default_delete (command, client, length, vrf_id);
       break;        break;
     case ZEBRA_IPV4_NEXTHOP_LOOKUP:      case ZEBRA_IPV4_NEXTHOP_LOOKUP:
      zread_ipv4_nexthop_lookup (client, length);      zread_ipv4_nexthop_lookup (client, length, vrf_id);
       break;        break;
       case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
         zread_ipv4_nexthop_lookup_mrib (client, length, vrf_id);
         break;
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
     case ZEBRA_IPV6_NEXTHOP_LOOKUP:      case ZEBRA_IPV6_NEXTHOP_LOOKUP:
      zread_ipv6_nexthop_lookup (client, length);      zread_ipv6_nexthop_lookup (client, length, vrf_id);
       break;        break;
 #endif /* HAVE_IPV6 */  #endif /* HAVE_IPV6 */
     case ZEBRA_IPV4_IMPORT_LOOKUP:      case ZEBRA_IPV4_IMPORT_LOOKUP:
      zread_ipv4_import_lookup (client, length);      zread_ipv4_import_lookup (client, length, vrf_id);
       break;        break;
       case ZEBRA_HELLO:
         zread_hello (client);
         break;
       case ZEBRA_VRF_UNREGISTER:
         zread_vrf_unregister (client, length, vrf_id);
         break;
     default:      default:
       zlog_info ("Zebra received unknown command %d", command);        zlog_info ("Zebra received unknown command %d", command);
       break;        break;
Line 1352  zebra_serv () Line 1573  zebra_serv ()
       return;        return;
     }      }
   
     memset (&route_type_oaths, 0, sizeof (route_type_oaths));
   memset (&addr, 0, sizeof (struct sockaddr_in));    memset (&addr, 0, sizeof (struct sockaddr_in));
   addr.sin_family = AF_INET;    addr.sin_family = AF_INET;
   addr.sin_port = htons (ZEBRA_PORT);    addr.sin_port = htons (ZEBRA_PORT);
Line 1392  zebra_serv () Line 1614  zebra_serv ()
   
   zebra_event (ZEBRA_SERV, accept_sock, NULL);    zebra_event (ZEBRA_SERV, accept_sock, NULL);
 }  }
#endif /* HAVE_TCP_ZEBRA */#else /* HAVE_TCP_ZEBRA */
   
 /* For sockaddr_un. */  /* For sockaddr_un. */
 #include <sys/un.h>  #include <sys/un.h>
Line 1422  zebra_serv_un (const char *path) Line 1644  zebra_serv_un (const char *path)
       return;        return;
     }      }
   
     memset (&route_type_oaths, 0, sizeof (route_type_oaths));
   
   /* Make server socket. */    /* Make server socket. */
   memset (&serv, 0, sizeof (struct sockaddr_un));    memset (&serv, 0, sizeof (struct sockaddr_un));
   serv.sun_family = AF_UNIX;    serv.sun_family = AF_UNIX;
Line 1456  zebra_serv_un (const char *path) Line 1680  zebra_serv_un (const char *path)
   
   zebra_event (ZEBRA_SERV, sock, NULL);    zebra_event (ZEBRA_SERV, sock, NULL);
 }  }
#endif /* HAVE_TCP_ZEBRA */
   
   
 static void  static void
 zebra_event (enum event event, int sock, struct zserv *client)  zebra_event (enum event event, int sock, struct zserv *client)
 {  {
Line 1475  zebra_event (enum event event, int sock, struct zserv  Line 1700  zebra_event (enum event event, int sock, struct zserv 
       break;        break;
     }      }
 }  }
 /* Display default rtm_table for all clients. */  /* Display default rtm_table for all clients. */
 DEFUN (show_table,  DEFUN (show_table,
        show_table_cmd,         show_table_cmd,
Line 1575  static struct cmd_node table_node = Line 1800  static struct cmd_node table_node =
   "",                           /* This node has no interface. */    "",                           /* This node has no interface. */
   1    1
 };  };
 /* Only display ip forwarding is enabled or not. */  /* Only display ip forwarding is enabled or not. */
 DEFUN (show_ip_forwarding,  DEFUN (show_ip_forwarding,
        show_ip_forwarding_cmd,         show_ip_forwarding_cmd,
Line 1696  static struct cmd_node forwarding_node = Line 1921  static struct cmd_node forwarding_node =
   1    1
 };  };
   
 /* Initialisation of zebra and installation of commands. */  /* Initialisation of zebra and installation of commands. */
 void  void
 zebra_init (void)  zebra_init (void)
Line 1733  zebra_init (void) Line 1958  zebra_init (void)
   
 /* Make zebra server socket, wiping any existing one (see bug #403). */  /* Make zebra server socket, wiping any existing one (see bug #403). */
 void  void
zebra_zserv_socket_init (void)zebra_zserv_socket_init (char *path)
 {  {
 #ifdef HAVE_TCP_ZEBRA  #ifdef HAVE_TCP_ZEBRA
   zebra_serv ();    zebra_serv ();
 #else  #else
  zebra_serv_un (ZEBRA_SERV_PATH);  zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
 #endif /* HAVE_TCP_ZEBRA */  #endif /* HAVE_TCP_ZEBRA */
 }  }

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


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