added files
[bcm963xx.git] / userapps / opensource / zebra / lib / zclient.c
1 /* Zebra's client library.
2  * Copyright (C) 1999 Kunihiro Ishiguro
3  *
4  * This file is part of GNU Zebra.
5  *
6  * GNU Zebra is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation; either version 2, or (at your
9  * option) any later version.
10  *
11  * GNU Zebra is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GNU Zebra; see the file COPYING.  If not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19  * MA 02111-1307, USA.
20  */
21
22 #include <zebra.h>
23
24 #include "prefix.h"
25 #include "stream.h"
26 #include "network.h"
27 #include "if.h"
28 #include "log.h"
29 #include "thread.h"
30 #include "zclient.h"
31 #include "memory.h"
32 #include "table.h"
33
34 #include "zebra/rib.h"
35 #include "zebra/zserv.h"
36 \f
37 /* Zebra client events. */
38 enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
39
40 /* Prototype for event manager. */
41 static void zclient_event (enum event, struct zclient *);
42
43 /* This file local debug flag. */
44 int zclient_debug = 0;
45 \f
46 /* Allocate zclient structure. */
47 struct zclient *
48 zclient_new ()
49 {
50   struct zclient *zclient;
51   zclient = XMALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
52   memset (zclient, 0, sizeof (struct zclient));
53
54   zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
55   zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
56
57   return zclient;
58 }
59
60 /* Free zclient structure. */
61 void
62 zclient_free (struct zclient *zclient)
63 {
64   XFREE (MTYPE_ZCLIENT, zclient);
65 }
66
67 /* Initialize zebra client.  Argument redist_default is unwanted
68    redistribute route type. */
69 void
70 zclient_init (struct zclient *zclient, int redist_default)
71 {
72   int i;
73   
74   /* Enable zebra client connection by default. */
75   zclient->enable = 1;
76
77   /* Set -1 to the default socket value. */
78   zclient->sock = -1;
79
80   /* Clear redistribution flags. */
81   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
82     zclient->redist[i] = 0;
83
84   /* Set unwanted redistribute route.  bgpd does not need BGP route
85      redistribution. */
86   zclient->redist_default = redist_default;
87   zclient->redist[redist_default] = 1;
88
89   /* Set default-information redistribute to zero. */
90   zclient->default_information = 0;
91
92   /* Schedule first zclient connection. */
93 #ifdef BRCM_RIP_DEBUG
94   if (zclient_debug)
95     zlog_info ("zclient start scheduled");
96 #endif
97   zclient_event (ZCLIENT_SCHEDULE, zclient);
98 }
99
100 /* Stop zebra client services. */
101 void
102 zclient_stop (struct zclient *zclient)
103 {
104   if (zclient_debug)
105 #ifdef BRCM_RIP_DEBUG
106     zlog_info ("zclient stopped");
107 #endif
108   /* Stop threads. */
109   if (zclient->t_read)
110     {
111       thread_cancel (zclient->t_read);
112       zclient->t_read = NULL;
113    }
114   if (zclient->t_connect)
115     {
116       thread_cancel (zclient->t_connect);
117       zclient->t_connect = NULL;
118     }
119
120   /* Close socket. */
121   if (zclient->sock >= 0)
122     {
123       close (zclient->sock);
124       zclient->sock = -1;
125     }
126   zclient->fail = 0;
127 }
128
129 void
130 zclient_reset (struct zclient *zclient)
131 {
132   zclient_stop (zclient);
133   zclient_init (zclient, zclient->redist_default);
134 }
135
136 /* Make socket to zebra daemon. Return zebra socket. */
137 int
138 zclient_socket ()
139 {
140   int sock;
141   int ret;
142   struct sockaddr_in serv;
143
144   /* We should think about IPv6 connection. */
145   sock = socket (AF_INET, SOCK_STREAM, 0);
146   if (sock < 0)
147     return -1;
148   
149   /* Make server socket. */ 
150   memset (&serv, 0, sizeof (struct sockaddr_in));
151   serv.sin_family = AF_INET;
152   serv.sin_port = htons (ZEBRA_PORT);
153 #ifdef HAVE_SIN_LEN
154   serv.sin_len = sizeof (struct sockaddr_in);
155 #endif /* HAVE_SIN_LEN */
156   serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
157
158   /* Connect to zebra. */
159   ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
160   if (ret < 0)
161     {
162       close (sock);
163       return -1;
164     }
165   return sock;
166 }
167 #ifdef BRCM_SUPPORT
168 /* For sockaddr_un. */
169 #include <sys/un.h>
170
171 int
172 zclient_socket_un (char *path)
173 {
174   int ret;
175   int sock, len;
176   struct sockaddr_un addr;
177
178   sock = socket (AF_UNIX, SOCK_STREAM, 0);
179   if (sock < 0)
180     return -1;
181   
182   /* Make server socket. */ 
183   memset (&addr, 0, sizeof (struct sockaddr_un));
184   addr.sun_family = AF_UNIX;
185   strncpy (addr.sun_path, path, strlen (path));
186 #ifdef HAVE_SUN_LEN
187   len = addr.sun_len = SUN_LEN(&addr);
188 #else
189   len = sizeof (addr.sun_family) + strlen (addr.sun_path);
190 #endif /* HAVE_SUN_LEN */
191
192   ret = connect (sock, (struct sockaddr *) &addr, len);
193   if (ret < 0)
194     {
195       close (sock);
196       return -1;
197     }
198   return sock;
199 }
200 #endif /* #ifdef BRCM_SUPPORT */
201 /* Send simple Zebra message. */
202 int
203 zebra_message_send (struct zclient *zclient, int command)
204 {
205   struct stream *s;
206
207   /* Get zclient output buffer. */
208   s = zclient->obuf;
209   stream_reset (s);
210
211   /* Send very simple command only Zebra message. */
212   stream_putw (s, 3);
213   stream_putc (s, command);
214
215   return writen (zclient->sock, s->data, 3);
216 }
217
218 /* Make connection to zebra daemon. */
219 int
220 zclient_start (struct zclient *zclient)
221 {
222   int i;
223
224 #ifdef BRCM_RIP_DEBUG
225   if (zclient_debug)
226     zlog_info ("zclient_start is called");
227 #endif
228   /* zclient is disabled. */
229   if (! zclient->enable)
230     return 0;
231
232   /* If already connected to the zebra. */
233   if (zclient->sock >= 0)
234     return 0;
235
236   /* Check connect thread. */
237   if (zclient->t_connect)
238     return 0;
239
240   /* Make socket. */
241 #ifdef HAVE_TCP_ZEBRA
242   zclient->sock = zclient_socket ();
243 #else
244   zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH);
245 #endif /* HAVE_TCP_ZEBRA */
246   if (zclient->sock < 0)
247     {
248 #ifdef BRCM_RIP_DEBUG
249       if (zclient_debug)
250         zlog_info ("zclient connection fail");
251 #endif
252       zclient->fail++;
253       zclient_event (ZCLIENT_CONNECT, zclient);
254       return -1;
255     }
256
257   /* Clear fail count. */
258   zclient->fail = 0;
259 #ifdef BRCM_RIP_DEBUG
260   if (zclient_debug)
261     zlog_info ("zclient connect success with socket [%d]", zclient->sock);
262 #endif      
263   /* Create read thread. */
264   zclient_event (ZCLIENT_READ, zclient);
265
266   /* We need interface information. */
267   zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
268
269   /* Flush all redistribute request. */
270   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
271     if (i != zclient->redist_default && zclient->redist[i])
272       zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, i);
273
274   /* If default information is needed. */
275   if (zclient->default_information)
276     zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
277
278   return 0;
279 }
280
281 /* This function is a wrapper function for calling zclient_start from
282    timer or event thread. */
283 int
284 zclient_connect (struct thread *t)
285 {
286   struct zclient *zclient;
287
288   zclient = THREAD_ARG (t);
289   zclient->t_connect = NULL;
290 #ifdef BRCM_RIP_DEBUG
291   if (zclient_debug)
292     zlog_info ("zclient_connect is called");
293 #endif
294   return zclient_start (zclient);
295 }
296 \f
297 int
298 zapi_ipv4_add (struct zclient *zclient, struct prefix_ipv4 *p,
299                struct zapi_ipv4 *api)
300 {
301   int i;
302   int psize;
303   struct stream *s;
304
305   /* Reset stream. */
306   s = zclient->obuf;
307   stream_reset (s);
308
309   /* Length place holder. */
310   stream_putw (s, 0);
311
312   /* Put command, type and nexthop. */
313   stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
314   stream_putc (s, api->type);
315   stream_putc (s, api->flags);
316   stream_putc (s, api->message);
317   
318   /* Put prefix information. */
319   psize = PSIZE (p->prefixlen);
320   stream_putc (s, p->prefixlen);
321   stream_write (s, (u_char *)&p->prefix, psize);
322
323   /* Nexthop, ifindex, distance and metric information. */
324   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
325     {
326       stream_putc (s, api->nexthop_num + api->ifindex_num);
327
328       for (i = 0; i < api->nexthop_num; i++)
329         {
330           stream_putc (s, ZEBRA_NEXTHOP_IPV4);
331           stream_put_in_addr (s, api->nexthop[i]);
332         }
333       for (i = 0; i < api->ifindex_num; i++)
334         {
335           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
336           stream_putl (s, api->ifindex[i]);
337         }
338     }
339
340   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
341     stream_putc (s, api->distance);
342   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
343     stream_putl (s, api->metric);
344
345   /* Put length at the first point of the stream. */
346   stream_putw_at (s, 0, stream_get_endp (s));
347
348   return writen (zclient->sock, s->data, stream_get_endp (s));
349 }
350
351 int
352 zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p,
353                   struct zapi_ipv4 *api)
354 {
355   int i;
356   int psize;
357   struct stream *s;
358
359   /* Reset stream. */
360   s = zclient->obuf;
361   stream_reset (s);
362
363   /* Length place holder. */
364   stream_putw (s, 0);
365
366   /* Put command, type and nexthop. */
367   stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
368   stream_putc (s, api->type);
369   stream_putc (s, api->flags);
370   stream_putc (s, api->message);
371   
372   /* Put prefix information. */
373   psize = PSIZE (p->prefixlen);
374   stream_putc (s, p->prefixlen);
375   stream_write (s, (u_char *)&p->prefix, psize);
376
377   /* Nexthop, ifindex, distance and metric information. */
378   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
379     {
380       stream_putc (s, api->nexthop_num + api->ifindex_num);
381
382       for (i = 0; i < api->nexthop_num; i++)
383         {
384           stream_putc (s, ZEBRA_NEXTHOP_IPV4);
385           stream_put_in_addr (s, api->nexthop[i]);
386         }
387       for (i = 0; i < api->ifindex_num; i++)
388         {
389           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
390           stream_putl (s, api->ifindex[i]);
391         }
392     }
393
394   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
395     stream_putc (s, api->distance);
396   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
397     stream_putl (s, api->metric);
398
399   /* Put length at the first point of the stream. */
400   stream_putw_at (s, 0, stream_get_endp (s));
401
402   return writen (zclient->sock, s->data, stream_get_endp (s));
403 }
404
405 #ifdef HAVE_IPV6
406 int
407 zapi_ipv6_add (struct zclient *zclient, struct prefix_ipv6 *p,
408                struct zapi_ipv6 *api)
409 {
410   int i;
411   int psize;
412   struct stream *s;
413
414   /* Reset stream. */
415   s = zclient->obuf;
416   stream_reset (s);
417
418   /* Length place holder. */
419   stream_putw (s, 0);
420
421   /* Put command, type and nexthop. */
422   stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
423   stream_putc (s, api->type);
424   stream_putc (s, api->flags);
425   stream_putc (s, api->message);
426   
427   /* Put prefix information. */
428   psize = PSIZE (p->prefixlen);
429   stream_putc (s, p->prefixlen);
430   stream_write (s, (u_char *)&p->prefix, psize);
431
432   /* Nexthop, ifindex, distance and metric information. */
433   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
434     {
435       stream_putc (s, api->nexthop_num + api->ifindex_num);
436
437       for (i = 0; i < api->nexthop_num; i++)
438         {
439           stream_putc (s, ZEBRA_NEXTHOP_IPV6);
440           stream_write (s, (u_char *)api->nexthop[i], 16);
441         }
442       for (i = 0; i < api->ifindex_num; i++)
443         {
444           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
445           stream_putl (s, api->ifindex[i]);
446         }
447     }
448
449   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
450     stream_putc (s, api->distance);
451   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
452     stream_putl (s, api->metric);
453
454   /* Put length at the first point of the stream. */
455   stream_putw_at (s, 0, stream_get_endp (s));
456
457   return writen (zclient->sock, s->data, stream_get_endp (s));
458 }
459
460 int
461 zapi_ipv6_delete (struct zclient *zclient, struct prefix_ipv6 *p,
462                   struct zapi_ipv6 *api)
463 {
464   int i;
465   int psize;
466   struct stream *s;
467
468   /* Reset stream. */
469   s = zclient->obuf;
470   stream_reset (s);
471
472   /* Length place holder. */
473   stream_putw (s, 0);
474
475   /* Put command, type and nexthop. */
476   stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
477   stream_putc (s, api->type);
478   stream_putc (s, api->flags);
479   stream_putc (s, api->message);
480   
481   /* Put prefix information. */
482   psize = PSIZE (p->prefixlen);
483   stream_putc (s, p->prefixlen);
484   stream_write (s, (u_char *)&p->prefix, psize);
485
486   /* Nexthop, ifindex, distance and metric information. */
487   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
488     {
489       stream_putc (s, api->nexthop_num + api->ifindex_num);
490
491       for (i = 0; i < api->nexthop_num; i++)
492         {
493           stream_putc (s, ZEBRA_NEXTHOP_IPV6);
494           stream_write (s, (u_char *)api->nexthop[i], 16);
495         }
496       for (i = 0; i < api->ifindex_num; i++)
497         {
498           stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
499           stream_putl (s, api->ifindex[i]);
500         }
501     }
502
503   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
504     stream_putc (s, api->distance);
505   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
506     stream_putl (s, api->metric);
507
508   /* Put length at the first point of the stream. */
509   stream_putw_at (s, 0, stream_get_endp (s));
510
511   return writen (zclient->sock, s->data, stream_get_endp (s));
512 }
513
514 #endif /* HAVE_IPV6 */
515
516 int
517 zebra_redistribute_send (int command, int sock, int type)
518 {
519   int ret;
520   struct stream *s;
521
522   s = stream_new (ZEBRA_MAX_PACKET_SIZ);
523
524   /* Total length of the messages. */
525   stream_putw (s, 4);
526   
527   stream_putc (s, command);
528   stream_putc (s, type);
529
530   ret = writen (sock, s->data, 4);
531
532   stream_free (s);
533
534   return ret;
535 }
536
537 /* Interface addition from zebra daemon. */
538 struct interface *
539 zebra_interface_add_read (struct stream *s)
540 {
541   struct interface *ifp;
542   u_char ifname_tmp[INTERFACE_NAMSIZ];
543
544   /* Read interface name. */
545   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
546
547   /* Lookup this by interface name. */
548   ifp = if_lookup_by_name (ifname_tmp);
549
550   /* If such interface does not exist, make new one. */
551   if (! ifp)
552     {
553       ifp = if_create ();
554       strncpy (ifp->name, ifname_tmp, IFNAMSIZ);
555     }
556
557   /* Read interface's index. */
558   ifp->ifindex = stream_getl (s);
559
560   /* Read interface's value. */
561   ifp->flags = stream_getl (s);
562   ifp->metric = stream_getl (s);
563   ifp->mtu = stream_getl (s);
564   ifp->bandwidth = stream_getl (s);
565 #ifdef HAVE_SOCKADDR_DL
566   stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
567 #else
568   ifp->hw_addr_len = stream_getl (s);
569   if (ifp->hw_addr_len)
570     stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
571 #endif /* HAVE_SOCKADDR_DL */
572   
573   return ifp;
574 }
575
576 /* Read interface up/down msg from zebra daemon. */
577 struct interface *
578 zebra_interface_state_read (struct stream *s)
579 {
580   struct interface *ifp;
581   u_char ifname_tmp[INTERFACE_NAMSIZ];
582
583   /* Read interface name. */
584   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
585
586   /* Lookup this by interface index. */
587   ifp = if_lookup_by_name (ifname_tmp);
588
589   /* If such interface does not exist, indicate an error */
590   if (! ifp)
591      return NULL;
592
593   /* Read interface's index. */
594   ifp->ifindex = stream_getl (s);
595
596   /* Read interface's value. */
597   ifp->flags = stream_getl (s);
598   ifp->metric = stream_getl (s);
599   ifp->mtu = stream_getl (s);
600   ifp->bandwidth = stream_getl (s);
601
602   return ifp;
603 }
604
605 struct connected *
606 zebra_interface_address_add_read (struct stream *s)
607 {
608   unsigned int ifindex;
609   struct interface *ifp;
610   struct connected *ifc;
611   struct prefix *p;
612   int family;
613   int plen;
614
615   /* Get interface index. */
616   ifindex = stream_getl (s);
617
618   /* Lookup index. */
619   ifp = if_lookup_by_index (ifindex);
620   if (ifp == NULL)
621     {
622 #ifdef BRCM_RIP_DEBUG
623       zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex);
624 #endif
625       return NULL;
626     }
627
628   /* Allocate new connected address. */
629   ifc = connected_new ();
630   ifc->ifp = ifp;
631
632   /* Fetch flag. */
633   ifc->flags = stream_getc (s);
634
635   /* Fetch interface address. */
636   p = prefix_new ();
637   family = p->family = stream_getc (s);
638
639   plen = prefix_blen (p);
640   stream_get (&p->u.prefix, s, plen);
641   p->prefixlen = stream_getc (s);
642   ifc->address = p;
643
644   /* Fetch destination address. */
645   p = prefix_new ();
646   stream_get (&p->u.prefix, s, plen);
647   p->family = family;
648
649   ifc->destination = p;
650
651   p = ifc->address;
652
653   /* Add connected address to the interface. */
654   listnode_add (ifp->connected, ifc);
655
656   return ifc;
657 }
658
659 struct connected *
660 zebra_interface_address_delete_read (struct stream *s)
661 {
662   unsigned int ifindex;
663   struct interface *ifp;
664   struct connected *ifc;
665   struct prefix p;
666   struct prefix d;
667   int family;
668   int len;
669   u_char flags;
670
671   /* Get interface index. */
672   ifindex = stream_getl (s);
673
674   /* Lookup index. */
675   ifp = if_lookup_by_index (ifindex);
676   if (ifp == NULL)
677     {
678 #ifdef BRCM_RIP_DEBUG
679       zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex);
680 #endif
681       return NULL;
682     }
683
684   /* Fetch flag. */
685   flags = stream_getc (s);
686
687   /* Fetch interface address. */
688   family = p.family = stream_getc (s);
689
690   len = prefix_blen (&p);
691   stream_get (&p.u.prefix, s, len);
692   p.prefixlen = stream_getc (s);
693
694   /* Fetch destination address. */
695   stream_get (&d.u.prefix, s, len);
696   d.family = family;
697
698   ifc = connected_delete_by_prefix (ifp, &p);
699
700   return ifc;
701 }
702 \f
703 /* Zebra client message read function. */
704 int
705 zclient_read (struct thread *thread)
706 {
707   int ret;
708   int nbytes;
709   int sock;
710   zebra_size_t length;
711   zebra_command_t command;
712   struct zclient *zclient;
713
714   /* Get socket to zebra. */
715   sock = THREAD_FD (thread);
716   zclient = THREAD_ARG (thread);
717   zclient->t_read = NULL;
718
719   /* Clear input buffer. */
720   stream_reset (zclient->ibuf);
721
722   /* Read zebra header. */
723   nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);
724
725   /* zebra socket is closed. */
726   if (nbytes == 0) 
727     {
728 #ifdef BRCM_RIP_DEBUG
729       if (zclient_debug)
730         zlog_info ("zclient connection closed socket [%d].", sock);
731 #endif
732       zclient->fail++;
733       zclient_stop (zclient);
734       zclient_event (ZCLIENT_CONNECT, zclient);
735       return -1;
736     }
737
738   /* zebra read error. */
739   if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
740     {
741 #ifdef BRCM_RIP_DEBUG
742       if (zclient_debug)
743         zlog_info ("Can't read all packet (length %d).", nbytes);
744 #endif
745       zclient->fail++;
746       zclient_stop (zclient);
747       zclient_event (ZCLIENT_CONNECT, zclient);
748       return -1;
749     }
750
751   /* Fetch length and command. */
752   length = stream_getw (zclient->ibuf);
753   command = stream_getc (zclient->ibuf);
754
755   /* Length check. */
756   if (length >= zclient->ibuf->size)
757     {
758       stream_free (zclient->ibuf);
759       zclient->ibuf = stream_new (length + 1);
760     }
761   length -= ZEBRA_HEADER_SIZE;
762
763   /* Read rest of zebra packet. */
764   nbytes = stream_read (zclient->ibuf, sock, length);
765  if (nbytes != length)
766    {
767 #ifdef BRCM_RIP_DEBUG
768      if (zclient_debug)
769        zlog_info ("zclient connection closed socket [%d].", sock);
770 #endif
771      zclient->fail++;
772      zclient_stop (zclient);
773      zclient_event (ZCLIENT_CONNECT, zclient);
774      return -1;
775    }
776
777   switch (command)
778     {
779     case ZEBRA_INTERFACE_ADD:
780       if (zclient->interface_add)
781         ret = (*zclient->interface_add) (command, zclient, length);
782       break;
783     case ZEBRA_INTERFACE_DELETE:
784       if (zclient->interface_delete)
785         ret = (*zclient->interface_delete) (command, zclient, length);
786       break;
787     case ZEBRA_INTERFACE_ADDRESS_ADD:
788       if (zclient->interface_address_add)
789         ret = (*zclient->interface_address_add) (command, zclient, length);
790       break;
791     case ZEBRA_INTERFACE_ADDRESS_DELETE:
792       if (zclient->interface_address_delete)
793         ret = (*zclient->interface_address_delete) (command, zclient, length);
794       break;
795     case ZEBRA_INTERFACE_UP:
796       if (zclient->interface_up)
797         ret = (*zclient->interface_up) (command, zclient, length);
798       break;
799     case ZEBRA_INTERFACE_DOWN:
800       if (zclient->interface_down)
801         ret = (*zclient->interface_down) (command, zclient, length);
802       break;
803     case ZEBRA_IPV4_ROUTE_ADD:
804       if (zclient->ipv4_route_add)
805         ret = (*zclient->ipv4_route_add) (command, zclient, length);
806       break;
807     case ZEBRA_IPV4_ROUTE_DELETE:
808       if (zclient->ipv4_route_delete)
809         ret = (*zclient->ipv4_route_delete) (command, zclient, length);
810       break;
811 #ifdef HAVE_IPV6
812     case ZEBRA_IPV6_ROUTE_ADD:
813       if (zclient->ipv6_route_add)
814         ret = (*zclient->ipv6_route_add) (command, zclient, length);
815       break;
816     case ZEBRA_IPV6_ROUTE_DELETE:
817       if (zclient->ipv6_route_delete)
818         ret = (*zclient->ipv6_route_delete) (command, zclient, length);
819       break;
820 #endif /* HAVE_IPV6 */
821     default:
822       break;
823     }
824
825   /* Register read thread. */
826   zclient_event (ZCLIENT_READ, zclient);
827
828   return 0;
829 }
830
831 void
832 zclient_redistribute_set (struct zclient *zclient, int type)
833 {
834   if (zclient->redist[type])
835     return;
836
837   zclient->redist[type] = 1;
838
839   if (zclient->sock > 0)
840     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
841 }
842
843 void
844 zclient_redistribute_unset (struct zclient *zclient, int type)
845 {
846   if (! zclient->redist[type])
847     return;
848
849   zclient->redist[type] = 0;
850
851   if (zclient->sock > 0)
852     zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
853 }
854
855 void
856 zclient_redistribute_default_set (struct zclient *zclient)
857 {
858   if (zclient->default_information)
859     return;
860
861   zclient->default_information = 1;
862
863   if (zclient->sock > 0)
864     zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
865 }
866
867 void
868 zclient_redistribute_default_unset (struct zclient *zclient)
869 {
870   if (! zclient->default_information)
871     return;
872
873   zclient->default_information = 0;
874
875   if (zclient->sock > 0)
876     zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE);
877 }
878 \f
879 extern struct thread_master *master;
880
881 static void
882 zclient_event (enum event event, struct zclient *zclient)
883 {
884   switch (event)
885     {
886     case ZCLIENT_SCHEDULE:
887       if (! zclient->t_connect)
888         zclient->t_connect =
889           thread_add_event (master, zclient_connect, zclient, 0);
890       break;
891     case ZCLIENT_CONNECT:
892       if (zclient->fail >= 10)
893         return;
894 #ifdef BRCM_RIP_DEBUG
895       if (zclient_debug)
896         zlog_info ("zclient connect schedule interval is %d", 
897                    zclient->fail < 3 ? 10 : 60);
898 #endif
899       if (! zclient->t_connect)
900         zclient->t_connect = 
901           thread_add_timer (master, zclient_connect, zclient,
902                             zclient->fail < 3 ? 10 : 60);
903       break;
904     case ZCLIENT_READ:
905       zclient->t_read = 
906         thread_add_read (master, zclient_read, zclient, zclient->sock);
907       break;
908     }
909 }