]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zserv.c
2005-06-28 Paul Jakma <paul.jakma@sun.com>
[mirror_frr.git] / zebra / zserv.c
CommitLineData
718e3744 1/* 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"
edd7c245 36#include "privs.h"
719e9741 37#include "network.h"
38#include "buffer.h"
718e3744 39
40#include "zebra/zserv.h"
18a6dce6 41#include "zebra/router-id.h"
718e3744 42#include "zebra/redistribute.h"
43#include "zebra/debug.h"
44#include "zebra/ipforward.h"
45\f
46/* Event list of zebra. */
47enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
48
b21b19c5 49extern struct zebra_t zebrad;
718e3744 50
b9df2d25 51static void zebra_event (enum event event, int sock, struct zserv *client);
ccf3557b 52
edd7c245 53extern struct zebra_privs_t zserv_privs;
718e3744 54\f
55/* For logging of zebra meesages. */
fce954f8 56static const char *zebra_command_str [] =
718e3744 57{
58 "NULL",
59 "ZEBRA_INTERFACE_ADD",
60 "ZEBRA_INTERFACE_DELETE",
61 "ZEBRA_INTERFACE_ADDRESS_ADD",
62 "ZEBRA_INTERFACE_ADDRESS_DELETE",
63 "ZEBRA_INTERFACE_UP",
64 "ZEBRA_INTERFACE_DOWN",
65 "ZEBRA_IPV4_ROUTE_ADD",
66 "ZEBRA_IPV4_ROUTE_DELETE",
67 "ZEBRA_IPV6_ROUTE_ADD",
68 "ZEBRA_IPV6_ROUTE_DELETE",
69 "ZEBRA_REDISTRIBUTE_ADD",
70 "ZEBRA_REDISTRIBUTE_DELETE",
71 "ZEBRA_REDISTRIBUTE_DEFAULT_ADD",
72 "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE",
73 "ZEBRA_IPV4_NEXTHOP_LOOKUP",
74 "ZEBRA_IPV6_NEXTHOP_LOOKUP",
75 "ZEBRA_IPV4_IMPORT_LOOKUP",
18a6dce6 76 "ZEBRA_IPV6_IMPORT_LOOKUP",
77 "ZEBRA_ROUTER_ID_ADD",
78 "ZEBRA_ROUTER_ID_DELETE",
79 "ZEBRA_ROUTER_ID_UPDATE"
718e3744 80};
81\f
ccf3557b 82
719e9741 83static void zebra_client_close (struct zserv *client);
ccf3557b 84
719e9741 85static int
86zserv_delayed_close(struct thread *thread)
ccf3557b 87{
719e9741 88 struct zserv *client = THREAD_ARG(thread);
ccf3557b 89
719e9741 90 client->t_suicide = NULL;
91 zebra_client_close(client);
ccf3557b 92 return 0;
93}
94
719e9741 95static int
96zserv_flush_data(struct thread *thread)
ccf3557b 97{
719e9741 98 struct zserv *client = THREAD_ARG(thread);
ccf3557b 99
719e9741 100 client->t_write = NULL;
101 if (client->t_suicide)
ccf3557b 102 {
719e9741 103 zebra_client_close(client);
104 return -1;
ccf3557b 105 }
719e9741 106 switch (buffer_flush_available(client->wb, client->sock))
ccf3557b 107 {
719e9741 108 case BUFFER_ERROR:
109 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
110 "closing", __func__, client->sock);
111 zebra_client_close(client);
112 break;
113 case BUFFER_PENDING:
114 client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
115 client, client->sock);
116 break;
117 case BUFFER_EMPTY:
118 break;
ccf3557b 119 }
719e9741 120 return 0;
121}
ccf3557b 122
719e9741 123static int
124zebra_server_send_message(struct zserv *client)
125{
126 if (client->t_suicide)
127 return -1;
128 switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
129 stream_get_endp(client->obuf)))
130 {
131 case BUFFER_ERROR:
132 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
133 __func__, client->sock);
134 /* Schedule a delayed close since many of the functions that call this
135 one do not check the return code. They do not allow for the
136 possibility that an I/O error may have caused the client to be
137 deleted. */
138 client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
139 client, 0);
140 return -1;
141 break;
142 case BUFFER_EMPTY:
143 THREAD_OFF(client->t_write);
144 break;
145 case BUFFER_PENDING:
146 THREAD_WRITE_ON(zebrad.master, client->t_write,
147 zserv_flush_data, client, client->sock);
148 break;
149 }
ccf3557b 150 return 0;
151}
152
718e3744 153/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
b9df2d25 154/*
155 * This function is called in the following situations:
156 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
157 * from the client.
158 * - at startup, when zebra figures out the available interfaces
159 * - when an interface is added (where support for
160 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
161 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
162 * received)
163 */
718e3744 164int
165zsend_interface_add (struct zserv *client, struct interface *ifp)
166{
167 struct stream *s;
168
169 /* Check this client need interface information. */
170 if (! client->ifinfo)
719e9741 171 return 0;
718e3744 172
173 s = client->obuf;
174 stream_reset (s);
175
176 /* Place holder for size. */
177 stream_putw (s, 0);
178
179 /* Message type. */
180 stream_putc (s, ZEBRA_INTERFACE_ADD);
181
182 /* Interface information. */
183 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
184 stream_putl (s, ifp->ifindex);
2e3b2e47 185 stream_putc (s, ifp->status);
718e3744 186 stream_putl (s, ifp->flags);
187 stream_putl (s, ifp->metric);
188 stream_putl (s, ifp->mtu);
b9df2d25 189 stream_putl (s, ifp->mtu6);
718e3744 190 stream_putl (s, ifp->bandwidth);
191#ifdef HAVE_SOCKADDR_DL
192 stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
193#else
194 stream_putl (s, ifp->hw_addr_len);
195 if (ifp->hw_addr_len)
196 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
197#endif /* HAVE_SOCKADDR_DL */
198
199 /* Write packet size. */
200 stream_putw_at (s, 0, stream_get_endp (s));
201
719e9741 202 return zebra_server_send_message(client);
718e3744 203}
204
205/* Interface deletion from zebra daemon. */
b9df2d25 206/*
207 * This function is only called when support for
208 * RTM_IFANNOUNCE or AF_NETLINK sockets (RTM_DELLINK message)
209 * is available. It is not called on Solaris.
210 */
211#if (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK))
718e3744 212int
213zsend_interface_delete (struct zserv *client, struct interface *ifp)
214{
215 struct stream *s;
216
217 /* Check this client need interface information. */
218 if (! client->ifinfo)
719e9741 219 return 0;
718e3744 220
221 s = client->obuf;
222 stream_reset (s);
223
224 /* Packet length placeholder. */
225 stream_putw (s, 0);
226
227 /* Interface information. */
228 stream_putc (s, ZEBRA_INTERFACE_DELETE);
229 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
230 stream_putl (s, ifp->ifindex);
2e3b2e47 231 stream_putc (s, ifp->status);
718e3744 232 stream_putl (s, ifp->flags);
233 stream_putl (s, ifp->metric);
234 stream_putl (s, ifp->mtu);
b9df2d25 235 stream_putl (s, ifp->mtu6);
718e3744 236 stream_putl (s, ifp->bandwidth);
237
238 /* Write packet length. */
239 stream_putw_at (s, 0, stream_get_endp (s));
240
719e9741 241 return zebra_server_send_message (client);
718e3744 242}
b9df2d25 243#endif /* (defined(RTM_IFANNOUNCE) || defined(HAVE_LINUX_RTNETLINK_H)) */
718e3744 244
b9df2d25 245/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
246 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
247 *
248 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
249 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
250 * from the client, after the ZEBRA_INTERFACE_ADD has been
251 * sent from zebra to the client
252 * - redistribute new address info to all clients in the following situations
253 * - at startup, when zebra figures out the available interfaces
254 * - when an interface is added (where support for
255 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
256 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
257 * received)
258 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
259 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
260 * - when an RTM_NEWADDR message is received from the kernel,
261 *
262 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
263 *
264 * zsend_interface_address(DELETE)
265 * ^
266 * |
267 * zebra_interface_address_delete_update
268 * ^ ^ ^
269 * | | if_delete_update (not called on
270 * | | Solaris)
271 * ip_address_uninstall connected_delete_ipv4
272 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
273 * ^ ^
274 * | |
275 * | RTM_NEWADDR on routing/netlink socket
276 * |
277 * vty commands:
278 * "no ip address A.B.C.D/M [label LINE]"
279 * "no ip address A.B.C.D/M secondary"
280 * ["no ipv6 address X:X::X:X/M"]
281 *
282 */
718e3744 283int
b9df2d25 284zsend_interface_address (int cmd, struct zserv *client,
285 struct interface *ifp, struct connected *ifc)
718e3744 286{
287 int blen;
288 struct stream *s;
289 struct prefix *p;
290
291 /* Check this client need interface information. */
292 if (! client->ifinfo)
719e9741 293 return 0;
718e3744 294
295 s = client->obuf;
296 stream_reset (s);
297
298 /* Place holder for size. */
299 stream_putw (s, 0);
300
b9df2d25 301 stream_putc (s, cmd);
718e3744 302 stream_putl (s, ifp->ifindex);
303
304 /* Interface address flag. */
305 stream_putc (s, ifc->flags);
306
307 /* Prefix information. */
308 p = ifc->address;
309 stream_putc (s, p->family);
310 blen = prefix_blen (p);
311 stream_put (s, &p->u.prefix, blen);
b9df2d25 312
313 /*
314 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
315 * but zebra_interface_address_delete_read() in the gnu version
316 * expects to find it
317 */
718e3744 318 stream_putc (s, p->prefixlen);
319
320 /* Destination. */
321 p = ifc->destination;
322 if (p)
323 stream_put (s, &p->u.prefix, blen);
324 else
325 stream_put (s, NULL, blen);
326
327 /* Write packet size. */
328 stream_putw_at (s, 0, stream_get_endp (s));
329
719e9741 330 return zebra_server_send_message(client);
718e3744 331}
332
b9df2d25 333/*
334 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
335 * ZEBRA_INTERFACE_DOWN.
336 *
337 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
338 * the clients in one of 2 situations:
339 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
340 * - a vty command modifying the bandwidth of an interface is received.
341 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
342 */
718e3744 343int
b9df2d25 344zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
718e3744 345{
346 struct stream *s;
347
348 /* Check this client need interface information. */
349 if (! client->ifinfo)
719e9741 350 return 0;
718e3744 351
352 s = client->obuf;
353 stream_reset (s);
354
355 /* Place holder for size. */
356 stream_putw (s, 0);
357
358 /* Zebra command. */
b9df2d25 359 stream_putc (s, cmd);
718e3744 360
361 /* Interface information. */
362 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
363 stream_putl (s, ifp->ifindex);
2e3b2e47 364 stream_putc (s, ifp->status);
718e3744 365 stream_putl (s, ifp->flags);
366 stream_putl (s, ifp->metric);
367 stream_putl (s, ifp->mtu);
b9df2d25 368 stream_putl (s, ifp->mtu6);
718e3744 369 stream_putl (s, ifp->bandwidth);
370
371 /* Write packet size. */
372 stream_putw_at (s, 0, stream_get_endp (s));
373
719e9741 374 return zebra_server_send_message(client);
718e3744 375}
376
b9df2d25 377/*
378 * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
379 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
380 * situations:
381 * - when the client starts up, and requests default information
382 * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
383 * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
384 * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
385 * - when the zebra server redistributes routes after it updates its rib
386 *
387 * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
388 * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
389 * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
390 * - deleted from zebra's rib, and this info
391 * has to be redistributed to the clients
392 *
393 * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
394 * zebra server when the client wants to tell the zebra server to add a
395 * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
396 * same message being sent back and forth, this function and
397 * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
398 * duplication.
399 */
718e3744 400int
b9df2d25 401zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
402 struct rib *rib)
718e3744 403{
404 int psize;
405 struct stream *s;
406 struct nexthop *nexthop;
1dcb5172 407 unsigned long nhnummark = 0, messmark = 0;
b9df2d25 408 int nhnum = 0;
1dcb5172 409 u_char zapi_flags = 0;
b9df2d25 410
718e3744 411 s = client->obuf;
412 stream_reset (s);
413
414 /* Place holder for size. */
415 stream_putw (s, 0);
416
417 /* Put command, type and nexthop. */
b9df2d25 418 stream_putc (s, cmd);
718e3744 419 stream_putc (s, rib->type);
420 stream_putc (s, rib->flags);
1dcb5172 421
422 /* marker for message flags field */
423 messmark = stream_get_endp (s);
424 stream_putc (s, 0);
718e3744 425
426 /* Prefix. */
427 psize = PSIZE (p->prefixlen);
428 stream_putc (s, p->prefixlen);
b9df2d25 429 stream_write (s, (u_char *) & p->u.prefix, psize);
430
431 /*
432 * XXX The message format sent by zebra below does not match the format
433 * of the corresponding message expected by the zebra server
434 * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
435 * (is there a bug on the client side if more than one segment is sent?)
436 * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
437 * is hard-coded.
438 */
718e3744 439 /* Nexthop */
1dcb5172 440
718e3744 441 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
442 {
443 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
b9df2d25 444 {
1dcb5172 445 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
446 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
447
448 if (nhnummark == 0)
449 {
450 nhnummark = stream_get_endp (s);
451 stream_putc (s, 1); /* placeholder */
452 }
453
b9df2d25 454 nhnum++;
455
456 switch(nexthop->type)
457 {
458 case NEXTHOP_TYPE_IPV4:
459 case NEXTHOP_TYPE_IPV4_IFINDEX:
460 stream_put_in_addr (s, &nexthop->gate.ipv4);
461 break;
718e3744 462#ifdef HAVE_IPV6
b9df2d25 463 case NEXTHOP_TYPE_IPV6:
464 case NEXTHOP_TYPE_IPV6_IFINDEX:
465 case NEXTHOP_TYPE_IPV6_IFNAME:
466 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
467 break;
468#endif
469 default:
470 if (cmd == ZEBRA_IPV4_ROUTE_ADD
471 || cmd == ZEBRA_IPV4_ROUTE_DELETE)
472 {
473 struct in_addr empty;
44983cf8 474 memset (&empty, 0, sizeof (struct in_addr));
b9df2d25 475 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
476 }
477 else
478 {
479 struct in6_addr empty;
480 memset (&empty, 0, sizeof (struct in6_addr));
481 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
482 }
483 }
484
485 /* Interface index. */
486 stream_putc (s, 1);
487 stream_putl (s, nexthop->ifindex);
488
489 break;
490 }
718e3744 491 }
492
493 /* Metric */
1dcb5172 494 if (cmd == ZEBRA_IPV4_ROUTE_ADD || ZEBRA_IPV6_ROUTE_ADD)
495 {
496 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
497 stream_putl (s, rib->metric);
498 }
499
500 /* write real message flags value */
501 stream_putc_at (s, messmark, zapi_flags);
502
b9df2d25 503 /* Write next-hop number */
504 if (nhnummark)
c1eaa442 505 stream_putc_at (s, nhnummark, nhnum);
b9df2d25 506
718e3744 507 /* Write packet size. */
508 stream_putw_at (s, 0, stream_get_endp (s));
509
719e9741 510 return zebra_server_send_message(client);
718e3744 511}
512
b9df2d25 513#ifdef HAVE_IPV6
719e9741 514static int
718e3744 515zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
516{
517 struct stream *s;
518 struct rib *rib;
519 unsigned long nump;
520 u_char num;
521 struct nexthop *nexthop;
522
523 /* Lookup nexthop. */
524 rib = rib_match_ipv6 (addr);
525
526 /* Get output stream. */
527 s = client->obuf;
528 stream_reset (s);
529
530 /* Fill in result. */
531 stream_putw (s, 0);
532 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
533 stream_put (s, &addr, 16);
534
535 if (rib)
536 {
537 stream_putl (s, rib->metric);
538 num = 0;
9985f83c 539 nump = stream_get_endp(s);
718e3744 540 stream_putc (s, 0);
541 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
542 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
543 {
544 stream_putc (s, nexthop->type);
545 switch (nexthop->type)
546 {
547 case ZEBRA_NEXTHOP_IPV6:
548 stream_put (s, &nexthop->gate.ipv6, 16);
549 break;
550 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
551 case ZEBRA_NEXTHOP_IPV6_IFNAME:
552 stream_put (s, &nexthop->gate.ipv6, 16);
553 stream_putl (s, nexthop->ifindex);
554 break;
555 case ZEBRA_NEXTHOP_IFINDEX:
556 case ZEBRA_NEXTHOP_IFNAME:
557 stream_putl (s, nexthop->ifindex);
558 break;
fa2b17e3 559 default:
560 /* do nothing */
561 break;
718e3744 562 }
563 num++;
564 }
565 stream_putc_at (s, nump, num);
566 }
567 else
568 {
569 stream_putl (s, 0);
570 stream_putc (s, 0);
571 }
572
573 stream_putw_at (s, 0, stream_get_endp (s));
574
719e9741 575 return zebra_server_send_message(client);
718e3744 576}
577#endif /* HAVE_IPV6 */
578
b9df2d25 579static int
718e3744 580zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
581{
582 struct stream *s;
583 struct rib *rib;
584 unsigned long nump;
585 u_char num;
586 struct nexthop *nexthop;
587
588 /* Lookup nexthop. */
589 rib = rib_match_ipv4 (addr);
590
591 /* Get output stream. */
592 s = client->obuf;
593 stream_reset (s);
594
595 /* Fill in result. */
596 stream_putw (s, 0);
597 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
598 stream_put_in_addr (s, &addr);
599
600 if (rib)
601 {
602 stream_putl (s, rib->metric);
603 num = 0;
9985f83c 604 nump = stream_get_endp(s);
718e3744 605 stream_putc (s, 0);
606 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
607 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
608 {
609 stream_putc (s, nexthop->type);
610 switch (nexthop->type)
611 {
612 case ZEBRA_NEXTHOP_IPV4:
613 stream_put_in_addr (s, &nexthop->gate.ipv4);
614 break;
615 case ZEBRA_NEXTHOP_IFINDEX:
616 case ZEBRA_NEXTHOP_IFNAME:
617 stream_putl (s, nexthop->ifindex);
618 break;
fa2b17e3 619 default:
620 /* do nothing */
621 break;
718e3744 622 }
623 num++;
624 }
625 stream_putc_at (s, nump, num);
626 }
627 else
628 {
629 stream_putl (s, 0);
630 stream_putc (s, 0);
631 }
632
633 stream_putw_at (s, 0, stream_get_endp (s));
634
719e9741 635 return zebra_server_send_message(client);
718e3744 636}
637
b9df2d25 638static int
718e3744 639zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
640{
641 struct stream *s;
642 struct rib *rib;
643 unsigned long nump;
644 u_char num;
645 struct nexthop *nexthop;
646
647 /* Lookup nexthop. */
648 rib = rib_lookup_ipv4 (p);
649
650 /* Get output stream. */
651 s = client->obuf;
652 stream_reset (s);
653
654 /* Fill in result. */
655 stream_putw (s, 0);
656 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
657 stream_put_in_addr (s, &p->prefix);
658
659 if (rib)
660 {
661 stream_putl (s, rib->metric);
662 num = 0;
9985f83c 663 nump = stream_get_endp(s);
718e3744 664 stream_putc (s, 0);
665 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
666 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
667 {
668 stream_putc (s, nexthop->type);
669 switch (nexthop->type)
670 {
671 case ZEBRA_NEXTHOP_IPV4:
672 stream_put_in_addr (s, &nexthop->gate.ipv4);
673 break;
674 case ZEBRA_NEXTHOP_IFINDEX:
675 case ZEBRA_NEXTHOP_IFNAME:
676 stream_putl (s, nexthop->ifindex);
677 break;
fa2b17e3 678 default:
679 /* do nothing */
680 break;
718e3744 681 }
682 num++;
683 }
684 stream_putc_at (s, nump, num);
685 }
686 else
687 {
688 stream_putl (s, 0);
689 stream_putc (s, 0);
690 }
691
692 stream_putw_at (s, 0, stream_get_endp (s));
693
719e9741 694 return zebra_server_send_message(client);
718e3744 695}
696\f
18a6dce6 697/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
698int
699zsend_router_id_update (struct zserv *client, struct prefix *p)
700{
701 struct stream *s;
702 int blen;
703
704 /* Check this client need interface information. */
705 if (!client->ridinfo)
719e9741 706 return 0;
18a6dce6 707
708 s = client->obuf;
709 stream_reset (s);
710
711 /* Place holder for size. */
712 stream_putw (s, 0);
713
714 /* Message type. */
715 stream_putc (s, ZEBRA_ROUTER_ID_UPDATE);
716
717 /* Prefix information. */
718 stream_putc (s, p->family);
719 blen = prefix_blen (p);
720 stream_put (s, &p->u.prefix, blen);
721 stream_putc (s, p->prefixlen);
722
723 /* Write packet size. */
724 stream_putw_at (s, 0, stream_get_endp (s));
725
719e9741 726 return zebra_server_send_message(client);
18a6dce6 727}
728\f
718e3744 729/* Register zebra server interface information. Send current all
730 interface and address information. */
719e9741 731static int
718e3744 732zread_interface_add (struct zserv *client, u_short length)
733{
1eb8ef25 734 struct listnode *ifnode, *ifnnode;
735 struct listnode *cnode, *cnnode;
718e3744 736 struct interface *ifp;
737 struct connected *c;
738
739 /* Interface information is needed. */
740 client->ifinfo = 1;
741
1eb8ef25 742 for (ALL_LIST_ELEMENTS (iflist, ifnode, ifnnode, ifp))
718e3744 743 {
718e3744 744 /* Skip pseudo interface. */
745 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
746 continue;
747
719e9741 748 if (zsend_interface_add (client, ifp) < 0)
749 return -1;
718e3744 750
1eb8ef25 751 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
718e3744 752 {
719e9741 753 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
754 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
755 ifp, c) < 0))
756 return -1;
718e3744 757 }
758 }
719e9741 759 return 0;
718e3744 760}
761
762/* Unregister zebra server interface information. */
719e9741 763static int
718e3744 764zread_interface_delete (struct zserv *client, u_short length)
765{
766 client->ifinfo = 0;
719e9741 767 return 0;
718e3744 768}
769
770/* This function support multiple nexthop. */
b9df2d25 771/*
772 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
773 * add kernel route.
774 */
719e9741 775static int
718e3744 776zread_ipv4_add (struct zserv *client, u_short length)
777{
778 int i;
779 struct rib *rib;
780 struct prefix_ipv4 p;
781 u_char message;
782 struct in_addr nexthop;
783 u_char nexthop_num;
784 u_char nexthop_type;
785 struct stream *s;
786 unsigned int ifindex;
787 u_char ifname_len;
788
789 /* Get input stream. */
790 s = client->ibuf;
791
792 /* Allocate new rib. */
4d38fdb4 793 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
794
718e3744 795 /* Type, flags, message. */
796 rib->type = stream_getc (s);
797 rib->flags = stream_getc (s);
b9df2d25 798 message = stream_getc (s);
718e3744 799 rib->uptime = time (NULL);
800
801 /* IPv4 prefix. */
802 memset (&p, 0, sizeof (struct prefix_ipv4));
803 p.family = AF_INET;
804 p.prefixlen = stream_getc (s);
805 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
806
807 /* Nexthop parse. */
808 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
809 {
810 nexthop_num = stream_getc (s);
811
812 for (i = 0; i < nexthop_num; i++)
813 {
814 nexthop_type = stream_getc (s);
815
816 switch (nexthop_type)
817 {
818 case ZEBRA_NEXTHOP_IFINDEX:
819 ifindex = stream_getl (s);
820 nexthop_ifindex_add (rib, ifindex);
821 break;
822 case ZEBRA_NEXTHOP_IFNAME:
823 ifname_len = stream_getc (s);
9985f83c 824 stream_forward_getp (s, ifname_len);
718e3744 825 break;
826 case ZEBRA_NEXTHOP_IPV4:
827 nexthop.s_addr = stream_get_ipv4 (s);
828 nexthop_ipv4_add (rib, &nexthop);
829 break;
830 case ZEBRA_NEXTHOP_IPV6:
9985f83c 831 stream_forward_getp (s, IPV6_MAX_BYTELEN);
718e3744 832 break;
595db7f1 833 case ZEBRA_NEXTHOP_BLACKHOLE:
834 nexthop_blackhole_add (rib);
835 break;
718e3744 836 }
837 }
838 }
839
840 /* Distance. */
841 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
842 rib->distance = stream_getc (s);
843
844 /* Metric. */
845 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
846 rib->metric = stream_getl (s);
847
848 rib_add_ipv4_multipath (&p, rib);
719e9741 849 return 0;
718e3744 850}
851
852/* Zebra server IPv4 prefix delete function. */
719e9741 853static int
718e3744 854zread_ipv4_delete (struct zserv *client, u_short length)
855{
856 int i;
857 struct stream *s;
858 struct zapi_ipv4 api;
859 struct in_addr nexthop;
860 unsigned long ifindex;
861 struct prefix_ipv4 p;
862 u_char nexthop_num;
863 u_char nexthop_type;
864 u_char ifname_len;
865
866 s = client->ibuf;
867 ifindex = 0;
868 nexthop.s_addr = 0;
869
870 /* Type, flags, message. */
871 api.type = stream_getc (s);
872 api.flags = stream_getc (s);
873 api.message = stream_getc (s);
874
875 /* IPv4 prefix. */
876 memset (&p, 0, sizeof (struct prefix_ipv4));
877 p.family = AF_INET;
878 p.prefixlen = stream_getc (s);
879 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
880
881 /* Nexthop, ifindex, distance, metric. */
882 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
883 {
884 nexthop_num = stream_getc (s);
885
886 for (i = 0; i < nexthop_num; i++)
887 {
888 nexthop_type = stream_getc (s);
889
890 switch (nexthop_type)
891 {
892 case ZEBRA_NEXTHOP_IFINDEX:
893 ifindex = stream_getl (s);
894 break;
895 case ZEBRA_NEXTHOP_IFNAME:
896 ifname_len = stream_getc (s);
9985f83c 897 stream_forward_getp (s, ifname_len);
718e3744 898 break;
899 case ZEBRA_NEXTHOP_IPV4:
900 nexthop.s_addr = stream_get_ipv4 (s);
901 break;
902 case ZEBRA_NEXTHOP_IPV6:
9985f83c 903 stream_forward_getp (s, IPV6_MAX_BYTELEN);
718e3744 904 break;
905 }
906 }
907 }
908
909 /* Distance. */
910 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
911 api.distance = stream_getc (s);
912 else
913 api.distance = 0;
914
915 /* Metric. */
916 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
917 api.metric = stream_getl (s);
918 else
919 api.metric = 0;
920
921 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
922 client->rtm_table);
719e9741 923 return 0;
718e3744 924}
925
926/* Nexthop lookup for IPv4. */
719e9741 927static int
718e3744 928zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
929{
930 struct in_addr addr;
931
932 addr.s_addr = stream_get_ipv4 (client->ibuf);
719e9741 933 return zsend_ipv4_nexthop_lookup (client, addr);
718e3744 934}
935
936/* Nexthop lookup for IPv4. */
719e9741 937static int
718e3744 938zread_ipv4_import_lookup (struct zserv *client, u_short length)
939{
940 struct prefix_ipv4 p;
941
942 p.family = AF_INET;
943 p.prefixlen = stream_getc (client->ibuf);
944 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
945
719e9741 946 return zsend_ipv4_import_lookup (client, &p);
718e3744 947}
948
949#ifdef HAVE_IPV6
950/* Zebra server IPv6 prefix add function. */
719e9741 951static int
718e3744 952zread_ipv6_add (struct zserv *client, u_short length)
953{
954 int i;
955 struct stream *s;
956 struct zapi_ipv6 api;
957 struct in6_addr nexthop;
958 unsigned long ifindex;
959 struct prefix_ipv6 p;
960
961 s = client->ibuf;
962 ifindex = 0;
963 memset (&nexthop, 0, sizeof (struct in6_addr));
964
965 /* Type, flags, message. */
966 api.type = stream_getc (s);
967 api.flags = stream_getc (s);
968 api.message = stream_getc (s);
969
970 /* IPv4 prefix. */
971 memset (&p, 0, sizeof (struct prefix_ipv6));
972 p.family = AF_INET6;
973 p.prefixlen = stream_getc (s);
974 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
975
976 /* Nexthop, ifindex, distance, metric. */
977 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
978 {
979 u_char nexthop_type;
980
981 api.nexthop_num = stream_getc (s);
982 for (i = 0; i < api.nexthop_num; i++)
983 {
984 nexthop_type = stream_getc (s);
985
986 switch (nexthop_type)
987 {
988 case ZEBRA_NEXTHOP_IPV6:
989 stream_get (&nexthop, s, 16);
990 break;
991 case ZEBRA_NEXTHOP_IFINDEX:
992 ifindex = stream_getl (s);
993 break;
994 }
995 }
996 }
997
998 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
999 api.distance = stream_getc (s);
1000 else
1001 api.distance = 0;
1002
1003 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1004 api.metric = stream_getl (s);
1005 else
1006 api.metric = 0;
1007
1008 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1009 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1010 else
1011 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
719e9741 1012 return 0;
718e3744 1013}
1014
1015/* Zebra server IPv6 prefix delete function. */
719e9741 1016static int
718e3744 1017zread_ipv6_delete (struct zserv *client, u_short length)
1018{
1019 int i;
1020 struct stream *s;
1021 struct zapi_ipv6 api;
1022 struct in6_addr nexthop;
1023 unsigned long ifindex;
1024 struct prefix_ipv6 p;
1025
1026 s = client->ibuf;
1027 ifindex = 0;
1028 memset (&nexthop, 0, sizeof (struct in6_addr));
1029
1030 /* Type, flags, message. */
1031 api.type = stream_getc (s);
1032 api.flags = stream_getc (s);
1033 api.message = stream_getc (s);
1034
1035 /* IPv4 prefix. */
1036 memset (&p, 0, sizeof (struct prefix_ipv6));
1037 p.family = AF_INET6;
1038 p.prefixlen = stream_getc (s);
1039 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1040
1041 /* Nexthop, ifindex, distance, metric. */
1042 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1043 {
1044 u_char nexthop_type;
1045
1046 api.nexthop_num = stream_getc (s);
1047 for (i = 0; i < api.nexthop_num; i++)
1048 {
1049 nexthop_type = stream_getc (s);
1050
1051 switch (nexthop_type)
1052 {
1053 case ZEBRA_NEXTHOP_IPV6:
1054 stream_get (&nexthop, s, 16);
1055 break;
1056 case ZEBRA_NEXTHOP_IFINDEX:
1057 ifindex = stream_getl (s);
1058 break;
1059 }
1060 }
1061 }
1062
1063 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1064 api.distance = stream_getc (s);
1065 else
1066 api.distance = 0;
1067 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1068 api.metric = stream_getl (s);
1069 else
1070 api.metric = 0;
1071
1072 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1073 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1074 else
1075 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
719e9741 1076 return 0;
718e3744 1077}
1078
719e9741 1079static int
718e3744 1080zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1081{
1082 struct in6_addr addr;
1083 char buf[BUFSIZ];
1084
1085 stream_get (&addr, client->ibuf, 16);
1086 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1087
719e9741 1088 return zsend_ipv6_nexthop_lookup (client, &addr);
718e3744 1089}
1090#endif /* HAVE_IPV6 */
1091
18a6dce6 1092/* Register zebra server router-id information. Send current router-id */
719e9741 1093static int
18a6dce6 1094zread_router_id_add (struct zserv *client, u_short length)
1095{
1096 struct prefix p;
1097
1098 /* Router-id information is needed. */
1099 client->ridinfo = 1;
1100
1101 router_id_get (&p);
1102
719e9741 1103 return zsend_router_id_update (client,&p);
18a6dce6 1104}
1105
1106/* Unregister zebra server router-id information. */
719e9741 1107static int
18a6dce6 1108zread_router_id_delete (struct zserv *client, u_short length)
1109{
1110 client->ridinfo = 0;
719e9741 1111 return 0;
18a6dce6 1112}
1113
718e3744 1114/* Close zebra client. */
b9df2d25 1115static void
718e3744 1116zebra_client_close (struct zserv *client)
1117{
1118 /* Close file descriptor. */
1119 if (client->sock)
1120 {
1121 close (client->sock);
1122 client->sock = -1;
1123 }
1124
1125 /* Free stream buffers. */
1126 if (client->ibuf)
1127 stream_free (client->ibuf);
1128 if (client->obuf)
1129 stream_free (client->obuf);
719e9741 1130 if (client->wb)
1131 buffer_free(client->wb);
718e3744 1132
1133 /* Release threads. */
1134 if (client->t_read)
1135 thread_cancel (client->t_read);
1136 if (client->t_write)
1137 thread_cancel (client->t_write);
719e9741 1138 if (client->t_suicide)
1139 thread_cancel (client->t_suicide);
718e3744 1140
1141 /* Free client structure. */
b21b19c5 1142 listnode_delete (zebrad.client_list, client);
718e3744 1143 XFREE (0, client);
1144}
1145
1146/* Make new client. */
b9df2d25 1147static void
718e3744 1148zebra_client_create (int sock)
1149{
1150 struct zserv *client;
1151
1152 client = XCALLOC (0, sizeof (struct zserv));
1153
1154 /* Make client input/output buffer. */
1155 client->sock = sock;
1156 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1157 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
719e9741 1158 client->wb = buffer_new(0);
718e3744 1159
1160 /* Set table number. */
b21b19c5 1161 client->rtm_table = zebrad.rtm_table_default;
718e3744 1162
1163 /* Add this client to linked list. */
b21b19c5 1164 listnode_add (zebrad.client_list, client);
718e3744 1165
1166 /* Make new read thread. */
1167 zebra_event (ZEBRA_READ, sock, client);
1168}
1169
1170/* Handler of zebra service request. */
b9df2d25 1171static int
718e3744 1172zebra_client_read (struct thread *thread)
1173{
1174 int sock;
1175 struct zserv *client;
57a1477b 1176 size_t already;
718e3744 1177 u_short length;
1178 u_char command;
1179
1180 /* Get thread data. Reset reading thread because I'm running. */
1181 sock = THREAD_FD (thread);
1182 client = THREAD_ARG (thread);
1183 client->t_read = NULL;
1184
719e9741 1185 if (client->t_suicide)
718e3744 1186 {
719e9741 1187 zebra_client_close(client);
718e3744 1188 return -1;
1189 }
719e9741 1190
1191 /* Read length and command (if we don't have it already). */
57a1477b 1192 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
719e9741 1193 {
57a1477b 1194 ssize_t nbyte;
719e9741 1195 if (((nbyte = stream_read_try (client->ibuf, sock,
57a1477b 1196 ZEBRA_HEADER_SIZE-already)) == 0) ||
719e9741 1197 (nbyte == -1))
1198 {
1199 if (IS_ZEBRA_DEBUG_EVENT)
1200 zlog_debug ("connection closed socket [%d]", sock);
1201 zebra_client_close (client);
1202 return -1;
1203 }
57a1477b 1204 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
719e9741 1205 {
1206 /* Try again later. */
1207 zebra_event (ZEBRA_READ, sock, client);
1208 return 0;
1209 }
57a1477b 1210 already = ZEBRA_HEADER_SIZE;
719e9741 1211 }
1212
1213 /* Reset to read from the beginning of the incoming packet. */
1214 stream_set_getp(client->ibuf, 0);
1215
718e3744 1216 length = stream_getw (client->ibuf);
1217 command = stream_getc (client->ibuf);
1218
719e9741 1219 if (length < ZEBRA_HEADER_SIZE)
718e3744 1220 {
57a1477b 1221 zlog_warn("%s: socket %d message length %u is less than header size %d",
1222 __func__, sock, length, ZEBRA_HEADER_SIZE);
1223 zebra_client_close (client);
1224 return -1;
1225 }
1226 if (length > STREAM_SIZE(client->ibuf))
1227 {
1228 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1229 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
718e3744 1230 zebra_client_close (client);
1231 return -1;
1232 }
1233
718e3744 1234 /* Read rest of data. */
57a1477b 1235 if (already < length)
718e3744 1236 {
57a1477b 1237 ssize_t nbyte;
1238 if (((nbyte = stream_read_try (client->ibuf, sock,
1239 length-already)) == 0) ||
1240 (nbyte == -1))
718e3744 1241 {
1242 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 1243 zlog_debug ("connection closed [%d] when reading zebra data", sock);
718e3744 1244 zebra_client_close (client);
1245 return -1;
1246 }
57a1477b 1247 if (nbyte != (ssize_t)(length-already))
719e9741 1248 {
1249 /* Try again later. */
1250 zebra_event (ZEBRA_READ, sock, client);
1251 return 0;
1252 }
718e3744 1253 }
1254
719e9741 1255 length -= ZEBRA_HEADER_SIZE;
1256
718e3744 1257 /* Debug packet information. */
1258 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 1259 zlog_debug ("zebra message comes from socket [%d]", sock);
718e3744 1260
1261 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
b6178002 1262 zlog_debug ("zebra message received [%s] %d",
718e3744 1263 zebra_command_str[command], length);
1264
1265 switch (command)
1266 {
18a6dce6 1267 case ZEBRA_ROUTER_ID_ADD:
1268 zread_router_id_add (client, length);
1269 break;
1270 case ZEBRA_ROUTER_ID_DELETE:
1271 zread_router_id_delete (client, length);
1272 break;
718e3744 1273 case ZEBRA_INTERFACE_ADD:
1274 zread_interface_add (client, length);
1275 break;
1276 case ZEBRA_INTERFACE_DELETE:
1277 zread_interface_delete (client, length);
1278 break;
1279 case ZEBRA_IPV4_ROUTE_ADD:
1280 zread_ipv4_add (client, length);
1281 break;
1282 case ZEBRA_IPV4_ROUTE_DELETE:
1283 zread_ipv4_delete (client, length);
1284 break;
1285#ifdef HAVE_IPV6
1286 case ZEBRA_IPV6_ROUTE_ADD:
1287 zread_ipv6_add (client, length);
1288 break;
1289 case ZEBRA_IPV6_ROUTE_DELETE:
1290 zread_ipv6_delete (client, length);
1291 break;
1292#endif /* HAVE_IPV6 */
1293 case ZEBRA_REDISTRIBUTE_ADD:
1294 zebra_redistribute_add (command, client, length);
1295 break;
1296 case ZEBRA_REDISTRIBUTE_DELETE:
1297 zebra_redistribute_delete (command, client, length);
1298 break;
1299 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1300 zebra_redistribute_default_add (command, client, length);
1301 break;
1302 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1303 zebra_redistribute_default_delete (command, client, length);
1304 break;
1305 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1306 zread_ipv4_nexthop_lookup (client, length);
1307 break;
1308#ifdef HAVE_IPV6
1309 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1310 zread_ipv6_nexthop_lookup (client, length);
1311 break;
1312#endif /* HAVE_IPV6 */
1313 case ZEBRA_IPV4_IMPORT_LOOKUP:
1314 zread_ipv4_import_lookup (client, length);
1315 break;
1316 default:
1317 zlog_info ("Zebra received unknown command %d", command);
1318 break;
1319 }
1320
719e9741 1321 if (client->t_suicide)
1322 {
1323 /* No need to wait for thread callback, just kill immediately. */
1324 zebra_client_close(client);
1325 return -1;
1326 }
1327
718e3744 1328 stream_reset (client->ibuf);
1329 zebra_event (ZEBRA_READ, sock, client);
718e3744 1330 return 0;
1331}
1332
718e3744 1333
1334/* Accept code of zebra server socket. */
b9df2d25 1335static int
718e3744 1336zebra_accept (struct thread *thread)
1337{
1338 int accept_sock;
1339 int client_sock;
1340 struct sockaddr_in client;
1341 socklen_t len;
1342
1343 accept_sock = THREAD_FD (thread);
1344
719e9741 1345 /* Reregister myself. */
1346 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1347
718e3744 1348 len = sizeof (struct sockaddr_in);
1349 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1350
1351 if (client_sock < 0)
1352 {
6099b3b5 1353 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
718e3744 1354 return -1;
1355 }
1356
ccf3557b 1357 /* Make client socket non-blocking. */
719e9741 1358 set_nonblocking(client_sock);
865b852c 1359
718e3744 1360 /* Create new zebra client. */
1361 zebra_client_create (client_sock);
1362
718e3744 1363 return 0;
1364}
1365
b9df2d25 1366#ifdef HAVE_TCP_ZEBRA
718e3744 1367/* Make zebra's server socket. */
b9df2d25 1368static void
718e3744 1369zebra_serv ()
1370{
1371 int ret;
1372 int accept_sock;
1373 struct sockaddr_in addr;
1374
1375 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1376
1377 if (accept_sock < 0)
1378 {
3d1dc857 1379 zlog_warn ("Can't create zserv stream socket: %s",
1380 safe_strerror (errno));
718e3744 1381 zlog_warn ("zebra can't provice full functionality due to above error");
1382 return;
1383 }
1384
1385 memset (&addr, 0, sizeof (struct sockaddr_in));
1386 addr.sin_family = AF_INET;
1387 addr.sin_port = htons (ZEBRA_PORT);
1388#ifdef HAVE_SIN_LEN
1389 addr.sin_len = sizeof (struct sockaddr_in);
1390#endif /* HAVE_SIN_LEN */
1391 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1392
1393 sockopt_reuseaddr (accept_sock);
1394 sockopt_reuseport (accept_sock);
1395
edd7c245 1396 if ( zserv_privs.change(ZPRIVS_RAISE) )
1397 zlog (NULL, LOG_ERR, "Can't raise privileges");
1398
718e3744 1399 ret = bind (accept_sock, (struct sockaddr *)&addr,
1400 sizeof (struct sockaddr_in));
1401 if (ret < 0)
1402 {
3d1dc857 1403 zlog_warn ("Can't bind to stream socket: %s",
1404 safe_strerror (errno));
718e3744 1405 zlog_warn ("zebra can't provice full functionality due to above error");
1406 close (accept_sock); /* Avoid sd leak. */
1407 return;
1408 }
edd7c245 1409
1410 if ( zserv_privs.change(ZPRIVS_LOWER) )
1411 zlog (NULL, LOG_ERR, "Can't lower privileges");
718e3744 1412
1413 ret = listen (accept_sock, 1);
1414 if (ret < 0)
1415 {
3d1dc857 1416 zlog_warn ("Can't listen to stream socket: %s",
1417 safe_strerror (errno));
718e3744 1418 zlog_warn ("zebra can't provice full functionality due to above error");
1419 close (accept_sock); /* Avoid sd leak. */
1420 return;
1421 }
1422
1423 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1424}
b9df2d25 1425#endif /* HAVE_TCP_ZEBRA */
718e3744 1426
1427/* For sockaddr_un. */
1428#include <sys/un.h>
1429
1430/* zebra server UNIX domain socket. */
b9df2d25 1431static void
fce954f8 1432zebra_serv_un (const char *path)
718e3744 1433{
1434 int ret;
1435 int sock, len;
1436 struct sockaddr_un serv;
1437 mode_t old_mask;
1438
1439 /* First of all, unlink existing socket */
1440 unlink (path);
1441
1442 /* Set umask */
1443 old_mask = umask (0077);
1444
1445 /* Make UNIX domain socket. */
1446 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1447 if (sock < 0)
1448 {
3d1dc857 1449 zlog_warn ("Can't create zserv unix socket: %s",
1450 safe_strerror (errno));
1451 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 1452 return;
1453 }
1454
1455 /* Make server socket. */
1456 memset (&serv, 0, sizeof (struct sockaddr_un));
1457 serv.sun_family = AF_UNIX;
1458 strncpy (serv.sun_path, path, strlen (path));
1459#ifdef HAVE_SUN_LEN
1460 len = serv.sun_len = SUN_LEN(&serv);
1461#else
1462 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1463#endif /* HAVE_SUN_LEN */
1464
1465 ret = bind (sock, (struct sockaddr *) &serv, len);
1466 if (ret < 0)
1467 {
3d1dc857 1468 zlog_warn ("Can't bind to unix socket %s: %s",
1469 path, safe_strerror (errno));
1470 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 1471 close (sock);
1472 return;
1473 }
1474
1475 ret = listen (sock, 5);
1476 if (ret < 0)
1477 {
3d1dc857 1478 zlog_warn ("Can't listen to unix socket %s: %s",
1479 path, safe_strerror (errno));
1480 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 1481 close (sock);
1482 return;
1483 }
1484
1485 umask (old_mask);
1486
1487 zebra_event (ZEBRA_SERV, sock, NULL);
1488}
1489\f
718e3744 1490
b9df2d25 1491static void
718e3744 1492zebra_event (enum event event, int sock, struct zserv *client)
1493{
1494 switch (event)
1495 {
1496 case ZEBRA_SERV:
b21b19c5 1497 thread_add_read (zebrad.master, zebra_accept, client, sock);
718e3744 1498 break;
1499 case ZEBRA_READ:
1500 client->t_read =
b21b19c5 1501 thread_add_read (zebrad.master, zebra_client_read, client, sock);
718e3744 1502 break;
1503 case ZEBRA_WRITE:
1504 /**/
1505 break;
1506 }
1507}
1508\f
1509/* Display default rtm_table for all clients. */
1510DEFUN (show_table,
1511 show_table_cmd,
1512 "show table",
1513 SHOW_STR
1514 "default routing table to use for all clients\n")
1515{
b21b19c5 1516 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
718e3744 1517 VTY_NEWLINE);
1518 return CMD_SUCCESS;
1519}
1520
1521DEFUN (config_table,
1522 config_table_cmd,
1523 "table TABLENO",
1524 "Configure target kernel routing table\n"
1525 "TABLE integer\n")
1526{
b21b19c5 1527 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
718e3744 1528 return CMD_SUCCESS;
1529}
1530
647e4f1f 1531DEFUN (ip_forwarding,
1532 ip_forwarding_cmd,
1533 "ip forwarding",
1534 IP_STR
1535 "Turn on IP forwarding")
1536{
1537 int ret;
1538
1539 ret = ipforward ();
b71f00f2 1540 if (ret == 0)
1541 ret = ipforward_on ();
647e4f1f 1542
647e4f1f 1543 if (ret == 0)
1544 {
1545 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1546 return CMD_WARNING;
1547 }
1548
1549 return CMD_SUCCESS;
1550}
1551
718e3744 1552DEFUN (no_ip_forwarding,
1553 no_ip_forwarding_cmd,
1554 "no ip forwarding",
1555 NO_STR
1556 IP_STR
1557 "Turn off IP forwarding")
1558{
1559 int ret;
1560
1561 ret = ipforward ();
b71f00f2 1562 if (ret != 0)
1563 ret = ipforward_off ();
718e3744 1564
718e3744 1565 if (ret != 0)
1566 {
1567 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1568 return CMD_WARNING;
1569 }
1570
1571 return CMD_SUCCESS;
1572}
1573
1574/* This command is for debugging purpose. */
1575DEFUN (show_zebra_client,
1576 show_zebra_client_cmd,
1577 "show zebra client",
1578 SHOW_STR
1579 "Zebra information"
1580 "Client information")
1581{
52dc7ee6 1582 struct listnode *node;
718e3744 1583 struct zserv *client;
1584
1eb8ef25 1585 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1586 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1587
718e3744 1588 return CMD_SUCCESS;
1589}
1590
1591/* Table configuration write function. */
b9df2d25 1592static int
718e3744 1593config_write_table (struct vty *vty)
1594{
b21b19c5 1595 if (zebrad.rtm_table_default)
1596 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
718e3744 1597 VTY_NEWLINE);
1598 return 0;
1599}
1600
1601/* table node for routing tables. */
1602struct cmd_node table_node =
1603{
1604 TABLE_NODE,
1605 "", /* This node has no interface. */
1606 1
1607};
1608\f
1609/* Only display ip forwarding is enabled or not. */
1610DEFUN (show_ip_forwarding,
1611 show_ip_forwarding_cmd,
1612 "show ip forwarding",
1613 SHOW_STR
1614 IP_STR
1615 "IP forwarding status\n")
1616{
1617 int ret;
1618
1619 ret = ipforward ();
1620
1621 if (ret == 0)
1622 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1623 else
1624 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1625 return CMD_SUCCESS;
1626}
1627
1628#ifdef HAVE_IPV6
1629/* Only display ipv6 forwarding is enabled or not. */
1630DEFUN (show_ipv6_forwarding,
1631 show_ipv6_forwarding_cmd,
1632 "show ipv6 forwarding",
1633 SHOW_STR
1634 "IPv6 information\n"
1635 "Forwarding status\n")
1636{
1637 int ret;
1638
1639 ret = ipforward_ipv6 ();
1640
1641 switch (ret)
1642 {
1643 case -1:
1644 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1645 break;
1646 case 0:
1647 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1648 break;
1649 case 1:
1650 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1651 break;
1652 default:
1653 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1654 break;
1655 }
1656 return CMD_SUCCESS;
1657}
1658
55906724 1659DEFUN (ipv6_forwarding,
1660 ipv6_forwarding_cmd,
1661 "ipv6 forwarding",
1662 IPV6_STR
1663 "Turn on IPv6 forwarding")
1664{
1665 int ret;
1666
41d3fc96 1667 ret = ipforward_ipv6 ();
b71f00f2 1668 if (ret == 0)
1669 ret = ipforward_ipv6_on ();
41d3fc96 1670
41d3fc96 1671 if (ret == 0)
55906724 1672 {
1673 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1674 return CMD_WARNING;
1675 }
1676
1677 return CMD_SUCCESS;
1678}
1679
718e3744 1680DEFUN (no_ipv6_forwarding,
1681 no_ipv6_forwarding_cmd,
1682 "no ipv6 forwarding",
1683 NO_STR
55906724 1684 IPV6_STR
1685 "Turn off IPv6 forwarding")
718e3744 1686{
1687 int ret;
1688
41d3fc96 1689 ret = ipforward_ipv6 ();
b71f00f2 1690 if (ret != 0)
1691 ret = ipforward_ipv6_off ();
41d3fc96 1692
718e3744 1693 if (ret != 0)
1694 {
1695 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1696 return CMD_WARNING;
1697 }
1698
1699 return CMD_SUCCESS;
1700}
1701
1702#endif /* HAVE_IPV6 */
1703
1704/* IPForwarding configuration write function. */
719e9741 1705static int
718e3744 1706config_write_forwarding (struct vty *vty)
1707{
18a6dce6 1708 /* FIXME: Find better place for that. */
1709 router_id_write (vty);
1710
3e0b3a56 1711 if (ipforward ())
1712 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
718e3744 1713#ifdef HAVE_IPV6
3e0b3a56 1714 if (ipforward_ipv6 ())
1715 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
718e3744 1716#endif /* HAVE_IPV6 */
1717 vty_out (vty, "!%s", VTY_NEWLINE);
1718 return 0;
1719}
1720
1721/* table node for routing tables. */
1722struct cmd_node forwarding_node =
1723{
1724 FORWARDING_NODE,
1725 "", /* This node has no interface. */
1726 1
1727};
1728
1729\f
1730/* Initialisation of zebra and installation of commands. */
1731void
a1ac18c4 1732zebra_init (void)
718e3744 1733{
1734 /* Client list init. */
b21b19c5 1735 zebrad.client_list = list_new ();
718e3744 1736
718e3744 1737 /* Make zebra server socket. */
1738#ifdef HAVE_TCP_ZEBRA
1739 zebra_serv ();
1740#else
1741 zebra_serv_un (ZEBRA_SERV_PATH);
1742#endif /* HAVE_TCP_ZEBRA */
1743
1744 /* Install configuration write function. */
1745 install_node (&table_node, config_write_table);
1746 install_node (&forwarding_node, config_write_forwarding);
1747
1748 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1749 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
647e4f1f 1750 install_element (CONFIG_NODE, &ip_forwarding_cmd);
718e3744 1751 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1752 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1753
1754#ifdef HAVE_NETLINK
1755 install_element (VIEW_NODE, &show_table_cmd);
1756 install_element (ENABLE_NODE, &show_table_cmd);
1757 install_element (CONFIG_NODE, &config_table_cmd);
1758#endif /* HAVE_NETLINK */
1759
1760#ifdef HAVE_IPV6
1761 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1762 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
55906724 1763 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
718e3744 1764 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1765#endif /* HAVE_IPV6 */
1766}