blob: 600b0e5c7cb39489ec884ed6d4e3fc1730a1ec00 [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);
157#ifdef HAVE_STRUCT_SOCKADDR_DL
David Lamparterca3ccd82012-09-26 14:52:39 +0200158 stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
Josh Bailey51d4ef82012-03-21 17:13:39 -0700159#else
160 stream_putl (s, ifp->hw_addr_len);
161 if (ifp->hw_addr_len)
162 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
163#endif /* HAVE_STRUCT_SOCKADDR_DL */
164
165 /* Write packet size. */
166 stream_putw_at (s, 0, stream_get_endp (s));
167}
168
paul718e3742002-12-13 20:15:29 +0000169/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
paulb9df2d22004-05-09 09:09:59 +0000170/*
171 * This function is called in the following situations:
172 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
173 * from the client.
174 * - at startup, when zebra figures out the available interfaces
175 * - when an interface is added (where support for
176 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
177 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
178 * received)
179 */
paul718e3742002-12-13 20:15:29 +0000180int
181zsend_interface_add (struct zserv *client, struct interface *ifp)
182{
183 struct stream *s;
184
185 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800186 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000187 return 0;
paul718e3742002-12-13 20:15:29 +0000188
189 s = client->obuf;
190 stream_reset (s);
191
Feng Luc99f3482014-10-16 09:52:36 +0800192 zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700193 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000194
ajs719e9742005-02-28 20:52:15 +0000195 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000196}
197
198/* Interface deletion from zebra daemon. */
199int
200zsend_interface_delete (struct zserv *client, struct interface *ifp)
201{
202 struct stream *s;
203
204 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800205 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000206 return 0;
paul718e3742002-12-13 20:15:29 +0000207
208 s = client->obuf;
209 stream_reset (s);
paul718e3742002-12-13 20:15:29 +0000210
Feng Luc99f3482014-10-16 09:52:36 +0800211 zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700212 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000213
ajs719e9742005-02-28 20:52:15 +0000214 return zebra_server_send_message (client);
paul718e3742002-12-13 20:15:29 +0000215}
216
paulb9df2d22004-05-09 09:09:59 +0000217/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
218 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
219 *
220 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
221 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
222 * from the client, after the ZEBRA_INTERFACE_ADD has been
223 * sent from zebra to the client
224 * - redistribute new address info to all clients in the following situations
225 * - at startup, when zebra figures out the available interfaces
226 * - when an interface is added (where support for
227 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
228 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
229 * received)
230 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
231 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
232 * - when an RTM_NEWADDR message is received from the kernel,
233 *
234 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
235 *
236 * zsend_interface_address(DELETE)
237 * ^
238 * |
239 * zebra_interface_address_delete_update
240 * ^ ^ ^
paul6eb88272005-07-29 14:36:00 +0000241 * | | if_delete_update
242 * | |
paulb9df2d22004-05-09 09:09:59 +0000243 * ip_address_uninstall connected_delete_ipv4
244 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
245 * ^ ^
246 * | |
247 * | RTM_NEWADDR on routing/netlink socket
248 * |
249 * vty commands:
250 * "no ip address A.B.C.D/M [label LINE]"
251 * "no ip address A.B.C.D/M secondary"
252 * ["no ipv6 address X:X::X:X/M"]
253 *
254 */
paul718e3742002-12-13 20:15:29 +0000255int
paulb9df2d22004-05-09 09:09:59 +0000256zsend_interface_address (int cmd, struct zserv *client,
257 struct interface *ifp, struct connected *ifc)
paul718e3742002-12-13 20:15:29 +0000258{
259 int blen;
260 struct stream *s;
261 struct prefix *p;
262
263 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800264 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000265 return 0;
paul718e3742002-12-13 20:15:29 +0000266
267 s = client->obuf;
268 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000269
Feng Luc99f3482014-10-16 09:52:36 +0800270 zserv_create_header (s, cmd, ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000271 stream_putl (s, ifp->ifindex);
272
273 /* Interface address flag. */
274 stream_putc (s, ifc->flags);
275
276 /* Prefix information. */
277 p = ifc->address;
278 stream_putc (s, p->family);
279 blen = prefix_blen (p);
280 stream_put (s, &p->u.prefix, blen);
paulb9df2d22004-05-09 09:09:59 +0000281
282 /*
283 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
284 * but zebra_interface_address_delete_read() in the gnu version
285 * expects to find it
286 */
paul718e3742002-12-13 20:15:29 +0000287 stream_putc (s, p->prefixlen);
288
289 /* Destination. */
290 p = ifc->destination;
291 if (p)
292 stream_put (s, &p->u.prefix, blen);
293 else
294 stream_put (s, NULL, blen);
295
296 /* Write packet size. */
297 stream_putw_at (s, 0, stream_get_endp (s));
298
ajs719e9742005-02-28 20:52:15 +0000299 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000300}
301
paulb9df2d22004-05-09 09:09:59 +0000302/*
303 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
304 * ZEBRA_INTERFACE_DOWN.
305 *
306 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
307 * the clients in one of 2 situations:
308 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
309 * - a vty command modifying the bandwidth of an interface is received.
310 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
311 */
paul718e3742002-12-13 20:15:29 +0000312int
paulb9df2d22004-05-09 09:09:59 +0000313zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000314{
315 struct stream *s;
316
317 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800318 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000319 return 0;
paul718e3742002-12-13 20:15:29 +0000320
321 s = client->obuf;
322 stream_reset (s);
323
Feng Luc99f3482014-10-16 09:52:36 +0800324 zserv_create_header (s, cmd, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700325 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000326
ajs719e9742005-02-28 20:52:15 +0000327 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000328}
329
paulb9df2d22004-05-09 09:09:59 +0000330/*
331 * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
332 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
333 * situations:
334 * - when the client starts up, and requests default information
335 * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
336 * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
337 * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
338 * - when the zebra server redistributes routes after it updates its rib
339 *
340 * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
341 * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
342 * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
343 * - deleted from zebra's rib, and this info
344 * has to be redistributed to the clients
345 *
346 * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
347 * zebra server when the client wants to tell the zebra server to add a
348 * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
349 * same message being sent back and forth, this function and
350 * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
351 * duplication.
352 */
paul718e3742002-12-13 20:15:29 +0000353int
paulb9df2d22004-05-09 09:09:59 +0000354zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
355 struct rib *rib)
paul718e3742002-12-13 20:15:29 +0000356{
357 int psize;
358 struct stream *s;
359 struct nexthop *nexthop;
paul1dcb5172005-05-31 08:38:50 +0000360 unsigned long nhnummark = 0, messmark = 0;
paulb9df2d22004-05-09 09:09:59 +0000361 int nhnum = 0;
paul1dcb5172005-05-31 08:38:50 +0000362 u_char zapi_flags = 0;
Feng Luc99f3482014-10-16 09:52:36 +0800363
364 /* Check this client need this route. */
365 if (!vrf_bitmap_check (client->redist[rib->type], rib->vrf_id) &&
366 !(is_default (p) &&
367 vrf_bitmap_check (client->redist_default, rib->vrf_id)))
368 return 0;
369
paul718e3742002-12-13 20:15:29 +0000370 s = client->obuf;
371 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000372
Feng Luc99f3482014-10-16 09:52:36 +0800373 zserv_create_header (s, cmd, rib->vrf_id);
paulc1b98002006-01-16 01:54:02 +0000374
375 /* Put type and nexthop. */
paul718e3742002-12-13 20:15:29 +0000376 stream_putc (s, rib->type);
377 stream_putc (s, rib->flags);
paul1dcb5172005-05-31 08:38:50 +0000378
379 /* marker for message flags field */
380 messmark = stream_get_endp (s);
381 stream_putc (s, 0);
paul718e3742002-12-13 20:15:29 +0000382
383 /* Prefix. */
384 psize = PSIZE (p->prefixlen);
385 stream_putc (s, p->prefixlen);
paulb9df2d22004-05-09 09:09:59 +0000386 stream_write (s, (u_char *) & p->u.prefix, psize);
paul718e3742002-12-13 20:15:29 +0000387
paulb9df2d22004-05-09 09:09:59 +0000388 /*
389 * XXX The message format sent by zebra below does not match the format
390 * of the corresponding message expected by the zebra server
391 * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
392 * (is there a bug on the client side if more than one segment is sent?)
393 * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
394 * is hard-coded.
395 */
paul718e3742002-12-13 20:15:29 +0000396 /* Nexthop */
paul1dcb5172005-05-31 08:38:50 +0000397
paul718e3742002-12-13 20:15:29 +0000398 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
399 {
Timo Teräs325823a2016-01-15 17:36:31 +0200400 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paulb9df2d22004-05-09 09:09:59 +0000401 {
paul1dcb5172005-05-31 08:38:50 +0000402 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
403 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
404
405 if (nhnummark == 0)
406 {
407 nhnummark = stream_get_endp (s);
408 stream_putc (s, 1); /* placeholder */
409 }
410
paulb9df2d22004-05-09 09:09:59 +0000411 nhnum++;
paul718e3742002-12-13 20:15:29 +0000412
paulb9df2d22004-05-09 09:09:59 +0000413 switch(nexthop->type)
414 {
415 case NEXTHOP_TYPE_IPV4:
416 case NEXTHOP_TYPE_IPV4_IFINDEX:
417 stream_put_in_addr (s, &nexthop->gate.ipv4);
418 break;
419#ifdef HAVE_IPV6
420 case NEXTHOP_TYPE_IPV6:
421 case NEXTHOP_TYPE_IPV6_IFINDEX:
422 case NEXTHOP_TYPE_IPV6_IFNAME:
423 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
424 break;
425#endif
426 default:
427 if (cmd == ZEBRA_IPV4_ROUTE_ADD
428 || cmd == ZEBRA_IPV4_ROUTE_DELETE)
429 {
430 struct in_addr empty;
paul44983cf2004-09-22 13:15:58 +0000431 memset (&empty, 0, sizeof (struct in_addr));
paulb9df2d22004-05-09 09:09:59 +0000432 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
433 }
434 else
435 {
436 struct in6_addr empty;
437 memset (&empty, 0, sizeof (struct in6_addr));
438 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
439 }
440 }
paul718e3742002-12-13 20:15:29 +0000441
paulb9df2d22004-05-09 09:09:59 +0000442 /* Interface index. */
443 stream_putc (s, 1);
444 stream_putl (s, nexthop->ifindex);
paul718e3742002-12-13 20:15:29 +0000445
paulb9df2d22004-05-09 09:09:59 +0000446 break;
447 }
paul718e3742002-12-13 20:15:29 +0000448 }
449
450 /* Metric */
Stephen Hemmingercf8a8312010-08-18 15:56:46 -0700451 if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
paul1dcb5172005-05-31 08:38:50 +0000452 {
vincentfbf5d032005-09-29 11:25:50 +0000453 SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
454 stream_putc (s, rib->distance);
paul1dcb5172005-05-31 08:38:50 +0000455 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
456 stream_putl (s, rib->metric);
Timo Teräsb11f3b52015-11-02 16:50:07 +0200457 SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
458 stream_putl (s, rib->mtu);
paul1dcb5172005-05-31 08:38:50 +0000459 }
460
461 /* write real message flags value */
462 stream_putc_at (s, messmark, zapi_flags);
463
paulb9df2d22004-05-09 09:09:59 +0000464 /* Write next-hop number */
465 if (nhnummark)
hassoc1eaa442004-10-19 06:26:01 +0000466 stream_putc_at (s, nhnummark, nhnum);
paulb9df2d22004-05-09 09:09:59 +0000467
paul718e3742002-12-13 20:15:29 +0000468 /* Write packet size. */
469 stream_putw_at (s, 0, stream_get_endp (s));
470
ajs719e9742005-02-28 20:52:15 +0000471 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000472}
473
paul718e3742002-12-13 20:15:29 +0000474#ifdef HAVE_IPV6
ajs719e9742005-02-28 20:52:15 +0000475static int
Feng Luc99f3482014-10-16 09:52:36 +0800476zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
477 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000478{
479 struct stream *s;
480 struct rib *rib;
481 unsigned long nump;
482 u_char num;
483 struct nexthop *nexthop;
484
485 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800486 rib = rib_match_ipv6 (addr, vrf_id);
paul718e3742002-12-13 20:15:29 +0000487
488 /* Get output stream. */
489 s = client->obuf;
490 stream_reset (s);
491
492 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800493 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
Hiroshi Yokoi8ccd74c2015-09-08 11:52:20 +0900494 stream_put (s, addr, 16);
paul718e3742002-12-13 20:15:29 +0000495
496 if (rib)
497 {
498 stream_putl (s, rib->metric);
499 num = 0;
paul9985f832005-02-09 15:51:56 +0000500 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000501 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000502 /* Only non-recursive routes are elegible to resolve nexthop we
503 * are looking up. Therefore, we will just iterate over the top
504 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000505 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200506 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000507 {
508 stream_putc (s, nexthop->type);
509 switch (nexthop->type)
510 {
511 case ZEBRA_NEXTHOP_IPV6:
512 stream_put (s, &nexthop->gate.ipv6, 16);
513 break;
514 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
515 case ZEBRA_NEXTHOP_IPV6_IFNAME:
516 stream_put (s, &nexthop->gate.ipv6, 16);
517 stream_putl (s, nexthop->ifindex);
518 break;
519 case ZEBRA_NEXTHOP_IFINDEX:
520 case ZEBRA_NEXTHOP_IFNAME:
521 stream_putl (s, nexthop->ifindex);
522 break;
hassofa2b17e2004-03-04 17:45:00 +0000523 default:
524 /* do nothing */
525 break;
paul718e3742002-12-13 20:15:29 +0000526 }
527 num++;
528 }
529 stream_putc_at (s, nump, num);
530 }
531 else
532 {
533 stream_putl (s, 0);
534 stream_putc (s, 0);
535 }
536
537 stream_putw_at (s, 0, stream_get_endp (s));
538
ajs719e9742005-02-28 20:52:15 +0000539 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000540}
541#endif /* HAVE_IPV6 */
542
paulb9df2d22004-05-09 09:09:59 +0000543static int
Feng Luc99f3482014-10-16 09:52:36 +0800544zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
545 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000546{
547 struct stream *s;
548 struct rib *rib;
549 unsigned long nump;
550 u_char num;
551 struct nexthop *nexthop;
552
David Lamparterf598cf72014-11-22 14:44:20 -0800553 /* Lookup nexthop - eBGP excluded */
Feng Luc99f3482014-10-16 09:52:36 +0800554 rib = rib_match_ipv4_safi (addr, SAFI_UNICAST, 1, NULL, vrf_id);
paul718e3742002-12-13 20:15:29 +0000555
556 /* Get output stream. */
557 s = client->obuf;
558 stream_reset (s);
559
560 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800561 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000562 stream_put_in_addr (s, &addr);
563
564 if (rib)
565 {
Christian Frankebb97e462013-05-25 14:01:35 +0000566 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
567 zlog_debug("%s: Matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000568 stream_putl (s, rib->metric);
569 num = 0;
paul9985f832005-02-09 15:51:56 +0000570 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000571 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000572 /* Only non-recursive routes are elegible to resolve the nexthop we
573 * are looking up. Therefore, we will just iterate over the top
574 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000575 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200576 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000577 {
578 stream_putc (s, nexthop->type);
579 switch (nexthop->type)
580 {
581 case ZEBRA_NEXTHOP_IPV4:
582 stream_put_in_addr (s, &nexthop->gate.ipv4);
583 break;
Christian Frankebb97e462013-05-25 14:01:35 +0000584 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
585 stream_put_in_addr (s, &nexthop->gate.ipv4);
586 stream_putl (s, nexthop->ifindex);
587 break;
paul718e3742002-12-13 20:15:29 +0000588 case ZEBRA_NEXTHOP_IFINDEX:
589 case ZEBRA_NEXTHOP_IFNAME:
590 stream_putl (s, nexthop->ifindex);
591 break;
hassofa2b17e2004-03-04 17:45:00 +0000592 default:
593 /* do nothing */
594 break;
paul718e3742002-12-13 20:15:29 +0000595 }
596 num++;
597 }
598 stream_putc_at (s, nump, num);
599 }
600 else
601 {
Christian Frankebb97e462013-05-25 14:01:35 +0000602 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
603 zlog_debug("%s: No matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000604 stream_putl (s, 0);
605 stream_putc (s, 0);
606 }
607
608 stream_putw_at (s, 0, stream_get_endp (s));
609
ajs719e9742005-02-28 20:52:15 +0000610 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000611}
612
Everton Marques4e5275b2014-07-01 15:15:52 -0300613/*
614 Modified version of zsend_ipv4_nexthop_lookup():
615 Query unicast rib if nexthop is not found on mrib.
616 Returns both route metric and protocol distance.
617*/
618static int
David Lamparterbd078122015-01-06 19:53:24 +0100619zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr,
620 struct rib *rib)
Everton Marques4e5275b2014-07-01 15:15:52 -0300621{
622 struct stream *s;
Everton Marques4e5275b2014-07-01 15:15:52 -0300623 unsigned long nump;
624 u_char num;
625 struct nexthop *nexthop;
Everton Marques4e5275b2014-07-01 15:15:52 -0300626
627 /* Get output stream. */
628 s = client->obuf;
629 stream_reset (s);
630
631 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800632 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, rib->vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -0300633 stream_put_in_addr (s, &addr);
634
635 if (rib)
636 {
637 stream_putc (s, rib->distance);
638 stream_putl (s, rib->metric);
639 num = 0;
640 nump = stream_get_endp(s); /* remember position for nexthop_num */
641 stream_putc (s, 0); /* reserve room for nexthop_num */
642 /* Only non-recursive routes are elegible to resolve the nexthop we
643 * are looking up. Therefore, we will just iterate over the top
644 * chain of nexthops. */
645 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200646 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
Everton Marques4e5275b2014-07-01 15:15:52 -0300647 {
648 stream_putc (s, nexthop->type);
649 switch (nexthop->type)
650 {
651 case ZEBRA_NEXTHOP_IPV4:
652 stream_put_in_addr (s, &nexthop->gate.ipv4);
653 break;
654 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
655 stream_put_in_addr (s, &nexthop->gate.ipv4);
656 stream_putl (s, nexthop->ifindex);
657 break;
658 case ZEBRA_NEXTHOP_IFINDEX:
659 case ZEBRA_NEXTHOP_IFNAME:
660 stream_putl (s, nexthop->ifindex);
661 break;
662 default:
663 /* do nothing */
664 break;
665 }
666 num++;
667 }
668
669 stream_putc_at (s, nump, num); /* store nexthop_num */
670 }
671 else
672 {
673 stream_putc (s, 0); /* distance */
674 stream_putl (s, 0); /* metric */
675 stream_putc (s, 0); /* nexthop_num */
676 }
677
678 stream_putw_at (s, 0, stream_get_endp (s));
679
680 return zebra_server_send_message(client);
681}
682
paulb9df2d22004-05-09 09:09:59 +0000683static int
Feng Luc99f3482014-10-16 09:52:36 +0800684zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
685 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000686{
687 struct stream *s;
688 struct rib *rib;
689 unsigned long nump;
690 u_char num;
691 struct nexthop *nexthop;
692
693 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800694 rib = rib_lookup_ipv4 (p, vrf_id);
paul718e3742002-12-13 20:15:29 +0000695
696 /* Get output stream. */
697 s = client->obuf;
698 stream_reset (s);
699
700 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800701 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000702 stream_put_in_addr (s, &p->prefix);
703
704 if (rib)
705 {
706 stream_putl (s, rib->metric);
707 num = 0;
paul9985f832005-02-09 15:51:56 +0000708 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000709 stream_putc (s, 0);
710 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200711 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000712 {
713 stream_putc (s, nexthop->type);
714 switch (nexthop->type)
715 {
716 case ZEBRA_NEXTHOP_IPV4:
717 stream_put_in_addr (s, &nexthop->gate.ipv4);
718 break;
Christian Frankea12afd52013-05-25 14:01:36 +0000719 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
720 stream_put_in_addr (s, &nexthop->gate.ipv4);
721 stream_putl (s, nexthop->ifindex);
722 break;
paul718e3742002-12-13 20:15:29 +0000723 case ZEBRA_NEXTHOP_IFINDEX:
724 case ZEBRA_NEXTHOP_IFNAME:
725 stream_putl (s, nexthop->ifindex);
726 break;
hassofa2b17e2004-03-04 17:45:00 +0000727 default:
728 /* do nothing */
729 break;
paul718e3742002-12-13 20:15:29 +0000730 }
731 num++;
732 }
733 stream_putc_at (s, nump, num);
734 }
735 else
736 {
737 stream_putl (s, 0);
738 stream_putc (s, 0);
739 }
740
741 stream_putw_at (s, 0, stream_get_endp (s));
742
ajs719e9742005-02-28 20:52:15 +0000743 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000744}
David Lamparter6b0655a2014-06-04 06:53:35 +0200745
hasso18a6dce2004-10-03 18:18:34 +0000746/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
747int
Feng Luac19a442015-05-22 11:40:07 +0200748zsend_router_id_update (struct zserv *client, struct prefix *p,
749 vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +0000750{
751 struct stream *s;
752 int blen;
753
754 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800755 if (! vrf_bitmap_check (client->ridinfo, vrf_id))
ajs719e9742005-02-28 20:52:15 +0000756 return 0;
hasso18a6dce2004-10-03 18:18:34 +0000757
758 s = client->obuf;
759 stream_reset (s);
760
hasso18a6dce2004-10-03 18:18:34 +0000761 /* Message type. */
Feng Luc99f3482014-10-16 09:52:36 +0800762 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +0000763
764 /* Prefix information. */
765 stream_putc (s, p->family);
766 blen = prefix_blen (p);
767 stream_put (s, &p->u.prefix, blen);
768 stream_putc (s, p->prefixlen);
769
770 /* Write packet size. */
771 stream_putw_at (s, 0, stream_get_endp (s));
772
ajs719e9742005-02-28 20:52:15 +0000773 return zebra_server_send_message(client);
hasso18a6dce2004-10-03 18:18:34 +0000774}
David Lamparter6b0655a2014-06-04 06:53:35 +0200775
paul718e3742002-12-13 20:15:29 +0000776/* Register zebra server interface information. Send current all
777 interface and address information. */
ajs719e9742005-02-28 20:52:15 +0000778static int
Feng Luc99f3482014-10-16 09:52:36 +0800779zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000780{
paul1eb8ef22005-04-07 07:30:20 +0000781 struct listnode *ifnode, *ifnnode;
782 struct listnode *cnode, *cnnode;
paul718e3742002-12-13 20:15:29 +0000783 struct interface *ifp;
784 struct connected *c;
785
786 /* Interface information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +0800787 vrf_bitmap_set (client->ifinfo, vrf_id);
paul718e3742002-12-13 20:15:29 +0000788
Feng Luc99f3482014-10-16 09:52:36 +0800789 for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
paul718e3742002-12-13 20:15:29 +0000790 {
paul718e3742002-12-13 20:15:29 +0000791 /* Skip pseudo interface. */
792 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
793 continue;
794
ajs719e9742005-02-28 20:52:15 +0000795 if (zsend_interface_add (client, ifp) < 0)
796 return -1;
paul718e3742002-12-13 20:15:29 +0000797
paul1eb8ef22005-04-07 07:30:20 +0000798 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
paul718e3742002-12-13 20:15:29 +0000799 {
ajs719e9742005-02-28 20:52:15 +0000800 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
801 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
802 ifp, c) < 0))
803 return -1;
paul718e3742002-12-13 20:15:29 +0000804 }
805 }
ajs719e9742005-02-28 20:52:15 +0000806 return 0;
paul718e3742002-12-13 20:15:29 +0000807}
808
809/* Unregister zebra server interface information. */
ajs719e9742005-02-28 20:52:15 +0000810static int
Feng Luc99f3482014-10-16 09:52:36 +0800811zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000812{
Feng Luc99f3482014-10-16 09:52:36 +0800813 vrf_bitmap_unset (client->ifinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +0000814 return 0;
paul718e3742002-12-13 20:15:29 +0000815}
816
817/* This function support multiple nexthop. */
paulb9df2d22004-05-09 09:09:59 +0000818/*
819 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
820 * add kernel route.
821 */
ajs719e9742005-02-28 20:52:15 +0000822static int
Feng Luc99f3482014-10-16 09:52:36 +0800823zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000824{
825 int i;
826 struct rib *rib;
827 struct prefix_ipv4 p;
828 u_char message;
829 struct in_addr nexthop;
830 u_char nexthop_num;
831 u_char nexthop_type;
832 struct stream *s;
833 unsigned int ifindex;
834 u_char ifname_len;
G.Balajicddf3912011-11-26 21:59:32 +0400835 safi_t safi;
836
paul718e3742002-12-13 20:15:29 +0000837
838 /* Get input stream. */
839 s = client->ibuf;
840
841 /* Allocate new rib. */
paul4d38fdb2005-04-28 17:35:14 +0000842 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
843
paul718e3742002-12-13 20:15:29 +0000844 /* Type, flags, message. */
845 rib->type = stream_getc (s);
846 rib->flags = stream_getc (s);
paulb9df2d22004-05-09 09:09:59 +0000847 message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400848 safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000849 rib->uptime = time (NULL);
850
851 /* IPv4 prefix. */
852 memset (&p, 0, sizeof (struct prefix_ipv4));
853 p.family = AF_INET;
854 p.prefixlen = stream_getc (s);
855 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
856
Feng Lu0d0686f2015-05-22 11:40:02 +0200857 /* VRF ID */
Feng Luc99f3482014-10-16 09:52:36 +0800858 rib->vrf_id = vrf_id;
Feng Lu0d0686f2015-05-22 11:40:02 +0200859
paul718e3742002-12-13 20:15:29 +0000860 /* Nexthop parse. */
861 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
862 {
863 nexthop_num = stream_getc (s);
864
865 for (i = 0; i < nexthop_num; i++)
866 {
867 nexthop_type = stream_getc (s);
868
869 switch (nexthop_type)
870 {
871 case ZEBRA_NEXTHOP_IFINDEX:
872 ifindex = stream_getl (s);
873 nexthop_ifindex_add (rib, ifindex);
874 break;
875 case ZEBRA_NEXTHOP_IFNAME:
876 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000877 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000878 break;
879 case ZEBRA_NEXTHOP_IPV4:
880 nexthop.s_addr = stream_get_ipv4 (s);
Paul Jakma7514fb72007-05-02 16:05:35 +0000881 nexthop_ipv4_add (rib, &nexthop, NULL);
paul718e3742002-12-13 20:15:29 +0000882 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200883 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
884 nexthop.s_addr = stream_get_ipv4 (s);
885 ifindex = stream_getl (s);
886 nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
887 break;
paul718e3742002-12-13 20:15:29 +0000888 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000889 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000890 break;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700891 case ZEBRA_NEXTHOP_BLACKHOLE:
892 nexthop_blackhole_add (rib);
893 break;
894 }
paul718e3742002-12-13 20:15:29 +0000895 }
896 }
897
898 /* Distance. */
899 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
900 rib->distance = stream_getc (s);
901
902 /* Metric. */
903 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
904 rib->metric = stream_getl (s);
905
Timo Teräsb11f3b52015-11-02 16:50:07 +0200906 if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
907 rib->mtu = stream_getl (s);
908
Paul Jakma171eee32006-07-27 16:11:02 +0000909 /* Table */
910 rib->table=zebrad.rtm_table_default;
G.Balajicddf3912011-11-26 21:59:32 +0400911 rib_add_ipv4_multipath (&p, rib, safi);
ajs719e9742005-02-28 20:52:15 +0000912 return 0;
paul718e3742002-12-13 20:15:29 +0000913}
914
915/* Zebra server IPv4 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +0000916static int
Feng Luc99f3482014-10-16 09:52:36 +0800917zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000918{
919 int i;
920 struct stream *s;
921 struct zapi_ipv4 api;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700922 struct in_addr nexthop, *nexthop_p;
paul718e3742002-12-13 20:15:29 +0000923 unsigned long ifindex;
924 struct prefix_ipv4 p;
925 u_char nexthop_num;
926 u_char nexthop_type;
927 u_char ifname_len;
928
929 s = client->ibuf;
930 ifindex = 0;
931 nexthop.s_addr = 0;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700932 nexthop_p = NULL;
paul718e3742002-12-13 20:15:29 +0000933
934 /* Type, flags, message. */
935 api.type = stream_getc (s);
936 api.flags = stream_getc (s);
937 api.message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400938 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000939
940 /* IPv4 prefix. */
941 memset (&p, 0, sizeof (struct prefix_ipv4));
942 p.family = AF_INET;
943 p.prefixlen = stream_getc (s);
944 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
945
946 /* Nexthop, ifindex, distance, metric. */
947 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
948 {
949 nexthop_num = stream_getc (s);
950
951 for (i = 0; i < nexthop_num; i++)
952 {
953 nexthop_type = stream_getc (s);
954
955 switch (nexthop_type)
956 {
957 case ZEBRA_NEXTHOP_IFINDEX:
958 ifindex = stream_getl (s);
959 break;
960 case ZEBRA_NEXTHOP_IFNAME:
961 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000962 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000963 break;
964 case ZEBRA_NEXTHOP_IPV4:
965 nexthop.s_addr = stream_get_ipv4 (s);
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700966 nexthop_p = &nexthop;
paul718e3742002-12-13 20:15:29 +0000967 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200968 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
969 nexthop.s_addr = stream_get_ipv4 (s);
Christian Franke23f5f7c2013-11-27 17:06:14 +0000970 nexthop_p = &nexthop;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200971 ifindex = stream_getl (s);
972 break;
paul718e3742002-12-13 20:15:29 +0000973 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000974 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000975 break;
976 }
977 }
978 }
979
980 /* Distance. */
981 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
982 api.distance = stream_getc (s);
983 else
984 api.distance = 0;
985
986 /* Metric. */
987 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
988 api.metric = stream_getl (s);
989 else
990 api.metric = 0;
991
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700992 rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +0800993 vrf_id, api.safi);
ajs719e9742005-02-28 20:52:15 +0000994 return 0;
paul718e3742002-12-13 20:15:29 +0000995}
996
997/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +0000998static int
Feng Luc99f3482014-10-16 09:52:36 +0800999zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
1000 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001001{
1002 struct in_addr addr;
Christian Frankebb97e462013-05-25 14:01:35 +00001003 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00001004
1005 addr.s_addr = stream_get_ipv4 (client->ibuf);
Christian Frankebb97e462013-05-25 14:01:35 +00001006 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1007 zlog_debug("%s: looking up %s", __func__,
1008 inet_ntop (AF_INET, &addr, buf, BUFSIZ));
Feng Luc99f3482014-10-16 09:52:36 +08001009 return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001010}
1011
Everton Marques4e5275b2014-07-01 15:15:52 -03001012/* MRIB Nexthop lookup for IPv4. */
1013static int
Feng Luc99f3482014-10-16 09:52:36 +08001014zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length,
1015 vrf_id_t vrf_id)
Everton Marques4e5275b2014-07-01 15:15:52 -03001016{
1017 struct in_addr addr;
David Lamparterbd078122015-01-06 19:53:24 +01001018 struct rib *rib;
Everton Marques4e5275b2014-07-01 15:15:52 -03001019
1020 addr.s_addr = stream_get_ipv4 (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001021 rib = rib_match_ipv4_multicast (addr, NULL, vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +01001022 return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib);
Everton Marques4e5275b2014-07-01 15:15:52 -03001023}
1024
paul718e3742002-12-13 20:15:29 +00001025/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +00001026static int
Feng Luc99f3482014-10-16 09:52:36 +08001027zread_ipv4_import_lookup (struct zserv *client, u_short length,
1028 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001029{
1030 struct prefix_ipv4 p;
1031
1032 p.family = AF_INET;
1033 p.prefixlen = stream_getc (client->ibuf);
1034 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1035
Feng Luc99f3482014-10-16 09:52:36 +08001036 return zsend_ipv4_import_lookup (client, &p, vrf_id);
paul718e3742002-12-13 20:15:29 +00001037}
1038
1039#ifdef HAVE_IPV6
1040/* Zebra server IPv6 prefix add function. */
ajs719e9742005-02-28 20:52:15 +00001041static int
Feng Luc99f3482014-10-16 09:52:36 +08001042zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001043{
1044 int i;
1045 struct stream *s;
1046 struct zapi_ipv6 api;
1047 struct in6_addr nexthop;
1048 unsigned long ifindex;
1049 struct prefix_ipv6 p;
1050
1051 s = client->ibuf;
1052 ifindex = 0;
1053 memset (&nexthop, 0, sizeof (struct in6_addr));
1054
1055 /* Type, flags, message. */
1056 api.type = stream_getc (s);
1057 api.flags = stream_getc (s);
1058 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001059 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001060
1061 /* IPv4 prefix. */
1062 memset (&p, 0, sizeof (struct prefix_ipv6));
1063 p.family = AF_INET6;
1064 p.prefixlen = stream_getc (s);
1065 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1066
1067 /* Nexthop, ifindex, distance, metric. */
1068 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1069 {
1070 u_char nexthop_type;
1071
1072 api.nexthop_num = stream_getc (s);
1073 for (i = 0; i < api.nexthop_num; i++)
1074 {
1075 nexthop_type = stream_getc (s);
1076
1077 switch (nexthop_type)
1078 {
1079 case ZEBRA_NEXTHOP_IPV6:
1080 stream_get (&nexthop, s, 16);
1081 break;
1082 case ZEBRA_NEXTHOP_IFINDEX:
1083 ifindex = stream_getl (s);
1084 break;
1085 }
1086 }
1087 }
1088
1089 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1090 api.distance = stream_getc (s);
1091 else
1092 api.distance = 0;
1093
1094 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1095 api.metric = stream_getl (s);
1096 else
1097 api.metric = 0;
Timo Teräsb11f3b52015-11-02 16:50:07 +02001098
1099 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_MTU))
1100 api.mtu = stream_getl (s);
1101 else
1102 api.mtu = 0;
paul718e3742002-12-13 20:15:29 +00001103
1104 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Lu0d0686f2015-05-22 11:40:02 +02001105 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001106 vrf_id, zebrad.rtm_table_default, api.metric,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001107 api.mtu, api.distance, api.safi);
paul718e3742002-12-13 20:15:29 +00001108 else
Feng Lu0d0686f2015-05-22 11:40:02 +02001109 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001110 vrf_id, zebrad.rtm_table_default, api.metric,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001111 api.mtu, api.distance, api.safi);
ajs719e9742005-02-28 20:52:15 +00001112 return 0;
paul718e3742002-12-13 20:15:29 +00001113}
1114
1115/* Zebra server IPv6 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +00001116static int
Feng Luc99f3482014-10-16 09:52:36 +08001117zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001118{
1119 int i;
1120 struct stream *s;
1121 struct zapi_ipv6 api;
1122 struct in6_addr nexthop;
1123 unsigned long ifindex;
1124 struct prefix_ipv6 p;
1125
1126 s = client->ibuf;
1127 ifindex = 0;
1128 memset (&nexthop, 0, sizeof (struct in6_addr));
1129
1130 /* Type, flags, message. */
1131 api.type = stream_getc (s);
1132 api.flags = stream_getc (s);
1133 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001134 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001135
1136 /* IPv4 prefix. */
1137 memset (&p, 0, sizeof (struct prefix_ipv6));
1138 p.family = AF_INET6;
1139 p.prefixlen = stream_getc (s);
1140 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1141
1142 /* Nexthop, ifindex, distance, metric. */
1143 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1144 {
1145 u_char nexthop_type;
1146
1147 api.nexthop_num = stream_getc (s);
1148 for (i = 0; i < api.nexthop_num; i++)
1149 {
1150 nexthop_type = stream_getc (s);
1151
1152 switch (nexthop_type)
1153 {
1154 case ZEBRA_NEXTHOP_IPV6:
1155 stream_get (&nexthop, s, 16);
1156 break;
1157 case ZEBRA_NEXTHOP_IFINDEX:
1158 ifindex = stream_getl (s);
1159 break;
1160 }
1161 }
1162 }
1163
1164 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1165 api.distance = stream_getc (s);
1166 else
1167 api.distance = 0;
1168 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1169 api.metric = stream_getl (s);
1170 else
1171 api.metric = 0;
1172
1173 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Luc99f3482014-10-16 09:52:36 +08001174 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001175 api.safi);
paul718e3742002-12-13 20:15:29 +00001176 else
Feng Luc99f3482014-10-16 09:52:36 +08001177 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001178 api.safi);
ajs719e9742005-02-28 20:52:15 +00001179 return 0;
paul718e3742002-12-13 20:15:29 +00001180}
1181
ajs719e9742005-02-28 20:52:15 +00001182static int
Feng Luc99f3482014-10-16 09:52:36 +08001183zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
1184 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001185{
1186 struct in6_addr addr;
1187 char buf[BUFSIZ];
1188
1189 stream_get (&addr, client->ibuf, 16);
Christian Frankea5207082013-04-11 08:24:29 +00001190 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1191 zlog_debug("%s: looking up %s", __func__,
1192 inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
paul718e3742002-12-13 20:15:29 +00001193
Feng Luc99f3482014-10-16 09:52:36 +08001194 return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001195}
1196#endif /* HAVE_IPV6 */
1197
hasso18a6dce2004-10-03 18:18:34 +00001198/* Register zebra server router-id information. Send current router-id */
ajs719e9742005-02-28 20:52:15 +00001199static int
Feng Luc99f3482014-10-16 09:52:36 +08001200zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001201{
1202 struct prefix p;
1203
1204 /* Router-id information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +08001205 vrf_bitmap_set (client->ridinfo, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001206
Feng Luc99f3482014-10-16 09:52:36 +08001207 router_id_get (&p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001208
Feng Luc99f3482014-10-16 09:52:36 +08001209 return zsend_router_id_update (client, &p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001210}
1211
1212/* Unregister zebra server router-id information. */
ajs719e9742005-02-28 20:52:15 +00001213static int
Feng Luc99f3482014-10-16 09:52:36 +08001214zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001215{
Feng Luc99f3482014-10-16 09:52:36 +08001216 vrf_bitmap_unset (client->ridinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +00001217 return 0;
hasso18a6dce2004-10-03 18:18:34 +00001218}
1219
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001220/* Tie up route-type and client->sock */
1221static void
1222zread_hello (struct zserv *client)
1223{
1224 /* type of protocol (lib/zebra.h) */
1225 u_char proto;
1226 proto = stream_getc (client->ibuf);
1227
1228 /* accept only dynamic routing protocols */
1229 if ((proto < ZEBRA_ROUTE_MAX)
1230 && (proto > ZEBRA_ROUTE_STATIC))
1231 {
1232 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1233 client->sock, zebra_route_string(proto));
1234
1235 /* if route-type was binded by other client */
1236 if (route_type_oaths[proto])
1237 zlog_warn ("sender of %s routes changed %c->%c",
1238 zebra_route_string(proto), route_type_oaths[proto],
1239 client->sock);
1240
1241 route_type_oaths[proto] = client->sock;
1242 }
1243}
1244
Feng Luc99f3482014-10-16 09:52:36 +08001245/* Unregister all information in a VRF. */
1246static int
1247zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
1248{
1249 int i;
1250
1251 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1252 vrf_bitmap_unset (client->redist[i], vrf_id);
1253 vrf_bitmap_unset (client->redist_default, vrf_id);
1254 vrf_bitmap_unset (client->ifinfo, vrf_id);
1255 vrf_bitmap_unset (client->ridinfo, vrf_id);
1256
1257 return 0;
1258}
1259
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001260/* If client sent routes of specific type, zebra removes it
1261 * and returns number of deleted routes.
1262 */
1263static void
1264zebra_score_rib (int client_sock)
1265{
1266 int i;
1267
1268 for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
1269 if (client_sock == route_type_oaths[i])
1270 {
1271 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1272 client_sock, rib_score_proto (i), zebra_route_string (i));
1273 route_type_oaths[i] = 0;
1274 break;
1275 }
1276}
1277
paul718e3742002-12-13 20:15:29 +00001278/* Close zebra client. */
paulb9df2d22004-05-09 09:09:59 +00001279static void
paul718e3742002-12-13 20:15:29 +00001280zebra_client_close (struct zserv *client)
1281{
1282 /* Close file descriptor. */
1283 if (client->sock)
1284 {
1285 close (client->sock);
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001286 zebra_score_rib (client->sock);
paul718e3742002-12-13 20:15:29 +00001287 client->sock = -1;
1288 }
1289
1290 /* Free stream buffers. */
1291 if (client->ibuf)
1292 stream_free (client->ibuf);
1293 if (client->obuf)
1294 stream_free (client->obuf);
ajs719e9742005-02-28 20:52:15 +00001295 if (client->wb)
1296 buffer_free(client->wb);
paul718e3742002-12-13 20:15:29 +00001297
1298 /* Release threads. */
1299 if (client->t_read)
1300 thread_cancel (client->t_read);
1301 if (client->t_write)
1302 thread_cancel (client->t_write);
ajs719e9742005-02-28 20:52:15 +00001303 if (client->t_suicide)
1304 thread_cancel (client->t_suicide);
paul718e3742002-12-13 20:15:29 +00001305
1306 /* Free client structure. */
paulb21b19c2003-06-15 01:28:29 +00001307 listnode_delete (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001308 XFREE (0, client);
1309}
1310
1311/* Make new client. */
paulb9df2d22004-05-09 09:09:59 +00001312static void
paul718e3742002-12-13 20:15:29 +00001313zebra_client_create (int sock)
1314{
1315 struct zserv *client;
Feng Luc99f3482014-10-16 09:52:36 +08001316 int i;
paul718e3742002-12-13 20:15:29 +00001317
1318 client = XCALLOC (0, sizeof (struct zserv));
1319
1320 /* Make client input/output buffer. */
1321 client->sock = sock;
1322 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1323 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
ajs719e9742005-02-28 20:52:15 +00001324 client->wb = buffer_new(0);
paul718e3742002-12-13 20:15:29 +00001325
1326 /* Set table number. */
paulb21b19c2003-06-15 01:28:29 +00001327 client->rtm_table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00001328
Feng Luc99f3482014-10-16 09:52:36 +08001329 /* Initialize flags */
1330 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1331 client->redist[i] = vrf_bitmap_init ();
1332 client->redist_default = vrf_bitmap_init ();
1333 client->ifinfo = vrf_bitmap_init ();
1334 client->ridinfo = vrf_bitmap_init ();
1335
paul718e3742002-12-13 20:15:29 +00001336 /* Add this client to linked list. */
paulb21b19c2003-06-15 01:28:29 +00001337 listnode_add (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001338
1339 /* Make new read thread. */
1340 zebra_event (ZEBRA_READ, sock, client);
1341}
1342
1343/* Handler of zebra service request. */
paulb9df2d22004-05-09 09:09:59 +00001344static int
paul718e3742002-12-13 20:15:29 +00001345zebra_client_read (struct thread *thread)
1346{
1347 int sock;
1348 struct zserv *client;
ajs57a14772005-04-10 15:01:56 +00001349 size_t already;
paulc1b98002006-01-16 01:54:02 +00001350 uint16_t length, command;
1351 uint8_t marker, version;
Feng Luc99f3482014-10-16 09:52:36 +08001352 vrf_id_t vrf_id;
paul718e3742002-12-13 20:15:29 +00001353
1354 /* Get thread data. Reset reading thread because I'm running. */
1355 sock = THREAD_FD (thread);
1356 client = THREAD_ARG (thread);
1357 client->t_read = NULL;
1358
ajs719e9742005-02-28 20:52:15 +00001359 if (client->t_suicide)
paul718e3742002-12-13 20:15:29 +00001360 {
ajs719e9742005-02-28 20:52:15 +00001361 zebra_client_close(client);
paul718e3742002-12-13 20:15:29 +00001362 return -1;
1363 }
ajs719e9742005-02-28 20:52:15 +00001364
1365 /* Read length and command (if we don't have it already). */
ajs57a14772005-04-10 15:01:56 +00001366 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
ajs719e9742005-02-28 20:52:15 +00001367 {
ajs57a14772005-04-10 15:01:56 +00001368 ssize_t nbyte;
ajs719e9742005-02-28 20:52:15 +00001369 if (((nbyte = stream_read_try (client->ibuf, sock,
ajs57a14772005-04-10 15:01:56 +00001370 ZEBRA_HEADER_SIZE-already)) == 0) ||
ajs719e9742005-02-28 20:52:15 +00001371 (nbyte == -1))
1372 {
1373 if (IS_ZEBRA_DEBUG_EVENT)
1374 zlog_debug ("connection closed socket [%d]", sock);
1375 zebra_client_close (client);
1376 return -1;
1377 }
ajs57a14772005-04-10 15:01:56 +00001378 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
ajs719e9742005-02-28 20:52:15 +00001379 {
1380 /* Try again later. */
1381 zebra_event (ZEBRA_READ, sock, client);
1382 return 0;
1383 }
ajs57a14772005-04-10 15:01:56 +00001384 already = ZEBRA_HEADER_SIZE;
ajs719e9742005-02-28 20:52:15 +00001385 }
1386
1387 /* Reset to read from the beginning of the incoming packet. */
1388 stream_set_getp(client->ibuf, 0);
1389
paulc1b98002006-01-16 01:54:02 +00001390 /* Fetch header values */
paul718e3742002-12-13 20:15:29 +00001391 length = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001392 marker = stream_getc (client->ibuf);
1393 version = stream_getc (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001394 vrf_id = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001395 command = stream_getw (client->ibuf);
paul718e3742002-12-13 20:15:29 +00001396
paulc1b98002006-01-16 01:54:02 +00001397 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1398 {
1399 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1400 __func__, sock, marker, version);
1401 zebra_client_close (client);
1402 return -1;
1403 }
ajs719e9742005-02-28 20:52:15 +00001404 if (length < ZEBRA_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00001405 {
ajs57a14772005-04-10 15:01:56 +00001406 zlog_warn("%s: socket %d message length %u is less than header size %d",
1407 __func__, sock, length, ZEBRA_HEADER_SIZE);
1408 zebra_client_close (client);
1409 return -1;
1410 }
1411 if (length > STREAM_SIZE(client->ibuf))
1412 {
1413 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1414 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
paul718e3742002-12-13 20:15:29 +00001415 zebra_client_close (client);
1416 return -1;
1417 }
1418
paul718e3742002-12-13 20:15:29 +00001419 /* Read rest of data. */
ajs57a14772005-04-10 15:01:56 +00001420 if (already < length)
paul718e3742002-12-13 20:15:29 +00001421 {
ajs57a14772005-04-10 15:01:56 +00001422 ssize_t nbyte;
1423 if (((nbyte = stream_read_try (client->ibuf, sock,
1424 length-already)) == 0) ||
1425 (nbyte == -1))
paul718e3742002-12-13 20:15:29 +00001426 {
1427 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001428 zlog_debug ("connection closed [%d] when reading zebra data", sock);
paul718e3742002-12-13 20:15:29 +00001429 zebra_client_close (client);
1430 return -1;
1431 }
ajs57a14772005-04-10 15:01:56 +00001432 if (nbyte != (ssize_t)(length-already))
ajs719e9742005-02-28 20:52:15 +00001433 {
1434 /* Try again later. */
1435 zebra_event (ZEBRA_READ, sock, client);
1436 return 0;
1437 }
paul718e3742002-12-13 20:15:29 +00001438 }
1439
ajs719e9742005-02-28 20:52:15 +00001440 length -= ZEBRA_HEADER_SIZE;
1441
paul718e3742002-12-13 20:15:29 +00001442 /* Debug packet information. */
1443 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001444 zlog_debug ("zebra message comes from socket [%d]", sock);
paul718e3742002-12-13 20:15:29 +00001445
1446 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
Feng Luc99f3482014-10-16 09:52:36 +08001447 zlog_debug ("zebra message received [%s] %d in VRF %u",
1448 zserv_command_string (command), length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001449
1450 switch (command)
1451 {
hasso18a6dce2004-10-03 18:18:34 +00001452 case ZEBRA_ROUTER_ID_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001453 zread_router_id_add (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001454 break;
1455 case ZEBRA_ROUTER_ID_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001456 zread_router_id_delete (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001457 break;
paul718e3742002-12-13 20:15:29 +00001458 case ZEBRA_INTERFACE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001459 zread_interface_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001460 break;
1461 case ZEBRA_INTERFACE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001462 zread_interface_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001463 break;
1464 case ZEBRA_IPV4_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001465 zread_ipv4_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001466 break;
1467 case ZEBRA_IPV4_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001468 zread_ipv4_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001469 break;
1470#ifdef HAVE_IPV6
1471 case ZEBRA_IPV6_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001472 zread_ipv6_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001473 break;
1474 case ZEBRA_IPV6_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001475 zread_ipv6_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001476 break;
1477#endif /* HAVE_IPV6 */
1478 case ZEBRA_REDISTRIBUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001479 zebra_redistribute_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001480 break;
1481 case ZEBRA_REDISTRIBUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001482 zebra_redistribute_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001483 break;
1484 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001485 zebra_redistribute_default_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001486 break;
1487 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001488 zebra_redistribute_default_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001489 break;
1490 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001491 zread_ipv4_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001492 break;
Everton Marques4e5275b2014-07-01 15:15:52 -03001493 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
Feng Luc99f3482014-10-16 09:52:36 +08001494 zread_ipv4_nexthop_lookup_mrib (client, length, vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -03001495 break;
paul718e3742002-12-13 20:15:29 +00001496#ifdef HAVE_IPV6
1497 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001498 zread_ipv6_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001499 break;
1500#endif /* HAVE_IPV6 */
1501 case ZEBRA_IPV4_IMPORT_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001502 zread_ipv4_import_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001503 break;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001504 case ZEBRA_HELLO:
1505 zread_hello (client);
1506 break;
Feng Luc99f3482014-10-16 09:52:36 +08001507 case ZEBRA_VRF_UNREGISTER:
1508 zread_vrf_unregister (client, length, vrf_id);
1509 break;
paul718e3742002-12-13 20:15:29 +00001510 default:
1511 zlog_info ("Zebra received unknown command %d", command);
1512 break;
1513 }
1514
ajs719e9742005-02-28 20:52:15 +00001515 if (client->t_suicide)
1516 {
1517 /* No need to wait for thread callback, just kill immediately. */
1518 zebra_client_close(client);
1519 return -1;
1520 }
1521
paul718e3742002-12-13 20:15:29 +00001522 stream_reset (client->ibuf);
1523 zebra_event (ZEBRA_READ, sock, client);
paul718e3742002-12-13 20:15:29 +00001524 return 0;
1525}
1526
paul718e3742002-12-13 20:15:29 +00001527
1528/* Accept code of zebra server socket. */
paulb9df2d22004-05-09 09:09:59 +00001529static int
paul718e3742002-12-13 20:15:29 +00001530zebra_accept (struct thread *thread)
1531{
1532 int accept_sock;
1533 int client_sock;
1534 struct sockaddr_in client;
1535 socklen_t len;
1536
1537 accept_sock = THREAD_FD (thread);
1538
ajs719e9742005-02-28 20:52:15 +00001539 /* Reregister myself. */
1540 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1541
paul718e3742002-12-13 20:15:29 +00001542 len = sizeof (struct sockaddr_in);
1543 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1544
1545 if (client_sock < 0)
1546 {
ajs6099b3b2004-11-20 02:06:59 +00001547 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001548 return -1;
1549 }
1550
paulccf35572003-03-01 11:42:20 +00001551 /* Make client socket non-blocking. */
ajs719e9742005-02-28 20:52:15 +00001552 set_nonblocking(client_sock);
paul865b8522005-01-05 08:30:35 +00001553
paul718e3742002-12-13 20:15:29 +00001554 /* Create new zebra client. */
1555 zebra_client_create (client_sock);
1556
paul718e3742002-12-13 20:15:29 +00001557 return 0;
1558}
1559
paulb9df2d22004-05-09 09:09:59 +00001560#ifdef HAVE_TCP_ZEBRA
paul718e3742002-12-13 20:15:29 +00001561/* Make zebra's server socket. */
paulb9df2d22004-05-09 09:09:59 +00001562static void
paul718e3742002-12-13 20:15:29 +00001563zebra_serv ()
1564{
1565 int ret;
1566 int accept_sock;
1567 struct sockaddr_in addr;
1568
1569 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1570
1571 if (accept_sock < 0)
1572 {
paul3d1dc852005-04-05 00:45:23 +00001573 zlog_warn ("Can't create zserv stream socket: %s",
1574 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001575 zlog_warn ("zebra can't provice full functionality due to above error");
1576 return;
1577 }
1578
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001579 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
paul718e3742002-12-13 20:15:29 +00001580 memset (&addr, 0, sizeof (struct sockaddr_in));
1581 addr.sin_family = AF_INET;
1582 addr.sin_port = htons (ZEBRA_PORT);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001583#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +00001584 addr.sin_len = sizeof (struct sockaddr_in);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001585#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +00001586 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1587
1588 sockopt_reuseaddr (accept_sock);
1589 sockopt_reuseport (accept_sock);
1590
pauledd7c242003-06-04 13:59:38 +00001591 if ( zserv_privs.change(ZPRIVS_RAISE) )
1592 zlog (NULL, LOG_ERR, "Can't raise privileges");
1593
paul718e3742002-12-13 20:15:29 +00001594 ret = bind (accept_sock, (struct sockaddr *)&addr,
1595 sizeof (struct sockaddr_in));
1596 if (ret < 0)
1597 {
paul3d1dc852005-04-05 00:45:23 +00001598 zlog_warn ("Can't bind to stream socket: %s",
1599 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001600 zlog_warn ("zebra can't provice full functionality due to above error");
1601 close (accept_sock); /* Avoid sd leak. */
1602 return;
1603 }
pauledd7c242003-06-04 13:59:38 +00001604
1605 if ( zserv_privs.change(ZPRIVS_LOWER) )
1606 zlog (NULL, LOG_ERR, "Can't lower privileges");
paul718e3742002-12-13 20:15:29 +00001607
1608 ret = listen (accept_sock, 1);
1609 if (ret < 0)
1610 {
paul3d1dc852005-04-05 00:45:23 +00001611 zlog_warn ("Can't listen to stream socket: %s",
1612 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001613 zlog_warn ("zebra can't provice full functionality due to above error");
1614 close (accept_sock); /* Avoid sd leak. */
1615 return;
1616 }
1617
1618 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1619}
David Lamparter4b6c3322015-04-21 09:47:57 +02001620#else /* HAVE_TCP_ZEBRA */
paul718e3742002-12-13 20:15:29 +00001621
1622/* For sockaddr_un. */
1623#include <sys/un.h>
1624
1625/* zebra server UNIX domain socket. */
paulb9df2d22004-05-09 09:09:59 +00001626static void
hassofce954f2004-10-07 20:29:24 +00001627zebra_serv_un (const char *path)
paul718e3742002-12-13 20:15:29 +00001628{
1629 int ret;
1630 int sock, len;
1631 struct sockaddr_un serv;
1632 mode_t old_mask;
1633
1634 /* First of all, unlink existing socket */
1635 unlink (path);
1636
1637 /* Set umask */
1638 old_mask = umask (0077);
1639
1640 /* Make UNIX domain socket. */
1641 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1642 if (sock < 0)
1643 {
paul3d1dc852005-04-05 00:45:23 +00001644 zlog_warn ("Can't create zserv unix socket: %s",
1645 safe_strerror (errno));
1646 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001647 return;
1648 }
1649
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001650 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1651
paul718e3742002-12-13 20:15:29 +00001652 /* Make server socket. */
1653 memset (&serv, 0, sizeof (struct sockaddr_un));
1654 serv.sun_family = AF_UNIX;
1655 strncpy (serv.sun_path, path, strlen (path));
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001656#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
paul718e3742002-12-13 20:15:29 +00001657 len = serv.sun_len = SUN_LEN(&serv);
1658#else
1659 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001660#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
paul718e3742002-12-13 20:15:29 +00001661
1662 ret = bind (sock, (struct sockaddr *) &serv, len);
1663 if (ret < 0)
1664 {
paul3d1dc852005-04-05 00:45:23 +00001665 zlog_warn ("Can't bind to unix socket %s: %s",
1666 path, safe_strerror (errno));
1667 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001668 close (sock);
1669 return;
1670 }
1671
1672 ret = listen (sock, 5);
1673 if (ret < 0)
1674 {
paul3d1dc852005-04-05 00:45:23 +00001675 zlog_warn ("Can't listen to unix socket %s: %s",
1676 path, safe_strerror (errno));
1677 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001678 close (sock);
1679 return;
1680 }
1681
1682 umask (old_mask);
1683
1684 zebra_event (ZEBRA_SERV, sock, NULL);
1685}
David Lamparter4b6c3322015-04-21 09:47:57 +02001686#endif /* HAVE_TCP_ZEBRA */
David Lamparter6b0655a2014-06-04 06:53:35 +02001687
paul718e3742002-12-13 20:15:29 +00001688
paulb9df2d22004-05-09 09:09:59 +00001689static void
paul718e3742002-12-13 20:15:29 +00001690zebra_event (enum event event, int sock, struct zserv *client)
1691{
1692 switch (event)
1693 {
1694 case ZEBRA_SERV:
paulb21b19c2003-06-15 01:28:29 +00001695 thread_add_read (zebrad.master, zebra_accept, client, sock);
paul718e3742002-12-13 20:15:29 +00001696 break;
1697 case ZEBRA_READ:
1698 client->t_read =
paulb21b19c2003-06-15 01:28:29 +00001699 thread_add_read (zebrad.master, zebra_client_read, client, sock);
paul718e3742002-12-13 20:15:29 +00001700 break;
1701 case ZEBRA_WRITE:
1702 /**/
1703 break;
1704 }
1705}
David Lamparter6b0655a2014-06-04 06:53:35 +02001706
paul718e3742002-12-13 20:15:29 +00001707/* Display default rtm_table for all clients. */
1708DEFUN (show_table,
1709 show_table_cmd,
1710 "show table",
1711 SHOW_STR
1712 "default routing table to use for all clients\n")
1713{
paulb21b19c2003-06-15 01:28:29 +00001714 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001715 VTY_NEWLINE);
1716 return CMD_SUCCESS;
1717}
1718
1719DEFUN (config_table,
1720 config_table_cmd,
1721 "table TABLENO",
1722 "Configure target kernel routing table\n"
1723 "TABLE integer\n")
1724{
paulb21b19c2003-06-15 01:28:29 +00001725 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
paul718e3742002-12-13 20:15:29 +00001726 return CMD_SUCCESS;
1727}
1728
hasso647e4f12003-05-25 11:43:52 +00001729DEFUN (ip_forwarding,
1730 ip_forwarding_cmd,
1731 "ip forwarding",
1732 IP_STR
1733 "Turn on IP forwarding")
1734{
1735 int ret;
1736
1737 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001738 if (ret == 0)
1739 ret = ipforward_on ();
hasso647e4f12003-05-25 11:43:52 +00001740
hasso647e4f12003-05-25 11:43:52 +00001741 if (ret == 0)
1742 {
1743 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1744 return CMD_WARNING;
1745 }
1746
1747 return CMD_SUCCESS;
1748}
1749
paul718e3742002-12-13 20:15:29 +00001750DEFUN (no_ip_forwarding,
1751 no_ip_forwarding_cmd,
1752 "no ip forwarding",
1753 NO_STR
1754 IP_STR
1755 "Turn off IP forwarding")
1756{
1757 int ret;
1758
1759 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001760 if (ret != 0)
1761 ret = ipforward_off ();
paul718e3742002-12-13 20:15:29 +00001762
paul718e3742002-12-13 20:15:29 +00001763 if (ret != 0)
1764 {
1765 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1766 return CMD_WARNING;
1767 }
1768
1769 return CMD_SUCCESS;
1770}
1771
1772/* This command is for debugging purpose. */
1773DEFUN (show_zebra_client,
1774 show_zebra_client_cmd,
1775 "show zebra client",
1776 SHOW_STR
1777 "Zebra information"
1778 "Client information")
1779{
hasso52dc7ee2004-09-23 19:18:23 +00001780 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001781 struct zserv *client;
1782
paul1eb8ef22005-04-07 07:30:20 +00001783 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1784 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1785
paul718e3742002-12-13 20:15:29 +00001786 return CMD_SUCCESS;
1787}
1788
1789/* Table configuration write function. */
paulb9df2d22004-05-09 09:09:59 +00001790static int
paul718e3742002-12-13 20:15:29 +00001791config_write_table (struct vty *vty)
1792{
paulb21b19c2003-06-15 01:28:29 +00001793 if (zebrad.rtm_table_default)
1794 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001795 VTY_NEWLINE);
1796 return 0;
1797}
1798
1799/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001800static struct cmd_node table_node =
paul718e3742002-12-13 20:15:29 +00001801{
1802 TABLE_NODE,
1803 "", /* This node has no interface. */
1804 1
1805};
David Lamparter6b0655a2014-06-04 06:53:35 +02001806
paul718e3742002-12-13 20:15:29 +00001807/* Only display ip forwarding is enabled or not. */
1808DEFUN (show_ip_forwarding,
1809 show_ip_forwarding_cmd,
1810 "show ip forwarding",
1811 SHOW_STR
1812 IP_STR
1813 "IP forwarding status\n")
1814{
1815 int ret;
1816
1817 ret = ipforward ();
1818
1819 if (ret == 0)
1820 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1821 else
1822 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1823 return CMD_SUCCESS;
1824}
1825
1826#ifdef HAVE_IPV6
1827/* Only display ipv6 forwarding is enabled or not. */
1828DEFUN (show_ipv6_forwarding,
1829 show_ipv6_forwarding_cmd,
1830 "show ipv6 forwarding",
1831 SHOW_STR
1832 "IPv6 information\n"
1833 "Forwarding status\n")
1834{
1835 int ret;
1836
1837 ret = ipforward_ipv6 ();
1838
1839 switch (ret)
1840 {
1841 case -1:
1842 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1843 break;
1844 case 0:
1845 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1846 break;
1847 case 1:
1848 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1849 break;
1850 default:
1851 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1852 break;
1853 }
1854 return CMD_SUCCESS;
1855}
1856
hasso55906722004-02-11 22:42:16 +00001857DEFUN (ipv6_forwarding,
1858 ipv6_forwarding_cmd,
1859 "ipv6 forwarding",
1860 IPV6_STR
1861 "Turn on IPv6 forwarding")
1862{
1863 int ret;
1864
hasso41d3fc92004-04-06 11:59:00 +00001865 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001866 if (ret == 0)
1867 ret = ipforward_ipv6_on ();
hasso41d3fc92004-04-06 11:59:00 +00001868
hasso41d3fc92004-04-06 11:59:00 +00001869 if (ret == 0)
1870 {
hasso55906722004-02-11 22:42:16 +00001871 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1872 return CMD_WARNING;
1873 }
1874
1875 return CMD_SUCCESS;
1876}
1877
paul718e3742002-12-13 20:15:29 +00001878DEFUN (no_ipv6_forwarding,
1879 no_ipv6_forwarding_cmd,
1880 "no ipv6 forwarding",
1881 NO_STR
hasso55906722004-02-11 22:42:16 +00001882 IPV6_STR
1883 "Turn off IPv6 forwarding")
paul718e3742002-12-13 20:15:29 +00001884{
1885 int ret;
1886
hasso41d3fc92004-04-06 11:59:00 +00001887 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001888 if (ret != 0)
1889 ret = ipforward_ipv6_off ();
hasso41d3fc92004-04-06 11:59:00 +00001890
paul718e3742002-12-13 20:15:29 +00001891 if (ret != 0)
1892 {
1893 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1894 return CMD_WARNING;
1895 }
1896
1897 return CMD_SUCCESS;
1898}
1899
1900#endif /* HAVE_IPV6 */
1901
1902/* IPForwarding configuration write function. */
ajs719e9742005-02-28 20:52:15 +00001903static int
paul718e3742002-12-13 20:15:29 +00001904config_write_forwarding (struct vty *vty)
1905{
hasso18a6dce2004-10-03 18:18:34 +00001906 /* FIXME: Find better place for that. */
1907 router_id_write (vty);
1908
paul3e0b3a52004-08-23 18:58:32 +00001909 if (ipforward ())
1910 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001911#ifdef HAVE_IPV6
paul3e0b3a52004-08-23 18:58:32 +00001912 if (ipforward_ipv6 ())
1913 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001914#endif /* HAVE_IPV6 */
1915 vty_out (vty, "!%s", VTY_NEWLINE);
1916 return 0;
1917}
1918
1919/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001920static struct cmd_node forwarding_node =
paul718e3742002-12-13 20:15:29 +00001921{
1922 FORWARDING_NODE,
1923 "", /* This node has no interface. */
1924 1
1925};
1926
David Lamparter6b0655a2014-06-04 06:53:35 +02001927
paul718e3742002-12-13 20:15:29 +00001928/* Initialisation of zebra and installation of commands. */
1929void
paula1ac18c2005-06-28 17:17:12 +00001930zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001931{
1932 /* Client list init. */
paulb21b19c2003-06-15 01:28:29 +00001933 zebrad.client_list = list_new ();
paul718e3742002-12-13 20:15:29 +00001934
paul718e3742002-12-13 20:15:29 +00001935 /* Install configuration write function. */
1936 install_node (&table_node, config_write_table);
1937 install_node (&forwarding_node, config_write_forwarding);
1938
1939 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1940 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00001941 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001942 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1943 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1944
1945#ifdef HAVE_NETLINK
1946 install_element (VIEW_NODE, &show_table_cmd);
1947 install_element (ENABLE_NODE, &show_table_cmd);
1948 install_element (CONFIG_NODE, &config_table_cmd);
1949#endif /* HAVE_NETLINK */
1950
1951#ifdef HAVE_IPV6
1952 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1953 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
hasso55906722004-02-11 22:42:16 +00001954 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001955 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1956#endif /* HAVE_IPV6 */
Paul Jakma7514fb72007-05-02 16:05:35 +00001957
1958 /* Route-map */
1959 zebra_route_map_init ();
paul718e3742002-12-13 20:15:29 +00001960}
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001961
1962/* Make zebra server socket, wiping any existing one (see bug #403). */
1963void
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04001964zebra_zserv_socket_init (char *path)
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001965{
1966#ifdef HAVE_TCP_ZEBRA
1967 zebra_serv ();
1968#else
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04001969 zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001970#endif /* HAVE_TCP_ZEBRA */
1971}