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"
37 #include "zebra/zserv.h"
38 #include "zebra/redistribute.h"
39 #include "zebra/debug.h"
40 #include "zebra/ipforward.h"
42 /* Event list of zebra. */
43 enum event
{ ZEBRA_SERV
, ZEBRA_READ
, ZEBRA_WRITE
};
45 /* Zebra client list. */
48 /* Default rtm_table for all clients */
49 int rtm_table_default
= 0;
51 void zebra_event (enum event event
, int sock
, struct zserv
*client
);
53 /* For logging of zebra meesages. */
54 char *zebra_command_str
[] =
57 "ZEBRA_INTERFACE_ADD",
58 "ZEBRA_INTERFACE_DELETE",
59 "ZEBRA_INTERFACE_ADDRESS_ADD",
60 "ZEBRA_INTERFACE_ADDRESS_DELETE",
62 "ZEBRA_INTERFACE_DOWN",
63 "ZEBRA_IPV4_ROUTE_ADD",
64 "ZEBRA_IPV4_ROUTE_DELETE",
65 "ZEBRA_IPV6_ROUTE_ADD",
66 "ZEBRA_IPV6_ROUTE_DELETE",
67 "ZEBRA_REDISTRIBUTE_ADD",
68 "ZEBRA_REDISTRIBUTE_DELETE",
69 "ZEBRA_REDISTRIBUTE_DEFAULT_ADD",
70 "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE",
71 "ZEBRA_IPV4_NEXTHOP_LOOKUP",
72 "ZEBRA_IPV6_NEXTHOP_LOOKUP",
73 "ZEBRA_IPV4_IMPORT_LOOKUP",
74 "ZEBRA_IPV6_IMPORT_LOOKUP"
77 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
79 zsend_interface_add (struct zserv
*client
, struct interface
*ifp
)
83 /* Check this client need interface information. */
90 /* Place holder for size. */
94 stream_putc (s
, ZEBRA_INTERFACE_ADD
);
96 /* Interface information. */
97 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
98 stream_putl (s
, ifp
->ifindex
);
99 stream_putl (s
, ifp
->flags
);
100 stream_putl (s
, ifp
->metric
);
101 stream_putl (s
, ifp
->mtu
);
102 stream_putl (s
, ifp
->bandwidth
);
103 #ifdef HAVE_SOCKADDR_DL
104 stream_put (s
, &ifp
->sdl
, sizeof (ifp
->sdl
));
106 stream_putl (s
, ifp
->hw_addr_len
);
107 if (ifp
->hw_addr_len
)
108 stream_put (s
, ifp
->hw_addr
, ifp
->hw_addr_len
);
109 #endif /* HAVE_SOCKADDR_DL */
111 /* Write packet size. */
112 stream_putw_at (s
, 0, stream_get_endp (s
));
114 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
117 /* Interface deletion from zebra daemon. */
119 zsend_interface_delete (struct zserv
*client
, struct interface
*ifp
)
123 /* Check this client need interface information. */
124 if (! client
->ifinfo
)
130 /* Packet length placeholder. */
133 /* Interface information. */
134 stream_putc (s
, ZEBRA_INTERFACE_DELETE
);
135 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
136 stream_putl (s
, ifp
->ifindex
);
137 stream_putl (s
, ifp
->flags
);
138 stream_putl (s
, ifp
->metric
);
139 stream_putl (s
, ifp
->mtu
);
140 stream_putl (s
, ifp
->bandwidth
);
142 /* Write packet length. */
143 stream_putw_at (s
, 0, stream_get_endp (s
));
145 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
148 /* Interface address is added. Send ZEBRA_INTERFACE_ADDRESS_ADD to the
151 zsend_interface_address_add (struct zserv
*client
, struct interface
*ifp
,
152 struct connected
*ifc
)
158 /* Check this client need interface information. */
159 if (! client
->ifinfo
)
165 /* Place holder for size. */
168 stream_putc (s
, ZEBRA_INTERFACE_ADDRESS_ADD
);
169 stream_putl (s
, ifp
->ifindex
);
171 /* Interface address flag. */
172 stream_putc (s
, ifc
->flags
);
174 /* Prefix information. */
176 stream_putc (s
, p
->family
);
177 blen
= prefix_blen (p
);
178 stream_put (s
, &p
->u
.prefix
, blen
);
179 stream_putc (s
, p
->prefixlen
);
182 p
= ifc
->destination
;
184 stream_put (s
, &p
->u
.prefix
, blen
);
186 stream_put (s
, NULL
, blen
);
188 /* Write packet size. */
189 stream_putw_at (s
, 0, stream_get_endp (s
));
191 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
194 /* Interface address is deleted. Send ZEBRA_INTERFACE_ADDRESS_DELETE
197 zsend_interface_address_delete (struct zserv
*client
, struct interface
*ifp
,
198 struct connected
*ifc
)
204 /* Check this client need interface information. */
205 if (! client
->ifinfo
)
211 /* Place holder for size. */
214 stream_putc (s
, ZEBRA_INTERFACE_ADDRESS_DELETE
);
215 stream_putl (s
, ifp
->ifindex
);
217 /* Interface address flag. */
218 stream_putc (s
, ifc
->flags
);
220 /* Prefix information. */
222 stream_putc (s
, p
->family
);
223 blen
= prefix_blen (p
);
224 stream_put (s
, &p
->u
.prefix
, blen
);
226 p
= ifc
->destination
;
228 stream_put (s
, &p
->u
.prefix
, blen
);
230 stream_put (s
, NULL
, blen
);
232 /* Write packet size. */
233 stream_putw_at (s
, 0, stream_get_endp (s
));
235 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
239 zsend_interface_up (struct zserv
*client
, struct interface
*ifp
)
243 /* Check this client need interface information. */
244 if (! client
->ifinfo
)
250 /* Place holder for size. */
254 stream_putc (s
, ZEBRA_INTERFACE_UP
);
256 /* Interface information. */
257 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
258 stream_putl (s
, ifp
->ifindex
);
259 stream_putl (s
, ifp
->flags
);
260 stream_putl (s
, ifp
->metric
);
261 stream_putl (s
, ifp
->mtu
);
262 stream_putl (s
, ifp
->bandwidth
);
264 /* Write packet size. */
265 stream_putw_at (s
, 0, stream_get_endp (s
));
267 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
271 zsend_interface_down (struct zserv
*client
, struct interface
*ifp
)
275 /* Check this client need interface information. */
276 if (! client
->ifinfo
)
282 /* Place holder for size. */
286 stream_putc (s
, ZEBRA_INTERFACE_DOWN
);
288 /* Interface information. */
289 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
290 stream_putl (s
, ifp
->ifindex
);
291 stream_putl (s
, ifp
->flags
);
292 stream_putl (s
, ifp
->metric
);
293 stream_putl (s
, ifp
->mtu
);
294 stream_putl (s
, ifp
->bandwidth
);
296 /* Write packet size. */
297 stream_putw_at (s
, 0, stream_get_endp (s
));
299 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
303 zsend_ipv4_add_multipath (struct zserv
*client
, struct prefix
*p
,
308 struct nexthop
*nexthop
;
309 struct in_addr empty
;
315 /* Place holder for size. */
318 /* Put command, type and nexthop. */
319 stream_putc (s
, ZEBRA_IPV4_ROUTE_ADD
);
320 stream_putc (s
, rib
->type
);
321 stream_putc (s
, rib
->flags
);
322 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
| ZAPI_MESSAGE_IFINDEX
| ZAPI_MESSAGE_METRIC
);
325 psize
= PSIZE (p
->prefixlen
);
326 stream_putc (s
, p
->prefixlen
);
327 stream_write (s
, (u_char
*)&p
->u
.prefix
, psize
);
330 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
332 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
336 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
337 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
338 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
340 stream_put_in_addr (s
, &empty
);
342 /* Interface index. */
344 stream_putl (s
, nexthop
->ifindex
);
351 stream_putl (s
, rib
->metric
);
353 /* Write packet size. */
354 stream_putw_at (s
, 0, stream_get_endp (s
));
356 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
360 zsend_ipv4_delete_multipath (struct zserv
*client
, struct prefix
*p
,
365 struct nexthop
*nexthop
;
366 struct in_addr empty
;
373 /* Place holder for size. */
376 /* Put command, type and nexthop. */
377 stream_putc (s
, ZEBRA_IPV4_ROUTE_DELETE
);
378 stream_putc (s
, rib
->type
);
379 stream_putc (s
, rib
->flags
);
380 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
383 psize
= PSIZE (p
->prefixlen
);
384 stream_putc (s
, p
->prefixlen
);
385 stream_write (s
, (u_char
*)&p
->u
.prefix
, psize
);
388 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
390 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
394 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
)
395 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
397 stream_put_in_addr (s
, &empty
);
399 /* Interface index. */
401 stream_putl (s
, nexthop
->ifindex
);
407 /* Write packet size. */
408 stream_putw_at (s
, 0, stream_get_endp (s
));
410 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
414 zsend_ipv4_add (struct zserv
*client
, int type
, int flags
,
415 struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
416 unsigned int ifindex
)
424 /* Place holder for size. */
427 /* Put command, type and nexthop. */
428 stream_putc (s
, ZEBRA_IPV4_ROUTE_ADD
);
429 stream_putc (s
, type
);
430 stream_putc (s
, flags
);
431 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
434 psize
= PSIZE (p
->prefixlen
);
435 stream_putc (s
, p
->prefixlen
);
436 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
440 stream_put_in_addr (s
, nexthop
);
442 /* Interface index. */
444 stream_putl (s
, ifindex
);
446 /* Write packet size. */
447 stream_putw_at (s
, 0, stream_get_endp (s
));
449 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
453 zsend_ipv4_delete (struct zserv
*client
, int type
, int flags
,
454 struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
455 unsigned int ifindex
)
463 /* Place holder for size. */
466 /* Put command, type and nexthop. */
467 stream_putc (s
, ZEBRA_IPV4_ROUTE_DELETE
);
468 stream_putc (s
, type
);
469 stream_putc (s
, flags
);
470 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
473 psize
= PSIZE (p
->prefixlen
);
474 stream_putc (s
, p
->prefixlen
);
475 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
479 stream_put_in_addr (s
, nexthop
);
481 /* Interface index. */
483 stream_putl (s
, ifindex
);
485 /* Write packet size. */
486 stream_putw_at (s
, 0, stream_get_endp (s
));
488 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
493 zsend_ipv6_add (struct zserv
*client
, int type
, int flags
,
494 struct prefix_ipv6
*p
, struct in6_addr
*nexthop
,
495 unsigned int ifindex
)
503 /* Place holder for size. */
506 /* Put command, type and nexthop. */
507 stream_putc (s
, ZEBRA_IPV6_ROUTE_ADD
);
508 stream_putc (s
, type
);
509 stream_putc (s
, flags
);
510 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
513 psize
= PSIZE (p
->prefixlen
);
514 stream_putc (s
, p
->prefixlen
);
515 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
519 stream_write (s
, (u_char
*)nexthop
, 16);
521 /* Interface index. */
523 stream_putl (s
, ifindex
);
525 /* Write packet size. */
526 stream_putw_at (s
, 0, stream_get_endp (s
));
528 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
532 zsend_ipv6_add_multipath (struct zserv
*client
, struct prefix
*p
,
537 struct nexthop
*nexthop
;
538 struct in6_addr empty
;
540 memset (&empty
, 0, sizeof (struct in6_addr
));
544 /* Place holder for size. */
547 /* Put command, type and nexthop. */
548 stream_putc (s
, ZEBRA_IPV6_ROUTE_ADD
);
549 stream_putc (s
, rib
->type
);
550 stream_putc (s
, rib
->flags
);
551 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
| ZAPI_MESSAGE_IFINDEX
| ZAPI_MESSAGE_METRIC
);
554 psize
= PSIZE (p
->prefixlen
);
555 stream_putc (s
, p
->prefixlen
);
556 stream_write (s
, (u_char
*) &p
->u
.prefix
, psize
);
559 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
561 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
565 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
)
566 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
568 stream_write (s
, (u_char
*) &empty
, 16);
570 /* Interface index. */
572 stream_putl (s
, nexthop
->ifindex
);
579 stream_putl (s
, rib
->metric
);
581 /* Write packet size. */
582 stream_putw_at (s
, 0, stream_get_endp (s
));
584 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
588 zsend_ipv6_delete (struct zserv
*client
, int type
, int flags
,
589 struct prefix_ipv6
*p
, struct in6_addr
*nexthop
,
590 unsigned int ifindex
)
598 /* Place holder for size. */
601 /* Put command, type and nexthop. */
602 stream_putc (s
, ZEBRA_IPV6_ROUTE_DELETE
);
603 stream_putc (s
, type
);
604 stream_putc (s
, flags
);
605 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
608 psize
= PSIZE (p
->prefixlen
);
609 stream_putc (s
, p
->prefixlen
);
610 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
614 stream_write (s
, (u_char
*)nexthop
, 16);
616 /* Interface index. */
618 stream_putl (s
, ifindex
);
620 /* Write packet size. */
621 stream_putw_at (s
, 0, stream_get_endp (s
));
623 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
627 zsend_ipv6_delete_multipath (struct zserv
*client
, struct prefix
*p
,
632 struct nexthop
*nexthop
;
633 struct in6_addr empty
;
635 memset (&empty
, 0, sizeof (struct in6_addr
));
639 /* Place holder for size. */
642 /* Put command, type and nexthop. */
643 stream_putc (s
, ZEBRA_IPV6_ROUTE_DELETE
);
644 stream_putc (s
, rib
->type
);
645 stream_putc (s
, rib
->flags
);
646 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
649 psize
= PSIZE (p
->prefixlen
);
650 stream_putc (s
, p
->prefixlen
);
651 stream_write (s
, (u_char
*)&p
->u
.prefix
, psize
);
654 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
656 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
660 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
)
661 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
663 stream_write (s
, (u_char
*) &empty
, 16);
665 /* Interface index. */
667 stream_putl (s
, nexthop
->ifindex
);
673 /* Write packet size. */
674 stream_putw_at (s
, 0, stream_get_endp (s
));
676 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
680 zsend_ipv6_nexthop_lookup (struct zserv
*client
, struct in6_addr
*addr
)
686 struct nexthop
*nexthop
;
688 /* Lookup nexthop. */
689 rib
= rib_match_ipv6 (addr
);
691 /* Get output stream. */
695 /* Fill in result. */
697 stream_putc (s
, ZEBRA_IPV6_NEXTHOP_LOOKUP
);
698 stream_put (s
, &addr
, 16);
702 stream_putl (s
, rib
->metric
);
706 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
707 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
709 stream_putc (s
, nexthop
->type
);
710 switch (nexthop
->type
)
712 case ZEBRA_NEXTHOP_IPV6
:
713 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
715 case ZEBRA_NEXTHOP_IPV6_IFINDEX
:
716 case ZEBRA_NEXTHOP_IPV6_IFNAME
:
717 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
718 stream_putl (s
, nexthop
->ifindex
);
720 case ZEBRA_NEXTHOP_IFINDEX
:
721 case ZEBRA_NEXTHOP_IFNAME
:
722 stream_putl (s
, nexthop
->ifindex
);
727 stream_putc_at (s
, nump
, num
);
735 stream_putw_at (s
, 0, stream_get_endp (s
));
737 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
739 #endif /* HAVE_IPV6 */
742 zsend_ipv4_nexthop_lookup (struct zserv
*client
, struct in_addr addr
)
748 struct nexthop
*nexthop
;
750 /* Lookup nexthop. */
751 rib
= rib_match_ipv4 (addr
);
753 /* Get output stream. */
757 /* Fill in result. */
759 stream_putc (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP
);
760 stream_put_in_addr (s
, &addr
);
764 stream_putl (s
, rib
->metric
);
768 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
769 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
771 stream_putc (s
, nexthop
->type
);
772 switch (nexthop
->type
)
774 case ZEBRA_NEXTHOP_IPV4
:
775 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
777 case ZEBRA_NEXTHOP_IFINDEX
:
778 case ZEBRA_NEXTHOP_IFNAME
:
779 stream_putl (s
, nexthop
->ifindex
);
784 stream_putc_at (s
, nump
, num
);
792 stream_putw_at (s
, 0, stream_get_endp (s
));
794 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
798 zsend_ipv4_import_lookup (struct zserv
*client
, struct prefix_ipv4
*p
)
804 struct nexthop
*nexthop
;
806 /* Lookup nexthop. */
807 rib
= rib_lookup_ipv4 (p
);
809 /* Get output stream. */
813 /* Fill in result. */
815 stream_putc (s
, ZEBRA_IPV4_IMPORT_LOOKUP
);
816 stream_put_in_addr (s
, &p
->prefix
);
820 stream_putl (s
, rib
->metric
);
824 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
825 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
827 stream_putc (s
, nexthop
->type
);
828 switch (nexthop
->type
)
830 case ZEBRA_NEXTHOP_IPV4
:
831 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
833 case ZEBRA_NEXTHOP_IFINDEX
:
834 case ZEBRA_NEXTHOP_IFNAME
:
835 stream_putl (s
, nexthop
->ifindex
);
840 stream_putc_at (s
, nump
, num
);
848 stream_putw_at (s
, 0, stream_get_endp (s
));
850 return writen (client
->sock
, s
->data
, stream_get_endp (s
));
853 /* Register zebra server interface information. Send current all
854 interface and address information. */
856 zread_interface_add (struct zserv
*client
, u_short length
)
860 struct interface
*ifp
;
863 /* Interface information is needed. */
866 for (ifnode
= listhead (iflist
); ifnode
; ifnode
= nextnode (ifnode
))
868 ifp
= getdata (ifnode
);
870 /* Skip pseudo interface. */
871 if (! CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
874 zsend_interface_add (client
, ifp
);
876 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
879 if (CHECK_FLAG (c
->conf
, ZEBRA_IFC_REAL
))
880 zsend_interface_address_add (client
, ifp
, c
);
885 /* Unregister zebra server interface information. */
887 zread_interface_delete (struct zserv
*client
, u_short length
)
892 /* This function support multiple nexthop. */
894 zread_ipv4_add (struct zserv
*client
, u_short length
)
898 struct prefix_ipv4 p
;
900 struct in_addr nexthop
;
904 unsigned int ifindex
;
907 /* Get input stream. */
910 /* Allocate new rib. */
911 rib
= XMALLOC (MTYPE_RIB
, sizeof (struct rib
));
912 memset (rib
, 0, sizeof (struct rib
));
914 /* Type, flags, message. */
915 rib
->type
= stream_getc (s
);
916 rib
->flags
= stream_getc (s
);
917 message
= stream_getc (s
);
918 rib
->uptime
= time (NULL
);
921 memset (&p
, 0, sizeof (struct prefix_ipv4
));
923 p
.prefixlen
= stream_getc (s
);
924 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
927 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
929 nexthop_num
= stream_getc (s
);
931 for (i
= 0; i
< nexthop_num
; i
++)
933 nexthop_type
= stream_getc (s
);
935 switch (nexthop_type
)
937 case ZEBRA_NEXTHOP_IFINDEX
:
938 ifindex
= stream_getl (s
);
939 nexthop_ifindex_add (rib
, ifindex
);
941 case ZEBRA_NEXTHOP_IFNAME
:
942 ifname_len
= stream_getc (s
);
943 stream_forward (s
, ifname_len
);
945 case ZEBRA_NEXTHOP_IPV4
:
946 nexthop
.s_addr
= stream_get_ipv4 (s
);
947 nexthop_ipv4_add (rib
, &nexthop
);
949 case ZEBRA_NEXTHOP_IPV6
:
950 stream_forward (s
, IPV6_MAX_BYTELEN
);
957 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
958 rib
->distance
= stream_getc (s
);
961 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
962 rib
->metric
= stream_getl (s
);
964 rib_add_ipv4_multipath (&p
, rib
);
967 /* Zebra server IPv4 prefix delete function. */
969 zread_ipv4_delete (struct zserv
*client
, u_short length
)
973 struct zapi_ipv4 api
;
974 struct in_addr nexthop
;
975 unsigned long ifindex
;
976 struct prefix_ipv4 p
;
985 /* Type, flags, message. */
986 api
.type
= stream_getc (s
);
987 api
.flags
= stream_getc (s
);
988 api
.message
= stream_getc (s
);
991 memset (&p
, 0, sizeof (struct prefix_ipv4
));
993 p
.prefixlen
= stream_getc (s
);
994 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
996 /* Nexthop, ifindex, distance, metric. */
997 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
999 nexthop_num
= stream_getc (s
);
1001 for (i
= 0; i
< nexthop_num
; i
++)
1003 nexthop_type
= stream_getc (s
);
1005 switch (nexthop_type
)
1007 case ZEBRA_NEXTHOP_IFINDEX
:
1008 ifindex
= stream_getl (s
);
1010 case ZEBRA_NEXTHOP_IFNAME
:
1011 ifname_len
= stream_getc (s
);
1012 stream_forward (s
, ifname_len
);
1014 case ZEBRA_NEXTHOP_IPV4
:
1015 nexthop
.s_addr
= stream_get_ipv4 (s
);
1017 case ZEBRA_NEXTHOP_IPV6
:
1018 stream_forward (s
, IPV6_MAX_BYTELEN
);
1025 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1026 api
.distance
= stream_getc (s
);
1031 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1032 api
.metric
= stream_getl (s
);
1036 rib_delete_ipv4 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
,
1040 /* Nexthop lookup for IPv4. */
1042 zread_ipv4_nexthop_lookup (struct zserv
*client
, u_short length
)
1044 struct in_addr addr
;
1046 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1047 zsend_ipv4_nexthop_lookup (client
, addr
);
1050 /* Nexthop lookup for IPv4. */
1052 zread_ipv4_import_lookup (struct zserv
*client
, u_short length
)
1054 struct prefix_ipv4 p
;
1057 p
.prefixlen
= stream_getc (client
->ibuf
);
1058 p
.prefix
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1060 zsend_ipv4_import_lookup (client
, &p
);
1064 /* Zebra server IPv6 prefix add function. */
1066 zread_ipv6_add (struct zserv
*client
, u_short length
)
1070 struct zapi_ipv6 api
;
1071 struct in6_addr nexthop
;
1072 unsigned long ifindex
;
1073 struct prefix_ipv6 p
;
1077 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1079 /* Type, flags, message. */
1080 api
.type
= stream_getc (s
);
1081 api
.flags
= stream_getc (s
);
1082 api
.message
= stream_getc (s
);
1085 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1086 p
.family
= AF_INET6
;
1087 p
.prefixlen
= stream_getc (s
);
1088 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1090 /* Nexthop, ifindex, distance, metric. */
1091 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1093 u_char nexthop_type
;
1095 api
.nexthop_num
= stream_getc (s
);
1096 for (i
= 0; i
< api
.nexthop_num
; i
++)
1098 nexthop_type
= stream_getc (s
);
1100 switch (nexthop_type
)
1102 case ZEBRA_NEXTHOP_IPV6
:
1103 stream_get (&nexthop
, s
, 16);
1105 case ZEBRA_NEXTHOP_IFINDEX
:
1106 ifindex
= stream_getl (s
);
1112 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1113 api
.distance
= stream_getc (s
);
1117 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1118 api
.metric
= stream_getl (s
);
1122 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1123 rib_add_ipv6 (api
.type
, api
.flags
, &p
, NULL
, ifindex
, 0);
1125 rib_add_ipv6 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
, 0);
1128 /* Zebra server IPv6 prefix delete function. */
1130 zread_ipv6_delete (struct zserv
*client
, u_short length
)
1134 struct zapi_ipv6 api
;
1135 struct in6_addr nexthop
;
1136 unsigned long ifindex
;
1137 struct prefix_ipv6 p
;
1141 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1143 /* Type, flags, message. */
1144 api
.type
= stream_getc (s
);
1145 api
.flags
= stream_getc (s
);
1146 api
.message
= stream_getc (s
);
1149 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1150 p
.family
= AF_INET6
;
1151 p
.prefixlen
= stream_getc (s
);
1152 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1154 /* Nexthop, ifindex, distance, metric. */
1155 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1157 u_char nexthop_type
;
1159 api
.nexthop_num
= stream_getc (s
);
1160 for (i
= 0; i
< api
.nexthop_num
; i
++)
1162 nexthop_type
= stream_getc (s
);
1164 switch (nexthop_type
)
1166 case ZEBRA_NEXTHOP_IPV6
:
1167 stream_get (&nexthop
, s
, 16);
1169 case ZEBRA_NEXTHOP_IFINDEX
:
1170 ifindex
= stream_getl (s
);
1176 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1177 api
.distance
= stream_getc (s
);
1180 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1181 api
.metric
= stream_getl (s
);
1185 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1186 rib_delete_ipv6 (api
.type
, api
.flags
, &p
, NULL
, ifindex
, 0);
1188 rib_delete_ipv6 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
, 0);
1192 zebra_read_ipv6 (int command
, struct zserv
*client
, u_short length
)
1196 struct in6_addr nexthop
, *gate
;
1199 unsigned int ifindex
;
1201 pnt
= stream_pnt (client
->ibuf
);
1204 type
= stream_getc (client
->ibuf
);
1205 flags
= stream_getc (client
->ibuf
);
1206 stream_get (&nexthop
, client
->ibuf
, sizeof (struct in6_addr
));
1208 while (stream_pnt (client
->ibuf
) < lim
)
1211 struct prefix_ipv6 p
;
1213 ifindex
= stream_getl (client
->ibuf
);
1215 bzero (&p
, sizeof (struct prefix_ipv6
));
1216 p
.family
= AF_INET6
;
1217 p
.prefixlen
= stream_getc (client
->ibuf
);
1218 size
= PSIZE(p
.prefixlen
);
1219 stream_get (&p
.prefix
, client
->ibuf
, size
);
1221 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1226 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
1227 rib_add_ipv6 (type
, flags
, &p
, gate
, ifindex
, 0);
1229 rib_delete_ipv6 (type
, flags
, &p
, gate
, ifindex
, 0);
1234 zread_ipv6_nexthop_lookup (struct zserv
*client
, u_short length
)
1236 struct in6_addr addr
;
1239 stream_get (&addr
, client
->ibuf
, 16);
1240 printf ("DEBUG %s\n", inet_ntop (AF_INET6
, &addr
, buf
, BUFSIZ
));
1242 zsend_ipv6_nexthop_lookup (client
, &addr
);
1244 #endif /* HAVE_IPV6 */
1246 /* Close zebra client. */
1248 zebra_client_close (struct zserv
*client
)
1250 /* Close file descriptor. */
1253 close (client
->sock
);
1257 /* Free stream buffers. */
1259 stream_free (client
->ibuf
);
1261 stream_free (client
->obuf
);
1263 /* Release threads. */
1265 thread_cancel (client
->t_read
);
1266 if (client
->t_write
)
1267 thread_cancel (client
->t_write
);
1269 /* Free client structure. */
1270 listnode_delete (client_list
, client
);
1274 /* Make new client. */
1276 zebra_client_create (int sock
)
1278 struct zserv
*client
;
1280 client
= XMALLOC (0, sizeof (struct zserv
));
1281 bzero (client
, sizeof (struct zserv
));
1283 /* Make client input/output buffer. */
1284 client
->sock
= sock
;
1285 client
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1286 client
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1288 /* Set table number. */
1289 client
->rtm_table
= rtm_table_default
;
1291 /* Add this client to linked list. */
1292 listnode_add (client_list
, client
);
1294 /* Make new read thread. */
1295 zebra_event (ZEBRA_READ
, sock
, client
);
1298 /* Handler of zebra service request. */
1300 zebra_client_read (struct thread
*thread
)
1303 struct zserv
*client
;
1308 /* Get thread data. Reset reading thread because I'm running. */
1309 sock
= THREAD_FD (thread
);
1310 client
= THREAD_ARG (thread
);
1311 client
->t_read
= NULL
;
1313 /* Read length and command. */
1314 nbyte
= stream_read (client
->ibuf
, sock
, 3);
1317 if (IS_ZEBRA_DEBUG_EVENT
)
1318 zlog_info ("connection closed socket [%d]", sock
);
1319 zebra_client_close (client
);
1322 length
= stream_getw (client
->ibuf
);
1323 command
= stream_getc (client
->ibuf
);
1327 if (IS_ZEBRA_DEBUG_EVENT
)
1328 zlog_info ("length %d is less than 3 ", length
);
1329 zebra_client_close (client
);
1335 /* Read rest of data. */
1338 nbyte
= stream_read (client
->ibuf
, sock
, length
);
1341 if (IS_ZEBRA_DEBUG_EVENT
)
1342 zlog_info ("connection closed [%d] when reading zebra data", sock
);
1343 zebra_client_close (client
);
1348 /* Debug packet information. */
1349 if (IS_ZEBRA_DEBUG_EVENT
)
1350 zlog_info ("zebra message comes from socket [%d]", sock
);
1352 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1353 zlog_info ("zebra message received [%s] %d",
1354 zebra_command_str
[command
], length
);
1358 case ZEBRA_INTERFACE_ADD
:
1359 zread_interface_add (client
, length
);
1361 case ZEBRA_INTERFACE_DELETE
:
1362 zread_interface_delete (client
, length
);
1364 case ZEBRA_IPV4_ROUTE_ADD
:
1365 zread_ipv4_add (client
, length
);
1367 case ZEBRA_IPV4_ROUTE_DELETE
:
1368 zread_ipv4_delete (client
, length
);
1371 case ZEBRA_IPV6_ROUTE_ADD
:
1372 zread_ipv6_add (client
, length
);
1374 case ZEBRA_IPV6_ROUTE_DELETE
:
1375 zread_ipv6_delete (client
, length
);
1377 #endif /* HAVE_IPV6 */
1378 case ZEBRA_REDISTRIBUTE_ADD
:
1379 zebra_redistribute_add (command
, client
, length
);
1381 case ZEBRA_REDISTRIBUTE_DELETE
:
1382 zebra_redistribute_delete (command
, client
, length
);
1384 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD
:
1385 zebra_redistribute_default_add (command
, client
, length
);
1387 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
:
1388 zebra_redistribute_default_delete (command
, client
, length
);
1390 case ZEBRA_IPV4_NEXTHOP_LOOKUP
:
1391 zread_ipv4_nexthop_lookup (client
, length
);
1394 case ZEBRA_IPV6_NEXTHOP_LOOKUP
:
1395 zread_ipv6_nexthop_lookup (client
, length
);
1397 #endif /* HAVE_IPV6 */
1398 case ZEBRA_IPV4_IMPORT_LOOKUP
:
1399 zread_ipv4_import_lookup (client
, length
);
1402 zlog_info ("Zebra received unknown command %d", command
);
1406 stream_reset (client
->ibuf
);
1407 zebra_event (ZEBRA_READ
, sock
, client
);
1412 /* Write output buffer to the socket. */
1414 zebra_write (struct thread
*thread
)
1417 struct zserv
*client
;
1419 /* Thread treatment. */
1420 sock
= THREAD_FD (thread
);
1421 client
= THREAD_ARG (thread
);
1422 client
->t_write
= NULL
;
1424 stream_flush (client
->obuf
, sock
);
1427 /* Accept code of zebra server socket. */
1429 zebra_accept (struct thread
*thread
)
1433 struct sockaddr_in client
;
1436 accept_sock
= THREAD_FD (thread
);
1438 len
= sizeof (struct sockaddr_in
);
1439 client_sock
= accept (accept_sock
, (struct sockaddr
*) &client
, &len
);
1441 if (client_sock
< 0)
1443 zlog_warn ("Can't accept zebra socket: %s", strerror (errno
));
1447 /* Create new zebra client. */
1448 zebra_client_create (client_sock
);
1450 /* Register myself. */
1451 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
1456 /* Make zebra's server socket. */
1462 struct sockaddr_in addr
;
1464 accept_sock
= socket (AF_INET
, SOCK_STREAM
, 0);
1466 if (accept_sock
< 0)
1468 zlog_warn ("Can't bind to socket: %s", strerror (errno
));
1469 zlog_warn ("zebra can't provice full functionality due to above error");
1473 memset (&addr
, 0, sizeof (struct sockaddr_in
));
1474 addr
.sin_family
= AF_INET
;
1475 addr
.sin_port
= htons (ZEBRA_PORT
);
1477 addr
.sin_len
= sizeof (struct sockaddr_in
);
1478 #endif /* HAVE_SIN_LEN */
1479 addr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
1481 sockopt_reuseaddr (accept_sock
);
1482 sockopt_reuseport (accept_sock
);
1484 ret
= bind (accept_sock
, (struct sockaddr
*)&addr
,
1485 sizeof (struct sockaddr_in
));
1488 zlog_warn ("Can't bind to socket: %s", strerror (errno
));
1489 zlog_warn ("zebra can't provice full functionality due to above error");
1490 close (accept_sock
); /* Avoid sd leak. */
1494 ret
= listen (accept_sock
, 1);
1497 zlog_warn ("Can't listen to socket: %s", strerror (errno
));
1498 zlog_warn ("zebra can't provice full functionality due to above error");
1499 close (accept_sock
); /* Avoid sd leak. */
1503 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
1506 /* For sockaddr_un. */
1509 /* zebra server UNIX domain socket. */
1511 zebra_serv_un (char *path
)
1515 struct sockaddr_un serv
;
1518 /* First of all, unlink existing socket */
1522 old_mask
= umask (0077);
1524 /* Make UNIX domain socket. */
1525 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
1532 /* Make server socket. */
1533 memset (&serv
, 0, sizeof (struct sockaddr_un
));
1534 serv
.sun_family
= AF_UNIX
;
1535 strncpy (serv
.sun_path
, path
, strlen (path
));
1537 len
= serv
.sun_len
= SUN_LEN(&serv
);
1539 len
= sizeof (serv
.sun_family
) + strlen (serv
.sun_path
);
1540 #endif /* HAVE_SUN_LEN */
1542 ret
= bind (sock
, (struct sockaddr
*) &serv
, len
);
1550 ret
= listen (sock
, 5);
1560 zebra_event (ZEBRA_SERV
, sock
, NULL
);
1563 /* Zebra's event management function. */
1564 extern struct thread_master
*master
;
1567 zebra_event (enum event event
, int sock
, struct zserv
*client
)
1572 thread_add_read (master
, zebra_accept
, client
, sock
);
1576 thread_add_read (master
, zebra_client_read
, client
, sock
);
1584 /* Display default rtm_table for all clients. */
1589 "default routing table to use for all clients\n")
1591 vty_out (vty
, "table %d%s", rtm_table_default
,
1596 DEFUN (config_table
,
1599 "Configure target kernel routing table\n"
1602 rtm_table_default
= strtol (argv
[0], (char**)0, 10);
1606 DEFUN (no_ip_forwarding
,
1607 no_ip_forwarding_cmd
,
1611 "Turn off IP forwarding")
1619 vty_out (vty
, "IP forwarding is already off%s", VTY_NEWLINE
);
1620 return CMD_ERR_NOTHING_TODO
;
1623 ret
= ipforward_off ();
1626 vty_out (vty
, "Can't turn off IP forwarding%s", VTY_NEWLINE
);
1633 /* This command is for debugging purpose. */
1634 DEFUN (show_zebra_client
,
1635 show_zebra_client_cmd
,
1636 "show zebra client",
1639 "Client information")
1642 struct zserv
*client
;
1644 for (node
= listhead (client_list
); node
; nextnode (node
))
1646 client
= getdata (node
);
1647 vty_out (vty
, "Client fd %d%s", client
->sock
, VTY_NEWLINE
);
1652 /* Table configuration write function. */
1654 config_write_table (struct vty
*vty
)
1656 if (rtm_table_default
)
1657 vty_out (vty
, "table %d%s", rtm_table_default
,
1662 /* table node for routing tables. */
1663 struct cmd_node table_node
=
1666 "", /* This node has no interface. */
1670 /* Only display ip forwarding is enabled or not. */
1671 DEFUN (show_ip_forwarding
,
1672 show_ip_forwarding_cmd
,
1673 "show ip forwarding",
1676 "IP forwarding status\n")
1683 vty_out (vty
, "IP forwarding is off%s", VTY_NEWLINE
);
1685 vty_out (vty
, "IP forwarding is on%s", VTY_NEWLINE
);
1690 /* Only display ipv6 forwarding is enabled or not. */
1691 DEFUN (show_ipv6_forwarding
,
1692 show_ipv6_forwarding_cmd
,
1693 "show ipv6 forwarding",
1695 "IPv6 information\n"
1696 "Forwarding status\n")
1700 ret
= ipforward_ipv6 ();
1705 vty_out (vty
, "ipv6 forwarding is unknown%s", VTY_NEWLINE
);
1708 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
1711 vty_out (vty
, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE
);
1714 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
1720 DEFUN (no_ipv6_forwarding
,
1721 no_ipv6_forwarding_cmd
,
1722 "no ipv6 forwarding",
1725 "Doesn't forward IPv6 protocol packet")
1729 ret
= ipforward_ipv6_off ();
1732 vty_out (vty
, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE
);
1739 #endif /* HAVE_IPV6 */
1742 /* Initialisation of zebra and installation of commands. */
1746 /* Client list init. */
1747 client_list
= list_new ();
1749 /* Forwarding on. */
1752 ipforward_ipv6_on ();
1753 #endif /* HAVE_IPV6 */
1755 /* Make zebra server socket. */
1756 #ifdef HAVE_TCP_ZEBRA
1759 zebra_serv_un (ZEBRA_SERV_PATH
);
1760 #endif /* HAVE_TCP_ZEBRA */
1762 /* Install configuration write function. */
1763 install_node (&table_node
, config_write_table
);
1765 install_element (VIEW_NODE
, &show_ip_forwarding_cmd
);
1766 install_element (ENABLE_NODE
, &show_ip_forwarding_cmd
);
1767 install_element (CONFIG_NODE
, &no_ip_forwarding_cmd
);
1768 install_element (ENABLE_NODE
, &show_zebra_client_cmd
);
1770 #ifdef HAVE_LINUX_RTNETLINK_H
1771 install_element (VIEW_NODE
, &show_table_cmd
);
1772 install_element (ENABLE_NODE
, &show_table_cmd
);
1773 install_element (CONFIG_NODE
, &config_table_cmd
);
1777 install_element (VIEW_NODE
, &show_ipv6_forwarding_cmd
);
1778 install_element (ENABLE_NODE
, &show_ipv6_forwarding_cmd
);
1779 install_element (CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
1780 #endif /* HAVE_IPV6 */