2004-05-08 Paul Jakma <paul@dishone.st>

       * bgp_zebra.c: (bgp_interface_address_add) sync to zclient changes
         (bgp_interface_address_delete) ditto.
         (bgp_zebra_announce) ditto.
         (bgp_zebra_withdraw) ditto.
       * isis_zebra.c: Sync with zclient changes.
       * zclient.c (zapi_ipv4_route) Follow Sowmini's lead and describe
         message format.
       * ospf6_zebra.c: Sync to zclient changes
       * ospf_zebra.c: Sync with lib/zclient changes
       * rip_zebra.c: sync with zclient changes.
       * rip_interface.c: ditto.
       * ripng_{interface,zebra}.c: sync with zclient changes


2004-05-08 Sowmini Varadhan <sowmini.varadhan@sun.com>

       * zclient.c: (zapi_ipv4_add) collapsed into zapi_ipv4_route
         (zapi_ipv4_delete) ditto.
         (zapi_ipv4_route) add/delete a route by way of cmd arg.
         (zapi_ipv6_add) collapsed into zapi_ipv6_route.
         (zapi_ipv6_delete) ditto.
         (zapi_ipv6_route) add/delete a route by way of cmd arg.
         (zebra_interface_address_delete_read) collapsed into
         zebra_interface_address_read.
         (zebra_interface_address_delete_read) ditto.
         (zebra_interface_address_read) read address add/delete messages
         by way of type argument. Describe command message format.
         (zebra_interface_add_read) Unconditionally read new ifmtu6 field.
         Describe command message format.
         (zebra_interface_state_read) Unconditionally read new ifmtu6 field.
         (zclient_redistribute_set) Collapsed into zclient_redistribute
         (zclient_redistribute_unset) ditto
         (zclient_redistribute) set/unset redistribution.
         (zclient_redistribute_default_set) Collapsed into
         zclient_redistribute_default.
         (zclient_redistribute_default_unset) ditto.
         (zclient_redistribute_default) Redistribute default set/unset.
       * zclient.h: delete zapi_ipv{4,6}_add, zapi_ipv{4,6}_delete. Add
         zapi_ipv{4,6}_route. delete zclient_redistribute_set/unset. Add
         zclient_redistribute. Ditto for
         zclient_redistribute_default_{set/unset}.
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index b5f2887..98bf90c 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -1,3 +1,10 @@
+2004-05-08 Paul Jakma <paul@dishone.st>
+
+	* bgp_zebra.c: (bgp_interface_address_add) sync to zclient changes
+	  (bgp_interface_address_delete) ditto.
+	  (bgp_zebra_announce) ditto.
+	  (bgp_zebra_withdraw) ditto.
+
 2004-05-03 Daniel Roesen <dr@cluenet.de>
 	
 	* bgp_fsm.c: (bgp_stop) Reset uptime only on transition from 
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index aef888b..394bde6 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -201,7 +201,7 @@
 {
   struct connected *ifc;
 
-  ifc = zebra_interface_address_add_read (zclient->ibuf);
+  ifc = zebra_interface_address_read (command, zclient->ibuf);
 
   if (ifc == NULL)
     return 0;
@@ -220,7 +220,7 @@
 {
   struct connected *ifc;
 
-  ifc = zebra_interface_address_delete_read (zclient->ibuf);
+  ifc = zebra_interface_address_read (command, zclient->ibuf);
 
   if (ifc == NULL)
     return 0;
@@ -703,7 +703,8 @@
 	  SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
 	  api.distance = distance;
 	}
-      zapi_ipv4_add (zclient, (struct prefix_ipv4 *) p, &api);
+      zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, 
+                       (struct prefix_ipv4 *) p, &api);
     }
 #ifdef HAVE_IPV6
   /* We have to think about a IPv6 link-local address curse. */
@@ -758,7 +759,8 @@
       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
       api.metric = info->attr->med;
 
-      zapi_ipv6_add (zclient, (struct prefix_ipv6 *) p, &api);
+      zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, 
+                       (struct prefix_ipv6 *) p, &api);
     }
 #endif /* HAVE_IPV6 */
 }
@@ -805,7 +807,8 @@
       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
       api.metric = info->attr->med;
 
-      zapi_ipv4_delete (zclient, (struct prefix_ipv4 *) p, &api);
+      zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, 
+                       (struct prefix_ipv4 *) p, &api);
     }
 #ifdef HAVE_IPV6
   /* We have to think about a IPv6 link-local address curse. */
@@ -849,7 +852,8 @@
       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
       api.metric = info->attr->med;
 
-      zapi_ipv6_delete (zclient, (struct prefix_ipv6 *) p, &api);
+      zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, 
+                       (struct prefix_ipv6 *) p, &api);
     }
 #endif /* HAVE_IPV6 */
 }
