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"
38 #include "zebra/zserv.h"
39 #include "zebra/redistribute.h"
40 #include "zebra/debug.h"
41 #include "zebra/ipforward.h"
43 /* Event list of zebra. */
44 enum event
{ ZEBRA_SERV
, ZEBRA_READ
, ZEBRA_WRITE
};
46 /* Zebra client list. */
49 /* Default rtm_table for all clients */
50 int rtm_table_default
= 0;
52 void zebra_event (enum event event
, int sock
, struct zserv
*client
);
54 extern struct zebra_privs_t zserv_privs
;
56 extern struct thread_master
*master
;
58 /* For logging of zebra meesages. */
59 char *zebra_command_str
[] =
62 "ZEBRA_INTERFACE_ADD",
63 "ZEBRA_INTERFACE_DELETE",
64 "ZEBRA_INTERFACE_ADDRESS_ADD",
65 "ZEBRA_INTERFACE_ADDRESS_DELETE",
67 "ZEBRA_INTERFACE_DOWN",
68 "ZEBRA_IPV4_ROUTE_ADD",
69 "ZEBRA_IPV4_ROUTE_DELETE",
70 "ZEBRA_IPV6_ROUTE_ADD",
71 "ZEBRA_IPV6_ROUTE_DELETE",
72 "ZEBRA_REDISTRIBUTE_ADD",
73 "ZEBRA_REDISTRIBUTE_DELETE",
74 "ZEBRA_REDISTRIBUTE_DEFAULT_ADD",
75 "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE",
76 "ZEBRA_IPV4_NEXTHOP_LOOKUP",
77 "ZEBRA_IPV6_NEXTHOP_LOOKUP",
78 "ZEBRA_IPV4_IMPORT_LOOKUP",
79 "ZEBRA_IPV6_IMPORT_LOOKUP"
82 struct zebra_message_queue
84 struct nsm_message_queue
*next
;
85 struct nsm_message_queue
*prev
;
92 struct thread
*t_write
;
93 struct fifo message_queue
;
96 zebra_server_dequeue (struct thread
*t
)
100 struct zebra_message_queue
*queue
;
102 sock
= THREAD_FD (t
);
105 queue
= (struct zebra_message_queue
*) FIFO_HEAD (&message_queue
);
108 nbytes
= write (sock
, queue
->buf
+ queue
->written
,
109 queue
->length
- queue
->written
);
116 else if (nbytes
!= (queue
->length
- queue
->written
))
118 queue
->written
+= nbytes
;
123 XFREE (MTYPE_TMP
, queue
->buf
);
124 XFREE (MTYPE_TMP
, queue
);
128 if (FIFO_TOP (&message_queue
))
129 THREAD_WRITE_ON (master
, t_write
, zebra_server_dequeue
, NULL
, sock
);
134 /* Enqueu message. */
136 zebra_server_enqueue (int sock
, u_char
*buf
, unsigned long length
,
137 unsigned long written
)
139 struct zebra_message_queue
*queue
;
141 queue
= XCALLOC (MTYPE_TMP
, sizeof (struct zebra_message_queue
));
142 queue
->buf
= XMALLOC (MTYPE_TMP
, length
);
143 memcpy (queue
->buf
, buf
, length
);
144 queue
->length
= length
;
145 queue
->written
= written
;
147 FIFO_ADD (&message_queue
, queue
);
149 THREAD_WRITE_ON (master
, t_write
, zebra_server_dequeue
, NULL
, sock
);
153 zebra_server_send_message (int sock
, u_char
*buf
, unsigned long length
)
157 if (FIFO_TOP (&message_queue
))
159 zebra_server_enqueue (sock
, buf
, length
, 0);
164 nbytes
= write (sock
, buf
, length
);
169 zebra_server_enqueue (sock
, buf
, length
, 0);
173 else if (nbytes
!= length
)
174 zebra_server_enqueue (sock
, buf
, length
, nbytes
);
179 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
181 zsend_interface_add (struct zserv
*client
, struct interface
*ifp
)
185 /* Check this client need interface information. */
186 if (! client
->ifinfo
)
192 /* Place holder for size. */
196 stream_putc (s
, ZEBRA_INTERFACE_ADD
);
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_putl (s
, ifp
->flags
);
203 stream_putl (s
, ifp
->metric
);
204 stream_putl (s
, ifp
->mtu
);
205 stream_putl (s
, ifp
->bandwidth
);
206 #ifdef HAVE_SOCKADDR_DL
207 stream_put (s
, &ifp
->sdl
, sizeof (ifp
->sdl
));
209 stream_putl (s
, ifp
->hw_addr_len
);
210 if (ifp
->hw_addr_len
)
211 stream_put (s
, ifp
->hw_addr
, ifp
->hw_addr_len
);
212 #endif /* HAVE_SOCKADDR_DL */
214 /* Write packet size. */
215 stream_putw_at (s
, 0, stream_get_endp (s
));
217 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
222 /* Interface deletion from zebra daemon. */
224 zsend_interface_delete (struct zserv
*client
, struct interface
*ifp
)
228 /* Check this client need interface information. */
229 if (! client
->ifinfo
)
235 /* Packet length placeholder. */
238 /* Interface information. */
239 stream_putc (s
, ZEBRA_INTERFACE_DELETE
);
240 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
241 stream_putl (s
, ifp
->ifindex
);
242 stream_putc (s
, ifp
->status
);
243 stream_putl (s
, ifp
->flags
);
244 stream_putl (s
, ifp
->metric
);
245 stream_putl (s
, ifp
->mtu
);
246 stream_putl (s
, ifp
->bandwidth
);
248 /* Write packet length. */
249 stream_putw_at (s
, 0, stream_get_endp (s
));
251 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
256 /* Interface address is added. Send ZEBRA_INTERFACE_ADDRESS_ADD to the
259 zsend_interface_address_add (struct zserv
*client
, struct interface
*ifp
,
260 struct connected
*ifc
)
266 /* Check this client need interface information. */
267 if (! client
->ifinfo
)
273 /* Place holder for size. */
276 stream_putc (s
, ZEBRA_INTERFACE_ADDRESS_ADD
);
277 stream_putl (s
, ifp
->ifindex
);
279 /* Interface address flag. */
280 stream_putc (s
, ifc
->flags
);
282 /* Prefix information. */
284 stream_putc (s
, p
->family
);
285 blen
= prefix_blen (p
);
286 stream_put (s
, &p
->u
.prefix
, blen
);
287 stream_putc (s
, p
->prefixlen
);
290 p
= ifc
->destination
;
292 stream_put (s
, &p
->u
.prefix
, blen
);
294 stream_put (s
, NULL
, blen
);
296 /* Write packet size. */
297 stream_putw_at (s
, 0, stream_get_endp (s
));
299 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
304 /* Interface address is deleted. Send ZEBRA_INTERFACE_ADDRESS_DELETE
307 zsend_interface_address_delete (struct zserv
*client
, struct interface
*ifp
,
308 struct connected
*ifc
)
314 /* Check this client need interface information. */
315 if (! client
->ifinfo
)
321 /* Place holder for size. */
324 stream_putc (s
, ZEBRA_INTERFACE_ADDRESS_DELETE
);
325 stream_putl (s
, ifp
->ifindex
);
327 /* Interface address flag. */
328 stream_putc (s
, ifc
->flags
);
330 /* Prefix information. */
332 stream_putc (s
, p
->family
);
333 blen
= prefix_blen (p
);
334 stream_put (s
, &p
->u
.prefix
, blen
);
336 p
= ifc
->destination
;
338 stream_put (s
, &p
->u
.prefix
, blen
);
340 stream_put (s
, NULL
, blen
);
342 /* Write packet size. */
343 stream_putw_at (s
, 0, stream_get_endp (s
));
345 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
351 zsend_interface_up (struct zserv
*client
, struct interface
*ifp
)
355 /* Check this client need interface information. */
356 if (! client
->ifinfo
)
362 /* Place holder for size. */
366 stream_putc (s
, ZEBRA_INTERFACE_UP
);
368 /* Interface information. */
369 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
370 stream_putl (s
, ifp
->ifindex
);
371 stream_putc (s
, ifp
->status
);
372 stream_putl (s
, ifp
->flags
);
373 stream_putl (s
, ifp
->metric
);
374 stream_putl (s
, ifp
->mtu
);
375 stream_putl (s
, ifp
->bandwidth
);
377 /* Write packet size. */
378 stream_putw_at (s
, 0, stream_get_endp (s
));
380 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
386 zsend_interface_down (struct zserv
*client
, struct interface
*ifp
)
390 /* Check this client need interface information. */
391 if (! client
->ifinfo
)
397 /* Place holder for size. */
401 stream_putc (s
, ZEBRA_INTERFACE_DOWN
);
403 /* Interface information. */
404 stream_put (s
, ifp
->name
, INTERFACE_NAMSIZ
);
405 stream_putl (s
, ifp
->ifindex
);
406 stream_putc (s
, ifp
->status
);
407 stream_putl (s
, ifp
->flags
);
408 stream_putl (s
, ifp
->metric
);
409 stream_putl (s
, ifp
->mtu
);
410 stream_putl (s
, ifp
->bandwidth
);
412 /* Write packet size. */
413 stream_putw_at (s
, 0, stream_get_endp (s
));
415 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
421 zsend_ipv4_add_multipath (struct zserv
*client
, struct prefix
*p
,
426 struct nexthop
*nexthop
;
427 struct in_addr empty
;
433 /* Place holder for size. */
436 /* Put command, type and nexthop. */
437 stream_putc (s
, ZEBRA_IPV4_ROUTE_ADD
);
438 stream_putc (s
, rib
->type
);
439 stream_putc (s
, rib
->flags
);
440 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
| ZAPI_MESSAGE_IFINDEX
| ZAPI_MESSAGE_METRIC
);
443 psize
= PSIZE (p
->prefixlen
);
444 stream_putc (s
, p
->prefixlen
);
445 stream_write (s
, (u_char
*)&p
->u
.prefix
, psize
);
448 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
450 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
454 /* XXX: Waht's about NEXTHOP_TYPE_IPV4_IFNAME ? */
455 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
456 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
457 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
459 stream_put_in_addr (s
, &empty
);
461 /* Interface index. */
463 stream_putl (s
, nexthop
->ifindex
);
470 stream_putl (s
, rib
->metric
);
472 /* Write packet size. */
473 stream_putw_at (s
, 0, stream_get_endp (s
));
475 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
481 zsend_ipv4_delete_multipath (struct zserv
*client
, struct prefix
*p
,
486 struct nexthop
*nexthop
;
487 struct in_addr empty
;
494 /* Place holder for size. */
497 /* Put command, type and nexthop. */
498 stream_putc (s
, ZEBRA_IPV4_ROUTE_DELETE
);
499 stream_putc (s
, rib
->type
);
500 stream_putc (s
, rib
->flags
);
501 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
504 psize
= PSIZE (p
->prefixlen
);
505 stream_putc (s
, p
->prefixlen
);
506 stream_write (s
, (u_char
*)&p
->u
.prefix
, psize
);
509 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
511 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
515 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
)
516 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
518 stream_put_in_addr (s
, &empty
);
520 /* Interface index. */
522 stream_putl (s
, nexthop
->ifindex
);
528 /* Write packet size. */
529 stream_putw_at (s
, 0, stream_get_endp (s
));
531 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
539 zsend_ipv4_add (struct zserv
*client
, int type
, int flags
,
540 struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
541 unsigned int ifindex
)
549 /* Place holder for size. */
552 /* Put command, type and nexthop. */
553 stream_putc (s
, ZEBRA_IPV4_ROUTE_ADD
);
554 stream_putc (s
, type
);
555 stream_putc (s
, flags
);
556 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
559 psize
= PSIZE (p
->prefixlen
);
560 stream_putc (s
, p
->prefixlen
);
561 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
565 stream_put_in_addr (s
, nexthop
);
567 /* Interface index. */
569 stream_putl (s
, ifindex
);
571 /* Write packet size. */
572 stream_putw_at (s
, 0, stream_get_endp (s
));
574 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
580 zsend_ipv4_delete (struct zserv
*client
, int type
, int flags
,
581 struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
582 unsigned int ifindex
)
590 /* Place holder for size. */
593 /* Put command, type and nexthop. */
594 stream_putc (s
, ZEBRA_IPV4_ROUTE_DELETE
);
595 stream_putc (s
, type
);
596 stream_putc (s
, flags
);
597 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
600 psize
= PSIZE (p
->prefixlen
);
601 stream_putc (s
, p
->prefixlen
);
602 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
606 stream_put_in_addr (s
, nexthop
);
608 /* Interface index. */
610 stream_putl (s
, ifindex
);
612 /* Write packet size. */
613 stream_putw_at (s
, 0, stream_get_endp (s
));
615 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
625 zsend_ipv6_add (struct zserv
*client
, int type
, int flags
,
626 struct prefix_ipv6
*p
, struct in6_addr
*nexthop
,
627 unsigned int ifindex
)
635 /* Place holder for size. */
638 /* Put command, type and nexthop. */
639 stream_putc (s
, ZEBRA_IPV6_ROUTE_ADD
);
640 stream_putc (s
, type
);
641 stream_putc (s
, flags
);
642 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
645 psize
= PSIZE (p
->prefixlen
);
646 stream_putc (s
, p
->prefixlen
);
647 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
651 stream_write (s
, (u_char
*)nexthop
, 16);
653 /* Interface index. */
655 stream_putl (s
, ifindex
);
657 /* Write packet size. */
658 stream_putw_at (s
, 0, stream_get_endp (s
));
660 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
667 zsend_ipv6_add_multipath (struct zserv
*client
, struct prefix
*p
,
672 struct nexthop
*nexthop
;
673 struct in6_addr empty
;
675 memset (&empty
, 0, sizeof (struct in6_addr
));
679 /* Place holder for size. */
682 /* Put command, type and nexthop. */
683 stream_putc (s
, ZEBRA_IPV6_ROUTE_ADD
);
684 stream_putc (s
, rib
->type
);
685 stream_putc (s
, rib
->flags
);
686 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
| ZAPI_MESSAGE_IFINDEX
| ZAPI_MESSAGE_METRIC
);
689 psize
= PSIZE (p
->prefixlen
);
690 stream_putc (s
, p
->prefixlen
);
691 stream_write (s
, (u_char
*) &p
->u
.prefix
, psize
);
694 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
696 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
700 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
701 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
702 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
)
703 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
705 stream_write (s
, (u_char
*) &empty
, 16);
707 /* Interface index. */
709 stream_putl (s
, nexthop
->ifindex
);
716 stream_putl (s
, rib
->metric
);
718 /* Write packet size. */
719 stream_putw_at (s
, 0, stream_get_endp (s
));
721 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
729 zsend_ipv6_delete (struct zserv
*client
, int type
, int flags
,
730 struct prefix_ipv6
*p
, struct in6_addr
*nexthop
,
731 unsigned int ifindex
)
739 /* Place holder for size. */
742 /* Put command, type and nexthop. */
743 stream_putc (s
, ZEBRA_IPV6_ROUTE_DELETE
);
744 stream_putc (s
, type
);
745 stream_putc (s
, flags
);
746 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
749 psize
= PSIZE (p
->prefixlen
);
750 stream_putc (s
, p
->prefixlen
);
751 stream_write (s
, (u_char
*)&p
->prefix
, psize
);
755 stream_write (s
, (u_char
*)nexthop
, 16);
757 /* Interface index. */
759 stream_putl (s
, ifindex
);
761 /* Write packet size. */
762 stream_putw_at (s
, 0, stream_get_endp (s
));
764 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
771 zsend_ipv6_delete_multipath (struct zserv
*client
, struct prefix
*p
,
776 struct nexthop
*nexthop
;
777 struct in6_addr empty
;
779 memset (&empty
, 0, sizeof (struct in6_addr
));
783 /* Place holder for size. */
786 /* Put command, type and nexthop. */
787 stream_putc (s
, ZEBRA_IPV6_ROUTE_DELETE
);
788 stream_putc (s
, rib
->type
);
789 stream_putc (s
, rib
->flags
);
790 stream_putc (s
, ZAPI_MESSAGE_NEXTHOP
|ZAPI_MESSAGE_IFINDEX
);
793 psize
= PSIZE (p
->prefixlen
);
794 stream_putc (s
, p
->prefixlen
);
795 stream_write (s
, (u_char
*)&p
->u
.prefix
, psize
);
798 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
800 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
804 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
)
805 stream_write (s
, (u_char
*) &nexthop
->gate
.ipv6
, 16);
807 stream_write (s
, (u_char
*) &empty
, 16);
809 /* Interface index. */
811 stream_putl (s
, nexthop
->ifindex
);
817 /* Write packet size. */
818 stream_putw_at (s
, 0, stream_get_endp (s
));
820 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
826 zsend_ipv6_nexthop_lookup (struct zserv
*client
, struct in6_addr
*addr
)
832 struct nexthop
*nexthop
;
834 /* Lookup nexthop. */
835 rib
= rib_match_ipv6 (addr
);
837 /* Get output stream. */
841 /* Fill in result. */
843 stream_putc (s
, ZEBRA_IPV6_NEXTHOP_LOOKUP
);
844 stream_put (s
, &addr
, 16);
848 stream_putl (s
, rib
->metric
);
852 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
853 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
855 stream_putc (s
, nexthop
->type
);
856 switch (nexthop
->type
)
858 case ZEBRA_NEXTHOP_IPV6
:
859 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
861 case ZEBRA_NEXTHOP_IPV6_IFINDEX
:
862 case ZEBRA_NEXTHOP_IPV6_IFNAME
:
863 stream_put (s
, &nexthop
->gate
.ipv6
, 16);
864 stream_putl (s
, nexthop
->ifindex
);
866 case ZEBRA_NEXTHOP_IFINDEX
:
867 case ZEBRA_NEXTHOP_IFNAME
:
868 stream_putl (s
, nexthop
->ifindex
);
873 stream_putc_at (s
, nump
, num
);
881 stream_putw_at (s
, 0, stream_get_endp (s
));
883 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
887 #endif /* HAVE_IPV6 */
890 zsend_ipv4_nexthop_lookup (struct zserv
*client
, struct in_addr addr
)
896 struct nexthop
*nexthop
;
898 /* Lookup nexthop. */
899 rib
= rib_match_ipv4 (addr
);
901 /* Get output stream. */
905 /* Fill in result. */
907 stream_putc (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP
);
908 stream_put_in_addr (s
, &addr
);
912 stream_putl (s
, rib
->metric
);
916 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
917 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
919 stream_putc (s
, nexthop
->type
);
920 switch (nexthop
->type
)
922 case ZEBRA_NEXTHOP_IPV4
:
923 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
925 case ZEBRA_NEXTHOP_IFINDEX
:
926 case ZEBRA_NEXTHOP_IFNAME
:
927 stream_putl (s
, nexthop
->ifindex
);
932 stream_putc_at (s
, nump
, num
);
940 stream_putw_at (s
, 0, stream_get_endp (s
));
942 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
948 zsend_ipv4_import_lookup (struct zserv
*client
, struct prefix_ipv4
*p
)
954 struct nexthop
*nexthop
;
956 /* Lookup nexthop. */
957 rib
= rib_lookup_ipv4 (p
);
959 /* Get output stream. */
963 /* Fill in result. */
965 stream_putc (s
, ZEBRA_IPV4_IMPORT_LOOKUP
);
966 stream_put_in_addr (s
, &p
->prefix
);
970 stream_putl (s
, rib
->metric
);
974 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
975 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
977 stream_putc (s
, nexthop
->type
);
978 switch (nexthop
->type
)
980 case ZEBRA_NEXTHOP_IPV4
:
981 stream_put_in_addr (s
, &nexthop
->gate
.ipv4
);
983 case ZEBRA_NEXTHOP_IFINDEX
:
984 case ZEBRA_NEXTHOP_IFNAME
:
985 stream_putl (s
, nexthop
->ifindex
);
990 stream_putc_at (s
, nump
, num
);
998 stream_putw_at (s
, 0, stream_get_endp (s
));
1000 zebra_server_send_message (client
->sock
, s
->data
, stream_get_endp (s
));
1005 /* Register zebra server interface information. Send current all
1006 interface and address information. */
1008 zread_interface_add (struct zserv
*client
, u_short length
)
1012 struct interface
*ifp
;
1013 struct connected
*c
;
1015 /* Interface information is needed. */
1018 for (ifnode
= listhead (iflist
); ifnode
; ifnode
= nextnode (ifnode
))
1020 ifp
= getdata (ifnode
);
1022 /* Skip pseudo interface. */
1023 if (! CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
1026 zsend_interface_add (client
, ifp
);
1028 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
1030 c
= getdata (cnode
);
1031 if (CHECK_FLAG (c
->conf
, ZEBRA_IFC_REAL
))
1032 zsend_interface_address_add (client
, ifp
, c
);
1037 /* Unregister zebra server interface information. */
1039 zread_interface_delete (struct zserv
*client
, u_short length
)
1044 /* This function support multiple nexthop. */
1046 zread_ipv4_add (struct zserv
*client
, u_short length
)
1050 struct prefix_ipv4 p
;
1052 struct in_addr nexthop
;
1054 u_char nexthop_type
;
1056 unsigned int ifindex
;
1059 /* Get input stream. */
1062 /* Allocate new rib. */
1063 rib
= XMALLOC (MTYPE_RIB
, sizeof (struct rib
));
1064 memset (rib
, 0, sizeof (struct rib
));
1066 /* Type, flags, message. */
1067 rib
->type
= stream_getc (s
);
1068 rib
->flags
= stream_getc (s
);
1069 message
= stream_getc (s
);
1070 rib
->uptime
= time (NULL
);
1073 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1075 p
.prefixlen
= stream_getc (s
);
1076 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1078 /* Nexthop parse. */
1079 if (CHECK_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
))
1081 nexthop_num
= stream_getc (s
);
1083 for (i
= 0; i
< nexthop_num
; i
++)
1085 nexthop_type
= stream_getc (s
);
1087 switch (nexthop_type
)
1089 case ZEBRA_NEXTHOP_IFINDEX
:
1090 ifindex
= stream_getl (s
);
1091 nexthop_ifindex_add (rib
, ifindex
);
1093 case ZEBRA_NEXTHOP_IFNAME
:
1094 ifname_len
= stream_getc (s
);
1095 stream_forward (s
, ifname_len
);
1097 case ZEBRA_NEXTHOP_IPV4
:
1098 nexthop
.s_addr
= stream_get_ipv4 (s
);
1099 nexthop_ipv4_add (rib
, &nexthop
);
1101 case ZEBRA_NEXTHOP_IPV6
:
1102 stream_forward (s
, IPV6_MAX_BYTELEN
);
1104 case ZEBRA_NEXTHOP_BLACKHOLE
:
1105 nexthop_blackhole_add (rib
);
1112 if (CHECK_FLAG (message
, ZAPI_MESSAGE_DISTANCE
))
1113 rib
->distance
= stream_getc (s
);
1116 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
1117 rib
->metric
= stream_getl (s
);
1119 rib_add_ipv4_multipath (&p
, rib
);
1122 /* Zebra server IPv4 prefix delete function. */
1124 zread_ipv4_delete (struct zserv
*client
, u_short length
)
1128 struct zapi_ipv4 api
;
1129 struct in_addr nexthop
;
1130 unsigned long ifindex
;
1131 struct prefix_ipv4 p
;
1133 u_char nexthop_type
;
1140 /* Type, flags, message. */
1141 api
.type
= stream_getc (s
);
1142 api
.flags
= stream_getc (s
);
1143 api
.message
= stream_getc (s
);
1146 memset (&p
, 0, sizeof (struct prefix_ipv4
));
1148 p
.prefixlen
= stream_getc (s
);
1149 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1151 /* Nexthop, ifindex, distance, metric. */
1152 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1154 nexthop_num
= stream_getc (s
);
1156 for (i
= 0; i
< nexthop_num
; i
++)
1158 nexthop_type
= stream_getc (s
);
1160 switch (nexthop_type
)
1162 case ZEBRA_NEXTHOP_IFINDEX
:
1163 ifindex
= stream_getl (s
);
1165 case ZEBRA_NEXTHOP_IFNAME
:
1166 ifname_len
= stream_getc (s
);
1167 stream_forward (s
, ifname_len
);
1169 case ZEBRA_NEXTHOP_IPV4
:
1170 nexthop
.s_addr
= stream_get_ipv4 (s
);
1172 case ZEBRA_NEXTHOP_IPV6
:
1173 stream_forward (s
, IPV6_MAX_BYTELEN
);
1180 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1181 api
.distance
= stream_getc (s
);
1186 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1187 api
.metric
= stream_getl (s
);
1191 rib_delete_ipv4 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
,
1195 /* Nexthop lookup for IPv4. */
1197 zread_ipv4_nexthop_lookup (struct zserv
*client
, u_short length
)
1199 struct in_addr addr
;
1201 addr
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1202 zsend_ipv4_nexthop_lookup (client
, addr
);
1205 /* Nexthop lookup for IPv4. */
1207 zread_ipv4_import_lookup (struct zserv
*client
, u_short length
)
1209 struct prefix_ipv4 p
;
1212 p
.prefixlen
= stream_getc (client
->ibuf
);
1213 p
.prefix
.s_addr
= stream_get_ipv4 (client
->ibuf
);
1215 zsend_ipv4_import_lookup (client
, &p
);
1219 /* Zebra server IPv6 prefix add function. */
1221 zread_ipv6_add (struct zserv
*client
, u_short length
)
1225 struct zapi_ipv6 api
;
1226 struct in6_addr nexthop
;
1227 unsigned long ifindex
;
1228 struct prefix_ipv6 p
;
1232 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1234 /* Type, flags, message. */
1235 api
.type
= stream_getc (s
);
1236 api
.flags
= stream_getc (s
);
1237 api
.message
= stream_getc (s
);
1240 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1241 p
.family
= AF_INET6
;
1242 p
.prefixlen
= stream_getc (s
);
1243 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1245 /* Nexthop, ifindex, distance, metric. */
1246 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1248 u_char nexthop_type
;
1250 api
.nexthop_num
= stream_getc (s
);
1251 for (i
= 0; i
< api
.nexthop_num
; i
++)
1253 nexthop_type
= stream_getc (s
);
1255 switch (nexthop_type
)
1257 case ZEBRA_NEXTHOP_IPV6
:
1258 stream_get (&nexthop
, s
, 16);
1260 case ZEBRA_NEXTHOP_IFINDEX
:
1261 ifindex
= stream_getl (s
);
1267 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1268 api
.distance
= stream_getc (s
);
1272 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1273 api
.metric
= stream_getl (s
);
1277 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1278 rib_add_ipv6 (api
.type
, api
.flags
, &p
, NULL
, ifindex
, 0);
1280 rib_add_ipv6 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
, 0);
1283 /* Zebra server IPv6 prefix delete function. */
1285 zread_ipv6_delete (struct zserv
*client
, u_short length
)
1289 struct zapi_ipv6 api
;
1290 struct in6_addr nexthop
;
1291 unsigned long ifindex
;
1292 struct prefix_ipv6 p
;
1296 memset (&nexthop
, 0, sizeof (struct in6_addr
));
1298 /* Type, flags, message. */
1299 api
.type
= stream_getc (s
);
1300 api
.flags
= stream_getc (s
);
1301 api
.message
= stream_getc (s
);
1304 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1305 p
.family
= AF_INET6
;
1306 p
.prefixlen
= stream_getc (s
);
1307 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
1309 /* Nexthop, ifindex, distance, metric. */
1310 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
1312 u_char nexthop_type
;
1314 api
.nexthop_num
= stream_getc (s
);
1315 for (i
= 0; i
< api
.nexthop_num
; i
++)
1317 nexthop_type
= stream_getc (s
);
1319 switch (nexthop_type
)
1321 case ZEBRA_NEXTHOP_IPV6
:
1322 stream_get (&nexthop
, s
, 16);
1324 case ZEBRA_NEXTHOP_IFINDEX
:
1325 ifindex
= stream_getl (s
);
1331 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
1332 api
.distance
= stream_getc (s
);
1335 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
1336 api
.metric
= stream_getl (s
);
1340 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1341 rib_delete_ipv6 (api
.type
, api
.flags
, &p
, NULL
, ifindex
, 0);
1343 rib_delete_ipv6 (api
.type
, api
.flags
, &p
, &nexthop
, ifindex
, 0);
1347 zebra_read_ipv6 (int command
, struct zserv
*client
, u_short length
)
1351 struct in6_addr nexthop
, *gate
;
1354 unsigned int ifindex
;
1356 pnt
= stream_pnt (client
->ibuf
);
1359 type
= stream_getc (client
->ibuf
);
1360 flags
= stream_getc (client
->ibuf
);
1361 stream_get (&nexthop
, client
->ibuf
, sizeof (struct in6_addr
));
1363 while (stream_pnt (client
->ibuf
) < lim
)
1366 struct prefix_ipv6 p
;
1368 ifindex
= stream_getl (client
->ibuf
);
1370 memset (&p
, 0, sizeof (struct prefix_ipv6
));
1371 p
.family
= AF_INET6
;
1372 p
.prefixlen
= stream_getc (client
->ibuf
);
1373 size
= PSIZE(p
.prefixlen
);
1374 stream_get (&p
.prefix
, client
->ibuf
, size
);
1376 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop
))
1381 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
1382 rib_add_ipv6 (type
, flags
, &p
, gate
, ifindex
, 0);
1384 rib_delete_ipv6 (type
, flags
, &p
, gate
, ifindex
, 0);
1389 zread_ipv6_nexthop_lookup (struct zserv
*client
, u_short length
)
1391 struct in6_addr addr
;
1394 stream_get (&addr
, client
->ibuf
, 16);
1395 printf ("DEBUG %s\n", inet_ntop (AF_INET6
, &addr
, buf
, BUFSIZ
));
1397 zsend_ipv6_nexthop_lookup (client
, &addr
);
1399 #endif /* HAVE_IPV6 */
1401 /* Close zebra client. */
1403 zebra_client_close (struct zserv
*client
)
1405 /* Close file descriptor. */
1408 close (client
->sock
);
1412 /* Free stream buffers. */
1414 stream_free (client
->ibuf
);
1416 stream_free (client
->obuf
);
1418 /* Release threads. */
1420 thread_cancel (client
->t_read
);
1421 if (client
->t_write
)
1422 thread_cancel (client
->t_write
);
1424 /* Free client structure. */
1425 listnode_delete (client_list
, client
);
1429 /* Make new client. */
1431 zebra_client_create (int sock
)
1433 struct zserv
*client
;
1435 client
= XCALLOC (0, sizeof (struct zserv
));
1437 /* Make client input/output buffer. */
1438 client
->sock
= sock
;
1439 client
->ibuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1440 client
->obuf
= stream_new (ZEBRA_MAX_PACKET_SIZ
);
1442 /* Set table number. */
1443 client
->rtm_table
= rtm_table_default
;
1445 /* Add this client to linked list. */
1446 listnode_add (client_list
, client
);
1448 /* Make new read thread. */
1449 zebra_event (ZEBRA_READ
, sock
, client
);
1452 /* Handler of zebra service request. */
1454 zebra_client_read (struct thread
*thread
)
1457 struct zserv
*client
;
1462 /* Get thread data. Reset reading thread because I'm running. */
1463 sock
= THREAD_FD (thread
);
1464 client
= THREAD_ARG (thread
);
1465 client
->t_read
= NULL
;
1467 /* Read length and command. */
1468 nbyte
= stream_read (client
->ibuf
, sock
, 3);
1471 if (IS_ZEBRA_DEBUG_EVENT
)
1472 zlog_info ("connection closed socket [%d]", sock
);
1473 zebra_client_close (client
);
1476 length
= stream_getw (client
->ibuf
);
1477 command
= stream_getc (client
->ibuf
);
1481 if (IS_ZEBRA_DEBUG_EVENT
)
1482 zlog_info ("length %d is less than 3 ", length
);
1483 zebra_client_close (client
);
1489 /* Read rest of data. */
1492 nbyte
= stream_read (client
->ibuf
, sock
, length
);
1495 if (IS_ZEBRA_DEBUG_EVENT
)
1496 zlog_info ("connection closed [%d] when reading zebra data", sock
);
1497 zebra_client_close (client
);
1502 /* Debug packet information. */
1503 if (IS_ZEBRA_DEBUG_EVENT
)
1504 zlog_info ("zebra message comes from socket [%d]", sock
);
1506 if (IS_ZEBRA_DEBUG_PACKET
&& IS_ZEBRA_DEBUG_RECV
)
1507 zlog_info ("zebra message received [%s] %d",
1508 zebra_command_str
[command
], length
);
1512 case ZEBRA_INTERFACE_ADD
:
1513 zread_interface_add (client
, length
);
1515 case ZEBRA_INTERFACE_DELETE
:
1516 zread_interface_delete (client
, length
);
1518 case ZEBRA_IPV4_ROUTE_ADD
:
1519 zread_ipv4_add (client
, length
);
1521 case ZEBRA_IPV4_ROUTE_DELETE
:
1522 zread_ipv4_delete (client
, length
);
1525 case ZEBRA_IPV6_ROUTE_ADD
:
1526 zread_ipv6_add (client
, length
);
1528 case ZEBRA_IPV6_ROUTE_DELETE
:
1529 zread_ipv6_delete (client
, length
);
1531 #endif /* HAVE_IPV6 */
1532 case ZEBRA_REDISTRIBUTE_ADD
:
1533 zebra_redistribute_add (command
, client
, length
);
1535 case ZEBRA_REDISTRIBUTE_DELETE
:
1536 zebra_redistribute_delete (command
, client
, length
);
1538 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD
:
1539 zebra_redistribute_default_add (command
, client
, length
);
1541 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
:
1542 zebra_redistribute_default_delete (command
, client
, length
);
1544 case ZEBRA_IPV4_NEXTHOP_LOOKUP
:
1545 zread_ipv4_nexthop_lookup (client
, length
);
1548 case ZEBRA_IPV6_NEXTHOP_LOOKUP
:
1549 zread_ipv6_nexthop_lookup (client
, length
);
1551 #endif /* HAVE_IPV6 */
1552 case ZEBRA_IPV4_IMPORT_LOOKUP
:
1553 zread_ipv4_import_lookup (client
, length
);
1556 zlog_info ("Zebra received unknown command %d", command
);
1560 stream_reset (client
->ibuf
);
1561 zebra_event (ZEBRA_READ
, sock
, client
);
1566 /* Write output buffer to the socket. */
1568 zebra_write (struct thread
*thread
)
1571 struct zserv
*client
;
1573 /* Thread treatment. */
1574 sock
= THREAD_FD (thread
);
1575 client
= THREAD_ARG (thread
);
1576 client
->t_write
= NULL
;
1578 stream_flush (client
->obuf
, sock
);
1581 /* Accept code of zebra server socket. */
1583 zebra_accept (struct thread
*thread
)
1588 struct sockaddr_in client
;
1591 accept_sock
= THREAD_FD (thread
);
1593 len
= sizeof (struct sockaddr_in
);
1594 client_sock
= accept (accept_sock
, (struct sockaddr
*) &client
, &len
);
1596 if (client_sock
< 0)
1598 zlog_warn ("Can't accept zebra socket: %s", strerror (errno
));
1602 /* Make client socket non-blocking. */
1604 val
= fcntl (client_sock
, F_GETFL
, 0);
1605 fcntl (client_sock
, F_SETFL
, (val
| O_NONBLOCK
));
1607 /* Create new zebra client. */
1608 zebra_client_create (client_sock
);
1610 /* Register myself. */
1611 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
1616 /* Make zebra's server socket. */
1622 struct sockaddr_in addr
;
1624 accept_sock
= socket (AF_INET
, SOCK_STREAM
, 0);
1626 if (accept_sock
< 0)
1628 zlog_warn ("Can't bind to socket: %s", strerror (errno
));
1629 zlog_warn ("zebra can't provice full functionality due to above error");
1633 memset (&addr
, 0, sizeof (struct sockaddr_in
));
1634 addr
.sin_family
= AF_INET
;
1635 addr
.sin_port
= htons (ZEBRA_PORT
);
1637 addr
.sin_len
= sizeof (struct sockaddr_in
);
1638 #endif /* HAVE_SIN_LEN */
1639 addr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
1641 sockopt_reuseaddr (accept_sock
);
1642 sockopt_reuseport (accept_sock
);
1644 if ( zserv_privs
.change(ZPRIVS_RAISE
) )
1645 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1647 ret
= bind (accept_sock
, (struct sockaddr
*)&addr
,
1648 sizeof (struct sockaddr_in
));
1651 zlog_warn ("Can't bind to socket: %s", strerror (errno
));
1652 zlog_warn ("zebra can't provice full functionality due to above error");
1653 close (accept_sock
); /* Avoid sd leak. */
1657 if ( zserv_privs
.change(ZPRIVS_LOWER
) )
1658 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1660 ret
= listen (accept_sock
, 1);
1663 zlog_warn ("Can't listen to socket: %s", strerror (errno
));
1664 zlog_warn ("zebra can't provice full functionality due to above error");
1665 close (accept_sock
); /* Avoid sd leak. */
1669 zebra_event (ZEBRA_SERV
, accept_sock
, NULL
);
1672 /* For sockaddr_un. */
1675 /* zebra server UNIX domain socket. */
1677 zebra_serv_un (char *path
)
1681 struct sockaddr_un serv
;
1684 /* First of all, unlink existing socket */
1688 old_mask
= umask (0077);
1690 /* Make UNIX domain socket. */
1691 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
1698 /* Make server socket. */
1699 memset (&serv
, 0, sizeof (struct sockaddr_un
));
1700 serv
.sun_family
= AF_UNIX
;
1701 strncpy (serv
.sun_path
, path
, strlen (path
));
1703 len
= serv
.sun_len
= SUN_LEN(&serv
);
1705 len
= sizeof (serv
.sun_family
) + strlen (serv
.sun_path
);
1706 #endif /* HAVE_SUN_LEN */
1708 ret
= bind (sock
, (struct sockaddr
*) &serv
, len
);
1716 ret
= listen (sock
, 5);
1726 zebra_event (ZEBRA_SERV
, sock
, NULL
);
1729 /* Zebra's event management function. */
1730 extern struct thread_master
*master
;
1733 zebra_event (enum event event
, int sock
, struct zserv
*client
)
1738 thread_add_read (master
, zebra_accept
, client
, sock
);
1742 thread_add_read (master
, zebra_client_read
, client
, sock
);
1750 /* Display default rtm_table for all clients. */
1755 "default routing table to use for all clients\n")
1757 vty_out (vty
, "table %d%s", rtm_table_default
,
1762 DEFUN (config_table
,
1765 "Configure target kernel routing table\n"
1768 rtm_table_default
= strtol (argv
[0], (char**)0, 10);
1772 DEFUN (ip_forwarding
,
1776 "Turn on IP forwarding")
1784 vty_out (vty
, "IP forwarding is already on%s", VTY_NEWLINE
);
1785 return CMD_ERR_NOTHING_TODO
;
1788 ret
= ipforward_on ();
1791 vty_out (vty
, "Can't turn on IP forwarding%s", VTY_NEWLINE
);
1798 DEFUN (no_ip_forwarding
,
1799 no_ip_forwarding_cmd
,
1803 "Turn off IP forwarding")
1811 vty_out (vty
, "IP forwarding is already off%s", VTY_NEWLINE
);
1812 return CMD_ERR_NOTHING_TODO
;
1815 ret
= ipforward_off ();
1818 vty_out (vty
, "Can't turn off IP forwarding%s", VTY_NEWLINE
);
1825 /* This command is for debugging purpose. */
1826 DEFUN (show_zebra_client
,
1827 show_zebra_client_cmd
,
1828 "show zebra client",
1831 "Client information")
1834 struct zserv
*client
;
1836 for (node
= listhead (client_list
); node
; nextnode (node
))
1838 client
= getdata (node
);
1839 vty_out (vty
, "Client fd %d%s", client
->sock
, VTY_NEWLINE
);
1844 /* Table configuration write function. */
1846 config_write_table (struct vty
*vty
)
1848 if (rtm_table_default
)
1849 vty_out (vty
, "table %d%s", rtm_table_default
,
1854 /* table node for routing tables. */
1855 struct cmd_node table_node
=
1858 "", /* This node has no interface. */
1862 /* Only display ip forwarding is enabled or not. */
1863 DEFUN (show_ip_forwarding
,
1864 show_ip_forwarding_cmd
,
1865 "show ip forwarding",
1868 "IP forwarding status\n")
1875 vty_out (vty
, "IP forwarding is off%s", VTY_NEWLINE
);
1877 vty_out (vty
, "IP forwarding is on%s", VTY_NEWLINE
);
1882 /* Only display ipv6 forwarding is enabled or not. */
1883 DEFUN (show_ipv6_forwarding
,
1884 show_ipv6_forwarding_cmd
,
1885 "show ipv6 forwarding",
1887 "IPv6 information\n"
1888 "Forwarding status\n")
1892 ret
= ipforward_ipv6 ();
1897 vty_out (vty
, "ipv6 forwarding is unknown%s", VTY_NEWLINE
);
1900 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
1903 vty_out (vty
, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE
);
1906 vty_out (vty
, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE
);
1912 DEFUN (no_ipv6_forwarding
,
1913 no_ipv6_forwarding_cmd
,
1914 "no ipv6 forwarding",
1917 "Doesn't forward IPv6 protocol packet")
1921 ret
= ipforward_ipv6_off ();
1924 vty_out (vty
, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE
);
1931 #endif /* HAVE_IPV6 */
1933 /* IPForwarding configuration write function. */
1935 config_write_forwarding (struct vty
*vty
)
1938 vty_out (vty
, "no ip forwarding%s", VTY_NEWLINE
);
1940 if (! ipforward_ipv6 ())
1941 vty_out (vty
, "no ipv6 forwarding%s", VTY_NEWLINE
);
1942 #endif /* HAVE_IPV6 */
1943 vty_out (vty
, "!%s", VTY_NEWLINE
);
1947 /* table node for routing tables. */
1948 struct cmd_node forwarding_node
=
1951 "", /* This node has no interface. */
1956 /* Initialisation of zebra and installation of commands. */
1960 /* Client list init. */
1961 client_list
= list_new ();
1963 /* Forwarding is on by default. */
1966 ipforward_ipv6_on ();
1967 #endif /* HAVE_IPV6 */
1969 /* Make zebra server socket. */
1970 #ifdef HAVE_TCP_ZEBRA
1973 zebra_serv_un (ZEBRA_SERV_PATH
);
1974 #endif /* HAVE_TCP_ZEBRA */
1976 /* Install configuration write function. */
1977 install_node (&table_node
, config_write_table
);
1978 install_node (&forwarding_node
, config_write_forwarding
);
1980 install_element (VIEW_NODE
, &show_ip_forwarding_cmd
);
1981 install_element (ENABLE_NODE
, &show_ip_forwarding_cmd
);
1982 install_element (CONFIG_NODE
, &ip_forwarding_cmd
);
1983 install_element (CONFIG_NODE
, &no_ip_forwarding_cmd
);
1984 install_element (ENABLE_NODE
, &show_zebra_client_cmd
);
1987 install_element (VIEW_NODE
, &show_table_cmd
);
1988 install_element (ENABLE_NODE
, &show_table_cmd
);
1989 install_element (CONFIG_NODE
, &config_table_cmd
);
1990 #endif /* HAVE_NETLINK */
1993 install_element (VIEW_NODE
, &show_ipv6_forwarding_cmd
);
1994 install_element (ENABLE_NODE
, &show_ipv6_forwarding_cmd
);
1995 install_element (CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
1996 #endif /* HAVE_IPV6 */
1998 FIFO_INIT(&message_queue
);