blob: e27db44936a4d2af821b8a2ced41f9d3bcfab78b [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;
1089 case ZEBRA_NEXTHOP_BLACKHOLE:
1090 nexthop_blackhole_add (rib);
1091 break;
1092 }
1093 }
1094 }
1095
1096 /* Distance. */
1097 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1098 rib->distance = stream_getc (s);
1099
1100 /* Metric. */
1101 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1102 rib->metric = stream_getl (s);
1103
1104 rib_add_ipv4_multipath (&p, rib);
1105}
1106
1107/* Zebra server IPv4 prefix delete function. */
1108void
1109zread_ipv4_delete (struct zserv *client, u_short length)
1110{
1111 int i;
1112 struct stream *s;
1113 struct zapi_ipv4 api;
1114 struct in_addr nexthop;
1115 unsigned long ifindex;
1116 struct prefix_ipv4 p;
1117 u_char nexthop_num;
1118 u_char nexthop_type;
1119 u_char ifname_len;
1120
1121 s = client->ibuf;
1122 ifindex = 0;
1123 nexthop.s_addr = 0;
1124
1125 /* Type, flags, message. */
1126 api.type = stream_getc (s);
1127 api.flags = stream_getc (s);
1128 api.message = stream_getc (s);
1129
1130 /* IPv4 prefix. */
1131 memset (&p, 0, sizeof (struct prefix_ipv4));
1132 p.family = AF_INET;
1133 p.prefixlen = stream_getc (s);
1134 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1135
1136 /* Nexthop, ifindex, distance, metric. */
1137 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1138 {
1139 nexthop_num = stream_getc (s);
1140
1141 for (i = 0; i < nexthop_num; i++)
1142 {
1143 nexthop_type = stream_getc (s);
1144
1145 switch (nexthop_type)
1146 {
1147 case ZEBRA_NEXTHOP_IFINDEX:
1148 ifindex = stream_getl (s);
1149 break;
1150 case ZEBRA_NEXTHOP_IFNAME:
1151 ifname_len = stream_getc (s);
1152 stream_forward (s, ifname_len);
1153 break;
1154 case ZEBRA_NEXTHOP_IPV4:
1155 nexthop.s_addr = stream_get_ipv4 (s);
1156 break;
1157 case ZEBRA_NEXTHOP_IPV6:
1158 stream_forward (s, IPV6_MAX_BYTELEN);
1159 break;
1160 }
1161 }
1162 }
1163
1164 /* Distance. */
1165 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1166 api.distance = stream_getc (s);
1167 else
1168 api.distance = 0;
1169
1170 /* Metric. */
1171 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1172 api.metric = stream_getl (s);
1173 else
1174 api.metric = 0;
1175
1176 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
1177 client->rtm_table);
1178}
1179
1180/* Nexthop lookup for IPv4. */
1181void
1182zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
1183{
1184 struct in_addr addr;
1185
1186 addr.s_addr = stream_get_ipv4 (client->ibuf);
1187 zsend_ipv4_nexthop_lookup (client, addr);
1188}
1189
1190/* Nexthop lookup for IPv4. */
1191void
1192zread_ipv4_import_lookup (struct zserv *client, u_short length)
1193{
1194 struct prefix_ipv4 p;
1195
1196 p.family = AF_INET;
1197 p.prefixlen = stream_getc (client->ibuf);
1198 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1199
1200 zsend_ipv4_import_lookup (client, &p);
1201}
1202
1203#ifdef HAVE_IPV6
1204/* Zebra server IPv6 prefix add function. */
1205void
1206zread_ipv6_add (struct zserv *client, u_short length)
1207{
1208 int i;
1209 struct stream *s;
1210 struct zapi_ipv6 api;
1211 struct in6_addr nexthop;
1212 unsigned long ifindex;
1213 struct prefix_ipv6 p;
1214
1215 s = client->ibuf;
1216 ifindex = 0;
1217 memset (&nexthop, 0, sizeof (struct in6_addr));
1218
1219 /* Type, flags, message. */
1220 api.type = stream_getc (s);
1221 api.flags = stream_getc (s);
1222 api.message = stream_getc (s);
1223
1224 /* IPv4 prefix. */
1225 memset (&p, 0, sizeof (struct prefix_ipv6));
1226 p.family = AF_INET6;
1227 p.prefixlen = stream_getc (s);
1228 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1229
1230 /* Nexthop, ifindex, distance, metric. */
1231 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1232 {
1233 u_char nexthop_type;
1234
1235 api.nexthop_num = stream_getc (s);
1236 for (i = 0; i < api.nexthop_num; i++)
1237 {
1238 nexthop_type = stream_getc (s);
1239
1240 switch (nexthop_type)
1241 {
1242 case ZEBRA_NEXTHOP_IPV6:
1243 stream_get (&nexthop, s, 16);
1244 break;
1245 case ZEBRA_NEXTHOP_IFINDEX:
1246 ifindex = stream_getl (s);
1247 break;
1248 }
1249 }
1250 }
1251
1252 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1253 api.distance = stream_getc (s);
1254 else
1255 api.distance = 0;
1256
1257 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1258 api.metric = stream_getl (s);
1259 else
1260 api.metric = 0;
1261
1262 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1263 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1264 else
1265 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1266}
1267
1268/* Zebra server IPv6 prefix delete function. */
1269void
1270zread_ipv6_delete (struct zserv *client, u_short length)
1271{
1272 int i;
1273 struct stream *s;
1274 struct zapi_ipv6 api;
1275 struct in6_addr nexthop;
1276 unsigned long ifindex;
1277 struct prefix_ipv6 p;
1278
1279 s = client->ibuf;
1280 ifindex = 0;
1281 memset (&nexthop, 0, sizeof (struct in6_addr));
1282
1283 /* Type, flags, message. */
1284 api.type = stream_getc (s);
1285 api.flags = stream_getc (s);
1286 api.message = stream_getc (s);
1287
1288 /* IPv4 prefix. */
1289 memset (&p, 0, sizeof (struct prefix_ipv6));
1290 p.family = AF_INET6;
1291 p.prefixlen = stream_getc (s);
1292 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1293
1294 /* Nexthop, ifindex, distance, metric. */
1295 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1296 {
1297 u_char nexthop_type;
1298
1299 api.nexthop_num = stream_getc (s);
1300 for (i = 0; i < api.nexthop_num; i++)
1301 {
1302 nexthop_type = stream_getc (s);
1303
1304 switch (nexthop_type)
1305 {
1306 case ZEBRA_NEXTHOP_IPV6:
1307 stream_get (&nexthop, s, 16);
1308 break;
1309 case ZEBRA_NEXTHOP_IFINDEX:
1310 ifindex = stream_getl (s);
1311 break;
1312 }
1313 }
1314 }
1315
1316 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1317 api.distance = stream_getc (s);
1318 else
1319 api.distance = 0;
1320 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1321 api.metric = stream_getl (s);
1322 else
1323 api.metric = 0;
1324
1325 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1326 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1327 else
1328 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1329}
1330
1331void
1332zebra_read_ipv6 (int command, struct zserv *client, u_short length)
1333{
1334 u_char type;
1335 u_char flags;
1336 struct in6_addr nexthop, *gate;
1337 u_char *lim;
1338 u_char *pnt;
1339 unsigned int ifindex;
1340
1341 pnt = stream_pnt (client->ibuf);
1342 lim = pnt + length;
1343
1344 type = stream_getc (client->ibuf);
1345 flags = stream_getc (client->ibuf);
1346 stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr));
1347
1348 while (stream_pnt (client->ibuf) < lim)
1349 {
1350 int size;
1351 struct prefix_ipv6 p;
1352
1353 ifindex = stream_getl (client->ibuf);
1354
1355 memset (&p, 0, sizeof (struct prefix_ipv6));
1356 p.family = AF_INET6;
1357 p.prefixlen = stream_getc (client->ibuf);
1358 size = PSIZE(p.prefixlen);
1359 stream_get (&p.prefix, client->ibuf, size);
1360
1361 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1362 gate = NULL;
1363 else
1364 gate = &nexthop;
1365
1366 if (command == ZEBRA_IPV6_ROUTE_ADD)
1367 rib_add_ipv6 (type, flags, &p, gate, ifindex, 0);
1368 else
1369 rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);
1370 }
1371}
1372
1373void
1374zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1375{
1376 struct in6_addr addr;
1377 char buf[BUFSIZ];
1378
1379 stream_get (&addr, client->ibuf, 16);
1380 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1381
1382 zsend_ipv6_nexthop_lookup (client, &addr);
1383}
1384#endif /* HAVE_IPV6 */
1385
1386/* Close zebra client. */
1387void
1388zebra_client_close (struct zserv *client)
1389{
1390 /* Close file descriptor. */
1391 if (client->sock)
1392 {
1393 close (client->sock);
1394 client->sock = -1;
1395 }
1396
1397 /* Free stream buffers. */
1398 if (client->ibuf)
1399 stream_free (client->ibuf);
1400 if (client->obuf)
1401 stream_free (client->obuf);
1402
1403 /* Release threads. */
1404 if (client->t_read)
1405 thread_cancel (client->t_read);
1406 if (client->t_write)
1407 thread_cancel (client->t_write);
1408
1409 /* Free client structure. */
1410 listnode_delete (client_list, client);
1411 XFREE (0, client);
1412}
1413
1414/* Make new client. */
1415void
1416zebra_client_create (int sock)
1417{
1418 struct zserv *client;
1419
1420 client = XCALLOC (0, sizeof (struct zserv));
1421
1422 /* Make client input/output buffer. */
1423 client->sock = sock;
1424 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1425 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1426
1427 /* Set table number. */
1428 client->rtm_table = rtm_table_default;
1429
1430 /* Add this client to linked list. */
1431 listnode_add (client_list, client);
1432
1433 /* Make new read thread. */
1434 zebra_event (ZEBRA_READ, sock, client);
1435}
1436
1437/* Handler of zebra service request. */
1438int
1439zebra_client_read (struct thread *thread)
1440{
1441 int sock;
1442 struct zserv *client;
1443 int nbyte;
1444 u_short length;
1445 u_char command;
1446
1447 /* Get thread data. Reset reading thread because I'm running. */
1448 sock = THREAD_FD (thread);
1449 client = THREAD_ARG (thread);
1450 client->t_read = NULL;
1451
1452 /* Read length and command. */
1453 nbyte = stream_read (client->ibuf, sock, 3);
1454 if (nbyte <= 0)
1455 {
1456 if (IS_ZEBRA_DEBUG_EVENT)
1457 zlog_info ("connection closed socket [%d]", sock);
1458 zebra_client_close (client);
1459 return -1;
1460 }
1461 length = stream_getw (client->ibuf);
1462 command = stream_getc (client->ibuf);
1463
1464 if (length < 3)
1465 {
1466 if (IS_ZEBRA_DEBUG_EVENT)
1467 zlog_info ("length %d is less than 3 ", length);
1468 zebra_client_close (client);
1469 return -1;
1470 }
1471
1472 length -= 3;
1473
1474 /* Read rest of data. */
1475 if (length)
1476 {
1477 nbyte = stream_read (client->ibuf, sock, length);
1478 if (nbyte <= 0)
1479 {
1480 if (IS_ZEBRA_DEBUG_EVENT)
1481 zlog_info ("connection closed [%d] when reading zebra data", sock);
1482 zebra_client_close (client);
1483 return -1;
1484 }
1485 }
1486
1487 /* Debug packet information. */
1488 if (IS_ZEBRA_DEBUG_EVENT)
1489 zlog_info ("zebra message comes from socket [%d]", sock);
1490
1491 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1492 zlog_info ("zebra message received [%s] %d",
1493 zebra_command_str[command], length);
1494
1495 switch (command)
1496 {
1497 case ZEBRA_INTERFACE_ADD:
1498 zread_interface_add (client, length);
1499 break;
1500 case ZEBRA_INTERFACE_DELETE:
1501 zread_interface_delete (client, length);
1502 break;
1503 case ZEBRA_IPV4_ROUTE_ADD:
1504 zread_ipv4_add (client, length);
1505 break;
1506 case ZEBRA_IPV4_ROUTE_DELETE:
1507 zread_ipv4_delete (client, length);
1508 break;
1509#ifdef HAVE_IPV6
1510 case ZEBRA_IPV6_ROUTE_ADD:
1511 zread_ipv6_add (client, length);
1512 break;
1513 case ZEBRA_IPV6_ROUTE_DELETE:
1514 zread_ipv6_delete (client, length);
1515 break;
1516#endif /* HAVE_IPV6 */
1517 case ZEBRA_REDISTRIBUTE_ADD:
1518 zebra_redistribute_add (command, client, length);
1519 break;
1520 case ZEBRA_REDISTRIBUTE_DELETE:
1521 zebra_redistribute_delete (command, client, length);
1522 break;
1523 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1524 zebra_redistribute_default_add (command, client, length);
1525 break;
1526 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1527 zebra_redistribute_default_delete (command, client, length);
1528 break;
1529 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1530 zread_ipv4_nexthop_lookup (client, length);
1531 break;
1532#ifdef HAVE_IPV6
1533 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1534 zread_ipv6_nexthop_lookup (client, length);
1535 break;
1536#endif /* HAVE_IPV6 */
1537 case ZEBRA_IPV4_IMPORT_LOOKUP:
1538 zread_ipv4_import_lookup (client, length);
1539 break;
1540 default:
1541 zlog_info ("Zebra received unknown command %d", command);
1542 break;
1543 }
1544
1545 stream_reset (client->ibuf);
1546 zebra_event (ZEBRA_READ, sock, client);
1547
1548 return 0;
1549}
1550
1551/* Write output buffer to the socket. */
1552void
1553zebra_write (struct thread *thread)
1554{
1555 int sock;
1556 struct zserv *client;
1557
1558 /* Thread treatment. */
1559 sock = THREAD_FD (thread);
1560 client = THREAD_ARG (thread);
1561 client->t_write = NULL;
1562
1563 stream_flush (client->obuf, sock);
1564}
1565
1566/* Accept code of zebra server socket. */
1567int
1568zebra_accept (struct thread *thread)
1569{
paulccf35572003-03-01 11:42:20 +00001570 int val;
paul718e3742002-12-13 20:15:29 +00001571 int accept_sock;
1572 int client_sock;
1573 struct sockaddr_in client;
1574 socklen_t len;
1575
1576 accept_sock = THREAD_FD (thread);
1577
1578 len = sizeof (struct sockaddr_in);
1579 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1580
1581 if (client_sock < 0)
1582 {
1583 zlog_warn ("Can't accept zebra socket: %s", strerror (errno));
1584 return -1;
1585 }
1586
paulccf35572003-03-01 11:42:20 +00001587 /* Make client socket non-blocking. */
1588
1589 val = fcntl (client_sock, F_GETFL, 0);
1590 fcntl (client_sock, F_SETFL, (val | O_NONBLOCK));
1591
paul718e3742002-12-13 20:15:29 +00001592 /* Create new zebra client. */
1593 zebra_client_create (client_sock);
1594
1595 /* Register myself. */
1596 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1597
1598 return 0;
1599}
1600
1601/* Make zebra's server socket. */
1602void
1603zebra_serv ()
1604{
1605 int ret;
1606 int accept_sock;
1607 struct sockaddr_in addr;
1608
1609 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1610
1611 if (accept_sock < 0)
1612 {
1613 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1614 zlog_warn ("zebra can't provice full functionality due to above error");
1615 return;
1616 }
1617
1618 memset (&addr, 0, sizeof (struct sockaddr_in));
1619 addr.sin_family = AF_INET;
1620 addr.sin_port = htons (ZEBRA_PORT);
1621#ifdef HAVE_SIN_LEN
1622 addr.sin_len = sizeof (struct sockaddr_in);
1623#endif /* HAVE_SIN_LEN */
1624 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1625
1626 sockopt_reuseaddr (accept_sock);
1627 sockopt_reuseport (accept_sock);
1628
1629 ret = bind (accept_sock, (struct sockaddr *)&addr,
1630 sizeof (struct sockaddr_in));
1631 if (ret < 0)
1632 {
1633 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1634 zlog_warn ("zebra can't provice full functionality due to above error");
1635 close (accept_sock); /* Avoid sd leak. */
1636 return;
1637 }
1638
1639 ret = listen (accept_sock, 1);
1640 if (ret < 0)
1641 {
1642 zlog_warn ("Can't listen to socket: %s", strerror (errno));
1643 zlog_warn ("zebra can't provice full functionality due to above error");
1644 close (accept_sock); /* Avoid sd leak. */
1645 return;
1646 }
1647
1648 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1649}
1650
1651/* For sockaddr_un. */
1652#include <sys/un.h>
1653
1654/* zebra server UNIX domain socket. */
1655void
1656zebra_serv_un (char *path)
1657{
1658 int ret;
1659 int sock, len;
1660 struct sockaddr_un serv;
1661 mode_t old_mask;
1662
1663 /* First of all, unlink existing socket */
1664 unlink (path);
1665
1666 /* Set umask */
1667 old_mask = umask (0077);
1668
1669 /* Make UNIX domain socket. */
1670 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1671 if (sock < 0)
1672 {
1673 perror ("sock");
1674 return;
1675 }
1676
1677 /* Make server socket. */
1678 memset (&serv, 0, sizeof (struct sockaddr_un));
1679 serv.sun_family = AF_UNIX;
1680 strncpy (serv.sun_path, path, strlen (path));
1681#ifdef HAVE_SUN_LEN
1682 len = serv.sun_len = SUN_LEN(&serv);
1683#else
1684 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1685#endif /* HAVE_SUN_LEN */
1686
1687 ret = bind (sock, (struct sockaddr *) &serv, len);
1688 if (ret < 0)
1689 {
1690 perror ("bind");
1691 close (sock);
1692 return;
1693 }
1694
1695 ret = listen (sock, 5);
1696 if (ret < 0)
1697 {
1698 perror ("listen");
1699 close (sock);
1700 return;
1701 }
1702
1703 umask (old_mask);
1704
1705 zebra_event (ZEBRA_SERV, sock, NULL);
1706}
1707
1708/* Zebra's event management function. */
1709extern struct thread_master *master;
1710
1711void
1712zebra_event (enum event event, int sock, struct zserv *client)
1713{
1714 switch (event)
1715 {
1716 case ZEBRA_SERV:
1717 thread_add_read (master, zebra_accept, client, sock);
1718 break;
1719 case ZEBRA_READ:
1720 client->t_read =
1721 thread_add_read (master, zebra_client_read, client, sock);
1722 break;
1723 case ZEBRA_WRITE:
1724 /**/
1725 break;
1726 }
1727}
1728
1729/* Display default rtm_table for all clients. */
1730DEFUN (show_table,
1731 show_table_cmd,
1732 "show table",
1733 SHOW_STR
1734 "default routing table to use for all clients\n")
1735{
1736 vty_out (vty, "table %d%s", rtm_table_default,
1737 VTY_NEWLINE);
1738 return CMD_SUCCESS;
1739}
1740
1741DEFUN (config_table,
1742 config_table_cmd,
1743 "table TABLENO",
1744 "Configure target kernel routing table\n"
1745 "TABLE integer\n")
1746{
1747 rtm_table_default = strtol (argv[0], (char**)0, 10);
1748 return CMD_SUCCESS;
1749}
1750
1751DEFUN (no_ip_forwarding,
1752 no_ip_forwarding_cmd,
1753 "no ip forwarding",
1754 NO_STR
1755 IP_STR
1756 "Turn off IP forwarding")
1757{
1758 int ret;
1759
1760 ret = ipforward ();
1761
1762 if (ret == 0)
1763 {
1764 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);
1765 return CMD_ERR_NOTHING_TODO;
1766 }
1767
1768 ret = ipforward_off ();
1769 if (ret != 0)
1770 {
1771 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1772 return CMD_WARNING;
1773 }
1774
1775 return CMD_SUCCESS;
1776}
1777
1778/* This command is for debugging purpose. */
1779DEFUN (show_zebra_client,
1780 show_zebra_client_cmd,
1781 "show zebra client",
1782 SHOW_STR
1783 "Zebra information"
1784 "Client information")
1785{
1786 listnode node;
1787 struct zserv *client;
1788
1789 for (node = listhead (client_list); node; nextnode (node))
1790 {
1791 client = getdata (node);
1792 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1793 }
1794 return CMD_SUCCESS;
1795}
1796
1797/* Table configuration write function. */
1798int
1799config_write_table (struct vty *vty)
1800{
1801 if (rtm_table_default)
1802 vty_out (vty, "table %d%s", rtm_table_default,
1803 VTY_NEWLINE);
1804 return 0;
1805}
1806
1807/* table node for routing tables. */
1808struct cmd_node table_node =
1809{
1810 TABLE_NODE,
1811 "", /* This node has no interface. */
1812 1
1813};
1814
1815/* Only display ip forwarding is enabled or not. */
1816DEFUN (show_ip_forwarding,
1817 show_ip_forwarding_cmd,
1818 "show ip forwarding",
1819 SHOW_STR
1820 IP_STR
1821 "IP forwarding status\n")
1822{
1823 int ret;
1824
1825 ret = ipforward ();
1826
1827 if (ret == 0)
1828 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1829 else
1830 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1831 return CMD_SUCCESS;
1832}
1833
1834#ifdef HAVE_IPV6
1835/* Only display ipv6 forwarding is enabled or not. */
1836DEFUN (show_ipv6_forwarding,
1837 show_ipv6_forwarding_cmd,
1838 "show ipv6 forwarding",
1839 SHOW_STR
1840 "IPv6 information\n"
1841 "Forwarding status\n")
1842{
1843 int ret;
1844
1845 ret = ipforward_ipv6 ();
1846
1847 switch (ret)
1848 {
1849 case -1:
1850 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1851 break;
1852 case 0:
1853 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1854 break;
1855 case 1:
1856 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1857 break;
1858 default:
1859 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1860 break;
1861 }
1862 return CMD_SUCCESS;
1863}
1864
1865DEFUN (no_ipv6_forwarding,
1866 no_ipv6_forwarding_cmd,
1867 "no ipv6 forwarding",
1868 NO_STR
1869 IP_STR
1870 "Doesn't forward IPv6 protocol packet")
1871{
1872 int ret;
1873
1874 ret = ipforward_ipv6_off ();
1875 if (ret != 0)
1876 {
1877 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1878 return CMD_WARNING;
1879 }
1880
1881 return CMD_SUCCESS;
1882}
1883
1884#endif /* HAVE_IPV6 */
1885
1886/* IPForwarding configuration write function. */
1887int
1888config_write_forwarding (struct vty *vty)
1889{
1890 if (! ipforward ())
1891 vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
1892#ifdef HAVE_IPV6
1893 if (! ipforward_ipv6 ())
1894 vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
1895#endif /* HAVE_IPV6 */
1896 vty_out (vty, "!%s", VTY_NEWLINE);
1897 return 0;
1898}
1899
1900/* table node for routing tables. */
1901struct cmd_node forwarding_node =
1902{
1903 FORWARDING_NODE,
1904 "", /* This node has no interface. */
1905 1
1906};
1907
1908
1909/* Initialisation of zebra and installation of commands. */
1910void
1911zebra_init ()
1912{
1913 /* Client list init. */
1914 client_list = list_new ();
1915
1916 /* Forwarding is on by default. */
1917 ipforward_on ();
1918#ifdef HAVE_IPV6
1919 ipforward_ipv6_on ();
1920#endif /* HAVE_IPV6 */
1921
1922 /* Make zebra server socket. */
1923#ifdef HAVE_TCP_ZEBRA
1924 zebra_serv ();
1925#else
1926 zebra_serv_un (ZEBRA_SERV_PATH);
1927#endif /* HAVE_TCP_ZEBRA */
1928
1929 /* Install configuration write function. */
1930 install_node (&table_node, config_write_table);
1931 install_node (&forwarding_node, config_write_forwarding);
1932
1933 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1934 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
1935 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1936 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1937
1938#ifdef HAVE_NETLINK
1939 install_element (VIEW_NODE, &show_table_cmd);
1940 install_element (ENABLE_NODE, &show_table_cmd);
1941 install_element (CONFIG_NODE, &config_table_cmd);
1942#endif /* HAVE_NETLINK */
1943
1944#ifdef HAVE_IPV6
1945 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1946 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
1947 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1948#endif /* HAVE_IPV6 */
paulccf35572003-03-01 11:42:20 +00001949
1950 FIFO_INIT(&message_queue);
1951 t_write = NULL;
paul718e3742002-12-13 20:15:29 +00001952}