1 /* Zebra daemon server routine.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
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.
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,
19 * Boston, MA 02111-1307, USA.
33 #include "sockunion.h"
40 #include "zebra/zserv.h"
41 #include "zebra/router-id.h"
42 #include "zebra/redistribute.h"
43 #include "zebra/debug.h"
44 #include "zebra/ipforward.h"
46 /* Event list of zebra. */
47 enum event
{ ZEBRA_SERV
, ZEBRA_READ
, ZEBRA_WRITE
};
49 extern struct zebra_t zebrad
;
51 static void zebra_event (enum event event
, int sock
, struct zserv
*client
);
53 extern struct zebra_privs_t zserv_privs
;
55 /* For logging of zebra meesages. */
56 static const char *zebra_command_str
[] =
59 "ZEBRA_INTERFACE_ADD",
60 "ZEBRA_INTERFACE_DELETE",
61 "ZEBRA_INTERFACE_ADDRESS_ADD",
62 "ZEBRA_INTERFACE_ADDRESS_DELETE",
64 "ZEBRA_INTERFACE_DOWN",
65 "ZEBRA_IPV4_ROUTE_ADD",
66 "ZEBRA_IPV4_ROUTE_DELETE",
67 "ZEBRA_IPV6_ROUTE_ADD",
68 "ZEBRA_IPV6_ROUTE_DELETE",
69 "ZEBRA_REDISTRIBUTE_ADD",
70 "ZEBRA_REDISTRIBUTE_DELETE",
71 "ZEBRA_REDISTRIBUTE_DEFAULT_ADD",
72 "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE",
73 "ZEBRA_IPV4_NEXTHOP_LOOKUP",
74 "ZEBRA_IPV6_NEXTHOP_LOOKUP",
75 "ZEBRA_IPV4_IMPORT_LOOKUP",
76 "ZEBRA_IPV6_IMPORT_LOOKUP",
77 "ZEBRA_ROUTER_ID_ADD",
78 "ZEBRA_ROUTER_ID_DELETE",
79 "ZEBRA_ROUTER_ID_UPDATE"
83 static void zebra_client_close (struct zserv
*client
);
86 zserv_delayed_close(struct thread
*thread
)
88 struct zserv
*client
= THREAD_ARG(thread
);
90 client
->t_suicide
= NULL
;
91 zebra_client_close(client
);
96 zserv_flush_data(struct thread
*thread
)
98 struct zserv
*client
= THREAD_ARG(thread
);
100 client
->t_write
= NULL
;
101 if (client
->t_suicide
)
103 zebra_client_close(client
);
106 switch (buffer_flush_available(client
->wb
, client
->sock
))
109 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
110 "closing", __func__
, client
->sock
);
111 zebra_client_close(client
);
114 client
->t_write
= thread_add_write(zebrad
.master
, zserv_flush_data
,
115 client
, client
->sock
);
124 zebra_server_send_message(struct zserv
*client
)
126 if (client
->t_suicide
)
128 switch (buffer_write(client
->wb
, client
->sock
, STREAM_DATA(client
->obuf
),
129 stream_get_endp(client
->obuf
)))
132 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
133 __func__
, client
->sock
);
134 /* Schedule a delayed close since many of the functions that call this
135 one do not check the return code. They do not allow for the
136 possibility that an I/O error may have caused the client to be
138 client
->t_suicide
= thread_add_event(zebrad
.master
, zserv_delayed_close
,
143 THREAD_OFF(client
->t_write
);
146 THREAD_WRITE_ON(zebrad
.master
, client
->t_write
,
147 zserv_flush_data
, client
, client
->sock
);
154 zserv_create_header (struct stream
*s
, uint16_t cmd
)
156 /* length placeholder, caller can update */
157 stream_putw (s
, ZEBRA_HEADER_SIZE
);
158 stream_putc (s
, ZEBRA_HEADER_MARKER
);
159 stream_putc (s
, ZSERV_VERSION
);
160 stream_putw (s
, cmd
);
163 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
165 * This function is called in the following situations:
166 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
168 * - at startup, when zebra figures out the available interfaces
169 * - when an interface is added (where support for
170 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
171 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
175 zsend_interface_add (struct zserv
*client
, struct interface
*ifp
)
179 /* Check this client need interface information. */
180 if (! client
->ifinfo
)
187 zserv_create_header (s
, ZEBRA_INTERFACE_ADD
);
189 /* Interface information. */
190 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
191 stream_putl (s
, ifp
->ifindex
);
192 stream_putc (s
, ifp
->status
);
193 stream_putq (s
, ifp
->flags
);
194 stream_putl (s
, ifp
->metric
);
195 stream_putl (s
, ifp
->mtu
);
196 stream_putl (s
, ifp
->mtu6
);
197 stream_putl (s
, ifp
->bandwidth
);
198 #ifdef HAVE_SOCKADDR_DL
199 stream_put (s
, &ifp
->sdl
, sizeof (ifp
->sdl
));
201 stream_putl (s
, ifp
->hw_addr_len
);
202 if (ifp
->hw_addr_len
)
203 stream_put (s
, ifp
->hw_addr
, ifp
->hw_addr_len
);
204 #endif /* HAVE_SOCKADDR_DL */
206 /* Write packet size. */
207 stream_putw_at (s
, 0, stream_get_endp (s
));
209 return zebra_server_send_message(client
);
212 /* Interface deletion from zebra daemon. */
214 zsend_interface_delete (struct zserv
*client
, struct interface
*ifp
)
218 /* Check this client need interface information. */
219 if (! client
->ifinfo
)
225 zserv_create_header (s
, ZEBRA_INTERFACE_DELETE
);
227 /* Interface information. */
228 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
229 stream_putl (s
, ifp
->ifindex
);
230 stream_putc (s
, ifp
->status
);
231 stream_putq (s
, ifp
->flags
);
232 stream_putl (s
, ifp
->metric
);
233 stream_putl (s
, ifp
->mtu
);
234 stream_putl (s
, ifp
->mtu6
);
235 stream_putl (s
, ifp
->bandwidth
);
237 /* Write packet length. */
238 stream_putw_at (s
, 0, stream_get_endp (s
));
240 return zebra_server_send_message (client
);
243 /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
244 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
246 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
247 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
248 * from the client, after the ZEBRA_INTERFACE_ADD has been
249 * sent from zebra to the client
250 * - redistribute new address info to all clients in the following situations
251 * - at startup, when zebra figures out the available interfaces
252 * - when an interface is added (where support for
253 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
254 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
256 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
257 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
258 * - when an RTM_NEWADDR message is received from the kernel,
260 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
262 * zsend_interface_address(DELETE)
265 * zebra_interface_address_delete_update
267 * | | if_delete_update
269 * ip_address_uninstall connected_delete_ipv4
270 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
273 * | RTM_NEWADDR on routing/netlink socket
276 * "no ip address A.B.C.D/M [label LINE]"
277 * "no ip address A.B.C.D/M secondary"
278 * ["no ipv6 address X:X::X:X/M"]
282 zsend_interface_address (int cmd
, struct zserv
*client
,
283 struct interface
*ifp
, struct connected
*ifc
)
289 /* Check this client need interface information. */
290 if (! client
->ifinfo
)
296 zserv_create_header (s
, cmd
);
297 stream_putl (s
, ifp
->ifindex
);
299 /* Interface address flag. */
300 stream_putc (s
, ifc
->flags
);
302 /* Prefix information. */
304 stream_putc (s
, p
->family
);
305 blen
= prefix_blen (p
);
306 stream_put (s
, &p
->u
.prefix
, blen
);
309 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
310 * but zebra_interface_address_delete_read() in the gnu version
313 stream_putc (s
, p
->prefixlen
);
316 p
= ifc
->destination
;
318 stream_put (s
, &p
->u
.prefix
, blen
);
320 stream_put (s
, NULL
, blen
);
322 /* Write packet size. */
323 stream_putw_at (s
, 0, stream_get_endp (s
));
325 return zebra_server_send_message(client
);
329 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
330 * ZEBRA_INTERFACE_DOWN.
332 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
333 * the clients in one of 2 situations:
334 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
335 * - a vty command modifying the bandwidth of an interface is received.
336 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
339 zsend_interface_update (int cmd
, struct zserv
*client
, struct interface
*ifp
)
343 /* Check this client need interface information. */
344 if (! client
->ifinfo
)
350 zserv_create_header (s
, cmd
);
352 /* Interface information. */
353 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
354 stream_putl (s
, ifp
->ifindex
);
355 stream_putc (s
, ifp
->status
);
356 stream_putq (s
, ifp
->flags
);
357 stream_putl (s
, ifp
->metric
);
358 stream_putl (s
, ifp
->mtu
);
359 stream_putl (s
, ifp
->mtu6
);
360 stream_putl (s
, ifp
->bandwidth
);
362 /* Write packet size. */
363 stream_putw_at (s
, 0, stream_get_endp (s
));
365 return zebra_server_send_message(client
);
369 * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
370 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
372 * - when the client starts up, and requests default information
373 * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
374 * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
375 * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
376 * - when the zebra server redistributes routes after it updates its rib
378 * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
379 * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
380 * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
381 * - deleted from zebra's rib, and this info
382 * has to be redistributed to the clients
384 * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
385 * zebra server when the client wants to tell the zebra server to add a
386 * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
387 * same message being sent back and forth, this function and
388 * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
392 zsend_route_multipath (int cmd
, struct zserv
*client
, struct prefix
*p
,
397 struct nexthop
*nexthop
;
398 unsigned long nhnummark
= 0, messmark
= 0;
400 u_char zapi_flags
= 0;
405 zserv_create_header (s
, cmd
);
407 /* Put type and nexthop. */
408 stream_putc (s
, rib
->type
);
409 stream_putc (s
, rib
->flags
);
411 /* marker for message flags field */
412 messmark
= stream_get_endp (s
);
416 psize
= PSIZE (p
->prefixlen
);
417 stream_putc (s
, p
->prefixlen
);
418 stream_write (s
, (u_char
*) & p
->u
.prefix
, psize
);
421 * XXX The message format sent by zebra below does not match the format
422 * of the corresponding message expected by the zebra server
423 * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
424 * (is there a bug on the client side if more than one segment is sent?)
425 * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
430 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
432 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
434 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_NEXTHOP
);
435 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_IFINDEX
);
439 nhnummark
= stream_get_endp (s
);
440 stream_putc (s
, 1); /* placeholder */
445 switch(nexthop
->type
)
447 case NEXTHOP_TYPE_IPV4
:
448 case NEXTHOP_TYPE_IPV4_IFINDEX
:
449 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
452 case NEXTHOP_TYPE_IPV6
:
453 case NEXTHOP_TYPE_IPV6_IFINDEX
:
454 case NEXTHOP_TYPE_IPV6_IFNAME
:
455 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
459 if (cmd
== ZEBRA_IPV4_ROUTE_ADD
460 || cmd
== ZEBRA_IPV4_ROUTE_DELETE
)
462 struct in_addr empty
;
463 memset (&empty
, 0, sizeof (struct in_addr
));
464 stream_write (s
, (u_char
*) &empty
, IPV4_MAX_BYTELEN
);
468 struct in6_addr empty
;
469 memset (&empty
, 0, sizeof (struct in6_addr
));
470 stream_write (s
, (u_char
*) &empty
, IPV6_MAX_BYTELEN
);
474 /* Interface index. */
476 stream_putl (s
, nexthop
->ifindex
);
483 if (cmd
== ZEBRA_IPV4_ROUTE_ADD
|| ZEBRA_IPV6_ROUTE_ADD
)
485 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_DISTANCE
);
486 stream_putc (s
, rib
->distance
);
487 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_METRIC
);
488 stream_putl (s
, rib
->metric
);
491 /* write real message flags value */
492 stream_putc_at (s
, messmark
, zapi_flags
);
494 /* Write next-hop number */
496 stream_putc_at (s
, nhnummark
, nhnum
);
498 /* Write packet size. */
499 stream_putw_at (s
, 0, stream_get_endp (s
));
501 return zebra_server_send_message(client
);
506 zsend_ipv6_nexthop_lookup (struct zserv
*client
, struct in6_addr
*addr
)
512 struct nexthop
*nexthop
;
514 /* Lookup nexthop. */
515 rib
= rib_match_ipv6 (addr
);
517 /* Get output stream. */
521 /* Fill in result. */
522 zserv_create_header (s
, ZEBRA_IPV6_NEXTHOP_LOOKUP
);
523 stream_put (s
, &addr
, 16);
527 stream_putl (s
, rib
->metric
);
529 nump
= stream_get_endp(s
);
531 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
532 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
534 stream_putc (s
, nexthop
->type
);
535 switch (nexthop
->type
)
537 case ZEBRA_NEXTHOP_IPV6
:
538 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
540 case ZEBRA_NEXTHOP_IPV6_IFINDEX
:
541 case ZEBRA_NEXTHOP_IPV6_IFNAME
:
542 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
543 stream_putl (s
, nexthop
->ifindex
);
545 case ZEBRA_NEXTHOP_IFINDEX
:
546 case ZEBRA_NEXTHOP_IFNAME
:
547 stream_putl (s
, nexthop
->ifindex
);
555 stream_putc_at (s
, nump
, num
);
563 stream_putw_at (s
, 0, stream_get_endp (s
));
565 return zebra_server_send_message(client
);
567 #endif /* HAVE_IPV6 */
570 zsend_ipv4_nexthop_lookup (struct zserv
*client
, struct in_addr addr
)
576 struct nexthop
*nexthop
;
578 /* Lookup nexthop. */
579 rib
= rib_match_ipv4 (addr
);
581 /* Get output stream. */
585 /* Fill in result. */
586 zserv_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP
);
587 stream_put_in_addr (s
, &addr
);
591 stream_putl (s
, rib
->metric
);
593 nump
= stream_get_endp(s
);
595 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
596 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
598 stream_putc (s
, nexthop
->type
);
599 switch (nexthop
->type
)
601 case ZEBRA_NEXTHOP_IPV4
:
602 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
604 case ZEBRA_NEXTHOP_IFINDEX
:
605 case ZEBRA_NEXTHOP_IFNAME
:
606 stream_putl (s
, nexthop
->ifindex
);
614 stream_putc_at (s
, nump
, num
);
622 stream_putw_at (s
, 0, stream_get_endp (s
));
624 return zebra_server_send_message(client
);
628 zsend_ipv4_import_lookup (struct zserv
*client
, struct prefix_ipv4
*p
)
634 struct nexthop
*nexthop
;
636 /* Lookup nexthop. */
637 rib
= rib_lookup_ipv4 (p
);
639 /* Get output stream. */
643 /* Fill in result. */
644 zserv_create_header (s
, ZEBRA_IPV4_IMPORT_LOOKUP
);
645 stream_put_in_addr (s
, &p
->prefix
);
649 stream_putl (s
, rib
->metric
);
651 nump
= stream_get_endp(s
);
653 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
654 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
656 stream_putc (s
, nexthop
->type
);
657 switch (nexthop
->type
)
659 case ZEBRA_NEXTHOP_IPV4
:
660 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
662 case ZEBRA_NEXTHOP_IFINDEX
:
663 case ZEBRA_NEXTHOP_IFNAME
:
664 stream_putl (s
, nexthop
->ifindex
);
672 stream_putc_at (s
, nump
, num
);
680 stream_putw_at (s
, 0, stream_get_endp (s
));
682 return zebra_server_send_message(client
);
685 /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
687 zsend_router_id_update (struct zserv
*client
, struct prefix
*p
)
692 /* Check this client need interface information. */
693 if (!client
->ridinfo
)
700 zserv_create_header (s
, ZEBRA_ROUTER_ID_UPDATE
);
702 /* Prefix information. */
703 stream_putc (s
, p
->family
);
704 blen
= prefix_blen (p
);
705 stream_put (s
, &p
->u
.prefix
, blen
);
706 stream_putc (s
, p
->prefixlen
);
708 /* Write packet size. */
709 stream_putw_at (s
, 0, stream_get_endp (s
));
711 return zebra_server_send_message(client
);
714 /* Register zebra server interface information. Send current all
715 interface and address information. */
717 zread_interface_add (struct zserv
*client
, u_short length
)
719 struct listnode
*ifnode
, *ifnnode
;
720 struct listnode
*cnode
, *cnnode
;
721 struct interface
*ifp
;
724 /* Interface information is needed. */
727 for (ALL_LIST_ELEMENTS (iflist
, ifnode
, ifnnode
, ifp
))
729 /* Skip pseudo interface. */
730 if (! CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
733 if (zsend_interface_add (client
, ifp
) < 0)
736 for (ALL_LIST_ELEMENTS (ifp
->connected
, cnode
, cnnode
, c
))
738 if (CHECK_FLAG (c
->conf
, ZEBRA_IFC_REAL
) &&
739 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD
, client
,
747 /* Unregister zebra server interface information. */
749 zread_interface_delete (struct zserv
*client
, u_short length
)
755 /* This function support multiple nexthop. */
757 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
761 zread_ipv4_add (struct zserv
*client
, u_short length
)
765 struct prefix_ipv4 p
;
767 struct in_addr nexthop
;
771 unsigned int ifindex
;
774 /* Get input stream. */
777 /* Allocate new rib. */
778 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
780 /* Type, flags, message. */
781 rib
->type
= stream_getc (s
);
782 rib
->flags
= stream_getc (s
);
783 message
= stream_getc (s
);
784 rib
->uptime
= time (NULL
);
787 memset (&p
, 0, sizeof (struct prefix_ipv4
));
789 p
.prefixlen
= stream_getc (s
);
790 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
793 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
795 nexthop_num
= stream_getc (s
);
797 for (i
= 0; i
< nexthop_num
; i
++)
799 nexthop_type
= stream_getc (s
);
801 switch (nexthop_type
)
803 case ZEBRA_NEXTHOP_IFINDEX
:
804 ifindex
= stream_getl (s
);
805 nexthop_ifindex_add (rib
, ifindex
);
807 case ZEBRA_NEXTHOP_IFNAME
:
808 ifname_len
= stream_getc (s
);
809 stream_forward_getp (s
, ifname_len
);
811 case ZEBRA_NEXTHOP_IPV4
:
812 nexthop
.s_addr
= stream_get_ipv4 (s
);
813 nexthop_ipv4_add (rib
, &nexthop
);
815 case ZEBRA_NEXTHOP_IPV6
:
816 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
818 case ZEBRA_NEXTHOP_BLACKHOLE
:
819 nexthop_blackhole_add (rib
);
826 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
827 rib
->distance
= stream_getc (s
);
830 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
831 rib
->metric
= stream_getl (s
);
833 rib_add_ipv4_multipath (&p
, rib
);
837 /* Zebra server IPv4 prefix delete function. */
839 zread_ipv4_delete (struct zserv
*client
, u_short length
)
843 struct zapi_ipv4 api
;
844 struct in_addr nexthop
;
845 unsigned long ifindex
;
846 struct prefix_ipv4 p
;
855 /* Type, flags, message. */
856 api
.type
= stream_getc (s
);
857 api
.flags
= stream_getc (s
);
858 api
.message
= stream_getc (s
);
861 memset (&p
, 0, sizeof (struct prefix_ipv4
));
863 p
.prefixlen
= stream_getc (s
);
864 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
866 /* Nexthop, ifindex, distance, metric. */
867 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
869 nexthop_num
= stream_getc (s
);
871 for (i
= 0; i
< nexthop_num
; i
++)
873 nexthop_type
= stream_getc (s
);
875 switch (nexthop_type
)
877 case ZEBRA_NEXTHOP_IFINDEX
:
878 ifindex
= stream_getl (s
);
880 case ZEBRA_NEXTHOP_IFNAME
:
881 ifname_len
= stream_getc (s
);
882 stream_forward_getp (s
, ifname_len
);
884 case ZEBRA_NEXTHOP_IPV4
:
885 nexthop
.s_addr
= stream_get_ipv4 (s
);
887 case ZEBRA_NEXTHOP_IPV6
:
888 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
895 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
896 api
.distance
= stream_getc (s
);
901 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
902 api
.metric
= stream_getl (s
);
906 rib_delete_ipv4 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
,
911 /* Nexthop lookup for IPv4. */
913 zread_ipv4_nexthop_lookup (struct zserv
*client
, u_short length
)
917 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
918 return zsend_ipv4_nexthop_lookup (client
, addr
);
921 /* Nexthop lookup for IPv4. */
923 zread_ipv4_import_lookup (struct zserv
*client
, u_short length
)
925 struct prefix_ipv4 p
;
928 p
.prefixlen
= stream_getc (client
->ibuf
);
929 p
.prefix
.s_addr
= stream_get_ipv4 (client
->ibuf
);
931 return zsend_ipv4_import_lookup (client
, &p
);
935 /* Zebra server IPv6 prefix add function. */
937 zread_ipv6_add (struct zserv
*client
, u_short length
)
941 struct zapi_ipv6 api
;
942 struct in6_addr nexthop
;
943 unsigned long ifindex
;
944 struct prefix_ipv6 p
;
948 memset (&nexthop
, 0, sizeof (struct in6_addr
));
950 /* Type, flags, message. */
951 api
.type
= stream_getc (s
);
952 api
.flags
= stream_getc (s
);
953 api
.message
= stream_getc (s
);
956 memset (&p
, 0, sizeof (struct prefix_ipv6
));
958 p
.prefixlen
= stream_getc (s
);
959 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
961 /* Nexthop, ifindex, distance, metric. */
962 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
966 api
.nexthop_num
= stream_getc (s
);
967 for (i
= 0; i
< api
.nexthop_num
; i
++)
969 nexthop_type
= stream_getc (s
);
971 switch (nexthop_type
)
973 case ZEBRA_NEXTHOP_IPV6
:
974 stream_get (&nexthop
, s
, 16);
976 case ZEBRA_NEXTHOP_IFINDEX
:
977 ifindex
= stream_getl (s
);
983 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
984 api
.distance
= stream_getc (s
);
988 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
989 api
.metric
= stream_getl (s
);
993 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
994 rib_add_ipv6 (api
.type
, api
.flags
, &p
, NULL
, ifindex
, 0, api
.metric
,
997 rib_add_ipv6 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
, 0, api
.metric
,
1002 /* Zebra server IPv6 prefix delete function. */
1004 zread_ipv6_delete (struct zserv
*client
, u_short length
)
1008 struct zapi_ipv6 api
;
1009 struct in6_addr nexthop
;
1010 unsigned long ifindex
;
1011 struct prefix_ipv6 p
;
1015 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1017 /* Type, flags, message. */
1018 api
.type
= stream_getc (s
);
1019 api
.flags
= stream_getc (s
);
1020 api
.message
= stream_getc (s
);
1023 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1024 p
.family
= AF_INET6
;
1025 p
.prefixlen
= stream_getc (s
);
1026 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1028 /* Nexthop, ifindex, distance, metric. */
1029 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1031 u_char nexthop_type
;
1033 api
.nexthop_num
= stream_getc (s
);
1034 for (i
= 0; i
< api
.nexthop_num
; i
++)
1036 nexthop_type
= stream_getc (s
);
1038 switch (nexthop_type
)
1040 case ZEBRA_NEXTHOP_IPV6
:
1041 stream_get (&nexthop
, s
, 16);
1043 case ZEBRA_NEXTHOP_IFINDEX
:
1044 ifindex
= stream_getl (s
);
1050 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1051 api
.distance
= stream_getc (s
);
1054 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1055 api
.metric
= stream_getl (s
);
1059 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1060 rib_delete_ipv6 (api
.type
, api
.flags
, &p
, NULL
, ifindex
, 0);
1062 rib_delete_ipv6 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
, 0);
1067 zread_ipv6_nexthop_lookup (struct zserv
*client
, u_short length
)
1069 struct in6_addr addr
;
1072 stream_get (&addr
, client
->ibuf
, 16);
1073 printf ("DEBUG %s\n", inet_ntop (AF_INET6
, &addr
, buf
, BUFSIZ
));
1075 return zsend_ipv6_nexthop_lookup (client
, &addr
);
1077 #endif /* HAVE_IPV6 */
1079 /* Register zebra server router-id information. Send current router-id */
1081 zread_router_id_add (struct zserv
*client
, u_short length
)
1085 /* Router-id information is needed. */
1086 client
->ridinfo
= 1;
1090 return zsend_router_id_update (client
,&p
);
1093 /* Unregister zebra server router-id information. */
1095 zread_router_id_delete (struct zserv
*client
, u_short length
)
1097 client
->ridinfo
= 0;
1101 /* Close zebra client. */
1103 zebra_client_close (struct zserv
*client
)
1105 /* Close file descriptor. */
1108 close (client
->sock
);
1112 /* Free stream buffers. */
1114 stream_free (client
->ibuf
);
1116 stream_free (client
->obuf
);
1118 buffer_free(client
->wb
);
1120 /* Release threads. */
1122 thread_cancel (client
->t_read
);
1123 if (client
->t_write
)
1124 thread_cancel (client
->t_write
);
1125 if (client
->t_suicide
)
1126 thread_cancel (client
->t_suicide
);
1128 /* Free client structure. */
1129 listnode_delete (zebrad
.client_list
, client
);
1133 /* Make new client. */
1135 zebra_client_create (int sock
)
1137 struct zserv
*client
;
1139 client
= XCALLOC (0, sizeof (struct zserv
));
1141 /* Make client input/output buffer. */
1142 client
->sock
= sock
;
1143 client
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1144 client
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1145 client
->wb
= buffer_new(0);
1147 /* Set table number. */
1148 client
->rtm_table
= zebrad
.rtm_table_default
;
1150 /* Add this client to linked list. */
1151 listnode_add (zebrad
.client_list
, client
);
1153 /* Make new read thread. */
1154 zebra_event (ZEBRA_READ
, sock
, client
);
1157 /* Handler of zebra service request. */
1159 zebra_client_read (struct thread
*thread
)
1162 struct zserv
*client
;
1164 uint16_t length
, command
;
1165 uint8_t marker
, version
;
1167 /* Get thread data. Reset reading thread because I'm running. */
1168 sock
= THREAD_FD (thread
);
1169 client
= THREAD_ARG (thread
);
1170 client
->t_read
= NULL
;
1172 if (client
->t_suicide
)
1174 zebra_client_close(client
);
1178 /* Read length and command (if we don't have it already). */
1179 if ((already
= stream_get_endp(client
->ibuf
)) < ZEBRA_HEADER_SIZE
)
1182 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1183 ZEBRA_HEADER_SIZE
-already
)) == 0) ||
1186 if (IS_ZEBRA_DEBUG_EVENT
)
1187 zlog_debug ("connection closed socket [%d]", sock
);
1188 zebra_client_close (client
);
1191 if (nbyte
!= (ssize_t
)(ZEBRA_HEADER_SIZE
-already
))
1193 /* Try again later. */
1194 zebra_event (ZEBRA_READ
, sock
, client
);
1197 already
= ZEBRA_HEADER_SIZE
;
1200 /* Reset to read from the beginning of the incoming packet. */
1201 stream_set_getp(client
->ibuf
, 0);
1203 /* Fetch header values */
1204 length
= stream_getw (client
->ibuf
);
1205 marker
= stream_getc (client
->ibuf
);
1206 version
= stream_getc (client
->ibuf
);
1207 command
= stream_getw (client
->ibuf
);
1209 if (marker
!= ZEBRA_HEADER_MARKER
|| version
!= ZSERV_VERSION
)
1211 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1212 __func__
, sock
, marker
, version
);
1213 zebra_client_close (client
);
1216 if (length
< ZEBRA_HEADER_SIZE
)
1218 zlog_warn("%s: socket %d message length %u is less than header size %d",
1219 __func__
, sock
, length
, ZEBRA_HEADER_SIZE
);
1220 zebra_client_close (client
);
1223 if (length
> STREAM_SIZE(client
->ibuf
))
1225 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1226 __func__
, sock
, length
, (u_long
)STREAM_SIZE(client
->ibuf
));
1227 zebra_client_close (client
);
1231 /* Read rest of data. */
1232 if (already
< length
)
1235 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1236 length
-already
)) == 0) ||
1239 if (IS_ZEBRA_DEBUG_EVENT
)
1240 zlog_debug ("connection closed [%d] when reading zebra data", sock
);
1241 zebra_client_close (client
);
1244 if (nbyte
!= (ssize_t
)(length
-already
))
1246 /* Try again later. */
1247 zebra_event (ZEBRA_READ
, sock
, client
);
1252 length
-= ZEBRA_HEADER_SIZE
;
1254 /* Debug packet information. */
1255 if (IS_ZEBRA_DEBUG_EVENT
)
1256 zlog_debug ("zebra message comes from socket [%d]", sock
);
1258 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1259 zlog_debug ("zebra message received [%s] %d",
1260 zebra_command_str
[command
], length
);
1264 case ZEBRA_ROUTER_ID_ADD
:
1265 zread_router_id_add (client
, length
);
1267 case ZEBRA_ROUTER_ID_DELETE
:
1268 zread_router_id_delete (client
, length
);
1270 case ZEBRA_INTERFACE_ADD
:
1271 zread_interface_add (client
, length
);
1273 case ZEBRA_INTERFACE_DELETE
:
1274 zread_interface_delete (client
, length
);
1276 case ZEBRA_IPV4_ROUTE_ADD
:
1277 zread_ipv4_add (client
, length
);
1279 case ZEBRA_IPV4_ROUTE_DELETE
:
1280 zread_ipv4_delete (client
, length
);
1283 case ZEBRA_IPV6_ROUTE_ADD
:
1284 zread_ipv6_add (client
, length
);
1286 case ZEBRA_IPV6_ROUTE_DELETE
:
1287 zread_ipv6_delete (client
, length
);
1289 #endif /* HAVE_IPV6 */
1290 case ZEBRA_REDISTRIBUTE_ADD
:
1291 zebra_redistribute_add (command
, client
, length
);
1293 case ZEBRA_REDISTRIBUTE_DELETE
:
1294 zebra_redistribute_delete (command
, client
, length
);
1296 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD
:
1297 zebra_redistribute_default_add (command
, client
, length
);
1299 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
:
1300 zebra_redistribute_default_delete (command
, client
, length
);
1302 case ZEBRA_IPV4_NEXTHOP_LOOKUP
:
1303 zread_ipv4_nexthop_lookup (client
, length
);
1306 case ZEBRA_IPV6_NEXTHOP_LOOKUP
:
1307 zread_ipv6_nexthop_lookup (client
, length
);
1309 #endif /* HAVE_IPV6 */
1310 case ZEBRA_IPV4_IMPORT_LOOKUP
:
1311 zread_ipv4_import_lookup (client
, length
);
1314 zlog_info ("Zebra received unknown command %d", command
);
1318 if (client
->t_suicide
)
1320 /* No need to wait for thread callback, just kill immediately. */
1321 zebra_client_close(client
);
1325 stream_reset (client
->ibuf
);
1326 zebra_event (ZEBRA_READ
, sock
, client
);
1331 /* Accept code of zebra server socket. */
1333 zebra_accept (struct thread
*thread
)
1337 struct sockaddr_in client
;
1340 accept_sock
= THREAD_FD (thread
);
1342 /* Reregister myself. */
1343 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
1345 len
= sizeof (struct sockaddr_in
);
1346 client_sock
= accept (accept_sock
, (struct sockaddr
*) &client
, &len
);
1348 if (client_sock
< 0)
1350 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno
));
1354 /* Make client socket non-blocking. */
1355 set_nonblocking(client_sock
);
1357 /* Create new zebra client. */
1358 zebra_client_create (client_sock
);
1363 #ifdef HAVE_TCP_ZEBRA
1364 /* Make zebra's server socket. */
1370 struct sockaddr_in addr
;
1372 accept_sock
= socket (AF_INET
, SOCK_STREAM
, 0);
1374 if (accept_sock
< 0)
1376 zlog_warn ("Can't create zserv stream socket: %s",
1377 safe_strerror (errno
));
1378 zlog_warn ("zebra can't provice full functionality due to above error");
1382 memset (&addr
, 0, sizeof (struct sockaddr_in
));
1383 addr
.sin_family
= AF_INET
;
1384 addr
.sin_port
= htons (ZEBRA_PORT
);
1386 addr
.sin_len
= sizeof (struct sockaddr_in
);
1387 #endif /* HAVE_SIN_LEN */
1388 addr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
1390 sockopt_reuseaddr (accept_sock
);
1391 sockopt_reuseport (accept_sock
);
1393 if ( zserv_privs
.change(ZPRIVS_RAISE
) )
1394 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1396 ret
= bind (accept_sock
, (struct sockaddr
*)&addr
,
1397 sizeof (struct sockaddr_in
));
1400 zlog_warn ("Can't bind to stream socket: %s",
1401 safe_strerror (errno
));
1402 zlog_warn ("zebra can't provice full functionality due to above error");
1403 close (accept_sock
); /* Avoid sd leak. */
1407 if ( zserv_privs
.change(ZPRIVS_LOWER
) )
1408 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1410 ret
= listen (accept_sock
, 1);
1413 zlog_warn ("Can't listen to stream socket: %s",
1414 safe_strerror (errno
));
1415 zlog_warn ("zebra can't provice full functionality due to above error");
1416 close (accept_sock
); /* Avoid sd leak. */
1420 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
1422 #endif /* HAVE_TCP_ZEBRA */
1424 /* For sockaddr_un. */
1427 /* zebra server UNIX domain socket. */
1429 zebra_serv_un (const char *path
)
1433 struct sockaddr_un serv
;
1436 /* First of all, unlink existing socket */
1440 old_mask
= umask (0077);
1442 /* Make UNIX domain socket. */
1443 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
1446 zlog_warn ("Can't create zserv unix socket: %s",
1447 safe_strerror (errno
));
1448 zlog_warn ("zebra can't provide full functionality due to above error");
1452 /* Make server socket. */
1453 memset (&serv
, 0, sizeof (struct sockaddr_un
));
1454 serv
.sun_family
= AF_UNIX
;
1455 strncpy (serv
.sun_path
, path
, strlen (path
));
1457 len
= serv
.sun_len
= SUN_LEN(&serv
);
1459 len
= sizeof (serv
.sun_family
) + strlen (serv
.sun_path
);
1460 #endif /* HAVE_SUN_LEN */
1462 ret
= bind (sock
, (struct sockaddr
*) &serv
, len
);
1465 zlog_warn ("Can't bind to unix socket %s: %s",
1466 path
, safe_strerror (errno
));
1467 zlog_warn ("zebra can't provide full functionality due to above error");
1472 ret
= listen (sock
, 5);
1475 zlog_warn ("Can't listen to unix socket %s: %s",
1476 path
, safe_strerror (errno
));
1477 zlog_warn ("zebra can't provide full functionality due to above error");
1484 zebra_event (ZEBRA_SERV
, sock
, NULL
);
1489 zebra_event (enum event event
, int sock
, struct zserv
*client
)
1494 thread_add_read (zebrad
.master
, zebra_accept
, client
, sock
);
1498 thread_add_read (zebrad
.master
, zebra_client_read
, client
, sock
);
1506 /* Display default rtm_table for all clients. */
1511 "default routing table to use for all clients\n")
1513 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
1518 DEFUN (config_table
,
1521 "Configure target kernel routing table\n"
1524 zebrad
.rtm_table_default
= strtol (argv
[0], (char**)0, 10);
1528 DEFUN (ip_forwarding
,
1532 "Turn on IP forwarding")
1538 ret
= ipforward_on ();
1542 vty_out (vty
, "Can't turn on IP forwarding%s", VTY_NEWLINE
);
1549 DEFUN (no_ip_forwarding
,
1550 no_ip_forwarding_cmd
,
1554 "Turn off IP forwarding")
1560 ret
= ipforward_off ();
1564 vty_out (vty
, "Can't turn off IP forwarding%s", VTY_NEWLINE
);
1571 /* This command is for debugging purpose. */
1572 DEFUN (show_zebra_client
,
1573 show_zebra_client_cmd
,
1574 "show zebra client",
1577 "Client information")
1579 struct listnode
*node
;
1580 struct zserv
*client
;
1582 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
1583 vty_out (vty
, "Client fd %d%s", client
->sock
, VTY_NEWLINE
);
1588 /* Table configuration write function. */
1590 config_write_table (struct vty
*vty
)
1592 if (zebrad
.rtm_table_default
)
1593 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
1598 /* table node for routing tables. */
1599 struct cmd_node table_node
=
1602 "", /* This node has no interface. */
1606 /* Only display ip forwarding is enabled or not. */
1607 DEFUN (show_ip_forwarding
,
1608 show_ip_forwarding_cmd
,
1609 "show ip forwarding",
1612 "IP forwarding status\n")
1619 vty_out (vty
, "IP forwarding is off%s", VTY_NEWLINE
);
1621 vty_out (vty
, "IP forwarding is on%s", VTY_NEWLINE
);
1626 /* Only display ipv6 forwarding is enabled or not. */
1627 DEFUN (show_ipv6_forwarding
,
1628 show_ipv6_forwarding_cmd
,
1629 "show ipv6 forwarding",
1631 "IPv6 information\n"
1632 "Forwarding status\n")
1636 ret
= ipforward_ipv6 ();
1641 vty_out (vty
, "ipv6 forwarding is unknown%s", VTY_NEWLINE
);
1644 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
1647 vty_out (vty
, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE
);
1650 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
1656 DEFUN (ipv6_forwarding
,
1657 ipv6_forwarding_cmd
,
1660 "Turn on IPv6 forwarding")
1664 ret
= ipforward_ipv6 ();
1666 ret
= ipforward_ipv6_on ();
1670 vty_out (vty
, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE
);
1677 DEFUN (no_ipv6_forwarding
,
1678 no_ipv6_forwarding_cmd
,
1679 "no ipv6 forwarding",
1682 "Turn off IPv6 forwarding")
1686 ret
= ipforward_ipv6 ();
1688 ret
= ipforward_ipv6_off ();
1692 vty_out (vty
, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE
);
1699 #endif /* HAVE_IPV6 */
1701 /* IPForwarding configuration write function. */
1703 config_write_forwarding (struct vty
*vty
)
1705 /* FIXME: Find better place for that. */
1706 router_id_write (vty
);
1709 vty_out (vty
, "ip forwarding%s", VTY_NEWLINE
);
1711 if (ipforward_ipv6 ())
1712 vty_out (vty
, "ipv6 forwarding%s", VTY_NEWLINE
);
1713 #endif /* HAVE_IPV6 */
1714 vty_out (vty
, "!%s", VTY_NEWLINE
);
1718 /* table node for routing tables. */
1719 struct cmd_node forwarding_node
=
1722 "", /* This node has no interface. */
1727 /* Initialisation of zebra and installation of commands. */
1731 /* Client list init. */
1732 zebrad
.client_list
= list_new ();
1734 /* Make zebra server socket. */
1735 #ifdef HAVE_TCP_ZEBRA
1738 zebra_serv_un (ZEBRA_SERV_PATH
);
1739 #endif /* HAVE_TCP_ZEBRA */
1741 /* Install configuration write function. */
1742 install_node (&table_node
, config_write_table
);
1743 install_node (&forwarding_node
, config_write_forwarding
);
1745 install_element (VIEW_NODE
, &show_ip_forwarding_cmd
);
1746 install_element (ENABLE_NODE
, &show_ip_forwarding_cmd
);
1747 install_element (CONFIG_NODE
, &ip_forwarding_cmd
);
1748 install_element (CONFIG_NODE
, &no_ip_forwarding_cmd
);
1749 install_element (ENABLE_NODE
, &show_zebra_client_cmd
);
1752 install_element (VIEW_NODE
, &show_table_cmd
);
1753 install_element (ENABLE_NODE
, &show_table_cmd
);
1754 install_element (CONFIG_NODE
, &config_table_cmd
);
1755 #endif /* HAVE_NETLINK */
1758 install_element (VIEW_NODE
, &show_ipv6_forwarding_cmd
);
1759 install_element (ENABLE_NODE
, &show_ipv6_forwarding_cmd
);
1760 install_element (CONFIG_NODE
, &ipv6_forwarding_cmd
);
1761 install_element (CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
1762 #endif /* HAVE_IPV6 */