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