blob: c1b286f400184dcc4e616c0da0f402f5ff1e60b6 [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 {
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. */
paul2e3b2e42002-12-13 21:03:13 +0000567 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000568 ifp->flags = stream_getl (s);
569 ifp->metric = stream_getl (s);
570 ifp->mtu = stream_getl (s);
571 ifp->bandwidth = stream_getl (s);
572#ifdef HAVE_SOCKADDR_DL
573 stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
574#else
575 ifp->hw_addr_len = stream_getl (s);
576 if (ifp->hw_addr_len)
577 stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
578#endif /* HAVE_SOCKADDR_DL */
579
580 return ifp;
581}
582
583/* Read interface up/down msg from zebra daemon. */
584struct interface *
585zebra_interface_state_read (struct stream *s)
586{
587 struct interface *ifp;
588 u_char ifname_tmp[INTERFACE_NAMSIZ];
589
590 /* Read interface name. */
591 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
592
593 /* Lookup this by interface index. */
594 ifp = if_lookup_by_name (ifname_tmp);
595
596 /* If such interface does not exist, indicate an error */
597 if (! ifp)
598 return NULL;
599
600 /* Read interface's index. */
601 ifp->ifindex = stream_getl (s);
602
603 /* Read interface's value. */
paul2e3b2e42002-12-13 21:03:13 +0000604 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000605 ifp->flags = stream_getl (s);
606 ifp->metric = stream_getl (s);
607 ifp->mtu = stream_getl (s);
608 ifp->bandwidth = stream_getl (s);
609
610 return ifp;
611}
612
613struct connected *
614zebra_interface_address_add_read (struct stream *s)
615{
616 unsigned int ifindex;
617 struct interface *ifp;
618 struct connected *ifc;
619 struct prefix *p;
620 int family;
621 int plen;
622
623 /* Get interface index. */
624 ifindex = stream_getl (s);
625
626 /* Lookup index. */
627 ifp = if_lookup_by_index (ifindex);
628 if (ifp == NULL)
629 {
630 zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex);
631 return NULL;
632 }
633
634 /* Allocate new connected address. */
635 ifc = connected_new ();
636 ifc->ifp = ifp;
637
638 /* Fetch flag. */
639 ifc->flags = stream_getc (s);
640
641 /* Fetch interface address. */
642 p = prefix_new ();
643 family = p->family = stream_getc (s);
644
645 plen = prefix_blen (p);
646 stream_get (&p->u.prefix, s, plen);
647 p->prefixlen = stream_getc (s);
648 ifc->address = p;
649
650 /* Fetch destination address. */
651 p = prefix_new ();
652 stream_get (&p->u.prefix, s, plen);
653 p->family = family;
654
655 ifc->destination = p;
656
657 p = ifc->address;
658
659 /* Add connected address to the interface. */
660 listnode_add (ifp->connected, ifc);
661
662 return ifc;
663}
664
665struct connected *
666zebra_interface_address_delete_read (struct stream *s)
667{
668 unsigned int ifindex;
669 struct interface *ifp;
670 struct connected *ifc;
671 struct prefix p;
672 struct prefix d;
673 int family;
674 int len;
675 u_char flags;
676
677 /* Get interface index. */
678 ifindex = stream_getl (s);
679
680 /* Lookup index. */
681 ifp = if_lookup_by_index (ifindex);
682 if (ifp == NULL)
683 {
684 zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex);
685 return NULL;
686 }
687
688 /* Fetch flag. */
689 flags = stream_getc (s);
690
691 /* Fetch interface address. */
692 family = p.family = stream_getc (s);
693
694 len = prefix_blen (&p);
695 stream_get (&p.u.prefix, s, len);
696 p.prefixlen = stream_getc (s);
697
698 /* Fetch destination address. */
699 stream_get (&d.u.prefix, s, len);
700 d.family = family;
701
702 ifc = connected_delete_by_prefix (ifp, &p);
703
704 return ifc;
705}
706
707/* Zebra client message read function. */
708int
709zclient_read (struct thread *thread)
710{
711 int ret;
712 int nbytes;
713 int sock;
714 zebra_size_t length;
715 zebra_command_t command;
716 struct zclient *zclient;
717
718 /* Get socket to zebra. */
719 sock = THREAD_FD (thread);
720 zclient = THREAD_ARG (thread);
721 zclient->t_read = NULL;
722
723 /* Clear input buffer. */
724 stream_reset (zclient->ibuf);
725
726 /* Read zebra header. */
727 nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);
728
729 /* zebra socket is closed. */
730 if (nbytes == 0)
731 {
732 if (zclient_debug)
733 zlog_info ("zclient connection closed socket [%d].", sock);
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 if (zclient_debug)
744 zlog_info ("Can't read all packet (length %d).", nbytes);
745 zclient->fail++;
746 zclient_stop (zclient);
747 zclient_event (ZCLIENT_CONNECT, zclient);
748 return -1;
749 }
750
751 /* Fetch length and command. */
752 length = stream_getw (zclient->ibuf);
753 command = stream_getc (zclient->ibuf);
754
755 /* Length check. */
756 if (length >= zclient->ibuf->size)
757 {
758 stream_free (zclient->ibuf);
759 zclient->ibuf = stream_new (length + 1);
760 }
761 length -= ZEBRA_HEADER_SIZE;
762
763 /* Read rest of zebra packet. */
764 nbytes = stream_read (zclient->ibuf, sock, length);
765 if (nbytes != length)
766 {
767 if (zclient_debug)
768 zlog_info ("zclient connection closed socket [%d].", sock);
769 zclient->fail++;
770 zclient_stop (zclient);
771 zclient_event (ZCLIENT_CONNECT, zclient);
772 return -1;
773 }
774
775 switch (command)
776 {
777 case ZEBRA_INTERFACE_ADD:
778 if (zclient->interface_add)
779 ret = (*zclient->interface_add) (command, zclient, length);
780 break;
781 case ZEBRA_INTERFACE_DELETE:
782 if (zclient->interface_delete)
783 ret = (*zclient->interface_delete) (command, zclient, length);
784 break;
785 case ZEBRA_INTERFACE_ADDRESS_ADD:
786 if (zclient->interface_address_add)
787 ret = (*zclient->interface_address_add) (command, zclient, length);
788 break;
789 case ZEBRA_INTERFACE_ADDRESS_DELETE:
790 if (zclient->interface_address_delete)
791 ret = (*zclient->interface_address_delete) (command, zclient, length);
792 break;
793 case ZEBRA_INTERFACE_UP:
794 if (zclient->interface_up)
795 ret = (*zclient->interface_up) (command, zclient, length);
796 break;
797 case ZEBRA_INTERFACE_DOWN:
798 if (zclient->interface_down)
799 ret = (*zclient->interface_down) (command, zclient, length);
800 break;
801 case ZEBRA_IPV4_ROUTE_ADD:
802 if (zclient->ipv4_route_add)
803 ret = (*zclient->ipv4_route_add) (command, zclient, length);
804 break;
805 case ZEBRA_IPV4_ROUTE_DELETE:
806 if (zclient->ipv4_route_delete)
807 ret = (*zclient->ipv4_route_delete) (command, zclient, length);
808 break;
809 case ZEBRA_IPV6_ROUTE_ADD:
810 if (zclient->ipv6_route_add)
811 ret = (*zclient->ipv6_route_add) (command, zclient, length);
812 break;
813 case ZEBRA_IPV6_ROUTE_DELETE:
814 if (zclient->ipv6_route_delete)
815 ret = (*zclient->ipv6_route_delete) (command, zclient, length);
816 break;
817 default:
818 break;
819 }
820
821 /* Register read thread. */
822 zclient_event (ZCLIENT_READ, zclient);
823
824 return 0;
825}
826
827void
828zclient_redistribute_set (struct zclient *zclient, int type)
829{
830 if (zclient->redist[type])
831 return;
832
833 zclient->redist[type] = 1;
834
835 if (zclient->sock > 0)
836 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
837}
838
839void
840zclient_redistribute_unset (struct zclient *zclient, int type)
841{
842 if (! zclient->redist[type])
843 return;
844
845 zclient->redist[type] = 0;
846
847 if (zclient->sock > 0)
848 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
849}
850
851void
852zclient_redistribute_default_set (struct zclient *zclient)
853{
854 if (zclient->default_information)
855 return;
856
857 zclient->default_information = 1;
858
859 if (zclient->sock > 0)
860 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
861}
862
863void
864zclient_redistribute_default_unset (struct zclient *zclient)
865{
866 if (! zclient->default_information)
867 return;
868
869 zclient->default_information = 0;
870
871 if (zclient->sock > 0)
872 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE);
873}
874
875extern struct thread_master *master;
876
877static void
878zclient_event (enum event event, struct zclient *zclient)
879{
880 switch (event)
881 {
882 case ZCLIENT_SCHEDULE:
883 if (! zclient->t_connect)
884 zclient->t_connect =
885 thread_add_event (master, zclient_connect, zclient, 0);
886 break;
887 case ZCLIENT_CONNECT:
888 if (zclient->fail >= 10)
889 return;
890 if (zclient_debug)
891 zlog_info ("zclient connect schedule interval is %d",
892 zclient->fail < 3 ? 10 : 60);
893 if (! zclient->t_connect)
894 zclient->t_connect =
895 thread_add_timer (master, zclient_connect, zclient,
896 zclient->fail < 3 ? 10 : 60);
897 break;
898 case ZCLIENT_READ:
899 zclient->t_read =
900 thread_add_read (master, zclient_read, zclient, zclient->sock);
901 break;
902 }
903}