blob: ebf685a05308d36a3fa426d4150869bfb5b81065 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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 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
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 {
paul718e3742002-12-13 20:15:29 +0000320 stream_putc (s, api->nexthop_num + api->ifindex_num);
321
322 for (i = 0; i < api->nexthop_num; i++)
323 {
324 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
325 stream_put_in_addr (s, api->nexthop[i]);
326 }
327 for (i = 0; i < api->ifindex_num; i++)
328 {
329 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
330 stream_putl (s, api->ifindex[i]);
331 }
332 }
333
334 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
335 stream_putc (s, api->distance);
336 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
337 stream_putl (s, api->metric);
338
339 /* Put length at the first point of the stream. */
340 stream_putw_at (s, 0, stream_get_endp (s));
341
342 return writen (zclient->sock, s->data, stream_get_endp (s));
343}
344
345int
346zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p,
347 struct zapi_ipv4 *api)
348{
349 int i;
350 int psize;
351 struct stream *s;
352
353 /* Reset stream. */
354 s = zclient->obuf;
355 stream_reset (s);
356
357 /* Length place holder. */
358 stream_putw (s, 0);
359
360 /* Put command, type and nexthop. */
361 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
362 stream_putc (s, api->type);
363 stream_putc (s, api->flags);
364 stream_putc (s, api->message);
365
366 /* Put prefix information. */
367 psize = PSIZE (p->prefixlen);
368 stream_putc (s, p->prefixlen);
369 stream_write (s, (u_char *)&p->prefix, psize);
370
371 /* Nexthop, ifindex, distance and metric information. */
372 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
373 {
paul718e3742002-12-13 20:15:29 +0000374 stream_putc (s, api->nexthop_num + api->ifindex_num);
375
376 for (i = 0; i < api->nexthop_num; i++)
377 {
378 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
379 stream_put_in_addr (s, api->nexthop[i]);
380 }
381 for (i = 0; i < api->ifindex_num; i++)
382 {
383 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
384 stream_putl (s, api->ifindex[i]);
385 }
386 }
387
388 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
389 stream_putc (s, api->distance);
390 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
391 stream_putl (s, api->metric);
392
393 /* Put length at the first point of the stream. */
394 stream_putw_at (s, 0, stream_get_endp (s));
395
396 return writen (zclient->sock, s->data, stream_get_endp (s));
397}
398
399#ifdef HAVE_IPV6
400int
401zapi_ipv6_add (struct zclient *zclient, struct prefix_ipv6 *p,
402 struct zapi_ipv6 *api)
403{
404 int i;
405 int psize;
406 struct stream *s;
407
408 /* Reset stream. */
409 s = zclient->obuf;
410 stream_reset (s);
411
412 /* Length place holder. */
413 stream_putw (s, 0);
414
415 /* Put command, type and nexthop. */
416 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
417 stream_putc (s, api->type);
418 stream_putc (s, api->flags);
419 stream_putc (s, api->message);
420
421 /* Put prefix information. */
422 psize = PSIZE (p->prefixlen);
423 stream_putc (s, p->prefixlen);
424 stream_write (s, (u_char *)&p->prefix, psize);
425
426 /* Nexthop, ifindex, distance and metric information. */
427 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
428 {
429 stream_putc (s, api->nexthop_num + api->ifindex_num);
430
431 for (i = 0; i < api->nexthop_num; i++)
432 {
433 stream_putc (s, ZEBRA_NEXTHOP_IPV6);
434 stream_write (s, (u_char *)api->nexthop[i], 16);
435 }
436 for (i = 0; i < api->ifindex_num; i++)
437 {
438 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
439 stream_putl (s, api->ifindex[i]);
440 }
441 }
442
443 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
444 stream_putc (s, api->distance);
445 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
446 stream_putl (s, api->metric);
447
448 /* Put length at the first point of the stream. */
449 stream_putw_at (s, 0, stream_get_endp (s));
450
451 return writen (zclient->sock, s->data, stream_get_endp (s));
452}
453
454int
455zapi_ipv6_delete (struct zclient *zclient, struct prefix_ipv6 *p,
456 struct zapi_ipv6 *api)
457{
458 int i;
459 int psize;
460 struct stream *s;
461
462 /* Reset stream. */
463 s = zclient->obuf;
464 stream_reset (s);
465
466 /* Length place holder. */
467 stream_putw (s, 0);
468
469 /* Put command, type and nexthop. */
470 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
471 stream_putc (s, api->type);
472 stream_putc (s, api->flags);
473 stream_putc (s, api->message);
474
475 /* Put prefix information. */
476 psize = PSIZE (p->prefixlen);
477 stream_putc (s, p->prefixlen);
478 stream_write (s, (u_char *)&p->prefix, psize);
479
480 /* Nexthop, ifindex, distance and metric information. */
481 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
482 {
483 stream_putc (s, api->nexthop_num + api->ifindex_num);
484
485 for (i = 0; i < api->nexthop_num; i++)
486 {
487 stream_putc (s, ZEBRA_NEXTHOP_IPV6);
488 stream_write (s, (u_char *)api->nexthop[i], 16);
489 }
490 for (i = 0; i < api->ifindex_num; i++)
491 {
492 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
493 stream_putl (s, api->ifindex[i]);
494 }
495 }
496
497 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
498 stream_putc (s, api->distance);
499 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
500 stream_putl (s, api->metric);
501
502 /* Put length at the first point of the stream. */
503 stream_putw_at (s, 0, stream_get_endp (s));
504
505 return writen (zclient->sock, s->data, stream_get_endp (s));
506}
507
508#endif /* HAVE_IPV6 */
509
510int
511zebra_redistribute_send (int command, int sock, int type)
512{
513 int ret;
514 struct stream *s;
515
516 s = stream_new (ZEBRA_MAX_PACKET_SIZ);
517
518 /* Total length of the messages. */
519 stream_putw (s, 4);
520
521 stream_putc (s, command);
522 stream_putc (s, type);
523
524 ret = writen (sock, s->data, 4);
525
526 stream_free (s);
527
528 return ret;
529}
530
531/* Interface addition from zebra daemon. */
532struct interface *
533zebra_interface_add_read (struct stream *s)
534{
535 struct interface *ifp;
536 u_char ifname_tmp[INTERFACE_NAMSIZ];
537
538 /* Read interface name. */
539 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
540
541 /* Lookup this by interface name. */
542 ifp = if_lookup_by_name (ifname_tmp);
543
544 /* If such interface does not exist, make new one. */
545 if (! ifp)
546 {
547 ifp = if_create ();
548 strncpy (ifp->name, ifname_tmp, IFNAMSIZ);
549 }
550
551 /* Read interface's index. */
552 ifp->ifindex = stream_getl (s);
553
554 /* Read interface's value. */
paul2e3b2e42002-12-13 21:03:13 +0000555 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000556 ifp->flags = stream_getl (s);
557 ifp->metric = stream_getl (s);
558 ifp->mtu = stream_getl (s);
559 ifp->bandwidth = stream_getl (s);
560#ifdef HAVE_SOCKADDR_DL
561 stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
562#else
563 ifp->hw_addr_len = stream_getl (s);
564 if (ifp->hw_addr_len)
565 stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
566#endif /* HAVE_SOCKADDR_DL */
567
568 return ifp;
569}
570
571/* Read interface up/down msg from zebra daemon. */
572struct interface *
573zebra_interface_state_read (struct stream *s)
574{
575 struct interface *ifp;
576 u_char ifname_tmp[INTERFACE_NAMSIZ];
577
578 /* Read interface name. */
579 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
580
581 /* Lookup this by interface index. */
582 ifp = if_lookup_by_name (ifname_tmp);
583
584 /* If such interface does not exist, indicate an error */
585 if (! ifp)
586 return NULL;
587
588 /* Read interface's index. */
589 ifp->ifindex = stream_getl (s);
590
591 /* Read interface's value. */
paul2e3b2e42002-12-13 21:03:13 +0000592 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000593 ifp->flags = stream_getl (s);
594 ifp->metric = stream_getl (s);
595 ifp->mtu = stream_getl (s);
596 ifp->bandwidth = stream_getl (s);
597
598 return ifp;
599}
600
601struct connected *
602zebra_interface_address_add_read (struct stream *s)
603{
604 unsigned int ifindex;
605 struct interface *ifp;
606 struct connected *ifc;
607 struct prefix *p;
608 int family;
609 int plen;
610
611 /* Get interface index. */
612 ifindex = stream_getl (s);
613
614 /* Lookup index. */
615 ifp = if_lookup_by_index (ifindex);
616 if (ifp == NULL)
617 {
618 zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex);
619 return NULL;
620 }
621
622 /* Allocate new connected address. */
623 ifc = connected_new ();
624 ifc->ifp = ifp;
625
626 /* Fetch flag. */
627 ifc->flags = stream_getc (s);
628
629 /* Fetch interface address. */
630 p = prefix_new ();
631 family = p->family = stream_getc (s);
632
633 plen = prefix_blen (p);
634 stream_get (&p->u.prefix, s, plen);
635 p->prefixlen = stream_getc (s);
636 ifc->address = p;
637
638 /* Fetch destination address. */
639 p = prefix_new ();
640 stream_get (&p->u.prefix, s, plen);
641 p->family = family;
642
643 ifc->destination = p;
644
645 p = ifc->address;
646
647 /* Add connected address to the interface. */
648 listnode_add (ifp->connected, ifc);
649
650 return ifc;
651}
652
653struct connected *
654zebra_interface_address_delete_read (struct stream *s)
655{
656 unsigned int ifindex;
657 struct interface *ifp;
658 struct connected *ifc;
659 struct prefix p;
660 struct prefix d;
661 int family;
662 int len;
663 u_char flags;
664
665 /* Get interface index. */
666 ifindex = stream_getl (s);
667
668 /* Lookup index. */
669 ifp = if_lookup_by_index (ifindex);
670 if (ifp == NULL)
671 {
672 zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex);
673 return NULL;
674 }
675
676 /* Fetch flag. */
677 flags = stream_getc (s);
678
679 /* Fetch interface address. */
680 family = p.family = stream_getc (s);
681
682 len = prefix_blen (&p);
683 stream_get (&p.u.prefix, s, len);
684 p.prefixlen = stream_getc (s);
685
686 /* Fetch destination address. */
687 stream_get (&d.u.prefix, s, len);
688 d.family = family;
689
690 ifc = connected_delete_by_prefix (ifp, &p);
691
692 return ifc;
693}
694
695/* Zebra client message read function. */
696int
697zclient_read (struct thread *thread)
698{
699 int ret;
700 int nbytes;
701 int sock;
702 zebra_size_t length;
703 zebra_command_t command;
704 struct zclient *zclient;
705
706 /* Get socket to zebra. */
707 sock = THREAD_FD (thread);
708 zclient = THREAD_ARG (thread);
709 zclient->t_read = NULL;
710
711 /* Clear input buffer. */
712 stream_reset (zclient->ibuf);
713
714 /* Read zebra header. */
715 nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);
716
717 /* zebra socket is closed. */
718 if (nbytes == 0)
719 {
720 if (zclient_debug)
721 zlog_info ("zclient connection closed socket [%d].", sock);
722 zclient->fail++;
723 zclient_stop (zclient);
724 zclient_event (ZCLIENT_CONNECT, zclient);
725 return -1;
726 }
727
728 /* zebra read error. */
729 if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
730 {
731 if (zclient_debug)
732 zlog_info ("Can't read all packet (length %d).", nbytes);
733 zclient->fail++;
734 zclient_stop (zclient);
735 zclient_event (ZCLIENT_CONNECT, zclient);
736 return -1;
737 }
738
739 /* Fetch length and command. */
740 length = stream_getw (zclient->ibuf);
741 command = stream_getc (zclient->ibuf);
742
743 /* Length check. */
744 if (length >= zclient->ibuf->size)
745 {
746 stream_free (zclient->ibuf);
747 zclient->ibuf = stream_new (length + 1);
748 }
749 length -= ZEBRA_HEADER_SIZE;
750
751 /* Read rest of zebra packet. */
752 nbytes = stream_read (zclient->ibuf, sock, length);
753 if (nbytes != length)
754 {
755 if (zclient_debug)
756 zlog_info ("zclient connection closed socket [%d].", sock);
757 zclient->fail++;
758 zclient_stop (zclient);
759 zclient_event (ZCLIENT_CONNECT, zclient);
760 return -1;
761 }
762
763 switch (command)
764 {
765 case ZEBRA_INTERFACE_ADD:
766 if (zclient->interface_add)
767 ret = (*zclient->interface_add) (command, zclient, length);
768 break;
769 case ZEBRA_INTERFACE_DELETE:
770 if (zclient->interface_delete)
771 ret = (*zclient->interface_delete) (command, zclient, length);
772 break;
773 case ZEBRA_INTERFACE_ADDRESS_ADD:
774 if (zclient->interface_address_add)
775 ret = (*zclient->interface_address_add) (command, zclient, length);
776 break;
777 case ZEBRA_INTERFACE_ADDRESS_DELETE:
778 if (zclient->interface_address_delete)
779 ret = (*zclient->interface_address_delete) (command, zclient, length);
780 break;
781 case ZEBRA_INTERFACE_UP:
782 if (zclient->interface_up)
783 ret = (*zclient->interface_up) (command, zclient, length);
784 break;
785 case ZEBRA_INTERFACE_DOWN:
786 if (zclient->interface_down)
787 ret = (*zclient->interface_down) (command, zclient, length);
788 break;
789 case ZEBRA_IPV4_ROUTE_ADD:
790 if (zclient->ipv4_route_add)
791 ret = (*zclient->ipv4_route_add) (command, zclient, length);
792 break;
793 case ZEBRA_IPV4_ROUTE_DELETE:
794 if (zclient->ipv4_route_delete)
795 ret = (*zclient->ipv4_route_delete) (command, zclient, length);
796 break;
797 case ZEBRA_IPV6_ROUTE_ADD:
798 if (zclient->ipv6_route_add)
799 ret = (*zclient->ipv6_route_add) (command, zclient, length);
800 break;
801 case ZEBRA_IPV6_ROUTE_DELETE:
802 if (zclient->ipv6_route_delete)
803 ret = (*zclient->ipv6_route_delete) (command, zclient, length);
804 break;
805 default:
806 break;
807 }
808
809 /* Register read thread. */
810 zclient_event (ZCLIENT_READ, zclient);
811
812 return 0;
813}
814
815void
816zclient_redistribute_set (struct zclient *zclient, int type)
817{
818 if (zclient->redist[type])
819 return;
820
821 zclient->redist[type] = 1;
822
823 if (zclient->sock > 0)
824 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
825}
826
827void
828zclient_redistribute_unset (struct zclient *zclient, int type)
829{
830 if (! zclient->redist[type])
831 return;
832
833 zclient->redist[type] = 0;
834
835 if (zclient->sock > 0)
836 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
837}
838
839void
840zclient_redistribute_default_set (struct zclient *zclient)
841{
842 if (zclient->default_information)
843 return;
844
845 zclient->default_information = 1;
846
847 if (zclient->sock > 0)
848 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
849}
850
851void
852zclient_redistribute_default_unset (struct zclient *zclient)
853{
854 if (! zclient->default_information)
855 return;
856
857 zclient->default_information = 0;
858
859 if (zclient->sock > 0)
860 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE);
861}
862
863extern struct thread_master *master;
864
865static void
866zclient_event (enum event event, struct zclient *zclient)
867{
868 switch (event)
869 {
870 case ZCLIENT_SCHEDULE:
871 if (! zclient->t_connect)
872 zclient->t_connect =
873 thread_add_event (master, zclient_connect, zclient, 0);
874 break;
875 case ZCLIENT_CONNECT:
876 if (zclient->fail >= 10)
877 return;
878 if (zclient_debug)
879 zlog_info ("zclient connect schedule interval is %d",
880 zclient->fail < 3 ? 10 : 60);
881 if (! zclient->t_connect)
882 zclient->t_connect =
883 thread_add_timer (master, zclient_connect, zclient,
884 zclient->fail < 3 ? 10 : 60);
885 break;
886 case ZCLIENT_READ:
887 zclient->t_read =
888 thread_add_read (master, zclient_read, zclient, zclient->sock);
889 break;
890 }
891}