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 static void zebra_client_close (struct zserv
*client
);
58 zserv_delayed_close(struct thread
*thread
)
60 struct zserv
*client
= THREAD_ARG(thread
);
62 client
->t_suicide
= NULL
;
63 zebra_client_close(client
);
68 zserv_flush_data(struct thread
*thread
)
70 struct zserv
*client
= THREAD_ARG(thread
);
72 client
->t_write
= NULL
;
73 if (client
->t_suicide
)
75 zebra_client_close(client
);
78 switch (buffer_flush_available(client
->wb
, client
->sock
))
81 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
82 "closing", __func__
, client
->sock
);
83 zebra_client_close(client
);
86 client
->t_write
= thread_add_write(zebrad
.master
, zserv_flush_data
,
87 client
, client
->sock
);
96 zebra_server_send_message(struct zserv
*client
)
98 if (client
->t_suicide
)
100 switch (buffer_write(client
->wb
, client
->sock
, STREAM_DATA(client
->obuf
),
101 stream_get_endp(client
->obuf
)))
104 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
105 __func__
, client
->sock
);
106 /* Schedule a delayed close since many of the functions that call this
107 one do not check the return code. They do not allow for the
108 possibility that an I/O error may have caused the client to be
110 client
->t_suicide
= thread_add_event(zebrad
.master
, zserv_delayed_close
,
114 THREAD_OFF(client
->t_write
);
117 THREAD_WRITE_ON(zebrad
.master
, client
->t_write
,
118 zserv_flush_data
, client
, client
->sock
);
125 zserv_create_header (struct stream
*s
, uint16_t cmd
)
127 /* length placeholder, caller can update */
128 stream_putw (s
, ZEBRA_HEADER_SIZE
);
129 stream_putc (s
, ZEBRA_HEADER_MARKER
);
130 stream_putc (s
, ZSERV_VERSION
);
131 stream_putw (s
, cmd
);
134 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
136 * This function is called in the following situations:
137 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
139 * - at startup, when zebra figures out the available interfaces
140 * - when an interface is added (where support for
141 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
142 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
146 zsend_interface_add (struct zserv
*client
, struct interface
*ifp
)
150 /* Check this client need interface information. */
151 if (! client
->ifinfo
)
158 zserv_create_header (s
, ZEBRA_INTERFACE_ADD
);
160 /* Interface information. */
161 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
162 stream_putl (s
, ifp
->ifindex
);
163 stream_putc (s
, ifp
->status
);
164 stream_putq (s
, ifp
->flags
);
165 stream_putl (s
, ifp
->metric
);
166 stream_putl (s
, ifp
->mtu
);
167 stream_putl (s
, ifp
->mtu6
);
168 stream_putl (s
, ifp
->bandwidth
);
169 #ifdef HAVE_STRUCT_SOCKADDR_DL
170 stream_put (s
, &ifp
->sdl
, sizeof (ifp
->sdl
));
172 stream_putl (s
, ifp
->hw_addr_len
);
173 if (ifp
->hw_addr_len
)
174 stream_put (s
, ifp
->hw_addr
, ifp
->hw_addr_len
);
175 #endif /* HAVE_STRUCT_SOCKADDR_DL */
177 /* Write packet size. */
178 stream_putw_at (s
, 0, stream_get_endp (s
));
180 return zebra_server_send_message(client
);
183 /* Interface deletion from zebra daemon. */
185 zsend_interface_delete (struct zserv
*client
, struct interface
*ifp
)
189 /* Check this client need interface information. */
190 if (! client
->ifinfo
)
196 zserv_create_header (s
, ZEBRA_INTERFACE_DELETE
);
198 /* Interface information. */
199 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
200 stream_putl (s
, ifp
->ifindex
);
201 stream_putc (s
, ifp
->status
);
202 stream_putq (s
, ifp
->flags
);
203 stream_putl (s
, ifp
->metric
);
204 stream_putl (s
, ifp
->mtu
);
205 stream_putl (s
, ifp
->mtu6
);
206 stream_putl (s
, ifp
->bandwidth
);
208 /* Write packet length. */
209 stream_putw_at (s
, 0, stream_get_endp (s
));
211 return zebra_server_send_message (client
);
214 /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
215 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
217 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
218 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
219 * from the client, after the ZEBRA_INTERFACE_ADD has been
220 * sent from zebra to the client
221 * - redistribute new address info to all clients in the following situations
222 * - at startup, when zebra figures out the available interfaces
223 * - when an interface is added (where support for
224 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
225 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
227 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
228 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
229 * - when an RTM_NEWADDR message is received from the kernel,
231 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
233 * zsend_interface_address(DELETE)
236 * zebra_interface_address_delete_update
238 * | | if_delete_update
240 * ip_address_uninstall connected_delete_ipv4
241 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
244 * | RTM_NEWADDR on routing/netlink socket
247 * "no ip address A.B.C.D/M [label LINE]"
248 * "no ip address A.B.C.D/M secondary"
249 * ["no ipv6 address X:X::X:X/M"]
253 zsend_interface_address (int cmd
, struct zserv
*client
,
254 struct interface
*ifp
, struct connected
*ifc
)
260 /* Check this client need interface information. */
261 if (! client
->ifinfo
)
267 zserv_create_header (s
, cmd
);
268 stream_putl (s
, ifp
->ifindex
);
270 /* Interface address flag. */
271 stream_putc (s
, ifc
->flags
);
273 /* Prefix information. */
275 stream_putc (s
, p
->family
);
276 blen
= prefix_blen (p
);
277 stream_put (s
, &p
->u
.prefix
, blen
);
280 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
281 * but zebra_interface_address_delete_read() in the gnu version
284 stream_putc (s
, p
->prefixlen
);
287 p
= ifc
->destination
;
289 stream_put (s
, &p
->u
.prefix
, blen
);
291 stream_put (s
, NULL
, blen
);
293 /* Write packet size. */
294 stream_putw_at (s
, 0, stream_get_endp (s
));
296 return zebra_server_send_message(client
);
300 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
301 * ZEBRA_INTERFACE_DOWN.
303 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
304 * the clients in one of 2 situations:
305 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
306 * - a vty command modifying the bandwidth of an interface is received.
307 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
310 zsend_interface_update (int cmd
, struct zserv
*client
, struct interface
*ifp
)
314 /* Check this client need interface information. */
315 if (! client
->ifinfo
)
321 zserv_create_header (s
, cmd
);
323 /* Interface information. */
324 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
325 stream_putl (s
, ifp
->ifindex
);
326 stream_putc (s
, ifp
->status
);
327 stream_putq (s
, ifp
->flags
);
328 stream_putl (s
, ifp
->metric
);
329 stream_putl (s
, ifp
->mtu
);
330 stream_putl (s
, ifp
->mtu6
);
331 stream_putl (s
, ifp
->bandwidth
);
333 /* Write packet size. */
334 stream_putw_at (s
, 0, stream_get_endp (s
));
336 return zebra_server_send_message(client
);
340 * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
341 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
343 * - when the client starts up, and requests default information
344 * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
345 * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
346 * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
347 * - when the zebra server redistributes routes after it updates its rib
349 * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
350 * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
351 * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
352 * - deleted from zebra's rib, and this info
353 * has to be redistributed to the clients
355 * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
356 * zebra server when the client wants to tell the zebra server to add a
357 * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
358 * same message being sent back and forth, this function and
359 * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
363 zsend_route_multipath (int cmd
, struct zserv
*client
, struct prefix
*p
,
368 struct nexthop
*nexthop
;
369 unsigned long nhnummark
= 0, messmark
= 0;
371 u_char zapi_flags
= 0;
376 zserv_create_header (s
, cmd
);
378 /* Put type and nexthop. */
379 stream_putc (s
, rib
->type
);
380 stream_putc (s
, rib
->flags
);
382 /* marker for message flags field */
383 messmark
= stream_get_endp (s
);
387 psize
= PSIZE (p
->prefixlen
);
388 stream_putc (s
, p
->prefixlen
);
389 stream_write (s
, (u_char
*) & p
->u
.prefix
, psize
);
392 * XXX The message format sent by zebra below does not match the format
393 * of the corresponding message expected by the zebra server
394 * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
395 * (is there a bug on the client side if more than one segment is sent?)
396 * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
401 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
403 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
405 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_NEXTHOP
);
406 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_IFINDEX
);
410 nhnummark
= stream_get_endp (s
);
411 stream_putc (s
, 1); /* placeholder */
416 switch(nexthop
->type
)
418 case NEXTHOP_TYPE_IPV4
:
419 case NEXTHOP_TYPE_IPV4_IFINDEX
:
420 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
423 case NEXTHOP_TYPE_IPV6
:
424 case NEXTHOP_TYPE_IPV6_IFINDEX
:
425 case NEXTHOP_TYPE_IPV6_IFNAME
:
426 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
430 if (cmd
== ZEBRA_IPV4_ROUTE_ADD
431 || cmd
== ZEBRA_IPV4_ROUTE_DELETE
)
433 struct in_addr empty
;
434 memset (&empty
, 0, sizeof (struct in_addr
));
435 stream_write (s
, (u_char
*) &empty
, IPV4_MAX_BYTELEN
);
439 struct in6_addr empty
;
440 memset (&empty
, 0, sizeof (struct in6_addr
));
441 stream_write (s
, (u_char
*) &empty
, IPV6_MAX_BYTELEN
);
445 /* Interface index. */
447 stream_putl (s
, nexthop
->ifindex
);
454 if (cmd
== ZEBRA_IPV4_ROUTE_ADD
|| ZEBRA_IPV6_ROUTE_ADD
)
456 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_DISTANCE
);
457 stream_putc (s
, rib
->distance
);
458 SET_FLAG (zapi_flags
, ZAPI_MESSAGE_METRIC
);
459 stream_putl (s
, rib
->metric
);
462 /* write real message flags value */
463 stream_putc_at (s
, messmark
, zapi_flags
);
465 /* Write next-hop number */
467 stream_putc_at (s
, nhnummark
, nhnum
);
469 /* Write packet size. */
470 stream_putw_at (s
, 0, stream_get_endp (s
));
472 return zebra_server_send_message(client
);
477 zsend_ipv6_nexthop_lookup (struct zserv
*client
, struct in6_addr
*addr
)
483 struct nexthop
*nexthop
;
485 /* Lookup nexthop. */
486 rib
= rib_match_ipv6 (addr
);
488 /* Get output stream. */
492 /* Fill in result. */
493 zserv_create_header (s
, ZEBRA_IPV6_NEXTHOP_LOOKUP
);
494 stream_put (s
, &addr
, 16);
498 stream_putl (s
, rib
->metric
);
500 nump
= stream_get_endp(s
);
502 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
503 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
505 stream_putc (s
, nexthop
->type
);
506 switch (nexthop
->type
)
508 case ZEBRA_NEXTHOP_IPV6
:
509 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
511 case ZEBRA_NEXTHOP_IPV6_IFINDEX
:
512 case ZEBRA_NEXTHOP_IPV6_IFNAME
:
513 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
514 stream_putl (s
, nexthop
->ifindex
);
516 case ZEBRA_NEXTHOP_IFINDEX
:
517 case ZEBRA_NEXTHOP_IFNAME
:
518 stream_putl (s
, nexthop
->ifindex
);
526 stream_putc_at (s
, nump
, num
);
534 stream_putw_at (s
, 0, stream_get_endp (s
));
536 return zebra_server_send_message(client
);
538 #endif /* HAVE_IPV6 */
541 zsend_ipv4_nexthop_lookup (struct zserv
*client
, struct in_addr addr
)
547 struct nexthop
*nexthop
;
549 /* Lookup nexthop. */
550 rib
= rib_match_ipv4 (addr
);
552 /* Get output stream. */
556 /* Fill in result. */
557 zserv_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP
);
558 stream_put_in_addr (s
, &addr
);
562 stream_putl (s
, rib
->metric
);
564 nump
= stream_get_endp(s
);
566 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
567 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
569 stream_putc (s
, nexthop
->type
);
570 switch (nexthop
->type
)
572 case ZEBRA_NEXTHOP_IPV4
:
573 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
575 case ZEBRA_NEXTHOP_IFINDEX
:
576 case ZEBRA_NEXTHOP_IFNAME
:
577 stream_putl (s
, nexthop
->ifindex
);
585 stream_putc_at (s
, nump
, num
);
593 stream_putw_at (s
, 0, stream_get_endp (s
));
595 return zebra_server_send_message(client
);
599 zsend_ipv4_import_lookup (struct zserv
*client
, struct prefix_ipv4
*p
)
605 struct nexthop
*nexthop
;
607 /* Lookup nexthop. */
608 rib
= rib_lookup_ipv4 (p
);
610 /* Get output stream. */
614 /* Fill in result. */
615 zserv_create_header (s
, ZEBRA_IPV4_IMPORT_LOOKUP
);
616 stream_put_in_addr (s
, &p
->prefix
);
620 stream_putl (s
, rib
->metric
);
622 nump
= stream_get_endp(s
);
624 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
625 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
627 stream_putc (s
, nexthop
->type
);
628 switch (nexthop
->type
)
630 case ZEBRA_NEXTHOP_IPV4
:
631 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
633 case ZEBRA_NEXTHOP_IFINDEX
:
634 case ZEBRA_NEXTHOP_IFNAME
:
635 stream_putl (s
, nexthop
->ifindex
);
643 stream_putc_at (s
, nump
, num
);
651 stream_putw_at (s
, 0, stream_get_endp (s
));
653 return zebra_server_send_message(client
);
656 /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
658 zsend_router_id_update (struct zserv
*client
, struct prefix
*p
)
663 /* Check this client need interface information. */
664 if (!client
->ridinfo
)
671 zserv_create_header (s
, ZEBRA_ROUTER_ID_UPDATE
);
673 /* Prefix information. */
674 stream_putc (s
, p
->family
);
675 blen
= prefix_blen (p
);
676 stream_put (s
, &p
->u
.prefix
, blen
);
677 stream_putc (s
, p
->prefixlen
);
679 /* Write packet size. */
680 stream_putw_at (s
, 0, stream_get_endp (s
));
682 return zebra_server_send_message(client
);
685 /* Register zebra server interface information. Send current all
686 interface and address information. */
688 zread_interface_add (struct zserv
*client
, u_short length
)
690 struct listnode
*ifnode
, *ifnnode
;
691 struct listnode
*cnode
, *cnnode
;
692 struct interface
*ifp
;
695 /* Interface information is needed. */
698 for (ALL_LIST_ELEMENTS (iflist
, ifnode
, ifnnode
, ifp
))
700 /* Skip pseudo interface. */
701 if (! CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
704 if (zsend_interface_add (client
, ifp
) < 0)
707 for (ALL_LIST_ELEMENTS (ifp
->connected
, cnode
, cnnode
, c
))
709 if (CHECK_FLAG (c
->conf
, ZEBRA_IFC_REAL
) &&
710 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD
, client
,
718 /* Unregister zebra server interface information. */
720 zread_interface_delete (struct zserv
*client
, u_short length
)
726 /* This function support multiple nexthop. */
728 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
732 zread_ipv4_add (struct zserv
*client
, u_short length
)
736 struct prefix_ipv4 p
;
738 struct in_addr nexthop
;
742 unsigned int ifindex
;
745 /* Get input stream. */
748 /* Allocate new rib. */
749 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
751 /* Type, flags, message. */
752 rib
->type
= stream_getc (s
);
753 rib
->flags
= stream_getc (s
);
754 message
= stream_getc (s
);
755 rib
->uptime
= time (NULL
);
758 memset (&p
, 0, sizeof (struct prefix_ipv4
));
760 p
.prefixlen
= stream_getc (s
);
761 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
764 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
766 nexthop_num
= stream_getc (s
);
768 for (i
= 0; i
< nexthop_num
; i
++)
770 nexthop_type
= stream_getc (s
);
772 switch (nexthop_type
)
774 case ZEBRA_NEXTHOP_IFINDEX
:
775 ifindex
= stream_getl (s
);
776 nexthop_ifindex_add (rib
, ifindex
);
778 case ZEBRA_NEXTHOP_IFNAME
:
779 ifname_len
= stream_getc (s
);
780 stream_forward_getp (s
, ifname_len
);
782 case ZEBRA_NEXTHOP_IPV4
:
783 nexthop
.s_addr
= stream_get_ipv4 (s
);
784 nexthop_ipv4_add (rib
, &nexthop
, NULL
);
786 case ZEBRA_NEXTHOP_IPV6
:
787 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
789 case ZEBRA_NEXTHOP_BLACKHOLE
:
790 nexthop_blackhole_add (rib
);
797 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
798 rib
->distance
= stream_getc (s
);
801 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
802 rib
->metric
= stream_getl (s
);
805 rib
->table
=zebrad
.rtm_table_default
;
806 rib_add_ipv4_multipath (&p
, rib
);
810 /* Zebra server IPv4 prefix delete function. */
812 zread_ipv4_delete (struct zserv
*client
, u_short length
)
816 struct zapi_ipv4 api
;
817 struct in_addr nexthop
;
818 unsigned long ifindex
;
819 struct prefix_ipv4 p
;
828 /* Type, flags, message. */
829 api
.type
= stream_getc (s
);
830 api
.flags
= stream_getc (s
);
831 api
.message
= stream_getc (s
);
834 memset (&p
, 0, sizeof (struct prefix_ipv4
));
836 p
.prefixlen
= stream_getc (s
);
837 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
839 /* Nexthop, ifindex, distance, metric. */
840 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
842 nexthop_num
= stream_getc (s
);
844 for (i
= 0; i
< nexthop_num
; i
++)
846 nexthop_type
= stream_getc (s
);
848 switch (nexthop_type
)
850 case ZEBRA_NEXTHOP_IFINDEX
:
851 ifindex
= stream_getl (s
);
853 case ZEBRA_NEXTHOP_IFNAME
:
854 ifname_len
= stream_getc (s
);
855 stream_forward_getp (s
, ifname_len
);
857 case ZEBRA_NEXTHOP_IPV4
:
858 nexthop
.s_addr
= stream_get_ipv4 (s
);
860 case ZEBRA_NEXTHOP_IPV6
:
861 stream_forward_getp (s
, IPV6_MAX_BYTELEN
);
868 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
869 api
.distance
= stream_getc (s
);
874 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
875 api
.metric
= stream_getl (s
);
879 rib_delete_ipv4 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
,
884 /* Nexthop lookup for IPv4. */
886 zread_ipv4_nexthop_lookup (struct zserv
*client
, u_short length
)
890 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
891 return zsend_ipv4_nexthop_lookup (client
, addr
);
894 /* Nexthop lookup for IPv4. */
896 zread_ipv4_import_lookup (struct zserv
*client
, u_short length
)
898 struct prefix_ipv4 p
;
901 p
.prefixlen
= stream_getc (client
->ibuf
);
902 p
.prefix
.s_addr
= stream_get_ipv4 (client
->ibuf
);
904 return zsend_ipv4_import_lookup (client
, &p
);
908 /* Zebra server IPv6 prefix add function. */
910 zread_ipv6_add (struct zserv
*client
, u_short length
)
914 struct zapi_ipv6 api
;
915 struct in6_addr nexthop
;
916 unsigned long ifindex
;
917 struct prefix_ipv6 p
;
921 memset (&nexthop
, 0, sizeof (struct in6_addr
));
923 /* Type, flags, message. */
924 api
.type
= stream_getc (s
);
925 api
.flags
= stream_getc (s
);
926 api
.message
= stream_getc (s
);
929 memset (&p
, 0, sizeof (struct prefix_ipv6
));
931 p
.prefixlen
= stream_getc (s
);
932 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
934 /* Nexthop, ifindex, distance, metric. */
935 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
939 api
.nexthop_num
= stream_getc (s
);
940 for (i
= 0; i
< api
.nexthop_num
; i
++)
942 nexthop_type
= stream_getc (s
);
944 switch (nexthop_type
)
946 case ZEBRA_NEXTHOP_IPV6
:
947 stream_get (&nexthop
, s
, 16);
949 case ZEBRA_NEXTHOP_IFINDEX
:
950 ifindex
= stream_getl (s
);
956 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
957 api
.distance
= stream_getc (s
);
961 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
962 api
.metric
= stream_getl (s
);
966 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
967 rib_add_ipv6 (api
.type
, api
.flags
, &p
, NULL
, ifindex
, zebrad
.rtm_table_default
, api
.metric
,
970 rib_add_ipv6 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
, zebrad
.rtm_table_default
, api
.metric
,
975 /* Zebra server IPv6 prefix delete function. */
977 zread_ipv6_delete (struct zserv
*client
, u_short length
)
981 struct zapi_ipv6 api
;
982 struct in6_addr nexthop
;
983 unsigned long ifindex
;
984 struct prefix_ipv6 p
;
988 memset (&nexthop
, 0, sizeof (struct in6_addr
));
990 /* Type, flags, message. */
991 api
.type
= stream_getc (s
);
992 api
.flags
= stream_getc (s
);
993 api
.message
= stream_getc (s
);
996 memset (&p
, 0, sizeof (struct prefix_ipv6
));
998 p
.prefixlen
= stream_getc (s
);
999 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1001 /* Nexthop, ifindex, distance, metric. */
1002 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1004 u_char nexthop_type
;
1006 api
.nexthop_num
= stream_getc (s
);
1007 for (i
= 0; i
< api
.nexthop_num
; i
++)
1009 nexthop_type
= stream_getc (s
);
1011 switch (nexthop_type
)
1013 case ZEBRA_NEXTHOP_IPV6
:
1014 stream_get (&nexthop
, s
, 16);
1016 case ZEBRA_NEXTHOP_IFINDEX
:
1017 ifindex
= stream_getl (s
);
1023 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1024 api
.distance
= stream_getc (s
);
1027 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1028 api
.metric
= stream_getl (s
);
1032 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1033 rib_delete_ipv6 (api
.type
, api
.flags
, &p
, NULL
, ifindex
, client
->rtm_table
);
1035 rib_delete_ipv6 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
, client
->rtm_table
);
1040 zread_ipv6_nexthop_lookup (struct zserv
*client
, u_short length
)
1042 struct in6_addr addr
;
1045 stream_get (&addr
, client
->ibuf
, 16);
1046 printf ("DEBUG %s\n", inet_ntop (AF_INET6
, &addr
, buf
, BUFSIZ
));
1048 return zsend_ipv6_nexthop_lookup (client
, &addr
);
1050 #endif /* HAVE_IPV6 */
1052 /* Register zebra server router-id information. Send current router-id */
1054 zread_router_id_add (struct zserv
*client
, u_short length
)
1058 /* Router-id information is needed. */
1059 client
->ridinfo
= 1;
1063 return zsend_router_id_update (client
,&p
);
1066 /* Unregister zebra server router-id information. */
1068 zread_router_id_delete (struct zserv
*client
, u_short length
)
1070 client
->ridinfo
= 0;
1074 /* Close zebra client. */
1076 zebra_client_close (struct zserv
*client
)
1078 /* Close file descriptor. */
1081 close (client
->sock
);
1085 /* Free stream buffers. */
1087 stream_free (client
->ibuf
);
1089 stream_free (client
->obuf
);
1091 buffer_free(client
->wb
);
1093 /* Release threads. */
1095 thread_cancel (client
->t_read
);
1096 if (client
->t_write
)
1097 thread_cancel (client
->t_write
);
1098 if (client
->t_suicide
)
1099 thread_cancel (client
->t_suicide
);
1101 /* Free client structure. */
1102 listnode_delete (zebrad
.client_list
, client
);
1106 /* Make new client. */
1108 zebra_client_create (int sock
)
1110 struct zserv
*client
;
1112 client
= XCALLOC (0, sizeof (struct zserv
));
1114 /* Make client input/output buffer. */
1115 client
->sock
= sock
;
1116 client
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1117 client
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1118 client
->wb
= buffer_new(0);
1120 /* Set table number. */
1121 client
->rtm_table
= zebrad
.rtm_table_default
;
1123 /* Add this client to linked list. */
1124 listnode_add (zebrad
.client_list
, client
);
1126 /* Make new read thread. */
1127 zebra_event (ZEBRA_READ
, sock
, client
);
1130 /* Handler of zebra service request. */
1132 zebra_client_read (struct thread
*thread
)
1135 struct zserv
*client
;
1137 uint16_t length
, command
;
1138 uint8_t marker
, version
;
1140 /* Get thread data. Reset reading thread because I'm running. */
1141 sock
= THREAD_FD (thread
);
1142 client
= THREAD_ARG (thread
);
1143 client
->t_read
= NULL
;
1145 if (client
->t_suicide
)
1147 zebra_client_close(client
);
1151 /* Read length and command (if we don't have it already). */
1152 if ((already
= stream_get_endp(client
->ibuf
)) < ZEBRA_HEADER_SIZE
)
1155 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1156 ZEBRA_HEADER_SIZE
-already
)) == 0) ||
1159 if (IS_ZEBRA_DEBUG_EVENT
)
1160 zlog_debug ("connection closed socket [%d]", sock
);
1161 zebra_client_close (client
);
1164 if (nbyte
!= (ssize_t
)(ZEBRA_HEADER_SIZE
-already
))
1166 /* Try again later. */
1167 zebra_event (ZEBRA_READ
, sock
, client
);
1170 already
= ZEBRA_HEADER_SIZE
;
1173 /* Reset to read from the beginning of the incoming packet. */
1174 stream_set_getp(client
->ibuf
, 0);
1176 /* Fetch header values */
1177 length
= stream_getw (client
->ibuf
);
1178 marker
= stream_getc (client
->ibuf
);
1179 version
= stream_getc (client
->ibuf
);
1180 command
= stream_getw (client
->ibuf
);
1182 if (marker
!= ZEBRA_HEADER_MARKER
|| version
!= ZSERV_VERSION
)
1184 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1185 __func__
, sock
, marker
, version
);
1186 zebra_client_close (client
);
1189 if (length
< ZEBRA_HEADER_SIZE
)
1191 zlog_warn("%s: socket %d message length %u is less than header size %d",
1192 __func__
, sock
, length
, ZEBRA_HEADER_SIZE
);
1193 zebra_client_close (client
);
1196 if (length
> STREAM_SIZE(client
->ibuf
))
1198 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1199 __func__
, sock
, length
, (u_long
)STREAM_SIZE(client
->ibuf
));
1200 zebra_client_close (client
);
1204 /* Read rest of data. */
1205 if (already
< length
)
1208 if (((nbyte
= stream_read_try (client
->ibuf
, sock
,
1209 length
-already
)) == 0) ||
1212 if (IS_ZEBRA_DEBUG_EVENT
)
1213 zlog_debug ("connection closed [%d] when reading zebra data", sock
);
1214 zebra_client_close (client
);
1217 if (nbyte
!= (ssize_t
)(length
-already
))
1219 /* Try again later. */
1220 zebra_event (ZEBRA_READ
, sock
, client
);
1225 length
-= ZEBRA_HEADER_SIZE
;
1227 /* Debug packet information. */
1228 if (IS_ZEBRA_DEBUG_EVENT
)
1229 zlog_debug ("zebra message comes from socket [%d]", sock
);
1231 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1232 zlog_debug ("zebra message received [%s] %d",
1233 zserv_command_string (command
), length
);
1237 case ZEBRA_ROUTER_ID_ADD
:
1238 zread_router_id_add (client
, length
);
1240 case ZEBRA_ROUTER_ID_DELETE
:
1241 zread_router_id_delete (client
, length
);
1243 case ZEBRA_INTERFACE_ADD
:
1244 zread_interface_add (client
, length
);
1246 case ZEBRA_INTERFACE_DELETE
:
1247 zread_interface_delete (client
, length
);
1249 case ZEBRA_IPV4_ROUTE_ADD
:
1250 zread_ipv4_add (client
, length
);
1252 case ZEBRA_IPV4_ROUTE_DELETE
:
1253 zread_ipv4_delete (client
, length
);
1256 case ZEBRA_IPV6_ROUTE_ADD
:
1257 zread_ipv6_add (client
, length
);
1259 case ZEBRA_IPV6_ROUTE_DELETE
:
1260 zread_ipv6_delete (client
, length
);
1262 #endif /* HAVE_IPV6 */
1263 case ZEBRA_REDISTRIBUTE_ADD
:
1264 zebra_redistribute_add (command
, client
, length
);
1266 case ZEBRA_REDISTRIBUTE_DELETE
:
1267 zebra_redistribute_delete (command
, client
, length
);
1269 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD
:
1270 zebra_redistribute_default_add (command
, client
, length
);
1272 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
:
1273 zebra_redistribute_default_delete (command
, client
, length
);
1275 case ZEBRA_IPV4_NEXTHOP_LOOKUP
:
1276 zread_ipv4_nexthop_lookup (client
, length
);
1279 case ZEBRA_IPV6_NEXTHOP_LOOKUP
:
1280 zread_ipv6_nexthop_lookup (client
, length
);
1282 #endif /* HAVE_IPV6 */
1283 case ZEBRA_IPV4_IMPORT_LOOKUP
:
1284 zread_ipv4_import_lookup (client
, length
);
1287 zlog_info ("Zebra received unknown command %d", command
);
1291 if (client
->t_suicide
)
1293 /* No need to wait for thread callback, just kill immediately. */
1294 zebra_client_close(client
);
1298 stream_reset (client
->ibuf
);
1299 zebra_event (ZEBRA_READ
, sock
, client
);
1304 /* Accept code of zebra server socket. */
1306 zebra_accept (struct thread
*thread
)
1310 struct sockaddr_in client
;
1313 accept_sock
= THREAD_FD (thread
);
1315 /* Reregister myself. */
1316 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
1318 len
= sizeof (struct sockaddr_in
);
1319 client_sock
= accept (accept_sock
, (struct sockaddr
*) &client
, &len
);
1321 if (client_sock
< 0)
1323 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno
));
1327 /* Make client socket non-blocking. */
1328 set_nonblocking(client_sock
);
1330 /* Create new zebra client. */
1331 zebra_client_create (client_sock
);
1336 #ifdef HAVE_TCP_ZEBRA
1337 /* Make zebra's server socket. */
1343 struct sockaddr_in addr
;
1345 accept_sock
= socket (AF_INET
, SOCK_STREAM
, 0);
1347 if (accept_sock
< 0)
1349 zlog_warn ("Can't create zserv stream socket: %s",
1350 safe_strerror (errno
));
1351 zlog_warn ("zebra can't provice full functionality due to above error");
1355 memset (&addr
, 0, sizeof (struct sockaddr_in
));
1356 addr
.sin_family
= AF_INET
;
1357 addr
.sin_port
= htons (ZEBRA_PORT
);
1358 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1359 addr
.sin_len
= sizeof (struct sockaddr_in
);
1360 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1361 addr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
1363 sockopt_reuseaddr (accept_sock
);
1364 sockopt_reuseport (accept_sock
);
1366 if ( zserv_privs
.change(ZPRIVS_RAISE
) )
1367 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1369 ret
= bind (accept_sock
, (struct sockaddr
*)&addr
,
1370 sizeof (struct sockaddr_in
));
1373 zlog_warn ("Can't bind to stream socket: %s",
1374 safe_strerror (errno
));
1375 zlog_warn ("zebra can't provice full functionality due to above error");
1376 close (accept_sock
); /* Avoid sd leak. */
1380 if ( zserv_privs
.change(ZPRIVS_LOWER
) )
1381 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1383 ret
= listen (accept_sock
, 1);
1386 zlog_warn ("Can't listen to stream socket: %s",
1387 safe_strerror (errno
));
1388 zlog_warn ("zebra can't provice full functionality due to above error");
1389 close (accept_sock
); /* Avoid sd leak. */
1393 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
1395 #endif /* HAVE_TCP_ZEBRA */
1397 /* For sockaddr_un. */
1400 /* zebra server UNIX domain socket. */
1402 zebra_serv_un (const char *path
)
1406 struct sockaddr_un serv
;
1409 /* First of all, unlink existing socket */
1413 old_mask
= umask (0077);
1415 /* Make UNIX domain socket. */
1416 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
1419 zlog_warn ("Can't create zserv unix socket: %s",
1420 safe_strerror (errno
));
1421 zlog_warn ("zebra can't provide full functionality due to above error");
1425 /* Make server socket. */
1426 memset (&serv
, 0, sizeof (struct sockaddr_un
));
1427 serv
.sun_family
= AF_UNIX
;
1428 strncpy (serv
.sun_path
, path
, strlen (path
));
1429 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1430 len
= serv
.sun_len
= SUN_LEN(&serv
);
1432 len
= sizeof (serv
.sun_family
) + strlen (serv
.sun_path
);
1433 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
1435 ret
= bind (sock
, (struct sockaddr
*) &serv
, len
);
1438 zlog_warn ("Can't bind to unix socket %s: %s",
1439 path
, safe_strerror (errno
));
1440 zlog_warn ("zebra can't provide full functionality due to above error");
1445 ret
= listen (sock
, 5);
1448 zlog_warn ("Can't listen to unix socket %s: %s",
1449 path
, safe_strerror (errno
));
1450 zlog_warn ("zebra can't provide full functionality due to above error");
1457 zebra_event (ZEBRA_SERV
, sock
, NULL
);
1462 zebra_event (enum event event
, int sock
, struct zserv
*client
)
1467 thread_add_read (zebrad
.master
, zebra_accept
, client
, sock
);
1471 thread_add_read (zebrad
.master
, zebra_client_read
, client
, sock
);
1479 /* Display default rtm_table for all clients. */
1484 "default routing table to use for all clients\n")
1486 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
1491 DEFUN (config_table
,
1494 "Configure target kernel routing table\n"
1497 zebrad
.rtm_table_default
= strtol (argv
[0], (char**)0, 10);
1501 DEFUN (ip_forwarding
,
1505 "Turn on IP forwarding")
1511 ret
= ipforward_on ();
1515 vty_out (vty
, "Can't turn on IP forwarding%s", VTY_NEWLINE
);
1522 DEFUN (no_ip_forwarding
,
1523 no_ip_forwarding_cmd
,
1527 "Turn off IP forwarding")
1533 ret
= ipforward_off ();
1537 vty_out (vty
, "Can't turn off IP forwarding%s", VTY_NEWLINE
);
1544 /* This command is for debugging purpose. */
1545 DEFUN (show_zebra_client
,
1546 show_zebra_client_cmd
,
1547 "show zebra client",
1550 "Client information")
1552 struct listnode
*node
;
1553 struct zserv
*client
;
1555 for (ALL_LIST_ELEMENTS_RO (zebrad
.client_list
, node
, client
))
1556 vty_out (vty
, "Client fd %d%s", client
->sock
, VTY_NEWLINE
);
1561 /* Table configuration write function. */
1563 config_write_table (struct vty
*vty
)
1565 if (zebrad
.rtm_table_default
)
1566 vty_out (vty
, "table %d%s", zebrad
.rtm_table_default
,
1571 /* table node for routing tables. */
1572 static struct cmd_node table_node
=
1575 "", /* This node has no interface. */
1579 /* Only display ip forwarding is enabled or not. */
1580 DEFUN (show_ip_forwarding
,
1581 show_ip_forwarding_cmd
,
1582 "show ip forwarding",
1585 "IP forwarding status\n")
1592 vty_out (vty
, "IP forwarding is off%s", VTY_NEWLINE
);
1594 vty_out (vty
, "IP forwarding is on%s", VTY_NEWLINE
);
1599 /* Only display ipv6 forwarding is enabled or not. */
1600 DEFUN (show_ipv6_forwarding
,
1601 show_ipv6_forwarding_cmd
,
1602 "show ipv6 forwarding",
1604 "IPv6 information\n"
1605 "Forwarding status\n")
1609 ret
= ipforward_ipv6 ();
1614 vty_out (vty
, "ipv6 forwarding is unknown%s", VTY_NEWLINE
);
1617 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
1620 vty_out (vty
, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE
);
1623 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
1629 DEFUN (ipv6_forwarding
,
1630 ipv6_forwarding_cmd
,
1633 "Turn on IPv6 forwarding")
1637 ret
= ipforward_ipv6 ();
1639 ret
= ipforward_ipv6_on ();
1643 vty_out (vty
, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE
);
1650 DEFUN (no_ipv6_forwarding
,
1651 no_ipv6_forwarding_cmd
,
1652 "no ipv6 forwarding",
1655 "Turn off IPv6 forwarding")
1659 ret
= ipforward_ipv6 ();
1661 ret
= ipforward_ipv6_off ();
1665 vty_out (vty
, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE
);
1672 #endif /* HAVE_IPV6 */
1674 /* IPForwarding configuration write function. */
1676 config_write_forwarding (struct vty
*vty
)
1678 /* FIXME: Find better place for that. */
1679 router_id_write (vty
);
1682 vty_out (vty
, "ip forwarding%s", VTY_NEWLINE
);
1684 if (ipforward_ipv6 ())
1685 vty_out (vty
, "ipv6 forwarding%s", VTY_NEWLINE
);
1686 #endif /* HAVE_IPV6 */
1687 vty_out (vty
, "!%s", VTY_NEWLINE
);
1691 /* table node for routing tables. */
1692 static struct cmd_node forwarding_node
=
1695 "", /* This node has no interface. */
1700 /* Initialisation of zebra and installation of commands. */
1704 /* Client list init. */
1705 zebrad
.client_list
= list_new ();
1707 /* Install configuration write function. */
1708 install_node (&table_node
, config_write_table
);
1709 install_node (&forwarding_node
, config_write_forwarding
);
1711 install_element (VIEW_NODE
, &show_ip_forwarding_cmd
);
1712 install_element (ENABLE_NODE
, &show_ip_forwarding_cmd
);
1713 install_element (CONFIG_NODE
, &ip_forwarding_cmd
);
1714 install_element (CONFIG_NODE
, &no_ip_forwarding_cmd
);
1715 install_element (ENABLE_NODE
, &show_zebra_client_cmd
);
1718 install_element (VIEW_NODE
, &show_table_cmd
);
1719 install_element (ENABLE_NODE
, &show_table_cmd
);
1720 install_element (CONFIG_NODE
, &config_table_cmd
);
1721 #endif /* HAVE_NETLINK */
1724 install_element (VIEW_NODE
, &show_ipv6_forwarding_cmd
);
1725 install_element (ENABLE_NODE
, &show_ipv6_forwarding_cmd
);
1726 install_element (CONFIG_NODE
, &ipv6_forwarding_cmd
);
1727 install_element (CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
1728 #endif /* HAVE_IPV6 */
1731 zebra_route_map_init ();
1734 /* Make zebra server socket, wiping any existing one (see bug #403). */
1736 zebra_zserv_socket_init (void)
1738 #ifdef HAVE_TCP_ZEBRA
1741 zebra_serv_un (ZEBRA_SERV_PATH
);
1742 #endif /* HAVE_TCP_ZEBRA */