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