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
= XCALLOC (MTYPE_ZCLIENT
, sizeof (struct zclient
));
54 zclient
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
55 zclient
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
56 zclient
->wb
= buffer_new(0);
61 /* This function is only called when exiting, because
62 many parts of the code do not check for I/O errors, so they could
63 reference an invalid pointer if the structure was ever freed.
65 Free zclient structure. */
67 zclient_free (struct zclient
*zclient
)
70 stream_free(zclient
->ibuf
);
72 stream_free(zclient
->obuf
);
74 buffer_free(zclient
->wb
);
76 XFREE (MTYPE_ZCLIENT
, zclient
);
79 /* Initialize zebra client. Argument redist_default is unwanted
80 redistribute route type. */
82 zclient_init (struct zclient
*zclient
, int redist_default
)
86 /* Enable zebra client connection by default. */
89 /* Set -1 to the default socket value. */
92 /* Clear redistribution flags. */
93 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
94 zclient
->redist
[i
] = 0;
96 /* Set unwanted redistribute route. bgpd does not need BGP route
98 zclient
->redist_default
= redist_default
;
99 zclient
->redist
[redist_default
] = 1;
101 /* Set default-information redistribute to zero. */
102 zclient
->default_information
= 0;
104 /* Schedule first zclient connection. */
106 zlog_debug ("zclient start scheduled");
108 zclient_event (ZCLIENT_SCHEDULE
, zclient
);
111 /* Stop zebra client services. */
113 zclient_stop (struct zclient
*zclient
)
116 zlog_debug ("zclient stopped");
119 THREAD_OFF(zclient
->t_read
);
120 THREAD_OFF(zclient
->t_connect
);
121 THREAD_OFF(zclient
->t_write
);
124 stream_reset(zclient
->ibuf
);
125 stream_reset(zclient
->obuf
);
127 /* Empty the write buffer. */
128 buffer_reset(zclient
->wb
);
131 if (zclient
->sock
>= 0)
133 close (zclient
->sock
);
140 zclient_reset (struct zclient
*zclient
)
142 zclient_stop (zclient
);
143 zclient_init (zclient
, zclient
->redist_default
);
146 /* Make socket to zebra daemon. Return zebra socket. */
152 struct sockaddr_in serv
;
154 /* We should think about IPv6 connection. */
155 sock
= socket (AF_INET
, SOCK_STREAM
, 0);
159 /* Make server socket. */
160 memset (&serv
, 0, sizeof (struct sockaddr_in
));
161 serv
.sin_family
= AF_INET
;
162 serv
.sin_port
= htons (ZEBRA_PORT
);
163 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
164 serv
.sin_len
= sizeof (struct sockaddr_in
);
165 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
166 serv
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
168 /* Connect to zebra. */
169 ret
= connect (sock
, (struct sockaddr
*) &serv
, sizeof (serv
));
178 /* For sockaddr_un. */
182 zclient_socket_un (const char *path
)
186 struct sockaddr_un addr
;
188 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
192 /* Make server socket. */
193 memset (&addr
, 0, sizeof (struct sockaddr_un
));
194 addr
.sun_family
= AF_UNIX
;
195 strncpy (addr
.sun_path
, path
, strlen (path
));
196 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
197 len
= addr
.sun_len
= SUN_LEN(&addr
);
199 len
= sizeof (addr
.sun_family
) + strlen (addr
.sun_path
);
200 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
202 ret
= connect (sock
, (struct sockaddr
*) &addr
, len
);
212 zclient_failed(struct zclient
*zclient
)
215 zclient_stop(zclient
);
216 zclient_event(ZCLIENT_CONNECT
, zclient
);
221 zclient_flush_data(struct thread
*thread
)
223 struct zclient
*zclient
= THREAD_ARG(thread
);
225 zclient
->t_write
= NULL
;
226 if (zclient
->sock
< 0)
228 switch (buffer_flush_available(zclient
->wb
, zclient
->sock
))
231 zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
232 __func__
, zclient
->sock
);
233 return zclient_failed(zclient
);
236 zclient
->t_write
= thread_add_write(master
, zclient_flush_data
,
237 zclient
, zclient
->sock
);
246 zclient_send_message(struct zclient
*zclient
)
248 if (zclient
->sock
< 0)
250 switch (buffer_write(zclient
->wb
, zclient
->sock
, STREAM_DATA(zclient
->obuf
),
251 stream_get_endp(zclient
->obuf
)))
254 zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
255 __func__
, zclient
->sock
);
256 return zclient_failed(zclient
);
259 THREAD_OFF(zclient
->t_write
);
262 THREAD_WRITE_ON(master
, zclient
->t_write
,
263 zclient_flush_data
, zclient
, zclient
->sock
);
270 zclient_create_header (struct stream
*s
, uint16_t command
)
272 /* length placeholder, caller can update */
273 stream_putw (s
, ZEBRA_HEADER_SIZE
);
274 stream_putc (s
, ZEBRA_HEADER_MARKER
);
275 stream_putc (s
, ZSERV_VERSION
);
276 stream_putw (s
, command
);
279 /* Send simple Zebra message. */
281 zebra_message_send (struct zclient
*zclient
, int command
)
285 /* Get zclient output buffer. */
289 /* Send very simple command only Zebra message. */
290 zclient_create_header (s
, command
);
292 return zclient_send_message(zclient
);
295 /* Make connection to zebra daemon. */
297 zclient_start (struct zclient
*zclient
)
302 zlog_debug ("zclient_start is called");
304 /* zclient is disabled. */
305 if (! zclient
->enable
)
308 /* If already connected to the zebra. */
309 if (zclient
->sock
>= 0)
312 /* Check connect thread. */
313 if (zclient
->t_connect
)
317 #ifdef HAVE_TCP_ZEBRA
318 zclient
->sock
= zclient_socket ();
320 zclient
->sock
= zclient_socket_un (ZEBRA_SERV_PATH
);
321 #endif /* HAVE_TCP_ZEBRA */
322 if (zclient
->sock
< 0)
325 zlog_debug ("zclient connection fail");
327 zclient_event (ZCLIENT_CONNECT
, zclient
);
331 if (set_nonblocking(zclient
->sock
) < 0)
332 zlog_warn("%s: set_nonblocking(%d) failed", __func__
, zclient
->sock
);
334 /* Clear fail count. */
337 zlog_debug ("zclient connect success with socket [%d]", zclient
->sock
);
339 /* Create read thread. */
340 zclient_event (ZCLIENT_READ
, zclient
);
342 /* We need interface information. */
343 zebra_message_send (zclient
, ZEBRA_INTERFACE_ADD
);
345 /* We need router-id information. */
346 zebra_message_send (zclient
, ZEBRA_ROUTER_ID_ADD
);
348 /* Flush all redistribute request. */
349 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
350 if (i
!= zclient
->redist_default
&& zclient
->redist
[i
])
351 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, i
);
353 /* If default information is needed. */
354 if (zclient
->default_information
)
355 zebra_message_send (zclient
, ZEBRA_REDISTRIBUTE_DEFAULT_ADD
);
360 /* This function is a wrapper function for calling zclient_start from
361 timer or event thread. */
363 zclient_connect (struct thread
*t
)
365 struct zclient
*zclient
;
367 zclient
= THREAD_ARG (t
);
368 zclient
->t_connect
= NULL
;
371 zlog_debug ("zclient_connect is called");
373 return zclient_start (zclient
);
377 * "xdr_encode"-like interface that allows daemon (client) to send
378 * a message to zebra server for a route that needs to be
379 * added/deleted to the kernel. Info about the route is specified
380 * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
381 * the info down the zclient socket using the stream_* functions.
383 * The corresponding read ("xdr_decode") function on the server
384 * side is zread_ipv4_add()/zread_ipv4_delete().
386 * 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
387 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
388 * | Length (2) | Command | Route Type |
389 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
390 * | ZEBRA Flags | Message Flags | Prefix length |
391 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
392 * | Destination IPv4 Prefix for route |
393 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
398 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
399 * described, as per the Nexthop count. Each nexthop described as:
402 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
403 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
404 * | IPv4 Nexthop address or Interface Index number |
405 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
407 * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
408 * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_
409 * nexthop information is provided, and the message describes a prefix
410 * to blackhole or reject route.
412 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
415 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
418 * XXX: No attention paid to alignment.
421 zapi_ipv4_route (u_char cmd
, struct zclient
*zclient
, struct prefix_ipv4
*p
,
422 struct zapi_ipv4
*api
)
432 zclient_create_header (s
, cmd
);
434 /* Put type and nexthop. */
435 stream_putc (s
, api
->type
);
436 stream_putc (s
, api
->flags
);
437 stream_putc (s
, api
->message
);
439 /* Put prefix information. */
440 psize
= PSIZE (p
->prefixlen
);
441 stream_putc (s
, p
->prefixlen
);
442 stream_write (s
, (u_char
*) & p
->prefix
, psize
);
444 /* Nexthop, ifindex, distance and metric information. */
445 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_NEXTHOP
))
447 if (CHECK_FLAG (api
->flags
, ZEBRA_FLAG_BLACKHOLE
))
450 stream_putc (s
, ZEBRA_NEXTHOP_BLACKHOLE
);
451 /* XXX assert(api->nexthop_num == 0); */
452 /* XXX assert(api->ifindex_num == 0); */
455 stream_putc (s
, api
->nexthop_num
+ api
->ifindex_num
);
457 for (i
= 0; i
< api
->nexthop_num
; i
++)
459 stream_putc (s
, ZEBRA_NEXTHOP_IPV4
);
460 stream_put_in_addr (s
, api
->nexthop
[i
]);
462 for (i
= 0; i
< api
->ifindex_num
; i
++)
464 stream_putc (s
, ZEBRA_NEXTHOP_IFINDEX
);
465 stream_putl (s
, api
->ifindex
[i
]);
469 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_DISTANCE
))
470 stream_putc (s
, api
->distance
);
471 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_METRIC
))
472 stream_putl (s
, api
->metric
);
474 /* Put length at the first point of the stream. */
475 stream_putw_at (s
, 0, stream_get_endp (s
));
477 return zclient_send_message(zclient
);
482 zapi_ipv6_route (u_char cmd
, struct zclient
*zclient
, struct prefix_ipv6
*p
,
483 struct zapi_ipv6
*api
)
493 zclient_create_header (s
, cmd
);
495 /* Put type and nexthop. */
496 stream_putc (s
, api
->type
);
497 stream_putc (s
, api
->flags
);
498 stream_putc (s
, api
->message
);
500 /* Put prefix information. */
501 psize
= PSIZE (p
->prefixlen
);
502 stream_putc (s
, p
->prefixlen
);
503 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
505 /* Nexthop, ifindex, distance and metric information. */
506 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_NEXTHOP
))
508 stream_putc (s
, api
->nexthop_num
+ api
->ifindex_num
);
510 for (i
= 0; i
< api
->nexthop_num
; i
++)
512 stream_putc (s
, ZEBRA_NEXTHOP_IPV6
);
513 stream_write (s
, (u_char
*)api
->nexthop
[i
], 16);
515 for (i
= 0; i
< api
->ifindex_num
; i
++)
517 stream_putc (s
, ZEBRA_NEXTHOP_IFINDEX
);
518 stream_putl (s
, api
->ifindex
[i
]);
522 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_DISTANCE
))
523 stream_putc (s
, api
->distance
);
524 if (CHECK_FLAG (api
->message
, ZAPI_MESSAGE_METRIC
))
525 stream_putl (s
, api
->metric
);
527 /* Put length at the first point of the stream. */
528 stream_putw_at (s
, 0, stream_get_endp (s
));
530 return zclient_send_message(zclient
);
532 #endif /* HAVE_IPV6 */
535 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
536 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
537 * then set/unset redist[type] in the client handle (a struct zserv) for the
541 zebra_redistribute_send (int command
, struct zclient
*zclient
, int type
)
548 zclient_create_header (s
, command
);
549 stream_putc (s
, type
);
551 stream_putw_at (s
, 0, stream_get_endp (s
));
553 return zclient_send_message(zclient
);
556 /* Router-id update from zebra daemon. */
558 zebra_router_id_update_read (struct stream
*s
, struct prefix
*rid
)
562 /* Fetch interface address. */
563 rid
->family
= stream_getc (s
);
565 plen
= prefix_blen (rid
);
566 stream_get (&rid
->u
.prefix
, s
, plen
);
567 rid
->prefixlen
= stream_getc (s
);
570 /* Interface addition from zebra daemon. */
572 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
573 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
575 * 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
578 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
584 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
586 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
589 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
591 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
593 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
595 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
597 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
599 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
603 zebra_interface_add_read (struct stream
*s
)
605 struct interface
*ifp
;
606 char ifname_tmp
[INTERFACE_NAMSIZ
];
608 /* Read interface name. */
609 stream_get (ifname_tmp
, s
, INTERFACE_NAMSIZ
);
611 /* Lookup/create interface by name. */
612 ifp
= if_get_by_name_len (ifname_tmp
, strnlen(ifname_tmp
, INTERFACE_NAMSIZ
));
614 /* Read interface's index. */
615 ifp
->ifindex
= stream_getl (s
);
617 /* Read interface's value. */
618 ifp
->status
= stream_getc (s
);
619 ifp
->flags
= stream_getq (s
);
620 ifp
->metric
= stream_getl (s
);
621 ifp
->mtu
= stream_getl (s
);
622 ifp
->mtu6
= stream_getl (s
);
623 ifp
->bandwidth
= stream_getl (s
);
624 #ifdef HAVE_STRUCT_SOCKADDR_DL
625 stream_get (&ifp
->sdl
, s
, sizeof (ifp
->sdl
));
627 ifp
->hw_addr_len
= stream_getl (s
);
628 if (ifp
->hw_addr_len
)
629 stream_get (ifp
->hw_addr
, s
, ifp
->hw_addr_len
);
630 #endif /* HAVE_STRUCT_SOCKADDR_DL */
636 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
637 * from zebra server. The format of this message is the same as
638 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
639 * comments for zebra_interface_add_read), except that no sockaddr_dl
640 * is sent at the tail of the message.
643 zebra_interface_state_read (struct stream
*s
)
645 struct interface
*ifp
;
646 char ifname_tmp
[INTERFACE_NAMSIZ
];
648 /* Read interface name. */
649 stream_get (ifname_tmp
, s
, INTERFACE_NAMSIZ
);
651 /* Lookup this by interface index. */
652 ifp
= if_lookup_by_name_len (ifname_tmp
,
653 strnlen(ifname_tmp
, INTERFACE_NAMSIZ
));
655 /* If such interface does not exist, indicate an error */
659 /* Read interface's index. */
660 ifp
->ifindex
= stream_getl (s
);
662 /* Read interface's value. */
663 ifp
->status
= stream_getc (s
);
664 ifp
->flags
= stream_getq (s
);
665 ifp
->metric
= stream_getl (s
);
666 ifp
->mtu
= stream_getl (s
);
667 ifp
->mtu6
= stream_getl (s
);
668 ifp
->bandwidth
= stream_getl (s
);
674 * format of message for address additon is:
678 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
679 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
688 * | ifc_flags | flags for connected address
696 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
706 zebra_interface_if_set_value (struct stream
*s
, struct interface
*ifp
)
708 /* Read interface's index. */
709 ifp
->ifindex
= stream_getl (s
);
710 ifp
->status
= stream_getc (s
);
712 /* Read interface's value. */
713 ifp
->flags
= stream_getq (s
);
714 ifp
->metric
= stream_getl (s
);
715 ifp
->mtu
= stream_getl (s
);
716 ifp
->mtu6
= stream_getl (s
);
717 ifp
->bandwidth
= stream_getl (s
);
721 memconstant(const void *s
, int c
, size_t n
)
732 zebra_interface_address_read (int type
, struct stream
*s
)
734 unsigned int ifindex
;
735 struct interface
*ifp
;
736 struct connected
*ifc
;
742 memset (&p
, 0, sizeof(p
));
743 memset (&d
, 0, sizeof(d
));
745 /* Get interface index. */
746 ifindex
= stream_getl (s
);
749 ifp
= if_lookup_by_index (ifindex
);
752 zlog_warn ("zebra_interface_address_read(%s): "
753 "Can't find interface by ifindex: %d ",
754 (type
== ZEBRA_INTERFACE_ADDRESS_ADD
? "ADD" : "DELETE"),
760 ifc_flags
= stream_getc (s
);
762 /* Fetch interface address. */
763 family
= p
.family
= stream_getc (s
);
765 plen
= prefix_blen (&p
);
766 stream_get (&p
.u
.prefix
, s
, plen
);
767 p
.prefixlen
= stream_getc (s
);
769 /* Fetch destination address. */
770 stream_get (&d
.u
.prefix
, s
, plen
);
773 if (type
== ZEBRA_INTERFACE_ADDRESS_ADD
)
775 /* N.B. NULL destination pointers are encoded as all zeroes */
776 ifc
= connected_add_by_prefix(ifp
, &p
,(memconstant(&d
.u
.prefix
,0,plen
) ?
780 ifc
->flags
= ifc_flags
;
781 if (ifc
->destination
)
782 ifc
->destination
->prefixlen
= ifc
->address
->prefixlen
;
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
);