blob: e624ef2f632dcd7af9157c8c09d6d1ee0c504cbe [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"
Feng Lu0d0686f2015-05-22 11:40:02 +020039#include "vrf.h"
paul718e3742002-12-13 20:15:29 +000040
41#include "zebra/zserv.h"
hasso18a6dce2004-10-03 18:18:34 +000042#include "zebra/router-id.h"
paul718e3742002-12-13 20:15:29 +000043#include "zebra/redistribute.h"
44#include "zebra/debug.h"
45#include "zebra/ipforward.h"
David Lamparter6b0655a2014-06-04 06:53:35 +020046
paul718e3742002-12-13 20:15:29 +000047/* Event list of zebra. */
48enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
49
paulb21b19c2003-06-15 01:28:29 +000050extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000051
paulb9df2d22004-05-09 09:09:59 +000052static void zebra_event (enum event event, int sock, struct zserv *client);
paulccf35572003-03-01 11:42:20 +000053
pauledd7c242003-06-04 13:59:38 +000054extern struct zebra_privs_t zserv_privs;
David Lamparter6b0655a2014-06-04 06:53:35 +020055
ajs719e9742005-02-28 20:52:15 +000056static void zebra_client_close (struct zserv *client);
57
58static int
59zserv_delayed_close(struct thread *thread)
paulccf35572003-03-01 11:42:20 +000060{
ajs719e9742005-02-28 20:52:15 +000061 struct zserv *client = THREAD_ARG(thread);
paulccf35572003-03-01 11:42:20 +000062
ajs719e9742005-02-28 20:52:15 +000063 client->t_suicide = NULL;
64 zebra_client_close(client);
paulccf35572003-03-01 11:42:20 +000065 return 0;
66}
67
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +040068/* When client connects, it sends hello message
69 * with promise to send zebra routes of specific type.
70 * Zebra stores a socket fd of the client into
71 * this array. And use it to clean up routes that
72 * client didn't remove for some reasons after closing
73 * connection.
74 */
75static int route_type_oaths[ZEBRA_ROUTE_MAX];
76
ajs719e9742005-02-28 20:52:15 +000077static int
78zserv_flush_data(struct thread *thread)
paulccf35572003-03-01 11:42:20 +000079{
ajs719e9742005-02-28 20:52:15 +000080 struct zserv *client = THREAD_ARG(thread);
paulccf35572003-03-01 11:42:20 +000081
ajs719e9742005-02-28 20:52:15 +000082 client->t_write = NULL;
83 if (client->t_suicide)
84 {
85 zebra_client_close(client);
86 return -1;
87 }
88 switch (buffer_flush_available(client->wb, client->sock))
89 {
90 case BUFFER_ERROR:
91 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
92 "closing", __func__, client->sock);
93 zebra_client_close(client);
94 break;
95 case BUFFER_PENDING:
96 client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
97 client, client->sock);
98 break;
99 case BUFFER_EMPTY:
100 break;
101 }
102 return 0;
paulccf35572003-03-01 11:42:20 +0000103}
104
ajs719e9742005-02-28 20:52:15 +0000105static int
106zebra_server_send_message(struct zserv *client)
paulccf35572003-03-01 11:42:20 +0000107{
ajs719e9742005-02-28 20:52:15 +0000108 if (client->t_suicide)
109 return -1;
110 switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
111 stream_get_endp(client->obuf)))
paulccf35572003-03-01 11:42:20 +0000112 {
ajs719e9742005-02-28 20:52:15 +0000113 case BUFFER_ERROR:
114 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
115 __func__, client->sock);
116 /* Schedule a delayed close since many of the functions that call this
117 one do not check the return code. They do not allow for the
118 possibility that an I/O error may have caused the client to be
119 deleted. */
120 client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
121 client, 0);
122 return -1;
ajs719e9742005-02-28 20:52:15 +0000123 case BUFFER_EMPTY:
124 THREAD_OFF(client->t_write);
125 break;
126 case BUFFER_PENDING:
127 THREAD_WRITE_ON(zebrad.master, client->t_write,
128 zserv_flush_data, client, client->sock);
129 break;
paulccf35572003-03-01 11:42:20 +0000130 }
paulccf35572003-03-01 11:42:20 +0000131 return 0;
132}
133
paulc1b98002006-01-16 01:54:02 +0000134static void
Feng Luc99f3482014-10-16 09:52:36 +0800135zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
paulc1b98002006-01-16 01:54:02 +0000136{
137 /* length placeholder, caller can update */
138 stream_putw (s, ZEBRA_HEADER_SIZE);
139 stream_putc (s, ZEBRA_HEADER_MARKER);
140 stream_putc (s, ZSERV_VERSION);
Feng Luc99f3482014-10-16 09:52:36 +0800141 stream_putw (s, vrf_id);
paulc1b98002006-01-16 01:54:02 +0000142 stream_putw (s, cmd);
143}
144
Josh Bailey51d4ef82012-03-21 17:13:39 -0700145static void
146zserv_encode_interface (struct stream *s, struct interface *ifp)
147{
148 /* Interface information. */
149 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
150 stream_putl (s, ifp->ifindex);
151 stream_putc (s, ifp->status);
152 stream_putq (s, ifp->flags);
153 stream_putl (s, ifp->metric);
154 stream_putl (s, ifp->mtu);
155 stream_putl (s, ifp->mtu6);
156 stream_putl (s, ifp->bandwidth);
Timo Teräs954c7d62016-01-15 17:36:33 +0200157 stream_putl (s, ifp->ll_type);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700158 stream_putl (s, ifp->hw_addr_len);
159 if (ifp->hw_addr_len)
160 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700161
162 /* Write packet size. */
163 stream_putw_at (s, 0, stream_get_endp (s));
164}
165
paul718e3742002-12-13 20:15:29 +0000166/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
paulb9df2d22004-05-09 09:09:59 +0000167/*
168 * This function is called in the following situations:
169 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
170 * from the client.
171 * - at startup, when zebra figures out the available interfaces
172 * - when an interface is added (where support for
173 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
174 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
175 * received)
176 */
paul718e3742002-12-13 20:15:29 +0000177int
178zsend_interface_add (struct zserv *client, struct interface *ifp)
179{
180 struct stream *s;
181
182 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800183 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000184 return 0;
paul718e3742002-12-13 20:15:29 +0000185
186 s = client->obuf;
187 stream_reset (s);
188
Feng Luc99f3482014-10-16 09:52:36 +0800189 zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700190 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000191
ajs719e9742005-02-28 20:52:15 +0000192 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000193}
194
195/* Interface deletion from zebra daemon. */
196int
197zsend_interface_delete (struct zserv *client, struct interface *ifp)
198{
199 struct stream *s;
200
201 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800202 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000203 return 0;
paul718e3742002-12-13 20:15:29 +0000204
205 s = client->obuf;
206 stream_reset (s);
paul718e3742002-12-13 20:15:29 +0000207
Feng Luc99f3482014-10-16 09:52:36 +0800208 zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700209 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000210
ajs719e9742005-02-28 20:52:15 +0000211 return zebra_server_send_message (client);
paul718e3742002-12-13 20:15:29 +0000212}
213
paulb9df2d22004-05-09 09:09:59 +0000214/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
215 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
216 *
217 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
218 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
219 * from the client, after the ZEBRA_INTERFACE_ADD has been
220 * sent from zebra to the client
221 * - redistribute new address info to all clients in the following situations
222 * - at startup, when zebra figures out the available interfaces
223 * - when an interface is added (where support for
224 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
225 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
226 * received)
227 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
228 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
229 * - when an RTM_NEWADDR message is received from the kernel,
230 *
231 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
232 *
233 * zsend_interface_address(DELETE)
234 * ^
235 * |
236 * zebra_interface_address_delete_update
237 * ^ ^ ^
paul6eb88272005-07-29 14:36:00 +0000238 * | | if_delete_update
239 * | |
paulb9df2d22004-05-09 09:09:59 +0000240 * ip_address_uninstall connected_delete_ipv4
241 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
242 * ^ ^
243 * | |
244 * | RTM_NEWADDR on routing/netlink socket
245 * |
246 * vty commands:
247 * "no ip address A.B.C.D/M [label LINE]"
248 * "no ip address A.B.C.D/M secondary"
249 * ["no ipv6 address X:X::X:X/M"]
250 *
251 */
paul718e3742002-12-13 20:15:29 +0000252int
paulb9df2d22004-05-09 09:09:59 +0000253zsend_interface_address (int cmd, struct zserv *client,
254 struct interface *ifp, struct connected *ifc)
paul718e3742002-12-13 20:15:29 +0000255{
256 int blen;
257 struct stream *s;
258 struct prefix *p;
259
260 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800261 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000262 return 0;
paul718e3742002-12-13 20:15:29 +0000263
264 s = client->obuf;
265 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000266
Feng Luc99f3482014-10-16 09:52:36 +0800267 zserv_create_header (s, cmd, ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000268 stream_putl (s, ifp->ifindex);
269
270 /* Interface address flag. */
271 stream_putc (s, ifc->flags);
272
273 /* Prefix information. */
274 p = ifc->address;
275 stream_putc (s, p->family);
276 blen = prefix_blen (p);
277 stream_put (s, &p->u.prefix, blen);
paulb9df2d22004-05-09 09:09:59 +0000278
279 /*
280 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
281 * but zebra_interface_address_delete_read() in the gnu version
282 * expects to find it
283 */
paul718e3742002-12-13 20:15:29 +0000284 stream_putc (s, p->prefixlen);
285
286 /* Destination. */
287 p = ifc->destination;
288 if (p)
289 stream_put (s, &p->u.prefix, blen);
290 else
291 stream_put (s, NULL, blen);
292
293 /* Write packet size. */
294 stream_putw_at (s, 0, stream_get_endp (s));
295
ajs719e9742005-02-28 20:52:15 +0000296 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000297}
298
paulb9df2d22004-05-09 09:09:59 +0000299/*
300 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
301 * ZEBRA_INTERFACE_DOWN.
302 *
303 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
304 * the clients in one of 2 situations:
305 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
306 * - a vty command modifying the bandwidth of an interface is received.
307 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
308 */
paul718e3742002-12-13 20:15:29 +0000309int
paulb9df2d22004-05-09 09:09:59 +0000310zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000311{
312 struct stream *s;
313
314 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800315 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000316 return 0;
paul718e3742002-12-13 20:15:29 +0000317
318 s = client->obuf;
319 stream_reset (s);
320
Feng Luc99f3482014-10-16 09:52:36 +0800321 zserv_create_header (s, cmd, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700322 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000323
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 zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
329 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
330 * situations:
331 * - when the client starts up, and requests default information
332 * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
333 * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
334 * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
335 * - when the zebra server redistributes routes after it updates its rib
336 *
337 * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
338 * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
339 * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
340 * - deleted from zebra's rib, and this info
341 * has to be redistributed to the clients
342 *
343 * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
344 * zebra server when the client wants to tell the zebra server to add a
345 * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
346 * same message being sent back and forth, this function and
347 * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
348 * duplication.
349 */
paul718e3742002-12-13 20:15:29 +0000350int
paulb9df2d22004-05-09 09:09:59 +0000351zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
352 struct rib *rib)
paul718e3742002-12-13 20:15:29 +0000353{
354 int psize;
355 struct stream *s;
356 struct nexthop *nexthop;
paul1dcb5172005-05-31 08:38:50 +0000357 unsigned long nhnummark = 0, messmark = 0;
paulb9df2d22004-05-09 09:09:59 +0000358 int nhnum = 0;
paul1dcb5172005-05-31 08:38:50 +0000359 u_char zapi_flags = 0;
Feng Luc99f3482014-10-16 09:52:36 +0800360
361 /* Check this client need this route. */
362 if (!vrf_bitmap_check (client->redist[rib->type], rib->vrf_id) &&
363 !(is_default (p) &&
364 vrf_bitmap_check (client->redist_default, rib->vrf_id)))
365 return 0;
366
paul718e3742002-12-13 20:15:29 +0000367 s = client->obuf;
368 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000369
Feng Luc99f3482014-10-16 09:52:36 +0800370 zserv_create_header (s, cmd, rib->vrf_id);
paulc1b98002006-01-16 01:54:02 +0000371
372 /* Put type and nexthop. */
paul718e3742002-12-13 20:15:29 +0000373 stream_putc (s, rib->type);
374 stream_putc (s, rib->flags);
paul1dcb5172005-05-31 08:38:50 +0000375
376 /* marker for message flags field */
377 messmark = stream_get_endp (s);
378 stream_putc (s, 0);
paul718e3742002-12-13 20:15:29 +0000379
380 /* Prefix. */
381 psize = PSIZE (p->prefixlen);
382 stream_putc (s, p->prefixlen);
paulb9df2d22004-05-09 09:09:59 +0000383 stream_write (s, (u_char *) & p->u.prefix, psize);
paul718e3742002-12-13 20:15:29 +0000384
paulb9df2d22004-05-09 09:09:59 +0000385 /*
386 * XXX The message format sent by zebra below does not match the format
387 * of the corresponding message expected by the zebra server
388 * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
389 * (is there a bug on the client side if more than one segment is sent?)
390 * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
391 * is hard-coded.
392 */
paul718e3742002-12-13 20:15:29 +0000393 /* Nexthop */
paul1dcb5172005-05-31 08:38:50 +0000394
paul718e3742002-12-13 20:15:29 +0000395 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
396 {
Timo Teräs325823a2016-01-15 17:36:31 +0200397 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paulb9df2d22004-05-09 09:09:59 +0000398 {
paul1dcb5172005-05-31 08:38:50 +0000399 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
400 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
401
402 if (nhnummark == 0)
403 {
404 nhnummark = stream_get_endp (s);
405 stream_putc (s, 1); /* placeholder */
406 }
407
paulb9df2d22004-05-09 09:09:59 +0000408 nhnum++;
paul718e3742002-12-13 20:15:29 +0000409
paulb9df2d22004-05-09 09:09:59 +0000410 switch(nexthop->type)
411 {
412 case NEXTHOP_TYPE_IPV4:
413 case NEXTHOP_TYPE_IPV4_IFINDEX:
414 stream_put_in_addr (s, &nexthop->gate.ipv4);
415 break;
416#ifdef HAVE_IPV6
417 case NEXTHOP_TYPE_IPV6:
418 case NEXTHOP_TYPE_IPV6_IFINDEX:
419 case NEXTHOP_TYPE_IPV6_IFNAME:
420 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
421 break;
422#endif
423 default:
424 if (cmd == ZEBRA_IPV4_ROUTE_ADD
425 || cmd == ZEBRA_IPV4_ROUTE_DELETE)
426 {
427 struct in_addr empty;
paul44983cf2004-09-22 13:15:58 +0000428 memset (&empty, 0, sizeof (struct in_addr));
paulb9df2d22004-05-09 09:09:59 +0000429 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
430 }
431 else
432 {
433 struct in6_addr empty;
434 memset (&empty, 0, sizeof (struct in6_addr));
435 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
436 }
437 }
paul718e3742002-12-13 20:15:29 +0000438
paulb9df2d22004-05-09 09:09:59 +0000439 /* Interface index. */
440 stream_putc (s, 1);
441 stream_putl (s, nexthop->ifindex);
paul718e3742002-12-13 20:15:29 +0000442
paulb9df2d22004-05-09 09:09:59 +0000443 break;
444 }
paul718e3742002-12-13 20:15:29 +0000445 }
446
447 /* Metric */
Stephen Hemmingercf8a8312010-08-18 15:56:46 -0700448 if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
paul1dcb5172005-05-31 08:38:50 +0000449 {
vincentfbf5d032005-09-29 11:25:50 +0000450 SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
451 stream_putc (s, rib->distance);
paul1dcb5172005-05-31 08:38:50 +0000452 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
453 stream_putl (s, rib->metric);
Timo Teräsb11f3b52015-11-02 16:50:07 +0200454 SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
455 stream_putl (s, rib->mtu);
paul1dcb5172005-05-31 08:38:50 +0000456 }
457
458 /* write real message flags value */
459 stream_putc_at (s, messmark, zapi_flags);
460
paulb9df2d22004-05-09 09:09:59 +0000461 /* Write next-hop number */
462 if (nhnummark)
hassoc1eaa442004-10-19 06:26:01 +0000463 stream_putc_at (s, nhnummark, nhnum);
paulb9df2d22004-05-09 09:09:59 +0000464
paul718e3742002-12-13 20:15:29 +0000465 /* Write packet size. */
466 stream_putw_at (s, 0, stream_get_endp (s));
467
ajs719e9742005-02-28 20:52:15 +0000468 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000469}
470
paul718e3742002-12-13 20:15:29 +0000471#ifdef HAVE_IPV6
ajs719e9742005-02-28 20:52:15 +0000472static int
Feng Luc99f3482014-10-16 09:52:36 +0800473zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
474 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000475{
476 struct stream *s;
477 struct rib *rib;
478 unsigned long nump;
479 u_char num;
480 struct nexthop *nexthop;
481
482 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800483 rib = rib_match_ipv6 (addr, vrf_id);
paul718e3742002-12-13 20:15:29 +0000484
485 /* Get output stream. */
486 s = client->obuf;
487 stream_reset (s);
488
489 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800490 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
Hiroshi Yokoi8ccd74c2015-09-08 11:52:20 +0900491 stream_put (s, addr, 16);
paul718e3742002-12-13 20:15:29 +0000492
493 if (rib)
494 {
495 stream_putl (s, rib->metric);
496 num = 0;
paul9985f832005-02-09 15:51:56 +0000497 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000498 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000499 /* Only non-recursive routes are elegible to resolve nexthop we
500 * are looking up. Therefore, we will just iterate over the top
501 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000502 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200503 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000504 {
505 stream_putc (s, nexthop->type);
506 switch (nexthop->type)
507 {
508 case ZEBRA_NEXTHOP_IPV6:
509 stream_put (s, &nexthop->gate.ipv6, 16);
510 break;
511 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
512 case ZEBRA_NEXTHOP_IPV6_IFNAME:
513 stream_put (s, &nexthop->gate.ipv6, 16);
514 stream_putl (s, nexthop->ifindex);
515 break;
516 case ZEBRA_NEXTHOP_IFINDEX:
517 case ZEBRA_NEXTHOP_IFNAME:
518 stream_putl (s, nexthop->ifindex);
519 break;
hassofa2b17e2004-03-04 17:45:00 +0000520 default:
521 /* do nothing */
522 break;
paul718e3742002-12-13 20:15:29 +0000523 }
524 num++;
525 }
526 stream_putc_at (s, nump, num);
527 }
528 else
529 {
530 stream_putl (s, 0);
531 stream_putc (s, 0);
532 }
533
534 stream_putw_at (s, 0, stream_get_endp (s));
535
ajs719e9742005-02-28 20:52:15 +0000536 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000537}
538#endif /* HAVE_IPV6 */
539
paulb9df2d22004-05-09 09:09:59 +0000540static int
Feng Luc99f3482014-10-16 09:52:36 +0800541zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
542 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000543{
544 struct stream *s;
545 struct rib *rib;
546 unsigned long nump;
547 u_char num;
548 struct nexthop *nexthop;
549
David Lamparterf598cf72014-11-22 14:44:20 -0800550 /* Lookup nexthop - eBGP excluded */
Feng Luc99f3482014-10-16 09:52:36 +0800551 rib = rib_match_ipv4_safi (addr, SAFI_UNICAST, 1, NULL, vrf_id);
paul718e3742002-12-13 20:15:29 +0000552
553 /* Get output stream. */
554 s = client->obuf;
555 stream_reset (s);
556
557 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800558 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000559 stream_put_in_addr (s, &addr);
560
561 if (rib)
562 {
Christian Frankebb97e462013-05-25 14:01:35 +0000563 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
564 zlog_debug("%s: Matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000565 stream_putl (s, rib->metric);
566 num = 0;
paul9985f832005-02-09 15:51:56 +0000567 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000568 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000569 /* Only non-recursive routes are elegible to resolve the nexthop we
570 * are looking up. Therefore, we will just iterate over the top
571 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000572 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200573 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000574 {
575 stream_putc (s, nexthop->type);
576 switch (nexthop->type)
577 {
578 case ZEBRA_NEXTHOP_IPV4:
579 stream_put_in_addr (s, &nexthop->gate.ipv4);
580 break;
Christian Frankebb97e462013-05-25 14:01:35 +0000581 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
582 stream_put_in_addr (s, &nexthop->gate.ipv4);
583 stream_putl (s, nexthop->ifindex);
584 break;
paul718e3742002-12-13 20:15:29 +0000585 case ZEBRA_NEXTHOP_IFINDEX:
586 case ZEBRA_NEXTHOP_IFNAME:
587 stream_putl (s, nexthop->ifindex);
588 break;
hassofa2b17e2004-03-04 17:45:00 +0000589 default:
590 /* do nothing */
591 break;
paul718e3742002-12-13 20:15:29 +0000592 }
593 num++;
594 }
595 stream_putc_at (s, nump, num);
596 }
597 else
598 {
Christian Frankebb97e462013-05-25 14:01:35 +0000599 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
600 zlog_debug("%s: No matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000601 stream_putl (s, 0);
602 stream_putc (s, 0);
603 }
604
605 stream_putw_at (s, 0, stream_get_endp (s));
606
ajs719e9742005-02-28 20:52:15 +0000607 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000608}
609
Everton Marques4e5275b2014-07-01 15:15:52 -0300610/*
611 Modified version of zsend_ipv4_nexthop_lookup():
612 Query unicast rib if nexthop is not found on mrib.
613 Returns both route metric and protocol distance.
614*/
615static int
David Lamparterbd078122015-01-06 19:53:24 +0100616zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr,
617 struct rib *rib)
Everton Marques4e5275b2014-07-01 15:15:52 -0300618{
619 struct stream *s;
Everton Marques4e5275b2014-07-01 15:15:52 -0300620 unsigned long nump;
621 u_char num;
622 struct nexthop *nexthop;
Everton Marques4e5275b2014-07-01 15:15:52 -0300623
624 /* Get output stream. */
625 s = client->obuf;
626 stream_reset (s);
627
628 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800629 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, rib->vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -0300630 stream_put_in_addr (s, &addr);
631
632 if (rib)
633 {
634 stream_putc (s, rib->distance);
635 stream_putl (s, rib->metric);
636 num = 0;
637 nump = stream_get_endp(s); /* remember position for nexthop_num */
638 stream_putc (s, 0); /* reserve room for nexthop_num */
639 /* Only non-recursive routes are elegible to resolve the nexthop we
640 * are looking up. Therefore, we will just iterate over the top
641 * chain of nexthops. */
642 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200643 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
Everton Marques4e5275b2014-07-01 15:15:52 -0300644 {
645 stream_putc (s, nexthop->type);
646 switch (nexthop->type)
647 {
648 case ZEBRA_NEXTHOP_IPV4:
649 stream_put_in_addr (s, &nexthop->gate.ipv4);
650 break;
651 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
652 stream_put_in_addr (s, &nexthop->gate.ipv4);
653 stream_putl (s, nexthop->ifindex);
654 break;
655 case ZEBRA_NEXTHOP_IFINDEX:
656 case ZEBRA_NEXTHOP_IFNAME:
657 stream_putl (s, nexthop->ifindex);
658 break;
659 default:
660 /* do nothing */
661 break;
662 }
663 num++;
664 }
665
666 stream_putc_at (s, nump, num); /* store nexthop_num */
667 }
668 else
669 {
670 stream_putc (s, 0); /* distance */
671 stream_putl (s, 0); /* metric */
672 stream_putc (s, 0); /* nexthop_num */
673 }
674
675 stream_putw_at (s, 0, stream_get_endp (s));
676
677 return zebra_server_send_message(client);
678}
679
paulb9df2d22004-05-09 09:09:59 +0000680static int
Feng Luc99f3482014-10-16 09:52:36 +0800681zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
682 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000683{
684 struct stream *s;
685 struct rib *rib;
686 unsigned long nump;
687 u_char num;
688 struct nexthop *nexthop;
689
690 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800691 rib = rib_lookup_ipv4 (p, vrf_id);
paul718e3742002-12-13 20:15:29 +0000692
693 /* Get output stream. */
694 s = client->obuf;
695 stream_reset (s);
696
697 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800698 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000699 stream_put_in_addr (s, &p->prefix);
700
701 if (rib)
702 {
703 stream_putl (s, rib->metric);
704 num = 0;
paul9985f832005-02-09 15:51:56 +0000705 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000706 stream_putc (s, 0);
707 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200708 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000709 {
710 stream_putc (s, nexthop->type);
711 switch (nexthop->type)
712 {
713 case ZEBRA_NEXTHOP_IPV4:
714 stream_put_in_addr (s, &nexthop->gate.ipv4);
715 break;
Christian Frankea12afd52013-05-25 14:01:36 +0000716 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
717 stream_put_in_addr (s, &nexthop->gate.ipv4);
718 stream_putl (s, nexthop->ifindex);
719 break;
paul718e3742002-12-13 20:15:29 +0000720 case ZEBRA_NEXTHOP_IFINDEX:
721 case ZEBRA_NEXTHOP_IFNAME:
722 stream_putl (s, nexthop->ifindex);
723 break;
hassofa2b17e2004-03-04 17:45:00 +0000724 default:
725 /* do nothing */
726 break;
paul718e3742002-12-13 20:15:29 +0000727 }
728 num++;
729 }
730 stream_putc_at (s, nump, num);
731 }
732 else
733 {
734 stream_putl (s, 0);
735 stream_putc (s, 0);
736 }
737
738 stream_putw_at (s, 0, stream_get_endp (s));
739
ajs719e9742005-02-28 20:52:15 +0000740 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000741}
David Lamparter6b0655a2014-06-04 06:53:35 +0200742
hasso18a6dce2004-10-03 18:18:34 +0000743/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
744int
Feng Luac19a442015-05-22 11:40:07 +0200745zsend_router_id_update (struct zserv *client, struct prefix *p,
746 vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +0000747{
748 struct stream *s;
749 int blen;
750
751 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800752 if (! vrf_bitmap_check (client->ridinfo, vrf_id))
ajs719e9742005-02-28 20:52:15 +0000753 return 0;
hasso18a6dce2004-10-03 18:18:34 +0000754
755 s = client->obuf;
756 stream_reset (s);
757
hasso18a6dce2004-10-03 18:18:34 +0000758 /* Message type. */
Feng Luc99f3482014-10-16 09:52:36 +0800759 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +0000760
761 /* Prefix information. */
762 stream_putc (s, p->family);
763 blen = prefix_blen (p);
764 stream_put (s, &p->u.prefix, blen);
765 stream_putc (s, p->prefixlen);
766
767 /* Write packet size. */
768 stream_putw_at (s, 0, stream_get_endp (s));
769
ajs719e9742005-02-28 20:52:15 +0000770 return zebra_server_send_message(client);
hasso18a6dce2004-10-03 18:18:34 +0000771}
David Lamparter6b0655a2014-06-04 06:53:35 +0200772
paul718e3742002-12-13 20:15:29 +0000773/* Register zebra server interface information. Send current all
774 interface and address information. */
ajs719e9742005-02-28 20:52:15 +0000775static int
Feng Luc99f3482014-10-16 09:52:36 +0800776zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000777{
paul1eb8ef22005-04-07 07:30:20 +0000778 struct listnode *ifnode, *ifnnode;
779 struct listnode *cnode, *cnnode;
paul718e3742002-12-13 20:15:29 +0000780 struct interface *ifp;
781 struct connected *c;
782
783 /* Interface information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +0800784 vrf_bitmap_set (client->ifinfo, vrf_id);
paul718e3742002-12-13 20:15:29 +0000785
Feng Luc99f3482014-10-16 09:52:36 +0800786 for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
paul718e3742002-12-13 20:15:29 +0000787 {
paul718e3742002-12-13 20:15:29 +0000788 /* Skip pseudo interface. */
789 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
790 continue;
791
ajs719e9742005-02-28 20:52:15 +0000792 if (zsend_interface_add (client, ifp) < 0)
793 return -1;
paul718e3742002-12-13 20:15:29 +0000794
paul1eb8ef22005-04-07 07:30:20 +0000795 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
paul718e3742002-12-13 20:15:29 +0000796 {
ajs719e9742005-02-28 20:52:15 +0000797 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
798 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
799 ifp, c) < 0))
800 return -1;
paul718e3742002-12-13 20:15:29 +0000801 }
802 }
ajs719e9742005-02-28 20:52:15 +0000803 return 0;
paul718e3742002-12-13 20:15:29 +0000804}
805
806/* Unregister zebra server interface information. */
ajs719e9742005-02-28 20:52:15 +0000807static int
Feng Luc99f3482014-10-16 09:52:36 +0800808zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000809{
Feng Luc99f3482014-10-16 09:52:36 +0800810 vrf_bitmap_unset (client->ifinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +0000811 return 0;
paul718e3742002-12-13 20:15:29 +0000812}
813
814/* This function support multiple nexthop. */
paulb9df2d22004-05-09 09:09:59 +0000815/*
816 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
817 * add kernel route.
818 */
ajs719e9742005-02-28 20:52:15 +0000819static int
Feng Luc99f3482014-10-16 09:52:36 +0800820zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000821{
822 int i;
823 struct rib *rib;
824 struct prefix_ipv4 p;
825 u_char message;
826 struct in_addr nexthop;
827 u_char nexthop_num;
828 u_char nexthop_type;
829 struct stream *s;
Paul Jakma9099f9b2016-01-18 10:12:10 +0000830 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000831 u_char ifname_len;
G.Balajicddf3912011-11-26 21:59:32 +0400832 safi_t safi;
833
paul718e3742002-12-13 20:15:29 +0000834
835 /* Get input stream. */
836 s = client->ibuf;
837
838 /* Allocate new rib. */
paul4d38fdb2005-04-28 17:35:14 +0000839 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
840
paul718e3742002-12-13 20:15:29 +0000841 /* Type, flags, message. */
842 rib->type = stream_getc (s);
843 rib->flags = stream_getc (s);
paulb9df2d22004-05-09 09:09:59 +0000844 message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400845 safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000846 rib->uptime = time (NULL);
847
848 /* IPv4 prefix. */
849 memset (&p, 0, sizeof (struct prefix_ipv4));
850 p.family = AF_INET;
851 p.prefixlen = stream_getc (s);
852 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
853
Feng Lu0d0686f2015-05-22 11:40:02 +0200854 /* VRF ID */
Feng Luc99f3482014-10-16 09:52:36 +0800855 rib->vrf_id = vrf_id;
Feng Lu0d0686f2015-05-22 11:40:02 +0200856
paul718e3742002-12-13 20:15:29 +0000857 /* Nexthop parse. */
858 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
859 {
860 nexthop_num = stream_getc (s);
861
862 for (i = 0; i < nexthop_num; i++)
863 {
864 nexthop_type = stream_getc (s);
865
866 switch (nexthop_type)
867 {
868 case ZEBRA_NEXTHOP_IFINDEX:
869 ifindex = stream_getl (s);
870 nexthop_ifindex_add (rib, ifindex);
871 break;
872 case ZEBRA_NEXTHOP_IFNAME:
873 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000874 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000875 break;
876 case ZEBRA_NEXTHOP_IPV4:
877 nexthop.s_addr = stream_get_ipv4 (s);
Paul Jakma7514fb72007-05-02 16:05:35 +0000878 nexthop_ipv4_add (rib, &nexthop, NULL);
paul718e3742002-12-13 20:15:29 +0000879 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200880 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
881 nexthop.s_addr = stream_get_ipv4 (s);
882 ifindex = stream_getl (s);
883 nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
884 break;
paul718e3742002-12-13 20:15:29 +0000885 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000886 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000887 break;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700888 case ZEBRA_NEXTHOP_BLACKHOLE:
889 nexthop_blackhole_add (rib);
890 break;
891 }
paul718e3742002-12-13 20:15:29 +0000892 }
893 }
894
895 /* Distance. */
896 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
897 rib->distance = stream_getc (s);
898
899 /* Metric. */
900 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
901 rib->metric = stream_getl (s);
902
Timo Teräsb11f3b52015-11-02 16:50:07 +0200903 if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
904 rib->mtu = stream_getl (s);
905
Paul Jakma171eee32006-07-27 16:11:02 +0000906 /* Table */
907 rib->table=zebrad.rtm_table_default;
G.Balajicddf3912011-11-26 21:59:32 +0400908 rib_add_ipv4_multipath (&p, rib, safi);
ajs719e9742005-02-28 20:52:15 +0000909 return 0;
paul718e3742002-12-13 20:15:29 +0000910}
911
912/* Zebra server IPv4 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +0000913static int
Feng Luc99f3482014-10-16 09:52:36 +0800914zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000915{
916 int i;
917 struct stream *s;
918 struct zapi_ipv4 api;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700919 struct in_addr nexthop, *nexthop_p;
paul718e3742002-12-13 20:15:29 +0000920 unsigned long ifindex;
921 struct prefix_ipv4 p;
922 u_char nexthop_num;
923 u_char nexthop_type;
924 u_char ifname_len;
925
926 s = client->ibuf;
927 ifindex = 0;
928 nexthop.s_addr = 0;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700929 nexthop_p = NULL;
paul718e3742002-12-13 20:15:29 +0000930
931 /* Type, flags, message. */
932 api.type = stream_getc (s);
933 api.flags = stream_getc (s);
934 api.message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400935 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000936
937 /* IPv4 prefix. */
938 memset (&p, 0, sizeof (struct prefix_ipv4));
939 p.family = AF_INET;
940 p.prefixlen = stream_getc (s);
941 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
942
943 /* Nexthop, ifindex, distance, metric. */
944 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
945 {
946 nexthop_num = stream_getc (s);
947
948 for (i = 0; i < nexthop_num; i++)
949 {
950 nexthop_type = stream_getc (s);
951
952 switch (nexthop_type)
953 {
954 case ZEBRA_NEXTHOP_IFINDEX:
955 ifindex = stream_getl (s);
956 break;
957 case ZEBRA_NEXTHOP_IFNAME:
958 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000959 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000960 break;
961 case ZEBRA_NEXTHOP_IPV4:
962 nexthop.s_addr = stream_get_ipv4 (s);
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700963 nexthop_p = &nexthop;
paul718e3742002-12-13 20:15:29 +0000964 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200965 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
966 nexthop.s_addr = stream_get_ipv4 (s);
Christian Franke23f5f7c2013-11-27 17:06:14 +0000967 nexthop_p = &nexthop;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200968 ifindex = stream_getl (s);
969 break;
paul718e3742002-12-13 20:15:29 +0000970 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000971 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000972 break;
973 }
974 }
975 }
976
977 /* Distance. */
978 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
979 api.distance = stream_getc (s);
980 else
981 api.distance = 0;
982
983 /* Metric. */
984 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
985 api.metric = stream_getl (s);
986 else
987 api.metric = 0;
988
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700989 rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +0800990 vrf_id, api.safi);
ajs719e9742005-02-28 20:52:15 +0000991 return 0;
paul718e3742002-12-13 20:15:29 +0000992}
993
994/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +0000995static int
Feng Luc99f3482014-10-16 09:52:36 +0800996zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
997 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000998{
999 struct in_addr addr;
Christian Frankebb97e462013-05-25 14:01:35 +00001000 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00001001
1002 addr.s_addr = stream_get_ipv4 (client->ibuf);
Christian Frankebb97e462013-05-25 14:01:35 +00001003 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1004 zlog_debug("%s: looking up %s", __func__,
1005 inet_ntop (AF_INET, &addr, buf, BUFSIZ));
Feng Luc99f3482014-10-16 09:52:36 +08001006 return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001007}
1008
Everton Marques4e5275b2014-07-01 15:15:52 -03001009/* MRIB Nexthop lookup for IPv4. */
1010static int
Feng Luc99f3482014-10-16 09:52:36 +08001011zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length,
1012 vrf_id_t vrf_id)
Everton Marques4e5275b2014-07-01 15:15:52 -03001013{
1014 struct in_addr addr;
David Lamparterbd078122015-01-06 19:53:24 +01001015 struct rib *rib;
Everton Marques4e5275b2014-07-01 15:15:52 -03001016
1017 addr.s_addr = stream_get_ipv4 (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001018 rib = rib_match_ipv4_multicast (addr, NULL, vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +01001019 return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib);
Everton Marques4e5275b2014-07-01 15:15:52 -03001020}
1021
paul718e3742002-12-13 20:15:29 +00001022/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +00001023static int
Feng Luc99f3482014-10-16 09:52:36 +08001024zread_ipv4_import_lookup (struct zserv *client, u_short length,
1025 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001026{
1027 struct prefix_ipv4 p;
1028
1029 p.family = AF_INET;
1030 p.prefixlen = stream_getc (client->ibuf);
1031 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1032
Feng Luc99f3482014-10-16 09:52:36 +08001033 return zsend_ipv4_import_lookup (client, &p, vrf_id);
paul718e3742002-12-13 20:15:29 +00001034}
1035
1036#ifdef HAVE_IPV6
1037/* Zebra server IPv6 prefix add function. */
ajs719e9742005-02-28 20:52:15 +00001038static int
Feng Luc99f3482014-10-16 09:52:36 +08001039zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001040{
1041 int i;
1042 struct stream *s;
1043 struct zapi_ipv6 api;
1044 struct in6_addr nexthop;
1045 unsigned long ifindex;
1046 struct prefix_ipv6 p;
1047
1048 s = client->ibuf;
1049 ifindex = 0;
1050 memset (&nexthop, 0, sizeof (struct in6_addr));
1051
1052 /* Type, flags, message. */
1053 api.type = stream_getc (s);
1054 api.flags = stream_getc (s);
1055 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001056 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001057
1058 /* IPv4 prefix. */
1059 memset (&p, 0, sizeof (struct prefix_ipv6));
1060 p.family = AF_INET6;
1061 p.prefixlen = stream_getc (s);
1062 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1063
1064 /* Nexthop, ifindex, distance, metric. */
1065 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1066 {
1067 u_char nexthop_type;
1068
1069 api.nexthop_num = stream_getc (s);
1070 for (i = 0; i < api.nexthop_num; i++)
1071 {
1072 nexthop_type = stream_getc (s);
1073
1074 switch (nexthop_type)
1075 {
1076 case ZEBRA_NEXTHOP_IPV6:
1077 stream_get (&nexthop, s, 16);
1078 break;
1079 case ZEBRA_NEXTHOP_IFINDEX:
1080 ifindex = stream_getl (s);
1081 break;
1082 }
1083 }
1084 }
1085
1086 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1087 api.distance = stream_getc (s);
1088 else
1089 api.distance = 0;
1090
1091 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1092 api.metric = stream_getl (s);
1093 else
1094 api.metric = 0;
Timo Teräsb11f3b52015-11-02 16:50:07 +02001095
1096 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_MTU))
1097 api.mtu = stream_getl (s);
1098 else
1099 api.mtu = 0;
paul718e3742002-12-13 20:15:29 +00001100
1101 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Lu0d0686f2015-05-22 11:40:02 +02001102 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001103 vrf_id, zebrad.rtm_table_default, api.metric,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001104 api.mtu, api.distance, api.safi);
paul718e3742002-12-13 20:15:29 +00001105 else
Feng Lu0d0686f2015-05-22 11:40:02 +02001106 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001107 vrf_id, zebrad.rtm_table_default, api.metric,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001108 api.mtu, api.distance, api.safi);
ajs719e9742005-02-28 20:52:15 +00001109 return 0;
paul718e3742002-12-13 20:15:29 +00001110}
1111
1112/* Zebra server IPv6 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +00001113static int
Feng Luc99f3482014-10-16 09:52:36 +08001114zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001115{
1116 int i;
1117 struct stream *s;
1118 struct zapi_ipv6 api;
1119 struct in6_addr nexthop;
1120 unsigned long ifindex;
1121 struct prefix_ipv6 p;
1122
1123 s = client->ibuf;
1124 ifindex = 0;
1125 memset (&nexthop, 0, sizeof (struct in6_addr));
1126
1127 /* Type, flags, message. */
1128 api.type = stream_getc (s);
1129 api.flags = stream_getc (s);
1130 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001131 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001132
1133 /* IPv4 prefix. */
1134 memset (&p, 0, sizeof (struct prefix_ipv6));
1135 p.family = AF_INET6;
1136 p.prefixlen = stream_getc (s);
1137 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1138
1139 /* Nexthop, ifindex, distance, metric. */
1140 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1141 {
1142 u_char nexthop_type;
1143
1144 api.nexthop_num = stream_getc (s);
1145 for (i = 0; i < api.nexthop_num; i++)
1146 {
1147 nexthop_type = stream_getc (s);
1148
1149 switch (nexthop_type)
1150 {
1151 case ZEBRA_NEXTHOP_IPV6:
1152 stream_get (&nexthop, s, 16);
1153 break;
1154 case ZEBRA_NEXTHOP_IFINDEX:
1155 ifindex = stream_getl (s);
1156 break;
1157 }
1158 }
1159 }
1160
1161 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1162 api.distance = stream_getc (s);
1163 else
1164 api.distance = 0;
1165 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1166 api.metric = stream_getl (s);
1167 else
1168 api.metric = 0;
1169
1170 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Luc99f3482014-10-16 09:52:36 +08001171 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001172 api.safi);
paul718e3742002-12-13 20:15:29 +00001173 else
Feng Luc99f3482014-10-16 09:52:36 +08001174 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001175 api.safi);
ajs719e9742005-02-28 20:52:15 +00001176 return 0;
paul718e3742002-12-13 20:15:29 +00001177}
1178
ajs719e9742005-02-28 20:52:15 +00001179static int
Feng Luc99f3482014-10-16 09:52:36 +08001180zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
1181 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001182{
1183 struct in6_addr addr;
1184 char buf[BUFSIZ];
1185
1186 stream_get (&addr, client->ibuf, 16);
Christian Frankea5207082013-04-11 08:24:29 +00001187 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1188 zlog_debug("%s: looking up %s", __func__,
1189 inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
paul718e3742002-12-13 20:15:29 +00001190
Feng Luc99f3482014-10-16 09:52:36 +08001191 return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001192}
1193#endif /* HAVE_IPV6 */
1194
hasso18a6dce2004-10-03 18:18:34 +00001195/* Register zebra server router-id information. Send current router-id */
ajs719e9742005-02-28 20:52:15 +00001196static int
Feng Luc99f3482014-10-16 09:52:36 +08001197zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001198{
1199 struct prefix p;
1200
1201 /* Router-id information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +08001202 vrf_bitmap_set (client->ridinfo, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001203
Feng Luc99f3482014-10-16 09:52:36 +08001204 router_id_get (&p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001205
Feng Luc99f3482014-10-16 09:52:36 +08001206 return zsend_router_id_update (client, &p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001207}
1208
1209/* Unregister zebra server router-id information. */
ajs719e9742005-02-28 20:52:15 +00001210static int
Feng Luc99f3482014-10-16 09:52:36 +08001211zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001212{
Feng Luc99f3482014-10-16 09:52:36 +08001213 vrf_bitmap_unset (client->ridinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +00001214 return 0;
hasso18a6dce2004-10-03 18:18:34 +00001215}
1216
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001217/* Tie up route-type and client->sock */
1218static void
1219zread_hello (struct zserv *client)
1220{
1221 /* type of protocol (lib/zebra.h) */
1222 u_char proto;
1223 proto = stream_getc (client->ibuf);
1224
1225 /* accept only dynamic routing protocols */
1226 if ((proto < ZEBRA_ROUTE_MAX)
1227 && (proto > ZEBRA_ROUTE_STATIC))
1228 {
1229 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1230 client->sock, zebra_route_string(proto));
1231
1232 /* if route-type was binded by other client */
1233 if (route_type_oaths[proto])
1234 zlog_warn ("sender of %s routes changed %c->%c",
1235 zebra_route_string(proto), route_type_oaths[proto],
1236 client->sock);
1237
1238 route_type_oaths[proto] = client->sock;
1239 }
1240}
1241
Feng Luc99f3482014-10-16 09:52:36 +08001242/* Unregister all information in a VRF. */
1243static int
1244zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
1245{
1246 int i;
1247
1248 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1249 vrf_bitmap_unset (client->redist[i], vrf_id);
1250 vrf_bitmap_unset (client->redist_default, vrf_id);
1251 vrf_bitmap_unset (client->ifinfo, vrf_id);
1252 vrf_bitmap_unset (client->ridinfo, vrf_id);
1253
1254 return 0;
1255}
1256
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001257/* If client sent routes of specific type, zebra removes it
1258 * and returns number of deleted routes.
1259 */
1260static void
1261zebra_score_rib (int client_sock)
1262{
1263 int i;
1264
1265 for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
1266 if (client_sock == route_type_oaths[i])
1267 {
1268 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1269 client_sock, rib_score_proto (i), zebra_route_string (i));
1270 route_type_oaths[i] = 0;
1271 break;
1272 }
1273}
1274
paul718e3742002-12-13 20:15:29 +00001275/* Close zebra client. */
paulb9df2d22004-05-09 09:09:59 +00001276static void
paul718e3742002-12-13 20:15:29 +00001277zebra_client_close (struct zserv *client)
1278{
1279 /* Close file descriptor. */
1280 if (client->sock)
1281 {
1282 close (client->sock);
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001283 zebra_score_rib (client->sock);
paul718e3742002-12-13 20:15:29 +00001284 client->sock = -1;
1285 }
1286
1287 /* Free stream buffers. */
1288 if (client->ibuf)
1289 stream_free (client->ibuf);
1290 if (client->obuf)
1291 stream_free (client->obuf);
ajs719e9742005-02-28 20:52:15 +00001292 if (client->wb)
1293 buffer_free(client->wb);
paul718e3742002-12-13 20:15:29 +00001294
1295 /* Release threads. */
1296 if (client->t_read)
1297 thread_cancel (client->t_read);
1298 if (client->t_write)
1299 thread_cancel (client->t_write);
ajs719e9742005-02-28 20:52:15 +00001300 if (client->t_suicide)
1301 thread_cancel (client->t_suicide);
paul718e3742002-12-13 20:15:29 +00001302
1303 /* Free client structure. */
paulb21b19c2003-06-15 01:28:29 +00001304 listnode_delete (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001305 XFREE (0, client);
1306}
1307
1308/* Make new client. */
paulb9df2d22004-05-09 09:09:59 +00001309static void
paul718e3742002-12-13 20:15:29 +00001310zebra_client_create (int sock)
1311{
1312 struct zserv *client;
Feng Luc99f3482014-10-16 09:52:36 +08001313 int i;
paul718e3742002-12-13 20:15:29 +00001314
1315 client = XCALLOC (0, sizeof (struct zserv));
1316
1317 /* Make client input/output buffer. */
1318 client->sock = sock;
1319 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1320 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
ajs719e9742005-02-28 20:52:15 +00001321 client->wb = buffer_new(0);
paul718e3742002-12-13 20:15:29 +00001322
1323 /* Set table number. */
paulb21b19c2003-06-15 01:28:29 +00001324 client->rtm_table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00001325
Feng Luc99f3482014-10-16 09:52:36 +08001326 /* Initialize flags */
1327 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1328 client->redist[i] = vrf_bitmap_init ();
1329 client->redist_default = vrf_bitmap_init ();
1330 client->ifinfo = vrf_bitmap_init ();
1331 client->ridinfo = vrf_bitmap_init ();
1332
paul718e3742002-12-13 20:15:29 +00001333 /* Add this client to linked list. */
paulb21b19c2003-06-15 01:28:29 +00001334 listnode_add (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001335
1336 /* Make new read thread. */
1337 zebra_event (ZEBRA_READ, sock, client);
1338}
1339
1340/* Handler of zebra service request. */
paulb9df2d22004-05-09 09:09:59 +00001341static int
paul718e3742002-12-13 20:15:29 +00001342zebra_client_read (struct thread *thread)
1343{
1344 int sock;
1345 struct zserv *client;
ajs57a14772005-04-10 15:01:56 +00001346 size_t already;
paulc1b98002006-01-16 01:54:02 +00001347 uint16_t length, command;
1348 uint8_t marker, version;
Feng Luc99f3482014-10-16 09:52:36 +08001349 vrf_id_t vrf_id;
paul718e3742002-12-13 20:15:29 +00001350
1351 /* Get thread data. Reset reading thread because I'm running. */
1352 sock = THREAD_FD (thread);
1353 client = THREAD_ARG (thread);
1354 client->t_read = NULL;
1355
ajs719e9742005-02-28 20:52:15 +00001356 if (client->t_suicide)
paul718e3742002-12-13 20:15:29 +00001357 {
ajs719e9742005-02-28 20:52:15 +00001358 zebra_client_close(client);
paul718e3742002-12-13 20:15:29 +00001359 return -1;
1360 }
ajs719e9742005-02-28 20:52:15 +00001361
1362 /* Read length and command (if we don't have it already). */
ajs57a14772005-04-10 15:01:56 +00001363 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
ajs719e9742005-02-28 20:52:15 +00001364 {
ajs57a14772005-04-10 15:01:56 +00001365 ssize_t nbyte;
ajs719e9742005-02-28 20:52:15 +00001366 if (((nbyte = stream_read_try (client->ibuf, sock,
ajs57a14772005-04-10 15:01:56 +00001367 ZEBRA_HEADER_SIZE-already)) == 0) ||
ajs719e9742005-02-28 20:52:15 +00001368 (nbyte == -1))
1369 {
1370 if (IS_ZEBRA_DEBUG_EVENT)
1371 zlog_debug ("connection closed socket [%d]", sock);
1372 zebra_client_close (client);
1373 return -1;
1374 }
ajs57a14772005-04-10 15:01:56 +00001375 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
ajs719e9742005-02-28 20:52:15 +00001376 {
1377 /* Try again later. */
1378 zebra_event (ZEBRA_READ, sock, client);
1379 return 0;
1380 }
ajs57a14772005-04-10 15:01:56 +00001381 already = ZEBRA_HEADER_SIZE;
ajs719e9742005-02-28 20:52:15 +00001382 }
1383
1384 /* Reset to read from the beginning of the incoming packet. */
1385 stream_set_getp(client->ibuf, 0);
1386
paulc1b98002006-01-16 01:54:02 +00001387 /* Fetch header values */
paul718e3742002-12-13 20:15:29 +00001388 length = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001389 marker = stream_getc (client->ibuf);
1390 version = stream_getc (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001391 vrf_id = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001392 command = stream_getw (client->ibuf);
paul718e3742002-12-13 20:15:29 +00001393
paulc1b98002006-01-16 01:54:02 +00001394 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1395 {
1396 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1397 __func__, sock, marker, version);
1398 zebra_client_close (client);
1399 return -1;
1400 }
ajs719e9742005-02-28 20:52:15 +00001401 if (length < ZEBRA_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00001402 {
ajs57a14772005-04-10 15:01:56 +00001403 zlog_warn("%s: socket %d message length %u is less than header size %d",
1404 __func__, sock, length, ZEBRA_HEADER_SIZE);
1405 zebra_client_close (client);
1406 return -1;
1407 }
1408 if (length > STREAM_SIZE(client->ibuf))
1409 {
1410 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1411 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
paul718e3742002-12-13 20:15:29 +00001412 zebra_client_close (client);
1413 return -1;
1414 }
1415
paul718e3742002-12-13 20:15:29 +00001416 /* Read rest of data. */
ajs57a14772005-04-10 15:01:56 +00001417 if (already < length)
paul718e3742002-12-13 20:15:29 +00001418 {
ajs57a14772005-04-10 15:01:56 +00001419 ssize_t nbyte;
1420 if (((nbyte = stream_read_try (client->ibuf, sock,
1421 length-already)) == 0) ||
1422 (nbyte == -1))
paul718e3742002-12-13 20:15:29 +00001423 {
1424 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001425 zlog_debug ("connection closed [%d] when reading zebra data", sock);
paul718e3742002-12-13 20:15:29 +00001426 zebra_client_close (client);
1427 return -1;
1428 }
ajs57a14772005-04-10 15:01:56 +00001429 if (nbyte != (ssize_t)(length-already))
ajs719e9742005-02-28 20:52:15 +00001430 {
1431 /* Try again later. */
1432 zebra_event (ZEBRA_READ, sock, client);
1433 return 0;
1434 }
paul718e3742002-12-13 20:15:29 +00001435 }
1436
ajs719e9742005-02-28 20:52:15 +00001437 length -= ZEBRA_HEADER_SIZE;
1438
paul718e3742002-12-13 20:15:29 +00001439 /* Debug packet information. */
1440 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001441 zlog_debug ("zebra message comes from socket [%d]", sock);
paul718e3742002-12-13 20:15:29 +00001442
1443 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
Feng Luc99f3482014-10-16 09:52:36 +08001444 zlog_debug ("zebra message received [%s] %d in VRF %u",
1445 zserv_command_string (command), length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001446
1447 switch (command)
1448 {
hasso18a6dce2004-10-03 18:18:34 +00001449 case ZEBRA_ROUTER_ID_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001450 zread_router_id_add (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001451 break;
1452 case ZEBRA_ROUTER_ID_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001453 zread_router_id_delete (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001454 break;
paul718e3742002-12-13 20:15:29 +00001455 case ZEBRA_INTERFACE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001456 zread_interface_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001457 break;
1458 case ZEBRA_INTERFACE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001459 zread_interface_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001460 break;
1461 case ZEBRA_IPV4_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001462 zread_ipv4_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001463 break;
1464 case ZEBRA_IPV4_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001465 zread_ipv4_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001466 break;
1467#ifdef HAVE_IPV6
1468 case ZEBRA_IPV6_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001469 zread_ipv6_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001470 break;
1471 case ZEBRA_IPV6_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001472 zread_ipv6_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001473 break;
1474#endif /* HAVE_IPV6 */
1475 case ZEBRA_REDISTRIBUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001476 zebra_redistribute_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001477 break;
1478 case ZEBRA_REDISTRIBUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001479 zebra_redistribute_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001480 break;
1481 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001482 zebra_redistribute_default_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001483 break;
1484 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001485 zebra_redistribute_default_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001486 break;
1487 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001488 zread_ipv4_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001489 break;
Everton Marques4e5275b2014-07-01 15:15:52 -03001490 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
Feng Luc99f3482014-10-16 09:52:36 +08001491 zread_ipv4_nexthop_lookup_mrib (client, length, vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -03001492 break;
paul718e3742002-12-13 20:15:29 +00001493#ifdef HAVE_IPV6
1494 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001495 zread_ipv6_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001496 break;
1497#endif /* HAVE_IPV6 */
1498 case ZEBRA_IPV4_IMPORT_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001499 zread_ipv4_import_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001500 break;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001501 case ZEBRA_HELLO:
1502 zread_hello (client);
1503 break;
Feng Luc99f3482014-10-16 09:52:36 +08001504 case ZEBRA_VRF_UNREGISTER:
1505 zread_vrf_unregister (client, length, vrf_id);
1506 break;
paul718e3742002-12-13 20:15:29 +00001507 default:
1508 zlog_info ("Zebra received unknown command %d", command);
1509 break;
1510 }
1511
ajs719e9742005-02-28 20:52:15 +00001512 if (client->t_suicide)
1513 {
1514 /* No need to wait for thread callback, just kill immediately. */
1515 zebra_client_close(client);
1516 return -1;
1517 }
1518
paul718e3742002-12-13 20:15:29 +00001519 stream_reset (client->ibuf);
1520 zebra_event (ZEBRA_READ, sock, client);
paul718e3742002-12-13 20:15:29 +00001521 return 0;
1522}
1523
paul718e3742002-12-13 20:15:29 +00001524
1525/* Accept code of zebra server socket. */
paulb9df2d22004-05-09 09:09:59 +00001526static int
paul718e3742002-12-13 20:15:29 +00001527zebra_accept (struct thread *thread)
1528{
1529 int accept_sock;
1530 int client_sock;
1531 struct sockaddr_in client;
1532 socklen_t len;
1533
1534 accept_sock = THREAD_FD (thread);
1535
ajs719e9742005-02-28 20:52:15 +00001536 /* Reregister myself. */
1537 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1538
paul718e3742002-12-13 20:15:29 +00001539 len = sizeof (struct sockaddr_in);
1540 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1541
1542 if (client_sock < 0)
1543 {
ajs6099b3b2004-11-20 02:06:59 +00001544 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001545 return -1;
1546 }
1547
paulccf35572003-03-01 11:42:20 +00001548 /* Make client socket non-blocking. */
ajs719e9742005-02-28 20:52:15 +00001549 set_nonblocking(client_sock);
paul865b8522005-01-05 08:30:35 +00001550
paul718e3742002-12-13 20:15:29 +00001551 /* Create new zebra client. */
1552 zebra_client_create (client_sock);
1553
paul718e3742002-12-13 20:15:29 +00001554 return 0;
1555}
1556
paulb9df2d22004-05-09 09:09:59 +00001557#ifdef HAVE_TCP_ZEBRA
paul718e3742002-12-13 20:15:29 +00001558/* Make zebra's server socket. */
paulb9df2d22004-05-09 09:09:59 +00001559static void
paul718e3742002-12-13 20:15:29 +00001560zebra_serv ()
1561{
1562 int ret;
1563 int accept_sock;
1564 struct sockaddr_in addr;
1565
1566 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1567
1568 if (accept_sock < 0)
1569 {
paul3d1dc852005-04-05 00:45:23 +00001570 zlog_warn ("Can't create zserv stream socket: %s",
1571 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001572 zlog_warn ("zebra can't provice full functionality due to above error");
1573 return;
1574 }
1575
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001576 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
paul718e3742002-12-13 20:15:29 +00001577 memset (&addr, 0, sizeof (struct sockaddr_in));
1578 addr.sin_family = AF_INET;
1579 addr.sin_port = htons (ZEBRA_PORT);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001580#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +00001581 addr.sin_len = sizeof (struct sockaddr_in);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001582#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +00001583 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1584
1585 sockopt_reuseaddr (accept_sock);
1586 sockopt_reuseport (accept_sock);
1587
pauledd7c242003-06-04 13:59:38 +00001588 if ( zserv_privs.change(ZPRIVS_RAISE) )
1589 zlog (NULL, LOG_ERR, "Can't raise privileges");
1590
paul718e3742002-12-13 20:15:29 +00001591 ret = bind (accept_sock, (struct sockaddr *)&addr,
1592 sizeof (struct sockaddr_in));
1593 if (ret < 0)
1594 {
paul3d1dc852005-04-05 00:45:23 +00001595 zlog_warn ("Can't bind to stream socket: %s",
1596 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001597 zlog_warn ("zebra can't provice full functionality due to above error");
1598 close (accept_sock); /* Avoid sd leak. */
1599 return;
1600 }
pauledd7c242003-06-04 13:59:38 +00001601
1602 if ( zserv_privs.change(ZPRIVS_LOWER) )
1603 zlog (NULL, LOG_ERR, "Can't lower privileges");
paul718e3742002-12-13 20:15:29 +00001604
1605 ret = listen (accept_sock, 1);
1606 if (ret < 0)
1607 {
paul3d1dc852005-04-05 00:45:23 +00001608 zlog_warn ("Can't listen to stream socket: %s",
1609 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001610 zlog_warn ("zebra can't provice full functionality due to above error");
1611 close (accept_sock); /* Avoid sd leak. */
1612 return;
1613 }
1614
1615 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1616}
David Lamparter4b6c3322015-04-21 09:47:57 +02001617#else /* HAVE_TCP_ZEBRA */
paul718e3742002-12-13 20:15:29 +00001618
1619/* For sockaddr_un. */
1620#include <sys/un.h>
1621
1622/* zebra server UNIX domain socket. */
paulb9df2d22004-05-09 09:09:59 +00001623static void
hassofce954f2004-10-07 20:29:24 +00001624zebra_serv_un (const char *path)
paul718e3742002-12-13 20:15:29 +00001625{
1626 int ret;
1627 int sock, len;
1628 struct sockaddr_un serv;
1629 mode_t old_mask;
1630
1631 /* First of all, unlink existing socket */
1632 unlink (path);
1633
1634 /* Set umask */
1635 old_mask = umask (0077);
1636
1637 /* Make UNIX domain socket. */
1638 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1639 if (sock < 0)
1640 {
paul3d1dc852005-04-05 00:45:23 +00001641 zlog_warn ("Can't create zserv unix socket: %s",
1642 safe_strerror (errno));
1643 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001644 return;
1645 }
1646
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001647 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1648
paul718e3742002-12-13 20:15:29 +00001649 /* Make server socket. */
1650 memset (&serv, 0, sizeof (struct sockaddr_un));
1651 serv.sun_family = AF_UNIX;
1652 strncpy (serv.sun_path, path, strlen (path));
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001653#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
paul718e3742002-12-13 20:15:29 +00001654 len = serv.sun_len = SUN_LEN(&serv);
1655#else
1656 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001657#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
paul718e3742002-12-13 20:15:29 +00001658
1659 ret = bind (sock, (struct sockaddr *) &serv, len);
1660 if (ret < 0)
1661 {
paul3d1dc852005-04-05 00:45:23 +00001662 zlog_warn ("Can't bind to unix socket %s: %s",
1663 path, safe_strerror (errno));
1664 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001665 close (sock);
1666 return;
1667 }
1668
1669 ret = listen (sock, 5);
1670 if (ret < 0)
1671 {
paul3d1dc852005-04-05 00:45:23 +00001672 zlog_warn ("Can't listen to unix socket %s: %s",
1673 path, safe_strerror (errno));
1674 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001675 close (sock);
1676 return;
1677 }
1678
1679 umask (old_mask);
1680
1681 zebra_event (ZEBRA_SERV, sock, NULL);
1682}
David Lamparter4b6c3322015-04-21 09:47:57 +02001683#endif /* HAVE_TCP_ZEBRA */
David Lamparter6b0655a2014-06-04 06:53:35 +02001684
paul718e3742002-12-13 20:15:29 +00001685
paulb9df2d22004-05-09 09:09:59 +00001686static void
paul718e3742002-12-13 20:15:29 +00001687zebra_event (enum event event, int sock, struct zserv *client)
1688{
1689 switch (event)
1690 {
1691 case ZEBRA_SERV:
paulb21b19c2003-06-15 01:28:29 +00001692 thread_add_read (zebrad.master, zebra_accept, client, sock);
paul718e3742002-12-13 20:15:29 +00001693 break;
1694 case ZEBRA_READ:
1695 client->t_read =
paulb21b19c2003-06-15 01:28:29 +00001696 thread_add_read (zebrad.master, zebra_client_read, client, sock);
paul718e3742002-12-13 20:15:29 +00001697 break;
1698 case ZEBRA_WRITE:
1699 /**/
1700 break;
1701 }
1702}
David Lamparter6b0655a2014-06-04 06:53:35 +02001703
paul718e3742002-12-13 20:15:29 +00001704/* Display default rtm_table for all clients. */
1705DEFUN (show_table,
1706 show_table_cmd,
1707 "show table",
1708 SHOW_STR
1709 "default routing table to use for all clients\n")
1710{
paulb21b19c2003-06-15 01:28:29 +00001711 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001712 VTY_NEWLINE);
1713 return CMD_SUCCESS;
1714}
1715
1716DEFUN (config_table,
1717 config_table_cmd,
1718 "table TABLENO",
1719 "Configure target kernel routing table\n"
1720 "TABLE integer\n")
1721{
paulb21b19c2003-06-15 01:28:29 +00001722 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
paul718e3742002-12-13 20:15:29 +00001723 return CMD_SUCCESS;
1724}
1725
hasso647e4f12003-05-25 11:43:52 +00001726DEFUN (ip_forwarding,
1727 ip_forwarding_cmd,
1728 "ip forwarding",
1729 IP_STR
1730 "Turn on IP forwarding")
1731{
1732 int ret;
1733
1734 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001735 if (ret == 0)
1736 ret = ipforward_on ();
hasso647e4f12003-05-25 11:43:52 +00001737
hasso647e4f12003-05-25 11:43:52 +00001738 if (ret == 0)
1739 {
1740 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1741 return CMD_WARNING;
1742 }
1743
1744 return CMD_SUCCESS;
1745}
1746
paul718e3742002-12-13 20:15:29 +00001747DEFUN (no_ip_forwarding,
1748 no_ip_forwarding_cmd,
1749 "no ip forwarding",
1750 NO_STR
1751 IP_STR
1752 "Turn off IP forwarding")
1753{
1754 int ret;
1755
1756 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001757 if (ret != 0)
1758 ret = ipforward_off ();
paul718e3742002-12-13 20:15:29 +00001759
paul718e3742002-12-13 20:15:29 +00001760 if (ret != 0)
1761 {
1762 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1763 return CMD_WARNING;
1764 }
1765
1766 return CMD_SUCCESS;
1767}
1768
1769/* This command is for debugging purpose. */
1770DEFUN (show_zebra_client,
1771 show_zebra_client_cmd,
1772 "show zebra client",
1773 SHOW_STR
1774 "Zebra information"
1775 "Client information")
1776{
hasso52dc7ee2004-09-23 19:18:23 +00001777 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001778 struct zserv *client;
1779
paul1eb8ef22005-04-07 07:30:20 +00001780 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1781 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1782
paul718e3742002-12-13 20:15:29 +00001783 return CMD_SUCCESS;
1784}
1785
1786/* Table configuration write function. */
paulb9df2d22004-05-09 09:09:59 +00001787static int
paul718e3742002-12-13 20:15:29 +00001788config_write_table (struct vty *vty)
1789{
paulb21b19c2003-06-15 01:28:29 +00001790 if (zebrad.rtm_table_default)
1791 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001792 VTY_NEWLINE);
1793 return 0;
1794}
1795
1796/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001797static struct cmd_node table_node =
paul718e3742002-12-13 20:15:29 +00001798{
1799 TABLE_NODE,
1800 "", /* This node has no interface. */
1801 1
1802};
David Lamparter6b0655a2014-06-04 06:53:35 +02001803
paul718e3742002-12-13 20:15:29 +00001804/* Only display ip forwarding is enabled or not. */
1805DEFUN (show_ip_forwarding,
1806 show_ip_forwarding_cmd,
1807 "show ip forwarding",
1808 SHOW_STR
1809 IP_STR
1810 "IP forwarding status\n")
1811{
1812 int ret;
1813
1814 ret = ipforward ();
1815
1816 if (ret == 0)
1817 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1818 else
1819 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1820 return CMD_SUCCESS;
1821}
1822
1823#ifdef HAVE_IPV6
1824/* Only display ipv6 forwarding is enabled or not. */
1825DEFUN (show_ipv6_forwarding,
1826 show_ipv6_forwarding_cmd,
1827 "show ipv6 forwarding",
1828 SHOW_STR
1829 "IPv6 information\n"
1830 "Forwarding status\n")
1831{
1832 int ret;
1833
1834 ret = ipforward_ipv6 ();
1835
1836 switch (ret)
1837 {
1838 case -1:
1839 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1840 break;
1841 case 0:
1842 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1843 break;
1844 case 1:
1845 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1846 break;
1847 default:
1848 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1849 break;
1850 }
1851 return CMD_SUCCESS;
1852}
1853
hasso55906722004-02-11 22:42:16 +00001854DEFUN (ipv6_forwarding,
1855 ipv6_forwarding_cmd,
1856 "ipv6 forwarding",
1857 IPV6_STR
1858 "Turn on IPv6 forwarding")
1859{
1860 int ret;
1861
hasso41d3fc92004-04-06 11:59:00 +00001862 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001863 if (ret == 0)
1864 ret = ipforward_ipv6_on ();
hasso41d3fc92004-04-06 11:59:00 +00001865
hasso41d3fc92004-04-06 11:59:00 +00001866 if (ret == 0)
1867 {
hasso55906722004-02-11 22:42:16 +00001868 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1869 return CMD_WARNING;
1870 }
1871
1872 return CMD_SUCCESS;
1873}
1874
paul718e3742002-12-13 20:15:29 +00001875DEFUN (no_ipv6_forwarding,
1876 no_ipv6_forwarding_cmd,
1877 "no ipv6 forwarding",
1878 NO_STR
hasso55906722004-02-11 22:42:16 +00001879 IPV6_STR
1880 "Turn off IPv6 forwarding")
paul718e3742002-12-13 20:15:29 +00001881{
1882 int ret;
1883
hasso41d3fc92004-04-06 11:59:00 +00001884 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001885 if (ret != 0)
1886 ret = ipforward_ipv6_off ();
hasso41d3fc92004-04-06 11:59:00 +00001887
paul718e3742002-12-13 20:15:29 +00001888 if (ret != 0)
1889 {
1890 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1891 return CMD_WARNING;
1892 }
1893
1894 return CMD_SUCCESS;
1895}
1896
1897#endif /* HAVE_IPV6 */
1898
1899/* IPForwarding configuration write function. */
ajs719e9742005-02-28 20:52:15 +00001900static int
paul718e3742002-12-13 20:15:29 +00001901config_write_forwarding (struct vty *vty)
1902{
hasso18a6dce2004-10-03 18:18:34 +00001903 /* FIXME: Find better place for that. */
1904 router_id_write (vty);
1905
paul3e0b3a52004-08-23 18:58:32 +00001906 if (ipforward ())
1907 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001908#ifdef HAVE_IPV6
paul3e0b3a52004-08-23 18:58:32 +00001909 if (ipforward_ipv6 ())
1910 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001911#endif /* HAVE_IPV6 */
1912 vty_out (vty, "!%s", VTY_NEWLINE);
1913 return 0;
1914}
1915
1916/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001917static struct cmd_node forwarding_node =
paul718e3742002-12-13 20:15:29 +00001918{
1919 FORWARDING_NODE,
1920 "", /* This node has no interface. */
1921 1
1922};
1923
David Lamparter6b0655a2014-06-04 06:53:35 +02001924
paul718e3742002-12-13 20:15:29 +00001925/* Initialisation of zebra and installation of commands. */
1926void
paula1ac18c2005-06-28 17:17:12 +00001927zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001928{
1929 /* Client list init. */
paulb21b19c2003-06-15 01:28:29 +00001930 zebrad.client_list = list_new ();
paul718e3742002-12-13 20:15:29 +00001931
paul718e3742002-12-13 20:15:29 +00001932 /* Install configuration write function. */
1933 install_node (&table_node, config_write_table);
1934 install_node (&forwarding_node, config_write_forwarding);
1935
1936 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1937 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00001938 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001939 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1940 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1941
1942#ifdef HAVE_NETLINK
1943 install_element (VIEW_NODE, &show_table_cmd);
1944 install_element (ENABLE_NODE, &show_table_cmd);
1945 install_element (CONFIG_NODE, &config_table_cmd);
1946#endif /* HAVE_NETLINK */
1947
1948#ifdef HAVE_IPV6
1949 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1950 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
hasso55906722004-02-11 22:42:16 +00001951 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001952 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1953#endif /* HAVE_IPV6 */
Paul Jakma7514fb72007-05-02 16:05:35 +00001954
1955 /* Route-map */
1956 zebra_route_map_init ();
paul718e3742002-12-13 20:15:29 +00001957}
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001958
1959/* Make zebra server socket, wiping any existing one (see bug #403). */
1960void
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04001961zebra_zserv_socket_init (char *path)
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001962{
1963#ifdef HAVE_TCP_ZEBRA
1964 zebra_serv ();
1965#else
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04001966 zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001967#endif /* HAVE_TCP_ZEBRA */
1968}