blob: aa88ab5d668972bc9271a96a3e760bb8cc028caf [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"
ajs719e9742005-02-28 20:52:15 +000037#include "network.h"
38#include "buffer.h"
paul718e3742002-12-13 20:15:29 +000039
40#include "zebra/zserv.h"
hasso18a6dce2004-10-03 18:18:34 +000041#include "zebra/router-id.h"
paul718e3742002-12-13 20:15:29 +000042#include "zebra/redistribute.h"
43#include "zebra/debug.h"
44#include "zebra/ipforward.h"
45
46/* Event list of zebra. */
47enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
48
paulb21b19c2003-06-15 01:28:29 +000049extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000050
paulb9df2d22004-05-09 09:09:59 +000051static void zebra_event (enum event event, int sock, struct zserv *client);
paulccf35572003-03-01 11:42:20 +000052
pauledd7c242003-06-04 13:59:38 +000053extern struct zebra_privs_t zserv_privs;
paul718e3742002-12-13 20:15:29 +000054
55/* For logging of zebra meesages. */
hassofce954f2004-10-07 20:29:24 +000056static const char *zebra_command_str [] =
paul718e3742002-12-13 20:15:29 +000057{
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",
hasso18a6dce2004-10-03 18:18:34 +000076 "ZEBRA_IPV6_IMPORT_LOOKUP",
77 "ZEBRA_ROUTER_ID_ADD",
78 "ZEBRA_ROUTER_ID_DELETE",
79 "ZEBRA_ROUTER_ID_UPDATE"
paul718e3742002-12-13 20:15:29 +000080};
81
ajs719e9742005-02-28 20:52:15 +000082
83static void zebra_client_close (struct zserv *client);
84
85static int
86zserv_delayed_close(struct thread *thread)
paulccf35572003-03-01 11:42:20 +000087{
ajs719e9742005-02-28 20:52:15 +000088 struct zserv *client = THREAD_ARG(thread);
paulccf35572003-03-01 11:42:20 +000089
ajs719e9742005-02-28 20:52:15 +000090 client->t_suicide = NULL;
91 zebra_client_close(client);
paulccf35572003-03-01 11:42:20 +000092 return 0;
93}
94
ajs719e9742005-02-28 20:52:15 +000095static int
96zserv_flush_data(struct thread *thread)
paulccf35572003-03-01 11:42:20 +000097{
ajs719e9742005-02-28 20:52:15 +000098 struct zserv *client = THREAD_ARG(thread);
paulccf35572003-03-01 11:42:20 +000099
ajs719e9742005-02-28 20:52:15 +0000100 client->t_write = NULL;
101 if (client->t_suicide)
102 {
103 zebra_client_close(client);
104 return -1;
105 }
106 switch (buffer_flush_available(client->wb, client->sock))
107 {
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;
119 }
120 return 0;
paulccf35572003-03-01 11:42:20 +0000121}
122
ajs719e9742005-02-28 20:52:15 +0000123static int
124zebra_server_send_message(struct zserv *client)
paulccf35572003-03-01 11:42:20 +0000125{
ajs719e9742005-02-28 20:52:15 +0000126 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)))
paulccf35572003-03-01 11:42:20 +0000130 {
ajs719e9742005-02-28 20:52:15 +0000131 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;
ajs719e9742005-02-28 20:52:15 +0000141 case BUFFER_EMPTY:
142 THREAD_OFF(client->t_write);
143 break;
144 case BUFFER_PENDING:
145 THREAD_WRITE_ON(zebrad.master, client->t_write,
146 zserv_flush_data, client, client->sock);
147 break;
paulccf35572003-03-01 11:42:20 +0000148 }
paulccf35572003-03-01 11:42:20 +0000149 return 0;
150}
151
paulc1b98002006-01-16 01:54:02 +0000152static void
153zserv_create_header (struct stream *s, uint16_t cmd)
154{
155 /* length placeholder, caller can update */
156 stream_putw (s, ZEBRA_HEADER_SIZE);
157 stream_putc (s, ZEBRA_HEADER_MARKER);
158 stream_putc (s, ZSERV_VERSION);
159 stream_putw (s, cmd);
160}
161
paul718e3742002-12-13 20:15:29 +0000162/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
paulb9df2d22004-05-09 09:09:59 +0000163/*
164 * This function is called in the following situations:
165 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
166 * from the client.
167 * - at startup, when zebra figures out the available interfaces
168 * - when an interface is added (where support for
169 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
170 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
171 * received)
172 */
paul718e3742002-12-13 20:15:29 +0000173int
174zsend_interface_add (struct zserv *client, struct interface *ifp)
175{
176 struct stream *s;
177
178 /* Check this client need interface information. */
179 if (! client->ifinfo)
ajs719e9742005-02-28 20:52:15 +0000180 return 0;
paul718e3742002-12-13 20:15:29 +0000181
182 s = client->obuf;
183 stream_reset (s);
184
paul718e3742002-12-13 20:15:29 +0000185 /* Message type. */
paulc1b98002006-01-16 01:54:02 +0000186 zserv_create_header (s, ZEBRA_INTERFACE_ADD);
paul718e3742002-12-13 20:15:29 +0000187
188 /* Interface information. */
189 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
190 stream_putl (s, ifp->ifindex);
paul2e3b2e42002-12-13 21:03:13 +0000191 stream_putc (s, ifp->status);
paulc77d4542006-01-11 01:59:04 +0000192 stream_putq (s, ifp->flags);
paul718e3742002-12-13 20:15:29 +0000193 stream_putl (s, ifp->metric);
194 stream_putl (s, ifp->mtu);
paulb9df2d22004-05-09 09:09:59 +0000195 stream_putl (s, ifp->mtu6);
paul718e3742002-12-13 20:15:29 +0000196 stream_putl (s, ifp->bandwidth);
197#ifdef HAVE_SOCKADDR_DL
198 stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
199#else
200 stream_putl (s, ifp->hw_addr_len);
201 if (ifp->hw_addr_len)
202 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
203#endif /* HAVE_SOCKADDR_DL */
204
205 /* Write packet size. */
206 stream_putw_at (s, 0, stream_get_endp (s));
207
ajs719e9742005-02-28 20:52:15 +0000208 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000209}
210
211/* Interface deletion from zebra daemon. */
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)
ajs719e9742005-02-28 20:52:15 +0000219 return 0;
paul718e3742002-12-13 20:15:29 +0000220
221 s = client->obuf;
222 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000223
224 zserv_create_header (s, ZEBRA_INTERFACE_DELETE);
225
paul718e3742002-12-13 20:15:29 +0000226 /* Interface information. */
paul718e3742002-12-13 20:15:29 +0000227 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
228 stream_putl (s, ifp->ifindex);
paul2e3b2e42002-12-13 21:03:13 +0000229 stream_putc (s, ifp->status);
paulc77d4542006-01-11 01:59:04 +0000230 stream_putq (s, ifp->flags);
paul718e3742002-12-13 20:15:29 +0000231 stream_putl (s, ifp->metric);
232 stream_putl (s, ifp->mtu);
paulb9df2d22004-05-09 09:09:59 +0000233 stream_putl (s, ifp->mtu6);
paul718e3742002-12-13 20:15:29 +0000234 stream_putl (s, ifp->bandwidth);
235
236 /* Write packet length. */
237 stream_putw_at (s, 0, stream_get_endp (s));
238
ajs719e9742005-02-28 20:52:15 +0000239 return zebra_server_send_message (client);
paul718e3742002-12-13 20:15:29 +0000240}
241
paulb9df2d22004-05-09 09:09:59 +0000242/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
243 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
244 *
245 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
246 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
247 * from the client, after the ZEBRA_INTERFACE_ADD has been
248 * sent from zebra to the client
249 * - redistribute new address info to all clients in the following situations
250 * - at startup, when zebra figures out the available interfaces
251 * - when an interface is added (where support for
252 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
253 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
254 * received)
255 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
256 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
257 * - when an RTM_NEWADDR message is received from the kernel,
258 *
259 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
260 *
261 * zsend_interface_address(DELETE)
262 * ^
263 * |
264 * zebra_interface_address_delete_update
265 * ^ ^ ^
paul6eb88272005-07-29 14:36:00 +0000266 * | | if_delete_update
267 * | |
paulb9df2d22004-05-09 09:09:59 +0000268 * ip_address_uninstall connected_delete_ipv4
269 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
270 * ^ ^
271 * | |
272 * | RTM_NEWADDR on routing/netlink socket
273 * |
274 * vty commands:
275 * "no ip address A.B.C.D/M [label LINE]"
276 * "no ip address A.B.C.D/M secondary"
277 * ["no ipv6 address X:X::X:X/M"]
278 *
279 */
paul718e3742002-12-13 20:15:29 +0000280int
paulb9df2d22004-05-09 09:09:59 +0000281zsend_interface_address (int cmd, struct zserv *client,
282 struct interface *ifp, struct connected *ifc)
paul718e3742002-12-13 20:15:29 +0000283{
284 int blen;
285 struct stream *s;
286 struct prefix *p;
287
288 /* Check this client need interface information. */
289 if (! client->ifinfo)
ajs719e9742005-02-28 20:52:15 +0000290 return 0;
paul718e3742002-12-13 20:15:29 +0000291
292 s = client->obuf;
293 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000294
295 zserv_create_header (s, cmd);
paul718e3742002-12-13 20:15:29 +0000296 stream_putl (s, ifp->ifindex);
297
298 /* Interface address flag. */
299 stream_putc (s, ifc->flags);
300
301 /* Prefix information. */
302 p = ifc->address;
303 stream_putc (s, p->family);
304 blen = prefix_blen (p);
305 stream_put (s, &p->u.prefix, blen);
paulb9df2d22004-05-09 09:09:59 +0000306
307 /*
308 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
309 * but zebra_interface_address_delete_read() in the gnu version
310 * expects to find it
311 */
paul718e3742002-12-13 20:15:29 +0000312 stream_putc (s, p->prefixlen);
313
314 /* Destination. */
315 p = ifc->destination;
316 if (p)
317 stream_put (s, &p->u.prefix, blen);
318 else
319 stream_put (s, NULL, blen);
320
321 /* Write packet size. */
322 stream_putw_at (s, 0, stream_get_endp (s));
323
ajs719e9742005-02-28 20:52:15 +0000324 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000325}
326
paulb9df2d22004-05-09 09:09:59 +0000327/*
328 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
329 * ZEBRA_INTERFACE_DOWN.
330 *
331 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
332 * the clients in one of 2 situations:
333 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
334 * - a vty command modifying the bandwidth of an interface is received.
335 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
336 */
paul718e3742002-12-13 20:15:29 +0000337int
paulb9df2d22004-05-09 09:09:59 +0000338zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000339{
340 struct stream *s;
341
342 /* Check this client need interface information. */
343 if (! client->ifinfo)
ajs719e9742005-02-28 20:52:15 +0000344 return 0;
paul718e3742002-12-13 20:15:29 +0000345
346 s = client->obuf;
347 stream_reset (s);
348
paulc1b98002006-01-16 01:54:02 +0000349 zserv_create_header (s, cmd);
paul718e3742002-12-13 20:15:29 +0000350
351 /* Interface information. */
352 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
353 stream_putl (s, ifp->ifindex);
paul2e3b2e42002-12-13 21:03:13 +0000354 stream_putc (s, ifp->status);
paulc77d4542006-01-11 01:59:04 +0000355 stream_putq (s, ifp->flags);
paul718e3742002-12-13 20:15:29 +0000356 stream_putl (s, ifp->metric);
357 stream_putl (s, ifp->mtu);
paulb9df2d22004-05-09 09:09:59 +0000358 stream_putl (s, ifp->mtu6);
paul718e3742002-12-13 20:15:29 +0000359 stream_putl (s, ifp->bandwidth);
360
361 /* Write packet size. */
362 stream_putw_at (s, 0, stream_get_endp (s));
363
ajs719e9742005-02-28 20:52:15 +0000364 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000365}
366
paulb9df2d22004-05-09 09:09:59 +0000367/*
368 * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
369 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
370 * situations:
371 * - when the client starts up, and requests default information
372 * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
373 * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
374 * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
375 * - when the zebra server redistributes routes after it updates its rib
376 *
377 * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
378 * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
379 * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
380 * - deleted from zebra's rib, and this info
381 * has to be redistributed to the clients
382 *
383 * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
384 * zebra server when the client wants to tell the zebra server to add a
385 * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
386 * same message being sent back and forth, this function and
387 * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
388 * duplication.
389 */
paul718e3742002-12-13 20:15:29 +0000390int
paulb9df2d22004-05-09 09:09:59 +0000391zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
392 struct rib *rib)
paul718e3742002-12-13 20:15:29 +0000393{
394 int psize;
395 struct stream *s;
396 struct nexthop *nexthop;
paul1dcb5172005-05-31 08:38:50 +0000397 unsigned long nhnummark = 0, messmark = 0;
paulb9df2d22004-05-09 09:09:59 +0000398 int nhnum = 0;
paul1dcb5172005-05-31 08:38:50 +0000399 u_char zapi_flags = 0;
paulb9df2d22004-05-09 09:09:59 +0000400
paul718e3742002-12-13 20:15:29 +0000401 s = client->obuf;
402 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000403
404 zserv_create_header (s, cmd);
405
406 /* Put type and nexthop. */
paul718e3742002-12-13 20:15:29 +0000407 stream_putc (s, rib->type);
408 stream_putc (s, rib->flags);
paul1dcb5172005-05-31 08:38:50 +0000409
410 /* marker for message flags field */
411 messmark = stream_get_endp (s);
412 stream_putc (s, 0);
paul718e3742002-12-13 20:15:29 +0000413
414 /* Prefix. */
415 psize = PSIZE (p->prefixlen);
416 stream_putc (s, p->prefixlen);
paulb9df2d22004-05-09 09:09:59 +0000417 stream_write (s, (u_char *) & p->u.prefix, psize);
paul718e3742002-12-13 20:15:29 +0000418
paulb9df2d22004-05-09 09:09:59 +0000419 /*
420 * XXX The message format sent by zebra below does not match the format
421 * of the corresponding message expected by the zebra server
422 * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
423 * (is there a bug on the client side if more than one segment is sent?)
424 * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
425 * is hard-coded.
426 */
paul718e3742002-12-13 20:15:29 +0000427 /* Nexthop */
paul1dcb5172005-05-31 08:38:50 +0000428
paul718e3742002-12-13 20:15:29 +0000429 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
430 {
431 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
paulb9df2d22004-05-09 09:09:59 +0000432 {
paul1dcb5172005-05-31 08:38:50 +0000433 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
434 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
435
436 if (nhnummark == 0)
437 {
438 nhnummark = stream_get_endp (s);
439 stream_putc (s, 1); /* placeholder */
440 }
441
paulb9df2d22004-05-09 09:09:59 +0000442 nhnum++;
paul718e3742002-12-13 20:15:29 +0000443
paulb9df2d22004-05-09 09:09:59 +0000444 switch(nexthop->type)
445 {
446 case NEXTHOP_TYPE_IPV4:
447 case NEXTHOP_TYPE_IPV4_IFINDEX:
448 stream_put_in_addr (s, &nexthop->gate.ipv4);
449 break;
450#ifdef HAVE_IPV6
451 case NEXTHOP_TYPE_IPV6:
452 case NEXTHOP_TYPE_IPV6_IFINDEX:
453 case NEXTHOP_TYPE_IPV6_IFNAME:
454 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
455 break;
456#endif
457 default:
458 if (cmd == ZEBRA_IPV4_ROUTE_ADD
459 || cmd == ZEBRA_IPV4_ROUTE_DELETE)
460 {
461 struct in_addr empty;
paul44983cf2004-09-22 13:15:58 +0000462 memset (&empty, 0, sizeof (struct in_addr));
paulb9df2d22004-05-09 09:09:59 +0000463 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
464 }
465 else
466 {
467 struct in6_addr empty;
468 memset (&empty, 0, sizeof (struct in6_addr));
469 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
470 }
471 }
paul718e3742002-12-13 20:15:29 +0000472
paulb9df2d22004-05-09 09:09:59 +0000473 /* Interface index. */
474 stream_putc (s, 1);
475 stream_putl (s, nexthop->ifindex);
paul718e3742002-12-13 20:15:29 +0000476
paulb9df2d22004-05-09 09:09:59 +0000477 break;
478 }
paul718e3742002-12-13 20:15:29 +0000479 }
480
481 /* Metric */
paul1dcb5172005-05-31 08:38:50 +0000482 if (cmd == ZEBRA_IPV4_ROUTE_ADD || ZEBRA_IPV6_ROUTE_ADD)
483 {
vincentfbf5d032005-09-29 11:25:50 +0000484 SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
485 stream_putc (s, rib->distance);
paul1dcb5172005-05-31 08:38:50 +0000486 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
487 stream_putl (s, rib->metric);
488 }
489
490 /* write real message flags value */
491 stream_putc_at (s, messmark, zapi_flags);
492
paulb9df2d22004-05-09 09:09:59 +0000493 /* Write next-hop number */
494 if (nhnummark)
hassoc1eaa442004-10-19 06:26:01 +0000495 stream_putc_at (s, nhnummark, nhnum);
paulb9df2d22004-05-09 09:09:59 +0000496
paul718e3742002-12-13 20:15:29 +0000497 /* Write packet size. */
498 stream_putw_at (s, 0, stream_get_endp (s));
499
ajs719e9742005-02-28 20:52:15 +0000500 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000501}
502
paul718e3742002-12-13 20:15:29 +0000503#ifdef HAVE_IPV6
ajs719e9742005-02-28 20:52:15 +0000504static int
paul718e3742002-12-13 20:15:29 +0000505zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
506{
507 struct stream *s;
508 struct rib *rib;
509 unsigned long nump;
510 u_char num;
511 struct nexthop *nexthop;
512
513 /* Lookup nexthop. */
514 rib = rib_match_ipv6 (addr);
515
516 /* Get output stream. */
517 s = client->obuf;
518 stream_reset (s);
519
520 /* Fill in result. */
paulc1b98002006-01-16 01:54:02 +0000521 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
paul718e3742002-12-13 20:15:29 +0000522 stream_put (s, &addr, 16);
523
524 if (rib)
525 {
526 stream_putl (s, rib->metric);
527 num = 0;
paul9985f832005-02-09 15:51:56 +0000528 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000529 stream_putc (s, 0);
530 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
531 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
532 {
533 stream_putc (s, nexthop->type);
534 switch (nexthop->type)
535 {
536 case ZEBRA_NEXTHOP_IPV6:
537 stream_put (s, &nexthop->gate.ipv6, 16);
538 break;
539 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
540 case ZEBRA_NEXTHOP_IPV6_IFNAME:
541 stream_put (s, &nexthop->gate.ipv6, 16);
542 stream_putl (s, nexthop->ifindex);
543 break;
544 case ZEBRA_NEXTHOP_IFINDEX:
545 case ZEBRA_NEXTHOP_IFNAME:
546 stream_putl (s, nexthop->ifindex);
547 break;
hassofa2b17e2004-03-04 17:45:00 +0000548 default:
549 /* do nothing */
550 break;
paul718e3742002-12-13 20:15:29 +0000551 }
552 num++;
553 }
554 stream_putc_at (s, nump, num);
555 }
556 else
557 {
558 stream_putl (s, 0);
559 stream_putc (s, 0);
560 }
561
562 stream_putw_at (s, 0, stream_get_endp (s));
563
ajs719e9742005-02-28 20:52:15 +0000564 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000565}
566#endif /* HAVE_IPV6 */
567
paulb9df2d22004-05-09 09:09:59 +0000568static int
paul718e3742002-12-13 20:15:29 +0000569zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
570{
571 struct stream *s;
572 struct rib *rib;
573 unsigned long nump;
574 u_char num;
575 struct nexthop *nexthop;
576
577 /* Lookup nexthop. */
578 rib = rib_match_ipv4 (addr);
579
580 /* Get output stream. */
581 s = client->obuf;
582 stream_reset (s);
583
584 /* Fill in result. */
paulc1b98002006-01-16 01:54:02 +0000585 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
paul718e3742002-12-13 20:15:29 +0000586 stream_put_in_addr (s, &addr);
587
588 if (rib)
589 {
590 stream_putl (s, rib->metric);
591 num = 0;
paul9985f832005-02-09 15:51:56 +0000592 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000593 stream_putc (s, 0);
594 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
595 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
596 {
597 stream_putc (s, nexthop->type);
598 switch (nexthop->type)
599 {
600 case ZEBRA_NEXTHOP_IPV4:
601 stream_put_in_addr (s, &nexthop->gate.ipv4);
602 break;
603 case ZEBRA_NEXTHOP_IFINDEX:
604 case ZEBRA_NEXTHOP_IFNAME:
605 stream_putl (s, nexthop->ifindex);
606 break;
hassofa2b17e2004-03-04 17:45:00 +0000607 default:
608 /* do nothing */
609 break;
paul718e3742002-12-13 20:15:29 +0000610 }
611 num++;
612 }
613 stream_putc_at (s, nump, num);
614 }
615 else
616 {
617 stream_putl (s, 0);
618 stream_putc (s, 0);
619 }
620
621 stream_putw_at (s, 0, stream_get_endp (s));
622
ajs719e9742005-02-28 20:52:15 +0000623 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000624}
625
paulb9df2d22004-05-09 09:09:59 +0000626static int
paul718e3742002-12-13 20:15:29 +0000627zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
628{
629 struct stream *s;
630 struct rib *rib;
631 unsigned long nump;
632 u_char num;
633 struct nexthop *nexthop;
634
635 /* Lookup nexthop. */
636 rib = rib_lookup_ipv4 (p);
637
638 /* Get output stream. */
639 s = client->obuf;
640 stream_reset (s);
641
642 /* Fill in result. */
paulc1b98002006-01-16 01:54:02 +0000643 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP);
paul718e3742002-12-13 20:15:29 +0000644 stream_put_in_addr (s, &p->prefix);
645
646 if (rib)
647 {
648 stream_putl (s, rib->metric);
649 num = 0;
paul9985f832005-02-09 15:51:56 +0000650 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000651 stream_putc (s, 0);
652 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
653 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
654 {
655 stream_putc (s, nexthop->type);
656 switch (nexthop->type)
657 {
658 case ZEBRA_NEXTHOP_IPV4:
659 stream_put_in_addr (s, &nexthop->gate.ipv4);
660 break;
661 case ZEBRA_NEXTHOP_IFINDEX:
662 case ZEBRA_NEXTHOP_IFNAME:
663 stream_putl (s, nexthop->ifindex);
664 break;
hassofa2b17e2004-03-04 17:45:00 +0000665 default:
666 /* do nothing */
667 break;
paul718e3742002-12-13 20:15:29 +0000668 }
669 num++;
670 }
671 stream_putc_at (s, nump, num);
672 }
673 else
674 {
675 stream_putl (s, 0);
676 stream_putc (s, 0);
677 }
678
679 stream_putw_at (s, 0, stream_get_endp (s));
680
ajs719e9742005-02-28 20:52:15 +0000681 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000682}
683
hasso18a6dce2004-10-03 18:18:34 +0000684/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
685int
686zsend_router_id_update (struct zserv *client, struct prefix *p)
687{
688 struct stream *s;
689 int blen;
690
691 /* Check this client need interface information. */
692 if (!client->ridinfo)
ajs719e9742005-02-28 20:52:15 +0000693 return 0;
hasso18a6dce2004-10-03 18:18:34 +0000694
695 s = client->obuf;
696 stream_reset (s);
697
hasso18a6dce2004-10-03 18:18:34 +0000698 /* Message type. */
paulc1b98002006-01-16 01:54:02 +0000699 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE);
hasso18a6dce2004-10-03 18:18:34 +0000700
701 /* Prefix information. */
702 stream_putc (s, p->family);
703 blen = prefix_blen (p);
704 stream_put (s, &p->u.prefix, blen);
705 stream_putc (s, p->prefixlen);
706
707 /* Write packet size. */
708 stream_putw_at (s, 0, stream_get_endp (s));
709
ajs719e9742005-02-28 20:52:15 +0000710 return zebra_server_send_message(client);
hasso18a6dce2004-10-03 18:18:34 +0000711}
712
paul718e3742002-12-13 20:15:29 +0000713/* Register zebra server interface information. Send current all
714 interface and address information. */
ajs719e9742005-02-28 20:52:15 +0000715static int
paul718e3742002-12-13 20:15:29 +0000716zread_interface_add (struct zserv *client, u_short length)
717{
paul1eb8ef22005-04-07 07:30:20 +0000718 struct listnode *ifnode, *ifnnode;
719 struct listnode *cnode, *cnnode;
paul718e3742002-12-13 20:15:29 +0000720 struct interface *ifp;
721 struct connected *c;
722
723 /* Interface information is needed. */
724 client->ifinfo = 1;
725
paul1eb8ef22005-04-07 07:30:20 +0000726 for (ALL_LIST_ELEMENTS (iflist, ifnode, ifnnode, ifp))
paul718e3742002-12-13 20:15:29 +0000727 {
paul718e3742002-12-13 20:15:29 +0000728 /* Skip pseudo interface. */
729 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
730 continue;
731
ajs719e9742005-02-28 20:52:15 +0000732 if (zsend_interface_add (client, ifp) < 0)
733 return -1;
paul718e3742002-12-13 20:15:29 +0000734
paul1eb8ef22005-04-07 07:30:20 +0000735 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
paul718e3742002-12-13 20:15:29 +0000736 {
ajs719e9742005-02-28 20:52:15 +0000737 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
738 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
739 ifp, c) < 0))
740 return -1;
paul718e3742002-12-13 20:15:29 +0000741 }
742 }
ajs719e9742005-02-28 20:52:15 +0000743 return 0;
paul718e3742002-12-13 20:15:29 +0000744}
745
746/* Unregister zebra server interface information. */
ajs719e9742005-02-28 20:52:15 +0000747static int
paul718e3742002-12-13 20:15:29 +0000748zread_interface_delete (struct zserv *client, u_short length)
749{
750 client->ifinfo = 0;
ajs719e9742005-02-28 20:52:15 +0000751 return 0;
paul718e3742002-12-13 20:15:29 +0000752}
753
754/* This function support multiple nexthop. */
paulb9df2d22004-05-09 09:09:59 +0000755/*
756 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
757 * add kernel route.
758 */
ajs719e9742005-02-28 20:52:15 +0000759static int
paul718e3742002-12-13 20:15:29 +0000760zread_ipv4_add (struct zserv *client, u_short length)
761{
762 int i;
763 struct rib *rib;
764 struct prefix_ipv4 p;
765 u_char message;
766 struct in_addr nexthop;
767 u_char nexthop_num;
768 u_char nexthop_type;
769 struct stream *s;
770 unsigned int ifindex;
771 u_char ifname_len;
772
773 /* Get input stream. */
774 s = client->ibuf;
775
776 /* Allocate new rib. */
paul4d38fdb2005-04-28 17:35:14 +0000777 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
778
paul718e3742002-12-13 20:15:29 +0000779 /* Type, flags, message. */
780 rib->type = stream_getc (s);
781 rib->flags = stream_getc (s);
paulb9df2d22004-05-09 09:09:59 +0000782 message = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000783 rib->uptime = time (NULL);
784
785 /* IPv4 prefix. */
786 memset (&p, 0, sizeof (struct prefix_ipv4));
787 p.family = AF_INET;
788 p.prefixlen = stream_getc (s);
789 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
790
791 /* Nexthop parse. */
792 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
793 {
794 nexthop_num = stream_getc (s);
795
796 for (i = 0; i < nexthop_num; i++)
797 {
798 nexthop_type = stream_getc (s);
799
800 switch (nexthop_type)
801 {
802 case ZEBRA_NEXTHOP_IFINDEX:
803 ifindex = stream_getl (s);
804 nexthop_ifindex_add (rib, ifindex);
805 break;
806 case ZEBRA_NEXTHOP_IFNAME:
807 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000808 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000809 break;
810 case ZEBRA_NEXTHOP_IPV4:
811 nexthop.s_addr = stream_get_ipv4 (s);
812 nexthop_ipv4_add (rib, &nexthop);
813 break;
814 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000815 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000816 break;
paul595db7f2003-05-25 21:35:06 +0000817 case ZEBRA_NEXTHOP_BLACKHOLE:
818 nexthop_blackhole_add (rib);
819 break;
paul718e3742002-12-13 20:15:29 +0000820 }
821 }
822 }
823
824 /* Distance. */
825 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
826 rib->distance = stream_getc (s);
827
828 /* Metric. */
829 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
830 rib->metric = stream_getl (s);
831
832 rib_add_ipv4_multipath (&p, rib);
ajs719e9742005-02-28 20:52:15 +0000833 return 0;
paul718e3742002-12-13 20:15:29 +0000834}
835
836/* Zebra server IPv4 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +0000837static int
paul718e3742002-12-13 20:15:29 +0000838zread_ipv4_delete (struct zserv *client, u_short length)
839{
840 int i;
841 struct stream *s;
842 struct zapi_ipv4 api;
843 struct in_addr nexthop;
844 unsigned long ifindex;
845 struct prefix_ipv4 p;
846 u_char nexthop_num;
847 u_char nexthop_type;
848 u_char ifname_len;
849
850 s = client->ibuf;
851 ifindex = 0;
852 nexthop.s_addr = 0;
853
854 /* Type, flags, message. */
855 api.type = stream_getc (s);
856 api.flags = stream_getc (s);
857 api.message = stream_getc (s);
858
859 /* IPv4 prefix. */
860 memset (&p, 0, sizeof (struct prefix_ipv4));
861 p.family = AF_INET;
862 p.prefixlen = stream_getc (s);
863 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
864
865 /* Nexthop, ifindex, distance, metric. */
866 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
867 {
868 nexthop_num = stream_getc (s);
869
870 for (i = 0; i < nexthop_num; i++)
871 {
872 nexthop_type = stream_getc (s);
873
874 switch (nexthop_type)
875 {
876 case ZEBRA_NEXTHOP_IFINDEX:
877 ifindex = stream_getl (s);
878 break;
879 case ZEBRA_NEXTHOP_IFNAME:
880 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000881 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000882 break;
883 case ZEBRA_NEXTHOP_IPV4:
884 nexthop.s_addr = stream_get_ipv4 (s);
885 break;
886 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000887 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000888 break;
889 }
890 }
891 }
892
893 /* Distance. */
894 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
895 api.distance = stream_getc (s);
896 else
897 api.distance = 0;
898
899 /* Metric. */
900 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
901 api.metric = stream_getl (s);
902 else
903 api.metric = 0;
904
905 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
906 client->rtm_table);
ajs719e9742005-02-28 20:52:15 +0000907 return 0;
paul718e3742002-12-13 20:15:29 +0000908}
909
910/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +0000911static int
paul718e3742002-12-13 20:15:29 +0000912zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
913{
914 struct in_addr addr;
915
916 addr.s_addr = stream_get_ipv4 (client->ibuf);
ajs719e9742005-02-28 20:52:15 +0000917 return zsend_ipv4_nexthop_lookup (client, addr);
paul718e3742002-12-13 20:15:29 +0000918}
919
920/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +0000921static int
paul718e3742002-12-13 20:15:29 +0000922zread_ipv4_import_lookup (struct zserv *client, u_short length)
923{
924 struct prefix_ipv4 p;
925
926 p.family = AF_INET;
927 p.prefixlen = stream_getc (client->ibuf);
928 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
929
ajs719e9742005-02-28 20:52:15 +0000930 return zsend_ipv4_import_lookup (client, &p);
paul718e3742002-12-13 20:15:29 +0000931}
932
933#ifdef HAVE_IPV6
934/* Zebra server IPv6 prefix add function. */
ajs719e9742005-02-28 20:52:15 +0000935static int
paul718e3742002-12-13 20:15:29 +0000936zread_ipv6_add (struct zserv *client, u_short length)
937{
938 int i;
939 struct stream *s;
940 struct zapi_ipv6 api;
941 struct in6_addr nexthop;
942 unsigned long ifindex;
943 struct prefix_ipv6 p;
944
945 s = client->ibuf;
946 ifindex = 0;
947 memset (&nexthop, 0, sizeof (struct in6_addr));
948
949 /* Type, flags, message. */
950 api.type = stream_getc (s);
951 api.flags = stream_getc (s);
952 api.message = stream_getc (s);
953
954 /* IPv4 prefix. */
955 memset (&p, 0, sizeof (struct prefix_ipv6));
956 p.family = AF_INET6;
957 p.prefixlen = stream_getc (s);
958 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
959
960 /* Nexthop, ifindex, distance, metric. */
961 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
962 {
963 u_char nexthop_type;
964
965 api.nexthop_num = stream_getc (s);
966 for (i = 0; i < api.nexthop_num; i++)
967 {
968 nexthop_type = stream_getc (s);
969
970 switch (nexthop_type)
971 {
972 case ZEBRA_NEXTHOP_IPV6:
973 stream_get (&nexthop, s, 16);
974 break;
975 case ZEBRA_NEXTHOP_IFINDEX:
976 ifindex = stream_getl (s);
977 break;
978 }
979 }
980 }
981
982 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
983 api.distance = stream_getc (s);
984 else
985 api.distance = 0;
986
987 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
988 api.metric = stream_getl (s);
989 else
990 api.metric = 0;
991
992 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
hassobe61c4e2005-08-27 06:05:47 +0000993 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0, api.metric,
994 api.distance);
paul718e3742002-12-13 20:15:29 +0000995 else
hassobe61c4e2005-08-27 06:05:47 +0000996 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0, api.metric,
997 api.distance);
ajs719e9742005-02-28 20:52:15 +0000998 return 0;
paul718e3742002-12-13 20:15:29 +0000999}
1000
1001/* Zebra server IPv6 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +00001002static int
paul718e3742002-12-13 20:15:29 +00001003zread_ipv6_delete (struct zserv *client, u_short length)
1004{
1005 int i;
1006 struct stream *s;
1007 struct zapi_ipv6 api;
1008 struct in6_addr nexthop;
1009 unsigned long ifindex;
1010 struct prefix_ipv6 p;
1011
1012 s = client->ibuf;
1013 ifindex = 0;
1014 memset (&nexthop, 0, sizeof (struct in6_addr));
1015
1016 /* Type, flags, message. */
1017 api.type = stream_getc (s);
1018 api.flags = stream_getc (s);
1019 api.message = stream_getc (s);
1020
1021 /* IPv4 prefix. */
1022 memset (&p, 0, sizeof (struct prefix_ipv6));
1023 p.family = AF_INET6;
1024 p.prefixlen = stream_getc (s);
1025 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1026
1027 /* Nexthop, ifindex, distance, metric. */
1028 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1029 {
1030 u_char nexthop_type;
1031
1032 api.nexthop_num = stream_getc (s);
1033 for (i = 0; i < api.nexthop_num; i++)
1034 {
1035 nexthop_type = stream_getc (s);
1036
1037 switch (nexthop_type)
1038 {
1039 case ZEBRA_NEXTHOP_IPV6:
1040 stream_get (&nexthop, s, 16);
1041 break;
1042 case ZEBRA_NEXTHOP_IFINDEX:
1043 ifindex = stream_getl (s);
1044 break;
1045 }
1046 }
1047 }
1048
1049 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1050 api.distance = stream_getc (s);
1051 else
1052 api.distance = 0;
1053 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1054 api.metric = stream_getl (s);
1055 else
1056 api.metric = 0;
1057
1058 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1059 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
1060 else
1061 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
ajs719e9742005-02-28 20:52:15 +00001062 return 0;
paul718e3742002-12-13 20:15:29 +00001063}
1064
ajs719e9742005-02-28 20:52:15 +00001065static int
paul718e3742002-12-13 20:15:29 +00001066zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1067{
1068 struct in6_addr addr;
1069 char buf[BUFSIZ];
1070
1071 stream_get (&addr, client->ibuf, 16);
1072 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1073
ajs719e9742005-02-28 20:52:15 +00001074 return zsend_ipv6_nexthop_lookup (client, &addr);
paul718e3742002-12-13 20:15:29 +00001075}
1076#endif /* HAVE_IPV6 */
1077
hasso18a6dce2004-10-03 18:18:34 +00001078/* Register zebra server router-id information. Send current router-id */
ajs719e9742005-02-28 20:52:15 +00001079static int
hasso18a6dce2004-10-03 18:18:34 +00001080zread_router_id_add (struct zserv *client, u_short length)
1081{
1082 struct prefix p;
1083
1084 /* Router-id information is needed. */
1085 client->ridinfo = 1;
1086
1087 router_id_get (&p);
1088
ajs719e9742005-02-28 20:52:15 +00001089 return zsend_router_id_update (client,&p);
hasso18a6dce2004-10-03 18:18:34 +00001090}
1091
1092/* Unregister zebra server router-id information. */
ajs719e9742005-02-28 20:52:15 +00001093static int
hasso18a6dce2004-10-03 18:18:34 +00001094zread_router_id_delete (struct zserv *client, u_short length)
1095{
1096 client->ridinfo = 0;
ajs719e9742005-02-28 20:52:15 +00001097 return 0;
hasso18a6dce2004-10-03 18:18:34 +00001098}
1099
paul718e3742002-12-13 20:15:29 +00001100/* Close zebra client. */
paulb9df2d22004-05-09 09:09:59 +00001101static void
paul718e3742002-12-13 20:15:29 +00001102zebra_client_close (struct zserv *client)
1103{
1104 /* Close file descriptor. */
1105 if (client->sock)
1106 {
1107 close (client->sock);
1108 client->sock = -1;
1109 }
1110
1111 /* Free stream buffers. */
1112 if (client->ibuf)
1113 stream_free (client->ibuf);
1114 if (client->obuf)
1115 stream_free (client->obuf);
ajs719e9742005-02-28 20:52:15 +00001116 if (client->wb)
1117 buffer_free(client->wb);
paul718e3742002-12-13 20:15:29 +00001118
1119 /* Release threads. */
1120 if (client->t_read)
1121 thread_cancel (client->t_read);
1122 if (client->t_write)
1123 thread_cancel (client->t_write);
ajs719e9742005-02-28 20:52:15 +00001124 if (client->t_suicide)
1125 thread_cancel (client->t_suicide);
paul718e3742002-12-13 20:15:29 +00001126
1127 /* Free client structure. */
paulb21b19c2003-06-15 01:28:29 +00001128 listnode_delete (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001129 XFREE (0, client);
1130}
1131
1132/* Make new client. */
paulb9df2d22004-05-09 09:09:59 +00001133static void
paul718e3742002-12-13 20:15:29 +00001134zebra_client_create (int sock)
1135{
1136 struct zserv *client;
1137
1138 client = XCALLOC (0, sizeof (struct zserv));
1139
1140 /* Make client input/output buffer. */
1141 client->sock = sock;
1142 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1143 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
ajs719e9742005-02-28 20:52:15 +00001144 client->wb = buffer_new(0);
paul718e3742002-12-13 20:15:29 +00001145
1146 /* Set table number. */
paulb21b19c2003-06-15 01:28:29 +00001147 client->rtm_table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00001148
1149 /* Add this client to linked list. */
paulb21b19c2003-06-15 01:28:29 +00001150 listnode_add (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001151
1152 /* Make new read thread. */
1153 zebra_event (ZEBRA_READ, sock, client);
1154}
1155
1156/* Handler of zebra service request. */
paulb9df2d22004-05-09 09:09:59 +00001157static int
paul718e3742002-12-13 20:15:29 +00001158zebra_client_read (struct thread *thread)
1159{
1160 int sock;
1161 struct zserv *client;
ajs57a14772005-04-10 15:01:56 +00001162 size_t already;
paulc1b98002006-01-16 01:54:02 +00001163 uint16_t length, command;
1164 uint8_t marker, version;
paul718e3742002-12-13 20:15:29 +00001165
1166 /* Get thread data. Reset reading thread because I'm running. */
1167 sock = THREAD_FD (thread);
1168 client = THREAD_ARG (thread);
1169 client->t_read = NULL;
1170
ajs719e9742005-02-28 20:52:15 +00001171 if (client->t_suicide)
paul718e3742002-12-13 20:15:29 +00001172 {
ajs719e9742005-02-28 20:52:15 +00001173 zebra_client_close(client);
paul718e3742002-12-13 20:15:29 +00001174 return -1;
1175 }
ajs719e9742005-02-28 20:52:15 +00001176
1177 /* Read length and command (if we don't have it already). */
ajs57a14772005-04-10 15:01:56 +00001178 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
ajs719e9742005-02-28 20:52:15 +00001179 {
ajs57a14772005-04-10 15:01:56 +00001180 ssize_t nbyte;
ajs719e9742005-02-28 20:52:15 +00001181 if (((nbyte = stream_read_try (client->ibuf, sock,
ajs57a14772005-04-10 15:01:56 +00001182 ZEBRA_HEADER_SIZE-already)) == 0) ||
ajs719e9742005-02-28 20:52:15 +00001183 (nbyte == -1))
1184 {
1185 if (IS_ZEBRA_DEBUG_EVENT)
1186 zlog_debug ("connection closed socket [%d]", sock);
1187 zebra_client_close (client);
1188 return -1;
1189 }
ajs57a14772005-04-10 15:01:56 +00001190 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
ajs719e9742005-02-28 20:52:15 +00001191 {
1192 /* Try again later. */
1193 zebra_event (ZEBRA_READ, sock, client);
1194 return 0;
1195 }
ajs57a14772005-04-10 15:01:56 +00001196 already = ZEBRA_HEADER_SIZE;
ajs719e9742005-02-28 20:52:15 +00001197 }
1198
1199 /* Reset to read from the beginning of the incoming packet. */
1200 stream_set_getp(client->ibuf, 0);
1201
paulc1b98002006-01-16 01:54:02 +00001202 /* Fetch header values */
paul718e3742002-12-13 20:15:29 +00001203 length = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001204 marker = stream_getc (client->ibuf);
1205 version = stream_getc (client->ibuf);
1206 command = stream_getw (client->ibuf);
paul718e3742002-12-13 20:15:29 +00001207
paulc1b98002006-01-16 01:54:02 +00001208 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1209 {
1210 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1211 __func__, sock, marker, version);
1212 zebra_client_close (client);
1213 return -1;
1214 }
ajs719e9742005-02-28 20:52:15 +00001215 if (length < ZEBRA_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00001216 {
ajs57a14772005-04-10 15:01:56 +00001217 zlog_warn("%s: socket %d message length %u is less than header size %d",
1218 __func__, sock, length, ZEBRA_HEADER_SIZE);
1219 zebra_client_close (client);
1220 return -1;
1221 }
1222 if (length > STREAM_SIZE(client->ibuf))
1223 {
1224 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1225 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
paul718e3742002-12-13 20:15:29 +00001226 zebra_client_close (client);
1227 return -1;
1228 }
1229
paul718e3742002-12-13 20:15:29 +00001230 /* Read rest of data. */
ajs57a14772005-04-10 15:01:56 +00001231 if (already < length)
paul718e3742002-12-13 20:15:29 +00001232 {
ajs57a14772005-04-10 15:01:56 +00001233 ssize_t nbyte;
1234 if (((nbyte = stream_read_try (client->ibuf, sock,
1235 length-already)) == 0) ||
1236 (nbyte == -1))
paul718e3742002-12-13 20:15:29 +00001237 {
1238 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001239 zlog_debug ("connection closed [%d] when reading zebra data", sock);
paul718e3742002-12-13 20:15:29 +00001240 zebra_client_close (client);
1241 return -1;
1242 }
ajs57a14772005-04-10 15:01:56 +00001243 if (nbyte != (ssize_t)(length-already))
ajs719e9742005-02-28 20:52:15 +00001244 {
1245 /* Try again later. */
1246 zebra_event (ZEBRA_READ, sock, client);
1247 return 0;
1248 }
paul718e3742002-12-13 20:15:29 +00001249 }
1250
ajs719e9742005-02-28 20:52:15 +00001251 length -= ZEBRA_HEADER_SIZE;
1252
paul718e3742002-12-13 20:15:29 +00001253 /* Debug packet information. */
1254 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001255 zlog_debug ("zebra message comes from socket [%d]", sock);
paul718e3742002-12-13 20:15:29 +00001256
1257 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
ajsb6178002004-12-07 21:12:56 +00001258 zlog_debug ("zebra message received [%s] %d",
paul718e3742002-12-13 20:15:29 +00001259 zebra_command_str[command], length);
1260
1261 switch (command)
1262 {
hasso18a6dce2004-10-03 18:18:34 +00001263 case ZEBRA_ROUTER_ID_ADD:
1264 zread_router_id_add (client, length);
1265 break;
1266 case ZEBRA_ROUTER_ID_DELETE:
1267 zread_router_id_delete (client, length);
1268 break;
paul718e3742002-12-13 20:15:29 +00001269 case ZEBRA_INTERFACE_ADD:
1270 zread_interface_add (client, length);
1271 break;
1272 case ZEBRA_INTERFACE_DELETE:
1273 zread_interface_delete (client, length);
1274 break;
1275 case ZEBRA_IPV4_ROUTE_ADD:
1276 zread_ipv4_add (client, length);
1277 break;
1278 case ZEBRA_IPV4_ROUTE_DELETE:
1279 zread_ipv4_delete (client, length);
1280 break;
1281#ifdef HAVE_IPV6
1282 case ZEBRA_IPV6_ROUTE_ADD:
1283 zread_ipv6_add (client, length);
1284 break;
1285 case ZEBRA_IPV6_ROUTE_DELETE:
1286 zread_ipv6_delete (client, length);
1287 break;
1288#endif /* HAVE_IPV6 */
1289 case ZEBRA_REDISTRIBUTE_ADD:
1290 zebra_redistribute_add (command, client, length);
1291 break;
1292 case ZEBRA_REDISTRIBUTE_DELETE:
1293 zebra_redistribute_delete (command, client, length);
1294 break;
1295 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1296 zebra_redistribute_default_add (command, client, length);
1297 break;
1298 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1299 zebra_redistribute_default_delete (command, client, length);
1300 break;
1301 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1302 zread_ipv4_nexthop_lookup (client, length);
1303 break;
1304#ifdef HAVE_IPV6
1305 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1306 zread_ipv6_nexthop_lookup (client, length);
1307 break;
1308#endif /* HAVE_IPV6 */
1309 case ZEBRA_IPV4_IMPORT_LOOKUP:
1310 zread_ipv4_import_lookup (client, length);
1311 break;
1312 default:
1313 zlog_info ("Zebra received unknown command %d", command);
1314 break;
1315 }
1316
ajs719e9742005-02-28 20:52:15 +00001317 if (client->t_suicide)
1318 {
1319 /* No need to wait for thread callback, just kill immediately. */
1320 zebra_client_close(client);
1321 return -1;
1322 }
1323
paul718e3742002-12-13 20:15:29 +00001324 stream_reset (client->ibuf);
1325 zebra_event (ZEBRA_READ, sock, client);
paul718e3742002-12-13 20:15:29 +00001326 return 0;
1327}
1328
paul718e3742002-12-13 20:15:29 +00001329
1330/* Accept code of zebra server socket. */
paulb9df2d22004-05-09 09:09:59 +00001331static int
paul718e3742002-12-13 20:15:29 +00001332zebra_accept (struct thread *thread)
1333{
1334 int accept_sock;
1335 int client_sock;
1336 struct sockaddr_in client;
1337 socklen_t len;
1338
1339 accept_sock = THREAD_FD (thread);
1340
ajs719e9742005-02-28 20:52:15 +00001341 /* Reregister myself. */
1342 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1343
paul718e3742002-12-13 20:15:29 +00001344 len = sizeof (struct sockaddr_in);
1345 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1346
1347 if (client_sock < 0)
1348 {
ajs6099b3b2004-11-20 02:06:59 +00001349 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001350 return -1;
1351 }
1352
paulccf35572003-03-01 11:42:20 +00001353 /* Make client socket non-blocking. */
ajs719e9742005-02-28 20:52:15 +00001354 set_nonblocking(client_sock);
paul865b8522005-01-05 08:30:35 +00001355
paul718e3742002-12-13 20:15:29 +00001356 /* Create new zebra client. */
1357 zebra_client_create (client_sock);
1358
paul718e3742002-12-13 20:15:29 +00001359 return 0;
1360}
1361
paulb9df2d22004-05-09 09:09:59 +00001362#ifdef HAVE_TCP_ZEBRA
paul718e3742002-12-13 20:15:29 +00001363/* Make zebra's server socket. */
paulb9df2d22004-05-09 09:09:59 +00001364static void
paul718e3742002-12-13 20:15:29 +00001365zebra_serv ()
1366{
1367 int ret;
1368 int accept_sock;
1369 struct sockaddr_in addr;
1370
1371 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1372
1373 if (accept_sock < 0)
1374 {
paul3d1dc852005-04-05 00:45:23 +00001375 zlog_warn ("Can't create zserv stream socket: %s",
1376 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001377 zlog_warn ("zebra can't provice full functionality due to above error");
1378 return;
1379 }
1380
1381 memset (&addr, 0, sizeof (struct sockaddr_in));
1382 addr.sin_family = AF_INET;
1383 addr.sin_port = htons (ZEBRA_PORT);
1384#ifdef HAVE_SIN_LEN
1385 addr.sin_len = sizeof (struct sockaddr_in);
1386#endif /* HAVE_SIN_LEN */
1387 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1388
1389 sockopt_reuseaddr (accept_sock);
1390 sockopt_reuseport (accept_sock);
1391
pauledd7c242003-06-04 13:59:38 +00001392 if ( zserv_privs.change(ZPRIVS_RAISE) )
1393 zlog (NULL, LOG_ERR, "Can't raise privileges");
1394
paul718e3742002-12-13 20:15:29 +00001395 ret = bind (accept_sock, (struct sockaddr *)&addr,
1396 sizeof (struct sockaddr_in));
1397 if (ret < 0)
1398 {
paul3d1dc852005-04-05 00:45:23 +00001399 zlog_warn ("Can't bind to stream socket: %s",
1400 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001401 zlog_warn ("zebra can't provice full functionality due to above error");
1402 close (accept_sock); /* Avoid sd leak. */
1403 return;
1404 }
pauledd7c242003-06-04 13:59:38 +00001405
1406 if ( zserv_privs.change(ZPRIVS_LOWER) )
1407 zlog (NULL, LOG_ERR, "Can't lower privileges");
paul718e3742002-12-13 20:15:29 +00001408
1409 ret = listen (accept_sock, 1);
1410 if (ret < 0)
1411 {
paul3d1dc852005-04-05 00:45:23 +00001412 zlog_warn ("Can't listen to stream socket: %s",
1413 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001414 zlog_warn ("zebra can't provice full functionality due to above error");
1415 close (accept_sock); /* Avoid sd leak. */
1416 return;
1417 }
1418
1419 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1420}
paulb9df2d22004-05-09 09:09:59 +00001421#endif /* HAVE_TCP_ZEBRA */
paul718e3742002-12-13 20:15:29 +00001422
1423/* For sockaddr_un. */
1424#include <sys/un.h>
1425
1426/* zebra server UNIX domain socket. */
paulb9df2d22004-05-09 09:09:59 +00001427static void
hassofce954f2004-10-07 20:29:24 +00001428zebra_serv_un (const char *path)
paul718e3742002-12-13 20:15:29 +00001429{
1430 int ret;
1431 int sock, len;
1432 struct sockaddr_un serv;
1433 mode_t old_mask;
1434
1435 /* First of all, unlink existing socket */
1436 unlink (path);
1437
1438 /* Set umask */
1439 old_mask = umask (0077);
1440
1441 /* Make UNIX domain socket. */
1442 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1443 if (sock < 0)
1444 {
paul3d1dc852005-04-05 00:45:23 +00001445 zlog_warn ("Can't create zserv unix socket: %s",
1446 safe_strerror (errno));
1447 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001448 return;
1449 }
1450
1451 /* Make server socket. */
1452 memset (&serv, 0, sizeof (struct sockaddr_un));
1453 serv.sun_family = AF_UNIX;
1454 strncpy (serv.sun_path, path, strlen (path));
1455#ifdef HAVE_SUN_LEN
1456 len = serv.sun_len = SUN_LEN(&serv);
1457#else
1458 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1459#endif /* HAVE_SUN_LEN */
1460
1461 ret = bind (sock, (struct sockaddr *) &serv, len);
1462 if (ret < 0)
1463 {
paul3d1dc852005-04-05 00:45:23 +00001464 zlog_warn ("Can't bind to unix socket %s: %s",
1465 path, safe_strerror (errno));
1466 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001467 close (sock);
1468 return;
1469 }
1470
1471 ret = listen (sock, 5);
1472 if (ret < 0)
1473 {
paul3d1dc852005-04-05 00:45:23 +00001474 zlog_warn ("Can't listen to unix socket %s: %s",
1475 path, safe_strerror (errno));
1476 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001477 close (sock);
1478 return;
1479 }
1480
1481 umask (old_mask);
1482
1483 zebra_event (ZEBRA_SERV, sock, NULL);
1484}
1485
paul718e3742002-12-13 20:15:29 +00001486
paulb9df2d22004-05-09 09:09:59 +00001487static void
paul718e3742002-12-13 20:15:29 +00001488zebra_event (enum event event, int sock, struct zserv *client)
1489{
1490 switch (event)
1491 {
1492 case ZEBRA_SERV:
paulb21b19c2003-06-15 01:28:29 +00001493 thread_add_read (zebrad.master, zebra_accept, client, sock);
paul718e3742002-12-13 20:15:29 +00001494 break;
1495 case ZEBRA_READ:
1496 client->t_read =
paulb21b19c2003-06-15 01:28:29 +00001497 thread_add_read (zebrad.master, zebra_client_read, client, sock);
paul718e3742002-12-13 20:15:29 +00001498 break;
1499 case ZEBRA_WRITE:
1500 /**/
1501 break;
1502 }
1503}
1504
1505/* Display default rtm_table for all clients. */
1506DEFUN (show_table,
1507 show_table_cmd,
1508 "show table",
1509 SHOW_STR
1510 "default routing table to use for all clients\n")
1511{
paulb21b19c2003-06-15 01:28:29 +00001512 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001513 VTY_NEWLINE);
1514 return CMD_SUCCESS;
1515}
1516
1517DEFUN (config_table,
1518 config_table_cmd,
1519 "table TABLENO",
1520 "Configure target kernel routing table\n"
1521 "TABLE integer\n")
1522{
paulb21b19c2003-06-15 01:28:29 +00001523 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
paul718e3742002-12-13 20:15:29 +00001524 return CMD_SUCCESS;
1525}
1526
hasso647e4f12003-05-25 11:43:52 +00001527DEFUN (ip_forwarding,
1528 ip_forwarding_cmd,
1529 "ip forwarding",
1530 IP_STR
1531 "Turn on IP forwarding")
1532{
1533 int ret;
1534
1535 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001536 if (ret == 0)
1537 ret = ipforward_on ();
hasso647e4f12003-05-25 11:43:52 +00001538
hasso647e4f12003-05-25 11:43:52 +00001539 if (ret == 0)
1540 {
1541 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1542 return CMD_WARNING;
1543 }
1544
1545 return CMD_SUCCESS;
1546}
1547
paul718e3742002-12-13 20:15:29 +00001548DEFUN (no_ip_forwarding,
1549 no_ip_forwarding_cmd,
1550 "no ip forwarding",
1551 NO_STR
1552 IP_STR
1553 "Turn off IP forwarding")
1554{
1555 int ret;
1556
1557 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001558 if (ret != 0)
1559 ret = ipforward_off ();
paul718e3742002-12-13 20:15:29 +00001560
paul718e3742002-12-13 20:15:29 +00001561 if (ret != 0)
1562 {
1563 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1564 return CMD_WARNING;
1565 }
1566
1567 return CMD_SUCCESS;
1568}
1569
1570/* This command is for debugging purpose. */
1571DEFUN (show_zebra_client,
1572 show_zebra_client_cmd,
1573 "show zebra client",
1574 SHOW_STR
1575 "Zebra information"
1576 "Client information")
1577{
hasso52dc7ee2004-09-23 19:18:23 +00001578 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001579 struct zserv *client;
1580
paul1eb8ef22005-04-07 07:30:20 +00001581 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1582 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1583
paul718e3742002-12-13 20:15:29 +00001584 return CMD_SUCCESS;
1585}
1586
1587/* Table configuration write function. */
paulb9df2d22004-05-09 09:09:59 +00001588static int
paul718e3742002-12-13 20:15:29 +00001589config_write_table (struct vty *vty)
1590{
paulb21b19c2003-06-15 01:28:29 +00001591 if (zebrad.rtm_table_default)
1592 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001593 VTY_NEWLINE);
1594 return 0;
1595}
1596
1597/* table node for routing tables. */
1598struct cmd_node table_node =
1599{
1600 TABLE_NODE,
1601 "", /* This node has no interface. */
1602 1
1603};
1604
1605/* Only display ip forwarding is enabled or not. */
1606DEFUN (show_ip_forwarding,
1607 show_ip_forwarding_cmd,
1608 "show ip forwarding",
1609 SHOW_STR
1610 IP_STR
1611 "IP forwarding status\n")
1612{
1613 int ret;
1614
1615 ret = ipforward ();
1616
1617 if (ret == 0)
1618 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1619 else
1620 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1621 return CMD_SUCCESS;
1622}
1623
1624#ifdef HAVE_IPV6
1625/* Only display ipv6 forwarding is enabled or not. */
1626DEFUN (show_ipv6_forwarding,
1627 show_ipv6_forwarding_cmd,
1628 "show ipv6 forwarding",
1629 SHOW_STR
1630 "IPv6 information\n"
1631 "Forwarding status\n")
1632{
1633 int ret;
1634
1635 ret = ipforward_ipv6 ();
1636
1637 switch (ret)
1638 {
1639 case -1:
1640 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1641 break;
1642 case 0:
1643 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1644 break;
1645 case 1:
1646 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1647 break;
1648 default:
1649 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1650 break;
1651 }
1652 return CMD_SUCCESS;
1653}
1654
hasso55906722004-02-11 22:42:16 +00001655DEFUN (ipv6_forwarding,
1656 ipv6_forwarding_cmd,
1657 "ipv6 forwarding",
1658 IPV6_STR
1659 "Turn on IPv6 forwarding")
1660{
1661 int ret;
1662
hasso41d3fc92004-04-06 11:59:00 +00001663 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001664 if (ret == 0)
1665 ret = ipforward_ipv6_on ();
hasso41d3fc92004-04-06 11:59:00 +00001666
hasso41d3fc92004-04-06 11:59:00 +00001667 if (ret == 0)
1668 {
hasso55906722004-02-11 22:42:16 +00001669 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1670 return CMD_WARNING;
1671 }
1672
1673 return CMD_SUCCESS;
1674}
1675
paul718e3742002-12-13 20:15:29 +00001676DEFUN (no_ipv6_forwarding,
1677 no_ipv6_forwarding_cmd,
1678 "no ipv6 forwarding",
1679 NO_STR
hasso55906722004-02-11 22:42:16 +00001680 IPV6_STR
1681 "Turn off IPv6 forwarding")
paul718e3742002-12-13 20:15:29 +00001682{
1683 int ret;
1684
hasso41d3fc92004-04-06 11:59:00 +00001685 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001686 if (ret != 0)
1687 ret = ipforward_ipv6_off ();
hasso41d3fc92004-04-06 11:59:00 +00001688
paul718e3742002-12-13 20:15:29 +00001689 if (ret != 0)
1690 {
1691 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1692 return CMD_WARNING;
1693 }
1694
1695 return CMD_SUCCESS;
1696}
1697
1698#endif /* HAVE_IPV6 */
1699
1700/* IPForwarding configuration write function. */
ajs719e9742005-02-28 20:52:15 +00001701static int
paul718e3742002-12-13 20:15:29 +00001702config_write_forwarding (struct vty *vty)
1703{
hasso18a6dce2004-10-03 18:18:34 +00001704 /* FIXME: Find better place for that. */
1705 router_id_write (vty);
1706
paul3e0b3a52004-08-23 18:58:32 +00001707 if (ipforward ())
1708 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001709#ifdef HAVE_IPV6
paul3e0b3a52004-08-23 18:58:32 +00001710 if (ipforward_ipv6 ())
1711 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001712#endif /* HAVE_IPV6 */
1713 vty_out (vty, "!%s", VTY_NEWLINE);
1714 return 0;
1715}
1716
1717/* table node for routing tables. */
1718struct cmd_node forwarding_node =
1719{
1720 FORWARDING_NODE,
1721 "", /* This node has no interface. */
1722 1
1723};
1724
1725
1726/* Initialisation of zebra and installation of commands. */
1727void
paula1ac18c2005-06-28 17:17:12 +00001728zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001729{
1730 /* Client list init. */
paulb21b19c2003-06-15 01:28:29 +00001731 zebrad.client_list = list_new ();
paul718e3742002-12-13 20:15:29 +00001732
paul718e3742002-12-13 20:15:29 +00001733 /* Make zebra server socket. */
1734#ifdef HAVE_TCP_ZEBRA
1735 zebra_serv ();
1736#else
1737 zebra_serv_un (ZEBRA_SERV_PATH);
1738#endif /* HAVE_TCP_ZEBRA */
1739
1740 /* Install configuration write function. */
1741 install_node (&table_node, config_write_table);
1742 install_node (&forwarding_node, config_write_forwarding);
1743
1744 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1745 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00001746 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001747 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1748 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1749
1750#ifdef HAVE_NETLINK
1751 install_element (VIEW_NODE, &show_table_cmd);
1752 install_element (ENABLE_NODE, &show_table_cmd);
1753 install_element (CONFIG_NODE, &config_table_cmd);
1754#endif /* HAVE_NETLINK */
1755
1756#ifdef HAVE_IPV6
1757 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1758 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
hasso55906722004-02-11 22:42:16 +00001759 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001760 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1761#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001762}