blob: 4753f57722d8498fa8ba905120c0c8a9cd04b506 [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);
paulccf35572003-03-01 11:42:20 +000052
53extern struct thread_master *master;
paul718e3742002-12-13 20:15:29 +000054
55/* For logging of zebra meesages. */
56char *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
paulccf35572003-03-01 11:42:20 +000079struct 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
89struct thread *t_write;
90struct fifo message_queue;
91
92int
93zebra_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. */
132void
133zebra_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
149int
150zebra_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
paul718e3742002-12-13 20:15:29 +0000176/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
177int
178zsend_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);
paul2e3b2e42002-12-13 21:03:13 +0000198 stream_putc (s, ifp->status);
paul718e3742002-12-13 20:15:29 +0000199 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
paulccf35572003-03-01 11:42:20 +0000214 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
215
216 return 0;
paul718e3742002-12-13 20:15:29 +0000217}
218
219/* Interface deletion from zebra daemon. */
220int
221zsend_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);
paul2e3b2e42002-12-13 21:03:13 +0000239 stream_putc (s, ifp->status);
paul718e3742002-12-13 20:15:29 +0000240 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
paulccf35572003-03-01 11:42:20 +0000248 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
249
250 return 0;
paul718e3742002-12-13 20:15:29 +0000251}
252
253/* Interface address is added. Send ZEBRA_INTERFACE_ADDRESS_ADD to the
254 client. */
255int
256zsend_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
paulccf35572003-03-01 11:42:20 +0000296 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
297
298 return 0;
paul718e3742002-12-13 20:15:29 +0000299}
300
301/* Interface address is deleted. Send ZEBRA_INTERFACE_ADDRESS_DELETE
302 to the client. */
303int
304zsend_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
paulccf35572003-03-01 11:42:20 +0000342 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
343
344 return 0;
paul718e3742002-12-13 20:15:29 +0000345}
346
347int
348zsend_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);
paul2e3b2e42002-12-13 21:03:13 +0000368 stream_putc (s, ifp->status);
paul718e3742002-12-13 20:15:29 +0000369 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
paulccf35572003-03-01 11:42:20 +0000377 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
378
379 return 0;
paul718e3742002-12-13 20:15:29 +0000380}
381
382int
383zsend_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);
paul2e3b2e42002-12-13 21:03:13 +0000403 stream_putc (s, ifp->status);
paul718e3742002-12-13 20:15:29 +0000404 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
paulccf35572003-03-01 11:42:20 +0000412 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
413
414 return 0;
paul718e3742002-12-13 20:15:29 +0000415}
416
417int
418zsend_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
paulccf35572003-03-01 11:42:20 +0000471 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
472
473 return 0;
paul718e3742002-12-13 20:15:29 +0000474}
475
476int
477zsend_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
paulccf35572003-03-01 11:42:20 +0000527 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
528
529 return 0;
paul718e3742002-12-13 20:15:29 +0000530}
531
532int
533zsend_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
paulccf35572003-03-01 11:42:20 +0000568 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
569
570 return 0;
paul718e3742002-12-13 20:15:29 +0000571}
572
573int
574zsend_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
paulccf35572003-03-01 11:42:20 +0000609 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
610
611 return 0;
paul718e3742002-12-13 20:15:29 +0000612}
613
614#ifdef HAVE_IPV6
615int
616zsend_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
paulccf35572003-03-01 11:42:20 +0000651 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
652
653 return 0;
paul718e3742002-12-13 20:15:29 +0000654}
655
656int
657zsend_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
paulccf35572003-03-01 11:42:20 +0000709 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
710
711 return 0;
paul718e3742002-12-13 20:15:29 +0000712}
713
714int
715zsend_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
paulccf35572003-03-01 11:42:20 +0000750 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
751
752 return 0;
paul718e3742002-12-13 20:15:29 +0000753}
754
755int
756zsend_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
paulccf35572003-03-01 11:42:20 +0000805 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
806
807 return 0;
paul718e3742002-12-13 20:15:29 +0000808}
809
810int
811zsend_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
paulccf35572003-03-01 11:42:20 +0000868 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
869
870 return 0;
paul718e3742002-12-13 20:15:29 +0000871}
872#endif /* HAVE_IPV6 */
873
874int
875zsend_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
paulccf35572003-03-01 11:42:20 +0000927 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
928
929 return 0;
paul718e3742002-12-13 20:15:29 +0000930}
931
932int
933zsend_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
paulccf35572003-03-01 11:42:20 +0000985 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
986
987 return 0;
paul718e3742002-12-13 20:15:29 +0000988}
989
990/* Register zebra server interface information. Send current all
991 interface and address information. */
992void
993zread_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. */
1023void
1024zread_interface_delete (struct zserv *client, u_short length)
1025{
1026 client->ifinfo = 0;
1027}
1028
1029/* This function support multiple nexthop. */
1030void
1031zread_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;
paul718e3742002-12-13 20:15:29 +00001089 }
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. */
1105void
1106zread_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. */
1178void
1179zread_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. */
1188void
1189zread_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. */
1202void
1203zread_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. */
1266void
1267zread_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
1328void
1329zebra_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
1370void
1371zread_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. */
1384void
1385zebra_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. */
1412void
1413zebra_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. */
1435int
1436zebra_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. */
1549void
1550zebra_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. */
1564int
1565zebra_accept (struct thread *thread)
1566{
paulccf35572003-03-01 11:42:20 +00001567 int val;
paul718e3742002-12-13 20:15:29 +00001568 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
paulccf35572003-03-01 11:42:20 +00001584 /* Make client socket non-blocking. */
1585
1586 val = fcntl (client_sock, F_GETFL, 0);
1587 fcntl (client_sock, F_SETFL, (val | O_NONBLOCK));
1588
paul718e3742002-12-13 20:15:29 +00001589 /* 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. */
1599void
1600zebra_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. */
1652void
1653zebra_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
1705/* Zebra's event management function. */
1706extern struct thread_master *master;
1707
1708void
1709zebra_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
1726/* Display default rtm_table for all clients. */
1727DEFUN (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
1738DEFUN (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
hasso647e4f12003-05-25 11:43:52 +00001748DEFUN (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
paul718e3742002-12-13 20:15:29 +00001774DEFUN (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. */
1802DEFUN (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. */
1821int
1822config_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. */
1831struct cmd_node table_node =
1832{
1833 TABLE_NODE,
1834 "", /* This node has no interface. */
1835 1
1836};
1837
1838/* Only display ip forwarding is enabled or not. */
1839DEFUN (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. */
1859DEFUN (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
1888DEFUN (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. */
1910int
1911config_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. */
1924struct cmd_node forwarding_node =
1925{
1926 FORWARDING_NODE,
1927 "", /* This node has no interface. */
1928 1
1929};
1930
1931
1932/* Initialisation of zebra and installation of commands. */
1933void
1934zebra_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);
hasso647e4f12003-05-25 11:43:52 +00001958 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001959 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 */
paulccf35572003-03-01 11:42:20 +00001973
1974 FIFO_INIT(&message_queue);
1975 t_write = NULL;
paul718e3742002-12-13 20:15:29 +00001976}