blob: 0f30a559bd1b2b890235a00906065d5971200130 [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"
pauledd7c242003-06-04 13:59:38 +000036#include "privs.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/zserv.h"
39#include "zebra/redistribute.h"
40#include "zebra/debug.h"
41#include "zebra/ipforward.h"
42
43/* Event list of zebra. */
44enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
45
paulb21b19c2003-06-15 01:28:29 +000046extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000047
48void zebra_event (enum event event, int sock, struct zserv *client);
paulccf35572003-03-01 11:42:20 +000049
pauledd7c242003-06-04 13:59:38 +000050extern struct zebra_privs_t zserv_privs;
paul718e3742002-12-13 20:15:29 +000051
52/* For logging of zebra meesages. */
53char *zebra_command_str [] =
54{
55 "NULL",
56 "ZEBRA_INTERFACE_ADD",
57 "ZEBRA_INTERFACE_DELETE",
58 "ZEBRA_INTERFACE_ADDRESS_ADD",
59 "ZEBRA_INTERFACE_ADDRESS_DELETE",
60 "ZEBRA_INTERFACE_UP",
61 "ZEBRA_INTERFACE_DOWN",
62 "ZEBRA_IPV4_ROUTE_ADD",
63 "ZEBRA_IPV4_ROUTE_DELETE",
64 "ZEBRA_IPV6_ROUTE_ADD",
65 "ZEBRA_IPV6_ROUTE_DELETE",
66 "ZEBRA_REDISTRIBUTE_ADD",
67 "ZEBRA_REDISTRIBUTE_DELETE",
68 "ZEBRA_REDISTRIBUTE_DEFAULT_ADD",
69 "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE",
70 "ZEBRA_IPV4_NEXTHOP_LOOKUP",
71 "ZEBRA_IPV6_NEXTHOP_LOOKUP",
72 "ZEBRA_IPV4_IMPORT_LOOKUP",
73 "ZEBRA_IPV6_IMPORT_LOOKUP"
74};
75
paulccf35572003-03-01 11:42:20 +000076struct zebra_message_queue
77{
78 struct nsm_message_queue *next;
79 struct nsm_message_queue *prev;
80
81 u_char *buf;
82 u_int16_t length;
83 u_int16_t written;
84};
85
86struct thread *t_write;
87struct fifo message_queue;
88
89int
90zebra_server_dequeue (struct thread *t)
91{
92 int sock;
93 int nbytes;
94 struct zebra_message_queue *queue;
95
96 sock = THREAD_FD (t);
97 t_write = NULL;
98
99 queue = (struct zebra_message_queue *) FIFO_HEAD (&message_queue);
100 if (queue)
101 {
102 nbytes = write (sock, queue->buf + queue->written,
103 queue->length - queue->written);
104
105 if (nbytes <= 0)
106 {
107 if (errno != EAGAIN)
108 return -1;
109 }
110 else if (nbytes != (queue->length - queue->written))
111 {
112 queue->written += nbytes;
113 }
114 else
115 {
116 FIFO_DEL (queue);
117 XFREE (MTYPE_TMP, queue->buf);
118 XFREE (MTYPE_TMP, queue);
119 }
120 }
121
122 if (FIFO_TOP (&message_queue))
paulb21b19c2003-06-15 01:28:29 +0000123 THREAD_WRITE_ON (zebrad.master, t_write, zebra_server_dequeue,
124 NULL, sock);
paulccf35572003-03-01 11:42:20 +0000125
126 return 0;
127}
128
129/* Enqueu message. */
130void
131zebra_server_enqueue (int sock, u_char *buf, unsigned long length,
132 unsigned long written)
133{
134 struct zebra_message_queue *queue;
135
136 queue = XCALLOC (MTYPE_TMP, sizeof (struct zebra_message_queue));
137 queue->buf = XMALLOC (MTYPE_TMP, length);
138 memcpy (queue->buf, buf, length);
139 queue->length = length;
140 queue->written = written;
141
142 FIFO_ADD (&message_queue, queue);
143
paulb21b19c2003-06-15 01:28:29 +0000144 THREAD_WRITE_ON (zebrad.master, t_write, zebra_server_dequeue, NULL, sock);
paulccf35572003-03-01 11:42:20 +0000145}
146
147int
148zebra_server_send_message (int sock, u_char *buf, unsigned long length)
149{
150 int nbytes;
151
152 if (FIFO_TOP (&message_queue))
153 {
154 zebra_server_enqueue (sock, buf, length, 0);
155 return 0;
156 }
157
158 /* Send message. */
159 nbytes = write (sock, buf, length);
160
161 if (nbytes <= 0)
162 {
163 if (errno == EAGAIN)
164 zebra_server_enqueue (sock, buf, length, 0);
165 else
166 return -1;
167 }
168 else if (nbytes != length)
169 zebra_server_enqueue (sock, buf, length, nbytes);
170
171 return 0;
172}
173
paul718e3742002-12-13 20:15:29 +0000174/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
175int
176zsend_interface_add (struct zserv *client, struct interface *ifp)
177{
178 struct stream *s;
179
180 /* Check this client need interface information. */
181 if (! client->ifinfo)
182 return -1;
183
184 s = client->obuf;
185 stream_reset (s);
186
187 /* Place holder for size. */
188 stream_putw (s, 0);
189
190 /* Message type. */
191 stream_putc (s, ZEBRA_INTERFACE_ADD);
192
193 /* Interface information. */
194 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
195 stream_putl (s, ifp->ifindex);
paul2e3b2e42002-12-13 21:03:13 +0000196 stream_putc (s, ifp->status);
paul718e3742002-12-13 20:15:29 +0000197 stream_putl (s, ifp->flags);
198 stream_putl (s, ifp->metric);
199 stream_putl (s, ifp->mtu);
200 stream_putl (s, ifp->bandwidth);
201#ifdef HAVE_SOCKADDR_DL
202 stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
203#else
204 stream_putl (s, ifp->hw_addr_len);
205 if (ifp->hw_addr_len)
206 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
207#endif /* HAVE_SOCKADDR_DL */
208
209 /* Write packet size. */
210 stream_putw_at (s, 0, stream_get_endp (s));
211
paulccf35572003-03-01 11:42:20 +0000212 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
213
214 return 0;
paul718e3742002-12-13 20:15:29 +0000215}
216
217/* Interface deletion from zebra daemon. */
218int
219zsend_interface_delete (struct zserv *client, struct interface *ifp)
220{
221 struct stream *s;
222
223 /* Check this client need interface information. */
224 if (! client->ifinfo)
225 return -1;
226
227 s = client->obuf;
228 stream_reset (s);
229
230 /* Packet length placeholder. */
231 stream_putw (s, 0);
232
233 /* Interface information. */
234 stream_putc (s, ZEBRA_INTERFACE_DELETE);
235 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
236 stream_putl (s, ifp->ifindex);
paul2e3b2e42002-12-13 21:03:13 +0000237 stream_putc (s, ifp->status);
paul718e3742002-12-13 20:15:29 +0000238 stream_putl (s, ifp->flags);
239 stream_putl (s, ifp->metric);
240 stream_putl (s, ifp->mtu);
241 stream_putl (s, ifp->bandwidth);
242
243 /* Write packet length. */
244 stream_putw_at (s, 0, stream_get_endp (s));
245
paulccf35572003-03-01 11:42:20 +0000246 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
247
248 return 0;
paul718e3742002-12-13 20:15:29 +0000249}
250
251/* Interface address is added. Send ZEBRA_INTERFACE_ADDRESS_ADD to the
252 client. */
253int
254zsend_interface_address_add (struct zserv *client, struct interface *ifp,
255 struct connected *ifc)
256{
257 int blen;
258 struct stream *s;
259 struct prefix *p;
260
261 /* Check this client need interface information. */
262 if (! client->ifinfo)
263 return -1;
264
265 s = client->obuf;
266 stream_reset (s);
267
268 /* Place holder for size. */
269 stream_putw (s, 0);
270
271 stream_putc (s, ZEBRA_INTERFACE_ADDRESS_ADD);
272 stream_putl (s, ifp->ifindex);
273
274 /* Interface address flag. */
275 stream_putc (s, ifc->flags);
276
277 /* Prefix information. */
278 p = ifc->address;
279 stream_putc (s, p->family);
280 blen = prefix_blen (p);
281 stream_put (s, &p->u.prefix, blen);
282 stream_putc (s, p->prefixlen);
283
284 /* Destination. */
285 p = ifc->destination;
286 if (p)
287 stream_put (s, &p->u.prefix, blen);
288 else
289 stream_put (s, NULL, blen);
290
291 /* Write packet size. */
292 stream_putw_at (s, 0, stream_get_endp (s));
293
paulccf35572003-03-01 11:42:20 +0000294 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
295
296 return 0;
paul718e3742002-12-13 20:15:29 +0000297}
298
299/* Interface address is deleted. Send ZEBRA_INTERFACE_ADDRESS_DELETE
300 to the client. */
301int
302zsend_interface_address_delete (struct zserv *client, struct interface *ifp,
303 struct connected *ifc)
304{
305 int blen;
306 struct stream *s;
307 struct prefix *p;
308
309 /* Check this client need interface information. */
310 if (! client->ifinfo)
311 return -1;
312
313 s = client->obuf;
314 stream_reset (s);
315
316 /* Place holder for size. */
317 stream_putw (s, 0);
318
319 stream_putc (s, ZEBRA_INTERFACE_ADDRESS_DELETE);
320 stream_putl (s, ifp->ifindex);
321
322 /* Interface address flag. */
323 stream_putc (s, ifc->flags);
324
325 /* Prefix information. */
326 p = ifc->address;
327 stream_putc (s, p->family);
328 blen = prefix_blen (p);
329 stream_put (s, &p->u.prefix, blen);
330
331 p = ifc->destination;
332 if (p)
333 stream_put (s, &p->u.prefix, blen);
334 else
335 stream_put (s, NULL, blen);
336
337 /* Write packet size. */
338 stream_putw_at (s, 0, stream_get_endp (s));
339
paulccf35572003-03-01 11:42:20 +0000340 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
341
342 return 0;
paul718e3742002-12-13 20:15:29 +0000343}
344
345int
346zsend_interface_up (struct zserv *client, struct interface *ifp)
347{
348 struct stream *s;
349
350 /* Check this client need interface information. */
351 if (! client->ifinfo)
352 return -1;
353
354 s = client->obuf;
355 stream_reset (s);
356
357 /* Place holder for size. */
358 stream_putw (s, 0);
359
360 /* Zebra command. */
361 stream_putc (s, ZEBRA_INTERFACE_UP);
362
363 /* Interface information. */
364 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
365 stream_putl (s, ifp->ifindex);
paul2e3b2e42002-12-13 21:03:13 +0000366 stream_putc (s, ifp->status);
paul718e3742002-12-13 20:15:29 +0000367 stream_putl (s, ifp->flags);
368 stream_putl (s, ifp->metric);
369 stream_putl (s, ifp->mtu);
370 stream_putl (s, ifp->bandwidth);
371
372 /* Write packet size. */
373 stream_putw_at (s, 0, stream_get_endp (s));
374
paulccf35572003-03-01 11:42:20 +0000375 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
376
377 return 0;
paul718e3742002-12-13 20:15:29 +0000378}
379
380int
381zsend_interface_down (struct zserv *client, struct interface *ifp)
382{
383 struct stream *s;
384
385 /* Check this client need interface information. */
386 if (! client->ifinfo)
387 return -1;
388
389 s = client->obuf;
390 stream_reset (s);
391
392 /* Place holder for size. */
393 stream_putw (s, 0);
394
395 /* Zebra command. */
396 stream_putc (s, ZEBRA_INTERFACE_DOWN);
397
398 /* Interface information. */
399 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
400 stream_putl (s, ifp->ifindex);
paul2e3b2e42002-12-13 21:03:13 +0000401 stream_putc (s, ifp->status);
paul718e3742002-12-13 20:15:29 +0000402 stream_putl (s, ifp->flags);
403 stream_putl (s, ifp->metric);
404 stream_putl (s, ifp->mtu);
405 stream_putl (s, ifp->bandwidth);
406
407 /* Write packet size. */
408 stream_putw_at (s, 0, stream_get_endp (s));
409
paulccf35572003-03-01 11:42:20 +0000410 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
411
412 return 0;
paul718e3742002-12-13 20:15:29 +0000413}
414
415int
416zsend_ipv4_add_multipath (struct zserv *client, struct prefix *p,
417 struct rib *rib)
418{
419 int psize;
420 struct stream *s;
421 struct nexthop *nexthop;
422 struct in_addr empty;
423
424 empty.s_addr = 0;
425 s = client->obuf;
426 stream_reset (s);
427
428 /* Place holder for size. */
429 stream_putw (s, 0);
430
431 /* Put command, type and nexthop. */
432 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
433 stream_putc (s, rib->type);
434 stream_putc (s, rib->flags);
435 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC);
436
437 /* Prefix. */
438 psize = PSIZE (p->prefixlen);
439 stream_putc (s, p->prefixlen);
440 stream_write (s, (u_char *)&p->u.prefix, psize);
441
442 /* Nexthop */
443 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
444 {
445 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
446 {
447 stream_putc (s, 1);
448
hasso726f9b22003-05-25 21:04:54 +0000449 /* XXX: Waht's about NEXTHOP_TYPE_IPV4_IFNAME ? */
paul718e3742002-12-13 20:15:29 +0000450 if (nexthop->type == NEXTHOP_TYPE_IPV4
451 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
452 stream_put_in_addr (s, &nexthop->gate.ipv4);
453 else
454 stream_put_in_addr (s, &empty);
455
456 /* Interface index. */
457 stream_putc (s, 1);
458 stream_putl (s, nexthop->ifindex);
459
460 break;
461 }
462 }
463
464 /* Metric */
465 stream_putl (s, rib->metric);
466
467 /* Write packet size. */
468 stream_putw_at (s, 0, stream_get_endp (s));
469
paulccf35572003-03-01 11:42:20 +0000470 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
471
472 return 0;
paul718e3742002-12-13 20:15:29 +0000473}
474
475int
476zsend_ipv4_delete_multipath (struct zserv *client, struct prefix *p,
477 struct rib *rib)
478{
479 int psize;
480 struct stream *s;
481 struct nexthop *nexthop;
482 struct in_addr empty;
483
484 empty.s_addr = 0;
485
486 s = client->obuf;
487 stream_reset (s);
488
489 /* Place holder for size. */
490 stream_putw (s, 0);
491
492 /* Put command, type and nexthop. */
493 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
494 stream_putc (s, rib->type);
495 stream_putc (s, rib->flags);
496 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
497
498 /* Prefix. */
499 psize = PSIZE (p->prefixlen);
500 stream_putc (s, p->prefixlen);
501 stream_write (s, (u_char *)&p->u.prefix, psize);
502
503 /* Nexthop */
504 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
505 {
506 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
507 {
508 stream_putc (s, 1);
509
510 if (nexthop->type == NEXTHOP_TYPE_IPV4)
511 stream_put_in_addr (s, &nexthop->gate.ipv4);
512 else
513 stream_put_in_addr (s, &empty);
514
515 /* Interface index. */
516 stream_putc (s, 1);
517 stream_putl (s, nexthop->ifindex);
518
519 break;
520 }
521 }
522
523 /* Write packet size. */
524 stream_putw_at (s, 0, stream_get_endp (s));
525
paulccf35572003-03-01 11:42:20 +0000526 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
527
528 return 0;
paul718e3742002-12-13 20:15:29 +0000529}
530
hasso726f9b22003-05-25 21:04:54 +0000531#if 0
532#warning oldies
paul718e3742002-12-13 20:15:29 +0000533int
534zsend_ipv4_add (struct zserv *client, int type, int flags,
535 struct prefix_ipv4 *p, struct in_addr *nexthop,
536 unsigned int ifindex)
537{
538 int psize;
539 struct stream *s;
540
541 s = client->obuf;
542 stream_reset (s);
543
544 /* Place holder for size. */
545 stream_putw (s, 0);
546
547 /* Put command, type and nexthop. */
548 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
549 stream_putc (s, type);
550 stream_putc (s, flags);
551 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
552
553 /* Prefix. */
554 psize = PSIZE (p->prefixlen);
555 stream_putc (s, p->prefixlen);
556 stream_write (s, (u_char *)&p->prefix, psize);
557
558 /* Nexthop */
559 stream_putc (s, 1);
560 stream_put_in_addr (s, nexthop);
561
562 /* Interface index. */
563 stream_putc (s, 1);
564 stream_putl (s, ifindex);
565
566 /* Write packet size. */
567 stream_putw_at (s, 0, stream_get_endp (s));
568
paulccf35572003-03-01 11:42:20 +0000569 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
570
571 return 0;
paul718e3742002-12-13 20:15:29 +0000572}
573
574int
575zsend_ipv4_delete (struct zserv *client, int type, int flags,
576 struct prefix_ipv4 *p, struct in_addr *nexthop,
577 unsigned int ifindex)
578{
579 int psize;
580 struct stream *s;
581
582 s = client->obuf;
583 stream_reset (s);
584
585 /* Place holder for size. */
586 stream_putw (s, 0);
587
588 /* Put command, type and nexthop. */
589 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
590 stream_putc (s, type);
591 stream_putc (s, flags);
592 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
593
594 /* Prefix. */
595 psize = PSIZE (p->prefixlen);
596 stream_putc (s, p->prefixlen);
597 stream_write (s, (u_char *)&p->prefix, psize);
598
599 /* Nexthop */
600 stream_putc (s, 1);
601 stream_put_in_addr (s, nexthop);
602
603 /* Interface index. */
604 stream_putc (s, 1);
605 stream_putl (s, ifindex);
606
607 /* Write packet size. */
608 stream_putw_at (s, 0, stream_get_endp (s));
609
paulccf35572003-03-01 11:42:20 +0000610 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
611
612 return 0;
paul718e3742002-12-13 20:15:29 +0000613}
hasso726f9b22003-05-25 21:04:54 +0000614#endif /* oldies */
paul718e3742002-12-13 20:15:29 +0000615
616#ifdef HAVE_IPV6
hasso726f9b22003-05-25 21:04:54 +0000617#if 0
618#warning oldies
paul718e3742002-12-13 20:15:29 +0000619int
620zsend_ipv6_add (struct zserv *client, int type, int flags,
621 struct prefix_ipv6 *p, struct in6_addr *nexthop,
622 unsigned int ifindex)
623{
624 int psize;
625 struct stream *s;
626
627 s = client->obuf;
628 stream_reset (s);
629
630 /* Place holder for size. */
631 stream_putw (s, 0);
632
633 /* Put command, type and nexthop. */
634 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
635 stream_putc (s, type);
636 stream_putc (s, flags);
637 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
638
639 /* Prefix. */
640 psize = PSIZE (p->prefixlen);
641 stream_putc (s, p->prefixlen);
642 stream_write (s, (u_char *)&p->prefix, psize);
643
644 /* Nexthop */
645 stream_putc (s, 1);
646 stream_write (s, (u_char *)nexthop, 16);
647
648 /* Interface index. */
649 stream_putc (s, 1);
650 stream_putl (s, ifindex);
651
652 /* Write packet size. */
653 stream_putw_at (s, 0, stream_get_endp (s));
654
paulccf35572003-03-01 11:42:20 +0000655 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
656
657 return 0;
paul718e3742002-12-13 20:15:29 +0000658}
hasso726f9b22003-05-25 21:04:54 +0000659#endif /* oldies */
paul718e3742002-12-13 20:15:29 +0000660
661int
662zsend_ipv6_add_multipath (struct zserv *client, struct prefix *p,
663 struct rib *rib)
664{
665 int psize;
666 struct stream *s;
667 struct nexthop *nexthop;
668 struct in6_addr empty;
669
670 memset (&empty, 0, sizeof (struct in6_addr));
671 s = client->obuf;
672 stream_reset (s);
673
674 /* Place holder for size. */
675 stream_putw (s, 0);
676
677 /* Put command, type and nexthop. */
678 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
679 stream_putc (s, rib->type);
680 stream_putc (s, rib->flags);
681 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC);
682
683 /* Prefix. */
684 psize = PSIZE (p->prefixlen);
685 stream_putc (s, p->prefixlen);
686 stream_write (s, (u_char *) &p->u.prefix, psize);
687
688 /* Nexthop */
689 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
690 {
691 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
692 {
693 stream_putc (s, 1);
694
hasso726f9b22003-05-25 21:04:54 +0000695 if (nexthop->type == NEXTHOP_TYPE_IPV6
696 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
697 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
paul718e3742002-12-13 20:15:29 +0000698 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
699 else
700 stream_write (s, (u_char *) &empty, 16);
701
702 /* Interface index. */
703 stream_putc (s, 1);
704 stream_putl (s, nexthop->ifindex);
705
706 break;
707 }
708 }
709
710 /* Metric */
711 stream_putl (s, rib->metric);
712
713 /* Write packet size. */
714 stream_putw_at (s, 0, stream_get_endp (s));
715
paulccf35572003-03-01 11:42:20 +0000716 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
717
718 return 0;
paul718e3742002-12-13 20:15:29 +0000719}
720
hasso726f9b22003-05-25 21:04:54 +0000721#if 0
722#warning oldies
paul718e3742002-12-13 20:15:29 +0000723int
724zsend_ipv6_delete (struct zserv *client, int type, int flags,
725 struct prefix_ipv6 *p, struct in6_addr *nexthop,
726 unsigned int ifindex)
727{
728 int psize;
729 struct stream *s;
730
731 s = client->obuf;
732 stream_reset (s);
733
734 /* Place holder for size. */
735 stream_putw (s, 0);
736
737 /* Put command, type and nexthop. */
738 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
739 stream_putc (s, type);
740 stream_putc (s, flags);
741 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
742
743 /* Prefix. */
744 psize = PSIZE (p->prefixlen);
745 stream_putc (s, p->prefixlen);
746 stream_write (s, (u_char *)&p->prefix, psize);
747
748 /* Nexthop */
749 stream_putc (s, 1);
750 stream_write (s, (u_char *)nexthop, 16);
751
752 /* Interface index. */
753 stream_putc (s, 1);
754 stream_putl (s, ifindex);
755
756 /* Write packet size. */
757 stream_putw_at (s, 0, stream_get_endp (s));
758
paulccf35572003-03-01 11:42:20 +0000759 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
760
761 return 0;
paul718e3742002-12-13 20:15:29 +0000762}
hasso726f9b22003-05-25 21:04:54 +0000763#endif /* oldies */
paul718e3742002-12-13 20:15:29 +0000764
765int
766zsend_ipv6_delete_multipath (struct zserv *client, struct prefix *p,
767 struct rib *rib)
768{
769 int psize;
770 struct stream *s;
771 struct nexthop *nexthop;
772 struct in6_addr empty;
773
774 memset (&empty, 0, sizeof (struct in6_addr));
775 s = client->obuf;
776 stream_reset (s);
777
778 /* Place holder for size. */
779 stream_putw (s, 0);
780
781 /* Put command, type and nexthop. */
782 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
783 stream_putc (s, rib->type);
784 stream_putc (s, rib->flags);
785 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);
786
787 /* Prefix. */
788 psize = PSIZE (p->prefixlen);
789 stream_putc (s, p->prefixlen);
790 stream_write (s, (u_char *)&p->u.prefix, psize);
791
792 /* Nexthop */
793 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
794 {
795 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
796 {
797 stream_putc (s, 1);
798
799 if (nexthop->type == NEXTHOP_TYPE_IPV6)
800 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
801 else
802 stream_write (s, (u_char *) &empty, 16);
803
804 /* Interface index. */
805 stream_putc (s, 1);
806 stream_putl (s, nexthop->ifindex);
807
808 break;
809 }
810 }
811
812 /* Write packet size. */
813 stream_putw_at (s, 0, stream_get_endp (s));
814
paulccf35572003-03-01 11:42:20 +0000815 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
816
817 return 0;
paul718e3742002-12-13 20:15:29 +0000818}
819
820int
821zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
822{
823 struct stream *s;
824 struct rib *rib;
825 unsigned long nump;
826 u_char num;
827 struct nexthop *nexthop;
828
829 /* Lookup nexthop. */
830 rib = rib_match_ipv6 (addr);
831
832 /* Get output stream. */
833 s = client->obuf;
834 stream_reset (s);
835
836 /* Fill in result. */
837 stream_putw (s, 0);
838 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
839 stream_put (s, &addr, 16);
840
841 if (rib)
842 {
843 stream_putl (s, rib->metric);
844 num = 0;
845 nump = s->putp;
846 stream_putc (s, 0);
847 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
848 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
849 {
850 stream_putc (s, nexthop->type);
851 switch (nexthop->type)
852 {
853 case ZEBRA_NEXTHOP_IPV6:
854 stream_put (s, &nexthop->gate.ipv6, 16);
855 break;
856 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
857 case ZEBRA_NEXTHOP_IPV6_IFNAME:
858 stream_put (s, &nexthop->gate.ipv6, 16);
859 stream_putl (s, nexthop->ifindex);
860 break;
861 case ZEBRA_NEXTHOP_IFINDEX:
862 case ZEBRA_NEXTHOP_IFNAME:
863 stream_putl (s, nexthop->ifindex);
864 break;
865 }
866 num++;
867 }
868 stream_putc_at (s, nump, num);
869 }
870 else
871 {
872 stream_putl (s, 0);
873 stream_putc (s, 0);
874 }
875
876 stream_putw_at (s, 0, stream_get_endp (s));
877
paulccf35572003-03-01 11:42:20 +0000878 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
879
880 return 0;
paul718e3742002-12-13 20:15:29 +0000881}
882#endif /* HAVE_IPV6 */
883
884int
885zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
886{
887 struct stream *s;
888 struct rib *rib;
889 unsigned long nump;
890 u_char num;
891 struct nexthop *nexthop;
892
893 /* Lookup nexthop. */
894 rib = rib_match_ipv4 (addr);
895
896 /* Get output stream. */
897 s = client->obuf;
898 stream_reset (s);
899
900 /* Fill in result. */
901 stream_putw (s, 0);
902 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
903 stream_put_in_addr (s, &addr);
904
905 if (rib)
906 {
907 stream_putl (s, rib->metric);
908 num = 0;
909 nump = s->putp;
910 stream_putc (s, 0);
911 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
912 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
913 {
914 stream_putc (s, nexthop->type);
915 switch (nexthop->type)
916 {
917 case ZEBRA_NEXTHOP_IPV4:
918 stream_put_in_addr (s, &nexthop->gate.ipv4);
919 break;
920 case ZEBRA_NEXTHOP_IFINDEX:
921 case ZEBRA_NEXTHOP_IFNAME:
922 stream_putl (s, nexthop->ifindex);
923 break;
924 }
925 num++;
926 }
927 stream_putc_at (s, nump, num);
928 }
929 else
930 {
931 stream_putl (s, 0);
932 stream_putc (s, 0);
933 }
934
935 stream_putw_at (s, 0, stream_get_endp (s));
936
paulccf35572003-03-01 11:42:20 +0000937 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
938
939 return 0;
paul718e3742002-12-13 20:15:29 +0000940}
941
942int
943zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
944{
945 struct stream *s;
946 struct rib *rib;
947 unsigned long nump;
948 u_char num;
949 struct nexthop *nexthop;
950
951 /* Lookup nexthop. */
952 rib = rib_lookup_ipv4 (p);
953
954 /* Get output stream. */
955 s = client->obuf;
956 stream_reset (s);
957
958 /* Fill in result. */
959 stream_putw (s, 0);
960 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
961 stream_put_in_addr (s, &p->prefix);
962
963 if (rib)
964 {
965 stream_putl (s, rib->metric);
966 num = 0;
967 nump = s->putp;
968 stream_putc (s, 0);
969 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
970 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
971 {
972 stream_putc (s, nexthop->type);
973 switch (nexthop->type)
974 {
975 case ZEBRA_NEXTHOP_IPV4:
976 stream_put_in_addr (s, &nexthop->gate.ipv4);
977 break;
978 case ZEBRA_NEXTHOP_IFINDEX:
979 case ZEBRA_NEXTHOP_IFNAME:
980 stream_putl (s, nexthop->ifindex);
981 break;
982 }
983 num++;
984 }
985 stream_putc_at (s, nump, num);
986 }
987 else
988 {
989 stream_putl (s, 0);
990 stream_putc (s, 0);
991 }
992
993 stream_putw_at (s, 0, stream_get_endp (s));
994
paulccf35572003-03-01 11:42:20 +0000995 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
996
997 return 0;
paul718e3742002-12-13 20:15:29 +0000998}
999
1000/* Register zebra server interface information. Send current all
1001 interface and address information. */
1002void
1003zread_interface_add (struct zserv *client, u_short length)
1004{
1005 listnode ifnode;
1006 listnode cnode;
1007 struct interface *ifp;
1008 struct connected *c;
1009
1010 /* Interface information is needed. */
1011 client->ifinfo = 1;
1012
1013 for (ifnode = listhead (iflist); ifnode; ifnode = nextnode (ifnode))
1014 {
1015 ifp = getdata (ifnode);
1016
1017 /* Skip pseudo interface. */
1018 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1019 continue;
1020
1021 zsend_interface_add (client, ifp);
1022
1023 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
1024 {
1025 c = getdata (cnode);
1026 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
1027 zsend_interface_address_add (client, ifp, c);
1028 }
1029 }
1030}
1031
1032/* Unregister zebra server interface information. */
1033void
1034zread_interface_delete (struct zserv *client, u_short length)
1035{
1036 client->ifinfo = 0;
1037}
1038
1039/* This function support multiple nexthop. */
1040void
1041zread_ipv4_add (struct zserv *client, u_short length)
1042{
1043 int i;
1044 struct rib *rib;
1045 struct prefix_ipv4 p;
1046 u_char message;
1047 struct in_addr nexthop;
1048 u_char nexthop_num;
1049 u_char nexthop_type;
1050 struct stream *s;
1051 unsigned int ifindex;
1052 u_char ifname_len;
1053
1054 /* Get input stream. */
1055 s = client->ibuf;
1056
1057 /* Allocate new rib. */
1058 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1059 memset (rib, 0, sizeof (struct rib));
1060
1061 /* Type, flags, message. */
1062 rib->type = stream_getc (s);
1063 rib->flags = stream_getc (s);
1064 message = stream_getc (s);
1065 rib->uptime = time (NULL);
1066
1067 /* IPv4 prefix. */
1068 memset (&p, 0, sizeof (struct prefix_ipv4));
1069 p.family = AF_INET;
1070 p.prefixlen = stream_getc (s);
1071 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1072
1073 /* Nexthop parse. */
1074 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1075 {
1076 nexthop_num = stream_getc (s);
1077
1078 for (i = 0; i < nexthop_num; i++)
1079 {
1080 nexthop_type = stream_getc (s);
1081
1082 switch (nexthop_type)
1083 {
1084 case ZEBRA_NEXTHOP_IFINDEX:
1085 ifindex = stream_getl (s);
1086 nexthop_ifindex_add (rib, ifindex);
1087 break;
1088 case ZEBRA_NEXTHOP_IFNAME:
1089 ifname_len = stream_getc (s);
1090 stream_forward (s, ifname_len);
1091 break;
1092 case ZEBRA_NEXTHOP_IPV4:
1093 nexthop.s_addr = stream_get_ipv4 (s);
1094 nexthop_ipv4_add (rib, &nexthop);
1095 break;
1096 case ZEBRA_NEXTHOP_IPV6:
1097 stream_forward (s, IPV6_MAX_BYTELEN);
1098 break;
paul595db7f2003-05-25 21:35:06 +00001099 case ZEBRA_NEXTHOP_BLACKHOLE:
1100 nexthop_blackhole_add (rib);
1101 break;
paul718e3742002-12-13 20:15:29 +00001102 }
1103 }
1104 }
1105
1106 /* Distance. */
1107 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1108 rib->distance = stream_getc (s);
1109
1110 /* Metric. */
1111 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1112 rib->metric = stream_getl (s);
1113
1114 rib_add_ipv4_multipath (&p, rib);
1115}
1116
1117/* Zebra server IPv4 prefix delete function. */
1118void
1119zread_ipv4_delete (struct zserv *client, u_short length)
1120{
1121 int i;
1122 struct stream *s;
1123 struct zapi_ipv4 api;
1124 struct in_addr nexthop;
1125 unsigned long ifindex;
1126 struct prefix_ipv4 p;
1127 u_char nexthop_num;
1128 u_char nexthop_type;
1129 u_char ifname_len;
1130
1131 s = client->ibuf;
1132 ifindex = 0;
1133 nexthop.s_addr = 0;
1134
1135 /* Type, flags, message. */
1136 api.type = stream_getc (s);
1137 api.flags = stream_getc (s);
1138 api.message = stream_getc (s);
1139
1140 /* IPv4 prefix. */
1141 memset (&p, 0, sizeof (struct prefix_ipv4));
1142 p.family = AF_INET;
1143 p.prefixlen = stream_getc (s);
1144 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1145
1146 /* Nexthop, ifindex, distance, metric. */
1147 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1148 {
1149 nexthop_num = stream_getc (s);
1150
1151 for (i = 0; i < nexthop_num; i++)
1152 {
1153 nexthop_type = stream_getc (s);
1154
1155 switch (nexthop_type)
1156 {
1157 case ZEBRA_NEXTHOP_IFINDEX:
1158 ifindex = stream_getl (s);
1159 break;
1160 case ZEBRA_NEXTHOP_IFNAME:
1161 ifname_len = stream_getc (s);
1162 stream_forward (s, ifname_len);
1163 break;
1164 case ZEBRA_NEXTHOP_IPV4:
1165 nexthop.s_addr = stream_get_ipv4 (s);
1166 break;
1167 case ZEBRA_NEXTHOP_IPV6:
1168 stream_forward (s, IPV6_MAX_BYTELEN);
1169 break;
1170 }
1171 }
1172 }
1173
1174 /* Distance. */
1175 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1176 api.distance = stream_getc (s);
1177 else
1178 api.distance = 0;
1179
1180 /* Metric. */
1181 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1182 api.metric = stream_getl (s);
1183 else
1184 api.metric = 0;
1185
1186 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
1187 client->rtm_table);
1188}
1189
1190/* Nexthop lookup for IPv4. */
1191void
1192zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
1193{
1194 struct in_addr addr;
1195
1196 addr.s_addr = stream_get_ipv4 (client->ibuf);
1197 zsend_ipv4_nexthop_lookup (client, addr);
1198}
1199
1200/* Nexthop lookup for IPv4. */
1201void
1202zread_ipv4_import_lookup (struct zserv *client, u_short length)
1203{
1204 struct prefix_ipv4 p;
1205
1206 p.family = AF_INET;
1207 p.prefixlen = stream_getc (client->ibuf);
1208 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1209
1210 zsend_ipv4_import_lookup (client, &p);
1211}
1212
1213#ifdef HAVE_IPV6
1214/* Zebra server IPv6 prefix add function. */
1215void
1216zread_ipv6_add (struct zserv *client, u_short length)
1217{
1218 int i;
1219 struct stream *s;
1220 struct zapi_ipv6 api;
1221 struct in6_addr nexthop;
1222 unsigned long ifindex;
1223 struct prefix_ipv6 p;
1224
1225 s = client->ibuf;
1226 ifindex = 0;
1227 memset (&nexthop, 0, sizeof (struct in6_addr));
1228
1229 /* Type, flags, message. */
1230 api.type = stream_getc (s);
1231 api.flags = stream_getc (s);
1232 api.message = stream_getc (s);
1233
1234 /* IPv4 prefix. */
1235 memset (&p, 0, sizeof (struct prefix_ipv6));
1236 p.family = AF_INET6;
1237 p.prefixlen = stream_getc (s);
1238 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1239
1240 /* Nexthop, ifindex, distance, metric. */
1241 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1242 {
1243 u_char nexthop_type;
1244
1245 api.nexthop_num = stream_getc (s);
1246 for (i = 0; i < api.nexthop_num; i++)
1247 {
1248 nexthop_type = stream_getc (s);
1249
1250 switch (nexthop_type)
1251 {
1252 case ZEBRA_NEXTHOP_IPV6:
1253 stream_get (&nexthop, s, 16);
1254 break;
1255 case ZEBRA_NEXTHOP_IFINDEX:
1256 ifindex = stream_getl (s);
1257 break;
1258 }
1259 }
1260 }
1261
1262 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1263 api.distance = stream_getc (s);
1264 else
1265 api.distance = 0;
1266
1267 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1268 api.metric = stream_getl (s);
1269 else
1270 api.metric = 0;
1271
1272 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1273 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1274 else
1275 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1276}
1277
1278/* Zebra server IPv6 prefix delete function. */
1279void
1280zread_ipv6_delete (struct zserv *client, u_short length)
1281{
1282 int i;
1283 struct stream *s;
1284 struct zapi_ipv6 api;
1285 struct in6_addr nexthop;
1286 unsigned long ifindex;
1287 struct prefix_ipv6 p;
1288
1289 s = client->ibuf;
1290 ifindex = 0;
1291 memset (&nexthop, 0, sizeof (struct in6_addr));
1292
1293 /* Type, flags, message. */
1294 api.type = stream_getc (s);
1295 api.flags = stream_getc (s);
1296 api.message = stream_getc (s);
1297
1298 /* IPv4 prefix. */
1299 memset (&p, 0, sizeof (struct prefix_ipv6));
1300 p.family = AF_INET6;
1301 p.prefixlen = stream_getc (s);
1302 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1303
1304 /* Nexthop, ifindex, distance, metric. */
1305 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1306 {
1307 u_char nexthop_type;
1308
1309 api.nexthop_num = stream_getc (s);
1310 for (i = 0; i < api.nexthop_num; i++)
1311 {
1312 nexthop_type = stream_getc (s);
1313
1314 switch (nexthop_type)
1315 {
1316 case ZEBRA_NEXTHOP_IPV6:
1317 stream_get (&nexthop, s, 16);
1318 break;
1319 case ZEBRA_NEXTHOP_IFINDEX:
1320 ifindex = stream_getl (s);
1321 break;
1322 }
1323 }
1324 }
1325
1326 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1327 api.distance = stream_getc (s);
1328 else
1329 api.distance = 0;
1330 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1331 api.metric = stream_getl (s);
1332 else
1333 api.metric = 0;
1334
1335 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1336 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1337 else
1338 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1339}
1340
1341void
1342zebra_read_ipv6 (int command, struct zserv *client, u_short length)
1343{
1344 u_char type;
1345 u_char flags;
1346 struct in6_addr nexthop, *gate;
1347 u_char *lim;
1348 u_char *pnt;
1349 unsigned int ifindex;
1350
1351 pnt = stream_pnt (client->ibuf);
1352 lim = pnt + length;
1353
1354 type = stream_getc (client->ibuf);
1355 flags = stream_getc (client->ibuf);
1356 stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr));
1357
1358 while (stream_pnt (client->ibuf) < lim)
1359 {
1360 int size;
1361 struct prefix_ipv6 p;
1362
1363 ifindex = stream_getl (client->ibuf);
1364
1365 memset (&p, 0, sizeof (struct prefix_ipv6));
1366 p.family = AF_INET6;
1367 p.prefixlen = stream_getc (client->ibuf);
1368 size = PSIZE(p.prefixlen);
1369 stream_get (&p.prefix, client->ibuf, size);
1370
1371 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1372 gate = NULL;
1373 else
1374 gate = &nexthop;
1375
1376 if (command == ZEBRA_IPV6_ROUTE_ADD)
1377 rib_add_ipv6 (type, flags, &p, gate, ifindex, 0);
1378 else
1379 rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);
1380 }
1381}
1382
1383void
1384zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1385{
1386 struct in6_addr addr;
1387 char buf[BUFSIZ];
1388
1389 stream_get (&addr, client->ibuf, 16);
1390 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1391
1392 zsend_ipv6_nexthop_lookup (client, &addr);
1393}
1394#endif /* HAVE_IPV6 */
1395
1396/* Close zebra client. */
1397void
1398zebra_client_close (struct zserv *client)
1399{
1400 /* Close file descriptor. */
1401 if (client->sock)
1402 {
1403 close (client->sock);
1404 client->sock = -1;
1405 }
1406
1407 /* Free stream buffers. */
1408 if (client->ibuf)
1409 stream_free (client->ibuf);
1410 if (client->obuf)
1411 stream_free (client->obuf);
1412
1413 /* Release threads. */
1414 if (client->t_read)
1415 thread_cancel (client->t_read);
1416 if (client->t_write)
1417 thread_cancel (client->t_write);
1418
1419 /* Free client structure. */
paulb21b19c2003-06-15 01:28:29 +00001420 listnode_delete (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001421 XFREE (0, client);
1422}
1423
1424/* Make new client. */
1425void
1426zebra_client_create (int sock)
1427{
1428 struct zserv *client;
1429
1430 client = XCALLOC (0, sizeof (struct zserv));
1431
1432 /* Make client input/output buffer. */
1433 client->sock = sock;
1434 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1435 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1436
1437 /* Set table number. */
paulb21b19c2003-06-15 01:28:29 +00001438 client->rtm_table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00001439
1440 /* Add this client to linked list. */
paulb21b19c2003-06-15 01:28:29 +00001441 listnode_add (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001442
1443 /* Make new read thread. */
1444 zebra_event (ZEBRA_READ, sock, client);
1445}
1446
1447/* Handler of zebra service request. */
1448int
1449zebra_client_read (struct thread *thread)
1450{
1451 int sock;
1452 struct zserv *client;
1453 int nbyte;
1454 u_short length;
1455 u_char command;
1456
1457 /* Get thread data. Reset reading thread because I'm running. */
1458 sock = THREAD_FD (thread);
1459 client = THREAD_ARG (thread);
1460 client->t_read = NULL;
1461
1462 /* Read length and command. */
1463 nbyte = stream_read (client->ibuf, sock, 3);
1464 if (nbyte <= 0)
1465 {
1466 if (IS_ZEBRA_DEBUG_EVENT)
1467 zlog_info ("connection closed socket [%d]", sock);
1468 zebra_client_close (client);
1469 return -1;
1470 }
1471 length = stream_getw (client->ibuf);
1472 command = stream_getc (client->ibuf);
1473
1474 if (length < 3)
1475 {
1476 if (IS_ZEBRA_DEBUG_EVENT)
1477 zlog_info ("length %d is less than 3 ", length);
1478 zebra_client_close (client);
1479 return -1;
1480 }
1481
1482 length -= 3;
1483
1484 /* Read rest of data. */
1485 if (length)
1486 {
1487 nbyte = stream_read (client->ibuf, sock, length);
1488 if (nbyte <= 0)
1489 {
1490 if (IS_ZEBRA_DEBUG_EVENT)
1491 zlog_info ("connection closed [%d] when reading zebra data", sock);
1492 zebra_client_close (client);
1493 return -1;
1494 }
1495 }
1496
1497 /* Debug packet information. */
1498 if (IS_ZEBRA_DEBUG_EVENT)
1499 zlog_info ("zebra message comes from socket [%d]", sock);
1500
1501 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1502 zlog_info ("zebra message received [%s] %d",
1503 zebra_command_str[command], length);
1504
1505 switch (command)
1506 {
1507 case ZEBRA_INTERFACE_ADD:
1508 zread_interface_add (client, length);
1509 break;
1510 case ZEBRA_INTERFACE_DELETE:
1511 zread_interface_delete (client, length);
1512 break;
1513 case ZEBRA_IPV4_ROUTE_ADD:
1514 zread_ipv4_add (client, length);
1515 break;
1516 case ZEBRA_IPV4_ROUTE_DELETE:
1517 zread_ipv4_delete (client, length);
1518 break;
1519#ifdef HAVE_IPV6
1520 case ZEBRA_IPV6_ROUTE_ADD:
1521 zread_ipv6_add (client, length);
1522 break;
1523 case ZEBRA_IPV6_ROUTE_DELETE:
1524 zread_ipv6_delete (client, length);
1525 break;
1526#endif /* HAVE_IPV6 */
1527 case ZEBRA_REDISTRIBUTE_ADD:
1528 zebra_redistribute_add (command, client, length);
1529 break;
1530 case ZEBRA_REDISTRIBUTE_DELETE:
1531 zebra_redistribute_delete (command, client, length);
1532 break;
1533 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1534 zebra_redistribute_default_add (command, client, length);
1535 break;
1536 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1537 zebra_redistribute_default_delete (command, client, length);
1538 break;
1539 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1540 zread_ipv4_nexthop_lookup (client, length);
1541 break;
1542#ifdef HAVE_IPV6
1543 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1544 zread_ipv6_nexthop_lookup (client, length);
1545 break;
1546#endif /* HAVE_IPV6 */
1547 case ZEBRA_IPV4_IMPORT_LOOKUP:
1548 zread_ipv4_import_lookup (client, length);
1549 break;
1550 default:
1551 zlog_info ("Zebra received unknown command %d", command);
1552 break;
1553 }
1554
1555 stream_reset (client->ibuf);
1556 zebra_event (ZEBRA_READ, sock, client);
1557
1558 return 0;
1559}
1560
1561/* Write output buffer to the socket. */
1562void
1563zebra_write (struct thread *thread)
1564{
1565 int sock;
1566 struct zserv *client;
1567
1568 /* Thread treatment. */
1569 sock = THREAD_FD (thread);
1570 client = THREAD_ARG (thread);
1571 client->t_write = NULL;
1572
1573 stream_flush (client->obuf, sock);
1574}
1575
1576/* Accept code of zebra server socket. */
1577int
1578zebra_accept (struct thread *thread)
1579{
paulccf35572003-03-01 11:42:20 +00001580 int val;
paul718e3742002-12-13 20:15:29 +00001581 int accept_sock;
1582 int client_sock;
1583 struct sockaddr_in client;
1584 socklen_t len;
1585
1586 accept_sock = THREAD_FD (thread);
1587
1588 len = sizeof (struct sockaddr_in);
1589 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1590
1591 if (client_sock < 0)
1592 {
1593 zlog_warn ("Can't accept zebra socket: %s", strerror (errno));
1594 return -1;
1595 }
1596
paulccf35572003-03-01 11:42:20 +00001597 /* Make client socket non-blocking. */
1598
1599 val = fcntl (client_sock, F_GETFL, 0);
1600 fcntl (client_sock, F_SETFL, (val | O_NONBLOCK));
1601
paul718e3742002-12-13 20:15:29 +00001602 /* Create new zebra client. */
1603 zebra_client_create (client_sock);
1604
1605 /* Register myself. */
1606 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1607
1608 return 0;
1609}
1610
1611/* Make zebra's server socket. */
1612void
1613zebra_serv ()
1614{
1615 int ret;
1616 int accept_sock;
1617 struct sockaddr_in addr;
1618
1619 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1620
1621 if (accept_sock < 0)
1622 {
1623 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1624 zlog_warn ("zebra can't provice full functionality due to above error");
1625 return;
1626 }
1627
1628 memset (&addr, 0, sizeof (struct sockaddr_in));
1629 addr.sin_family = AF_INET;
1630 addr.sin_port = htons (ZEBRA_PORT);
1631#ifdef HAVE_SIN_LEN
1632 addr.sin_len = sizeof (struct sockaddr_in);
1633#endif /* HAVE_SIN_LEN */
1634 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1635
1636 sockopt_reuseaddr (accept_sock);
1637 sockopt_reuseport (accept_sock);
1638
pauledd7c242003-06-04 13:59:38 +00001639 if ( zserv_privs.change(ZPRIVS_RAISE) )
1640 zlog (NULL, LOG_ERR, "Can't raise privileges");
1641
paul718e3742002-12-13 20:15:29 +00001642 ret = bind (accept_sock, (struct sockaddr *)&addr,
1643 sizeof (struct sockaddr_in));
1644 if (ret < 0)
1645 {
1646 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1647 zlog_warn ("zebra can't provice full functionality due to above error");
1648 close (accept_sock); /* Avoid sd leak. */
1649 return;
1650 }
pauledd7c242003-06-04 13:59:38 +00001651
1652 if ( zserv_privs.change(ZPRIVS_LOWER) )
1653 zlog (NULL, LOG_ERR, "Can't lower privileges");
paul718e3742002-12-13 20:15:29 +00001654
1655 ret = listen (accept_sock, 1);
1656 if (ret < 0)
1657 {
1658 zlog_warn ("Can't listen to socket: %s", strerror (errno));
1659 zlog_warn ("zebra can't provice full functionality due to above error");
1660 close (accept_sock); /* Avoid sd leak. */
1661 return;
1662 }
1663
1664 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1665}
1666
1667/* For sockaddr_un. */
1668#include <sys/un.h>
1669
1670/* zebra server UNIX domain socket. */
1671void
1672zebra_serv_un (char *path)
1673{
1674 int ret;
1675 int sock, len;
1676 struct sockaddr_un serv;
1677 mode_t old_mask;
1678
1679 /* First of all, unlink existing socket */
1680 unlink (path);
1681
1682 /* Set umask */
1683 old_mask = umask (0077);
1684
1685 /* Make UNIX domain socket. */
1686 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1687 if (sock < 0)
1688 {
1689 perror ("sock");
1690 return;
1691 }
1692
1693 /* Make server socket. */
1694 memset (&serv, 0, sizeof (struct sockaddr_un));
1695 serv.sun_family = AF_UNIX;
1696 strncpy (serv.sun_path, path, strlen (path));
1697#ifdef HAVE_SUN_LEN
1698 len = serv.sun_len = SUN_LEN(&serv);
1699#else
1700 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1701#endif /* HAVE_SUN_LEN */
1702
1703 ret = bind (sock, (struct sockaddr *) &serv, len);
1704 if (ret < 0)
1705 {
1706 perror ("bind");
1707 close (sock);
1708 return;
1709 }
1710
1711 ret = listen (sock, 5);
1712 if (ret < 0)
1713 {
1714 perror ("listen");
1715 close (sock);
1716 return;
1717 }
1718
1719 umask (old_mask);
1720
1721 zebra_event (ZEBRA_SERV, sock, NULL);
1722}
1723
paul718e3742002-12-13 20:15:29 +00001724
1725void
1726zebra_event (enum event event, int sock, struct zserv *client)
1727{
1728 switch (event)
1729 {
1730 case ZEBRA_SERV:
paulb21b19c2003-06-15 01:28:29 +00001731 thread_add_read (zebrad.master, zebra_accept, client, sock);
paul718e3742002-12-13 20:15:29 +00001732 break;
1733 case ZEBRA_READ:
1734 client->t_read =
paulb21b19c2003-06-15 01:28:29 +00001735 thread_add_read (zebrad.master, zebra_client_read, client, sock);
paul718e3742002-12-13 20:15:29 +00001736 break;
1737 case ZEBRA_WRITE:
1738 /**/
1739 break;
1740 }
1741}
1742
1743/* Display default rtm_table for all clients. */
1744DEFUN (show_table,
1745 show_table_cmd,
1746 "show table",
1747 SHOW_STR
1748 "default routing table to use for all clients\n")
1749{
paulb21b19c2003-06-15 01:28:29 +00001750 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001751 VTY_NEWLINE);
1752 return CMD_SUCCESS;
1753}
1754
1755DEFUN (config_table,
1756 config_table_cmd,
1757 "table TABLENO",
1758 "Configure target kernel routing table\n"
1759 "TABLE integer\n")
1760{
paulb21b19c2003-06-15 01:28:29 +00001761 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
paul718e3742002-12-13 20:15:29 +00001762 return CMD_SUCCESS;
1763}
1764
hasso647e4f12003-05-25 11:43:52 +00001765DEFUN (ip_forwarding,
1766 ip_forwarding_cmd,
1767 "ip forwarding",
1768 IP_STR
1769 "Turn on IP forwarding")
1770{
1771 int ret;
1772
1773 ret = ipforward ();
1774
1775 if (ret != 0)
1776 {
1777 vty_out (vty, "IP forwarding is already on%s", VTY_NEWLINE);
1778 return CMD_ERR_NOTHING_TODO;
1779 }
1780
1781 ret = ipforward_on ();
1782 if (ret == 0)
1783 {
1784 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1785 return CMD_WARNING;
1786 }
1787
1788 return CMD_SUCCESS;
1789}
1790
paul718e3742002-12-13 20:15:29 +00001791DEFUN (no_ip_forwarding,
1792 no_ip_forwarding_cmd,
1793 "no ip forwarding",
1794 NO_STR
1795 IP_STR
1796 "Turn off IP forwarding")
1797{
1798 int ret;
1799
1800 ret = ipforward ();
1801
1802 if (ret == 0)
1803 {
1804 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);
1805 return CMD_ERR_NOTHING_TODO;
1806 }
1807
1808 ret = ipforward_off ();
1809 if (ret != 0)
1810 {
1811 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1812 return CMD_WARNING;
1813 }
1814
1815 return CMD_SUCCESS;
1816}
1817
1818/* This command is for debugging purpose. */
1819DEFUN (show_zebra_client,
1820 show_zebra_client_cmd,
1821 "show zebra client",
1822 SHOW_STR
1823 "Zebra information"
1824 "Client information")
1825{
1826 listnode node;
1827 struct zserv *client;
1828
paulb21b19c2003-06-15 01:28:29 +00001829 for (node = listhead (zebrad.client_list); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001830 {
1831 client = getdata (node);
1832 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1833 }
1834 return CMD_SUCCESS;
1835}
1836
1837/* Table configuration write function. */
1838int
1839config_write_table (struct vty *vty)
1840{
paulb21b19c2003-06-15 01:28:29 +00001841 if (zebrad.rtm_table_default)
1842 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001843 VTY_NEWLINE);
1844 return 0;
1845}
1846
1847/* table node for routing tables. */
1848struct cmd_node table_node =
1849{
1850 TABLE_NODE,
1851 "", /* This node has no interface. */
1852 1
1853};
1854
1855/* Only display ip forwarding is enabled or not. */
1856DEFUN (show_ip_forwarding,
1857 show_ip_forwarding_cmd,
1858 "show ip forwarding",
1859 SHOW_STR
1860 IP_STR
1861 "IP forwarding status\n")
1862{
1863 int ret;
1864
1865 ret = ipforward ();
1866
1867 if (ret == 0)
1868 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1869 else
1870 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1871 return CMD_SUCCESS;
1872}
1873
1874#ifdef HAVE_IPV6
1875/* Only display ipv6 forwarding is enabled or not. */
1876DEFUN (show_ipv6_forwarding,
1877 show_ipv6_forwarding_cmd,
1878 "show ipv6 forwarding",
1879 SHOW_STR
1880 "IPv6 information\n"
1881 "Forwarding status\n")
1882{
1883 int ret;
1884
1885 ret = ipforward_ipv6 ();
1886
1887 switch (ret)
1888 {
1889 case -1:
1890 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1891 break;
1892 case 0:
1893 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1894 break;
1895 case 1:
1896 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1897 break;
1898 default:
1899 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1900 break;
1901 }
1902 return CMD_SUCCESS;
1903}
1904
hasso55906722004-02-11 22:42:16 +00001905DEFUN (ipv6_forwarding,
1906 ipv6_forwarding_cmd,
1907 "ipv6 forwarding",
1908 IPV6_STR
1909 "Turn on IPv6 forwarding")
1910{
1911 int ret;
1912
1913 ret = ipforward_ipv6_on ();
1914 if (ret != 0)
1915 {
1916 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1917 return CMD_WARNING;
1918 }
1919
1920 return CMD_SUCCESS;
1921}
1922
paul718e3742002-12-13 20:15:29 +00001923DEFUN (no_ipv6_forwarding,
1924 no_ipv6_forwarding_cmd,
1925 "no ipv6 forwarding",
1926 NO_STR
hasso55906722004-02-11 22:42:16 +00001927 IPV6_STR
1928 "Turn off IPv6 forwarding")
paul718e3742002-12-13 20:15:29 +00001929{
1930 int ret;
1931
1932 ret = ipforward_ipv6_off ();
1933 if (ret != 0)
1934 {
1935 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1936 return CMD_WARNING;
1937 }
1938
1939 return CMD_SUCCESS;
1940}
1941
1942#endif /* HAVE_IPV6 */
1943
1944/* IPForwarding configuration write function. */
1945int
1946config_write_forwarding (struct vty *vty)
1947{
1948 if (! ipforward ())
1949 vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
1950#ifdef HAVE_IPV6
1951 if (! ipforward_ipv6 ())
1952 vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
1953#endif /* HAVE_IPV6 */
1954 vty_out (vty, "!%s", VTY_NEWLINE);
1955 return 0;
1956}
1957
1958/* table node for routing tables. */
1959struct cmd_node forwarding_node =
1960{
1961 FORWARDING_NODE,
1962 "", /* This node has no interface. */
1963 1
1964};
1965
1966
1967/* Initialisation of zebra and installation of commands. */
1968void
1969zebra_init ()
1970{
1971 /* Client list init. */
paulb21b19c2003-06-15 01:28:29 +00001972 zebrad.client_list = list_new ();
paul718e3742002-12-13 20:15:29 +00001973
1974 /* Forwarding is on by default. */
1975 ipforward_on ();
1976#ifdef HAVE_IPV6
1977 ipforward_ipv6_on ();
1978#endif /* HAVE_IPV6 */
1979
1980 /* Make zebra server socket. */
1981#ifdef HAVE_TCP_ZEBRA
1982 zebra_serv ();
1983#else
1984 zebra_serv_un (ZEBRA_SERV_PATH);
1985#endif /* HAVE_TCP_ZEBRA */
1986
1987 /* Install configuration write function. */
1988 install_node (&table_node, config_write_table);
1989 install_node (&forwarding_node, config_write_forwarding);
1990
1991 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1992 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00001993 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001994 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1995 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1996
1997#ifdef HAVE_NETLINK
1998 install_element (VIEW_NODE, &show_table_cmd);
1999 install_element (ENABLE_NODE, &show_table_cmd);
2000 install_element (CONFIG_NODE, &config_table_cmd);
2001#endif /* HAVE_NETLINK */
2002
2003#ifdef HAVE_IPV6
2004 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
2005 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
hasso55906722004-02-11 22:42:16 +00002006 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00002007 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
2008#endif /* HAVE_IPV6 */
paulccf35572003-03-01 11:42:20 +00002009
2010 FIFO_INIT(&message_queue);
2011 t_write = NULL;
paul718e3742002-12-13 20:15:29 +00002012}