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