1 /* Zebra's client library.
2 * Copyright (C) 1999 Kunihiro Ishiguro
3 * Copyright (C) 2005 Andrew J. Schorr
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
36 /* Zebra client events. */
37 enum event
{ZCLIENT_SCHEDULE
, ZCLIENT_READ
, ZCLIENT_CONNECT
};
39 /* Prototype for event manager. */
40 static void zclient_event (enum event
, struct zclient
*);
42 extern struct thread_master
*master
;
44 /* This file local debug flag. */
45 int zclient_debug
= 0;
47 /* Allocate zclient structure. */
51 struct zclient
*zclient
;
52 zclient
= XMALLOC (MTYPE_ZCLIENT
, sizeof (struct zclient
));
53 memset (zclient
, 0, sizeof (struct zclient
));
55 zclient
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
56 zclient
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
57 zclient
->wb
= buffer_new(0);
63 /* This function is never used. And it must not be used, because
64 many parts of the code do not check for I/O errors, so they could
65 reference an invalid pointer if the structure was ever freed.
68 /* Free zclient structure. */
70 zclient_free (struct zclient
*zclient
)
73 stream_free(zclient
->ibuf
);
75 stream_free(zclient
->obuf
);
77 buffer_free(zclient
->wb
);
79 XFREE (MTYPE_ZCLIENT
, zclient
);
83 /* Initialize zebra client. Argument redist_default is unwanted
84 redistribute route type. */
86 zclient_init (struct zclient
*zclient
, int redist_default
)
90 /* Enable zebra client connection by default. */
93 /* Set -1 to the default socket value. */
96 /* Clear redistribution flags. */
97 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
98 zclient
->redist
[i
] = 0;
100 /* Set unwanted redistribute route. bgpd does not need BGP route
102 zclient
->redist_default
= redist_default
;
103 zclient
->redist
[redist_default
] = 1;
105 /* Set default-information redistribute to zero. */
106 zclient
->default_information
= 0;
108 /* Schedule first zclient connection. */
110 zlog_debug ("zclient start scheduled");
112 zclient_event (ZCLIENT_SCHEDULE
, zclient
);
115 /* Stop zebra client services. */
117 zclient_stop (struct zclient
*zclient
)
120 zlog_debug ("zclient stopped");
123 THREAD_OFF(zclient
->t_read
);
124 THREAD_OFF(zclient
->t_connect
);
125 THREAD_OFF(zclient
->t_write
);
128 stream_reset(zclient
->ibuf
);
129 stream_reset(zclient
->obuf
);
131 /* Empty the write buffer. */
132 buffer_reset(zclient
->wb
);
135 if (zclient
->sock
>= 0)
137 close (zclient
->sock
);
144 zclient_reset (struct zclient
*zclient
)
146 zclient_stop (zclient
);
147 zclient_init (zclient
, zclient
->redist_default
);
150 /* Make socket to zebra daemon. Return zebra socket. */
156 struct sockaddr_in serv
;
158 /* We should think about IPv6 connection. */
159 sock
= socket (AF_INET
, SOCK_STREAM
, 0);
163 /* Make server socket. */
164 memset (&serv
, 0, sizeof (struct sockaddr_in
));
165 serv
.sin_family
= AF_INET
;
166 serv
.sin_port
= htons (ZEBRA_PORT
);
168 serv
.sin_len
= sizeof (struct sockaddr_in
);
169 #endif /* HAVE_SIN_LEN */
170 serv
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
172 /* Connect to zebra. */
173 ret
= connect (sock
, (struct sockaddr
*) &serv
, sizeof (serv
));
182 /* For sockaddr_un. */
186 zclient_socket_un (const char *path
)
190 struct sockaddr_un addr
;
192 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
196 /* Make server socket. */
197 memset (&addr
, 0, sizeof (struct sockaddr_un
));
198 addr
.sun_family
= AF_UNIX
;
199 strncpy (addr
.sun_path
, path
, strlen (path
));
201 len
= addr
.sun_len
= SUN_LEN(&addr
);
203 len
= sizeof (addr
.sun_family
) + strlen (addr
.sun_path
);
204 #endif /* HAVE_SUN_LEN */
206 ret
= connect (sock
, (struct sockaddr
*) &addr
, len
);
216 zclient_failed(struct zclient
*zclient
)
219 zclient_stop(zclient
);
220 zclient_event(ZCLIENT_CONNECT
, zclient
);
225 zclient_flush_data(struct thread
*thread
)
227 struct zclient
*zclient
= THREAD_ARG(thread
);
229 zclient
->t_write
= NULL
;
230 if (zclient
->sock
< 0)
232 switch (buffer_flush_available(zclient
->wb
, zclient
->sock
))
235 zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
236 __func__
, zclient
->sock
);
237 return zclient_failed(zclient
);
240 zclient
->t_write
= thread_add_write(master
, zclient_flush_data
,
241 zclient
, zclient
->sock
);
250 zclient_send_message(struct zclient
*zclient
)
252 if (zclient
->sock
< 0)
254 switch (buffer_write(zclient
->wb
, zclient
->sock
, STREAM_DATA(zclient
->obuf
),
255 stream_get_endp(zclient
->obuf
)))
258 zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
259 __func__
, zclient
->sock
);
260 return zclient_failed(zclient
);
263 THREAD_OFF(zclient
->t_write
);
266 THREAD_WRITE_ON(master
, zclient
->t_write
,
267 zclient_flush_data
, zclient
, zclient
->sock
);
274 zclient_create_header (struct stream
*s
, uint16_t command
)
276 /* length placeholder, caller can update */
277 stream_putw (s
, ZEBRA_HEADER_SIZE
);
278 stream_putc (s
, ZEBRA_HEADER_MARKER
);
279 stream_putc (s
, ZSERV_VERSION
);
280 stream_putw (s
, command
);
283 /* Send simple Zebra message. */
285 zebra_message_send (struct zclient
*zclient
, int command
)
289 /* Get zclient output buffer. */
293 /* Send very simple command only Zebra message. */
294 zclient_create_header (s
, command
);
296 return zclient_send_message(zclient
);
299 /* Make connection to zebra daemon. */
301 zclient_start (struct zclient
*zclient
)
306 zlog_debug ("zclient_start is called");
308 /* zclient is disabled. */
309 if (! zclient
->enable
)
312 /* If already connected to the zebra. */
313 if (zclient
->sock
>= 0)
316 /* Check connect thread. */
317 if (zclient
->t_connect
)
321 #ifdef HAVE_TCP_ZEBRA
322 zclient
->sock
= zclient_socket ();
324 zclient
->sock
= zclient_socket_un (ZEBRA_SERV_PATH
);
325 #endif /* HAVE_TCP_ZEBRA */
326 if (zclient
->sock
< 0)
329 zlog_debug ("zclient connection fail");
331 zclient_event (ZCLIENT_CONNECT
, zclient
);
335 if (set_nonblocking(zclient
->sock
) < 0)
336 zlog_warn("%s: set_nonblocking(%d) failed", __func__
, zclient
->sock
);
338 /* Clear fail count. */
341 zlog_debug ("zclient connect success with socket [%d]", zclient
->sock
);
343 /* Create read thread. */
344 zclient_event (ZCLIENT_READ
, zclient
);
346 /* We need interface information. */
347 zebra_message_send (zclient
, ZEBRA_INTERFACE_ADD
);
349 /* We need router-id information. */
350 zebra_message_send (zclient
, ZEBRA_ROUTER_ID_ADD
);
352 /* Flush all redistribute request. */
353 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
354 if (i
!= zclient
->redist_default
&& zclient
->redist
[i
])
355 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, i
);
357 /* If default information is needed. */
358 if (zclient
->default_information
)
359 zebra_message_send (zclient
, ZEBRA_REDISTRIBUTE_DEFAULT_ADD
);
364 /* This function is a wrapper function for calling zclient_start from
365 timer or event thread. */
367 zclient_connect (struct thread
*t
)
369 struct zclient
*zclient
;
371 zclient
= THREAD_ARG (t
);
372 zclient
->t_connect
= NULL
;
375 zlog_debug ("zclient_connect is called");
377 return zclient_start (zclient
);
381 * "xdr_encode"-like interface that allows daemon (client) to send
382 * a message to zebra server for a route that needs to be
383 * added/deleted to the kernel. Info about the route is specified
384 * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
385 * the info down the zclient socket using the stream_* functions.
387 * The corresponding read ("xdr_decode") function on the server
388 * side is zread_ipv4_add()/zread_ipv4_delete().
390 * 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
391 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
392 * | Length (2) | Command | Route Type |
393 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
394 * | ZEBRA Flags | Message Flags | Prefix length |
395 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
396 * | Destination IPv4 Prefix for route |
397 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
402 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
403 * described, as per the Nexthop count. Each nexthop described as:
406 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
407 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
408 * | IPv4 Nexthop address or Interface Index number |
409 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
411 * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
412 * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_
413 * nexthop information is provided, and the message describes a prefix
414 * to blackhole or reject route.
416 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
419 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
422 * XXX: No attention paid to alignment.
425 zapi_ipv4_route (u_char cmd
, struct zclient
*zclient
, struct prefix_ipv4
*p
,
426 struct zapi_ipv4
*api
)
436 zclient_create_header (s
, cmd
);
438 /* Put type and nexthop. */
439 stream_putc (s
, api
->type
);
440 stream_putc (s
, api
->flags
);
441 stream_putc (s
, api
->message
);
443 /* Put prefix information. */
444 psize
= PSIZE (p
->prefixlen
);
445 stream_putc (s
, p
->prefixlen
);
446 stream_write (s
, (u_char
*) & p
->prefix
, psize
);
448 /* Nexthop, ifindex, distance and metric information. */
449 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_NEXTHOP
))
451 if (CHECK_FLAG (api
->flags
, ZEBRA_FLAG_BLACKHOLE
))
454 stream_putc (s
, ZEBRA_NEXTHOP_BLACKHOLE
);
455 /* XXX assert(api->nexthop_num == 0); */
456 /* XXX assert(api->ifindex_num == 0); */
459 stream_putc (s
, api
->nexthop_num
+ api
->ifindex_num
);
461 for (i
= 0; i
< api
->nexthop_num
; i
++)
463 stream_putc (s
, ZEBRA_NEXTHOP_IPV4
);
464 stream_put_in_addr (s
, api
->nexthop
[i
]);
466 for (i
= 0; i
< api
->ifindex_num
; i
++)
468 stream_putc (s
, ZEBRA_NEXTHOP_IFINDEX
);
469 stream_putl (s
, api
->ifindex
[i
]);
473 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_DISTANCE
))
474 stream_putc (s
, api
->distance
);
475 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_METRIC
))
476 stream_putl (s
, api
->metric
);
478 /* Put length at the first point of the stream. */
479 stream_putw_at (s
, 0, stream_get_endp (s
));
481 return zclient_send_message(zclient
);
486 zapi_ipv6_route (u_char cmd
, struct zclient
*zclient
, struct prefix_ipv6
*p
,
487 struct zapi_ipv6
*api
)
497 zclient_create_header (s
, cmd
);
499 /* Put type and nexthop. */
500 stream_putc (s
, api
->type
);
501 stream_putc (s
, api
->flags
);
502 stream_putc (s
, api
->message
);
504 /* Put prefix information. */
505 psize
= PSIZE (p
->prefixlen
);
506 stream_putc (s
, p
->prefixlen
);
507 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
509 /* Nexthop, ifindex, distance and metric information. */
510 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_NEXTHOP
))
512 stream_putc (s
, api
->nexthop_num
+ api
->ifindex_num
);
514 for (i
= 0; i
< api
->nexthop_num
; i
++)
516 stream_putc (s
, ZEBRA_NEXTHOP_IPV6
);
517 stream_write (s
, (u_char
*)api
->nexthop
[i
], 16);
519 for (i
= 0; i
< api
->ifindex_num
; i
++)
521 stream_putc (s
, ZEBRA_NEXTHOP_IFINDEX
);
522 stream_putl (s
, api
->ifindex
[i
]);
526 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_DISTANCE
))
527 stream_putc (s
, api
->distance
);
528 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_METRIC
))
529 stream_putl (s
, api
->metric
);
531 /* Put length at the first point of the stream. */
532 stream_putw_at (s
, 0, stream_get_endp (s
));
534 return zclient_send_message(zclient
);
536 #endif /* HAVE_IPV6 */
539 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
540 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
541 * then set/unset redist[type] in the client handle (a struct zserv) for the
545 zebra_redistribute_send (int command
, struct zclient
*zclient
, int type
)
552 zclient_create_header (s
, command
);
553 stream_putc (s
, type
);
555 stream_putw_at (s
, 0, stream_get_endp (s
));
557 return zclient_send_message(zclient
);
560 /* Router-id update from zebra daemon. */
562 zebra_router_id_update_read (struct stream
*s
, struct prefix
*rid
)
566 /* Fetch interface address. */
567 rid
->family
= stream_getc (s
);
569 plen
= prefix_blen (rid
);
570 stream_get (&rid
->u
.prefix
, s
, plen
);
571 rid
->prefixlen
= stream_getc (s
);
574 /* Interface addition from zebra daemon. */
576 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
577 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
579 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
582 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
588 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
590 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
593 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
595 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
597 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
599 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
601 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
603 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
607 zebra_interface_add_read (struct stream
*s
)
609 struct interface
*ifp
;
610 char ifname_tmp
[INTERFACE_NAMSIZ
];
612 /* Read interface name. */
613 stream_get (ifname_tmp
, s
, INTERFACE_NAMSIZ
);
615 /* Lookup/create interface by name. */
616 ifp
= if_get_by_name_len (ifname_tmp
, strnlen(ifname_tmp
, INTERFACE_NAMSIZ
));
618 /* Read interface's index. */
619 ifp
->ifindex
= stream_getl (s
);
621 /* Read interface's value. */
622 ifp
->status
= stream_getc (s
);
623 ifp
->flags
= stream_getq (s
);
624 ifp
->metric
= stream_getl (s
);
625 ifp
->mtu
= stream_getl (s
);
626 ifp
->mtu6
= stream_getl (s
);
627 ifp
->bandwidth
= stream_getl (s
);
628 #ifdef HAVE_SOCKADDR_DL
629 stream_get (&ifp
->sdl
, s
, sizeof (ifp
->sdl
));
631 ifp
->hw_addr_len
= stream_getl (s
);
632 if (ifp
->hw_addr_len
)
633 stream_get (ifp
->hw_addr
, s
, ifp
->hw_addr_len
);
634 #endif /* HAVE_SOCKADDR_DL */
640 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
641 * from zebra server. The format of this message is the same as
642 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
643 * comments for zebra_interface_add_read), except that no sockaddr_dl
644 * is sent at the tail of the message.
647 zebra_interface_state_read (struct stream
*s
)
649 struct interface
*ifp
;
650 char ifname_tmp
[INTERFACE_NAMSIZ
];
652 /* Read interface name. */
653 stream_get (ifname_tmp
, s
, INTERFACE_NAMSIZ
);
655 /* Lookup this by interface index. */
656 ifp
= if_lookup_by_name_len (ifname_tmp
,
657 strnlen(ifname_tmp
, INTERFACE_NAMSIZ
));
659 /* If such interface does not exist, indicate an error */
663 /* Read interface's index. */
664 ifp
->ifindex
= stream_getl (s
);
666 /* Read interface's value. */
667 ifp
->status
= stream_getc (s
);
668 ifp
->flags
= stream_getq (s
);
669 ifp
->metric
= stream_getl (s
);
670 ifp
->mtu
= stream_getl (s
);
671 ifp
->mtu6
= stream_getl (s
);
672 ifp
->bandwidth
= stream_getl (s
);
678 * format of message for address additon is:
682 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
683 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
692 * | ifc_flags | flags for connected address
700 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
710 zebra_interface_if_set_value (struct stream
*s
, struct interface
*ifp
)
712 /* Read interface's index. */
713 ifp
->ifindex
= stream_getl (s
);
714 ifp
->status
= stream_getc (s
);
716 /* Read interface's value. */
717 ifp
->flags
= stream_getq (s
);
718 ifp
->metric
= stream_getl (s
);
719 ifp
->mtu
= stream_getl (s
);
720 ifp
->mtu6
= stream_getl (s
);
721 ifp
->bandwidth
= stream_getl (s
);
725 memconstant(const void *s
, int c
, size_t n
)
736 zebra_interface_address_read (int type
, struct stream
*s
)
738 unsigned int ifindex
;
739 struct interface
*ifp
;
740 struct connected
*ifc
;
746 memset (&p
, 0, sizeof(p
));
747 memset (&d
, 0, sizeof(d
));
749 /* Get interface index. */
750 ifindex
= stream_getl (s
);
753 ifp
= if_lookup_by_index (ifindex
);
756 zlog_warn ("zebra_interface_address_read(%s): "
757 "Can't find interface by ifindex: %d ",
758 (type
== ZEBRA_INTERFACE_ADDRESS_ADD
? "ADD" : "DELETE"),
764 ifc_flags
= stream_getc (s
);
766 /* Fetch interface address. */
767 family
= p
.family
= stream_getc (s
);
769 plen
= prefix_blen (&p
);
770 stream_get (&p
.u
.prefix
, s
, plen
);
771 p
.prefixlen
= stream_getc (s
);
773 /* Fetch destination address. */
774 stream_get (&d
.u
.prefix
, s
, plen
);
777 if (type
== ZEBRA_INTERFACE_ADDRESS_ADD
)
779 /* N.B. NULL destination pointers are encoded as all zeroes */
780 ifc
= connected_add_by_prefix(ifp
, &p
,(memconstant(&d
.u
.prefix
,0,plen
) ?
783 ifc
->flags
= ifc_flags
;
787 assert (type
== ZEBRA_INTERFACE_ADDRESS_DELETE
);
788 ifc
= connected_delete_by_prefix(ifp
, &p
);
795 /* Zebra client message read function. */
797 zclient_read (struct thread
*thread
)
801 uint16_t length
, command
;
802 uint8_t marker
, version
;
803 struct zclient
*zclient
;
805 /* Get socket to zebra. */
806 zclient
= THREAD_ARG (thread
);
807 zclient
->t_read
= NULL
;
809 /* Read zebra header (if we don't have it already). */
810 if ((already
= stream_get_endp(zclient
->ibuf
)) < ZEBRA_HEADER_SIZE
)
813 if (((nbyte
= stream_read_try(zclient
->ibuf
, zclient
->sock
,
814 ZEBRA_HEADER_SIZE
-already
)) == 0) ||
818 zlog_debug ("zclient connection closed socket [%d].", zclient
->sock
);
819 return zclient_failed(zclient
);
821 if (nbyte
!= (ssize_t
)(ZEBRA_HEADER_SIZE
-already
))
823 /* Try again later. */
824 zclient_event (ZCLIENT_READ
, zclient
);
827 already
= ZEBRA_HEADER_SIZE
;
830 /* Reset to read from the beginning of the incoming packet. */
831 stream_set_getp(zclient
->ibuf
, 0);
833 /* Fetch header values. */
834 length
= stream_getw (zclient
->ibuf
);
835 marker
= stream_getc (zclient
->ibuf
);
836 version
= stream_getc (zclient
->ibuf
);
837 command
= stream_getw (zclient
->ibuf
);
839 if (marker
!= ZEBRA_HEADER_MARKER
|| version
!= ZSERV_VERSION
)
841 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
842 __func__
, zclient
->sock
, marker
, version
);
843 return zclient_failed(zclient
);
846 if (length
< ZEBRA_HEADER_SIZE
)
848 zlog_err("%s: socket %d message length %u is less than %d ",
849 __func__
, zclient
->sock
, length
, ZEBRA_HEADER_SIZE
);
850 return zclient_failed(zclient
);
854 if (length
> STREAM_SIZE(zclient
->ibuf
))
857 zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
858 __func__
, length
, (u_long
)STREAM_SIZE(zclient
->ibuf
));
859 ns
= stream_new(length
);
860 stream_copy(ns
, zclient
->ibuf
);
861 stream_free (zclient
->ibuf
);
865 /* Read rest of zebra packet. */
866 if (already
< length
)
869 if (((nbyte
= stream_read_try(zclient
->ibuf
, zclient
->sock
,
870 length
-already
)) == 0) ||
874 zlog_debug("zclient connection closed socket [%d].", zclient
->sock
);
875 return zclient_failed(zclient
);
877 if (nbyte
!= (ssize_t
)(length
-already
))
879 /* Try again later. */
880 zclient_event (ZCLIENT_READ
, zclient
);
885 length
-= ZEBRA_HEADER_SIZE
;
888 zlog_debug("zclient 0x%p command 0x%x \n", zclient
, command
);
892 case ZEBRA_ROUTER_ID_UPDATE
:
893 if (zclient
->router_id_update
)
894 ret
= (*zclient
->router_id_update
) (command
, zclient
, length
);
896 case ZEBRA_INTERFACE_ADD
:
897 if (zclient
->interface_add
)
898 ret
= (*zclient
->interface_add
) (command
, zclient
, length
);
900 case ZEBRA_INTERFACE_DELETE
:
901 if (zclient
->interface_delete
)
902 ret
= (*zclient
->interface_delete
) (command
, zclient
, length
);
904 case ZEBRA_INTERFACE_ADDRESS_ADD
:
905 if (zclient
->interface_address_add
)
906 ret
= (*zclient
->interface_address_add
) (command
, zclient
, length
);
908 case ZEBRA_INTERFACE_ADDRESS_DELETE
:
909 if (zclient
->interface_address_delete
)
910 ret
= (*zclient
->interface_address_delete
) (command
, zclient
, length
);
912 case ZEBRA_INTERFACE_UP
:
913 if (zclient
->interface_up
)
914 ret
= (*zclient
->interface_up
) (command
, zclient
, length
);
916 case ZEBRA_INTERFACE_DOWN
:
917 if (zclient
->interface_down
)
918 ret
= (*zclient
->interface_down
) (command
, zclient
, length
);
920 case ZEBRA_IPV4_ROUTE_ADD
:
921 if (zclient
->ipv4_route_add
)
922 ret
= (*zclient
->ipv4_route_add
) (command
, zclient
, length
);
924 case ZEBRA_IPV4_ROUTE_DELETE
:
925 if (zclient
->ipv4_route_delete
)
926 ret
= (*zclient
->ipv4_route_delete
) (command
, zclient
, length
);
928 case ZEBRA_IPV6_ROUTE_ADD
:
929 if (zclient
->ipv6_route_add
)
930 ret
= (*zclient
->ipv6_route_add
) (command
, zclient
, length
);
932 case ZEBRA_IPV6_ROUTE_DELETE
:
933 if (zclient
->ipv6_route_delete
)
934 ret
= (*zclient
->ipv6_route_delete
) (command
, zclient
, length
);
940 if (zclient
->sock
< 0)
941 /* Connection was closed during packet processing. */
944 /* Register read thread. */
945 stream_reset(zclient
->ibuf
);
946 zclient_event (ZCLIENT_READ
, zclient
);
952 zclient_redistribute (int command
, struct zclient
*zclient
, int type
)
955 if (command
== ZEBRA_REDISTRIBUTE_ADD
)
957 if (zclient
->redist
[type
])
959 zclient
->redist
[type
] = 1;
963 if (!zclient
->redist
[type
])
965 zclient
->redist
[type
] = 0;
968 if (zclient
->sock
> 0)
969 zebra_redistribute_send (command
, zclient
, type
);
974 zclient_redistribute_default (int command
, struct zclient
*zclient
)
977 if (command
== ZEBRA_REDISTRIBUTE_DEFAULT_ADD
)
979 if (zclient
->default_information
)
981 zclient
->default_information
= 1;
985 if (!zclient
->default_information
)
987 zclient
->default_information
= 0;
990 if (zclient
->sock
> 0)
991 zebra_message_send (zclient
, command
);
995 zclient_event (enum event event
, struct zclient
*zclient
)
999 case ZCLIENT_SCHEDULE
:
1000 if (! zclient
->t_connect
)
1001 zclient
->t_connect
=
1002 thread_add_event (master
, zclient_connect
, zclient
, 0);
1004 case ZCLIENT_CONNECT
:
1005 if (zclient
->fail
>= 10)
1008 zlog_debug ("zclient connect schedule interval is %d",
1009 zclient
->fail
< 3 ? 10 : 60);
1010 if (! zclient
->t_connect
)
1011 zclient
->t_connect
=
1012 thread_add_timer (master
, zclient_connect
, zclient
,
1013 zclient
->fail
< 3 ? 10 : 60);
1017 thread_add_read (master
, zclient_read
, zclient
, zclient
->sock
);