]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zserv.c
Route (reject|blackhole) support from 6Wind patch.
[mirror_frr.git] / zebra / zserv.c
1 /* Zebra daemon server routine.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
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.
10 *
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.
15 *
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.
20 */
21
22 #include <zebra.h>
23
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"
36
37 #include "zebra/zserv.h"
38 #include "zebra/redistribute.h"
39 #include "zebra/debug.h"
40 #include "zebra/ipforward.h"
41 \f
42 /* Event list of zebra. */
43 enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
44
45 /* Zebra client list. */
46 list client_list;
47
48 /* Default rtm_table for all clients */
49 int rtm_table_default = 0;
50
51 void zebra_event (enum event event, int sock, struct zserv *client);
52
53 extern struct thread_master *master;
54 \f
55 /* For logging of zebra meesages. */
56 char *zebra_command_str [] =
57 {
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"
77 };
78 \f
79 struct zebra_message_queue
80 {
81 struct nsm_message_queue *next;
82 struct nsm_message_queue *prev;
83
84 u_char *buf;
85 u_int16_t length;
86 u_int16_t written;
87 };
88
89 struct thread *t_write;
90 struct fifo message_queue;
91
92 int
93 zebra_server_dequeue (struct thread *t)
94 {
95 int sock;
96 int nbytes;
97 struct zebra_message_queue *queue;
98
99 sock = THREAD_FD (t);
100 t_write = NULL;
101
102 queue = (struct zebra_message_queue *) FIFO_HEAD (&message_queue);
103 if (queue)
104 {
105 nbytes = write (sock, queue->buf + queue->written,
106 queue->length - queue->written);
107
108 if (nbytes <= 0)
109 {
110 if (errno != EAGAIN)
111 return -1;
112 }
113 else if (nbytes != (queue->length - queue->written))
114 {
115 queue->written += nbytes;
116 }
117 else
118 {
119 FIFO_DEL (queue);
120 XFREE (MTYPE_TMP, queue->buf);
121 XFREE (MTYPE_TMP, queue);
122 }
123 }
124
125 if (FIFO_TOP (&message_queue))
126 THREAD_WRITE_ON (master, t_write, zebra_server_dequeue, NULL, sock);
127
128 return 0;
129 }
130
131 /* Enqueu message. */
132 void
133 zebra_server_enqueue (int sock, u_char *buf, unsigned long length,
134 unsigned long written)
135 {
136 struct zebra_message_queue *queue;
137
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;
143
144 FIFO_ADD (&message_queue, queue);
145
146 THREAD_WRITE_ON (master, t_write, zebra_server_dequeue, NULL, sock);
147 }
148
149 int
150 zebra_server_send_message (int sock, u_char *buf, unsigned long length)
151 {
152 int nbytes;
153
154 if (FIFO_TOP (&message_queue))
155 {
156 zebra_server_enqueue (sock, buf, length, 0);
157 return 0;
158 }
159
160 /* Send message. */
161 nbytes = write (sock, buf, length);
162
163 if (nbytes <= 0)
164 {
165 if (errno == EAGAIN)
166 zebra_server_enqueue (sock, buf, length, 0);
167 else
168 return -1;
169 }
170 else if (nbytes != length)
171 zebra_server_enqueue (sock, buf, length, nbytes);
172
173 return 0;
174 }
175
176 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
177 int
178 zsend_interface_add (struct zserv *client, struct interface *ifp)
179 {
180 struct stream *s;
181
182 /* Check this client need interface information. */
183 if (! client->ifinfo)
184 return -1;
185
186 s = client->obuf;
187 stream_reset (s);
188
189 /* Place holder for size. */
190 stream_putw (s, 0);
191
192 /* Message type. */
193 stream_putc (s, ZEBRA_INTERFACE_ADD);
194
195 /* Interface information. */
196 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
197 stream_putl (s, ifp->ifindex);
198 stream_putc (s, ifp->status);
199 stream_putl (s, ifp->flags);
200 stream_putl (s, ifp->metric);
201 stream_putl (s, ifp->mtu);
202 stream_putl (s, ifp->bandwidth);
203 #ifdef HAVE_SOCKADDR_DL
204 stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
205 #else
206 stream_putl (s, ifp->hw_addr_len);
207 if (ifp->hw_addr_len)
208 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
209 #endif /* HAVE_SOCKADDR_DL */
210
211 /* Write packet size. */
212 stream_putw_at (s, 0, stream_get_endp (s));
213
214 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
215
216 return 0;
217 }
218
219 /* Interface deletion from zebra daemon. */
220 int
221 zsend_interface_delete (struct zserv *client, struct interface *ifp)
222 {
223 struct stream *s;
224
225 /* Check this client need interface information. */
226 if (! client->ifinfo)
227 return -1;
228
229 s = client->obuf;
230 stream_reset (s);
231
232 /* Packet length placeholder. */
233 stream_putw (s, 0);
234
235 /* Interface information. */
236 stream_putc (s, ZEBRA_INTERFACE_DELETE);
237 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
238 stream_putl (s, ifp->ifindex);
239 stream_putc (s, ifp->status);
240 stream_putl (s, ifp->flags);
241 stream_putl (s, ifp->metric);
242 stream_putl (s, ifp->mtu);
243 stream_putl (s, ifp->bandwidth);
244
245 /* Write packet length. */
246 stream_putw_at (s, 0, stream_get_endp (s));
247
248 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
249
250 return 0;
251 }
252
253 /* Interface address is added. Send ZEBRA_INTERFACE_ADDRESS_ADD to the
254 client. */
255 int
256 zsend_interface_address_add (struct zserv *client, struct interface *ifp,
257 struct connected *ifc)
258 {
259 int blen;
260 struct stream *s;
261 struct prefix *p;
262
263 /* Check this client need interface information. */
264 if (! client->ifinfo)
265 return -1;
266
267 s = client->obuf;
268 stream_reset (s);
269
270 /* Place holder for size. */
271 stream_putw (s, 0);
272
273 stream_putc (s, ZEBRA_INTERFACE_ADDRESS_ADD);
274 stream_putl (s, ifp->ifindex);
275
276 /* Interface address flag. */
277 stream_putc (s, ifc->flags);
278
279 /* Prefix information. */
280 p = ifc->address;
281 stream_putc (s, p->family);
282 blen = prefix_blen (p);
283 stream_put (s, &p->u.prefix, blen);
284 stream_putc (s, p->prefixlen);
285
286 /* Destination. */
287 p = ifc->destination;
288 if (p)
289 stream_put (s, &p->u.prefix, blen);
290 else
291 stream_put (s, NULL, blen);
292
293 /* Write packet size. */
294 stream_putw_at (s, 0, stream_get_endp (s));
295
296 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
297
298 return 0;
299 }
300
301 /* Interface address is deleted. Send ZEBRA_INTERFACE_ADDRESS_DELETE
302 to the client. */
303 int
304 zsend_interface_address_delete (struct zserv *client, struct interface *ifp,
305 struct connected *ifc)
306 {
307 int blen;
308 struct stream *s;
309 struct prefix *p;
310
311 /* Check this client need interface information. */
312 if (! client->ifinfo)
313 return -1;
314
315 s = client->obuf;
316 stream_reset (s);
317
318 /* Place holder for size. */
319 stream_putw (s, 0);
320
321 stream_putc (s, ZEBRA_INTERFACE_ADDRESS_DELETE);
322 stream_putl (s, ifp->ifindex);
323
324 /* Interface address flag. */
325 stream_putc (s, ifc->flags);
326
327 /* Prefix information. */
328 p = ifc->address;
329 stream_putc (s, p->family);
330 blen = prefix_blen (p);
331 stream_put (s, &p->u.prefix, blen);
332
333 p = ifc->destination;
334 if (p)
335 stream_put (s, &p->u.prefix, blen);
336 else
337 stream_put (s, NULL, blen);
338
339 /* Write packet size. */
340 stream_putw_at (s, 0, stream_get_endp (s));
341
342 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
343
344 return 0;
345 }
346
347 int
348 zsend_interface_up (struct zserv *client, struct interface *ifp)
349 {
350 struct stream *s;
351
352 /* Check this client need interface information. */
353 if (! client->ifinfo)
354 return -1;
355
356 s = client->obuf;
357 stream_reset (s);
358
359 /* Place holder for size. */
360 stream_putw (s, 0);
361
362 /* Zebra command. */
363 stream_putc (s, ZEBRA_INTERFACE_UP);
364
365 /* Interface information. */
366 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
367 stream_putl (s, ifp->ifindex);
368 stream_putc (s, ifp->status);
369 stream_putl (s, ifp->flags);
370 stream_putl (s, ifp->metric);
371 stream_putl (s, ifp->mtu);
372 stream_putl (s, ifp->bandwidth);
373
374 /* Write packet size. */
375 stream_putw_at (s, 0, stream_get_endp (s));
376
377 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
378
379 return 0;
380 }
381
382 int
383 zsend_interface_down (struct zserv *client, struct interface *ifp)
384 {
385 struct stream *s;
386
387 /* Check this client need interface information. */
388 if (! client->ifinfo)
389 return -1;
390
391 s = client->obuf;
392 stream_reset (s);
393
394 /* Place holder for size. */
395 stream_putw (s, 0);
396
397 /* Zebra command. */
398 stream_putc (s, ZEBRA_INTERFACE_DOWN);
399
400 /* Interface information. */
401 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
402 stream_putl (s, ifp->ifindex);
403 stream_putc (s, ifp->status);
404 stream_putl (s, ifp->flags);
405 stream_putl (s, ifp->metric);
406 stream_putl (s, ifp->mtu);
407 stream_putl (s, ifp->bandwidth);
408
409 /* Write packet size. */
410 stream_putw_at (s, 0, stream_get_endp (s));
411
412 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
413
414 return 0;
415 }
416
417 int
418 zsend_ipv4_add_multipath (struct zserv *client, struct prefix *p,
419 struct rib *rib)
420 {
421 int psize;
422 struct stream *s;
423 struct nexthop *nexthop;
424 struct in_addr empty;
425
426 empty.s_addr = 0;
427 s = client->obuf;
428 stream_reset (s);
429
430 /* Place holder for size. */
431 stream_putw (s, 0);
432
433 /* Put command, type and nexthop. */
434 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
435 stream_putc (s, rib->type);
436 stream_putc (s, rib->flags);
437 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC);
438
439 /* Prefix. */
440 psize = PSIZE (p->prefixlen);
441 stream_putc (s, p->prefixlen);
442 stream_write (s, (u_char *)&p->u.prefix, psize);
443
444 /* Nexthop */
445 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
446 {
447 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
448 {
449 stream_putc (s, 1);
450
451 if (nexthop->type == NEXTHOP_TYPE_IPV4
452 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
453 stream_put_in_addr (s, &nexthop->gate.ipv4);
454 else
455 stream_put_in_addr (s, &empty);
456
457 /* Interface index. */
458 stream_putc (s, 1);
459 stream_putl (s, nexthop->ifindex);
460
461 break;
462 }
463 }
464
465 /* Metric */
466 stream_putl (s, rib->metric);
467
468 /* Write packet size. */
469 stream_putw_at (s, 0, stream_get_endp (s));
470
471 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
472
473 return 0;
474 }
475
476 int
477 zsend_ipv4_delete_multipath (struct zserv *client, struct prefix *p,
478 struct rib *rib)
479 {
480 int psize;
481 struct stream *s;
482 struct nexthop *nexthop;
483 struct in_addr empty;
484
485 empty.s_addr = 0;
486
487 s = client->obuf;
488 stream_reset (s);
489
490 /* Place holder for size. */
491 stream_putw (s, 0);
492
493 /* Put command, type and nexthop. */
494 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
495 stream_putc (s, rib->type);
496 stream_putc (s, rib->flags);
497 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
498
499 /* Prefix. */
500 psize = PSIZE (p->prefixlen);
501 stream_putc (s, p->prefixlen);
502 stream_write (s, (u_char *)&p->u.prefix, psize);
503
504 /* Nexthop */
505 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
506 {
507 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
508 {
509 stream_putc (s, 1);
510
511 if (nexthop->type == NEXTHOP_TYPE_IPV4)
512 stream_put_in_addr (s, &nexthop->gate.ipv4);
513 else
514 stream_put_in_addr (s, &empty);
515
516 /* Interface index. */
517 stream_putc (s, 1);
518 stream_putl (s, nexthop->ifindex);
519
520 break;
521 }
522 }
523
524 /* Write packet size. */
525 stream_putw_at (s, 0, stream_get_endp (s));
526
527 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
528
529 return 0;
530 }
531
532 int
533 zsend_ipv4_add (struct zserv *client, int type, int flags,
534 struct prefix_ipv4 *p, struct in_addr *nexthop,
535 unsigned int ifindex)
536 {
537 int psize;
538 struct stream *s;
539
540 s = client->obuf;
541 stream_reset (s);
542
543 /* Place holder for size. */
544 stream_putw (s, 0);
545
546 /* Put command, type and nexthop. */
547 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
548 stream_putc (s, type);
549 stream_putc (s, flags);
550 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
551
552 /* Prefix. */
553 psize = PSIZE (p->prefixlen);
554 stream_putc (s, p->prefixlen);
555 stream_write (s, (u_char *)&p->prefix, psize);
556
557 /* Nexthop */
558 stream_putc (s, 1);
559 stream_put_in_addr (s, nexthop);
560
561 /* Interface index. */
562 stream_putc (s, 1);
563 stream_putl (s, ifindex);
564
565 /* Write packet size. */
566 stream_putw_at (s, 0, stream_get_endp (s));
567
568 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
569
570 return 0;
571 }
572
573 int
574 zsend_ipv4_delete (struct zserv *client, int type, int flags,
575 struct prefix_ipv4 *p, struct in_addr *nexthop,
576 unsigned int ifindex)
577 {
578 int psize;
579 struct stream *s;
580
581 s = client->obuf;
582 stream_reset (s);
583
584 /* Place holder for size. */
585 stream_putw (s, 0);
586
587 /* Put command, type and nexthop. */
588 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
589 stream_putc (s, type);
590 stream_putc (s, flags);
591 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
592
593 /* Prefix. */
594 psize = PSIZE (p->prefixlen);
595 stream_putc (s, p->prefixlen);
596 stream_write (s, (u_char *)&p->prefix, psize);
597
598 /* Nexthop */
599 stream_putc (s, 1);
600 stream_put_in_addr (s, nexthop);
601
602 /* Interface index. */
603 stream_putc (s, 1);
604 stream_putl (s, ifindex);
605
606 /* Write packet size. */
607 stream_putw_at (s, 0, stream_get_endp (s));
608
609 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
610
611 return 0;
612 }
613
614 #ifdef HAVE_IPV6
615 int
616 zsend_ipv6_add (struct zserv *client, int type, int flags,
617 struct prefix_ipv6 *p, struct in6_addr *nexthop,
618 unsigned int ifindex)
619 {
620 int psize;
621 struct stream *s;
622
623 s = client->obuf;
624 stream_reset (s);
625
626 /* Place holder for size. */
627 stream_putw (s, 0);
628
629 /* Put command, type and nexthop. */
630 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
631 stream_putc (s, type);
632 stream_putc (s, flags);
633 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
634
635 /* Prefix. */
636 psize = PSIZE (p->prefixlen);
637 stream_putc (s, p->prefixlen);
638 stream_write (s, (u_char *)&p->prefix, psize);
639
640 /* Nexthop */
641 stream_putc (s, 1);
642 stream_write (s, (u_char *)nexthop, 16);
643
644 /* Interface index. */
645 stream_putc (s, 1);
646 stream_putl (s, ifindex);
647
648 /* Write packet size. */
649 stream_putw_at (s, 0, stream_get_endp (s));
650
651 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
652
653 return 0;
654 }
655
656 int
657 zsend_ipv6_add_multipath (struct zserv *client, struct prefix *p,
658 struct rib *rib)
659 {
660 int psize;
661 struct stream *s;
662 struct nexthop *nexthop;
663 struct in6_addr empty;
664
665 memset (&empty, 0, sizeof (struct in6_addr));
666 s = client->obuf;
667 stream_reset (s);
668
669 /* Place holder for size. */
670 stream_putw (s, 0);
671
672 /* Put command, type and nexthop. */
673 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
674 stream_putc (s, rib->type);
675 stream_putc (s, rib->flags);
676 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC);
677
678 /* Prefix. */
679 psize = PSIZE (p->prefixlen);
680 stream_putc (s, p->prefixlen);
681 stream_write (s, (u_char *) &p->u.prefix, psize);
682
683 /* Nexthop */
684 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
685 {
686 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
687 {
688 stream_putc (s, 1);
689
690 if (nexthop->type == NEXTHOP_TYPE_IPV6)
691 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
692 else
693 stream_write (s, (u_char *) &empty, 16);
694
695 /* Interface index. */
696 stream_putc (s, 1);
697 stream_putl (s, nexthop->ifindex);
698
699 break;
700 }
701 }
702
703 /* Metric */
704 stream_putl (s, rib->metric);
705
706 /* Write packet size. */
707 stream_putw_at (s, 0, stream_get_endp (s));
708
709 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
710
711 return 0;
712 }
713
714 int
715 zsend_ipv6_delete (struct zserv *client, int type, int flags,
716 struct prefix_ipv6 *p, struct in6_addr *nexthop,
717 unsigned int ifindex)
718 {
719 int psize;
720 struct stream *s;
721
722 s = client->obuf;
723 stream_reset (s);
724
725 /* Place holder for size. */
726 stream_putw (s, 0);
727
728 /* Put command, type and nexthop. */
729 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
730 stream_putc (s, type);
731 stream_putc (s, flags);
732 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
733
734 /* Prefix. */
735 psize = PSIZE (p->prefixlen);
736 stream_putc (s, p->prefixlen);
737 stream_write (s, (u_char *)&p->prefix, psize);
738
739 /* Nexthop */
740 stream_putc (s, 1);
741 stream_write (s, (u_char *)nexthop, 16);
742
743 /* Interface index. */
744 stream_putc (s, 1);
745 stream_putl (s, ifindex);
746
747 /* Write packet size. */
748 stream_putw_at (s, 0, stream_get_endp (s));
749
750 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
751
752 return 0;
753 }
754
755 int
756 zsend_ipv6_delete_multipath (struct zserv *client, struct prefix *p,
757 struct rib *rib)
758 {
759 int psize;
760 struct stream *s;
761 struct nexthop *nexthop;
762 struct in6_addr empty;
763
764 memset (&empty, 0, sizeof (struct in6_addr));
765 s = client->obuf;
766 stream_reset (s);
767
768 /* Place holder for size. */
769 stream_putw (s, 0);
770
771 /* Put command, type and nexthop. */
772 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
773 stream_putc (s, rib->type);
774 stream_putc (s, rib->flags);
775 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
776
777 /* Prefix. */
778 psize = PSIZE (p->prefixlen);
779 stream_putc (s, p->prefixlen);
780 stream_write (s, (u_char *)&p->u.prefix, psize);
781
782 /* Nexthop */
783 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
784 {
785 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
786 {
787 stream_putc (s, 1);
788
789 if (nexthop->type == NEXTHOP_TYPE_IPV6)
790 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
791 else
792 stream_write (s, (u_char *) &empty, 16);
793
794 /* Interface index. */
795 stream_putc (s, 1);
796 stream_putl (s, nexthop->ifindex);
797
798 break;
799 }
800 }
801
802 /* Write packet size. */
803 stream_putw_at (s, 0, stream_get_endp (s));
804
805 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
806
807 return 0;
808 }
809
810 int
811 zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
812 {
813 struct stream *s;
814 struct rib *rib;
815 unsigned long nump;
816 u_char num;
817 struct nexthop *nexthop;
818
819 /* Lookup nexthop. */
820 rib = rib_match_ipv6 (addr);
821
822 /* Get output stream. */
823 s = client->obuf;
824 stream_reset (s);
825
826 /* Fill in result. */
827 stream_putw (s, 0);
828 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
829 stream_put (s, &addr, 16);
830
831 if (rib)
832 {
833 stream_putl (s, rib->metric);
834 num = 0;
835 nump = s->putp;
836 stream_putc (s, 0);
837 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
838 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
839 {
840 stream_putc (s, nexthop->type);
841 switch (nexthop->type)
842 {
843 case ZEBRA_NEXTHOP_IPV6:
844 stream_put (s, &nexthop->gate.ipv6, 16);
845 break;
846 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
847 case ZEBRA_NEXTHOP_IPV6_IFNAME:
848 stream_put (s, &nexthop->gate.ipv6, 16);
849 stream_putl (s, nexthop->ifindex);
850 break;
851 case ZEBRA_NEXTHOP_IFINDEX:
852 case ZEBRA_NEXTHOP_IFNAME:
853 stream_putl (s, nexthop->ifindex);
854 break;
855 }
856 num++;
857 }
858 stream_putc_at (s, nump, num);
859 }
860 else
861 {
862 stream_putl (s, 0);
863 stream_putc (s, 0);
864 }
865
866 stream_putw_at (s, 0, stream_get_endp (s));
867
868 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
869
870 return 0;
871 }
872 #endif /* HAVE_IPV6 */
873
874 int
875 zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
876 {
877 struct stream *s;
878 struct rib *rib;
879 unsigned long nump;
880 u_char num;
881 struct nexthop *nexthop;
882
883 /* Lookup nexthop. */
884 rib = rib_match_ipv4 (addr);
885
886 /* Get output stream. */
887 s = client->obuf;
888 stream_reset (s);
889
890 /* Fill in result. */
891 stream_putw (s, 0);
892 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
893 stream_put_in_addr (s, &addr);
894
895 if (rib)
896 {
897 stream_putl (s, rib->metric);
898 num = 0;
899 nump = s->putp;
900 stream_putc (s, 0);
901 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
902 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
903 {
904 stream_putc (s, nexthop->type);
905 switch (nexthop->type)
906 {
907 case ZEBRA_NEXTHOP_IPV4:
908 stream_put_in_addr (s, &nexthop->gate.ipv4);
909 break;
910 case ZEBRA_NEXTHOP_IFINDEX:
911 case ZEBRA_NEXTHOP_IFNAME:
912 stream_putl (s, nexthop->ifindex);
913 break;
914 }
915 num++;
916 }
917 stream_putc_at (s, nump, num);
918 }
919 else
920 {
921 stream_putl (s, 0);
922 stream_putc (s, 0);
923 }
924
925 stream_putw_at (s, 0, stream_get_endp (s));
926
927 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
928
929 return 0;
930 }
931
932 int
933 zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
934 {
935 struct stream *s;
936 struct rib *rib;
937 unsigned long nump;
938 u_char num;
939 struct nexthop *nexthop;
940
941 /* Lookup nexthop. */
942 rib = rib_lookup_ipv4 (p);
943
944 /* Get output stream. */
945 s = client->obuf;
946 stream_reset (s);
947
948 /* Fill in result. */
949 stream_putw (s, 0);
950 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
951 stream_put_in_addr (s, &p->prefix);
952
953 if (rib)
954 {
955 stream_putl (s, rib->metric);
956 num = 0;
957 nump = s->putp;
958 stream_putc (s, 0);
959 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
960 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
961 {
962 stream_putc (s, nexthop->type);
963 switch (nexthop->type)
964 {
965 case ZEBRA_NEXTHOP_IPV4:
966 stream_put_in_addr (s, &nexthop->gate.ipv4);
967 break;
968 case ZEBRA_NEXTHOP_IFINDEX:
969 case ZEBRA_NEXTHOP_IFNAME:
970 stream_putl (s, nexthop->ifindex);
971 break;
972 }
973 num++;
974 }
975 stream_putc_at (s, nump, num);
976 }
977 else
978 {
979 stream_putl (s, 0);
980 stream_putc (s, 0);
981 }
982
983 stream_putw_at (s, 0, stream_get_endp (s));
984
985 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
986
987 return 0;
988 }
989 \f
990 /* Register zebra server interface information. Send current all
991 interface and address information. */
992 void
993 zread_interface_add (struct zserv *client, u_short length)
994 {
995 listnode ifnode;
996 listnode cnode;
997 struct interface *ifp;
998 struct connected *c;
999
1000 /* Interface information is needed. */
1001 client->ifinfo = 1;
1002
1003 for (ifnode = listhead (iflist); ifnode; ifnode = nextnode (ifnode))
1004 {
1005 ifp = getdata (ifnode);
1006
1007 /* Skip pseudo interface. */
1008 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1009 continue;
1010
1011 zsend_interface_add (client, ifp);
1012
1013 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
1014 {
1015 c = getdata (cnode);
1016 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
1017 zsend_interface_address_add (client, ifp, c);
1018 }
1019 }
1020 }
1021
1022 /* Unregister zebra server interface information. */
1023 void
1024 zread_interface_delete (struct zserv *client, u_short length)
1025 {
1026 client->ifinfo = 0;
1027 }
1028
1029 /* This function support multiple nexthop. */
1030 void
1031 zread_ipv4_add (struct zserv *client, u_short length)
1032 {
1033 int i;
1034 struct rib *rib;
1035 struct prefix_ipv4 p;
1036 u_char message;
1037 struct in_addr nexthop;
1038 u_char nexthop_num;
1039 u_char nexthop_type;
1040 struct stream *s;
1041 unsigned int ifindex;
1042 u_char ifname_len;
1043
1044 /* Get input stream. */
1045 s = client->ibuf;
1046
1047 /* Allocate new rib. */
1048 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1049 memset (rib, 0, sizeof (struct rib));
1050
1051 /* Type, flags, message. */
1052 rib->type = stream_getc (s);
1053 rib->flags = stream_getc (s);
1054 message = stream_getc (s);
1055 rib->uptime = time (NULL);
1056
1057 /* IPv4 prefix. */
1058 memset (&p, 0, sizeof (struct prefix_ipv4));
1059 p.family = AF_INET;
1060 p.prefixlen = stream_getc (s);
1061 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1062
1063 /* Nexthop parse. */
1064 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1065 {
1066 nexthop_num = stream_getc (s);
1067
1068 for (i = 0; i < nexthop_num; i++)
1069 {
1070 nexthop_type = stream_getc (s);
1071
1072 switch (nexthop_type)
1073 {
1074 case ZEBRA_NEXTHOP_IFINDEX:
1075 ifindex = stream_getl (s);
1076 nexthop_ifindex_add (rib, ifindex);
1077 break;
1078 case ZEBRA_NEXTHOP_IFNAME:
1079 ifname_len = stream_getc (s);
1080 stream_forward (s, ifname_len);
1081 break;
1082 case ZEBRA_NEXTHOP_IPV4:
1083 nexthop.s_addr = stream_get_ipv4 (s);
1084 nexthop_ipv4_add (rib, &nexthop);
1085 break;
1086 case ZEBRA_NEXTHOP_IPV6:
1087 stream_forward (s, IPV6_MAX_BYTELEN);
1088 break;
1089 }
1090 }
1091 }
1092
1093 /* Distance. */
1094 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1095 rib->distance = stream_getc (s);
1096
1097 /* Metric. */
1098 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1099 rib->metric = stream_getl (s);
1100
1101 rib_add_ipv4_multipath (&p, rib);
1102 }
1103
1104 /* Zebra server IPv4 prefix delete function. */
1105 void
1106 zread_ipv4_delete (struct zserv *client, u_short length)
1107 {
1108 int i;
1109 struct stream *s;
1110 struct zapi_ipv4 api;
1111 struct in_addr nexthop;
1112 unsigned long ifindex;
1113 struct prefix_ipv4 p;
1114 u_char nexthop_num;
1115 u_char nexthop_type;
1116 u_char ifname_len;
1117
1118 s = client->ibuf;
1119 ifindex = 0;
1120 nexthop.s_addr = 0;
1121
1122 /* Type, flags, message. */
1123 api.type = stream_getc (s);
1124 api.flags = stream_getc (s);
1125 api.message = stream_getc (s);
1126
1127 /* IPv4 prefix. */
1128 memset (&p, 0, sizeof (struct prefix_ipv4));
1129 p.family = AF_INET;
1130 p.prefixlen = stream_getc (s);
1131 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1132
1133 /* Nexthop, ifindex, distance, metric. */
1134 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1135 {
1136 nexthop_num = stream_getc (s);
1137
1138 for (i = 0; i < nexthop_num; i++)
1139 {
1140 nexthop_type = stream_getc (s);
1141
1142 switch (nexthop_type)
1143 {
1144 case ZEBRA_NEXTHOP_IFINDEX:
1145 ifindex = stream_getl (s);
1146 break;
1147 case ZEBRA_NEXTHOP_IFNAME:
1148 ifname_len = stream_getc (s);
1149 stream_forward (s, ifname_len);
1150 break;
1151 case ZEBRA_NEXTHOP_IPV4:
1152 nexthop.s_addr = stream_get_ipv4 (s);
1153 break;
1154 case ZEBRA_NEXTHOP_IPV6:
1155 stream_forward (s, IPV6_MAX_BYTELEN);
1156 break;
1157 }
1158 }
1159 }
1160
1161 /* Distance. */
1162 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1163 api.distance = stream_getc (s);
1164 else
1165 api.distance = 0;
1166
1167 /* Metric. */
1168 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1169 api.metric = stream_getl (s);
1170 else
1171 api.metric = 0;
1172
1173 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
1174 client->rtm_table);
1175 }
1176
1177 /* Nexthop lookup for IPv4. */
1178 void
1179 zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
1180 {
1181 struct in_addr addr;
1182
1183 addr.s_addr = stream_get_ipv4 (client->ibuf);
1184 zsend_ipv4_nexthop_lookup (client, addr);
1185 }
1186
1187 /* Nexthop lookup for IPv4. */
1188 void
1189 zread_ipv4_import_lookup (struct zserv *client, u_short length)
1190 {
1191 struct prefix_ipv4 p;
1192
1193 p.family = AF_INET;
1194 p.prefixlen = stream_getc (client->ibuf);
1195 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1196
1197 zsend_ipv4_import_lookup (client, &p);
1198 }
1199
1200 #ifdef HAVE_IPV6
1201 /* Zebra server IPv6 prefix add function. */
1202 void
1203 zread_ipv6_add (struct zserv *client, u_short length)
1204 {
1205 int i;
1206 struct stream *s;
1207 struct zapi_ipv6 api;
1208 struct in6_addr nexthop;
1209 unsigned long ifindex;
1210 struct prefix_ipv6 p;
1211
1212 s = client->ibuf;
1213 ifindex = 0;
1214 memset (&nexthop, 0, sizeof (struct in6_addr));
1215
1216 /* Type, flags, message. */
1217 api.type = stream_getc (s);
1218 api.flags = stream_getc (s);
1219 api.message = stream_getc (s);
1220
1221 /* IPv4 prefix. */
1222 memset (&p, 0, sizeof (struct prefix_ipv6));
1223 p.family = AF_INET6;
1224 p.prefixlen = stream_getc (s);
1225 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1226
1227 /* Nexthop, ifindex, distance, metric. */
1228 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1229 {
1230 u_char nexthop_type;
1231
1232 api.nexthop_num = stream_getc (s);
1233 for (i = 0; i < api.nexthop_num; i++)
1234 {
1235 nexthop_type = stream_getc (s);
1236
1237 switch (nexthop_type)
1238 {
1239 case ZEBRA_NEXTHOP_IPV6:
1240 stream_get (&nexthop, s, 16);
1241 break;
1242 case ZEBRA_NEXTHOP_IFINDEX:
1243 ifindex = stream_getl (s);
1244 break;
1245 }
1246 }
1247 }
1248
1249 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1250 api.distance = stream_getc (s);
1251 else
1252 api.distance = 0;
1253
1254 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1255 api.metric = stream_getl (s);
1256 else
1257 api.metric = 0;
1258
1259 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1260 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1261 else
1262 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1263 }
1264
1265 /* Zebra server IPv6 prefix delete function. */
1266 void
1267 zread_ipv6_delete (struct zserv *client, u_short length)
1268 {
1269 int i;
1270 struct stream *s;
1271 struct zapi_ipv6 api;
1272 struct in6_addr nexthop;
1273 unsigned long ifindex;
1274 struct prefix_ipv6 p;
1275
1276 s = client->ibuf;
1277 ifindex = 0;
1278 memset (&nexthop, 0, sizeof (struct in6_addr));
1279
1280 /* Type, flags, message. */
1281 api.type = stream_getc (s);
1282 api.flags = stream_getc (s);
1283 api.message = stream_getc (s);
1284
1285 /* IPv4 prefix. */
1286 memset (&p, 0, sizeof (struct prefix_ipv6));
1287 p.family = AF_INET6;
1288 p.prefixlen = stream_getc (s);
1289 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1290
1291 /* Nexthop, ifindex, distance, metric. */
1292 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1293 {
1294 u_char nexthop_type;
1295
1296 api.nexthop_num = stream_getc (s);
1297 for (i = 0; i < api.nexthop_num; i++)
1298 {
1299 nexthop_type = stream_getc (s);
1300
1301 switch (nexthop_type)
1302 {
1303 case ZEBRA_NEXTHOP_IPV6:
1304 stream_get (&nexthop, s, 16);
1305 break;
1306 case ZEBRA_NEXTHOP_IFINDEX:
1307 ifindex = stream_getl (s);
1308 break;
1309 }
1310 }
1311 }
1312
1313 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1314 api.distance = stream_getc (s);
1315 else
1316 api.distance = 0;
1317 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1318 api.metric = stream_getl (s);
1319 else
1320 api.metric = 0;
1321
1322 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1323 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1324 else
1325 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1326 }
1327
1328 void
1329 zebra_read_ipv6 (int command, struct zserv *client, u_short length)
1330 {
1331 u_char type;
1332 u_char flags;
1333 struct in6_addr nexthop, *gate;
1334 u_char *lim;
1335 u_char *pnt;
1336 unsigned int ifindex;
1337
1338 pnt = stream_pnt (client->ibuf);
1339 lim = pnt + length;
1340
1341 type = stream_getc (client->ibuf);
1342 flags = stream_getc (client->ibuf);
1343 stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr));
1344
1345 while (stream_pnt (client->ibuf) < lim)
1346 {
1347 int size;
1348 struct prefix_ipv6 p;
1349
1350 ifindex = stream_getl (client->ibuf);
1351
1352 memset (&p, 0, sizeof (struct prefix_ipv6));
1353 p.family = AF_INET6;
1354 p.prefixlen = stream_getc (client->ibuf);
1355 size = PSIZE(p.prefixlen);
1356 stream_get (&p.prefix, client->ibuf, size);
1357
1358 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1359 gate = NULL;
1360 else
1361 gate = &nexthop;
1362
1363 if (command == ZEBRA_IPV6_ROUTE_ADD)
1364 rib_add_ipv6 (type, flags, &p, gate, ifindex, 0);
1365 else
1366 rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);
1367 }
1368 }
1369
1370 void
1371 zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1372 {
1373 struct in6_addr addr;
1374 char buf[BUFSIZ];
1375
1376 stream_get (&addr, client->ibuf, 16);
1377 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1378
1379 zsend_ipv6_nexthop_lookup (client, &addr);
1380 }
1381 #endif /* HAVE_IPV6 */
1382
1383 /* Close zebra client. */
1384 void
1385 zebra_client_close (struct zserv *client)
1386 {
1387 /* Close file descriptor. */
1388 if (client->sock)
1389 {
1390 close (client->sock);
1391 client->sock = -1;
1392 }
1393
1394 /* Free stream buffers. */
1395 if (client->ibuf)
1396 stream_free (client->ibuf);
1397 if (client->obuf)
1398 stream_free (client->obuf);
1399
1400 /* Release threads. */
1401 if (client->t_read)
1402 thread_cancel (client->t_read);
1403 if (client->t_write)
1404 thread_cancel (client->t_write);
1405
1406 /* Free client structure. */
1407 listnode_delete (client_list, client);
1408 XFREE (0, client);
1409 }
1410
1411 /* Make new client. */
1412 void
1413 zebra_client_create (int sock)
1414 {
1415 struct zserv *client;
1416
1417 client = XCALLOC (0, sizeof (struct zserv));
1418
1419 /* Make client input/output buffer. */
1420 client->sock = sock;
1421 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1422 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1423
1424 /* Set table number. */
1425 client->rtm_table = rtm_table_default;
1426
1427 /* Add this client to linked list. */
1428 listnode_add (client_list, client);
1429
1430 /* Make new read thread. */
1431 zebra_event (ZEBRA_READ, sock, client);
1432 }
1433
1434 /* Handler of zebra service request. */
1435 int
1436 zebra_client_read (struct thread *thread)
1437 {
1438 int sock;
1439 struct zserv *client;
1440 int nbyte;
1441 u_short length;
1442 u_char command;
1443
1444 /* Get thread data. Reset reading thread because I'm running. */
1445 sock = THREAD_FD (thread);
1446 client = THREAD_ARG (thread);
1447 client->t_read = NULL;
1448
1449 /* Read length and command. */
1450 nbyte = stream_read (client->ibuf, sock, 3);
1451 if (nbyte <= 0)
1452 {
1453 if (IS_ZEBRA_DEBUG_EVENT)
1454 zlog_info ("connection closed socket [%d]", sock);
1455 zebra_client_close (client);
1456 return -1;
1457 }
1458 length = stream_getw (client->ibuf);
1459 command = stream_getc (client->ibuf);
1460
1461 if (length < 3)
1462 {
1463 if (IS_ZEBRA_DEBUG_EVENT)
1464 zlog_info ("length %d is less than 3 ", length);
1465 zebra_client_close (client);
1466 return -1;
1467 }
1468
1469 length -= 3;
1470
1471 /* Read rest of data. */
1472 if (length)
1473 {
1474 nbyte = stream_read (client->ibuf, sock, length);
1475 if (nbyte <= 0)
1476 {
1477 if (IS_ZEBRA_DEBUG_EVENT)
1478 zlog_info ("connection closed [%d] when reading zebra data", sock);
1479 zebra_client_close (client);
1480 return -1;
1481 }
1482 }
1483
1484 /* Debug packet information. */
1485 if (IS_ZEBRA_DEBUG_EVENT)
1486 zlog_info ("zebra message comes from socket [%d]", sock);
1487
1488 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1489 zlog_info ("zebra message received [%s] %d",
1490 zebra_command_str[command], length);
1491
1492 switch (command)
1493 {
1494 case ZEBRA_INTERFACE_ADD:
1495 zread_interface_add (client, length);
1496 break;
1497 case ZEBRA_INTERFACE_DELETE:
1498 zread_interface_delete (client, length);
1499 break;
1500 case ZEBRA_IPV4_ROUTE_ADD:
1501 zread_ipv4_add (client, length);
1502 break;
1503 case ZEBRA_IPV4_ROUTE_DELETE:
1504 zread_ipv4_delete (client, length);
1505 break;
1506 #ifdef HAVE_IPV6
1507 case ZEBRA_IPV6_ROUTE_ADD:
1508 zread_ipv6_add (client, length);
1509 break;
1510 case ZEBRA_IPV6_ROUTE_DELETE:
1511 zread_ipv6_delete (client, length);
1512 break;
1513 #endif /* HAVE_IPV6 */
1514 case ZEBRA_REDISTRIBUTE_ADD:
1515 zebra_redistribute_add (command, client, length);
1516 break;
1517 case ZEBRA_REDISTRIBUTE_DELETE:
1518 zebra_redistribute_delete (command, client, length);
1519 break;
1520 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1521 zebra_redistribute_default_add (command, client, length);
1522 break;
1523 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1524 zebra_redistribute_default_delete (command, client, length);
1525 break;
1526 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1527 zread_ipv4_nexthop_lookup (client, length);
1528 break;
1529 #ifdef HAVE_IPV6
1530 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1531 zread_ipv6_nexthop_lookup (client, length);
1532 break;
1533 #endif /* HAVE_IPV6 */
1534 case ZEBRA_IPV4_IMPORT_LOOKUP:
1535 zread_ipv4_import_lookup (client, length);
1536 break;
1537 default:
1538 zlog_info ("Zebra received unknown command %d", command);
1539 break;
1540 }
1541
1542 stream_reset (client->ibuf);
1543 zebra_event (ZEBRA_READ, sock, client);
1544
1545 return 0;
1546 }
1547
1548 /* Write output buffer to the socket. */
1549 void
1550 zebra_write (struct thread *thread)
1551 {
1552 int sock;
1553 struct zserv *client;
1554
1555 /* Thread treatment. */
1556 sock = THREAD_FD (thread);
1557 client = THREAD_ARG (thread);
1558 client->t_write = NULL;
1559
1560 stream_flush (client->obuf, sock);
1561 }
1562
1563 /* Accept code of zebra server socket. */
1564 int
1565 zebra_accept (struct thread *thread)
1566 {
1567 int val;
1568 int accept_sock;
1569 int client_sock;
1570 struct sockaddr_in client;
1571 socklen_t len;
1572
1573 accept_sock = THREAD_FD (thread);
1574
1575 len = sizeof (struct sockaddr_in);
1576 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1577
1578 if (client_sock < 0)
1579 {
1580 zlog_warn ("Can't accept zebra socket: %s", strerror (errno));
1581 return -1;
1582 }
1583
1584 /* Make client socket non-blocking. */
1585
1586 val = fcntl (client_sock, F_GETFL, 0);
1587 fcntl (client_sock, F_SETFL, (val | O_NONBLOCK));
1588
1589 /* Create new zebra client. */
1590 zebra_client_create (client_sock);
1591
1592 /* Register myself. */
1593 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1594
1595 return 0;
1596 }
1597
1598 /* Make zebra's server socket. */
1599 void
1600 zebra_serv ()
1601 {
1602 int ret;
1603 int accept_sock;
1604 struct sockaddr_in addr;
1605
1606 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1607
1608 if (accept_sock < 0)
1609 {
1610 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1611 zlog_warn ("zebra can't provice full functionality due to above error");
1612 return;
1613 }
1614
1615 memset (&addr, 0, sizeof (struct sockaddr_in));
1616 addr.sin_family = AF_INET;
1617 addr.sin_port = htons (ZEBRA_PORT);
1618 #ifdef HAVE_SIN_LEN
1619 addr.sin_len = sizeof (struct sockaddr_in);
1620 #endif /* HAVE_SIN_LEN */
1621 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1622
1623 sockopt_reuseaddr (accept_sock);
1624 sockopt_reuseport (accept_sock);
1625
1626 ret = bind (accept_sock, (struct sockaddr *)&addr,
1627 sizeof (struct sockaddr_in));
1628 if (ret < 0)
1629 {
1630 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1631 zlog_warn ("zebra can't provice full functionality due to above error");
1632 close (accept_sock); /* Avoid sd leak. */
1633 return;
1634 }
1635
1636 ret = listen (accept_sock, 1);
1637 if (ret < 0)
1638 {
1639 zlog_warn ("Can't listen to socket: %s", strerror (errno));
1640 zlog_warn ("zebra can't provice full functionality due to above error");
1641 close (accept_sock); /* Avoid sd leak. */
1642 return;
1643 }
1644
1645 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1646 }
1647
1648 /* For sockaddr_un. */
1649 #include <sys/un.h>
1650
1651 /* zebra server UNIX domain socket. */
1652 void
1653 zebra_serv_un (char *path)
1654 {
1655 int ret;
1656 int sock, len;
1657 struct sockaddr_un serv;
1658 mode_t old_mask;
1659
1660 /* First of all, unlink existing socket */
1661 unlink (path);
1662
1663 /* Set umask */
1664 old_mask = umask (0077);
1665
1666 /* Make UNIX domain socket. */
1667 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1668 if (sock < 0)
1669 {
1670 perror ("sock");
1671 return;
1672 }
1673
1674 /* Make server socket. */
1675 memset (&serv, 0, sizeof (struct sockaddr_un));
1676 serv.sun_family = AF_UNIX;
1677 strncpy (serv.sun_path, path, strlen (path));
1678 #ifdef HAVE_SUN_LEN
1679 len = serv.sun_len = SUN_LEN(&serv);
1680 #else
1681 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1682 #endif /* HAVE_SUN_LEN */
1683
1684 ret = bind (sock, (struct sockaddr *) &serv, len);
1685 if (ret < 0)
1686 {
1687 perror ("bind");
1688 close (sock);
1689 return;
1690 }
1691
1692 ret = listen (sock, 5);
1693 if (ret < 0)
1694 {
1695 perror ("listen");
1696 close (sock);
1697 return;
1698 }
1699
1700 umask (old_mask);
1701
1702 zebra_event (ZEBRA_SERV, sock, NULL);
1703 }
1704 \f
1705 /* Zebra's event management function. */
1706 extern struct thread_master *master;
1707
1708 void
1709 zebra_event (enum event event, int sock, struct zserv *client)
1710 {
1711 switch (event)
1712 {
1713 case ZEBRA_SERV:
1714 thread_add_read (master, zebra_accept, client, sock);
1715 break;
1716 case ZEBRA_READ:
1717 client->t_read =
1718 thread_add_read (master, zebra_client_read, client, sock);
1719 break;
1720 case ZEBRA_WRITE:
1721 /**/
1722 break;
1723 }
1724 }
1725 \f
1726 /* Display default rtm_table for all clients. */
1727 DEFUN (show_table,
1728 show_table_cmd,
1729 "show table",
1730 SHOW_STR
1731 "default routing table to use for all clients\n")
1732 {
1733 vty_out (vty, "table %d%s", rtm_table_default,
1734 VTY_NEWLINE);
1735 return CMD_SUCCESS;
1736 }
1737
1738 DEFUN (config_table,
1739 config_table_cmd,
1740 "table TABLENO",
1741 "Configure target kernel routing table\n"
1742 "TABLE integer\n")
1743 {
1744 rtm_table_default = strtol (argv[0], (char**)0, 10);
1745 return CMD_SUCCESS;
1746 }
1747
1748 DEFUN (ip_forwarding,
1749 ip_forwarding_cmd,
1750 "ip forwarding",
1751 IP_STR
1752 "Turn on IP forwarding")
1753 {
1754 int ret;
1755
1756 ret = ipforward ();
1757
1758 if (ret != 0)
1759 {
1760 vty_out (vty, "IP forwarding is already on%s", VTY_NEWLINE);
1761 return CMD_ERR_NOTHING_TODO;
1762 }
1763
1764 ret = ipforward_on ();
1765 if (ret == 0)
1766 {
1767 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1768 return CMD_WARNING;
1769 }
1770
1771 return CMD_SUCCESS;
1772 }
1773
1774 DEFUN (no_ip_forwarding,
1775 no_ip_forwarding_cmd,
1776 "no ip forwarding",
1777 NO_STR
1778 IP_STR
1779 "Turn off IP forwarding")
1780 {
1781 int ret;
1782
1783 ret = ipforward ();
1784
1785 if (ret == 0)
1786 {
1787 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);
1788 return CMD_ERR_NOTHING_TODO;
1789 }
1790
1791 ret = ipforward_off ();
1792 if (ret != 0)
1793 {
1794 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1795 return CMD_WARNING;
1796 }
1797
1798 return CMD_SUCCESS;
1799 }
1800
1801 /* This command is for debugging purpose. */
1802 DEFUN (show_zebra_client,
1803 show_zebra_client_cmd,
1804 "show zebra client",
1805 SHOW_STR
1806 "Zebra information"
1807 "Client information")
1808 {
1809 listnode node;
1810 struct zserv *client;
1811
1812 for (node = listhead (client_list); node; nextnode (node))
1813 {
1814 client = getdata (node);
1815 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1816 }
1817 return CMD_SUCCESS;
1818 }
1819
1820 /* Table configuration write function. */
1821 int
1822 config_write_table (struct vty *vty)
1823 {
1824 if (rtm_table_default)
1825 vty_out (vty, "table %d%s", rtm_table_default,
1826 VTY_NEWLINE);
1827 return 0;
1828 }
1829
1830 /* table node for routing tables. */
1831 struct cmd_node table_node =
1832 {
1833 TABLE_NODE,
1834 "", /* This node has no interface. */
1835 1
1836 };
1837 \f
1838 /* Only display ip forwarding is enabled or not. */
1839 DEFUN (show_ip_forwarding,
1840 show_ip_forwarding_cmd,
1841 "show ip forwarding",
1842 SHOW_STR
1843 IP_STR
1844 "IP forwarding status\n")
1845 {
1846 int ret;
1847
1848 ret = ipforward ();
1849
1850 if (ret == 0)
1851 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1852 else
1853 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1854 return CMD_SUCCESS;
1855 }
1856
1857 #ifdef HAVE_IPV6
1858 /* Only display ipv6 forwarding is enabled or not. */
1859 DEFUN (show_ipv6_forwarding,
1860 show_ipv6_forwarding_cmd,
1861 "show ipv6 forwarding",
1862 SHOW_STR
1863 "IPv6 information\n"
1864 "Forwarding status\n")
1865 {
1866 int ret;
1867
1868 ret = ipforward_ipv6 ();
1869
1870 switch (ret)
1871 {
1872 case -1:
1873 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1874 break;
1875 case 0:
1876 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1877 break;
1878 case 1:
1879 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1880 break;
1881 default:
1882 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1883 break;
1884 }
1885 return CMD_SUCCESS;
1886 }
1887
1888 DEFUN (no_ipv6_forwarding,
1889 no_ipv6_forwarding_cmd,
1890 "no ipv6 forwarding",
1891 NO_STR
1892 IP_STR
1893 "Doesn't forward IPv6 protocol packet")
1894 {
1895 int ret;
1896
1897 ret = ipforward_ipv6_off ();
1898 if (ret != 0)
1899 {
1900 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1901 return CMD_WARNING;
1902 }
1903
1904 return CMD_SUCCESS;
1905 }
1906
1907 #endif /* HAVE_IPV6 */
1908
1909 /* IPForwarding configuration write function. */
1910 int
1911 config_write_forwarding (struct vty *vty)
1912 {
1913 if (! ipforward ())
1914 vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
1915 #ifdef HAVE_IPV6
1916 if (! ipforward_ipv6 ())
1917 vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
1918 #endif /* HAVE_IPV6 */
1919 vty_out (vty, "!%s", VTY_NEWLINE);
1920 return 0;
1921 }
1922
1923 /* table node for routing tables. */
1924 struct cmd_node forwarding_node =
1925 {
1926 FORWARDING_NODE,
1927 "", /* This node has no interface. */
1928 1
1929 };
1930
1931 \f
1932 /* Initialisation of zebra and installation of commands. */
1933 void
1934 zebra_init ()
1935 {
1936 /* Client list init. */
1937 client_list = list_new ();
1938
1939 /* Forwarding is on by default. */
1940 ipforward_on ();
1941 #ifdef HAVE_IPV6
1942 ipforward_ipv6_on ();
1943 #endif /* HAVE_IPV6 */
1944
1945 /* Make zebra server socket. */
1946 #ifdef HAVE_TCP_ZEBRA
1947 zebra_serv ();
1948 #else
1949 zebra_serv_un (ZEBRA_SERV_PATH);
1950 #endif /* HAVE_TCP_ZEBRA */
1951
1952 /* Install configuration write function. */
1953 install_node (&table_node, config_write_table);
1954 install_node (&forwarding_node, config_write_forwarding);
1955
1956 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1957 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
1958 install_element (CONFIG_NODE, &ip_forwarding_cmd);
1959 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1960 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1961
1962 #ifdef HAVE_NETLINK
1963 install_element (VIEW_NODE, &show_table_cmd);
1964 install_element (ENABLE_NODE, &show_table_cmd);
1965 install_element (CONFIG_NODE, &config_table_cmd);
1966 #endif /* HAVE_NETLINK */
1967
1968 #ifdef HAVE_IPV6
1969 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1970 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
1971 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1972 #endif /* HAVE_IPV6 */
1973
1974 FIFO_INIT(&message_queue);
1975 t_write = NULL;
1976 }