diff --git a/isisd/ChangeLog b/isisd/ChangeLog
index 60d5933..810be79 100644
--- a/isisd/ChangeLog
+++ b/isisd/ChangeLog
@@ -1,3 +1,7 @@
+2004-05-08 Paul Jakma <paul@dishone.st>
+
+	* isis_zebra.c: Sync with zclient changes.
+
 2004-02-11 Hasso Tepper <hasso@estpak.ee>
   * many *.c files: Replace thread_add_xxx() and thread_cancel() with
     THREAD_XXX_ON and THREAD_XXX_OFF macros.
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 3b83e7a..4b496c3 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -171,7 +171,8 @@
   struct prefix *p;
   u_char buf[BUFSIZ];
 
-  c = zebra_interface_address_add_read (zclient->ibuf);
+  c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, 
+                                    zclient->ibuf);
   
   if (c == NULL)
     return 0;
@@ -199,7 +200,8 @@
   struct connected *c;
   struct interface *ifp;
 
-  c = zebra_interface_address_delete_read (zclient->ibuf);
+  c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, 
+                                    zclient->ibuf);
   
   if (c == NULL)
     return 0;
@@ -293,7 +295,7 @@
     prefix4.family = AF_INET;
     prefix4.prefixlen = prefix->prefixlen;
     prefix4.prefix = prefix->u.prefix4;
-    zapi_ipv4_delete (zclient, &prefix4, &api);
+    zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
   }
   
   return;
@@ -370,7 +372,7 @@
     prefix6.family = AF_INET6;
     prefix6.prefixlen = prefix->prefixlen;
     memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
-    zapi_ipv6_add (zclient, &prefix6, &api);
+    zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
     SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
   }
   
@@ -444,7 +446,7 @@
     prefix6.family = AF_INET6;
     prefix6.prefixlen = prefix->prefixlen;
     memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
-    zapi_ipv6_delete (zclient, &prefix6, &api);
+    zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
     UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
   }
   
diff --git a/lib/ChangeLog b/lib/ChangeLog
index fa6c584..d02fb50 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,36 @@
+2004-05-08 Paul Jakma <paul@dishone.st>
+
+	* zclient.c (zapi_ipv4_route) Follow Sowmini's lead and describe
+	  message format.
+
+2004-05-08 Sowmini Varadhan <sowmini.varadhan@sun.com>
+
+	* zclient.c: (zapi_ipv4_add) collapsed into zapi_ipv4_route
+	  (zapi_ipv4_delete) ditto.
+	  (zapi_ipv4_route) add/delete a route by way of cmd arg.
+	  (zapi_ipv6_add) collapsed into zapi_ipv6_route.
+	  (zapi_ipv6_delete) ditto.
+	  (zapi_ipv6_route) add/delete a route by way of cmd arg.
+	  (zebra_interface_address_delete_read) collapsed into 
+	  zebra_interface_address_read.
+	  (zebra_interface_address_delete_read) ditto.
+	  (zebra_interface_address_read) read address add/delete messages
+	  by way of type argument. Describe command message format.
+	  (zebra_interface_add_read) Unconditionally read new ifmtu6 field.
+	  Describe command message format.
+	  (zebra_interface_state_read) Unconditionally read new ifmtu6 field.
+	  (zclient_redistribute_set) Collapsed into zclient_redistribute
+	  (zclient_redistribute_unset) ditto
+	  (zclient_redistribute) set/unset redistribution.
+	  (zclient_redistribute_default_set) Collapsed into
+	  zclient_redistribute_default.
+	  (zclient_redistribute_default_unset) ditto.
+	  (zclient_redistribute_default) Redistribute default set/unset.
+	* zclient.h: delete zapi_ipv{4,6}_add, zapi_ipv{4,6}_delete. Add
+	  zapi_ipv{4,6}_route. delete zclient_redistribute_set/unset. Add
+	  zclient_redistribute. Ditto for
+          zclient_redistribute_default_{set/unset}.
+          
 2004-05-08 Sowmini Varadhan <sowmini.varadhan@sun.com>
 
 	* if.h: Add mtu6 field to struct interface, IPv6 MTU may differ
@@ -8,7 +41,7 @@
 	  (if_dump) Dump mtu6 flag, for HAVE_IPV6.
 	* command.c: (sockunion_getsockname) use socklen_t for len.
 	  (sockunion_getpeername) ditto.
-	  
+	  	  
 2004-04-21 Boris Kovalenko <boris@tagnet.ru>
 
 	* daemon.c: (daemon) fix check for error return from setsid
diff --git a/lib/zclient.c b/lib/zclient.c
index e76652d..dcfa45f 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -288,9 +288,53 @@
   return zclient_start (zclient);
 }
 
