Tomato 1.28
[tomato.git] / release / src / router / zebra / zebra / zserv.c
blobb5f158d9da674e179396b7c508956393c7978177
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
9 * later version.
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.
22 #include <zebra.h>
24 #include "prefix.h"
25 #include "command.h"
26 #include "if.h"
27 #include "thread.h"
28 #include "stream.h"
29 #include "memory.h"
30 #include "table.h"
31 #include "rib.h"
32 #include "network.h"
33 #include "sockunion.h"
34 #include "log.h"
35 #include "zclient.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. */
46 list 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 [] =
56 "NULL",
57 "ZEBRA_INTERFACE_ADD",
58 "ZEBRA_INTERFACE_DELETE",
59 "ZEBRA_INTERFACE_ADDRESS_ADD",
60 "ZEBRA_INTERFACE_ADDRESS_DELETE",
61 "ZEBRA_INTERFACE_UP",
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. */
78 int
79 zsend_interface_add (struct zserv *client, struct interface *ifp)
81 struct stream *s;
83 /* Check this client need interface information. */
84 if (! client->ifinfo)
85 return -1;
87 s = client->obuf;
88 stream_reset (s);
90 /* Place holder for size. */
91 stream_putw (s, 0);
93 /* Message type. */
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));
105 #else
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)
121 struct stream *s;
123 /* Check this client need interface information. */
124 if (! client->ifinfo)
125 return -1;
127 s = client->obuf;
128 stream_reset (s);
130 /* Packet length placeholder. */
131 stream_putw (s, 0);
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
149 client. */
151 zsend_interface_address_add (struct zserv *client, struct interface *ifp,
152 struct connected *ifc)
154 int blen;
155 struct stream *s;
156 struct prefix *p;
158 /* Check this client need interface information. */
159 if (! client->ifinfo)
160 return -1;
162 s = client->obuf;
163 stream_reset (s);
165 /* Place holder for size. */
166 stream_putw (s, 0);
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. */
175 p = ifc->address;
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);
181 /* Destination. */
182 p = ifc->destination;
183 if (p)
184 stream_put (s, &p->u.prefix, blen);
185 else
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
195 to the client. */
197 zsend_interface_address_delete (struct zserv *client, struct interface *ifp,
198 struct connected *ifc)
200 int blen;
201 struct stream *s;
202 struct prefix *p;
204 /* Check this client need interface information. */
205 if (! client->ifinfo)
206 return -1;
208 s = client->obuf;
209 stream_reset (s);
211 /* Place holder for size. */
212 stream_putw (s, 0);
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. */
221 p = ifc->address;
222 stream_putc (s, p->family);
223 blen = prefix_blen (p);
224 stream_put (s, &p->u.prefix, blen);
226 p = ifc->destination;
227 if (p)
228 stream_put (s, &p->u.prefix, blen);
229 else
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)
241 struct stream *s;
243 /* Check this client need interface information. */
244 if (! client->ifinfo)
245 return -1;
247 s = client->obuf;
248 stream_reset (s);
250 /* Place holder for size. */
251 stream_putw (s, 0);
253 /* Zebra command. */
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)
273 struct stream *s;
275 /* Check this client need interface information. */
276 if (! client->ifinfo)
277 return -1;
279 s = client->obuf;
280 stream_reset (s);
282 /* Place holder for size. */
283 stream_putw (s, 0);
285 /* Zebra command. */
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,
304 struct rib *rib)
306 int psize;
307 struct stream *s;
308 struct nexthop *nexthop;
309 struct in_addr empty;
311 empty.s_addr = 0;
312 s = client->obuf;
313 stream_reset (s);
315 /* Place holder for size. */
316 stream_putw (s, 0);
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);
324 /* Prefix. */
325 psize = PSIZE (p->prefixlen);
326 stream_putc (s, p->prefixlen);
327 stream_write (s, (u_char *)&p->u.prefix, psize);
329 /* Nexthop */
330 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
332 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
334 stream_putc (s, 1);
336 if (nexthop->type == NEXTHOP_TYPE_IPV4
337 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
338 stream_put_in_addr (s, &nexthop->gate.ipv4);
339 else
340 stream_put_in_addr (s, &empty);
342 /* Interface index. */
343 stream_putc (s, 1);
344 stream_putl (s, nexthop->ifindex);
346 break;
350 /* Metric */
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,
361 struct rib *rib)
363 int psize;
364 struct stream *s;
365 struct nexthop *nexthop;
366 struct in_addr empty;
368 empty.s_addr = 0;
370 s = client->obuf;
371 stream_reset (s);
373 /* Place holder for size. */
374 stream_putw (s, 0);
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);
382 /* Prefix. */
383 psize = PSIZE (p->prefixlen);
384 stream_putc (s, p->prefixlen);
385 stream_write (s, (u_char *)&p->u.prefix, psize);
387 /* Nexthop */
388 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
390 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
392 stream_putc (s, 1);
394 if (nexthop->type == NEXTHOP_TYPE_IPV4)
395 stream_put_in_addr (s, &nexthop->gate.ipv4);
396 else
397 stream_put_in_addr (s, &empty);
399 /* Interface index. */
400 stream_putc (s, 1);
401 stream_putl (s, nexthop->ifindex);
403 break;
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)
418 int psize;
419 struct stream *s;
421 s = client->obuf;
422 stream_reset (s);
424 /* Place holder for size. */
425 stream_putw (s, 0);
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);
433 /* Prefix. */
434 psize = PSIZE (p->prefixlen);
435 stream_putc (s, p->prefixlen);
436 stream_write (s, (u_char *)&p->prefix, psize);
438 /* Nexthop */
439 stream_putc (s, 1);
440 stream_put_in_addr (s, nexthop);
442 /* Interface index. */
443 stream_putc (s, 1);
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)
457 int psize;
458 struct stream *s;
460 s = client->obuf;
461 stream_reset (s);
463 /* Place holder for size. */
464 stream_putw (s, 0);
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);
472 /* Prefix. */
473 psize = PSIZE (p->prefixlen);
474 stream_putc (s, p->prefixlen);
475 stream_write (s, (u_char *)&p->prefix, psize);
477 /* Nexthop */
478 stream_putc (s, 1);
479 stream_put_in_addr (s, nexthop);
481 /* Interface index. */
482 stream_putc (s, 1);
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));
491 #ifdef HAVE_IPV6
493 zsend_ipv6_add (struct zserv *client, int type, int flags,
494 struct prefix_ipv6 *p, struct in6_addr *nexthop,
495 unsigned int ifindex)
497 int psize;
498 struct stream *s;
500 s = client->obuf;
501 stream_reset (s);
503 /* Place holder for size. */
504 stream_putw (s, 0);
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);
512 /* Prefix. */
513 psize = PSIZE (p->prefixlen);
514 stream_putc (s, p->prefixlen);
515 stream_write (s, (u_char *)&p->prefix, psize);
517 /* Nexthop */
518 stream_putc (s, 1);
519 stream_write (s, (u_char *)nexthop, 16);
521 /* Interface index. */
522 stream_putc (s, 1);
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,
533 struct rib *rib)
535 int psize;
536 struct stream *s;
537 struct nexthop *nexthop;
538 struct in6_addr empty;
540 memset (&empty, 0, sizeof (struct in6_addr));
541 s = client->obuf;
542 stream_reset (s);
544 /* Place holder for size. */
545 stream_putw (s, 0);
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);
553 /* Prefix. */
554 psize = PSIZE (p->prefixlen);
555 stream_putc (s, p->prefixlen);
556 stream_write (s, (u_char *) &p->u.prefix, psize);
558 /* Nexthop */
559 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
561 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
563 stream_putc (s, 1);
565 if (nexthop->type == NEXTHOP_TYPE_IPV6)
566 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
567 else
568 stream_write (s, (u_char *) &empty, 16);
570 /* Interface index. */
571 stream_putc (s, 1);
572 stream_putl (s, nexthop->ifindex);
574 break;
578 /* Metric */
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)
592 int psize;
593 struct stream *s;
595 s = client->obuf;
596 stream_reset (s);
598 /* Place holder for size. */
599 stream_putw (s, 0);
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);
607 /* Prefix. */
608 psize = PSIZE (p->prefixlen);
609 stream_putc (s, p->prefixlen);
610 stream_write (s, (u_char *)&p->prefix, psize);
612 /* Nexthop */
613 stream_putc (s, 1);
614 stream_write (s, (u_char *)nexthop, 16);
616 /* Interface index. */
617 stream_putc (s, 1);
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,
628 struct rib *rib)
630 int psize;
631 struct stream *s;
632 struct nexthop *nexthop;
633 struct in6_addr empty;
635 memset (&empty, 0, sizeof (struct in6_addr));
636 s = client->obuf;
637 stream_reset (s);
639 /* Place holder for size. */
640 stream_putw (s, 0);
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);
648 /* Prefix. */
649 psize = PSIZE (p->prefixlen);
650 stream_putc (s, p->prefixlen);
651 stream_write (s, (u_char *)&p->u.prefix, psize);
653 /* Nexthop */
654 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
656 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
658 stream_putc (s, 1);
660 if (nexthop->type == NEXTHOP_TYPE_IPV6)
661 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
662 else
663 stream_write (s, (u_char *) &empty, 16);
665 /* Interface index. */
666 stream_putc (s, 1);
667 stream_putl (s, nexthop->ifindex);
669 break;
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)
682 struct stream *s;
683 struct rib *rib;
684 unsigned long nump;
685 u_char num;
686 struct nexthop *nexthop;
688 /* Lookup nexthop. */
689 rib = rib_match_ipv6 (addr);
691 /* Get output stream. */
692 s = client->obuf;
693 stream_reset (s);
695 /* Fill in result. */
696 stream_putw (s, 0);
697 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
698 stream_put (s, &addr, 16);
700 if (rib)
702 stream_putl (s, rib->metric);
703 num = 0;
704 nump = s->putp;
705 stream_putc (s, 0);
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);
714 break;
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);
719 break;
720 case ZEBRA_NEXTHOP_IFINDEX:
721 case ZEBRA_NEXTHOP_IFNAME:
722 stream_putl (s, nexthop->ifindex);
723 break;
725 num++;
727 stream_putc_at (s, nump, num);
729 else
731 stream_putl (s, 0);
732 stream_putc (s, 0);
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)
744 struct stream *s;
745 struct rib *rib;
746 unsigned long nump;
747 u_char num;
748 struct nexthop *nexthop;
750 /* Lookup nexthop. */
751 rib = rib_match_ipv4 (addr);
753 /* Get output stream. */
754 s = client->obuf;
755 stream_reset (s);
757 /* Fill in result. */
758 stream_putw (s, 0);
759 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
760 stream_put_in_addr (s, &addr);
762 if (rib)
764 stream_putl (s, rib->metric);
765 num = 0;
766 nump = s->putp;
767 stream_putc (s, 0);
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);
776 break;
777 case ZEBRA_NEXTHOP_IFINDEX:
778 case ZEBRA_NEXTHOP_IFNAME:
779 stream_putl (s, nexthop->ifindex);
780 break;
782 num++;
784 stream_putc_at (s, nump, num);
786 else
788 stream_putl (s, 0);
789 stream_putc (s, 0);
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)
800 struct stream *s;
801 struct rib *rib;
802 unsigned long nump;
803 u_char num;
804 struct nexthop *nexthop;
806 /* Lookup nexthop. */
807 rib = rib_lookup_ipv4 (p);
809 /* Get output stream. */
810 s = client->obuf;
811 stream_reset (s);
813 /* Fill in result. */
814 stream_putw (s, 0);
815 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
816 stream_put_in_addr (s, &p->prefix);
818 if (rib)
820 stream_putl (s, rib->metric);
821 num = 0;
822 nump = s->putp;
823 stream_putc (s, 0);
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);
832 break;
833 case ZEBRA_NEXTHOP_IFINDEX:
834 case ZEBRA_NEXTHOP_IFNAME:
835 stream_putl (s, nexthop->ifindex);
836 break;
838 num++;
840 stream_putc_at (s, nump, num);
842 else
844 stream_putl (s, 0);
845 stream_putc (s, 0);
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. */
855 void
856 zread_interface_add (struct zserv *client, u_short length)
858 listnode ifnode;
859 listnode cnode;
860 struct interface *ifp;
861 struct connected *c;
863 /* Interface information is needed. */
864 client->ifinfo = 1;
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))
872 continue;
874 zsend_interface_add (client, ifp);
876 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
878 c = getdata (cnode);
879 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
880 zsend_interface_address_add (client, ifp, c);
885 /* Unregister zebra server interface information. */
886 void
887 zread_interface_delete (struct zserv *client, u_short length)
889 client->ifinfo = 0;
892 /* This function support multiple nexthop. */
893 void
894 zread_ipv4_add (struct zserv *client, u_short length)
896 int i;
897 struct rib *rib;
898 struct prefix_ipv4 p;
899 u_char message;
900 struct in_addr nexthop;
901 u_char nexthop_num;
902 u_char nexthop_type;
903 struct stream *s;
904 unsigned int ifindex;
905 u_char ifname_len;
907 /* Get input stream. */
908 s = client->ibuf;
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);
920 /* IPv4 prefix. */
921 memset (&p, 0, sizeof (struct prefix_ipv4));
922 p.family = AF_INET;
923 p.prefixlen = stream_getc (s);
924 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
926 /* Nexthop parse. */
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);
940 break;
941 case ZEBRA_NEXTHOP_IFNAME:
942 ifname_len = stream_getc (s);
943 stream_forward (s, ifname_len);
944 break;
945 case ZEBRA_NEXTHOP_IPV4:
946 nexthop.s_addr = stream_get_ipv4 (s);
947 nexthop_ipv4_add (rib, &nexthop);
948 break;
949 case ZEBRA_NEXTHOP_IPV6:
950 stream_forward (s, IPV6_MAX_BYTELEN);
951 break;
956 /* Distance. */
957 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
958 rib->distance = stream_getc (s);
960 /* Metric. */
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. */
968 void
969 zread_ipv4_delete (struct zserv *client, u_short length)
971 int i;
972 struct stream *s;
973 struct zapi_ipv4 api;
974 struct in_addr nexthop;
975 unsigned long ifindex;
976 struct prefix_ipv4 p;
977 u_char nexthop_num;
978 u_char nexthop_type;
979 u_char ifname_len;
981 s = client->ibuf;
982 ifindex = 0;
983 nexthop.s_addr = 0;
985 /* Type, flags, message. */
986 api.type = stream_getc (s);
987 api.flags = stream_getc (s);
988 api.message = stream_getc (s);
990 /* IPv4 prefix. */
991 memset (&p, 0, sizeof (struct prefix_ipv4));
992 p.family = AF_INET;
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);
1009 break;
1010 case ZEBRA_NEXTHOP_IFNAME:
1011 ifname_len = stream_getc (s);
1012 stream_forward (s, ifname_len);
1013 break;
1014 case ZEBRA_NEXTHOP_IPV4:
1015 nexthop.s_addr = stream_get_ipv4 (s);
1016 break;
1017 case ZEBRA_NEXTHOP_IPV6:
1018 stream_forward (s, IPV6_MAX_BYTELEN);
1019 break;
1024 /* Distance. */
1025 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1026 api.distance = stream_getc (s);
1027 else
1028 api.distance = 0;
1030 /* Metric. */
1031 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1032 api.metric = stream_getl (s);
1033 else
1034 api.metric = 0;
1036 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
1037 client->rtm_table);
1040 /* Nexthop lookup for IPv4. */
1041 void
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. */
1051 void
1052 zread_ipv4_import_lookup (struct zserv *client, u_short length)
1054 struct prefix_ipv4 p;
1056 p.family = AF_INET;
1057 p.prefixlen = stream_getc (client->ibuf);
1058 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1060 zsend_ipv4_import_lookup (client, &p);
1063 #ifdef HAVE_IPV6
1064 /* Zebra server IPv6 prefix add function. */
1065 void
1066 zread_ipv6_add (struct zserv *client, u_short length)
1068 int i;
1069 struct stream *s;
1070 struct zapi_ipv6 api;
1071 struct in6_addr nexthop;
1072 unsigned long ifindex;
1073 struct prefix_ipv6 p;
1075 s = client->ibuf;
1076 ifindex = 0;
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);
1084 /* IPv4 prefix. */
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);
1104 break;
1105 case ZEBRA_NEXTHOP_IFINDEX:
1106 ifindex = stream_getl (s);
1107 break;
1112 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1113 api.distance = stream_getc (s);
1114 else
1115 api.distance = 0;
1117 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1118 api.metric = stream_getl (s);
1119 else
1120 api.metric = 0;
1122 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1123 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1124 else
1125 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1128 /* Zebra server IPv6 prefix delete function. */
1129 void
1130 zread_ipv6_delete (struct zserv *client, u_short length)
1132 int i;
1133 struct stream *s;
1134 struct zapi_ipv6 api;
1135 struct in6_addr nexthop;
1136 unsigned long ifindex;
1137 struct prefix_ipv6 p;
1139 s = client->ibuf;
1140 ifindex = 0;
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);
1148 /* IPv4 prefix. */
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);
1168 break;
1169 case ZEBRA_NEXTHOP_IFINDEX:
1170 ifindex = stream_getl (s);
1171 break;
1176 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1177 api.distance = stream_getc (s);
1178 else
1179 api.distance = 0;
1180 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1181 api.metric = stream_getl (s);
1182 else
1183 api.metric = 0;
1185 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1186 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1187 else
1188 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1191 void
1192 zebra_read_ipv6 (int command, struct zserv *client, u_short length)
1194 u_char type;
1195 u_char flags;
1196 struct in6_addr nexthop, *gate;
1197 u_char *lim;
1198 u_char *pnt;
1199 unsigned int ifindex;
1201 pnt = stream_pnt (client->ibuf);
1202 lim = pnt + length;
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)
1210 int size;
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))
1222 gate = NULL;
1223 else
1224 gate = &nexthop;
1226 if (command == ZEBRA_IPV6_ROUTE_ADD)
1227 rib_add_ipv6 (type, flags, &p, gate, ifindex, 0);
1228 else
1229 rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);
1233 void
1234 zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1236 struct in6_addr addr;
1237 char buf[BUFSIZ];
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. */
1247 void
1248 zebra_client_close (struct zserv *client)
1250 /* Close file descriptor. */
1251 if (client->sock)
1253 close (client->sock);
1254 client->sock = -1;
1257 /* Free stream buffers. */
1258 if (client->ibuf)
1259 stream_free (client->ibuf);
1260 if (client->obuf)
1261 stream_free (client->obuf);
1263 /* Release threads. */
1264 if (client->t_read)
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);
1271 XFREE (0, client);
1274 /* Make new client. */
1275 void
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)
1302 int sock;
1303 struct zserv *client;
1304 int nbyte;
1305 u_short length;
1306 u_char command;
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);
1315 if (nbyte <= 0)
1317 if (IS_ZEBRA_DEBUG_EVENT)
1318 zlog_info ("connection closed socket [%d]", sock);
1319 zebra_client_close (client);
1320 return -1;
1322 length = stream_getw (client->ibuf);
1323 command = stream_getc (client->ibuf);
1325 if (length < 3)
1327 if (IS_ZEBRA_DEBUG_EVENT)
1328 zlog_info ("length %d is less than 3 ", length);
1329 zebra_client_close (client);
1330 return -1;
1333 length -= 3;
1335 /* Read rest of data. */
1336 if (length)
1338 nbyte = stream_read (client->ibuf, sock, length);
1339 if (nbyte <= 0)
1341 if (IS_ZEBRA_DEBUG_EVENT)
1342 zlog_info ("connection closed [%d] when reading zebra data", sock);
1343 zebra_client_close (client);
1344 return -1;
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);
1356 switch (command)
1358 case ZEBRA_INTERFACE_ADD:
1359 zread_interface_add (client, length);
1360 break;
1361 case ZEBRA_INTERFACE_DELETE:
1362 zread_interface_delete (client, length);
1363 break;
1364 case ZEBRA_IPV4_ROUTE_ADD:
1365 zread_ipv4_add (client, length);
1366 break;
1367 case ZEBRA_IPV4_ROUTE_DELETE:
1368 zread_ipv4_delete (client, length);
1369 break;
1370 #ifdef HAVE_IPV6
1371 case ZEBRA_IPV6_ROUTE_ADD:
1372 zread_ipv6_add (client, length);
1373 break;
1374 case ZEBRA_IPV6_ROUTE_DELETE:
1375 zread_ipv6_delete (client, length);
1376 break;
1377 #endif /* HAVE_IPV6 */
1378 case ZEBRA_REDISTRIBUTE_ADD:
1379 zebra_redistribute_add (command, client, length);
1380 break;
1381 case ZEBRA_REDISTRIBUTE_DELETE:
1382 zebra_redistribute_delete (command, client, length);
1383 break;
1384 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1385 zebra_redistribute_default_add (command, client, length);
1386 break;
1387 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1388 zebra_redistribute_default_delete (command, client, length);
1389 break;
1390 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1391 zread_ipv4_nexthop_lookup (client, length);
1392 break;
1393 #ifdef HAVE_IPV6
1394 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1395 zread_ipv6_nexthop_lookup (client, length);
1396 break;
1397 #endif /* HAVE_IPV6 */
1398 case ZEBRA_IPV4_IMPORT_LOOKUP:
1399 zread_ipv4_import_lookup (client, length);
1400 break;
1401 default:
1402 zlog_info ("Zebra received unknown command %d", command);
1403 break;
1406 stream_reset (client->ibuf);
1407 zebra_event (ZEBRA_READ, sock, client);
1409 return 0;
1412 /* Write output buffer to the socket. */
1413 void
1414 zebra_write (struct thread *thread)
1416 int sock;
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)
1431 int accept_sock;
1432 int client_sock;
1433 struct sockaddr_in client;
1434 socklen_t len;
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));
1444 return -1;
1447 /* Create new zebra client. */
1448 zebra_client_create (client_sock);
1450 /* Register myself. */
1451 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1453 return 0;
1456 /* Make zebra's server socket. */
1457 void
1458 zebra_serv ()
1460 int ret;
1461 int accept_sock;
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");
1470 return;
1473 memset (&addr, 0, sizeof (struct sockaddr_in));
1474 addr.sin_family = AF_INET;
1475 addr.sin_port = htons (ZEBRA_PORT);
1476 #ifdef HAVE_SIN_LEN
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));
1486 if (ret < 0)
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. */
1491 return;
1494 ret = listen (accept_sock, 1);
1495 if (ret < 0)
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. */
1500 return;
1503 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1506 /* For sockaddr_un. */
1507 #include <sys/un.h>
1509 /* zebra server UNIX domain socket. */
1510 void
1511 zebra_serv_un (char *path)
1513 int ret;
1514 int sock, len;
1515 struct sockaddr_un serv;
1516 mode_t old_mask;
1518 /* First of all, unlink existing socket */
1519 unlink (path);
1521 /* Set umask */
1522 old_mask = umask (0077);
1524 /* Make UNIX domain socket. */
1525 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1526 if (sock < 0)
1528 perror ("sock");
1529 return;
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));
1536 #ifdef HAVE_SUN_LEN
1537 len = serv.sun_len = SUN_LEN(&serv);
1538 #else
1539 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1540 #endif /* HAVE_SUN_LEN */
1542 ret = bind (sock, (struct sockaddr *) &serv, len);
1543 if (ret < 0)
1545 perror ("bind");
1546 close (sock);
1547 return;
1550 ret = listen (sock, 5);
1551 if (ret < 0)
1553 perror ("listen");
1554 close (sock);
1555 return;
1558 umask (old_mask);
1560 zebra_event (ZEBRA_SERV, sock, NULL);
1563 /* Zebra's event management function. */
1564 extern struct thread_master *master;
1566 void
1567 zebra_event (enum event event, int sock, struct zserv *client)
1569 switch (event)
1571 case ZEBRA_SERV:
1572 thread_add_read (master, zebra_accept, client, sock);
1573 break;
1574 case ZEBRA_READ:
1575 client->t_read =
1576 thread_add_read (master, zebra_client_read, client, sock);
1577 break;
1578 case ZEBRA_WRITE:
1579 /**/
1580 break;
1584 /* Display default rtm_table for all clients. */
1585 DEFUN (show_table,
1586 show_table_cmd,
1587 "show table",
1588 SHOW_STR
1589 "default routing table to use for all clients\n")
1591 vty_out (vty, "table %d%s", rtm_table_default,
1592 VTY_NEWLINE);
1593 return CMD_SUCCESS;
1596 DEFUN (config_table,
1597 config_table_cmd,
1598 "table TABLENO",
1599 "Configure target kernel routing table\n"
1600 "TABLE integer\n")
1602 rtm_table_default = strtol (argv[0], (char**)0, 10);
1603 return CMD_SUCCESS;
1606 DEFUN (no_ip_forwarding,
1607 no_ip_forwarding_cmd,
1608 "no ip forwarding",
1609 NO_STR
1610 IP_STR
1611 "Turn off IP forwarding")
1613 int ret;
1615 ret = ipforward ();
1617 if (ret == 0)
1619 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);
1620 return CMD_ERR_NOTHING_TODO;
1623 ret = ipforward_off ();
1624 if (ret != 0)
1626 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1627 return CMD_WARNING;
1630 return CMD_SUCCESS;
1633 /* This command is for debugging purpose. */
1634 DEFUN (show_zebra_client,
1635 show_zebra_client_cmd,
1636 "show zebra client",
1637 SHOW_STR
1638 "Zebra information"
1639 "Client information")
1641 listnode node;
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);
1649 return CMD_SUCCESS;
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,
1658 VTY_NEWLINE);
1659 return 0;
1662 /* table node for routing tables. */
1663 struct cmd_node table_node =
1665 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",
1674 SHOW_STR
1675 IP_STR
1676 "IP forwarding status\n")
1678 int ret;
1680 ret = ipforward ();
1682 if (ret == 0)
1683 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1684 else
1685 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1686 return CMD_SUCCESS;
1689 #ifdef HAVE_IPV6
1690 /* Only display ipv6 forwarding is enabled or not. */
1691 DEFUN (show_ipv6_forwarding,
1692 show_ipv6_forwarding_cmd,
1693 "show ipv6 forwarding",
1694 SHOW_STR
1695 "IPv6 information\n"
1696 "Forwarding status\n")
1698 int ret;
1700 ret = ipforward_ipv6 ();
1702 switch (ret)
1704 case -1:
1705 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1706 break;
1707 case 0:
1708 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1709 break;
1710 case 1:
1711 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1712 break;
1713 default:
1714 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1715 break;
1717 return CMD_SUCCESS;
1720 DEFUN (no_ipv6_forwarding,
1721 no_ipv6_forwarding_cmd,
1722 "no ipv6 forwarding",
1723 NO_STR
1724 IP_STR
1725 "Doesn't forward IPv6 protocol packet")
1727 int ret;
1729 ret = ipforward_ipv6_off ();
1730 if (ret != 0)
1732 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1733 return CMD_WARNING;
1736 return CMD_SUCCESS;
1739 #endif /* HAVE_IPV6 */
1742 /* Initialisation of zebra and installation of commands. */
1743 void
1744 zebra_init ()
1746 /* Client list init. */
1747 client_list = list_new ();
1749 /* Forwarding on. */
1750 ipforward_on ();
1751 #ifdef HAVE_IPV6
1752 ipforward_ipv6_on ();
1753 #endif /* HAVE_IPV6 */
1755 /* Make zebra server socket. */
1756 #ifdef HAVE_TCP_ZEBRA
1757 zebra_serv ();
1758 #else
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);
1774 #endif
1776 #ifdef HAVE_IPV6
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 */