]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
ospfd Point-to-Multipoint support
[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 {
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
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
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 {
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);
387
388 for (i = 0; i < api->nexthop_num; i++)
389 {
390 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
391 stream_put_in_addr (s, api->nexthop[i]);
392 }
393 for (i = 0; i < api->ifindex_num; i++)
394 {
395 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
396 stream_putl (s, api->ifindex[i]);
397 }
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)
558 {
559 ifp = if_create ();
560 strncpy (ifp->name, ifname_tmp, IFNAMSIZ);
561 }
562
563 /* Read interface's index. */
564 ifp->ifindex = stream_getl (s);
565
566 /* Read interface's value. */
567 ifp->flags = stream_getl (s);
568 ifp->metric = stream_getl (s);
569 ifp->mtu = stream_getl (s);
570 ifp->bandwidth = stream_getl (s);
571#ifdef HAVE_SOCKADDR_DL
572 stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
573#else
574 ifp->hw_addr_len = stream_getl (s);
575 if (ifp->hw_addr_len)
576 stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
577#endif /* HAVE_SOCKADDR_DL */
578
579 return ifp;
580}
581
582/* Read interface up/down msg from zebra daemon. */
583struct interface *
584zebra_interface_state_read (struct stream *s)
585{
586 struct interface *ifp;
587 u_char ifname_tmp[INTERFACE_NAMSIZ];
588
589 /* Read interface name. */
590 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
591
592 /* Lookup this by interface index. */
593 ifp = if_lookup_by_name (ifname_tmp);
594
595 /* If such interface does not exist, indicate an error */
596 if (! ifp)
597 return NULL;
598
599 /* Read interface's index. */
600 ifp->ifindex = stream_getl (s);
601
602 /* Read interface's value. */
603 ifp->flags = stream_getl (s);
604 ifp->metric = stream_getl (s);
605 ifp->mtu = stream_getl (s);
606 ifp->bandwidth = stream_getl (s);
607
608 return ifp;
609}
610
611struct connected *
612zebra_interface_address_add_read (struct stream *s)
613{
614 unsigned int ifindex;
615 struct interface *ifp;
616 struct connected *ifc;
617 struct prefix *p;
618 int family;
619 int plen;
620
621 /* Get interface index. */
622 ifindex = stream_getl (s);
623
624 /* Lookup index. */
625 ifp = if_lookup_by_index (ifindex);
626 if (ifp == NULL)
627 {
628 zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex);
629 return NULL;
630 }
631
632 /* Allocate new connected address. */
633 ifc = connected_new ();
634 ifc->ifp = ifp;
635
636 /* Fetch flag. */
637 ifc->flags = stream_getc (s);
638
639 /* Fetch interface address. */
640 p = prefix_new ();
641 family = p->family = stream_getc (s);
642
643 plen = prefix_blen (p);
644 stream_get (&p->u.prefix, s, plen);
645 p->prefixlen = stream_getc (s);
646 ifc->address = p;
647
648 /* Fetch destination address. */
649 p = prefix_new ();
650 stream_get (&p->u.prefix, s, plen);
651 p->family = family;
652
653 ifc->destination = p;
654
655 p = ifc->address;
656
657 /* Add connected address to the interface. */
658 listnode_add (ifp->connected, ifc);
659
660 return ifc;
661}
662
663struct connected *
664zebra_interface_address_delete_read (struct stream *s)
665{
666 unsigned int ifindex;
667 struct interface *ifp;
668 struct connected *ifc;
669 struct prefix p;
670 struct prefix d;
671 int family;
672 int len;
673 u_char flags;
674
675 /* Get interface index. */
676 ifindex = stream_getl (s);
677
678 /* Lookup index. */
679 ifp = if_lookup_by_index (ifindex);
680 if (ifp == NULL)
681 {
682 zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex);
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\f
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 if (zclient_debug)
731 zlog_info ("zclient connection closed socket [%d].", sock);
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 if (zclient_debug)
742 zlog_info ("Can't read all packet (length %d).", nbytes);
743 zclient->fail++;
744 zclient_stop (zclient);
745 zclient_event (ZCLIENT_CONNECT, zclient);
746 return -1;
747 }
748
749 /* Fetch length and command. */
750 length = stream_getw (zclient->ibuf);
751 command = stream_getc (zclient->ibuf);
752
753 /* Length check. */
754 if (length >= zclient->ibuf->size)
755 {
756 stream_free (zclient->ibuf);
757 zclient->ibuf = stream_new (length + 1);
758 }
759 length -= ZEBRA_HEADER_SIZE;
760
761 /* Read rest of zebra packet. */
762 nbytes = stream_read (zclient->ibuf, sock, length);
763 if (nbytes != length)
764 {
765 if (zclient_debug)
766 zlog_info ("zclient connection closed socket [%d].", sock);
767 zclient->fail++;
768 zclient_stop (zclient);
769 zclient_event (ZCLIENT_CONNECT, zclient);
770 return -1;
771 }
772
773 switch (command)
774 {
775 case ZEBRA_INTERFACE_ADD:
776 if (zclient->interface_add)
777 ret = (*zclient->interface_add) (command, zclient, length);
778 break;
779 case ZEBRA_INTERFACE_DELETE:
780 if (zclient->interface_delete)
781 ret = (*zclient->interface_delete) (command, zclient, length);
782 break;
783 case ZEBRA_INTERFACE_ADDRESS_ADD:
784 if (zclient->interface_address_add)
785 ret = (*zclient->interface_address_add) (command, zclient, length);
786 break;
787 case ZEBRA_INTERFACE_ADDRESS_DELETE:
788 if (zclient->interface_address_delete)
789 ret = (*zclient->interface_address_delete) (command, zclient, length);
790 break;
791 case ZEBRA_INTERFACE_UP:
792 if (zclient->interface_up)
793 ret = (*zclient->interface_up) (command, zclient, length);
794 break;
795 case ZEBRA_INTERFACE_DOWN:
796 if (zclient->interface_down)
797 ret = (*zclient->interface_down) (command, zclient, length);
798 break;
799 case ZEBRA_IPV4_ROUTE_ADD:
800 if (zclient->ipv4_route_add)
801 ret = (*zclient->ipv4_route_add) (command, zclient, length);
802 break;
803 case ZEBRA_IPV4_ROUTE_DELETE:
804 if (zclient->ipv4_route_delete)
805 ret = (*zclient->ipv4_route_delete) (command, zclient, length);
806 break;
807 case ZEBRA_IPV6_ROUTE_ADD:
808 if (zclient->ipv6_route_add)
809 ret = (*zclient->ipv6_route_add) (command, zclient, length);
810 break;
811 case ZEBRA_IPV6_ROUTE_DELETE:
812 if (zclient->ipv6_route_delete)
813 ret = (*zclient->ipv6_route_delete) (command, zclient, length);
814 break;
815 default:
816 break;
817 }
818
819 /* Register read thread. */
820 zclient_event (ZCLIENT_READ, zclient);
821
822 return 0;
823}
824
825void
826zclient_redistribute_set (struct zclient *zclient, int type)
827{
828 if (zclient->redist[type])
829 return;
830
831 zclient->redist[type] = 1;
832
833 if (zclient->sock > 0)
834 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
835}
836
837void
838zclient_redistribute_unset (struct zclient *zclient, int type)
839{
840 if (! zclient->redist[type])
841 return;
842
843 zclient->redist[type] = 0;
844
845 if (zclient->sock > 0)
846 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
847}
848
849void
850zclient_redistribute_default_set (struct zclient *zclient)
851{
852 if (zclient->default_information)
853 return;
854
855 zclient->default_information = 1;
856
857 if (zclient->sock > 0)
858 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
859}
860
861void
862zclient_redistribute_default_unset (struct zclient *zclient)
863{
864 if (! zclient->default_information)
865 return;
866
867 zclient->default_information = 0;
868
869 if (zclient->sock > 0)
870 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE);
871}
872\f
873extern struct thread_master *master;
874
875static void
876zclient_event (enum event event, struct zclient *zclient)
877{
878 switch (event)
879 {
880 case ZCLIENT_SCHEDULE:
881 if (! zclient->t_connect)
882 zclient->t_connect =
883 thread_add_event (master, zclient_connect, zclient, 0);
884 break;
885 case ZCLIENT_CONNECT:
886 if (zclient->fail >= 10)
887 return;
888 if (zclient_debug)
889 zlog_info ("zclient connect schedule interval is %d",
890 zclient->fail < 3 ? 10 : 60);
891 if (! zclient->t_connect)
892 zclient->t_connect =
893 thread_add_timer (master, zclient_connect, zclient,
894 zclient->fail < 3 ? 10 : 60);
895 break;
896 case ZCLIENT_READ:
897 zclient->t_read =
898 thread_add_read (master, zclient_read, zclient, zclient->sock);
899 break;
900 }
901}