+ /* 
+  * "xdr_encode"-like interface that allows daemon (client) to send
+  * a message to zebra server for a route that needs to be
+  * added/deleted to the kernel. Info about the route is specified
+  * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
+  * the info down the zclient socket using the stream_* functions.
+  * 
+  * The corresponding read ("xdr_decode") function on the server
+  * side is zread_ipv4_add()/zread_ipv4_delete().
+  *
+  *  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
+  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  * |            Length (2)         |    Command    | Route Type    |
+  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  * | ZEBRA Flags   | Message Flags | Prefix length |
+  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  * | Destination IPv4 Prefix for route                             |
+  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  * | Nexthop count | 
+  * +-+-+-+-+-+-+-+-+
+  *
+  * 
+  * A number of IPv4 nexthop(s) or nexthop interface index(es) are then 
+  * described, as per the Nexthop count. Each nexthop described as:
+  *
+  * +-+-+-+-+-+-+-+-+
+  * | Nexthop Type  |  Set to one of ZEBRA_NEXTHOP_*
+  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  * |       IPv4 Nexthop address or Interface Index number          |
+  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  *
+  * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
+  * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_ 
+  * nexthop information is provided, and the message describes a prefix
+  * to blackhole or reject route.
+  *
+  * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
+  * byte value.
+  * 
+  * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
+  * byte value.
+  *
+  * XXX: No attention paid to alignment.
+  */ 
 int
