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