MiniDLNA update: 1.0.19.1 to 1.0.20
[tomato.git] / release / src / router / zebra / zebra / zserv.c
blobaa1c834275bc3eb4809c08cbbbbe5df338de33ef
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 extern struct thread_master *master;
55 /* For logging of zebra meesages. */
56 char *zebra_command_str [] =
58 "NULL",
59 "ZEBRA_INTERFACE_ADD",
60 "ZEBRA_INTERFACE_DELETE",
61 "ZEBRA_INTERFACE_ADDRESS_ADD",
62 "ZEBRA_INTERFACE_ADDRESS_DELETE",
63 "ZEBRA_INTERFACE_UP",
64 "ZEBRA_INTERFACE_DOWN",
65 "ZEBRA_IPV4_ROUTE_ADD",
66 "ZEBRA_IPV4_ROUTE_DELETE",
67 "ZEBRA_IPV6_ROUTE_ADD",
68 "ZEBRA_IPV6_ROUTE_DELETE",
69 "ZEBRA_REDISTRIBUTE_ADD",
70 "ZEBRA_REDISTRIBUTE_DELETE",
71 "ZEBRA_REDISTRIBUTE_DEFAULT_ADD",
72 "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE",
73 "ZEBRA_IPV4_NEXTHOP_LOOKUP",
74 "ZEBRA_IPV6_NEXTHOP_LOOKUP",
75 "ZEBRA_IPV4_IMPORT_LOOKUP",
76 "ZEBRA_IPV6_IMPORT_LOOKUP"
79 struct zebra_message_queue
81 struct nsm_message_queue *next;
82 struct nsm_message_queue *prev;
84 u_char *buf;
85 u_int16_t length;
86 u_int16_t written;
89 struct thread *t_write;
90 struct fifo message_queue;
92 int
93 zebra_server_dequeue (struct thread *t)
95 int sock;
96 int nbytes;
97 struct zebra_message_queue *queue;
99 sock = THREAD_FD (t);
100 t_write = NULL;
102 queue = (struct zebra_message_queue *) FIFO_HEAD (&message_queue);
103 if (queue)
105 nbytes = write (sock, queue->buf + queue->written,
106 queue->length - queue->written);
108 if (nbytes <= 0)
110 if (errno != EAGAIN)
111 return -1;
113 else if (nbytes != (queue->length - queue->written))
115 queue->written += nbytes;
117 else
119 FIFO_DEL (queue);
120 XFREE (MTYPE_TMP, queue->buf);
121 XFREE (MTYPE_TMP, queue);
125 if (FIFO_TOP (&message_queue))
126 THREAD_WRITE_ON (master, t_write, zebra_server_dequeue, NULL, sock);
128 return 0;
131 /* Enqueu message. */
132 void
133 zebra_server_enqueue (int sock, u_char *buf, unsigned long length,
134 unsigned long written)
136 struct zebra_message_queue *queue;
138 queue = XCALLOC (MTYPE_TMP, sizeof (struct zebra_message_queue));
139 queue->buf = XMALLOC (MTYPE_TMP, length);
140 memcpy (queue->buf, buf, length);
141 queue->length = length;
142 queue->written = written;
144 FIFO_ADD (&message_queue, queue);
146 THREAD_WRITE_ON (master, t_write, zebra_server_dequeue, NULL, sock);
150 zebra_server_send_message (int sock, u_char *buf, unsigned long length)
152 int nbytes;
154 if (FIFO_TOP (&message_queue))
156 zebra_server_enqueue (sock, buf, length, 0);
157 return 0;
160 /* Send message. */
161 nbytes = write (sock, buf, length);
163 if (nbytes <= 0)
165 if (errno == EAGAIN)
166 zebra_server_enqueue (sock, buf, length, 0);
167 else
168 return -1;
170 else if (nbytes != length)
171 zebra_server_enqueue (sock, buf, length, nbytes);
173 return 0;
176 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
178 zsend_interface_add (struct zserv *client, struct interface *ifp)
180 struct stream *s;
182 /* Check this client need interface information. */
183 if (! client->ifinfo)
184 return -1;
186 s = client->obuf;
187 stream_reset (s);
189 /* Place holder for size. */
190 stream_putw (s, 0);
192 /* Message type. */
193 stream_putc (s, ZEBRA_INTERFACE_ADD);
195 /* Interface information. */
196 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
197 stream_putl (s, ifp->ifindex);
198 stream_putl (s, ifp->flags);
199 stream_putl (s, ifp->metric);
200 stream_putl (s, ifp->mtu);
201 stream_putl (s, ifp->bandwidth);
202 #ifdef HAVE_SOCKADDR_DL
203 stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
204 #else
205 stream_putl (s, ifp->hw_addr_len);
206 if (ifp->hw_addr_len)
207 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
208 #endif /* HAVE_SOCKADDR_DL */
210 /* Write packet size. */
211 stream_putw_at (s, 0, stream_get_endp (s));
213 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
215 return 0;
218 /* Interface deletion from zebra daemon. */
220 zsend_interface_delete (struct zserv *client, struct interface *ifp)
222 struct stream *s;
224 /* Check this client need interface information. */
225 if (! client->ifinfo)
226 return -1;
228 s = client->obuf;
229 stream_reset (s);
231 /* Packet length placeholder. */
232 stream_putw (s, 0);
234 /* Interface information. */
235 stream_putc (s, ZEBRA_INTERFACE_DELETE);
236 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
237 stream_putl (s, ifp->ifindex);
238 stream_putl (s, ifp->flags);
239 stream_putl (s, ifp->metric);
240 stream_putl (s, ifp->mtu);
241 stream_putl (s, ifp->bandwidth);
243 /* Write packet length. */
244 stream_putw_at (s, 0, stream_get_endp (s));
246 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
248 return 0;
251 /* Interface address is added. Send ZEBRA_INTERFACE_ADDRESS_ADD to the
252 client. */
254 zsend_interface_address_add (struct zserv *client, struct interface *ifp,
255 struct connected *ifc)
257 int blen;
258 struct stream *s;
259 struct prefix *p;
261 /* Check this client need interface information. */
262 if (! client->ifinfo)
263 return -1;
265 s = client->obuf;
266 stream_reset (s);
268 /* Place holder for size. */
269 stream_putw (s, 0);
271 stream_putc (s, ZEBRA_INTERFACE_ADDRESS_ADD);
272 stream_putl (s, ifp->ifindex);
274 /* Interface address flag. */
275 stream_putc (s, ifc->flags);
277 /* Prefix information. */
278 p = ifc->address;
279 stream_putc (s, p->family);
280 blen = prefix_blen (p);
281 stream_put (s, &p->u.prefix, blen);
282 stream_putc (s, p->prefixlen);
284 /* Destination. */
285 p = ifc->destination;
286 if (p)
287 stream_put (s, &p->u.prefix, blen);
288 else
289 stream_put (s, NULL, blen);
291 /* Write packet size. */
292 stream_putw_at (s, 0, stream_get_endp (s));
294 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
296 return 0;
299 /* Interface address is deleted. Send ZEBRA_INTERFACE_ADDRESS_DELETE
300 to the client. */
302 zsend_interface_address_delete (struct zserv *client, struct interface *ifp,
303 struct connected *ifc)
305 int blen;
306 struct stream *s;
307 struct prefix *p;
309 /* Check this client need interface information. */
310 if (! client->ifinfo)
311 return -1;
313 s = client->obuf;
314 stream_reset (s);
316 /* Place holder for size. */
317 stream_putw (s, 0);
319 stream_putc (s, ZEBRA_INTERFACE_ADDRESS_DELETE);
320 stream_putl (s, ifp->ifindex);
322 /* Interface address flag. */
323 stream_putc (s, ifc->flags);
325 /* Prefix information. */
326 p = ifc->address;
327 stream_putc (s, p->family);
328 blen = prefix_blen (p);
329 stream_put (s, &p->u.prefix, blen);
331 p = ifc->destination;
332 if (p)
333 stream_put (s, &p->u.prefix, blen);
334 else
335 stream_put (s, NULL, blen);
337 /* Write packet size. */
338 stream_putw_at (s, 0, stream_get_endp (s));
340 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
342 return 0;
346 zsend_interface_up (struct zserv *client, struct interface *ifp)
348 struct stream *s;
350 /* Check this client need interface information. */
351 if (! client->ifinfo)
352 return -1;
354 s = client->obuf;
355 stream_reset (s);
357 /* Place holder for size. */
358 stream_putw (s, 0);
360 /* Zebra command. */
361 stream_putc (s, ZEBRA_INTERFACE_UP);
363 /* Interface information. */
364 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
365 stream_putl (s, ifp->ifindex);
366 stream_putl (s, ifp->flags);
367 stream_putl (s, ifp->metric);
368 stream_putl (s, ifp->mtu);
369 stream_putl (s, ifp->bandwidth);
371 /* Write packet size. */
372 stream_putw_at (s, 0, stream_get_endp (s));
374 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
376 return 0;
380 zsend_interface_down (struct zserv *client, struct interface *ifp)
382 struct stream *s;
384 /* Check this client need interface information. */
385 if (! client->ifinfo)
386 return -1;
388 s = client->obuf;
389 stream_reset (s);
391 /* Place holder for size. */
392 stream_putw (s, 0);
394 /* Zebra command. */
395 stream_putc (s, ZEBRA_INTERFACE_DOWN);
397 /* Interface information. */
398 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
399 stream_putl (s, ifp->ifindex);
400 stream_putl (s, ifp->flags);
401 stream_putl (s, ifp->metric);
402 stream_putl (s, ifp->mtu);
403 stream_putl (s, ifp->bandwidth);
405 /* Write packet size. */
406 stream_putw_at (s, 0, stream_get_endp (s));
408 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
410 return 0;
414 zsend_ipv4_add_multipath (struct zserv *client, struct prefix *p,
415 struct rib *rib)
417 int psize;
418 struct stream *s;
419 struct nexthop *nexthop;
420 struct in_addr empty;
422 empty.s_addr = 0;
423 s = client->obuf;
424 stream_reset (s);
426 /* Place holder for size. */
427 stream_putw (s, 0);
429 /* Put command, type and nexthop. */
430 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
431 stream_putc (s, rib->type);
432 stream_putc (s, rib->flags);
433 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC);
435 /* Prefix. */
436 psize = PSIZE (p->prefixlen);
437 stream_putc (s, p->prefixlen);
438 stream_write (s, (u_char *)&p->u.prefix, psize);
440 /* Nexthop */
441 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
443 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
445 stream_putc (s, 1);
447 if (nexthop->type == NEXTHOP_TYPE_IPV4
448 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
449 stream_put_in_addr (s, &nexthop->gate.ipv4);
450 else
451 stream_put_in_addr (s, &empty);
453 /* Interface index. */
454 stream_putc (s, 1);
455 stream_putl (s, nexthop->ifindex);
457 break;
461 /* Metric */
462 stream_putl (s, rib->metric);
464 /* Write packet size. */
465 stream_putw_at (s, 0, stream_get_endp (s));
467 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
469 return 0;
473 zsend_ipv4_delete_multipath (struct zserv *client, struct prefix *p,
474 struct rib *rib)
476 int psize;
477 struct stream *s;
478 struct nexthop *nexthop;
479 struct in_addr empty;
481 empty.s_addr = 0;
483 s = client->obuf;
484 stream_reset (s);
486 /* Place holder for size. */
487 stream_putw (s, 0);
489 /* Put command, type and nexthop. */
490 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
491 stream_putc (s, rib->type);
492 stream_putc (s, rib->flags);
493 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
495 /* Prefix. */
496 psize = PSIZE (p->prefixlen);
497 stream_putc (s, p->prefixlen);
498 stream_write (s, (u_char *)&p->u.prefix, psize);
500 /* Nexthop */
501 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
503 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
505 stream_putc (s, 1);
507 if (nexthop->type == NEXTHOP_TYPE_IPV4)
508 stream_put_in_addr (s, &nexthop->gate.ipv4);
509 else
510 stream_put_in_addr (s, &empty);
512 /* Interface index. */
513 stream_putc (s, 1);
514 stream_putl (s, nexthop->ifindex);
516 break;
520 /* Write packet size. */
521 stream_putw_at (s, 0, stream_get_endp (s));
523 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
525 return 0;
529 zsend_ipv4_add (struct zserv *client, int type, int flags,
530 struct prefix_ipv4 *p, struct in_addr *nexthop,
531 unsigned int ifindex)
533 int psize;
534 struct stream *s;
536 s = client->obuf;
537 stream_reset (s);
539 /* Place holder for size. */
540 stream_putw (s, 0);
542 /* Put command, type and nexthop. */
543 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
544 stream_putc (s, type);
545 stream_putc (s, flags);
546 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
548 /* Prefix. */
549 psize = PSIZE (p->prefixlen);
550 stream_putc (s, p->prefixlen);
551 stream_write (s, (u_char *)&p->prefix, psize);
553 /* Nexthop */
554 stream_putc (s, 1);
555 stream_put_in_addr (s, nexthop);
557 /* Interface index. */
558 stream_putc (s, 1);
559 stream_putl (s, ifindex);
561 /* Write packet size. */
562 stream_putw_at (s, 0, stream_get_endp (s));
564 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
566 return 0;
570 zsend_ipv4_delete (struct zserv *client, int type, int flags,
571 struct prefix_ipv4 *p, struct in_addr *nexthop,
572 unsigned int ifindex)
574 int psize;
575 struct stream *s;
577 s = client->obuf;
578 stream_reset (s);
580 /* Place holder for size. */
581 stream_putw (s, 0);
583 /* Put command, type and nexthop. */
584 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
585 stream_putc (s, type);
586 stream_putc (s, flags);
587 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
589 /* Prefix. */
590 psize = PSIZE (p->prefixlen);
591 stream_putc (s, p->prefixlen);
592 stream_write (s, (u_char *)&p->prefix, psize);
594 /* Nexthop */
595 stream_putc (s, 1);
596 stream_put_in_addr (s, nexthop);
598 /* Interface index. */
599 stream_putc (s, 1);
600 stream_putl (s, ifindex);
602 /* Write packet size. */
603 stream_putw_at (s, 0, stream_get_endp (s));
605 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
607 return 0;
610 #ifdef HAVE_IPV6
612 zsend_ipv6_add (struct zserv *client, int type, int flags,
613 struct prefix_ipv6 *p, struct in6_addr *nexthop,
614 unsigned int ifindex)
616 int psize;
617 struct stream *s;
619 s = client->obuf;
620 stream_reset (s);
622 /* Place holder for size. */
623 stream_putw (s, 0);
625 /* Put command, type and nexthop. */
626 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
627 stream_putc (s, type);
628 stream_putc (s, flags);
629 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
631 /* Prefix. */
632 psize = PSIZE (p->prefixlen);
633 stream_putc (s, p->prefixlen);
634 stream_write (s, (u_char *)&p->prefix, psize);
636 /* Nexthop */
637 stream_putc (s, 1);
638 stream_write (s, (u_char *)nexthop, 16);
640 /* Interface index. */
641 stream_putc (s, 1);
642 stream_putl (s, ifindex);
644 /* Write packet size. */
645 stream_putw_at (s, 0, stream_get_endp (s));
647 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
649 return 0;
653 zsend_ipv6_add_multipath (struct zserv *client, struct prefix *p,
654 struct rib *rib)
656 int psize;
657 struct stream *s;
658 struct nexthop *nexthop;
659 struct in6_addr empty;
661 memset (&empty, 0, sizeof (struct in6_addr));
662 s = client->obuf;
663 stream_reset (s);
665 /* Place holder for size. */
666 stream_putw (s, 0);
668 /* Put command, type and nexthop. */
669 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
670 stream_putc (s, rib->type);
671 stream_putc (s, rib->flags);
672 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC);
674 /* Prefix. */
675 psize = PSIZE (p->prefixlen);
676 stream_putc (s, p->prefixlen);
677 stream_write (s, (u_char *) &p->u.prefix, psize);
679 /* Nexthop */
680 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
682 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
684 stream_putc (s, 1);
686 if (nexthop->type == NEXTHOP_TYPE_IPV6)
687 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
688 else
689 stream_write (s, (u_char *) &empty, 16);
691 /* Interface index. */
692 stream_putc (s, 1);
693 stream_putl (s, nexthop->ifindex);
695 break;
699 /* Metric */
700 stream_putl (s, rib->metric);
702 /* Write packet size. */
703 stream_putw_at (s, 0, stream_get_endp (s));
705 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
707 return 0;
711 zsend_ipv6_delete (struct zserv *client, int type, int flags,
712 struct prefix_ipv6 *p, struct in6_addr *nexthop,
713 unsigned int ifindex)
715 int psize;
716 struct stream *s;
718 s = client->obuf;
719 stream_reset (s);
721 /* Place holder for size. */
722 stream_putw (s, 0);
724 /* Put command, type and nexthop. */
725 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
726 stream_putc (s, type);
727 stream_putc (s, flags);
728 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
730 /* Prefix. */
731 psize = PSIZE (p->prefixlen);
732 stream_putc (s, p->prefixlen);
733 stream_write (s, (u_char *)&p->prefix, psize);
735 /* Nexthop */
736 stream_putc (s, 1);
737 stream_write (s, (u_char *)nexthop, 16);
739 /* Interface index. */
740 stream_putc (s, 1);
741 stream_putl (s, ifindex);
743 /* Write packet size. */
744 stream_putw_at (s, 0, stream_get_endp (s));
746 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
748 return 0;
752 zsend_ipv6_delete_multipath (struct zserv *client, struct prefix *p,
753 struct rib *rib)
755 int psize;
756 struct stream *s;
757 struct nexthop *nexthop;
758 struct in6_addr empty;
760 memset (&empty, 0, sizeof (struct in6_addr));
761 s = client->obuf;
762 stream_reset (s);
764 /* Place holder for size. */
765 stream_putw (s, 0);
767 /* Put command, type and nexthop. */
768 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
769 stream_putc (s, rib->type);
770 stream_putc (s, rib->flags);
771 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
773 /* Prefix. */
774 psize = PSIZE (p->prefixlen);
775 stream_putc (s, p->prefixlen);
776 stream_write (s, (u_char *)&p->u.prefix, psize);
778 /* Nexthop */
779 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
781 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
783 stream_putc (s, 1);
785 if (nexthop->type == NEXTHOP_TYPE_IPV6)
786 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
787 else
788 stream_write (s, (u_char *) &empty, 16);
790 /* Interface index. */
791 stream_putc (s, 1);
792 stream_putl (s, nexthop->ifindex);
794 break;
798 /* Write packet size. */
799 stream_putw_at (s, 0, stream_get_endp (s));
801 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
803 return 0;
807 zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
809 struct stream *s;
810 struct rib *rib;
811 unsigned long nump;
812 u_char num;
813 struct nexthop *nexthop;
815 /* Lookup nexthop. */
816 rib = rib_match_ipv6 (addr);
818 /* Get output stream. */
819 s = client->obuf;
820 stream_reset (s);
822 /* Fill in result. */
823 stream_putw (s, 0);
824 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
825 stream_put (s, &addr, 16);
827 if (rib)
829 stream_putl (s, rib->metric);
830 num = 0;
831 nump = s->putp;
832 stream_putc (s, 0);
833 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
834 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
836 stream_putc (s, nexthop->type);
837 switch (nexthop->type)
839 case ZEBRA_NEXTHOP_IPV6:
840 stream_put (s, &nexthop->gate.ipv6, 16);
841 break;
842 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
843 case ZEBRA_NEXTHOP_IPV6_IFNAME:
844 stream_put (s, &nexthop->gate.ipv6, 16);
845 stream_putl (s, nexthop->ifindex);
846 break;
847 case ZEBRA_NEXTHOP_IFINDEX:
848 case ZEBRA_NEXTHOP_IFNAME:
849 stream_putl (s, nexthop->ifindex);
850 break;
852 num++;
854 stream_putc_at (s, nump, num);
856 else
858 stream_putl (s, 0);
859 stream_putc (s, 0);
862 stream_putw_at (s, 0, stream_get_endp (s));
864 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
866 return 0;
868 #endif /* HAVE_IPV6 */
871 zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
873 struct stream *s;
874 struct rib *rib;
875 unsigned long nump;
876 u_char num;
877 struct nexthop *nexthop;
879 /* Lookup nexthop. */
880 rib = rib_match_ipv4 (addr);
882 /* Get output stream. */
883 s = client->obuf;
884 stream_reset (s);
886 /* Fill in result. */
887 stream_putw (s, 0);
888 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
889 stream_put_in_addr (s, &addr);
891 if (rib)
893 stream_putl (s, rib->metric);
894 num = 0;
895 nump = s->putp;
896 stream_putc (s, 0);
897 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
898 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
900 stream_putc (s, nexthop->type);
901 switch (nexthop->type)
903 case ZEBRA_NEXTHOP_IPV4:
904 stream_put_in_addr (s, &nexthop->gate.ipv4);
905 break;
906 case ZEBRA_NEXTHOP_IFINDEX:
907 case ZEBRA_NEXTHOP_IFNAME:
908 stream_putl (s, nexthop->ifindex);
909 break;
911 num++;
913 stream_putc_at (s, nump, num);
915 else
917 stream_putl (s, 0);
918 stream_putc (s, 0);
921 stream_putw_at (s, 0, stream_get_endp (s));
923 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
925 return 0;
929 zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
931 struct stream *s;
932 struct rib *rib;
933 unsigned long nump;
934 u_char num;
935 struct nexthop *nexthop;
937 /* Lookup nexthop. */
938 rib = rib_lookup_ipv4 (p);
940 /* Get output stream. */
941 s = client->obuf;
942 stream_reset (s);
944 /* Fill in result. */
945 stream_putw (s, 0);
946 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
947 stream_put_in_addr (s, &p->prefix);
949 if (rib)
951 stream_putl (s, rib->metric);
952 num = 0;
953 nump = s->putp;
954 stream_putc (s, 0);
955 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
956 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
958 stream_putc (s, nexthop->type);
959 switch (nexthop->type)
961 case ZEBRA_NEXTHOP_IPV4:
962 stream_put_in_addr (s, &nexthop->gate.ipv4);
963 break;
964 case ZEBRA_NEXTHOP_IFINDEX:
965 case ZEBRA_NEXTHOP_IFNAME:
966 stream_putl (s, nexthop->ifindex);
967 break;
969 num++;
971 stream_putc_at (s, nump, num);
973 else
975 stream_putl (s, 0);
976 stream_putc (s, 0);
979 stream_putw_at (s, 0, stream_get_endp (s));
981 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
983 return 0;
986 /* Register zebra server interface information. Send current all
987 interface and address information. */
988 void
989 zread_interface_add (struct zserv *client, u_short length)
991 listnode ifnode;
992 listnode cnode;
993 struct interface *ifp;
994 struct connected *c;
996 /* Interface information is needed. */
997 client->ifinfo = 1;
999 for (ifnode = listhead (iflist); ifnode; ifnode = nextnode (ifnode))
1001 ifp = getdata (ifnode);
1003 /* Skip pseudo interface. */
1004 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1005 continue;
1007 zsend_interface_add (client, ifp);
1009 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
1011 c = getdata (cnode);
1012 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
1013 zsend_interface_address_add (client, ifp, c);
1018 /* Unregister zebra server interface information. */
1019 void
1020 zread_interface_delete (struct zserv *client, u_short length)
1022 client->ifinfo = 0;
1025 /* This function support multiple nexthop. */
1026 void
1027 zread_ipv4_add (struct zserv *client, u_short length)
1029 int i;
1030 struct rib *rib;
1031 struct prefix_ipv4 p;
1032 u_char message;
1033 struct in_addr nexthop;
1034 u_char nexthop_num;
1035 u_char nexthop_type;
1036 struct stream *s;
1037 unsigned int ifindex;
1038 u_char ifname_len;
1040 /* Get input stream. */
1041 s = client->ibuf;
1043 /* Allocate new rib. */
1044 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1045 memset (rib, 0, sizeof (struct rib));
1047 /* Type, flags, message. */
1048 rib->type = stream_getc (s);
1049 rib->flags = stream_getc (s);
1050 message = stream_getc (s);
1051 rib->uptime = time (NULL);
1053 /* IPv4 prefix. */
1054 memset (&p, 0, sizeof (struct prefix_ipv4));
1055 p.family = AF_INET;
1056 p.prefixlen = stream_getc (s);
1057 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1059 /* Nexthop parse. */
1060 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1062 nexthop_num = stream_getc (s);
1064 for (i = 0; i < nexthop_num; i++)
1066 nexthop_type = stream_getc (s);
1068 switch (nexthop_type)
1070 case ZEBRA_NEXTHOP_IFINDEX:
1071 ifindex = stream_getl (s);
1072 nexthop_ifindex_add (rib, ifindex);
1073 break;
1074 case ZEBRA_NEXTHOP_IFNAME:
1075 ifname_len = stream_getc (s);
1076 stream_forward (s, ifname_len);
1077 break;
1078 case ZEBRA_NEXTHOP_IPV4:
1079 nexthop.s_addr = stream_get_ipv4 (s);
1080 nexthop_ipv4_add (rib, &nexthop);
1081 break;
1082 case ZEBRA_NEXTHOP_IPV6:
1083 stream_forward (s, IPV6_MAX_BYTELEN);
1084 break;
1085 case ZEBRA_NEXTHOP_BLACKHOLE:
1086 nexthop_blackhole_add (rib);
1087 break;
1092 /* Distance. */
1093 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1094 rib->distance = stream_getc (s);
1096 /* Metric. */
1097 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1098 rib->metric = stream_getl (s);
1100 rib_add_ipv4_multipath (&p, rib);
1103 /* Zebra server IPv4 prefix delete function. */
1104 void
1105 zread_ipv4_delete (struct zserv *client, u_short length)
1107 int i;
1108 struct stream *s;
1109 struct zapi_ipv4 api;
1110 struct in_addr nexthop;
1111 unsigned long ifindex;
1112 struct prefix_ipv4 p;
1113 u_char nexthop_num;
1114 u_char nexthop_type;
1115 u_char ifname_len;
1117 s = client->ibuf;
1118 ifindex = 0;
1119 nexthop.s_addr = 0;
1121 /* Type, flags, message. */
1122 api.type = stream_getc (s);
1123 api.flags = stream_getc (s);
1124 api.message = stream_getc (s);
1126 /* IPv4 prefix. */
1127 memset (&p, 0, sizeof (struct prefix_ipv4));
1128 p.family = AF_INET;
1129 p.prefixlen = stream_getc (s);
1130 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1132 /* Nexthop, ifindex, distance, metric. */
1133 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1135 nexthop_num = stream_getc (s);
1137 for (i = 0; i < nexthop_num; i++)
1139 nexthop_type = stream_getc (s);
1141 switch (nexthop_type)
1143 case ZEBRA_NEXTHOP_IFINDEX:
1144 ifindex = stream_getl (s);
1145 break;
1146 case ZEBRA_NEXTHOP_IFNAME:
1147 ifname_len = stream_getc (s);
1148 stream_forward (s, ifname_len);
1149 break;
1150 case ZEBRA_NEXTHOP_IPV4:
1151 nexthop.s_addr = stream_get_ipv4 (s);
1152 break;
1153 case ZEBRA_NEXTHOP_IPV6:
1154 stream_forward (s, IPV6_MAX_BYTELEN);
1155 break;
1160 /* Distance. */
1161 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1162 api.distance = stream_getc (s);
1163 else
1164 api.distance = 0;
1166 /* Metric. */
1167 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1168 api.metric = stream_getl (s);
1169 else
1170 api.metric = 0;
1172 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
1173 client->rtm_table);
1176 /* Nexthop lookup for IPv4. */
1177 void
1178 zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
1180 struct in_addr addr;
1182 addr.s_addr = stream_get_ipv4 (client->ibuf);
1183 zsend_ipv4_nexthop_lookup (client, addr);
1186 /* Nexthop lookup for IPv4. */
1187 void
1188 zread_ipv4_import_lookup (struct zserv *client, u_short length)
1190 struct prefix_ipv4 p;
1192 p.family = AF_INET;
1193 p.prefixlen = stream_getc (client->ibuf);
1194 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1196 zsend_ipv4_import_lookup (client, &p);
1199 #ifdef HAVE_IPV6
1200 /* Zebra server IPv6 prefix add function. */
1201 void
1202 zread_ipv6_add (struct zserv *client, u_short length)
1204 int i;
1205 struct stream *s;
1206 struct zapi_ipv6 api;
1207 struct in6_addr nexthop;
1208 unsigned long ifindex;
1209 struct prefix_ipv6 p;
1211 s = client->ibuf;
1212 ifindex = 0;
1213 memset (&nexthop, 0, sizeof (struct in6_addr));
1215 /* Type, flags, message. */
1216 api.type = stream_getc (s);
1217 api.flags = stream_getc (s);
1218 api.message = stream_getc (s);
1220 /* IPv4 prefix. */
1221 memset (&p, 0, sizeof (struct prefix_ipv6));
1222 p.family = AF_INET6;
1223 p.prefixlen = stream_getc (s);
1224 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1226 /* Nexthop, ifindex, distance, metric. */
1227 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1229 u_char nexthop_type;
1231 api.nexthop_num = stream_getc (s);
1232 for (i = 0; i < api.nexthop_num; i++)
1234 nexthop_type = stream_getc (s);
1236 switch (nexthop_type)
1238 case ZEBRA_NEXTHOP_IPV6:
1239 stream_get (&nexthop, s, 16);
1240 break;
1241 case ZEBRA_NEXTHOP_IFINDEX:
1242 ifindex = stream_getl (s);
1243 break;
1248 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1249 api.distance = stream_getc (s);
1250 else
1251 api.distance = 0;
1253 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1254 api.metric = stream_getl (s);
1255 else
1256 api.metric = 0;
1258 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1259 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1260 else
1261 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1264 /* Zebra server IPv6 prefix delete function. */
1265 void
1266 zread_ipv6_delete (struct zserv *client, u_short length)
1268 int i;
1269 struct stream *s;
1270 struct zapi_ipv6 api;
1271 struct in6_addr nexthop;
1272 unsigned long ifindex;
1273 struct prefix_ipv6 p;
1275 s = client->ibuf;
1276 ifindex = 0;
1277 memset (&nexthop, 0, sizeof (struct in6_addr));
1279 /* Type, flags, message. */
1280 api.type = stream_getc (s);
1281 api.flags = stream_getc (s);
1282 api.message = stream_getc (s);
1284 /* IPv4 prefix. */
1285 memset (&p, 0, sizeof (struct prefix_ipv6));
1286 p.family = AF_INET6;
1287 p.prefixlen = stream_getc (s);
1288 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1290 /* Nexthop, ifindex, distance, metric. */
1291 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1293 u_char nexthop_type;
1295 api.nexthop_num = stream_getc (s);
1296 for (i = 0; i < api.nexthop_num; i++)
1298 nexthop_type = stream_getc (s);
1300 switch (nexthop_type)
1302 case ZEBRA_NEXTHOP_IPV6:
1303 stream_get (&nexthop, s, 16);
1304 break;
1305 case ZEBRA_NEXTHOP_IFINDEX:
1306 ifindex = stream_getl (s);
1307 break;
1312 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1313 api.distance = stream_getc (s);
1314 else
1315 api.distance = 0;
1316 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1317 api.metric = stream_getl (s);
1318 else
1319 api.metric = 0;
1321 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1322 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1323 else
1324 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1327 void
1328 zebra_read_ipv6 (int command, struct zserv *client, u_short length)
1330 u_char type;
1331 u_char flags;
1332 struct in6_addr nexthop, *gate;
1333 u_char *lim;
1334 u_char *pnt;
1335 unsigned int ifindex;
1337 pnt = stream_pnt (client->ibuf);
1338 lim = pnt + length;
1340 type = stream_getc (client->ibuf);
1341 flags = stream_getc (client->ibuf);
1342 stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr));
1344 while (stream_pnt (client->ibuf) < lim)
1346 int size;
1347 struct prefix_ipv6 p;
1349 ifindex = stream_getl (client->ibuf);
1351 memset (&p, 0, sizeof (struct prefix_ipv6));
1352 p.family = AF_INET6;
1353 p.prefixlen = stream_getc (client->ibuf);
1354 size = PSIZE(p.prefixlen);
1355 stream_get (&p.prefix, client->ibuf, size);
1357 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1358 gate = NULL;
1359 else
1360 gate = &nexthop;
1362 if (command == ZEBRA_IPV6_ROUTE_ADD)
1363 rib_add_ipv6 (type, flags, &p, gate, ifindex, 0);
1364 else
1365 rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);
1369 void
1370 zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1372 struct in6_addr addr;
1373 char buf[BUFSIZ];
1375 stream_get (&addr, client->ibuf, 16);
1376 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1378 zsend_ipv6_nexthop_lookup (client, &addr);
1380 #endif /* HAVE_IPV6 */
1382 /* Close zebra client. */
1383 void
1384 zebra_client_close (struct zserv *client)
1386 /* Close file descriptor. */
1387 if (client->sock)
1389 close (client->sock);
1390 client->sock = -1;
1393 /* Free stream buffers. */
1394 if (client->ibuf)
1395 stream_free (client->ibuf);
1396 if (client->obuf)
1397 stream_free (client->obuf);
1399 /* Release threads. */
1400 if (client->t_read)
1401 thread_cancel (client->t_read);
1402 if (client->t_write)
1403 thread_cancel (client->t_write);
1405 /* Free client structure. */
1406 listnode_delete (client_list, client);
1407 XFREE (0, client);
1410 /* Make new client. */
1411 void
1412 zebra_client_create (int sock)
1414 struct zserv *client;
1416 client = XCALLOC (0, sizeof (struct zserv));
1418 /* Make client input/output buffer. */
1419 client->sock = sock;
1420 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1421 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1423 /* Set table number. */
1424 client->rtm_table = rtm_table_default;
1426 /* Add this client to linked list. */
1427 listnode_add (client_list, client);
1429 /* Make new read thread. */
1430 zebra_event (ZEBRA_READ, sock, client);
1433 /* Handler of zebra service request. */
1435 zebra_client_read (struct thread *thread)
1437 int sock;
1438 struct zserv *client;
1439 int nbyte;
1440 u_short length;
1441 u_char command;
1443 /* Get thread data. Reset reading thread because I'm running. */
1444 sock = THREAD_FD (thread);
1445 client = THREAD_ARG (thread);
1446 client->t_read = NULL;
1448 /* Read length and command. */
1449 nbyte = stream_read (client->ibuf, sock, 3);
1450 if (nbyte <= 0)
1452 if (IS_ZEBRA_DEBUG_EVENT)
1453 zlog_info ("connection closed socket [%d]", sock);
1454 zebra_client_close (client);
1455 return -1;
1457 length = stream_getw (client->ibuf);
1458 command = stream_getc (client->ibuf);
1460 if (length < 3)
1462 if (IS_ZEBRA_DEBUG_EVENT)
1463 zlog_info ("length %d is less than 3 ", length);
1464 zebra_client_close (client);
1465 return -1;
1468 length -= 3;
1470 /* Read rest of data. */
1471 if (length)
1473 nbyte = stream_read (client->ibuf, sock, length);
1474 if (nbyte <= 0)
1476 if (IS_ZEBRA_DEBUG_EVENT)
1477 zlog_info ("connection closed [%d] when reading zebra data", sock);
1478 zebra_client_close (client);
1479 return -1;
1483 /* Debug packet information. */
1484 if (IS_ZEBRA_DEBUG_EVENT)
1485 zlog_info ("zebra message comes from socket [%d]", sock);
1487 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1488 zlog_info ("zebra message received [%s] %d",
1489 zebra_command_str[command], length);
1491 switch (command)
1493 case ZEBRA_INTERFACE_ADD:
1494 zread_interface_add (client, length);
1495 break;
1496 case ZEBRA_INTERFACE_DELETE:
1497 zread_interface_delete (client, length);
1498 break;
1499 case ZEBRA_IPV4_ROUTE_ADD:
1500 zread_ipv4_add (client, length);
1501 break;
1502 case ZEBRA_IPV4_ROUTE_DELETE:
1503 zread_ipv4_delete (client, length);
1504 break;
1505 #ifdef HAVE_IPV6
1506 case ZEBRA_IPV6_ROUTE_ADD:
1507 zread_ipv6_add (client, length);
1508 break;
1509 case ZEBRA_IPV6_ROUTE_DELETE:
1510 zread_ipv6_delete (client, length);
1511 break;
1512 #endif /* HAVE_IPV6 */
1513 case ZEBRA_REDISTRIBUTE_ADD:
1514 zebra_redistribute_add (command, client, length);
1515 break;
1516 case ZEBRA_REDISTRIBUTE_DELETE:
1517 zebra_redistribute_delete (command, client, length);
1518 break;
1519 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1520 zebra_redistribute_default_add (command, client, length);
1521 break;
1522 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1523 zebra_redistribute_default_delete (command, client, length);
1524 break;
1525 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1526 zread_ipv4_nexthop_lookup (client, length);
1527 break;
1528 #ifdef HAVE_IPV6
1529 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1530 zread_ipv6_nexthop_lookup (client, length);
1531 break;
1532 #endif /* HAVE_IPV6 */
1533 case ZEBRA_IPV4_IMPORT_LOOKUP:
1534 zread_ipv4_import_lookup (client, length);
1535 break;
1536 default:
1537 zlog_info ("Zebra received unknown command %d", command);
1538 break;
1541 stream_reset (client->ibuf);
1542 zebra_event (ZEBRA_READ, sock, client);
1544 return 0;
1547 /* Write output buffer to the socket. */
1548 void
1549 zebra_write (struct thread *thread)
1551 int sock;
1552 struct zserv *client;
1554 /* Thread treatment. */
1555 sock = THREAD_FD (thread);
1556 client = THREAD_ARG (thread);
1557 client->t_write = NULL;
1559 stream_flush (client->obuf, sock);
1562 /* Accept code of zebra server socket. */
1564 zebra_accept (struct thread *thread)
1566 int val;
1567 int accept_sock;
1568 int client_sock;
1569 struct sockaddr_in client;
1570 socklen_t len;
1572 accept_sock = THREAD_FD (thread);
1574 len = sizeof (struct sockaddr_in);
1575 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1577 if (client_sock < 0)
1579 zlog_warn ("Can't accept zebra socket: %s", strerror (errno));
1580 return -1;
1583 /* Make client socket non-blocking. */
1585 val = fcntl (client_sock, F_GETFL, 0);
1586 fcntl (client_sock, F_SETFL, (val | O_NONBLOCK));
1588 /* Create new zebra client. */
1589 zebra_client_create (client_sock);
1591 /* Register myself. */
1592 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1594 return 0;
1597 /* Make zebra's server socket. */
1598 void
1599 zebra_serv ()
1601 int ret;
1602 int accept_sock;
1603 struct sockaddr_in addr;
1605 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1607 if (accept_sock < 0)
1609 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1610 zlog_warn ("zebra can't provice full functionality due to above error");
1611 return;
1614 memset (&addr, 0, sizeof (struct sockaddr_in));
1615 addr.sin_family = AF_INET;
1616 addr.sin_port = htons (ZEBRA_PORT);
1617 #ifdef HAVE_SIN_LEN
1618 addr.sin_len = sizeof (struct sockaddr_in);
1619 #endif /* HAVE_SIN_LEN */
1620 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1622 sockopt_reuseaddr (accept_sock);
1623 sockopt_reuseport (accept_sock);
1625 ret = bind (accept_sock, (struct sockaddr *)&addr,
1626 sizeof (struct sockaddr_in));
1627 if (ret < 0)
1629 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1630 zlog_warn ("zebra can't provice full functionality due to above error");
1631 close (accept_sock); /* Avoid sd leak. */
1632 return;
1635 ret = listen (accept_sock, 1);
1636 if (ret < 0)
1638 zlog_warn ("Can't listen to socket: %s", strerror (errno));
1639 zlog_warn ("zebra can't provice full functionality due to above error");
1640 close (accept_sock); /* Avoid sd leak. */
1641 return;
1644 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1647 /* For sockaddr_un. */
1648 #include <sys/un.h>
1650 /* zebra server UNIX domain socket. */
1651 void
1652 zebra_serv_un (char *path)
1654 int ret;
1655 int sock, len;
1656 struct sockaddr_un serv;
1657 mode_t old_mask;
1659 /* First of all, unlink existing socket */
1660 unlink (path);
1662 /* Set umask */
1663 old_mask = umask (0077);
1665 /* Make UNIX domain socket. */
1666 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1667 if (sock < 0)
1669 perror ("sock");
1670 return;
1673 /* Make server socket. */
1674 memset (&serv, 0, sizeof (struct sockaddr_un));
1675 serv.sun_family = AF_UNIX;
1676 strncpy (serv.sun_path, path, strlen (path));
1677 #ifdef HAVE_SUN_LEN
1678 len = serv.sun_len = SUN_LEN(&serv);
1679 #else
1680 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1681 #endif /* HAVE_SUN_LEN */
1683 ret = bind (sock, (struct sockaddr *) &serv, len);
1684 if (ret < 0)
1686 perror ("bind");
1687 close (sock);
1688 return;
1691 ret = listen (sock, 5);
1692 if (ret < 0)
1694 perror ("listen");
1695 close (sock);
1696 return;
1699 umask (old_mask);
1701 zebra_event (ZEBRA_SERV, sock, NULL);
1704 /* Zebra's event management function. */
1705 extern struct thread_master *master;
1707 void
1708 zebra_event (enum event event, int sock, struct zserv *client)
1710 switch (event)
1712 case ZEBRA_SERV:
1713 thread_add_read (master, zebra_accept, client, sock);
1714 break;
1715 case ZEBRA_READ:
1716 client->t_read =
1717 thread_add_read (master, zebra_client_read, client, sock);
1718 break;
1719 case ZEBRA_WRITE:
1720 /**/
1721 break;
1725 /* Display default rtm_table for all clients. */
1726 DEFUN (show_table,
1727 show_table_cmd,
1728 "show table",
1729 SHOW_STR
1730 "default routing table to use for all clients\n")
1732 vty_out (vty, "table %d%s", rtm_table_default,
1733 VTY_NEWLINE);
1734 return CMD_SUCCESS;
1737 DEFUN (config_table,
1738 config_table_cmd,
1739 "table TABLENO",
1740 "Configure target kernel routing table\n"
1741 "TABLE integer\n")
1743 rtm_table_default = strtol (argv[0], (char**)0, 10);
1744 return CMD_SUCCESS;
1747 DEFUN (no_ip_forwarding,
1748 no_ip_forwarding_cmd,
1749 "no ip forwarding",
1750 NO_STR
1751 IP_STR
1752 "Turn off IP forwarding")
1754 int ret;
1756 ret = ipforward ();
1758 if (ret == 0)
1760 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);
1761 return CMD_ERR_NOTHING_TODO;
1764 ret = ipforward_off ();
1765 if (ret != 0)
1767 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1768 return CMD_WARNING;
1771 return CMD_SUCCESS;
1774 /* This command is for debugging purpose. */
1775 DEFUN (show_zebra_client,
1776 show_zebra_client_cmd,
1777 "show zebra client",
1778 SHOW_STR
1779 "Zebra information"
1780 "Client information")
1782 listnode node;
1783 struct zserv *client;
1785 for (node = listhead (client_list); node; nextnode (node))
1787 client = getdata (node);
1788 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1790 return CMD_SUCCESS;
1793 /* Table configuration write function. */
1795 config_write_table (struct vty *vty)
1797 if (rtm_table_default)
1798 vty_out (vty, "table %d%s", rtm_table_default,
1799 VTY_NEWLINE);
1800 return 0;
1803 /* table node for routing tables. */
1804 struct cmd_node table_node =
1806 TABLE_NODE,
1807 "", /* This node has no interface. */
1811 /* Only display ip forwarding is enabled or not. */
1812 DEFUN (show_ip_forwarding,
1813 show_ip_forwarding_cmd,
1814 "show ip forwarding",
1815 SHOW_STR
1816 IP_STR
1817 "IP forwarding status\n")
1819 int ret;
1821 ret = ipforward ();
1823 if (ret == 0)
1824 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1825 else
1826 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1827 return CMD_SUCCESS;
1830 #ifdef HAVE_IPV6
1831 /* Only display ipv6 forwarding is enabled or not. */
1832 DEFUN (show_ipv6_forwarding,
1833 show_ipv6_forwarding_cmd,
1834 "show ipv6 forwarding",
1835 SHOW_STR
1836 "IPv6 information\n"
1837 "Forwarding status\n")
1839 int ret;
1841 ret = ipforward_ipv6 ();
1843 switch (ret)
1845 case -1:
1846 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1847 break;
1848 case 0:
1849 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1850 break;
1851 case 1:
1852 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1853 break;
1854 default:
1855 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1856 break;
1858 return CMD_SUCCESS;
1861 DEFUN (no_ipv6_forwarding,
1862 no_ipv6_forwarding_cmd,
1863 "no ipv6 forwarding",
1864 NO_STR
1865 IP_STR
1866 "Doesn't forward IPv6 protocol packet")
1868 int ret;
1870 ret = ipforward_ipv6_off ();
1871 if (ret != 0)
1873 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1874 return CMD_WARNING;
1877 return CMD_SUCCESS;
1880 #endif /* HAVE_IPV6 */
1882 /* IPForwarding configuration write function. */
1884 config_write_forwarding (struct vty *vty)
1886 if (! ipforward ())
1887 vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
1888 #ifdef HAVE_IPV6
1889 if (! ipforward_ipv6 ())
1890 vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
1891 #endif /* HAVE_IPV6 */
1892 vty_out (vty, "!%s", VTY_NEWLINE);
1893 return 0;
1896 /* table node for routing tables. */
1897 struct cmd_node forwarding_node =
1899 FORWARDING_NODE,
1900 "", /* This node has no interface. */
1905 /* Initialisation of zebra and installation of commands. */
1906 void
1907 zebra_init ()
1909 /* Client list init. */
1910 client_list = list_new ();
1912 /* Forwarding is on by default. */
1913 ipforward_on ();
1914 #ifdef HAVE_IPV6
1915 ipforward_ipv6_on ();
1916 #endif /* HAVE_IPV6 */
1918 /* Make zebra server socket. */
1919 #ifdef HAVE_TCP_ZEBRA
1920 zebra_serv ();
1921 #else
1922 zebra_serv_un (ZEBRA_SERV_PATH);
1923 #endif /* HAVE_TCP_ZEBRA */
1925 /* Install configuration write function. */
1926 install_node (&table_node, config_write_table);
1927 install_node (&forwarding_node, config_write_forwarding);
1929 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1930 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
1931 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1932 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1934 #ifdef HAVE_NETLINK
1935 install_element (VIEW_NODE, &show_table_cmd);
1936 install_element (ENABLE_NODE, &show_table_cmd);
1937 install_element (CONFIG_NODE, &config_table_cmd);
1938 #endif /* HAVE_NETLINK */
1940 #ifdef HAVE_IPV6
1941 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1942 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
1943 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1944 #endif /* HAVE_IPV6 */
1946 FIFO_INIT(&message_queue);
1947 t_write = NULL;