-zapi_ipv4_add (struct zclient *zclient, struct prefix_ipv4 *p,
-	       struct zapi_ipv4 *api)
+zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
+                 struct zapi_ipv4 *api)
 {
   int i;
   int psize;
@@ -304,15 +348,15 @@
   stream_putw (s, 0);
 
   /* Put command, type and nexthop. */
-  stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
+  stream_putc (s, cmd);
   stream_putc (s, api->type);
   stream_putc (s, api->flags);
   stream_putc (s, api->message);
-  
+
   /* Put prefix information. */
   psize = PSIZE (p->prefixlen);
   stream_putc (s, p->prefixlen);
-  stream_write (s, (u_char *)&p->prefix, psize);
+  stream_write (s, (u_char *) & p->prefix, psize);
 
   /* Nexthop, ifindex, distance and metric information. */
   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
@@ -321,70 +365,8 @@
         {
           stream_putc (s, 1);
           stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
-	  /* XXX assert(api->nexthop_num == 0); */
-	  /* XXX assert(api->ifindex_num == 0); */
-        }
-      else
-        stream_putc (s, api->nexthop_num + api->ifindex_num);
-        
-      for (i = 0; i < api->nexthop_num; i++)
-        {
-          stream_putc (s, ZEBRA_NEXTHOP_IPV4);
-          stream_put_in_addr (s, api->nexthop[i]);
-        }
-      for (i = 0; i < api->ifindex_num; i++)
-        {
-          stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
-          stream_putl (s, api->ifindex[i]);
-        }
-    }
-
-  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
-    stream_putc (s, api->distance);
-  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
-    stream_putl (s, api->metric);
-
-  /* Put length at the first point of the stream. */
-  stream_putw_at (s, 0, stream_get_endp (s));
-
-  return writen (zclient->sock, s->data, stream_get_endp (s));
-}
-
-int
-zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p,
-		  struct zapi_ipv4 *api)
-{
-  int i;
-  int psize;
-  struct stream *s;
-
-  /* Reset stream. */
-  s = zclient->obuf;
-  stream_reset (s);
-
-  /* Length place holder. */
-  stream_putw (s, 0);
-
-  /* Put command, type and nexthop. */
-  stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
-  stream_putc (s, api->type);
-  stream_putc (s, api->flags);
-  stream_putc (s, api->message);
-  
-  /* Put prefix information. */
-  psize = PSIZE (p->prefixlen);
-  stream_putc (s, p->prefixlen);
-  stream_write (s, (u_char *)&p->prefix, psize);
-
-  /* Nexthop, ifindex, distance and metric information. */
-  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
-    {
-      if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
-        {
-          stream_putc (s, 1);
-          stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
-	  /* XXX assert(api->nexthop_num == 0); */
-	  /* XXX assert(api->ifindex_num == 0); */
+          /* XXX assert(api->nexthop_num == 0); */
+          /* XXX assert(api->ifindex_num == 0); */
         }
       else
         stream_putc (s, api->nexthop_num + api->ifindex_num);
@@ -414,7 +396,7 @@
 
 #ifdef HAVE_IPV6
 int
-zapi_ipv6_add (struct zclient *zclient, struct prefix_ipv6 *p,
+zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
 	       struct zapi_ipv6 *api)
 {
   int i;
@@ -429,7 +411,7 @@
   stream_putw (s, 0);
 
   /* Put command, type and nexthop. */
-  stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
+  stream_putc (s, cmd);
   stream_putc (s, api->type);
   stream_putc (s, api->flags);
   stream_putc (s, api->message);
@@ -466,63 +448,14 @@
 
   return writen (zclient->sock, s->data, stream_get_endp (s));
 }
-
-int
-zapi_ipv6_delete (struct zclient *zclient, struct prefix_ipv6 *p,
-		  struct zapi_ipv6 *api)
-{
-  int i;
-  int psize;
-  struct stream *s;
-
-  /* Reset stream. */
-  s = zclient->obuf;
-  stream_reset (s);
-
-  /* Length place holder. */
-  stream_putw (s, 0);
-
-  /* Put command, type and nexthop. */
-  stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
-  stream_putc (s, api->type);
-  stream_putc (s, api->flags);
-  stream_putc (s, api->message);
-  
-  /* Put prefix information. */
-  psize = PSIZE (p->prefixlen);
-  stream_putc (s, p->prefixlen);
-  stream_write (s, (u_char *)&p->prefix, psize);
-
-  /* Nexthop, ifindex, distance and metric information. */
-  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
-    {
-      stream_putc (s, api->nexthop_num + api->ifindex_num);
-
-      for (i = 0; i < api->nexthop_num; i++)
-	{
-	  stream_putc (s, ZEBRA_NEXTHOP_IPV6);
-	  stream_write (s, (u_char *)api->nexthop[i], 16);
-	}
-      for (i = 0; i < api->ifindex_num; i++)
-	{
-	  stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
-	  stream_putl (s, api->ifindex[i]);
-	}
-    }
-
-  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
-    stream_putc (s, api->distance);
-  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
-    stream_putl (s, api->metric);
-
-  /* Put length at the first point of the stream. */
-  stream_putw_at (s, 0, stream_get_endp (s));
-
-  return writen (zclient->sock, s->data, stream_get_endp (s));
-}
-
 #endif /* HAVE_IPV6 */
 
+/* 
+ * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
+ * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
+ * then set/unset redist[type] in the client handle (a struct zserv) for the 
+ * sending client
+ */
 int
 zebra_redistribute_send (int command, int sock, int type)
 {
@@ -545,6 +478,36 @@
 }
 
 /* Interface addition from zebra daemon. */
+/*  
+ * The format of the message sent with type ZEBRA_INTERFACE_ADD or
+ * ZEBRA_INTERFACE_DELETE from zebra to the client is:
+ *     0                   1                   2                   3
+ *  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
+ * +-+-+-+-+-+-+-+-+
+ * |   type        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  ifname                                                       |
+ * |                                                               |
+ * |                                                               |
+ * |                                                               |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |         ifindex                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |         if_flags                                              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |         metric                                                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |         ifmtu                                                 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |         ifmtu6                                                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |         bandwidth                                             |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |         sockaddr_dl                                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
 struct interface *
 zebra_interface_add_read (struct stream *s)
 {
@@ -569,6 +532,7 @@
   ifp->flags = stream_getl (s);
   ifp->metric = stream_getl (s);
   ifp->mtu = stream_getl (s);
+  ifp->mtu6 = stream_getl (s);
   ifp->bandwidth = stream_getl (s);
 #ifdef HAVE_SOCKADDR_DL
   stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
@@ -581,7 +545,13 @@
   return ifp;
 }
 
-/* Read interface up/down msg from zebra daemon. */
+/* 
+ * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
+ * from zebra server.  The format of this message is the same as
+ * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
+ * comments for zebra_interface_add_read), except that no sockaddr_dl
+ * is sent at the tail of the message.
+ */
 struct interface *
 zebra_interface_state_read (struct stream *s)
 {
@@ -606,20 +576,57 @@
   ifp->flags = stream_getl (s);
   ifp->metric = stream_getl (s);
   ifp->mtu = stream_getl (s);
+  ifp->mtu6 = stream_getl (s);
   ifp->bandwidth = stream_getl (s);
 
   return ifp;
 }
 
+/* 
+ * format of message for address additon is:
+ *    0
+ *  0 1 2 3 4 5 6 7
+ * +-+-+-+-+-+-+-+-+
+ * |   type        |  ZEBRA_INTERFACE_ADDRESS_ADD or
+ * +-+-+-+-+-+-+-+-+  ZEBRA_INTERFACE_ADDRES_DELETE
+ * |               |
+ * +               +
+ * |   ifindex     |
+ * +               +
+ * |               |
+ * +               +
+ * |               |
+ * +-+-+-+-+-+-+-+-+
+ * |   ifc_flags   |  flags for connected address
+ * +-+-+-+-+-+-+-+-+
+ * |  addr_family  |
+ * +-+-+-+-+-+-+-+-+
+ * |    addr...    |
+ * :               :
+ * |               |
+ * +-+-+-+-+-+-+-+-+
+ * |    addr_len   |  len of addr. E.g., addr_len = 4 for ipv4 addrs.
+ * +-+-+-+-+-+-+-+-+
+ * |     daddr..   |
+ * :               :
+ * |               |
+ * +-+-+-+-+-+-+-+-+
+ *
+ */
+
 struct connected *
-zebra_interface_address_add_read (struct stream *s)
+zebra_interface_address_read (int type, struct stream *s)
 {
   unsigned int ifindex;
   struct interface *ifp;
   struct connected *ifc;
-  struct prefix *p;
+  struct prefix p, d;
   int family;
   int plen;
+  u_char ifc_flags;
+
+  memset (&p, 0, sizeof(p));
+  memset (&d, 0, sizeof(d));
 
   /* Get interface index. */
   ifindex = stream_getl (s);
@@ -628,82 +635,42 @@
   ifp = if_lookup_by_index (ifindex);
   if (ifp == NULL)
     {
-      zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex);
-      return NULL;
-    }
-
-  /* Allocate new connected address. */
-  ifc = connected_new ();
-  ifc->ifp = ifp;
-
-  /* Fetch flag. */
-  ifc->flags = stream_getc (s);
-
-  /* Fetch interface address. */
-  p = prefix_new ();
-  family = p->family = stream_getc (s);
-
-  plen = prefix_blen (p);
-  stream_get (&p->u.prefix, s, plen);
-  p->prefixlen = stream_getc (s);
-  ifc->address = p;
-
-  /* Fetch destination address. */
-  p = prefix_new ();
-  stream_get (&p->u.prefix, s, plen);
-  p->family = family;
-
-  ifc->destination = p;
-
-  p = ifc->address;
-
-  /* Add connected address to the interface. */
-  listnode_add (ifp->connected, ifc);
-
-  return ifc;
-}
-
-struct connected *
-zebra_interface_address_delete_read (struct stream *s)
-{
-  unsigned int ifindex;
-  struct interface *ifp;
-  struct connected *ifc;
-  struct prefix p;
-  struct prefix d;
-  int family;
-  int len;
-  u_char flags;
-
-  /* Get interface index. */
-  ifindex = stream_getl (s);
-
-  /* Lookup index. */
-  ifp = if_lookup_by_index (ifindex);
-  if (ifp == NULL)
-    {
-      zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex);
+      zlog_warn ("zebra_interface_address_read(%s): "
+                 "Can't find interface by ifindex: %d ",
+                 (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
+                 ifindex);
       return NULL;
     }
 
   /* Fetch flag. */
-  flags = stream_getc (s);
+  ifc_flags = stream_getc (s);
 
   /* Fetch interface address. */
   family = p.family = stream_getc (s);
 
-  len = prefix_blen (&p);
-  stream_get (&p.u.prefix, s, len);
+  plen = prefix_blen (&p);
+  stream_get (&p.u.prefix, s, plen);
   p.prefixlen = stream_getc (s);
 
   /* Fetch destination address. */
-  stream_get (&d.u.prefix, s, len);
+  stream_get (&d.u.prefix, s, plen);
   d.family = family;
 
-  ifc = connected_delete_by_prefix (ifp, &p);
+  if (type == ZEBRA_INTERFACE_ADDRESS_ADD) 
+    {
+       ifc = connected_add_by_prefix(ifp, &p, &d);
+       if (ifc != NULL)
+       ifc->flags = ifc_flags;
+    }
+  else
+    {
+      assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
+      ifc = connected_delete_by_prefix(ifp, &p);
+    }
 
   return ifc;
 }
+
 
 /* Zebra client message read function. */
 int
@@ -731,7 +698,7 @@
   if (nbytes == 0) 
     {
       if (zclient_debug)
-	zlog_info ("zclient connection closed socket [%d].", sock);
+       zlog_info ("zclient connection closed socket [%d].", sock);
       zclient->fail++;
       zclient_stop (zclient);
       zclient_event (ZCLIENT_CONNECT, zclient);
@@ -742,7 +709,7 @@
   if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
     {
       if (zclient_debug)
-	zlog_info ("Can't read all packet (length %d).", nbytes);
+        zlog_info ("Can't read all packet (length %d).", nbytes);
       zclient->fail++;
       zclient_stop (zclient);
       zclient_event (ZCLIENT_CONNECT, zclient);
@@ -773,6 +740,9 @@
      return -1;
    }
 
+  if (zclient_debug)
+    zlog_info("zclient 0x%p command 0x%x \n", zclient, command);
+
   switch (command)
     {
     case ZEBRA_INTERFACE_ADD:
@@ -826,52 +796,48 @@
 }
 
 void
-zclient_redistribute_set (struct zclient *zclient, int type)
+zclient_redistribute (int command, struct zclient *zclient, int type)
 {
-  if (zclient->redist[type])
-    return;
 
-  zclient->redist[type] = 1;
+  if (command == ZEBRA_REDISTRIBUTE_ADD) 
+    {
+      if (zclient->redist[type])
+         return;
+      zclient->redist[type] = 1;
+    }
+  else
+    {
+      if (!zclient->redist[type])
+         return;
+      zclient->redist[type] = 0;
+    }
 
   if (zclient->sock > 0)
-    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
+    zebra_redistribute_send (command, zclient->sock, type);
 }
 
+
 void
-zclient_redistribute_unset (struct zclient *zclient, int type)
+zclient_redistribute_default (int command, struct zclient *zclient)
 {
-  if (! zclient->redist[type])
-    return;
 
-  zclient->redist[type] = 0;
+  if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
+    {
+      if (zclient->default_information)
+        return;
+      zclient->default_information = 1;
+    }
+  else 
+    {
+      if (!zclient->default_information)
+        return;
+      zclient->default_information = 0;
+    }
 
   if (zclient->sock > 0)
-    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
+    zebra_message_send (zclient, command);
 }
 
-void
-zclient_redistribute_default_set (struct zclient *zclient)
-{
-  if (zclient->default_information)
-    return;
-
-  zclient->default_information = 1;
-
-  if (zclient->sock > 0)
-    zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
-}
-
-void
-zclient_redistribute_default_unset (struct zclient *zclient)
-{
-  if (! zclient->default_information)
-    return;
-
-  zclient->default_information = 0;
-
-  if (zclient->sock > 0)
-    zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE);
-}
 
 extern struct thread_master *master;
 
diff --git a/lib/zclient.h b/lib/zclient.h
index 66307c9..da8d016 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -100,12 +100,6 @@
   u_int32_t metric;
 };
 
