blob: c623151ea62ba9271c9efd0eb338ae3f53f8accc [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;
hassofa2b17e2004-03-04 17:45:00 +0000865 default:
866 /* do nothing */
867 break;
paul718e3742002-12-13 20:15:29 +0000868 }
869 num++;
870 }
871 stream_putc_at (s, nump, num);
872 }
873 else
874 {
875 stream_putl (s, 0);
876 stream_putc (s, 0);
877 }
878
879 stream_putw_at (s, 0, stream_get_endp (s));
880
paulccf35572003-03-01 11:42:20 +0000881 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
882
883 return 0;
paul718e3742002-12-13 20:15:29 +0000884}
885#endif /* HAVE_IPV6 */
886
887int
888zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
889{
890 struct stream *s;
891 struct rib *rib;
892 unsigned long nump;
893 u_char num;
894 struct nexthop *nexthop;
895
896 /* Lookup nexthop. */
897 rib = rib_match_ipv4 (addr);
898
899 /* Get output stream. */
900 s = client->obuf;
901 stream_reset (s);
902
903 /* Fill in result. */
904 stream_putw (s, 0);
905 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
906 stream_put_in_addr (s, &addr);
907
908 if (rib)
909 {
910 stream_putl (s, rib->metric);
911 num = 0;
912 nump = s->putp;
913 stream_putc (s, 0);
914 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
915 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
916 {
917 stream_putc (s, nexthop->type);
918 switch (nexthop->type)
919 {
920 case ZEBRA_NEXTHOP_IPV4:
921 stream_put_in_addr (s, &nexthop->gate.ipv4);
922 break;
923 case ZEBRA_NEXTHOP_IFINDEX:
924 case ZEBRA_NEXTHOP_IFNAME:
925 stream_putl (s, nexthop->ifindex);
926 break;
hassofa2b17e2004-03-04 17:45:00 +0000927 default:
928 /* do nothing */
929 break;
paul718e3742002-12-13 20:15:29 +0000930 }
931 num++;
932 }
933 stream_putc_at (s, nump, num);
934 }
935 else
936 {
937 stream_putl (s, 0);
938 stream_putc (s, 0);
939 }
940
941 stream_putw_at (s, 0, stream_get_endp (s));
942
paulccf35572003-03-01 11:42:20 +0000943 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
944
945 return 0;
paul718e3742002-12-13 20:15:29 +0000946}
947
948int
949zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
950{
951 struct stream *s;
952 struct rib *rib;
953 unsigned long nump;
954 u_char num;
955 struct nexthop *nexthop;
956
957 /* Lookup nexthop. */
958 rib = rib_lookup_ipv4 (p);
959
960 /* Get output stream. */
961 s = client->obuf;
962 stream_reset (s);
963
964 /* Fill in result. */
965 stream_putw (s, 0);
966 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
967 stream_put_in_addr (s, &p->prefix);
968
969 if (rib)
970 {
971 stream_putl (s, rib->metric);
972 num = 0;
973 nump = s->putp;
974 stream_putc (s, 0);
975 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
976 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
977 {
978 stream_putc (s, nexthop->type);
979 switch (nexthop->type)
980 {
981 case ZEBRA_NEXTHOP_IPV4:
982 stream_put_in_addr (s, &nexthop->gate.ipv4);
983 break;
984 case ZEBRA_NEXTHOP_IFINDEX:
985 case ZEBRA_NEXTHOP_IFNAME:
986 stream_putl (s, nexthop->ifindex);
987 break;
hassofa2b17e2004-03-04 17:45:00 +0000988 default:
989 /* do nothing */
990 break;
paul718e3742002-12-13 20:15:29 +0000991 }
992 num++;
993 }
994 stream_putc_at (s, nump, num);
995 }
996 else
997 {
998 stream_putl (s, 0);
999 stream_putc (s, 0);
1000 }
1001
1002 stream_putw_at (s, 0, stream_get_endp (s));
1003
paulccf35572003-03-01 11:42:20 +00001004 zebra_server_send_message (client->sock, s->data, stream_get_endp (s));
1005
1006 return 0;
paul718e3742002-12-13 20:15:29 +00001007}
1008
1009/* Register zebra server interface information. Send current all
1010 interface and address information. */
1011void
1012zread_interface_add (struct zserv *client, u_short length)
1013{
1014 listnode ifnode;
1015 listnode cnode;
1016 struct interface *ifp;
1017 struct connected *c;
1018
1019 /* Interface information is needed. */
1020 client->ifinfo = 1;
1021
1022 for (ifnode = listhead (iflist); ifnode; ifnode = nextnode (ifnode))
1023 {
1024 ifp = getdata (ifnode);
1025
1026 /* Skip pseudo interface. */
1027 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1028 continue;
1029
1030 zsend_interface_add (client, ifp);
1031
1032 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
1033 {
1034 c = getdata (cnode);
1035 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
1036 zsend_interface_address_add (client, ifp, c);
1037 }
1038 }
1039}
1040
1041/* Unregister zebra server interface information. */
1042void
1043zread_interface_delete (struct zserv *client, u_short length)
1044{
1045 client->ifinfo = 0;
1046}
1047
1048/* This function support multiple nexthop. */
1049void
1050zread_ipv4_add (struct zserv *client, u_short length)
1051{
1052 int i;
1053 struct rib *rib;
1054 struct prefix_ipv4 p;
1055 u_char message;
1056 struct in_addr nexthop;
1057 u_char nexthop_num;
1058 u_char nexthop_type;
1059 struct stream *s;
1060 unsigned int ifindex;
1061 u_char ifname_len;
1062
1063 /* Get input stream. */
1064 s = client->ibuf;
1065
1066 /* Allocate new rib. */
1067 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
1068 memset (rib, 0, sizeof (struct rib));
1069
1070 /* Type, flags, message. */
1071 rib->type = stream_getc (s);
1072 rib->flags = stream_getc (s);
1073 message = stream_getc (s);
1074 rib->uptime = time (NULL);
1075
1076 /* IPv4 prefix. */
1077 memset (&p, 0, sizeof (struct prefix_ipv4));
1078 p.family = AF_INET;
1079 p.prefixlen = stream_getc (s);
1080 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1081
1082 /* Nexthop parse. */
1083 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1084 {
1085 nexthop_num = stream_getc (s);
1086
1087 for (i = 0; i < nexthop_num; i++)
1088 {
1089 nexthop_type = stream_getc (s);
1090
1091 switch (nexthop_type)
1092 {
1093 case ZEBRA_NEXTHOP_IFINDEX:
1094 ifindex = stream_getl (s);
1095 nexthop_ifindex_add (rib, ifindex);
1096 break;
1097 case ZEBRA_NEXTHOP_IFNAME:
1098 ifname_len = stream_getc (s);
1099 stream_forward (s, ifname_len);
1100 break;
1101 case ZEBRA_NEXTHOP_IPV4:
1102 nexthop.s_addr = stream_get_ipv4 (s);
1103 nexthop_ipv4_add (rib, &nexthop);
1104 break;
1105 case ZEBRA_NEXTHOP_IPV6:
1106 stream_forward (s, IPV6_MAX_BYTELEN);
1107 break;
paul595db7f2003-05-25 21:35:06 +00001108 case ZEBRA_NEXTHOP_BLACKHOLE:
1109 nexthop_blackhole_add (rib);
1110 break;
paul718e3742002-12-13 20:15:29 +00001111 }
1112 }
1113 }
1114
1115 /* Distance. */
1116 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1117 rib->distance = stream_getc (s);
1118
1119 /* Metric. */
1120 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1121 rib->metric = stream_getl (s);
1122
1123 rib_add_ipv4_multipath (&p, rib);
1124}
1125
1126/* Zebra server IPv4 prefix delete function. */
1127void
1128zread_ipv4_delete (struct zserv *client, u_short length)
1129{
1130 int i;
1131 struct stream *s;
1132 struct zapi_ipv4 api;
1133 struct in_addr nexthop;
1134 unsigned long ifindex;
1135 struct prefix_ipv4 p;
1136 u_char nexthop_num;
1137 u_char nexthop_type;
1138 u_char ifname_len;
1139
1140 s = client->ibuf;
1141 ifindex = 0;
1142 nexthop.s_addr = 0;
1143
1144 /* Type, flags, message. */
1145 api.type = stream_getc (s);
1146 api.flags = stream_getc (s);
1147 api.message = stream_getc (s);
1148
1149 /* IPv4 prefix. */
1150 memset (&p, 0, sizeof (struct prefix_ipv4));
1151 p.family = AF_INET;
1152 p.prefixlen = stream_getc (s);
1153 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1154
1155 /* Nexthop, ifindex, distance, metric. */
1156 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1157 {
1158 nexthop_num = stream_getc (s);
1159
1160 for (i = 0; i < nexthop_num; i++)
1161 {
1162 nexthop_type = stream_getc (s);
1163
1164 switch (nexthop_type)
1165 {
1166 case ZEBRA_NEXTHOP_IFINDEX:
1167 ifindex = stream_getl (s);
1168 break;
1169 case ZEBRA_NEXTHOP_IFNAME:
1170 ifname_len = stream_getc (s);
1171 stream_forward (s, ifname_len);
1172 break;
1173 case ZEBRA_NEXTHOP_IPV4:
1174 nexthop.s_addr = stream_get_ipv4 (s);
1175 break;
1176 case ZEBRA_NEXTHOP_IPV6:
1177 stream_forward (s, IPV6_MAX_BYTELEN);
1178 break;
1179 }
1180 }
1181 }
1182
1183 /* Distance. */
1184 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1185 api.distance = stream_getc (s);
1186 else
1187 api.distance = 0;
1188
1189 /* Metric. */
1190 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1191 api.metric = stream_getl (s);
1192 else
1193 api.metric = 0;
1194
1195 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
1196 client->rtm_table);
1197}
1198
1199/* Nexthop lookup for IPv4. */
1200void
1201zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
1202{
1203 struct in_addr addr;
1204
1205 addr.s_addr = stream_get_ipv4 (client->ibuf);
1206 zsend_ipv4_nexthop_lookup (client, addr);
1207}
1208
1209/* Nexthop lookup for IPv4. */
1210void
1211zread_ipv4_import_lookup (struct zserv *client, u_short length)
1212{
1213 struct prefix_ipv4 p;
1214
1215 p.family = AF_INET;
1216 p.prefixlen = stream_getc (client->ibuf);
1217 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1218
1219 zsend_ipv4_import_lookup (client, &p);
1220}
1221
1222#ifdef HAVE_IPV6
1223/* Zebra server IPv6 prefix add function. */
1224void
1225zread_ipv6_add (struct zserv *client, u_short length)
1226{
1227 int i;
1228 struct stream *s;
1229 struct zapi_ipv6 api;
1230 struct in6_addr nexthop;
1231 unsigned long ifindex;
1232 struct prefix_ipv6 p;
1233
1234 s = client->ibuf;
1235 ifindex = 0;
1236 memset (&nexthop, 0, sizeof (struct in6_addr));
1237
1238 /* Type, flags, message. */
1239 api.type = stream_getc (s);
1240 api.flags = stream_getc (s);
1241 api.message = stream_getc (s);
1242
1243 /* IPv4 prefix. */
1244 memset (&p, 0, sizeof (struct prefix_ipv6));
1245 p.family = AF_INET6;
1246 p.prefixlen = stream_getc (s);
1247 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1248
1249 /* Nexthop, ifindex, distance, metric. */
1250 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1251 {
1252 u_char nexthop_type;
1253
1254 api.nexthop_num = stream_getc (s);
1255 for (i = 0; i < api.nexthop_num; i++)
1256 {
1257 nexthop_type = stream_getc (s);
1258
1259 switch (nexthop_type)
1260 {
1261 case ZEBRA_NEXTHOP_IPV6:
1262 stream_get (&nexthop, s, 16);
1263 break;
1264 case ZEBRA_NEXTHOP_IFINDEX:
1265 ifindex = stream_getl (s);
1266 break;
1267 }
1268 }
1269 }
1270
1271 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1272 api.distance = stream_getc (s);
1273 else
1274 api.distance = 0;
1275
1276 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1277 api.metric = stream_getl (s);
1278 else
1279 api.metric = 0;
1280
1281 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1282 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1283 else
1284 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1285}
1286
1287/* Zebra server IPv6 prefix delete function. */
1288void
1289zread_ipv6_delete (struct zserv *client, u_short length)
1290{
1291 int i;
1292 struct stream *s;
1293 struct zapi_ipv6 api;
1294 struct in6_addr nexthop;
1295 unsigned long ifindex;
1296 struct prefix_ipv6 p;
1297
1298 s = client->ibuf;
1299 ifindex = 0;
1300 memset (&nexthop, 0, sizeof (struct in6_addr));
1301
1302 /* Type, flags, message. */
1303 api.type = stream_getc (s);
1304 api.flags = stream_getc (s);
1305 api.message = stream_getc (s);
1306
1307 /* IPv4 prefix. */
1308 memset (&p, 0, sizeof (struct prefix_ipv6));
1309 p.family = AF_INET6;
1310 p.prefixlen = stream_getc (s);
1311 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1312
1313 /* Nexthop, ifindex, distance, metric. */
1314 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1315 {
1316 u_char nexthop_type;
1317
1318 api.nexthop_num = stream_getc (s);
1319 for (i = 0; i < api.nexthop_num; i++)
1320 {
1321 nexthop_type = stream_getc (s);
1322
1323 switch (nexthop_type)
1324 {
1325 case ZEBRA_NEXTHOP_IPV6:
1326 stream_get (&nexthop, s, 16);
1327 break;
1328 case ZEBRA_NEXTHOP_IFINDEX:
1329 ifindex = stream_getl (s);
1330 break;
1331 }
1332 }
1333 }
1334
1335 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1336 api.distance = stream_getc (s);
1337 else
1338 api.distance = 0;
1339 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1340 api.metric = stream_getl (s);
1341 else
1342 api.metric = 0;
1343
1344 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1345 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1346 else
1347 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
1348}
1349
1350void
1351zebra_read_ipv6 (int command, struct zserv *client, u_short length)
1352{
1353 u_char type;
1354 u_char flags;
1355 struct in6_addr nexthop, *gate;
1356 u_char *lim;
1357 u_char *pnt;
1358 unsigned int ifindex;
1359
1360 pnt = stream_pnt (client->ibuf);
1361 lim = pnt + length;
1362
1363 type = stream_getc (client->ibuf);
1364 flags = stream_getc (client->ibuf);
1365 stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr));
1366
1367 while (stream_pnt (client->ibuf) < lim)
1368 {
1369 int size;
1370 struct prefix_ipv6 p;
1371
1372 ifindex = stream_getl (client->ibuf);
1373
1374 memset (&p, 0, sizeof (struct prefix_ipv6));
1375 p.family = AF_INET6;
1376 p.prefixlen = stream_getc (client->ibuf);
1377 size = PSIZE(p.prefixlen);
1378 stream_get (&p.prefix, client->ibuf, size);
1379
1380 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1381 gate = NULL;
1382 else
1383 gate = &nexthop;
1384
1385 if (command == ZEBRA_IPV6_ROUTE_ADD)
1386 rib_add_ipv6 (type, flags, &p, gate, ifindex, 0);
1387 else
1388 rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);
1389 }
1390}
1391
1392void
1393zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1394{
1395 struct in6_addr addr;
1396 char buf[BUFSIZ];
1397
1398 stream_get (&addr, client->ibuf, 16);
1399 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1400
1401 zsend_ipv6_nexthop_lookup (client, &addr);
1402}
1403#endif /* HAVE_IPV6 */
1404
1405/* Close zebra client. */
1406void
1407zebra_client_close (struct zserv *client)
1408{
1409 /* Close file descriptor. */
1410 if (client->sock)
1411 {
1412 close (client->sock);
1413 client->sock = -1;
1414 }
1415
1416 /* Free stream buffers. */
1417 if (client->ibuf)
1418 stream_free (client->ibuf);
1419 if (client->obuf)
1420 stream_free (client->obuf);
1421
1422 /* Release threads. */
1423 if (client->t_read)
1424 thread_cancel (client->t_read);
1425 if (client->t_write)
1426 thread_cancel (client->t_write);
1427
1428 /* Free client structure. */
paulb21b19c2003-06-15 01:28:29 +00001429 listnode_delete (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001430 XFREE (0, client);
1431}
1432
1433/* Make new client. */
1434void
1435zebra_client_create (int sock)
1436{
1437 struct zserv *client;
1438
1439 client = XCALLOC (0, sizeof (struct zserv));
1440
1441 /* Make client input/output buffer. */
1442 client->sock = sock;
1443 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1444 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1445
1446 /* Set table number. */
paulb21b19c2003-06-15 01:28:29 +00001447 client->rtm_table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00001448
1449 /* Add this client to linked list. */
paulb21b19c2003-06-15 01:28:29 +00001450 listnode_add (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001451
1452 /* Make new read thread. */
1453 zebra_event (ZEBRA_READ, sock, client);
1454}
1455
1456/* Handler of zebra service request. */
1457int
1458zebra_client_read (struct thread *thread)
1459{
1460 int sock;
1461 struct zserv *client;
1462 int nbyte;
1463 u_short length;
1464 u_char command;
1465
1466 /* Get thread data. Reset reading thread because I'm running. */
1467 sock = THREAD_FD (thread);
1468 client = THREAD_ARG (thread);
1469 client->t_read = NULL;
1470
1471 /* Read length and command. */
1472 nbyte = stream_read (client->ibuf, sock, 3);
1473 if (nbyte <= 0)
1474 {
1475 if (IS_ZEBRA_DEBUG_EVENT)
1476 zlog_info ("connection closed socket [%d]", sock);
1477 zebra_client_close (client);
1478 return -1;
1479 }
1480 length = stream_getw (client->ibuf);
1481 command = stream_getc (client->ibuf);
1482
1483 if (length < 3)
1484 {
1485 if (IS_ZEBRA_DEBUG_EVENT)
1486 zlog_info ("length %d is less than 3 ", length);
1487 zebra_client_close (client);
1488 return -1;
1489 }
1490
1491 length -= 3;
1492
1493 /* Read rest of data. */
1494 if (length)
1495 {
1496 nbyte = stream_read (client->ibuf, sock, length);
1497 if (nbyte <= 0)
1498 {
1499 if (IS_ZEBRA_DEBUG_EVENT)
1500 zlog_info ("connection closed [%d] when reading zebra data", sock);
1501 zebra_client_close (client);
1502 return -1;
1503 }
1504 }
1505
1506 /* Debug packet information. */
1507 if (IS_ZEBRA_DEBUG_EVENT)
1508 zlog_info ("zebra message comes from socket [%d]", sock);
1509
1510 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1511 zlog_info ("zebra message received [%s] %d",
1512 zebra_command_str[command], length);
1513
1514 switch (command)
1515 {
1516 case ZEBRA_INTERFACE_ADD:
1517 zread_interface_add (client, length);
1518 break;
1519 case ZEBRA_INTERFACE_DELETE:
1520 zread_interface_delete (client, length);
1521 break;
1522 case ZEBRA_IPV4_ROUTE_ADD:
1523 zread_ipv4_add (client, length);
1524 break;
1525 case ZEBRA_IPV4_ROUTE_DELETE:
1526 zread_ipv4_delete (client, length);
1527 break;
1528#ifdef HAVE_IPV6
1529 case ZEBRA_IPV6_ROUTE_ADD:
1530 zread_ipv6_add (client, length);
1531 break;
1532 case ZEBRA_IPV6_ROUTE_DELETE:
1533 zread_ipv6_delete (client, length);
1534 break;
1535#endif /* HAVE_IPV6 */
1536 case ZEBRA_REDISTRIBUTE_ADD:
1537 zebra_redistribute_add (command, client, length);
1538 break;
1539 case ZEBRA_REDISTRIBUTE_DELETE:
1540 zebra_redistribute_delete (command, client, length);
1541 break;
1542 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1543 zebra_redistribute_default_add (command, client, length);
1544 break;
1545 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1546 zebra_redistribute_default_delete (command, client, length);
1547 break;
1548 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1549 zread_ipv4_nexthop_lookup (client, length);
1550 break;
1551#ifdef HAVE_IPV6
1552 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1553 zread_ipv6_nexthop_lookup (client, length);
1554 break;
1555#endif /* HAVE_IPV6 */
1556 case ZEBRA_IPV4_IMPORT_LOOKUP:
1557 zread_ipv4_import_lookup (client, length);
1558 break;
1559 default:
1560 zlog_info ("Zebra received unknown command %d", command);
1561 break;
1562 }
1563
1564 stream_reset (client->ibuf);
1565 zebra_event (ZEBRA_READ, sock, client);
1566
1567 return 0;
1568}
1569
1570/* Write output buffer to the socket. */
1571void
1572zebra_write (struct thread *thread)
1573{
1574 int sock;
1575 struct zserv *client;
1576
1577 /* Thread treatment. */
1578 sock = THREAD_FD (thread);
1579 client = THREAD_ARG (thread);
1580 client->t_write = NULL;
1581
1582 stream_flush (client->obuf, sock);
1583}
1584
1585/* Accept code of zebra server socket. */
1586int
1587zebra_accept (struct thread *thread)
1588{
paulccf35572003-03-01 11:42:20 +00001589 int val;
paul718e3742002-12-13 20:15:29 +00001590 int accept_sock;
1591 int client_sock;
1592 struct sockaddr_in client;
1593 socklen_t len;
1594
1595 accept_sock = THREAD_FD (thread);
1596
1597 len = sizeof (struct sockaddr_in);
1598 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1599
1600 if (client_sock < 0)
1601 {
1602 zlog_warn ("Can't accept zebra socket: %s", strerror (errno));
1603 return -1;
1604 }
1605
paulccf35572003-03-01 11:42:20 +00001606 /* Make client socket non-blocking. */
1607
1608 val = fcntl (client_sock, F_GETFL, 0);
1609 fcntl (client_sock, F_SETFL, (val | O_NONBLOCK));
1610
paul718e3742002-12-13 20:15:29 +00001611 /* Create new zebra client. */
1612 zebra_client_create (client_sock);
1613
1614 /* Register myself. */
1615 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1616
1617 return 0;
1618}
1619
1620/* Make zebra's server socket. */
1621void
1622zebra_serv ()
1623{
1624 int ret;
1625 int accept_sock;
1626 struct sockaddr_in addr;
1627
1628 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1629
1630 if (accept_sock < 0)
1631 {
1632 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1633 zlog_warn ("zebra can't provice full functionality due to above error");
1634 return;
1635 }
1636
1637 memset (&addr, 0, sizeof (struct sockaddr_in));
1638 addr.sin_family = AF_INET;
1639 addr.sin_port = htons (ZEBRA_PORT);
1640#ifdef HAVE_SIN_LEN
1641 addr.sin_len = sizeof (struct sockaddr_in);
1642#endif /* HAVE_SIN_LEN */
1643 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1644
1645 sockopt_reuseaddr (accept_sock);
1646 sockopt_reuseport (accept_sock);
1647
pauledd7c242003-06-04 13:59:38 +00001648 if ( zserv_privs.change(ZPRIVS_RAISE) )
1649 zlog (NULL, LOG_ERR, "Can't raise privileges");
1650
paul718e3742002-12-13 20:15:29 +00001651 ret = bind (accept_sock, (struct sockaddr *)&addr,
1652 sizeof (struct sockaddr_in));
1653 if (ret < 0)
1654 {
1655 zlog_warn ("Can't bind to socket: %s", strerror (errno));
1656 zlog_warn ("zebra can't provice full functionality due to above error");
1657 close (accept_sock); /* Avoid sd leak. */
1658 return;
1659 }
pauledd7c242003-06-04 13:59:38 +00001660
1661 if ( zserv_privs.change(ZPRIVS_LOWER) )
1662 zlog (NULL, LOG_ERR, "Can't lower privileges");
paul718e3742002-12-13 20:15:29 +00001663
1664 ret = listen (accept_sock, 1);
1665 if (ret < 0)
1666 {
1667 zlog_warn ("Can't listen to socket: %s", strerror (errno));
1668 zlog_warn ("zebra can't provice full functionality due to above error");
1669 close (accept_sock); /* Avoid sd leak. */
1670 return;
1671 }
1672
1673 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1674}
1675
1676/* For sockaddr_un. */
1677#include <sys/un.h>
1678
1679/* zebra server UNIX domain socket. */
1680void
1681zebra_serv_un (char *path)
1682{
1683 int ret;
1684 int sock, len;
1685 struct sockaddr_un serv;
1686 mode_t old_mask;
1687
1688 /* First of all, unlink existing socket */
1689 unlink (path);
1690
1691 /* Set umask */
1692 old_mask = umask (0077);
1693
1694 /* Make UNIX domain socket. */
1695 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1696 if (sock < 0)
1697 {
1698 perror ("sock");
1699 return;
1700 }
1701
1702 /* Make server socket. */
1703 memset (&serv, 0, sizeof (struct sockaddr_un));
1704 serv.sun_family = AF_UNIX;
1705 strncpy (serv.sun_path, path, strlen (path));
1706#ifdef HAVE_SUN_LEN
1707 len = serv.sun_len = SUN_LEN(&serv);
1708#else
1709 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1710#endif /* HAVE_SUN_LEN */
1711
1712 ret = bind (sock, (struct sockaddr *) &serv, len);
1713 if (ret < 0)
1714 {
1715 perror ("bind");
1716 close (sock);
1717 return;
1718 }
1719
1720 ret = listen (sock, 5);
1721 if (ret < 0)
1722 {
1723 perror ("listen");
1724 close (sock);
1725 return;
1726 }
1727
1728 umask (old_mask);
1729
1730 zebra_event (ZEBRA_SERV, sock, NULL);
1731}
1732
paul718e3742002-12-13 20:15:29 +00001733
1734void
1735zebra_event (enum event event, int sock, struct zserv *client)
1736{
1737 switch (event)
1738 {
1739 case ZEBRA_SERV:
paulb21b19c2003-06-15 01:28:29 +00001740 thread_add_read (zebrad.master, zebra_accept, client, sock);
paul718e3742002-12-13 20:15:29 +00001741 break;
1742 case ZEBRA_READ:
1743 client->t_read =
paulb21b19c2003-06-15 01:28:29 +00001744 thread_add_read (zebrad.master, zebra_client_read, client, sock);
paul718e3742002-12-13 20:15:29 +00001745 break;
1746 case ZEBRA_WRITE:
1747 /**/
1748 break;
1749 }
1750}
1751
1752/* Display default rtm_table for all clients. */
1753DEFUN (show_table,
1754 show_table_cmd,
1755 "show table",
1756 SHOW_STR
1757 "default routing table to use for all clients\n")
1758{
paulb21b19c2003-06-15 01:28:29 +00001759 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001760 VTY_NEWLINE);
1761 return CMD_SUCCESS;
1762}
1763
1764DEFUN (config_table,
1765 config_table_cmd,
1766 "table TABLENO",
1767 "Configure target kernel routing table\n"
1768 "TABLE integer\n")
1769{
paulb21b19c2003-06-15 01:28:29 +00001770 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
paul718e3742002-12-13 20:15:29 +00001771 return CMD_SUCCESS;
1772}
1773
hasso647e4f12003-05-25 11:43:52 +00001774DEFUN (ip_forwarding,
1775 ip_forwarding_cmd,
1776 "ip forwarding",
1777 IP_STR
1778 "Turn on IP forwarding")
1779{
1780 int ret;
1781
1782 ret = ipforward ();
1783
1784 if (ret != 0)
1785 {
1786 vty_out (vty, "IP forwarding is already on%s", VTY_NEWLINE);
1787 return CMD_ERR_NOTHING_TODO;
1788 }
1789
1790 ret = ipforward_on ();
1791 if (ret == 0)
1792 {
1793 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1794 return CMD_WARNING;
1795 }
1796
1797 return CMD_SUCCESS;
1798}
1799
paul718e3742002-12-13 20:15:29 +00001800DEFUN (no_ip_forwarding,
1801 no_ip_forwarding_cmd,
1802 "no ip forwarding",
1803 NO_STR
1804 IP_STR
1805 "Turn off IP forwarding")
1806{
1807 int ret;
1808
1809 ret = ipforward ();
1810
1811 if (ret == 0)
1812 {
1813 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);
1814 return CMD_ERR_NOTHING_TODO;
1815 }
1816
1817 ret = ipforward_off ();
1818 if (ret != 0)
1819 {
1820 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1821 return CMD_WARNING;
1822 }
1823
1824 return CMD_SUCCESS;
1825}
1826
1827/* This command is for debugging purpose. */
1828DEFUN (show_zebra_client,
1829 show_zebra_client_cmd,
1830 "show zebra client",
1831 SHOW_STR
1832 "Zebra information"
1833 "Client information")
1834{
1835 listnode node;
1836 struct zserv *client;
1837
paulb21b19c2003-06-15 01:28:29 +00001838 for (node = listhead (zebrad.client_list); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001839 {
1840 client = getdata (node);
1841 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1842 }
1843 return CMD_SUCCESS;
1844}
1845
1846/* Table configuration write function. */
1847int
1848config_write_table (struct vty *vty)
1849{
paulb21b19c2003-06-15 01:28:29 +00001850 if (zebrad.rtm_table_default)
1851 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001852 VTY_NEWLINE);
1853 return 0;
1854}
1855
1856/* table node for routing tables. */
1857struct cmd_node table_node =
1858{
1859 TABLE_NODE,
1860 "", /* This node has no interface. */
1861 1
1862};
1863
1864/* Only display ip forwarding is enabled or not. */
1865DEFUN (show_ip_forwarding,
1866 show_ip_forwarding_cmd,
1867 "show ip forwarding",
1868 SHOW_STR
1869 IP_STR
1870 "IP forwarding status\n")
1871{
1872 int ret;
1873
1874 ret = ipforward ();
1875
1876 if (ret == 0)
1877 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1878 else
1879 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1880 return CMD_SUCCESS;
1881}
1882
1883#ifdef HAVE_IPV6
1884/* Only display ipv6 forwarding is enabled or not. */
1885DEFUN (show_ipv6_forwarding,
1886 show_ipv6_forwarding_cmd,
1887 "show ipv6 forwarding",
1888 SHOW_STR
1889 "IPv6 information\n"
1890 "Forwarding status\n")
1891{
1892 int ret;
1893
1894 ret = ipforward_ipv6 ();
1895
1896 switch (ret)
1897 {
1898 case -1:
1899 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1900 break;
1901 case 0:
1902 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1903 break;
1904 case 1:
1905 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1906 break;
1907 default:
1908 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1909 break;
1910 }
1911 return CMD_SUCCESS;
1912}
1913
hasso55906722004-02-11 22:42:16 +00001914DEFUN (ipv6_forwarding,
1915 ipv6_forwarding_cmd,
1916 "ipv6 forwarding",
1917 IPV6_STR
1918 "Turn on IPv6 forwarding")
1919{
1920 int ret;
1921
hasso41d3fc92004-04-06 11:59:00 +00001922 ret = ipforward_ipv6 ();
hasso55906722004-02-11 22:42:16 +00001923 if (ret != 0)
1924 {
hasso41d3fc92004-04-06 11:59:00 +00001925 vty_out (vty, "IPv6 forwarding is already on%s", VTY_NEWLINE);
1926 return CMD_ERR_NOTHING_TODO;
1927 }
1928
1929 ret = ipforward_ipv6_on ();
1930 if (ret == 0)
1931 {
hasso55906722004-02-11 22:42:16 +00001932 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1933 return CMD_WARNING;
1934 }
1935
1936 return CMD_SUCCESS;
1937}
1938
paul718e3742002-12-13 20:15:29 +00001939DEFUN (no_ipv6_forwarding,
1940 no_ipv6_forwarding_cmd,
1941 "no ipv6 forwarding",
1942 NO_STR
hasso55906722004-02-11 22:42:16 +00001943 IPV6_STR
1944 "Turn off IPv6 forwarding")
paul718e3742002-12-13 20:15:29 +00001945{
1946 int ret;
1947
hasso41d3fc92004-04-06 11:59:00 +00001948 ret = ipforward_ipv6 ();
1949 if (ret == 0)
1950 {
1951 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);
1952 return CMD_ERR_NOTHING_TODO;
1953 }
1954
paul718e3742002-12-13 20:15:29 +00001955 ret = ipforward_ipv6_off ();
1956 if (ret != 0)
1957 {
1958 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1959 return CMD_WARNING;
1960 }
1961
1962 return CMD_SUCCESS;
1963}
1964
1965#endif /* HAVE_IPV6 */
1966
1967/* IPForwarding configuration write function. */
1968int
1969config_write_forwarding (struct vty *vty)
1970{
1971 if (! ipforward ())
1972 vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
1973#ifdef HAVE_IPV6
1974 if (! ipforward_ipv6 ())
1975 vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
1976#endif /* HAVE_IPV6 */
1977 vty_out (vty, "!%s", VTY_NEWLINE);
1978 return 0;
1979}
1980
1981/* table node for routing tables. */
1982struct cmd_node forwarding_node =
1983{
1984 FORWARDING_NODE,
1985 "", /* This node has no interface. */
1986 1
1987};
1988
1989
1990/* Initialisation of zebra and installation of commands. */
1991void
1992zebra_init ()
1993{
1994 /* Client list init. */
paulb21b19c2003-06-15 01:28:29 +00001995 zebrad.client_list = list_new ();
paul718e3742002-12-13 20:15:29 +00001996
1997 /* Forwarding is on by default. */
1998 ipforward_on ();
1999#ifdef HAVE_IPV6
2000 ipforward_ipv6_on ();
2001#endif /* HAVE_IPV6 */
2002
2003 /* Make zebra server socket. */
2004#ifdef HAVE_TCP_ZEBRA
2005 zebra_serv ();
2006#else
2007 zebra_serv_un (ZEBRA_SERV_PATH);
2008#endif /* HAVE_TCP_ZEBRA */
2009
2010 /* Install configuration write function. */
2011 install_node (&table_node, config_write_table);
2012 install_node (&forwarding_node, config_write_forwarding);
2013
2014 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
2015 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00002016 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00002017 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
2018 install_element (ENABLE_NODE, &show_zebra_client_cmd);
2019
2020#ifdef HAVE_NETLINK
2021 install_element (VIEW_NODE, &show_table_cmd);
2022 install_element (ENABLE_NODE, &show_table_cmd);
2023 install_element (CONFIG_NODE, &config_table_cmd);
2024#endif /* HAVE_NETLINK */
2025
2026#ifdef HAVE_IPV6
2027 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
2028 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
hasso55906722004-02-11 22:42:16 +00002029 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00002030 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
2031#endif /* HAVE_IPV6 */
paulccf35572003-03-01 11:42:20 +00002032
2033 FIFO_INIT(&message_queue);
2034 t_write = NULL;
paul718e3742002-12-13 20:15:29 +00002035}