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