-int
-zapi_ipv4_add (struct zclient *, struct prefix_ipv4 *, struct zapi_ipv4 *);
-
-int
-zapi_ipv4_delete (struct zclient *, struct prefix_ipv4 *, struct zapi_ipv4 *);
-
 /* Prototypes of zebra client service functions. */
 struct zclient *zclient_new (void);
 void zclient_free (struct zclient *);
@@ -116,19 +110,17 @@
 int zclient_socket ();
 int zclient_socket_un (char *);
 
-void zclient_redistribute_set (struct zclient *, int);
-void zclient_redistribute_unset (struct zclient *, int);
-
-void zclient_redistribute_default_set (struct zclient *);
-void zclient_redistribute_default_unset (struct zclient *);
+void zclient_redistribute (int, struct zclient *, int);
+void zclient_redistribute_default (int, struct zclient *);
 
 /* struct zebra *zebra_new (); */
 int zebra_redistribute_send (int, int, int);
 
 struct interface *zebra_interface_add_read (struct stream *);
 struct interface *zebra_interface_state_read (struct stream *s);
-struct connected *zebra_interface_address_add_read (struct stream *);
-struct connected *zebra_interface_address_delete_read (struct stream *);
+struct connected *zebra_interface_address_read (int, struct stream *);
+int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *, 
+                     struct zapi_ipv4 *);
 
 #ifdef HAVE_IPV6
 /* IPv6 prefix add and delete function prototype. */
