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
37/* Zebra client events. */
38enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
39
40/* Prototype for event manager. */
41static void zclient_event (enum event, struct zclient *);
42
43/* This file local debug flag. */
44int zclient_debug = 0;
45
46/* Allocate zclient structure. */
47struct zclient *
48zclient_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. */
61void
62zclient_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. */
69void
70zclient_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 FOX_RIP_DEBUG
94  if (zclient_debug)
95    zlog_info ("zclient start scheduled");
96#endif /* FOX_RIP_DEBUG */
97  zclient_event (ZCLIENT_SCHEDULE, zclient);
98}
99
100/* Stop zebra client services. */
101void
102zclient_stop (struct zclient *zclient)
103{
104  if (zclient_debug)
105#ifdef FOX_RIP_DEBUG
106    zlog_info ("zclient stopped");
107#endif /* FOX_RIP_DEBUG */
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
129void
130zclient_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. */
137int
138zclient_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 FOX_SUPPORT
168/* For sockaddr_un. */
169#include <sys/un.h>
170
171int
172zclient_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 /* FOX_SUPPORT */
201/* Send simple Zebra message. */
202int
203zebra_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. */
219int
220zclient_start (struct zclient *zclient)
221{
222  int i;
223
224#ifdef FOX_RIP_DEBUG
225  if (zclient_debug)
226    zlog_info ("zclient_start is called");
227#endif /* FOX_RIP_DEBUG */
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 FOX_RIP_DEBUG
249      if (zclient_debug)
250	zlog_info ("zclient connection fail");
251#endif /* FOX_RIP_DEBUG */
252      zclient->fail++;
253      zclient_event (ZCLIENT_CONNECT, zclient);
254      return -1;
255    }
256
257  /* Clear fail count. */
258  zclient->fail = 0;
259  if (zclient_debug){
260#ifdef FOX_RIP_DEBUG
261    zlog_info ("zclient connect success with socket [%d]", zclient->sock);
262#endif /* FOX_RIP_DEBUG */
263  	}
264
265  /* Create read thread. */
266  zclient_event (ZCLIENT_READ, zclient);
267
268  /* We need interface information. */
269  zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
270
271  /* Flush all redistribute request. */
272  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
273    if (i != zclient->redist_default && zclient->redist[i])
274      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, i);
275
276  /* If default information is needed. */
277  if (zclient->default_information)
278    zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
279
280  return 0;
281}
282
283/* This function is a wrapper function for calling zclient_start from
284   timer or event thread. */
285int
286zclient_connect (struct thread *t)
287{
288  struct zclient *zclient;
289
290  zclient = THREAD_ARG (t);
291  zclient->t_connect = NULL;
292#ifdef FOX_RIP_DEBUG
293  if (zclient_debug)
294    zlog_info ("zclient_connect is called");
295#endif /* FOX_RIP_DEBUG */
296  return zclient_start (zclient);
297}
298
299int
300zapi_ipv4_add (struct zclient *zclient, struct prefix_ipv4 *p,
301	       struct zapi_ipv4 *api)
302{
303  int i;
304  int psize;
305  struct stream *s;
306
307  /* Reset stream. */
308  s = zclient->obuf;
309  stream_reset (s);
310
311  /* Length place holder. */
312  stream_putw (s, 0);
313
314  /* Put command, type and nexthop. */
315  stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
316  stream_putc (s, api->type);
317  stream_putc (s, api->flags);
318  stream_putc (s, api->message);
319
320  /* Put prefix information. */
321  psize = PSIZE (p->prefixlen);
322  stream_putc (s, p->prefixlen);
323  stream_write (s, (u_char *)&p->prefix, psize);
324
325  /* Nexthop, ifindex, distance and metric information. */
326  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
327    {
328      stream_putc (s, api->nexthop_num + api->ifindex_num);
329
330      for (i = 0; i < api->nexthop_num; i++)
331	{
332	  stream_putc (s, ZEBRA_NEXTHOP_IPV4);
333	  stream_put_in_addr (s, api->nexthop[i]);
334	}
335      for (i = 0; i < api->ifindex_num; i++)
336	{
337	  stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
338	  stream_putl (s, api->ifindex[i]);
339	}
340    }
341
342  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
343    stream_putc (s, api->distance);
344  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
345    stream_putl (s, api->metric);
346
347  /* Put length at the first point of the stream. */
348  stream_putw_at (s, 0, stream_get_endp (s));
349
350  return writen (zclient->sock, s->data, stream_get_endp (s));
351}
352
353int
354zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p,
355		  struct zapi_ipv4 *api)
356{
357  int i;
358  int psize;
359  struct stream *s;
360
361  /* Reset stream. */
362  s = zclient->obuf;
363  stream_reset (s);
364
365  /* Length place holder. */
366  stream_putw (s, 0);
367
368  /* Put command, type and nexthop. */
369  stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
370  stream_putc (s, api->type);
371  stream_putc (s, api->flags);
372  stream_putc (s, api->message);
373
374  /* Put prefix information. */
375  psize = PSIZE (p->prefixlen);
376  stream_putc (s, p->prefixlen);
377  stream_write (s, (u_char *)&p->prefix, psize);
378
379  /* Nexthop, ifindex, distance and metric information. */
380  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
381    {
382      stream_putc (s, api->nexthop_num + api->ifindex_num);
383
384      for (i = 0; i < api->nexthop_num; i++)
385	{
386	  stream_putc (s, ZEBRA_NEXTHOP_IPV4);
387	  stream_put_in_addr (s, api->nexthop[i]);
388	}
389      for (i = 0; i < api->ifindex_num; i++)
390	{
391	  stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
392	  stream_putl (s, api->ifindex[i]);
393	}
394    }
395
396  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
397    stream_putc (s, api->distance);
398  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
399    stream_putl (s, api->metric);
400
401  /* Put length at the first point of the stream. */
402  stream_putw_at (s, 0, stream_get_endp (s));
403
404  return writen (zclient->sock, s->data, stream_get_endp (s));
405}
406
407#ifdef HAVE_IPV6
408int
409zapi_ipv6_add (struct zclient *zclient, struct prefix_ipv6 *p,
410	       struct zapi_ipv6 *api)
411{
412  int i;
413  int psize;
414  struct stream *s;
415
416  /* Reset stream. */
417  s = zclient->obuf;
418  stream_reset (s);
419
420  /* Length place holder. */
421  stream_putw (s, 0);
422
423  /* Put command, type and nexthop. */
424  stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
425  stream_putc (s, api->type);
426  stream_putc (s, api->flags);
427  stream_putc (s, api->message);
428
429  /* Put prefix information. */
430  psize = PSIZE (p->prefixlen);
431  stream_putc (s, p->prefixlen);
432  stream_write (s, (u_char *)&p->prefix, psize);
433
434  /* Nexthop, ifindex, distance and metric information. */
435  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
436    {
437      stream_putc (s, api->nexthop_num + api->ifindex_num);
438
439      for (i = 0; i < api->nexthop_num; i++)
440	{
441	  stream_putc (s, ZEBRA_NEXTHOP_IPV6);
442	  stream_write (s, (u_char *)api->nexthop[i], 16);
443	}
444      for (i = 0; i < api->ifindex_num; i++)
445	{
446	  stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
447	  stream_putl (s, api->ifindex[i]);
448	}
449    }
450
451  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
452    stream_putc (s, api->distance);
453  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
454    stream_putl (s, api->metric);
455
456  /* Put length at the first point of the stream. */
457  stream_putw_at (s, 0, stream_get_endp (s));
458
459  return writen (zclient->sock, s->data, stream_get_endp (s));
460}
461
462int
463zapi_ipv6_delete (struct zclient *zclient, struct prefix_ipv6 *p,
464		  struct zapi_ipv6 *api)
465{
466  int i;
467  int psize;
468  struct stream *s;
469
470  /* Reset stream. */
471  s = zclient->obuf;
472  stream_reset (s);
473
474  /* Length place holder. */
475  stream_putw (s, 0);
476
477  /* Put command, type and nexthop. */
478  stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
479  stream_putc (s, api->type);
480  stream_putc (s, api->flags);
481  stream_putc (s, api->message);
482
483  /* Put prefix information. */
484  psize = PSIZE (p->prefixlen);
485  stream_putc (s, p->prefixlen);
486  stream_write (s, (u_char *)&p->prefix, psize);
487
488  /* Nexthop, ifindex, distance and metric information. */
489  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
490    {
491      stream_putc (s, api->nexthop_num + api->ifindex_num);
492
493      for (i = 0; i < api->nexthop_num; i++)
494	{
495	  stream_putc (s, ZEBRA_NEXTHOP_IPV6);
496	  stream_write (s, (u_char *)api->nexthop[i], 16);
497	}
498      for (i = 0; i < api->ifindex_num; i++)
499	{
500	  stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
501	  stream_putl (s, api->ifindex[i]);
502	}
503    }
504
505  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
506    stream_putc (s, api->distance);
507  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
508    stream_putl (s, api->metric);
509
510  /* Put length at the first point of the stream. */
511  stream_putw_at (s, 0, stream_get_endp (s));
512
513  return writen (zclient->sock, s->data, stream_get_endp (s));
514}
515
516#endif /* HAVE_IPV6 */
517
518int
519zebra_redistribute_send (int command, int sock, int type)
520{
521  int ret;
522  struct stream *s;
523
524  s = stream_new (ZEBRA_MAX_PACKET_SIZ);
525
526  /* Total length of the messages. */
527  stream_putw (s, 4);
528
529  stream_putc (s, command);
530  stream_putc (s, type);
531
532  ret = writen (sock, s->data, 4);
533
534  stream_free (s);
535
536  return ret;
537}
538
539/* Interface addition from zebra daemon. */
540struct interface *
541zebra_interface_add_read (struct stream *s)
542{
543  struct interface *ifp;
544  u_char ifname_tmp[INTERFACE_NAMSIZ];
545
546  /* Read interface name. */
547  stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
548
549  /* Lookup this by interface name. */
550  ifp = if_lookup_by_name (ifname_tmp);
551
552  /* If such interface does not exist, make new one. */
553  if (! ifp)
554    {
555      ifp = if_create ();
556      strncpy (ifp->name, ifname_tmp, IFNAMSIZ);
557    }
558
559  /* Read interface's index. */
560  ifp->ifindex = stream_getl (s);
561
562  /* Read interface's value. */
563  ifp->flags = stream_getl (s);
564  ifp->metric = stream_getl (s);
565  ifp->mtu = stream_getl (s);
566  ifp->bandwidth = stream_getl (s);
567#ifdef HAVE_SOCKADDR_DL
568  stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
569#else
570  ifp->hw_addr_len = stream_getl (s);
571  if (ifp->hw_addr_len)
572    stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
573#endif /* HAVE_SOCKADDR_DL */
574
575  return ifp;
576}
577
578/* Read interface up/down msg from zebra daemon. */
579struct interface *
580zebra_interface_state_read (struct stream *s)
581{
582  struct interface *ifp;
583  u_char ifname_tmp[INTERFACE_NAMSIZ];
584
585  /* Read interface name. */
586  stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
587
588  /* Lookup this by interface index. */
589  ifp = if_lookup_by_name (ifname_tmp);
590
591  /* If such interface does not exist, indicate an error */
592  if (! ifp)
593     return NULL;
594
595  /* Read interface's index. */
596  ifp->ifindex = stream_getl (s);
597
598  /* Read interface's value. */
599  ifp->flags = stream_getl (s);
600  ifp->metric = stream_getl (s);
601  ifp->mtu = stream_getl (s);
602  ifp->bandwidth = stream_getl (s);
603
604  return ifp;
605}
606
607struct connected *
608zebra_interface_address_add_read (struct stream *s)
609{
610  unsigned int ifindex;
611  struct interface *ifp;
612  struct connected *ifc;
613  struct prefix *p;
614  int family;
615  int plen;
616
617  /* Get interface index. */
618  ifindex = stream_getl (s);
619
620  /* Lookup index. */
621  ifp = if_lookup_by_index (ifindex);
622  if (ifp == NULL)
623    {
624#ifdef FOX_RIP_DEBUG
625      zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex);
626#endif /* FOX_RIP_DEBUG */
627      return NULL;
628    }
629
630  /* Allocate new connected address. */
631  ifc = connected_new ();
632  ifc->ifp = ifp;
633
634  /* Fetch flag. */
635  ifc->flags = stream_getc (s);
636
637  /* Fetch interface address. */
638  p = prefix_new ();
639  family = p->family = stream_getc (s);
640
641  plen = prefix_blen (p);
642  stream_get (&p->u.prefix, s, plen);
643  p->prefixlen = stream_getc (s);
644  ifc->address = p;
645
646  /* Fetch destination address. */
647  p = prefix_new ();
648  stream_get (&p->u.prefix, s, plen);
649  p->family = family;
650
651  ifc->destination = p;
652
653  p = ifc->address;
654
655  /* Add connected address to the interface. */
656  listnode_add (ifp->connected, ifc);
657
658  return ifc;
659}
660
661struct connected *
662zebra_interface_address_delete_read (struct stream *s)
663{
664  unsigned int ifindex;
665  struct interface *ifp;
666  struct connected *ifc;
667  struct prefix p;
668  struct prefix d;
669  int family;
670  int len;
671  u_char flags;
672
673  /* Get interface index. */
674  ifindex = stream_getl (s);
675
676  /* Lookup index. */
677  ifp = if_lookup_by_index (ifindex);
678  if (ifp == NULL)
679    {
680#ifdef FOX_RIP_DEBUG
681      zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex);
682#endif /* FOX_RIP_DEBUG */
683      return NULL;
684    }
685
686  /* Fetch flag. */
687  flags = stream_getc (s);
688
689  /* Fetch interface address. */
690  family = p.family = stream_getc (s);
691
692  len = prefix_blen (&p);
693  stream_get (&p.u.prefix, s, len);
694  p.prefixlen = stream_getc (s);
695
696  /* Fetch destination address. */
697  stream_get (&d.u.prefix, s, len);
698  d.family = family;
699
700  ifc = connected_delete_by_prefix (ifp, &p);
701
702  return ifc;
703}
704
705/* Zebra client message read function. */
706int
707zclient_read (struct thread *thread)
708{
709  int ret;
710  int nbytes;
711  int sock;
712  zebra_size_t length;
713  zebra_command_t command;
714  struct zclient *zclient;
715
716  /* Get socket to zebra. */
717  sock = THREAD_FD (thread);
718  zclient = THREAD_ARG (thread);
719  zclient->t_read = NULL;
720
721  /* Clear input buffer. */
722  stream_reset (zclient->ibuf);
723
724  /* Read zebra header. */
725  nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);
726
727  /* zebra socket is closed. */
728  if (nbytes == 0)
729    {
730#ifdef FOX_RIP_DEBUG
731      if (zclient_debug)
732	zlog_info ("zclient connection closed socket [%d].", sock);
733#endif /* FOX_RIP_DEBUG */
734      zclient->fail++;
735      zclient_stop (zclient);
736      zclient_event (ZCLIENT_CONNECT, zclient);
737      return -1;
738    }
739
740  /* zebra read error. */
741  if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
742    {
743#ifdef FOX_RIP_DEBUG
744      if (zclient_debug)
745	zlog_info ("Can't read all packet (length %d).", nbytes);
746#endif /* FOX_RIP_DEBUG */
747      zclient->fail++;
748      zclient_stop (zclient);
749      zclient_event (ZCLIENT_CONNECT, zclient);
750      return -1;
751    }
752
753  /* Fetch length and command. */
754  length = stream_getw (zclient->ibuf);
755  command = stream_getc (zclient->ibuf);
756
757  /* Length check. */
758  if (length >= zclient->ibuf->size)
759    {
760      stream_free (zclient->ibuf);
761      zclient->ibuf = stream_new (length + 1);
762    }
763  length -= ZEBRA_HEADER_SIZE;
764
765  /* Read rest of zebra packet. */
766  nbytes = stream_read (zclient->ibuf, sock, length);
767 if (nbytes != length)
768   {
769#ifdef FOX_RIP_DEBUG
770     if (zclient_debug)
771       zlog_info ("zclient connection closed socket [%d].", sock);
772#endif /* FOX_RIP_DEBUG */
773     zclient->fail++;
774     zclient_stop (zclient);
775     zclient_event (ZCLIENT_CONNECT, zclient);
776     return -1;
777   }
778
779  switch (command)
780    {
781    case ZEBRA_INTERFACE_ADD:
782      if (zclient->interface_add)
783	ret = (*zclient->interface_add) (command, zclient, length);
784      break;
785    case ZEBRA_INTERFACE_DELETE:
786      if (zclient->interface_delete)
787	ret = (*zclient->interface_delete) (command, zclient, length);
788      break;
789    case ZEBRA_INTERFACE_ADDRESS_ADD:
790      if (zclient->interface_address_add)
791	ret = (*zclient->interface_address_add) (command, zclient, length);
792      break;
793    case ZEBRA_INTERFACE_ADDRESS_DELETE:
794      if (zclient->interface_address_delete)
795	ret = (*zclient->interface_address_delete) (command, zclient, length);
796      break;
797    case ZEBRA_INTERFACE_UP:
798      if (zclient->interface_up)
799	ret = (*zclient->interface_up) (command, zclient, length);
800      break;
801    case ZEBRA_INTERFACE_DOWN:
802      if (zclient->interface_down)
803	ret = (*zclient->interface_down) (command, zclient, length);
804      break;
805    case ZEBRA_IPV4_ROUTE_ADD:
806      if (zclient->ipv4_route_add)
807	ret = (*zclient->ipv4_route_add) (command, zclient, length);
808      break;
809    case ZEBRA_IPV4_ROUTE_DELETE:
810      if (zclient->ipv4_route_delete)
811	ret = (*zclient->ipv4_route_delete) (command, zclient, length);
812      break;
813#ifdef HAVE_IPV6
814    case ZEBRA_IPV6_ROUTE_ADD:
815      if (zclient->ipv6_route_add)
816	ret = (*zclient->ipv6_route_add) (command, zclient, length);
817      break;
818    case ZEBRA_IPV6_ROUTE_DELETE:
819      if (zclient->ipv6_route_delete)
820	ret = (*zclient->ipv6_route_delete) (command, zclient, length);
821      break;
822#endif /* HAVE_IPV6 */
823    default:
824      break;
825    }
826
827  /* Register read thread. */
828  zclient_event (ZCLIENT_READ, zclient);
829
830  return 0;
831}
832
833void
834zclient_redistribute_set (struct zclient *zclient, int type)
835{
836  if (zclient->redist[type])
837    return;
838
839  zclient->redist[type] = 1;
840
841  if (zclient->sock > 0)
842    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
843}
844
845void
846zclient_redistribute_unset (struct zclient *zclient, int type)
847{
848  if (! zclient->redist[type])
849    return;
850
851  zclient->redist[type] = 0;
852
853  if (zclient->sock > 0)
854    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
855}
856
857void
858zclient_redistribute_default_set (struct zclient *zclient)
859{
860  if (zclient->default_information)
861    return;
862
863  zclient->default_information = 1;
864
865  if (zclient->sock > 0)
866    zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
867}
868
869void
870zclient_redistribute_default_unset (struct zclient *zclient)
871{
872  if (! zclient->default_information)
873    return;
874
875  zclient->default_information = 0;
876
877  if (zclient->sock > 0)
878    zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE);
879}
880
881extern struct thread_master *master;
882
883static void
884zclient_event (enum event event, struct zclient *zclient)
885{
886  switch (event)
887    {
888    case ZCLIENT_SCHEDULE:
889      if (! zclient->t_connect)
890	zclient->t_connect =
891	  thread_add_event (master, zclient_connect, zclient, 0);
892      break;
893    case ZCLIENT_CONNECT:
894      if (zclient->fail >= 10)
895	return;
896#ifdef FOX_RIP_DEBUG
897      if (zclient_debug)
898	zlog_info ("zclient connect schedule interval is %d",
899		   zclient->fail < 3 ? 10 : 60);
900#endif /* FOX_RIP_DEBUG */
901      if (! zclient->t_connect)
902	zclient->t_connect =
903	  thread_add_timer (master, zclient_connect, zclient,
904			    zclient->fail < 3 ? 10 : 60);
905      break;
906    case ZCLIENT_READ:
907      zclient->t_read =
908	thread_add_read (master, zclient_read, zclient, zclient->sock);
909      break;
910    }
911}
912