blob: 70e7672df84361945998d83a11176dd10433879c [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
hasso726f9b22003-05-25 21:04:54 +0000451 /* XXX: Waht's about NEXTHOP_TYPE_IPV4_IFNAME ? */
paul718e3742002-12-13 20:15:29 +0000452 if (nexthop->type == NEXTHOP_TYPE_IPV4
453 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
454 stream_put_in_addr (s, &nexthop->gate.ipv4);
455 else
456 stream_put_in_addr (s, &empty);
457
458 /* Interface index. */
459 stream_putc (s, 1);
460 stream_putl (s, nexthop->ifindex);
461
462 break;
463 }
464 }
465
466 /* Metric */
467 stream_putl (s, rib->metric);
468
469 /* Write packet size. */
470 stream_putw_at (s, 0, stream_get_endp (s));
471
paulccf35572003-03-01 11:42:20 +0000472 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
473
474 return 0;
paul718e3742002-12-13 20:15:29 +0000475}
476
477int
478zsend_ipv4_delete_multipath (struct zserv *client, struct prefix *p,
479 struct rib *rib)
480{
481 int psize;
482 struct stream *s;
483 struct nexthop *nexthop;
484 struct in_addr empty;
485
486 empty.s_addr = 0;
487
488 s = client->obuf;
489 stream_reset (s);
490
491 /* Place holder for size. */
492 stream_putw (s, 0);
493
494 /* Put command, type and nexthop. */
495 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
496 stream_putc (s, rib->type);
497 stream_putc (s, rib->flags);
498 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
499
500 /* Prefix. */
501 psize = PSIZE (p->prefixlen);
502 stream_putc (s, p->prefixlen);
503 stream_write (s, (u_char *)&p->u.prefix, psize);
504
505 /* Nexthop */
506 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
507 {
508 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
509 {
510 stream_putc (s, 1);
511
512 if (nexthop->type == NEXTHOP_TYPE_IPV4)
513 stream_put_in_addr (s, &nexthop->gate.ipv4);
514 else
515 stream_put_in_addr (s, &empty);
516
517 /* Interface index. */
518 stream_putc (s, 1);
519 stream_putl (s, nexthop->ifindex);
520
521 break;
522 }
523 }
524
525 /* Write packet size. */
526 stream_putw_at (s, 0, stream_get_endp (s));
527
paulccf35572003-03-01 11:42:20 +0000528 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
529
530 return 0;
paul718e3742002-12-13 20:15:29 +0000531}
532
hasso726f9b22003-05-25 21:04:54 +0000533#if 0
534#warning oldies
paul718e3742002-12-13 20:15:29 +0000535int
536zsend_ipv4_add (struct zserv *client, int type, int flags,
537 struct prefix_ipv4 *p, struct in_addr *nexthop,
538 unsigned int ifindex)
539{
540 int psize;
541 struct stream *s;
542
543 s = client->obuf;
544 stream_reset (s);
545
546 /* Place holder for size. */
547 stream_putw (s, 0);
548
549 /* Put command, type and nexthop. */
550 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
551 stream_putc (s, type);
552 stream_putc (s, flags);
553 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
554
555 /* Prefix. */
556 psize = PSIZE (p->prefixlen);
557 stream_putc (s, p->prefixlen);
558 stream_write (s, (u_char *)&p->prefix, psize);
559
560 /* Nexthop */
561 stream_putc (s, 1);
562 stream_put_in_addr (s, nexthop);
563
564 /* Interface index. */
565 stream_putc (s, 1);
566 stream_putl (s, ifindex);
567
568 /* Write packet size. */
569 stream_putw_at (s, 0, stream_get_endp (s));
570
paulccf35572003-03-01 11:42:20 +0000571 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
572
573 return 0;
paul718e3742002-12-13 20:15:29 +0000574}
575
576int
577zsend_ipv4_delete (struct zserv *client, int type, int flags,
578 struct prefix_ipv4 *p, struct in_addr *nexthop,
579 unsigned int ifindex)
580{
581 int psize;
582 struct stream *s;
583
584 s = client->obuf;
585 stream_reset (s);
586
587 /* Place holder for size. */
588 stream_putw (s, 0);
589
590 /* Put command, type and nexthop. */
591 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
592 stream_putc (s, type);
593 stream_putc (s, flags);
594 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
595
596 /* Prefix. */
597 psize = PSIZE (p->prefixlen);
598 stream_putc (s, p->prefixlen);
599 stream_write (s, (u_char *)&p->prefix, psize);
600
601 /* Nexthop */
602 stream_putc (s, 1);
603 stream_put_in_addr (s, nexthop);
604
605 /* Interface index. */
606 stream_putc (s, 1);
607 stream_putl (s, ifindex);
608
609 /* Write packet size. */
610 stream_putw_at (s, 0, stream_get_endp (s));
611
paulccf35572003-03-01 11:42:20 +0000612 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
613
614 return 0;
paul718e3742002-12-13 20:15:29 +0000615}
hasso726f9b22003-05-25 21:04:54 +0000616#endif /* oldies */
paul718e3742002-12-13 20:15:29 +0000617
618#ifdef HAVE_IPV6
hasso726f9b22003-05-25 21:04:54 +0000619#if 0
620#warning oldies
paul718e3742002-12-13 20:15:29 +0000621int
622zsend_ipv6_add (struct zserv *client, int type, int flags,
623 struct prefix_ipv6 *p, struct in6_addr *nexthop,
624 unsigned int ifindex)
625{
626 int psize;
627 struct stream *s;
628
629 s = client->obuf;
630 stream_reset (s);
631
632 /* Place holder for size. */
633 stream_putw (s, 0);
634
635 /* Put command, type and nexthop. */
636 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
637 stream_putc (s, type);
638 stream_putc (s, flags);
639 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
640
641 /* Prefix. */
642 psize = PSIZE (p->prefixlen);
643 stream_putc (s, p->prefixlen);
644 stream_write (s, (u_char *)&p->prefix, psize);
645
646 /* Nexthop */
647 stream_putc (s, 1);
648 stream_write (s, (u_char *)nexthop, 16);
649
650 /* Interface index. */
651 stream_putc (s, 1);
652 stream_putl (s, ifindex);
653
654 /* Write packet size. */
655 stream_putw_at (s, 0, stream_get_endp (s));
656
paulccf35572003-03-01 11:42:20 +0000657 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
658
659 return 0;
paul718e3742002-12-13 20:15:29 +0000660}
hasso726f9b22003-05-25 21:04:54 +0000661#endif /* oldies */
paul718e3742002-12-13 20:15:29 +0000662
663int
664zsend_ipv6_add_multipath (struct zserv *client, struct prefix *p,
665 struct rib *rib)
666{
667 int psize;
668 struct stream *s;
669 struct nexthop *nexthop;
670 struct in6_addr empty;
671
672 memset (&empty, 0, sizeof (struct in6_addr));
673 s = client->obuf;
674 stream_reset (s);
675
676 /* Place holder for size. */
677 stream_putw (s, 0);
678
679 /* Put command, type and nexthop. */
680 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
681 stream_putc (s, rib->type);
682 stream_putc (s, rib->flags);
683 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC);
684
685 /* Prefix. */
686 psize = PSIZE (p->prefixlen);
687 stream_putc (s, p->prefixlen);
688 stream_write (s, (u_char *) &p->u.prefix, psize);
689
690 /* Nexthop */
691 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
692 {
693 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
694 {
695 stream_putc (s, 1);
696
hasso726f9b22003-05-25 21:04:54 +0000697 if (nexthop->type == NEXTHOP_TYPE_IPV6
698 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
699 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
paul718e3742002-12-13 20:15:29 +0000700 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
701 else
702 stream_write (s, (u_char *) &empty, 16);
703
704 /* Interface index. */
705 stream_putc (s, 1);
706 stream_putl (s, nexthop->ifindex);
707
708 break;
709 }
710 }
711
712 /* Metric */
713 stream_putl (s, rib->metric);
714
715 /* Write packet size. */
716 stream_putw_at (s, 0, stream_get_endp (s));
717
paulccf35572003-03-01 11:42:20 +0000718 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
719
720 return 0;
paul718e3742002-12-13 20:15:29 +0000721}
722
hasso726f9b22003-05-25 21:04:54 +0000723#if 0
724#warning oldies
paul718e3742002-12-13 20:15:29 +0000725int
726zsend_ipv6_delete (struct zserv *client, int type, int flags,
727 struct prefix_ipv6 *p, struct in6_addr *nexthop,
728 unsigned int ifindex)
729{
730 int psize;
731 struct stream *s;
732
733 s = client->obuf;
734 stream_reset (s);
735
736 /* Place holder for size. */
737 stream_putw (s, 0);
738
739 /* Put command, type and nexthop. */
740 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
741 stream_putc (s, type);
742 stream_putc (s, flags);
743 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
744
745 /* Prefix. */
746 psize = PSIZE (p->prefixlen);
747 stream_putc (s, p->prefixlen);
748 stream_write (s, (u_char *)&p->prefix, psize);
749
750 /* Nexthop */
751 stream_putc (s, 1);
752 stream_write (s, (u_char *)nexthop, 16);
753
754 /* Interface index. */
755 stream_putc (s, 1);
756 stream_putl (s, ifindex);
757
758 /* Write packet size. */
759 stream_putw_at (s, 0, stream_get_endp (s));
760
paulccf35572003-03-01 11:42:20 +0000761 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
762
763 return 0;
paul718e3742002-12-13 20:15:29 +0000764}
hasso726f9b22003-05-25 21:04:54 +0000765#endif /* oldies */
paul718e3742002-12-13 20:15:29 +0000766
767int
768zsend_ipv6_delete_multipath (struct zserv *client, struct prefix *p,
769 struct rib *rib)
770{
771 int psize;
772 struct stream *s;
773 struct nexthop *nexthop;
774 struct in6_addr empty;
775
776 memset (&empty, 0, sizeof (struct in6_addr));
777 s = client->obuf;
778 stream_reset (s);
779
780 /* Place holder for size. */
781 stream_putw (s, 0);
782
783 /* Put command, type and nexthop. */
784 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
785 stream_putc (s, rib->type);
786 stream_putc (s, rib->flags);
787 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
788
789 /* Prefix. */
790 psize = PSIZE (p->prefixlen);
791 stream_putc (s, p->prefixlen);
792 stream_write (s, (u_char *)&p->u.prefix, psize);
793
794 /* Nexthop */
795 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
796 {
797 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
798 {
799 stream_putc (s, 1);
800
801 if (nexthop->type == NEXTHOP_TYPE_IPV6)
802 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
803 else
804 stream_write (s, (u_char *) &empty, 16);
805
806 /* Interface index. */
807 stream_putc (s, 1);
808 stream_putl (s, nexthop->ifindex);
809
810 break;
811 }
812 }
813
814 /* Write packet size. */
815 stream_putw_at (s, 0, stream_get_endp (s));
816
paulccf35572003-03-01 11:42:20 +0000817 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
818
819 return 0;
paul718e3742002-12-13 20:15:29 +0000820}
821
822int
823zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
824{
825 struct stream *s;
826 struct rib *rib;
827 unsigned long nump;
828 u_char num;
829 struct nexthop *nexthop;
830
831 /* Lookup nexthop. */
832 rib = rib_match_ipv6 (addr);
833
834 /* Get output stream. */
835 s = client->obuf;
836 stream_reset (s);
837
838 /* Fill in result. */
839 stream_putw (s, 0);
840 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
841 stream_put (s, &addr, 16);
842
843 if (rib)
844 {
845 stream_putl (s, rib->metric);
846 num = 0;
847 nump = s->putp;
848 stream_putc (s, 0);
849 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
850 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
851 {
852 stream_putc (s, nexthop->type);
853 switch (nexthop->type)
854 {
855 case ZEBRA_NEXTHOP_IPV6:
856 stream_put (s, &nexthop->gate.ipv6, 16);
857 break;
858 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
859 case ZEBRA_NEXTHOP_IPV6_IFNAME:
860 stream_put (s, &nexthop->gate.ipv6, 16);
861 stream_putl (s, nexthop->ifindex);
862 break;
863 case ZEBRA_NEXTHOP_IFINDEX:
864 case ZEBRA_NEXTHOP_IFNAME:
865 stream_putl (s, nexthop->ifindex);
866 break;
867 }
868 num++;
869 }
870 stream_putc_at (s, nump, num);
871 }
872 else
873 {
874 stream_putl (s, 0);
875 stream_putc (s, 0);
876 }
877
878 stream_putw_at (s, 0, stream_get_endp (s));
879
paulccf35572003-03-01 11:42:20 +0000880 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
881
882 return 0;
paul718e3742002-12-13 20:15:29 +0000883}
884#endif /* HAVE_IPV6 */
885
886int
887zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
888{
889 struct stream *s;
890 struct rib *rib;
891 unsigned long nump;
892 u_char num;
893 struct nexthop *nexthop;
894
895 /* Lookup nexthop. */
896 rib = rib_match_ipv4 (addr);
897
898 /* Get output stream. */
899 s = client->obuf;
900 stream_reset (s);
901
902 /* Fill in result. */
903 stream_putw (s, 0);
904 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
905 stream_put_in_addr (s, &addr);
906
907 if (rib)
908 {
909 stream_putl (s, rib->metric);
910 num = 0;
911 nump = s->putp;
912 stream_putc (s, 0);
913 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
914 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
915 {
916 stream_putc (s, nexthop->type);
917 switch (nexthop->type)
918 {
919 case ZEBRA_NEXTHOP_IPV4:
920 stream_put_in_addr (s, &nexthop->gate.ipv4);
921 break;
922 case ZEBRA_NEXTHOP_IFINDEX:
923 case ZEBRA_NEXTHOP_IFNAME:
924 stream_putl (s, nexthop->ifindex);
925 break;
926 }
927 num++;
928 }
929 stream_putc_at (s, nump, num);
930 }
931 else
932 {
933 stream_putl (s, 0);
934 stream_putc (s, 0);
935 }
936
937 stream_putw_at (s, 0, stream_get_endp (s));
938
paulccf35572003-03-01 11:42:20 +0000939 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
940
941 return 0;
paul718e3742002-12-13 20:15:29 +0000942}
943
944int
945zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
946{
947 struct stream *s;
948 struct rib *rib;
949 unsigned long nump;
950 u_char num;
951 struct nexthop *nexthop;
952
953 /* Lookup nexthop. */
954 rib = rib_lookup_ipv4 (p);
955
956 /* Get output stream. */
957 s = client->obuf;
958 stream_reset (s);
959
960 /* Fill in result. */
961 stream_putw (s, 0);
962 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
963 stream_put_in_addr (s, &p->prefix);
964
965 if (rib)
966 {
967 stream_putl (s, rib->metric);
968 num = 0;
969 nump = s->putp;
970 stream_putc (s, 0);
971 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
972 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
973 {
974 stream_putc (s, nexthop->type);
975 switch (nexthop->type)
976 {
977 case ZEBRA_NEXTHOP_IPV4:
978 stream_put_in_addr (s, &nexthop->gate.ipv4);
979 break;
980 case ZEBRA_NEXTHOP_IFINDEX:
981 case ZEBRA_NEXTHOP_IFNAME:
982 stream_putl (s, nexthop->ifindex);
983 break;
984 }
985 num++;
986 }
987 stream_putc_at (s, nump, num);
988 }
989 else
990 {
991 stream_putl (s, 0);
992 stream_putc (s, 0);
993 }
994
995 stream_putw_at (s, 0, stream_get_endp (s));
996
paulccf35572003-03-01 11:42:20 +0000997 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
998
999 return 0;
paul718e3742002-12-13 20:15:29 +00001000}
1001
1002/* Register zebra server interface information. Send current all
1003 interface and address information. */
1004void
1005zread_interface_add (struct zserv *client, u_short length)
1006{
1007 listnode ifnode;
1008 listnode cnode;
1009 struct interface *ifp;
1010 struct connected *c;
1011
1012 /* Interface information is needed. */
1013 client->ifinfo = 1;
1014
1015 for (ifnode = listhead (iflist); ifnode; ifnode = nextnode (ifnode))
1016 {
1017 ifp = getdata (ifnode);
1018
1019 /* Skip pseudo interface. */
1020 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1021 continue;
1022
1023 zsend_interface_add (client, ifp);
1024
1025 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
1026 {
1027 c = getdata (cnode);
1028 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
1029 zsend_interface_address_add (client, ifp, c);
1030 }
1031 }
1032}
1033
1034/* Unregister zebra server interface information. */
1035void
1036zread_interface_delete (struct zserv *client, u_short length)
1037{
1038 client->ifinfo = 0;
1039}
1040
1041/* This function support multiple nexthop. */
1042void
1043zread_ipv4_add (struct zserv *client, u_short length)
1044{
1045 int i;
1046 struct rib *rib;
1047 struct prefix_ipv4 p;
1048 u_char message;
1049 struct in_addr nexthop;
1050 u_char nexthop_num;
1051 u_char nexthop_type;
1052 struct stream *s;
1053 unsigned int ifindex;
1054 u_char ifname_len;
1055
1056 /* Get input stream. */
1057 s = client->ibuf;
1058
1059 /* Allocate new rib. */
1060 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1061 memset (rib, 0, sizeof (struct rib));
1062
1063 /* Type, flags, message. */
1064 rib->type = stream_getc (s);
1065 rib->flags = stream_getc (s);
1066 message = stream_getc (s);
1067 rib->uptime = time (NULL);
1068
1069 /* IPv4 prefix. */
1070 memset (&p, 0, sizeof (struct prefix_ipv4));
1071 p.family = AF_INET;
1072 p.prefixlen = stream_getc (s);
1073 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1074
1075 /* Nexthop parse. */
1076 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1077 {
1078 nexthop_num = stream_getc (s);
1079
1080 for (i = 0; i < nexthop_num; i++)
1081 {
1082 nexthop_type = stream_getc (s);
1083
1084 switch (nexthop_type)
1085 {
1086 case ZEBRA_NEXTHOP_IFINDEX:
1087 ifindex = stream_getl (s);
1088 nexthop_ifindex_add (rib, ifindex);
1089 break;
1090 case ZEBRA_NEXTHOP_IFNAME:
1091 ifname_len = stream_getc (s);
1092 stream_forward (s, ifname_len);
1093 break;
1094 case ZEBRA_NEXTHOP_IPV4:
1095 nexthop.s_addr = stream_get_ipv4 (s);
1096 nexthop_ipv4_add (rib, &nexthop);
1097 break;
1098 case ZEBRA_NEXTHOP_IPV6:
1099 stream_forward (s, IPV6_MAX_BYTELEN);
1100 break;
paul595db7f2003-05-25 21:35:06 +00001101 case ZEBRA_NEXTHOP_BLACKHOLE:
1102 nexthop_blackhole_add (rib);
1103 break;
paul718e3742002-12-13 20:15:29 +00001104 }
1105 }
1106 }
1107
1108 /* Distance. */
1109 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1110 rib->distance = stream_getc (s);
1111
1112 /* Metric. */
1113 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1114 rib->metric = stream_getl (s);
1115
1116 rib_add_ipv4_multipath (&p, rib);
1117}
1118
1119/* Zebra server IPv4 prefix delete function. */
1120void
1121zread_ipv4_delete (struct zserv *client, u_short length)
1122{
1123 int i;
1124 struct stream *s;
1125 struct zapi_ipv4 api;
1126 struct in_addr nexthop;
1127 unsigned long ifindex;
1128 struct prefix_ipv4 p;
1129 u_char nexthop_num;
1130 u_char nexthop_type;
1131 u_char ifname_len;
1132
1133 s = client->ibuf;
1134 ifindex = 0;
1135 nexthop.s_addr = 0;
1136
1137 /* Type, flags, message. */
1138 api.type = stream_getc (s);
1139 api.flags = stream_getc (s);
1140 api.message = stream_getc (s);
1141
1142 /* IPv4 prefix. */
1143 memset (&p, 0, sizeof (struct prefix_ipv4));
1144 p.family = AF_INET;
1145 p.prefixlen = stream_getc (s);
1146 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1147
1148 /* Nexthop, ifindex, distance, metric. */
1149 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1150 {
1151 nexthop_num = stream_getc (s);
1152
1153 for (i = 0; i < nexthop_num; i++)
1154 {
1155 nexthop_type = stream_getc (s);
1156
1157 switch (nexthop_type)
1158 {
1159 case ZEBRA_NEXTHOP_IFINDEX:
1160 ifindex = stream_getl (s);
1161 break;
1162 case ZEBRA_NEXTHOP_IFNAME:
1163 ifname_len = stream_getc (s);
1164 stream_forward (s, ifname_len);
1165 break;
1166 case ZEBRA_NEXTHOP_IPV4:
1167 nexthop.s_addr = stream_get_ipv4 (s);
1168 break;
1169 case ZEBRA_NEXTHOP_IPV6:
1170 stream_forward (s, IPV6_MAX_BYTELEN);
1171 break;
1172 }
1173 }
1174 }
1175
1176 /* Distance. */
1177 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1178 api.distance = stream_getc (s);
1179 else
1180 api.distance = 0;
1181
1182 /* Metric. */
1183 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1184 api.metric = stream_getl (s);
1185 else
1186 api.metric = 0;
1187
1188 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
1189 client->rtm_table);
1190}
1191
1192/* Nexthop lookup for IPv4. */
1193void
1194zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
1195{
1196 struct in_addr addr;
1197
1198 addr.s_addr = stream_get_ipv4 (client->ibuf);
1199 zsend_ipv4_nexthop_lookup (client, addr);
1200}
1201
1202/* Nexthop lookup for IPv4. */
1203void
1204zread_ipv4_import_lookup (struct zserv *client, u_short length)
1205{
1206 struct prefix_ipv4 p;
1207
1208 p.family = AF_INET;
1209 p.prefixlen = stream_getc (client->ibuf);
1210 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1211
1212 zsend_ipv4_import_lookup (client, &p);
1213}
1214
1215#ifdef HAVE_IPV6
1216/* Zebra server IPv6 prefix add function. */
1217void
1218zread_ipv6_add (struct zserv *client, u_short length)
1219{
1220 int i;
1221 struct stream *s;
1222 struct zapi_ipv6 api;
1223 struct in6_addr nexthop;
1224 unsigned long ifindex;
1225 struct prefix_ipv6 p;
1226
1227 s = client->ibuf;
1228 ifindex = 0;
1229 memset (&nexthop, 0, sizeof (struct in6_addr));
1230
1231 /* Type, flags, message. */
1232 api.type = stream_getc (s);
1233 api.flags = stream_getc (s);
1234 api.message = stream_getc (s);
1235
1236 /* IPv4 prefix. */
1237 memset (&p, 0, sizeof (struct prefix_ipv6));
1238 p.family = AF_INET6;
1239 p.prefixlen = stream_getc (s);
1240 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1241
1242 /* Nexthop, ifindex, distance, metric. */
1243 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1244 {
1245 u_char nexthop_type;
1246
1247 api.nexthop_num = stream_getc (s);
1248 for (i = 0; i < api.nexthop_num; i++)
1249 {
1250 nexthop_type = stream_getc (s);
1251
1252 switch (nexthop_type)
1253 {
1254 case ZEBRA_NEXTHOP_IPV6:
1255 stream_get (&nexthop, s, 16);
1256 break;
1257 case ZEBRA_NEXTHOP_IFINDEX:
1258 ifindex = stream_getl (s);
1259 break;
1260 }
1261 }
1262 }
1263
1264 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1265 api.distance = stream_getc (s);
1266 else
1267 api.distance = 0;
1268
1269 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1270 api.metric = stream_getl (s);
1271 else
1272 api.metric = 0;
1273
1274 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1275 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1276 else
1277 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1278}
1279
1280/* Zebra server IPv6 prefix delete function. */
1281void
1282zread_ipv6_delete (struct zserv *client, u_short length)
1283{
1284 int i;
1285 struct stream *s;
1286 struct zapi_ipv6 api;
1287 struct in6_addr nexthop;
1288 unsigned long ifindex;
1289 struct prefix_ipv6 p;
1290
1291 s = client->ibuf;
1292 ifindex = 0;
1293 memset (&nexthop, 0, sizeof (struct in6_addr));
1294
1295 /* Type, flags, message. */
1296 api.type = stream_getc (s);
1297 api.flags = stream_getc (s);
1298 api.message = stream_getc (s);
1299
1300 /* IPv4 prefix. */
1301 memset (&p, 0, sizeof (struct prefix_ipv6));
1302 p.family = AF_INET6;
1303 p.prefixlen = stream_getc (s);
1304 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1305
1306 /* Nexthop, ifindex, distance, metric. */
1307 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1308 {
1309 u_char nexthop_type;
1310
1311 api.nexthop_num = stream_getc (s);
1312 for (i = 0; i < api.nexthop_num; i++)
1313 {
1314 nexthop_type = stream_getc (s);
1315
1316 switch (nexthop_type)
1317 {
1318 case ZEBRA_NEXTHOP_IPV6:
1319 stream_get (&nexthop, s, 16);
1320 break;
1321 case ZEBRA_NEXTHOP_IFINDEX:
1322 ifindex = stream_getl (s);
1323 break;
1324 }
1325 }
1326 }
1327
1328 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1329 api.distance = stream_getc (s);
1330 else
1331 api.distance = 0;
1332 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1333 api.metric = stream_getl (s);
1334 else
1335 api.metric = 0;
1336
1337 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1338 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1339 else
1340 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1341}
1342
1343void
1344zebra_read_ipv6 (int command, struct zserv *client, u_short length)
1345{
1346 u_char type;
1347 u_char flags;
1348 struct in6_addr nexthop, *gate;
1349 u_char *lim;
1350 u_char *pnt;
1351 unsigned int ifindex;
1352
1353 pnt = stream_pnt (client->ibuf);
1354 lim = pnt + length;
1355
1356 type = stream_getc (client->ibuf);
1357 flags = stream_getc (client->ibuf);
1358 stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr));
1359
1360 while (stream_pnt (client->ibuf) < lim)
1361 {
1362 int size;
1363 struct prefix_ipv6 p;
1364
1365 ifindex = stream_getl (client->ibuf);
1366
1367 memset (&p, 0, sizeof (struct prefix_ipv6));
1368 p.family = AF_INET6;
1369 p.prefixlen = stream_getc (client->ibuf);
1370 size = PSIZE(p.prefixlen);
1371 stream_get (&p.prefix, client->ibuf, size);
1372
1373 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1374 gate = NULL;
1375 else
1376 gate = &nexthop;
1377
1378 if (command == ZEBRA_IPV6_ROUTE_ADD)
1379 rib_add_ipv6 (type, flags, &p, gate, ifindex, 0);
1380 else
1381 rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);
1382 }
1383}
1384
1385void
1386zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1387{
1388 struct in6_addr addr;
1389 char buf[BUFSIZ];
1390
1391 stream_get (&addr, client->ibuf, 16);
1392 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1393
1394 zsend_ipv6_nexthop_lookup (client, &addr);
1395}
1396#endif /* HAVE_IPV6 */
1397
1398/* Close zebra client. */
1399void
1400zebra_client_close (struct zserv *client)
1401{
1402 /* Close file descriptor. */
1403 if (client->sock)
1404 {
1405 close (client->sock);
1406 client->sock = -1;
1407 }
1408
1409 /* Free stream buffers. */
1410 if (client->ibuf)
1411 stream_free (client->ibuf);
1412 if (client->obuf)
1413 stream_free (client->obuf);
1414
1415 /* Release threads. */
1416 if (client->t_read)
1417 thread_cancel (client->t_read);
1418 if (client->t_write)
1419 thread_cancel (client->t_write);
1420
1421 /* Free client structure. */
1422 listnode_delete (client_list, client);
1423 XFREE (0, client);
1424}
1425
1426/* Make new client. */
1427void
1428zebra_client_create (int sock)
1429{
1430 struct zserv *client;
1431
1432 client = XCALLOC (0, sizeof (struct zserv));
1433
1434 /* Make client input/output buffer. */
1435 client->sock = sock;
1436 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1437 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1438
1439 /* Set table number. */
1440 client->rtm_table = rtm_table_default;
1441
1442 /* Add this client to linked list. */
1443 listnode_add (client_list, client);
1444
1445 /* Make new read thread. */
1446 zebra_event (ZEBRA_READ, sock, client);
1447}
1448
1449/* Handler of zebra service request. */
1450int
1451zebra_client_read (struct thread *thread)
1452{
1453 int sock;
1454 struct zserv *client;
1455 int nbyte;
1456 u_short length;
1457 u_char command;
1458
1459 /* Get thread data. Reset reading thread because I'm running. */
1460 sock = THREAD_FD (thread);
1461 client = THREAD_ARG (thread);
1462 client->t_read = NULL;
1463
1464 /* Read length and command. */
1465 nbyte = stream_read (client->ibuf, sock, 3);
1466 if (nbyte <= 0)
1467 {
1468 if (IS_ZEBRA_DEBUG_EVENT)
1469 zlog_info ("connection closed socket [%d]", sock);
1470 zebra_client_close (client);
1471 return -1;
1472 }
1473 length = stream_getw (client->ibuf);
1474 command = stream_getc (client->ibuf);
1475
1476 if (length < 3)
1477 {
1478 if (IS_ZEBRA_DEBUG_EVENT)
1479 zlog_info ("length %d is less than 3 ", length);
1480 zebra_client_close (client);
1481 return -1;
1482 }
1483
1484 length -= 3;
1485
1486 /* Read rest of data. */
1487 if (length)
1488 {
1489 nbyte = stream_read (client->ibuf, sock, length);
1490 if (nbyte <= 0)
1491 {
1492 if (IS_ZEBRA_DEBUG_EVENT)
1493 zlog_info ("connection closed [%d] when reading zebra data", sock);
1494 zebra_client_close (client);
1495 return -1;
1496 }
1497 }
1498
1499 /* Debug packet information. */
1500 if (IS_ZEBRA_DEBUG_EVENT)
1501 zlog_info ("zebra message comes from socket [%d]", sock);
1502
1503 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1504 zlog_info ("zebra message received [%s] %d",
1505 zebra_command_str[command], length);
1506
1507 switch (command)
1508 {
1509 case ZEBRA_INTERFACE_ADD:
1510 zread_interface_add (client, length);
1511 break;
1512 case ZEBRA_INTERFACE_DELETE:
1513 zread_interface_delete (client, length);
1514 break;
1515 case ZEBRA_IPV4_ROUTE_ADD:
1516 zread_ipv4_add (client, length);
1517 break;
1518 case ZEBRA_IPV4_ROUTE_DELETE:
1519 zread_ipv4_delete (client, length);
1520 break;
1521#ifdef HAVE_IPV6
1522 case ZEBRA_IPV6_ROUTE_ADD:
1523 zread_ipv6_add (client, length);
1524 break;
1525 case ZEBRA_IPV6_ROUTE_DELETE:
1526 zread_ipv6_delete (client, length);
1527 break;
1528#endif /* HAVE_IPV6 */
1529 case ZEBRA_REDISTRIBUTE_ADD:
1530 zebra_redistribute_add (command, client, length);
1531 break;
1532 case ZEBRA_REDISTRIBUTE_DELETE:
1533 zebra_redistribute_delete (command, client, length);
1534 break;
1535 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1536 zebra_redistribute_default_add (command, client, length);
1537 break;
1538 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1539 zebra_redistribute_default_delete (command, client, length);
1540 break;
1541 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1542 zread_ipv4_nexthop_lookup (client, length);
1543 break;
1544#ifdef HAVE_IPV6
1545 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1546 zread_ipv6_nexthop_lookup (client, length);
1547 break;
1548#endif /* HAVE_IPV6 */
1549 case ZEBRA_IPV4_IMPORT_LOOKUP:
1550 zread_ipv4_import_lookup (client, length);
1551 break;
1552 default:
1553 zlog_info ("Zebra received unknown command %d", command);
1554 break;
1555 }
1556
1557 stream_reset (client->ibuf);
1558 zebra_event (ZEBRA_READ, sock, client);
1559
1560 return 0;
1561}
1562
1563/* Write output buffer to the socket. */
1564void
1565zebra_write (struct thread *thread)
1566{
1567 int sock;
1568 struct zserv *client;
1569
1570 /* Thread treatment. */
1571 sock = THREAD_FD (thread);
1572 client = THREAD_ARG (thread);
1573 client->t_write = NULL;
1574
1575 stream_flush (client->obuf, sock);
1576}
1577
1578/* Accept code of zebra server socket. */
1579int
1580zebra_accept (struct thread *thread)
1581{
paulccf35572003-03-01 11:42:20 +00001582 int val;
paul718e3742002-12-13 20:15:29 +00001583 int accept_sock;
1584 int client_sock;
1585 struct sockaddr_in client;
1586 socklen_t len;
1587
1588 accept_sock = THREAD_FD (thread);
1589
1590 len = sizeof (struct sockaddr_in);
1591 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1592
1593 if (client_sock < 0)
1594 {
1595 zlog_warn ("Can't accept zebra socket: %s", strerror (errno));
1596 return -1;
1597 }
1598
paulccf35572003-03-01 11:42:20 +00001599 /* Make client socket non-blocking. */
1600
1601 val = fcntl (client_sock, F_GETFL, 0);
1602 fcntl (client_sock, F_SETFL, (val | O_NONBLOCK));
1603
paul718e3742002-12-13 20:15:29 +00001604 /* Create new zebra client. */
1605 zebra_client_create (client_sock);
1606
1607 /* Register myself. */
1608 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1609
1610 return 0;
1611}
1612
1613/* Make zebra's server socket. */
1614void
1615zebra_serv ()
1616{
1617 int ret;
1618 int accept_sock;
1619 struct sockaddr_in addr;
1620
1621 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1622
1623 if (accept_sock < 0)
1624 {
1625 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1626 zlog_warn ("zebra can't provice full functionality due to above error");
1627 return;
1628 }
1629
1630 memset (&addr, 0, sizeof (struct sockaddr_in));
1631 addr.sin_family = AF_INET;
1632 addr.sin_port = htons (ZEBRA_PORT);
1633#ifdef HAVE_SIN_LEN
1634 addr.sin_len = sizeof (struct sockaddr_in);
1635#endif /* HAVE_SIN_LEN */
1636 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1637
1638 sockopt_reuseaddr (accept_sock);
1639 sockopt_reuseport (accept_sock);
1640
1641 ret = bind (accept_sock, (struct sockaddr *)&addr,
1642 sizeof (struct sockaddr_in));
1643 if (ret < 0)
1644 {
1645 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1646 zlog_warn ("zebra can't provice full functionality due to above error");
1647 close (accept_sock); /* Avoid sd leak. */
1648 return;
1649 }
1650
1651 ret = listen (accept_sock, 1);
1652 if (ret < 0)
1653 {
1654 zlog_warn ("Can't listen to socket: %s", strerror (errno));
1655 zlog_warn ("zebra can't provice full functionality due to above error");
1656 close (accept_sock); /* Avoid sd leak. */
1657 return;
1658 }
1659
1660 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1661}
1662
1663/* For sockaddr_un. */
1664#include <sys/un.h>
1665
1666/* zebra server UNIX domain socket. */
1667void
1668zebra_serv_un (char *path)
1669{
1670 int ret;
1671 int sock, len;
1672 struct sockaddr_un serv;
1673 mode_t old_mask;
1674
1675 /* First of all, unlink existing socket */
1676 unlink (path);
1677
1678 /* Set umask */
1679 old_mask = umask (0077);
1680
1681 /* Make UNIX domain socket. */
1682 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1683 if (sock < 0)
1684 {
1685 perror ("sock");
1686 return;
1687 }
1688
1689 /* Make server socket. */
1690 memset (&serv, 0, sizeof (struct sockaddr_un));
1691 serv.sun_family = AF_UNIX;
1692 strncpy (serv.sun_path, path, strlen (path));
1693#ifdef HAVE_SUN_LEN
1694 len = serv.sun_len = SUN_LEN(&serv);
1695#else
1696 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1697#endif /* HAVE_SUN_LEN */
1698
1699 ret = bind (sock, (struct sockaddr *) &serv, len);
1700 if (ret < 0)
1701 {
1702 perror ("bind");
1703 close (sock);
1704 return;
1705 }
1706
1707 ret = listen (sock, 5);
1708 if (ret < 0)
1709 {
1710 perror ("listen");
1711 close (sock);
1712 return;
1713 }
1714
1715 umask (old_mask);
1716
1717 zebra_event (ZEBRA_SERV, sock, NULL);
1718}
1719
1720/* Zebra's event management function. */
1721extern struct thread_master *master;
1722
1723void
1724zebra_event (enum event event, int sock, struct zserv *client)
1725{
1726 switch (event)
1727 {
1728 case ZEBRA_SERV:
1729 thread_add_read (master, zebra_accept, client, sock);
1730 break;
1731 case ZEBRA_READ:
1732 client->t_read =
1733 thread_add_read (master, zebra_client_read, client, sock);
1734 break;
1735 case ZEBRA_WRITE:
1736 /**/
1737 break;
1738 }
1739}
1740
1741/* Display default rtm_table for all clients. */
1742DEFUN (show_table,
1743 show_table_cmd,
1744 "show table",
1745 SHOW_STR
1746 "default routing table to use for all clients\n")
1747{
1748 vty_out (vty, "table %d%s", rtm_table_default,
1749 VTY_NEWLINE);
1750 return CMD_SUCCESS;
1751}
1752
1753DEFUN (config_table,
1754 config_table_cmd,
1755 "table TABLENO",
1756 "Configure target kernel routing table\n"
1757 "TABLE integer\n")
1758{
1759 rtm_table_default = strtol (argv[0], (char**)0, 10);
1760 return CMD_SUCCESS;
1761}
1762
hasso647e4f12003-05-25 11:43:52 +00001763DEFUN (ip_forwarding,
1764 ip_forwarding_cmd,
1765 "ip forwarding",
1766 IP_STR
1767 "Turn on IP forwarding")
1768{
1769 int ret;
1770
1771 ret = ipforward ();
1772
1773 if (ret != 0)
1774 {
1775 vty_out (vty, "IP forwarding is already on%s", VTY_NEWLINE);
1776 return CMD_ERR_NOTHING_TODO;
1777 }
1778
1779 ret = ipforward_on ();
1780 if (ret == 0)
1781 {
1782 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1783 return CMD_WARNING;
1784 }
1785
1786 return CMD_SUCCESS;
1787}
1788
paul718e3742002-12-13 20:15:29 +00001789DEFUN (no_ip_forwarding,
1790 no_ip_forwarding_cmd,
1791 "no ip forwarding",
1792 NO_STR
1793 IP_STR
1794 "Turn off IP forwarding")
1795{
1796 int ret;
1797
1798 ret = ipforward ();
1799
1800 if (ret == 0)
1801 {
1802 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);
1803 return CMD_ERR_NOTHING_TODO;
1804 }
1805
1806 ret = ipforward_off ();
1807 if (ret != 0)
1808 {
1809 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1810 return CMD_WARNING;
1811 }
1812
1813 return CMD_SUCCESS;
1814}
1815
1816/* This command is for debugging purpose. */
1817DEFUN (show_zebra_client,
1818 show_zebra_client_cmd,
1819 "show zebra client",
1820 SHOW_STR
1821 "Zebra information"
1822 "Client information")
1823{
1824 listnode node;
1825 struct zserv *client;
1826
1827 for (node = listhead (client_list); node; nextnode (node))
1828 {
1829 client = getdata (node);
1830 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1831 }
1832 return CMD_SUCCESS;
1833}
1834
1835/* Table configuration write function. */
1836int
1837config_write_table (struct vty *vty)
1838{
1839 if (rtm_table_default)
1840 vty_out (vty, "table %d%s", rtm_table_default,
1841 VTY_NEWLINE);
1842 return 0;
1843}
1844
1845/* table node for routing tables. */
1846struct cmd_node table_node =
1847{
1848 TABLE_NODE,
1849 "", /* This node has no interface. */
1850 1
1851};
1852
1853/* Only display ip forwarding is enabled or not. */
1854DEFUN (show_ip_forwarding,
1855 show_ip_forwarding_cmd,
1856 "show ip forwarding",
1857 SHOW_STR
1858 IP_STR
1859 "IP forwarding status\n")
1860{
1861 int ret;
1862
1863 ret = ipforward ();
1864
1865 if (ret == 0)
1866 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1867 else
1868 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1869 return CMD_SUCCESS;
1870}
1871
1872#ifdef HAVE_IPV6
1873/* Only display ipv6 forwarding is enabled or not. */
1874DEFUN (show_ipv6_forwarding,
1875 show_ipv6_forwarding_cmd,
1876 "show ipv6 forwarding",
1877 SHOW_STR
1878 "IPv6 information\n"
1879 "Forwarding status\n")
1880{
1881 int ret;
1882
1883 ret = ipforward_ipv6 ();
1884
1885 switch (ret)
1886 {
1887 case -1:
1888 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1889 break;
1890 case 0:
1891 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1892 break;
1893 case 1:
1894 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1895 break;
1896 default:
1897 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1898 break;
1899 }
1900 return CMD_SUCCESS;
1901}
1902
1903DEFUN (no_ipv6_forwarding,
1904 no_ipv6_forwarding_cmd,
1905 "no ipv6 forwarding",
1906 NO_STR
1907 IP_STR
1908 "Doesn't forward IPv6 protocol packet")
1909{
1910 int ret;
1911
1912 ret = ipforward_ipv6_off ();
1913 if (ret != 0)
1914 {
1915 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1916 return CMD_WARNING;
1917 }
1918
1919 return CMD_SUCCESS;
1920}
1921
1922#endif /* HAVE_IPV6 */
1923
1924/* IPForwarding configuration write function. */
1925int
1926config_write_forwarding (struct vty *vty)
1927{
1928 if (! ipforward ())
1929 vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
1930#ifdef HAVE_IPV6
1931 if (! ipforward_ipv6 ())
1932 vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
1933#endif /* HAVE_IPV6 */
1934 vty_out (vty, "!%s", VTY_NEWLINE);
1935 return 0;
1936}
1937
1938/* table node for routing tables. */
1939struct cmd_node forwarding_node =
1940{
1941 FORWARDING_NODE,
1942 "", /* This node has no interface. */
1943 1
1944};
1945
1946
1947/* Initialisation of zebra and installation of commands. */
1948void
1949zebra_init ()
1950{
1951 /* Client list init. */
1952 client_list = list_new ();
1953
1954 /* Forwarding is on by default. */
1955 ipforward_on ();
1956#ifdef HAVE_IPV6
1957 ipforward_ipv6_on ();
1958#endif /* HAVE_IPV6 */
1959
1960 /* Make zebra server socket. */
1961#ifdef HAVE_TCP_ZEBRA
1962 zebra_serv ();
1963#else
1964 zebra_serv_un (ZEBRA_SERV_PATH);
1965#endif /* HAVE_TCP_ZEBRA */
1966
1967 /* Install configuration write function. */
1968 install_node (&table_node, config_write_table);
1969 install_node (&forwarding_node, config_write_forwarding);
1970
1971 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1972 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00001973 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001974 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1975 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1976
1977#ifdef HAVE_NETLINK
1978 install_element (VIEW_NODE, &show_table_cmd);
1979 install_element (ENABLE_NODE, &show_table_cmd);
1980 install_element (CONFIG_NODE, &config_table_cmd);
1981#endif /* HAVE_NETLINK */
1982
1983#ifdef HAVE_IPV6
1984 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1985 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
1986 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1987#endif /* HAVE_IPV6 */
paulccf35572003-03-01 11:42:20 +00001988
1989 FIFO_INIT(&message_queue);
1990 t_write = NULL;
paul718e3742002-12-13 20:15:29 +00001991}