@@ -152,13 +144,8 @@
   u_int32_t metric;
 };
 
-int
-zapi_ipv6_add (struct zclient *zclient, struct prefix_ipv6 *p,
-	       struct zapi_ipv6 *api);
-int
-zapi_ipv6_delete (struct zclient *zclient, struct prefix_ipv6 *p,
-		  struct zapi_ipv6 *api);
-
+int zapi_ipv6_route (u_char cmd, struct zclient *zclient, 
+                     struct prefix_ipv6 *p, struct zapi_ipv6 *api);
 #endif /* HAVE_IPV6 */
 
 #endif /* _ZEBRA_ZCLIENT_H */
diff --git a/ospf6d/ChangeLog b/ospf6d/ChangeLog
index f792596..0e9d7fc 100644
--- a/ospf6d/ChangeLog
+++ b/ospf6d/ChangeLog
@@ -1,3 +1,7 @@
+2004-05-08 Paul Jakma <paul@dishone.st>
+
+	* ospf6_zebra.c: Sync to zclient changes
+	
 2003-08-11  Taisuke Sasaki <sasaki@soft.net.fujitsu.co.jp>
 
 	* ospf6_ism.c: DR Election bug fix.
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 347ba1c..4e8815f 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -138,7 +138,7 @@
   struct connected *c;
   char buf[128];
 
-  c = zebra_interface_address_add_read (zclient->ibuf);
+  c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf);
   if (c == NULL)
     return 0;
 
@@ -161,7 +161,7 @@
   struct connected *c;
   char buf[128];
 
-  c = zebra_interface_address_delete_read (zclient->ibuf);
+  c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf);
   if (c == NULL)
     return 0;
 
@@ -568,12 +568,12 @@
 
   p = (struct prefix_ipv6 *) &request->route.prefix;
   if (type == REMOVE && nexthop_list->count == 1)
-    ret = zapi_ipv6_delete (zclient, p, &api);
+    ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
   else
-    ret = zapi_ipv6_add (zclient, p, &api);
+    ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);
 
   if (ret < 0)
-    zlog_err ("ZEBRA: zapi_ipv6_add () failed: %s", strerror (errno));
+    zlog_err ("ZEBRA: zapi_ipv6_route () failed: %s", strerror (errno));
 
   for (linklist_head (nexthop_list, &node); !linklist_end (&node);
        linklist_next (&node))
diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog
index ebeaa5b..77ffbe5 100644
--- a/ospfd/ChangeLog
+++ b/ospfd/ChangeLog
@@ -1,3 +1,7 @@
+2004-05-08 Paul Jakma <paul@dishone.st>
+
+	* ospf_zebra.c: Sync with lib/zclient changes
+	
 2004-05-05 Paul Jakma <paul@dishone.st>
 
 	* ospf_network.c: (ospf_sock_init) Check whether IP_HDRINCL is
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index ab9844f..518f554 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -246,7 +246,7 @@
   struct ospf *ospf;
   struct connected *c;
 
-  c = zebra_interface_address_add_read (zclient->ibuf);
+  c = zebra_interface_address_read (command, zclient->ibuf);
 
   if (c == NULL)
     return 0;
@@ -273,7 +273,7 @@
   struct route_node *rn;
   struct prefix p;
 
-  c = zebra_interface_address_delete_read (zclient->ibuf);
+  c = zebra_interface_address_read (command, zclient->ibuf);
 
   if (c == NULL)
     return 0;
@@ -436,7 +436,7 @@
                          p->prefixlen);
             }
 
-          zapi_ipv4_delete (zclient, p, &api);
+          zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
 
           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
             {
@@ -468,7 +468,7 @@
       api.nexthop_num = 0;
       api.ifindex_num = 0;
 
-      zapi_ipv4_add (zclient, p, &api);
+      zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
     }
 }
 
@@ -486,7 +486,7 @@
       api.nexthop_num = 0;
       api.ifindex_num = 0;
 
-      zapi_ipv4_delete (zclient, p, &api);
+      zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
 
       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
         zlog_info ("Zebra: Route delete discard %s/%d",
@@ -533,7 +533,7 @@
   ospf->dmetric[type].type = mtype;
   ospf->dmetric[type].value = mvalue;
 
-  zclient_redistribute_set (zclient, type);
+  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_info ("Redistribute[%s]: Start  Type[%d], Metric[%d]",
@@ -554,7 +554,7 @@
   if (!ospf_is_type_redistributed (type))
     return CMD_SUCCESS;
 
-  zclient_redistribute_unset (zclient, type);
+  zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_info ("Redistribute[%s]: Stop",
@@ -604,7 +604,7 @@
   ospf->dmetric[DEFAULT_ROUTE].type = mtype;
   ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
 
-  zclient_redistribute_default_set (zclient);
+  zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_info ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
@@ -632,7 +632,7 @@
   ospf->dmetric[DEFAULT_ROUTE].type = -1;
   ospf->dmetric[DEFAULT_ROUTE].value = -1;
 
-  zclient_redistribute_default_unset (zclient);
+  zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_info ("Redistribute[DEFAULT]: Stop");
diff --git a/ripd/ChangeLog b/ripd/ChangeLog
index 0f37179..2cf199e 100644
--- a/ripd/ChangeLog
+++ b/ripd/ChangeLog
@@ -1,3 +1,8 @@
+2004-05-08 Paul Jakma <paul@dishone.st>
+
+	* rip_zebra.c: sync with zclient changes.
+	* rip_interface.c: ditto.
+
 2004-05-05 Anthony.Golia@morganstanley.com
 
 	* ripd.c: (rip_update_jitter) Bound jitter to a more sensible
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 1d6ce04..3d69d6c 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -786,7 +786,8 @@
   struct connected *ifc;
   struct prefix *p;
 
-  ifc = zebra_interface_address_add_read (zclient->ibuf);
+  ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, 
+                                      zclient->ibuf);
 
   if (ifc == NULL)
     return 0;
@@ -841,7 +842,8 @@
   struct connected *ifc;
   struct prefix *p;
 
-  ifc = zebra_interface_address_delete_read (zclient->ibuf);
+  ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
+                                      zclient->ibuf);
   
   if (ifc)
     {
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index dcd82a4..437e3c6 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -66,7 +66,7 @@
 	  api.distance = distance;
 	}
 
-      zapi_ipv4_add (zclient, p, &api);
+      zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
 
       rip_global_route_changes++;
     }
@@ -90,7 +90,7 @@
       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
       api.metric = metric;
 
-      zapi_ipv4_delete (zclient, p, &api);
+      zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
 
       rip_global_route_changes++;
     }
@@ -331,7 +331,8 @@
       if (strncmp (redist_type[i].str, argv[0], 
 		   redist_type[i].str_min_len) == 0) 
 	{
-	  zclient_redistribute_set (zclient, redist_type[i].type);
+	  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, 
+	                        redist_type[i].type);
 	  return CMD_SUCCESS;
 	}
     }
@@ -392,7 +393,7 @@
 		redist_type[i].str_min_len) == 0) 
       {
 	rip_routemap_set (redist_type[i].type, argv[1]);
-	zclient_redistribute_set (zclient, redist_type[i].type);
+	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
 	return CMD_SUCCESS;
       }
   }
@@ -458,7 +459,7 @@
 		redist_type[i].str_min_len) == 0) 
       {
 	rip_redistribute_metric_set (redist_type[i].type, metric);
-	zclient_redistribute_set (zclient, redist_type[i].type);
+	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
 	return CMD_SUCCESS;
       }
   }
@@ -527,7 +528,7 @@
       {
 	rip_redistribute_metric_set (redist_type[i].type, metric);
 	rip_routemap_set (redist_type[i].type, argv[2]);
-	zclient_redistribute_set (zclient, redist_type[i].type);
+	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
 	return CMD_SUCCESS;
       }
   }
diff --git a/ripngd/ChangeLog b/ripngd/ChangeLog
index f5a3078..01256bb 100644
--- a/ripngd/ChangeLog
+++ b/ripngd/ChangeLog
@@ -1,3 +1,7 @@
+2004-05-08 Paul Jakma <paul@dishone.st>
+
+	* ripng_{interface,zebra}.c: sync with zclient changes
+
 2004-01-03  Greg Troxel  <gdt@ahi.ir.bbn.com>
 
 	* ripng_interface.c (ripng_multicast_join): If IPV6_JOIN_GROUP
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index 7437f70..28977be 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -411,7 +411,8 @@
   struct connected *c;
   struct prefix *p;
 
-  c = zebra_interface_address_add_read (zclient->ibuf);
+  c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, 
+                                    zclient->ibuf);
 
   if (c == NULL)
     return 0;
@@ -480,7 +481,8 @@
   struct prefix *p;
   char buf[INET6_ADDRSTRLEN];
 
-  ifc = zebra_interface_address_delete_read (zclient->ibuf);
+  ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, 
+                                      zclient->ibuf);
   
   if (ifc)
     {
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index de372dc..45ba213 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -60,7 +60,7 @@
       api.ifindex_num = 1;
       api.ifindex = &ifindex;
 
-      zapi_ipv6_add (zclient, p, &api);
+      zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);
     }
 }
 
@@ -82,7 +82,7 @@
       api.ifindex_num = 1;
       api.ifindex = &ifindex;
 
-      zapi_ipv6_delete (zclient, p, &api);
+      zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
     }
 }
 
@@ -300,7 +300,7 @@
       if (strncmp (redist_type[i].str, argv[0], 
 		   redist_type[i].str_min_len) == 0) 
 	{
-	  zclient_redistribute_set (zclient, redist_type[i].type);
+	  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
 	  return CMD_SUCCESS;
 	}
     }
@@ -364,7 +364,7 @@
 		redist_type[i].str_min_len) == 0) 
       {
 	ripng_redistribute_metric_set (redist_type[i].type, metric);
-	zclient_redistribute_set (zclient, redist_type[i].type);
+	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
 	return CMD_SUCCESS;
       }
   }
@@ -407,7 +407,7 @@
 		redist_type[i].str_min_len) == 0) 
       {
 	ripng_redistribute_routemap_set (redist_type[i].type, argv[1]);
-	zclient_redistribute_set (zclient, redist_type[i].type);
+	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
 	return CMD_SUCCESS;
       }
   }
@@ -456,7 +456,7 @@
       {
 	ripng_redistribute_metric_set (redist_type[i].type, metric);
 	ripng_redistribute_routemap_set (redist_type[i].type, argv[2]);
-	zclient_redistribute_set (zclient, redist_type[i].type);
+	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
 	return CMD_SUCCESS;
       }
   }