blob: 6e65aa1573c95d12bd2f5cf05c2421d8be2291b2 [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"
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -050040#include "nexthop.h"
paul718e3742002-12-13 20:15:29 +000041
42#include "zebra/zserv.h"
hasso18a6dce2004-10-03 18:18:34 +000043#include "zebra/router-id.h"
paul718e3742002-12-13 20:15:29 +000044#include "zebra/redistribute.h"
45#include "zebra/debug.h"
46#include "zebra/ipforward.h"
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -050047#include "zebra/zebra_rnh.h"
David Lamparter6b0655a2014-06-04 06:53:35 +020048
paul718e3742002-12-13 20:15:29 +000049/* Event list of zebra. */
50enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
51
paulb21b19c2003-06-15 01:28:29 +000052extern struct zebra_t zebrad;
paul718e3742002-12-13 20:15:29 +000053
paulb9df2d22004-05-09 09:09:59 +000054static void zebra_event (enum event event, int sock, struct zserv *client);
paulccf35572003-03-01 11:42:20 +000055
pauledd7c242003-06-04 13:59:38 +000056extern struct zebra_privs_t zserv_privs;
David Lamparter6b0655a2014-06-04 06:53:35 +020057
ajs719e9742005-02-28 20:52:15 +000058static void zebra_client_close (struct zserv *client);
59
60static int
61zserv_delayed_close(struct thread *thread)
paulccf35572003-03-01 11:42:20 +000062{
ajs719e9742005-02-28 20:52:15 +000063 struct zserv *client = THREAD_ARG(thread);
paulccf35572003-03-01 11:42:20 +000064
ajs719e9742005-02-28 20:52:15 +000065 client->t_suicide = NULL;
66 zebra_client_close(client);
paulccf35572003-03-01 11:42:20 +000067 return 0;
68}
69
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +040070/* When client connects, it sends hello message
71 * with promise to send zebra routes of specific type.
72 * Zebra stores a socket fd of the client into
73 * this array. And use it to clean up routes that
74 * client didn't remove for some reasons after closing
75 * connection.
76 */
77static int route_type_oaths[ZEBRA_ROUTE_MAX];
78
ajs719e9742005-02-28 20:52:15 +000079static int
80zserv_flush_data(struct thread *thread)
paulccf35572003-03-01 11:42:20 +000081{
ajs719e9742005-02-28 20:52:15 +000082 struct zserv *client = THREAD_ARG(thread);
paulccf35572003-03-01 11:42:20 +000083
ajs719e9742005-02-28 20:52:15 +000084 client->t_write = NULL;
85 if (client->t_suicide)
86 {
87 zebra_client_close(client);
88 return -1;
89 }
90 switch (buffer_flush_available(client->wb, client->sock))
91 {
92 case BUFFER_ERROR:
93 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
94 "closing", __func__, client->sock);
95 zebra_client_close(client);
96 break;
97 case BUFFER_PENDING:
98 client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
99 client, client->sock);
100 break;
101 case BUFFER_EMPTY:
102 break;
103 }
104 return 0;
paulccf35572003-03-01 11:42:20 +0000105}
106
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500107int
ajs719e9742005-02-28 20:52:15 +0000108zebra_server_send_message(struct zserv *client)
paulccf35572003-03-01 11:42:20 +0000109{
ajs719e9742005-02-28 20:52:15 +0000110 if (client->t_suicide)
111 return -1;
112 switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
113 stream_get_endp(client->obuf)))
paulccf35572003-03-01 11:42:20 +0000114 {
ajs719e9742005-02-28 20:52:15 +0000115 case BUFFER_ERROR:
116 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
117 __func__, client->sock);
118 /* Schedule a delayed close since many of the functions that call this
119 one do not check the return code. They do not allow for the
120 possibility that an I/O error may have caused the client to be
121 deleted. */
122 client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
123 client, 0);
124 return -1;
ajs719e9742005-02-28 20:52:15 +0000125 case BUFFER_EMPTY:
126 THREAD_OFF(client->t_write);
127 break;
128 case BUFFER_PENDING:
129 THREAD_WRITE_ON(zebrad.master, client->t_write,
130 zserv_flush_data, client, client->sock);
131 break;
paulccf35572003-03-01 11:42:20 +0000132 }
paulccf35572003-03-01 11:42:20 +0000133 return 0;
134}
135
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500136void
Feng Luc99f3482014-10-16 09:52:36 +0800137zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
paulc1b98002006-01-16 01:54:02 +0000138{
139 /* length placeholder, caller can update */
140 stream_putw (s, ZEBRA_HEADER_SIZE);
141 stream_putc (s, ZEBRA_HEADER_MARKER);
142 stream_putc (s, ZSERV_VERSION);
Feng Luc99f3482014-10-16 09:52:36 +0800143 stream_putw (s, vrf_id);
paulc1b98002006-01-16 01:54:02 +0000144 stream_putw (s, cmd);
145}
146
Josh Bailey51d4ef82012-03-21 17:13:39 -0700147static void
148zserv_encode_interface (struct stream *s, struct interface *ifp)
149{
150 /* Interface information. */
151 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
152 stream_putl (s, ifp->ifindex);
153 stream_putc (s, ifp->status);
154 stream_putq (s, ifp->flags);
155 stream_putl (s, ifp->metric);
156 stream_putl (s, ifp->mtu);
157 stream_putl (s, ifp->mtu6);
158 stream_putl (s, ifp->bandwidth);
Timo Teräs954c7d62016-01-15 17:36:33 +0200159 stream_putl (s, ifp->ll_type);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700160 stream_putl (s, ifp->hw_addr_len);
161 if (ifp->hw_addr_len)
162 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700163
Olivier Dugeon15773a82016-04-19 18:29:55 +0200164 zlog_info("Try to set TE Link Param");
165 /* Then, Traffic Engineering parameters if any */
166 if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params))
167 {
168 stream_putc (s, 1);
169 zebra_interface_link_params_write (s, ifp);
170 }
171 else
172 stream_putc (s, 0);
173
Josh Bailey51d4ef82012-03-21 17:13:39 -0700174 /* Write packet size. */
175 stream_putw_at (s, 0, stream_get_endp (s));
176}
177
paul718e3742002-12-13 20:15:29 +0000178/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
paulb9df2d22004-05-09 09:09:59 +0000179/*
180 * This function is called in the following situations:
181 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
182 * from the client.
183 * - at startup, when zebra figures out the available interfaces
184 * - when an interface is added (where support for
185 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
186 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
187 * received)
188 */
paul718e3742002-12-13 20:15:29 +0000189int
190zsend_interface_add (struct zserv *client, struct interface *ifp)
191{
192 struct stream *s;
193
194 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800195 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000196 return 0;
paul718e3742002-12-13 20:15:29 +0000197
198 s = client->obuf;
199 stream_reset (s);
200
Feng Luc99f3482014-10-16 09:52:36 +0800201 zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700202 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000203
ajs719e9742005-02-28 20:52:15 +0000204 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000205}
206
207/* Interface deletion from zebra daemon. */
208int
209zsend_interface_delete (struct zserv *client, struct interface *ifp)
210{
211 struct stream *s;
212
213 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800214 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000215 return 0;
paul718e3742002-12-13 20:15:29 +0000216
217 s = client->obuf;
218 stream_reset (s);
paul718e3742002-12-13 20:15:29 +0000219
Feng Luc99f3482014-10-16 09:52:36 +0800220 zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700221 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000222
ajs719e9742005-02-28 20:52:15 +0000223 return zebra_server_send_message (client);
paul718e3742002-12-13 20:15:29 +0000224}
225
Olivier Dugeon15773a82016-04-19 18:29:55 +0200226int
227zsend_interface_link_params (struct zserv *client, struct interface *ifp)
228{
229 struct stream *s;
230
231 /* Check this client need interface information. */
232 if (! client->ifinfo)
233 return 0;
234
235 if (!ifp->link_params)
236 return 0;
237 s = client->obuf;
238 stream_reset (s);
239
240 zserv_create_header (s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id);
241
242 /* Add Interface Index */
243 stream_putl (s, ifp->ifindex);
244
245 /* Then TE Link Parameters */
246 if (zebra_interface_link_params_write (s, ifp) == 0)
247 return 0;
248
249 /* Write packet size. */
250 stream_putw_at (s, 0, stream_get_endp (s));
251
252 return zebra_server_send_message (client);
253}
254
paulb9df2d22004-05-09 09:09:59 +0000255/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
256 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
257 *
258 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
259 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
260 * from the client, after the ZEBRA_INTERFACE_ADD has been
261 * sent from zebra to the client
262 * - redistribute new address info to all clients in the following situations
263 * - at startup, when zebra figures out the available interfaces
264 * - when an interface is added (where support for
265 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
266 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
267 * received)
268 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
269 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
270 * - when an RTM_NEWADDR message is received from the kernel,
271 *
272 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
273 *
274 * zsend_interface_address(DELETE)
275 * ^
276 * |
277 * zebra_interface_address_delete_update
278 * ^ ^ ^
paul6eb88272005-07-29 14:36:00 +0000279 * | | if_delete_update
280 * | |
paulb9df2d22004-05-09 09:09:59 +0000281 * ip_address_uninstall connected_delete_ipv4
282 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
283 * ^ ^
284 * | |
285 * | RTM_NEWADDR on routing/netlink socket
286 * |
287 * vty commands:
288 * "no ip address A.B.C.D/M [label LINE]"
289 * "no ip address A.B.C.D/M secondary"
290 * ["no ipv6 address X:X::X:X/M"]
291 *
292 */
paul718e3742002-12-13 20:15:29 +0000293int
paulb9df2d22004-05-09 09:09:59 +0000294zsend_interface_address (int cmd, struct zserv *client,
295 struct interface *ifp, struct connected *ifc)
paul718e3742002-12-13 20:15:29 +0000296{
297 int blen;
298 struct stream *s;
299 struct prefix *p;
300
301 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800302 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000303 return 0;
paul718e3742002-12-13 20:15:29 +0000304
305 s = client->obuf;
306 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000307
Feng Luc99f3482014-10-16 09:52:36 +0800308 zserv_create_header (s, cmd, ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000309 stream_putl (s, ifp->ifindex);
310
311 /* Interface address flag. */
312 stream_putc (s, ifc->flags);
313
314 /* Prefix information. */
315 p = ifc->address;
316 stream_putc (s, p->family);
317 blen = prefix_blen (p);
318 stream_put (s, &p->u.prefix, blen);
paulb9df2d22004-05-09 09:09:59 +0000319
320 /*
321 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
322 * but zebra_interface_address_delete_read() in the gnu version
323 * expects to find it
324 */
paul718e3742002-12-13 20:15:29 +0000325 stream_putc (s, p->prefixlen);
326
327 /* Destination. */
328 p = ifc->destination;
329 if (p)
330 stream_put (s, &p->u.prefix, blen);
331 else
332 stream_put (s, NULL, blen);
333
334 /* Write packet size. */
335 stream_putw_at (s, 0, stream_get_endp (s));
336
ajs719e9742005-02-28 20:52:15 +0000337 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000338}
339
paulb9df2d22004-05-09 09:09:59 +0000340/*
341 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
342 * ZEBRA_INTERFACE_DOWN.
343 *
344 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
345 * the clients in one of 2 situations:
346 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
347 * - a vty command modifying the bandwidth of an interface is received.
348 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
349 */
paul718e3742002-12-13 20:15:29 +0000350int
paulb9df2d22004-05-09 09:09:59 +0000351zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000352{
353 struct stream *s;
354
355 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800356 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
ajs719e9742005-02-28 20:52:15 +0000357 return 0;
paul718e3742002-12-13 20:15:29 +0000358
359 s = client->obuf;
360 stream_reset (s);
361
Feng Luc99f3482014-10-16 09:52:36 +0800362 zserv_create_header (s, cmd, ifp->vrf_id);
Josh Bailey51d4ef82012-03-21 17:13:39 -0700363 zserv_encode_interface (s, ifp);
paul718e3742002-12-13 20:15:29 +0000364
ajs719e9742005-02-28 20:52:15 +0000365 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000366}
367
paulb9df2d22004-05-09 09:09:59 +0000368/*
369 * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
370 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
371 * situations:
372 * - when the client starts up, and requests default information
373 * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
374 * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
375 * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
376 * - when the zebra server redistributes routes after it updates its rib
377 *
378 * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
379 * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
380 * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
381 * - deleted from zebra's rib, and this info
382 * has to be redistributed to the clients
383 *
384 * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
385 * zebra server when the client wants to tell the zebra server to add a
386 * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
387 * same message being sent back and forth, this function and
388 * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
389 * duplication.
390 */
paul718e3742002-12-13 20:15:29 +0000391int
paulb9df2d22004-05-09 09:09:59 +0000392zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
393 struct rib *rib)
paul718e3742002-12-13 20:15:29 +0000394{
395 int psize;
396 struct stream *s;
397 struct nexthop *nexthop;
paul1dcb5172005-05-31 08:38:50 +0000398 unsigned long nhnummark = 0, messmark = 0;
paulb9df2d22004-05-09 09:09:59 +0000399 int nhnum = 0;
paul1dcb5172005-05-31 08:38:50 +0000400 u_char zapi_flags = 0;
Feng Luc99f3482014-10-16 09:52:36 +0800401
402 /* Check this client need this route. */
403 if (!vrf_bitmap_check (client->redist[rib->type], rib->vrf_id) &&
404 !(is_default (p) &&
405 vrf_bitmap_check (client->redist_default, rib->vrf_id)))
406 return 0;
407
paul718e3742002-12-13 20:15:29 +0000408 s = client->obuf;
409 stream_reset (s);
paulc1b98002006-01-16 01:54:02 +0000410
Feng Luc99f3482014-10-16 09:52:36 +0800411 zserv_create_header (s, cmd, rib->vrf_id);
paulc1b98002006-01-16 01:54:02 +0000412
413 /* Put type and nexthop. */
paul718e3742002-12-13 20:15:29 +0000414 stream_putc (s, rib->type);
415 stream_putc (s, rib->flags);
paul1dcb5172005-05-31 08:38:50 +0000416
417 /* marker for message flags field */
418 messmark = stream_get_endp (s);
419 stream_putc (s, 0);
paul718e3742002-12-13 20:15:29 +0000420
421 /* Prefix. */
422 psize = PSIZE (p->prefixlen);
423 stream_putc (s, p->prefixlen);
paulb9df2d22004-05-09 09:09:59 +0000424 stream_write (s, (u_char *) & p->u.prefix, psize);
paul718e3742002-12-13 20:15:29 +0000425
paulb9df2d22004-05-09 09:09:59 +0000426 /*
427 * XXX The message format sent by zebra below does not match the format
428 * of the corresponding message expected by the zebra server
429 * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
430 * (is there a bug on the client side if more than one segment is sent?)
431 * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
432 * is hard-coded.
433 */
paul718e3742002-12-13 20:15:29 +0000434 /* Nexthop */
paul1dcb5172005-05-31 08:38:50 +0000435
paul718e3742002-12-13 20:15:29 +0000436 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
437 {
Timo Teräs325823a2016-01-15 17:36:31 +0200438 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paulb9df2d22004-05-09 09:09:59 +0000439 {
paul1dcb5172005-05-31 08:38:50 +0000440 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
441 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
442
443 if (nhnummark == 0)
444 {
445 nhnummark = stream_get_endp (s);
446 stream_putc (s, 1); /* placeholder */
447 }
448
paulb9df2d22004-05-09 09:09:59 +0000449 nhnum++;
paul718e3742002-12-13 20:15:29 +0000450
paulb9df2d22004-05-09 09:09:59 +0000451 switch(nexthop->type)
452 {
453 case NEXTHOP_TYPE_IPV4:
454 case NEXTHOP_TYPE_IPV4_IFINDEX:
455 stream_put_in_addr (s, &nexthop->gate.ipv4);
456 break;
457#ifdef HAVE_IPV6
458 case NEXTHOP_TYPE_IPV6:
459 case NEXTHOP_TYPE_IPV6_IFINDEX:
460 case NEXTHOP_TYPE_IPV6_IFNAME:
461 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
462 break;
463#endif
464 default:
465 if (cmd == ZEBRA_IPV4_ROUTE_ADD
466 || cmd == ZEBRA_IPV4_ROUTE_DELETE)
467 {
468 struct in_addr empty;
paul44983cf2004-09-22 13:15:58 +0000469 memset (&empty, 0, sizeof (struct in_addr));
paulb9df2d22004-05-09 09:09:59 +0000470 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
471 }
472 else
473 {
474 struct in6_addr empty;
475 memset (&empty, 0, sizeof (struct in6_addr));
476 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
477 }
478 }
paul718e3742002-12-13 20:15:29 +0000479
paulb9df2d22004-05-09 09:09:59 +0000480 /* Interface index. */
481 stream_putc (s, 1);
482 stream_putl (s, nexthop->ifindex);
paul718e3742002-12-13 20:15:29 +0000483
paulb9df2d22004-05-09 09:09:59 +0000484 break;
485 }
paul718e3742002-12-13 20:15:29 +0000486 }
487
488 /* Metric */
Stephen Hemmingercf8a8312010-08-18 15:56:46 -0700489 if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
paul1dcb5172005-05-31 08:38:50 +0000490 {
vincentfbf5d032005-09-29 11:25:50 +0000491 SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
492 stream_putc (s, rib->distance);
paul1dcb5172005-05-31 08:38:50 +0000493 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
494 stream_putl (s, rib->metric);
Timo Teräsb11f3b52015-11-02 16:50:07 +0200495 SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
496 stream_putl (s, rib->mtu);
paul1dcb5172005-05-31 08:38:50 +0000497 }
498
499 /* write real message flags value */
500 stream_putc_at (s, messmark, zapi_flags);
501
paulb9df2d22004-05-09 09:09:59 +0000502 /* Write next-hop number */
503 if (nhnummark)
hassoc1eaa442004-10-19 06:26:01 +0000504 stream_putc_at (s, nhnummark, nhnum);
paulb9df2d22004-05-09 09:09:59 +0000505
paul718e3742002-12-13 20:15:29 +0000506 /* Write packet size. */
507 stream_putw_at (s, 0, stream_get_endp (s));
508
ajs719e9742005-02-28 20:52:15 +0000509 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000510}
511
paul718e3742002-12-13 20:15:29 +0000512#ifdef HAVE_IPV6
ajs719e9742005-02-28 20:52:15 +0000513static int
Feng Luc99f3482014-10-16 09:52:36 +0800514zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
515 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000516{
517 struct stream *s;
518 struct rib *rib;
519 unsigned long nump;
520 u_char num;
521 struct nexthop *nexthop;
522
523 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800524 rib = rib_match_ipv6 (addr, vrf_id);
paul718e3742002-12-13 20:15:29 +0000525
526 /* Get output stream. */
527 s = client->obuf;
528 stream_reset (s);
529
530 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800531 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
Hiroshi Yokoi8ccd74c2015-09-08 11:52:20 +0900532 stream_put (s, addr, 16);
paul718e3742002-12-13 20:15:29 +0000533
534 if (rib)
535 {
536 stream_putl (s, rib->metric);
537 num = 0;
paul9985f832005-02-09 15:51:56 +0000538 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000539 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000540 /* Only non-recursive routes are elegible to resolve nexthop we
541 * are looking up. Therefore, we will just iterate over the top
542 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000543 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200544 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000545 {
546 stream_putc (s, nexthop->type);
547 switch (nexthop->type)
548 {
549 case ZEBRA_NEXTHOP_IPV6:
550 stream_put (s, &nexthop->gate.ipv6, 16);
551 break;
552 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
553 case ZEBRA_NEXTHOP_IPV6_IFNAME:
554 stream_put (s, &nexthop->gate.ipv6, 16);
555 stream_putl (s, nexthop->ifindex);
556 break;
557 case ZEBRA_NEXTHOP_IFINDEX:
558 case ZEBRA_NEXTHOP_IFNAME:
559 stream_putl (s, nexthop->ifindex);
560 break;
hassofa2b17e2004-03-04 17:45:00 +0000561 default:
562 /* do nothing */
563 break;
paul718e3742002-12-13 20:15:29 +0000564 }
565 num++;
566 }
567 stream_putc_at (s, nump, num);
568 }
569 else
570 {
571 stream_putl (s, 0);
572 stream_putc (s, 0);
573 }
574
575 stream_putw_at (s, 0, stream_get_endp (s));
576
ajs719e9742005-02-28 20:52:15 +0000577 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000578}
579#endif /* HAVE_IPV6 */
580
paulb9df2d22004-05-09 09:09:59 +0000581static int
Feng Luc99f3482014-10-16 09:52:36 +0800582zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
583 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000584{
585 struct stream *s;
586 struct rib *rib;
587 unsigned long nump;
588 u_char num;
589 struct nexthop *nexthop;
590
David Lamparterf598cf72014-11-22 14:44:20 -0800591 /* Lookup nexthop - eBGP excluded */
Feng Luc99f3482014-10-16 09:52:36 +0800592 rib = rib_match_ipv4_safi (addr, SAFI_UNICAST, 1, NULL, vrf_id);
paul718e3742002-12-13 20:15:29 +0000593
594 /* Get output stream. */
595 s = client->obuf;
596 stream_reset (s);
597
598 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800599 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000600 stream_put_in_addr (s, &addr);
601
602 if (rib)
603 {
Christian Frankebb97e462013-05-25 14:01:35 +0000604 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
605 zlog_debug("%s: Matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000606 stream_putl (s, rib->metric);
607 num = 0;
paul9985f832005-02-09 15:51:56 +0000608 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000609 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000610 /* Only non-recursive routes are elegible to resolve the nexthop we
611 * are looking up. Therefore, we will just iterate over the top
612 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000613 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200614 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000615 {
616 stream_putc (s, nexthop->type);
617 switch (nexthop->type)
618 {
619 case ZEBRA_NEXTHOP_IPV4:
620 stream_put_in_addr (s, &nexthop->gate.ipv4);
621 break;
Christian Frankebb97e462013-05-25 14:01:35 +0000622 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
623 stream_put_in_addr (s, &nexthop->gate.ipv4);
624 stream_putl (s, nexthop->ifindex);
625 break;
paul718e3742002-12-13 20:15:29 +0000626 case ZEBRA_NEXTHOP_IFINDEX:
627 case ZEBRA_NEXTHOP_IFNAME:
628 stream_putl (s, nexthop->ifindex);
629 break;
hassofa2b17e2004-03-04 17:45:00 +0000630 default:
631 /* do nothing */
632 break;
paul718e3742002-12-13 20:15:29 +0000633 }
634 num++;
635 }
636 stream_putc_at (s, nump, num);
637 }
638 else
639 {
Christian Frankebb97e462013-05-25 14:01:35 +0000640 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
641 zlog_debug("%s: No matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000642 stream_putl (s, 0);
643 stream_putc (s, 0);
644 }
645
646 stream_putw_at (s, 0, stream_get_endp (s));
647
ajs719e9742005-02-28 20:52:15 +0000648 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000649}
650
Everton Marques4e5275b2014-07-01 15:15:52 -0300651/*
652 Modified version of zsend_ipv4_nexthop_lookup():
653 Query unicast rib if nexthop is not found on mrib.
654 Returns both route metric and protocol distance.
655*/
656static int
David Lamparterbd078122015-01-06 19:53:24 +0100657zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr,
658 struct rib *rib)
Everton Marques4e5275b2014-07-01 15:15:52 -0300659{
660 struct stream *s;
Everton Marques4e5275b2014-07-01 15:15:52 -0300661 unsigned long nump;
662 u_char num;
663 struct nexthop *nexthop;
Everton Marques4e5275b2014-07-01 15:15:52 -0300664
665 /* Get output stream. */
666 s = client->obuf;
667 stream_reset (s);
668
669 /* Fill in result. */
Jafar Al-Gharaibeh190591f2016-04-21 17:40:12 -0500670 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB,
671 rib ? rib->vrf_id : VRF_DEFAULT);
Everton Marques4e5275b2014-07-01 15:15:52 -0300672 stream_put_in_addr (s, &addr);
673
674 if (rib)
675 {
676 stream_putc (s, rib->distance);
677 stream_putl (s, rib->metric);
678 num = 0;
679 nump = stream_get_endp(s); /* remember position for nexthop_num */
680 stream_putc (s, 0); /* reserve room for nexthop_num */
681 /* Only non-recursive routes are elegible to resolve the nexthop we
682 * are looking up. Therefore, we will just iterate over the top
683 * chain of nexthops. */
684 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200685 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
Everton Marques4e5275b2014-07-01 15:15:52 -0300686 {
687 stream_putc (s, nexthop->type);
688 switch (nexthop->type)
689 {
690 case ZEBRA_NEXTHOP_IPV4:
691 stream_put_in_addr (s, &nexthop->gate.ipv4);
692 break;
693 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
694 stream_put_in_addr (s, &nexthop->gate.ipv4);
695 stream_putl (s, nexthop->ifindex);
696 break;
697 case ZEBRA_NEXTHOP_IFINDEX:
698 case ZEBRA_NEXTHOP_IFNAME:
699 stream_putl (s, nexthop->ifindex);
700 break;
701 default:
702 /* do nothing */
703 break;
704 }
705 num++;
706 }
707
708 stream_putc_at (s, nump, num); /* store nexthop_num */
709 }
710 else
711 {
712 stream_putc (s, 0); /* distance */
713 stream_putl (s, 0); /* metric */
714 stream_putc (s, 0); /* nexthop_num */
715 }
716
717 stream_putw_at (s, 0, stream_get_endp (s));
718
719 return zebra_server_send_message(client);
720}
721
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500722/* Nexthop register */
723static int
724zserv_nexthop_register (struct zserv *client, int sock, u_short length, vrf_id_t vrf_id)
725{
726 struct rnh *rnh;
727 struct stream *s;
728 struct prefix p;
729 u_short l = 0;
730
731 if (IS_ZEBRA_DEBUG_NHT)
732 zlog_debug("nexthop_register msg from client %s: length=%d\n",
733 zebra_route_string(client->proto), length);
734
735 s = client->ibuf;
736
737 while (l < length)
738 {
739 p.family = stream_getw(s);
740 p.prefixlen = stream_getc(s);
741 l += 3;
742 stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
743 l += PSIZE(p.prefixlen);
744 rnh = zebra_add_rnh(&p, 0);
745 zebra_add_rnh_client(rnh, client, vrf_id);
746 }
747 zebra_evaluate_rnh_table(0, AF_INET);
748 zebra_evaluate_rnh_table(0, AF_INET6);
749 return 0;
750}
751
752/* Nexthop register */
753static int
754zserv_nexthop_unregister (struct zserv *client, int sock, u_short length)
755{
756 struct rnh *rnh;
757 struct stream *s;
758 struct prefix p;
759 u_short l = 0;
760
761 if (IS_ZEBRA_DEBUG_NHT)
762 zlog_debug("nexthop_unregister msg from client %s: length=%d\n",
763 zebra_route_string(client->proto), length);
764
765 s = client->ibuf;
766
767 while (l < length)
768 {
769 p.family = stream_getw(s);
770 p.prefixlen = stream_getc(s);
771 l += 3;
772 stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
773 l += PSIZE(p.prefixlen);
774 rnh = zebra_lookup_rnh(&p, 0);
775 if (rnh)
776 zebra_remove_rnh_client(rnh, client);
777 }
778 return 0;
779}
780
paulb9df2d22004-05-09 09:09:59 +0000781static int
Feng Luc99f3482014-10-16 09:52:36 +0800782zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
783 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000784{
785 struct stream *s;
786 struct rib *rib;
787 unsigned long nump;
788 u_char num;
789 struct nexthop *nexthop;
790
791 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800792 rib = rib_lookup_ipv4 (p, vrf_id);
paul718e3742002-12-13 20:15:29 +0000793
794 /* Get output stream. */
795 s = client->obuf;
796 stream_reset (s);
797
798 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800799 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000800 stream_put_in_addr (s, &p->prefix);
801
802 if (rib)
803 {
804 stream_putl (s, rib->metric);
805 num = 0;
paul9985f832005-02-09 15:51:56 +0000806 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000807 stream_putc (s, 0);
808 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Timo Teräs325823a2016-01-15 17:36:31 +0200809 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000810 {
811 stream_putc (s, nexthop->type);
812 switch (nexthop->type)
813 {
814 case ZEBRA_NEXTHOP_IPV4:
815 stream_put_in_addr (s, &nexthop->gate.ipv4);
816 break;
Christian Frankea12afd52013-05-25 14:01:36 +0000817 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
818 stream_put_in_addr (s, &nexthop->gate.ipv4);
819 stream_putl (s, nexthop->ifindex);
820 break;
paul718e3742002-12-13 20:15:29 +0000821 case ZEBRA_NEXTHOP_IFINDEX:
822 case ZEBRA_NEXTHOP_IFNAME:
823 stream_putl (s, nexthop->ifindex);
824 break;
hassofa2b17e2004-03-04 17:45:00 +0000825 default:
826 /* do nothing */
827 break;
paul718e3742002-12-13 20:15:29 +0000828 }
829 num++;
830 }
831 stream_putc_at (s, nump, num);
832 }
833 else
834 {
835 stream_putl (s, 0);
836 stream_putc (s, 0);
837 }
838
839 stream_putw_at (s, 0, stream_get_endp (s));
840
ajs719e9742005-02-28 20:52:15 +0000841 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000842}
David Lamparter6b0655a2014-06-04 06:53:35 +0200843
hasso18a6dce2004-10-03 18:18:34 +0000844/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
845int
Feng Luac19a442015-05-22 11:40:07 +0200846zsend_router_id_update (struct zserv *client, struct prefix *p,
847 vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +0000848{
849 struct stream *s;
850 int blen;
851
852 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800853 if (! vrf_bitmap_check (client->ridinfo, vrf_id))
ajs719e9742005-02-28 20:52:15 +0000854 return 0;
hasso18a6dce2004-10-03 18:18:34 +0000855
856 s = client->obuf;
857 stream_reset (s);
858
hasso18a6dce2004-10-03 18:18:34 +0000859 /* Message type. */
Feng Luc99f3482014-10-16 09:52:36 +0800860 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +0000861
862 /* Prefix information. */
863 stream_putc (s, p->family);
864 blen = prefix_blen (p);
865 stream_put (s, &p->u.prefix, blen);
866 stream_putc (s, p->prefixlen);
867
868 /* Write packet size. */
869 stream_putw_at (s, 0, stream_get_endp (s));
870
ajs719e9742005-02-28 20:52:15 +0000871 return zebra_server_send_message(client);
hasso18a6dce2004-10-03 18:18:34 +0000872}
David Lamparter6b0655a2014-06-04 06:53:35 +0200873
paul718e3742002-12-13 20:15:29 +0000874/* Register zebra server interface information. Send current all
875 interface and address information. */
ajs719e9742005-02-28 20:52:15 +0000876static int
Feng Luc99f3482014-10-16 09:52:36 +0800877zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000878{
paul1eb8ef22005-04-07 07:30:20 +0000879 struct listnode *ifnode, *ifnnode;
880 struct listnode *cnode, *cnnode;
paul718e3742002-12-13 20:15:29 +0000881 struct interface *ifp;
882 struct connected *c;
883
884 /* Interface information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +0800885 vrf_bitmap_set (client->ifinfo, vrf_id);
paul718e3742002-12-13 20:15:29 +0000886
Feng Luc99f3482014-10-16 09:52:36 +0800887 for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
paul718e3742002-12-13 20:15:29 +0000888 {
paul718e3742002-12-13 20:15:29 +0000889 /* Skip pseudo interface. */
890 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
891 continue;
892
ajs719e9742005-02-28 20:52:15 +0000893 if (zsend_interface_add (client, ifp) < 0)
894 return -1;
paul718e3742002-12-13 20:15:29 +0000895
paul1eb8ef22005-04-07 07:30:20 +0000896 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
paul718e3742002-12-13 20:15:29 +0000897 {
ajs719e9742005-02-28 20:52:15 +0000898 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
899 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
900 ifp, c) < 0))
901 return -1;
paul718e3742002-12-13 20:15:29 +0000902 }
903 }
ajs719e9742005-02-28 20:52:15 +0000904 return 0;
paul718e3742002-12-13 20:15:29 +0000905}
906
907/* Unregister zebra server interface information. */
ajs719e9742005-02-28 20:52:15 +0000908static int
Feng Luc99f3482014-10-16 09:52:36 +0800909zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000910{
Feng Luc99f3482014-10-16 09:52:36 +0800911 vrf_bitmap_unset (client->ifinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +0000912 return 0;
paul718e3742002-12-13 20:15:29 +0000913}
914
915/* This function support multiple nexthop. */
paulb9df2d22004-05-09 09:09:59 +0000916/*
917 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
918 * add kernel route.
919 */
ajs719e9742005-02-28 20:52:15 +0000920static int
Feng Luc99f3482014-10-16 09:52:36 +0800921zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000922{
923 int i;
924 struct rib *rib;
925 struct prefix_ipv4 p;
926 u_char message;
927 struct in_addr nexthop;
928 u_char nexthop_num;
929 u_char nexthop_type;
930 struct stream *s;
Paul Jakma9099f9b2016-01-18 10:12:10 +0000931 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000932 u_char ifname_len;
G.Balajicddf3912011-11-26 21:59:32 +0400933 safi_t safi;
934
paul718e3742002-12-13 20:15:29 +0000935
936 /* Get input stream. */
937 s = client->ibuf;
938
939 /* Allocate new rib. */
paul4d38fdb2005-04-28 17:35:14 +0000940 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
941
paul718e3742002-12-13 20:15:29 +0000942 /* Type, flags, message. */
943 rib->type = stream_getc (s);
944 rib->flags = stream_getc (s);
paulb9df2d22004-05-09 09:09:59 +0000945 message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400946 safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000947 rib->uptime = time (NULL);
948
949 /* IPv4 prefix. */
950 memset (&p, 0, sizeof (struct prefix_ipv4));
951 p.family = AF_INET;
952 p.prefixlen = stream_getc (s);
953 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
954
Feng Lu0d0686f2015-05-22 11:40:02 +0200955 /* VRF ID */
Feng Luc99f3482014-10-16 09:52:36 +0800956 rib->vrf_id = vrf_id;
Feng Lu0d0686f2015-05-22 11:40:02 +0200957
paul718e3742002-12-13 20:15:29 +0000958 /* Nexthop parse. */
959 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
960 {
961 nexthop_num = stream_getc (s);
962
963 for (i = 0; i < nexthop_num; i++)
964 {
965 nexthop_type = stream_getc (s);
966
967 switch (nexthop_type)
968 {
969 case ZEBRA_NEXTHOP_IFINDEX:
970 ifindex = stream_getl (s);
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500971 rib_nexthop_ifindex_add (rib, ifindex);
paul718e3742002-12-13 20:15:29 +0000972 break;
973 case ZEBRA_NEXTHOP_IFNAME:
974 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000975 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000976 break;
977 case ZEBRA_NEXTHOP_IPV4:
978 nexthop.s_addr = stream_get_ipv4 (s);
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500979 rib_nexthop_ipv4_add (rib, &nexthop, NULL);
paul718e3742002-12-13 20:15:29 +0000980 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200981 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
982 nexthop.s_addr = stream_get_ipv4 (s);
983 ifindex = stream_getl (s);
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500984 rib_nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200985 break;
paul718e3742002-12-13 20:15:29 +0000986 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000987 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000988 break;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700989 case ZEBRA_NEXTHOP_BLACKHOLE:
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -0500990 rib_nexthop_blackhole_add (rib);
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700991 break;
992 }
paul718e3742002-12-13 20:15:29 +0000993 }
994 }
995
996 /* Distance. */
997 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
998 rib->distance = stream_getc (s);
999
1000 /* Metric. */
1001 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1002 rib->metric = stream_getl (s);
1003
Timo Teräsb11f3b52015-11-02 16:50:07 +02001004 if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
1005 rib->mtu = stream_getl (s);
1006
Paul Jakma171eee32006-07-27 16:11:02 +00001007 /* Table */
1008 rib->table=zebrad.rtm_table_default;
G.Balajicddf3912011-11-26 21:59:32 +04001009 rib_add_ipv4_multipath (&p, rib, safi);
ajs719e9742005-02-28 20:52:15 +00001010 return 0;
paul718e3742002-12-13 20:15:29 +00001011}
1012
1013/* Zebra server IPv4 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +00001014static int
Feng Luc99f3482014-10-16 09:52:36 +08001015zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001016{
1017 int i;
1018 struct stream *s;
1019 struct zapi_ipv4 api;
Subbaiah Venkata6902c692012-03-27 19:21:29 -07001020 struct in_addr nexthop, *nexthop_p;
paul718e3742002-12-13 20:15:29 +00001021 unsigned long ifindex;
1022 struct prefix_ipv4 p;
1023 u_char nexthop_num;
1024 u_char nexthop_type;
1025 u_char ifname_len;
1026
1027 s = client->ibuf;
1028 ifindex = 0;
1029 nexthop.s_addr = 0;
Subbaiah Venkata6902c692012-03-27 19:21:29 -07001030 nexthop_p = NULL;
paul718e3742002-12-13 20:15:29 +00001031
1032 /* Type, flags, message. */
1033 api.type = stream_getc (s);
1034 api.flags = stream_getc (s);
1035 api.message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +04001036 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001037
1038 /* IPv4 prefix. */
1039 memset (&p, 0, sizeof (struct prefix_ipv4));
1040 p.family = AF_INET;
1041 p.prefixlen = stream_getc (s);
1042 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1043
1044 /* Nexthop, ifindex, distance, metric. */
1045 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1046 {
1047 nexthop_num = stream_getc (s);
1048
1049 for (i = 0; i < nexthop_num; i++)
1050 {
1051 nexthop_type = stream_getc (s);
1052
1053 switch (nexthop_type)
1054 {
1055 case ZEBRA_NEXTHOP_IFINDEX:
1056 ifindex = stream_getl (s);
1057 break;
1058 case ZEBRA_NEXTHOP_IFNAME:
1059 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +00001060 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +00001061 break;
1062 case ZEBRA_NEXTHOP_IPV4:
1063 nexthop.s_addr = stream_get_ipv4 (s);
Subbaiah Venkata6902c692012-03-27 19:21:29 -07001064 nexthop_p = &nexthop;
paul718e3742002-12-13 20:15:29 +00001065 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +02001066 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
1067 nexthop.s_addr = stream_get_ipv4 (s);
Christian Franke23f5f7c2013-11-27 17:06:14 +00001068 nexthop_p = &nexthop;
Joakim Tjernlundc963c202012-07-07 17:06:13 +02001069 ifindex = stream_getl (s);
1070 break;
paul718e3742002-12-13 20:15:29 +00001071 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +00001072 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +00001073 break;
1074 }
1075 }
1076 }
1077
1078 /* Distance. */
1079 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1080 api.distance = stream_getc (s);
1081 else
1082 api.distance = 0;
1083
1084 /* Metric. */
1085 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1086 api.metric = stream_getl (s);
1087 else
1088 api.metric = 0;
1089
Subbaiah Venkata6902c692012-03-27 19:21:29 -07001090 rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001091 vrf_id, api.safi);
ajs719e9742005-02-28 20:52:15 +00001092 return 0;
paul718e3742002-12-13 20:15:29 +00001093}
1094
1095/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +00001096static int
Feng Luc99f3482014-10-16 09:52:36 +08001097zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
1098 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001099{
1100 struct in_addr addr;
Christian Frankebb97e462013-05-25 14:01:35 +00001101 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00001102
1103 addr.s_addr = stream_get_ipv4 (client->ibuf);
Christian Frankebb97e462013-05-25 14:01:35 +00001104 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1105 zlog_debug("%s: looking up %s", __func__,
1106 inet_ntop (AF_INET, &addr, buf, BUFSIZ));
Feng Luc99f3482014-10-16 09:52:36 +08001107 return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001108}
1109
Everton Marques4e5275b2014-07-01 15:15:52 -03001110/* MRIB Nexthop lookup for IPv4. */
1111static int
Feng Luc99f3482014-10-16 09:52:36 +08001112zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length,
1113 vrf_id_t vrf_id)
Everton Marques4e5275b2014-07-01 15:15:52 -03001114{
1115 struct in_addr addr;
David Lamparterbd078122015-01-06 19:53:24 +01001116 struct rib *rib;
Everton Marques4e5275b2014-07-01 15:15:52 -03001117
1118 addr.s_addr = stream_get_ipv4 (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001119 rib = rib_match_ipv4_multicast (addr, NULL, vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +01001120 return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib);
Everton Marques4e5275b2014-07-01 15:15:52 -03001121}
1122
paul718e3742002-12-13 20:15:29 +00001123/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +00001124static int
Feng Luc99f3482014-10-16 09:52:36 +08001125zread_ipv4_import_lookup (struct zserv *client, u_short length,
1126 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001127{
1128 struct prefix_ipv4 p;
1129
1130 p.family = AF_INET;
1131 p.prefixlen = stream_getc (client->ibuf);
1132 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1133
Feng Luc99f3482014-10-16 09:52:36 +08001134 return zsend_ipv4_import_lookup (client, &p, vrf_id);
paul718e3742002-12-13 20:15:29 +00001135}
1136
1137#ifdef HAVE_IPV6
1138/* Zebra server IPv6 prefix add function. */
ajs719e9742005-02-28 20:52:15 +00001139static int
Feng Luc99f3482014-10-16 09:52:36 +08001140zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001141{
1142 int i;
1143 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001144 struct in6_addr nexthop;
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001145 struct rib *rib;
1146 u_char message;
1147 u_char gateway_num;
1148 u_char nexthop_type;
paul718e3742002-12-13 20:15:29 +00001149 struct prefix_ipv6 p;
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001150 safi_t safi;
1151 static struct in6_addr nexthops[MULTIPATH_NUM];
1152 static unsigned int ifindices[MULTIPATH_NUM];
1153
1154 /* Get input stream. */
paul718e3742002-12-13 20:15:29 +00001155 s = client->ibuf;
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001156
paul718e3742002-12-13 20:15:29 +00001157 memset (&nexthop, 0, sizeof (struct in6_addr));
1158
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001159 /* Allocate new rib. */
1160 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
paul718e3742002-12-13 20:15:29 +00001161
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001162 /* Type, flags, message. */
1163 rib->type = stream_getc (s);
1164 rib->flags = stream_getc (s);
1165 message = stream_getc (s);
1166 safi = stream_getw (s);
1167 rib->uptime = time (NULL);
1168
1169 /* IPv6 prefix. */
paul718e3742002-12-13 20:15:29 +00001170 memset (&p, 0, sizeof (struct prefix_ipv6));
1171 p.family = AF_INET6;
1172 p.prefixlen = stream_getc (s);
1173 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1174
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001175 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1176 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1177 * these. Clients should send the same number of paired set of
1178 * next-hop-addr/next-hop-ifindices. */
1179 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
paul718e3742002-12-13 20:15:29 +00001180 {
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001181 int nh_count = 0;
1182 int if_count = 0;
1183 int max_nh_if = 0;
1184 unsigned int ifindex;
paul718e3742002-12-13 20:15:29 +00001185
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001186 gateway_num = stream_getc (s);
1187 for (i = 0; i < gateway_num; i++)
paul718e3742002-12-13 20:15:29 +00001188 {
1189 nexthop_type = stream_getc (s);
1190
1191 switch (nexthop_type)
1192 {
1193 case ZEBRA_NEXTHOP_IPV6:
1194 stream_get (&nexthop, s, 16);
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001195 if (nh_count < MULTIPATH_NUM) {
1196 nexthops[nh_count++] = nexthop;
1197 }
paul718e3742002-12-13 20:15:29 +00001198 break;
1199 case ZEBRA_NEXTHOP_IFINDEX:
1200 ifindex = stream_getl (s);
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001201 if (if_count < MULTIPATH_NUM) {
1202 ifindices[if_count++] = ifindex;
1203 }
paul718e3742002-12-13 20:15:29 +00001204 break;
1205 }
1206 }
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001207
1208 max_nh_if = (nh_count > if_count) ? nh_count : if_count;
1209 for (i = 0; i < max_nh_if; i++)
1210 {
1211 if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i]))
1212 {
1213 if ((i < if_count) && ifindices[i])
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001214 rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001215 else
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001216 rib_nexthop_ipv6_add (rib, &nexthops[i]);
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001217 }
1218 else
1219 {
1220 if ((i < if_count) && ifindices[i])
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001221 rib_nexthop_ifindex_add (rib, ifindices[i]);
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001222 }
1223 }
paul718e3742002-12-13 20:15:29 +00001224 }
1225
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001226 /* Distance. */
1227 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1228 rib->distance = stream_getc (s);
paul718e3742002-12-13 20:15:29 +00001229
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001230 /* Metric. */
1231 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1232 rib->metric = stream_getl (s);
Timo Teräsb11f3b52015-11-02 16:50:07 +02001233
Ayan Banerjee34c5d892015-11-09 20:14:53 -05001234 if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
1235 rib->mtu = stream_getl (s);
1236
1237 /* Table */
1238 rib->table=zebrad.rtm_table_default;
1239 rib_add_ipv6_multipath (&p, rib, safi);
ajs719e9742005-02-28 20:52:15 +00001240 return 0;
paul718e3742002-12-13 20:15:29 +00001241}
1242
1243/* Zebra server IPv6 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +00001244static int
Feng Luc99f3482014-10-16 09:52:36 +08001245zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001246{
1247 int i;
1248 struct stream *s;
1249 struct zapi_ipv6 api;
1250 struct in6_addr nexthop;
1251 unsigned long ifindex;
1252 struct prefix_ipv6 p;
1253
1254 s = client->ibuf;
1255 ifindex = 0;
1256 memset (&nexthop, 0, sizeof (struct in6_addr));
1257
1258 /* Type, flags, message. */
1259 api.type = stream_getc (s);
1260 api.flags = stream_getc (s);
1261 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001262 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001263
1264 /* IPv4 prefix. */
1265 memset (&p, 0, sizeof (struct prefix_ipv6));
1266 p.family = AF_INET6;
1267 p.prefixlen = stream_getc (s);
1268 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1269
1270 /* Nexthop, ifindex, distance, metric. */
1271 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1272 {
1273 u_char nexthop_type;
1274
1275 api.nexthop_num = stream_getc (s);
1276 for (i = 0; i < api.nexthop_num; i++)
1277 {
1278 nexthop_type = stream_getc (s);
1279
1280 switch (nexthop_type)
1281 {
1282 case ZEBRA_NEXTHOP_IPV6:
1283 stream_get (&nexthop, s, 16);
1284 break;
1285 case ZEBRA_NEXTHOP_IFINDEX:
1286 ifindex = stream_getl (s);
1287 break;
1288 }
1289 }
1290 }
1291
1292 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1293 api.distance = stream_getc (s);
1294 else
1295 api.distance = 0;
1296 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1297 api.metric = stream_getl (s);
1298 else
1299 api.metric = 0;
1300
1301 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Luc99f3482014-10-16 09:52:36 +08001302 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001303 api.safi);
paul718e3742002-12-13 20:15:29 +00001304 else
Feng Luc99f3482014-10-16 09:52:36 +08001305 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001306 api.safi);
ajs719e9742005-02-28 20:52:15 +00001307 return 0;
paul718e3742002-12-13 20:15:29 +00001308}
1309
ajs719e9742005-02-28 20:52:15 +00001310static int
Feng Luc99f3482014-10-16 09:52:36 +08001311zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
1312 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001313{
1314 struct in6_addr addr;
1315 char buf[BUFSIZ];
1316
1317 stream_get (&addr, client->ibuf, 16);
Christian Frankea5207082013-04-11 08:24:29 +00001318 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1319 zlog_debug("%s: looking up %s", __func__,
1320 inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
paul718e3742002-12-13 20:15:29 +00001321
Feng Luc99f3482014-10-16 09:52:36 +08001322 return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001323}
1324#endif /* HAVE_IPV6 */
1325
hasso18a6dce2004-10-03 18:18:34 +00001326/* Register zebra server router-id information. Send current router-id */
ajs719e9742005-02-28 20:52:15 +00001327static int
Feng Luc99f3482014-10-16 09:52:36 +08001328zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001329{
1330 struct prefix p;
1331
1332 /* Router-id information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +08001333 vrf_bitmap_set (client->ridinfo, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001334
Feng Luc99f3482014-10-16 09:52:36 +08001335 router_id_get (&p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001336
Feng Luc99f3482014-10-16 09:52:36 +08001337 return zsend_router_id_update (client, &p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001338}
1339
1340/* Unregister zebra server router-id information. */
ajs719e9742005-02-28 20:52:15 +00001341static int
Feng Luc99f3482014-10-16 09:52:36 +08001342zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001343{
Feng Luc99f3482014-10-16 09:52:36 +08001344 vrf_bitmap_unset (client->ridinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +00001345 return 0;
hasso18a6dce2004-10-03 18:18:34 +00001346}
1347
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001348/* Tie up route-type and client->sock */
1349static void
1350zread_hello (struct zserv *client)
1351{
1352 /* type of protocol (lib/zebra.h) */
1353 u_char proto;
1354 proto = stream_getc (client->ibuf);
1355
1356 /* accept only dynamic routing protocols */
1357 if ((proto < ZEBRA_ROUTE_MAX)
1358 && (proto > ZEBRA_ROUTE_STATIC))
1359 {
1360 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1361 client->sock, zebra_route_string(proto));
1362
1363 /* if route-type was binded by other client */
1364 if (route_type_oaths[proto])
1365 zlog_warn ("sender of %s routes changed %c->%c",
1366 zebra_route_string(proto), route_type_oaths[proto],
1367 client->sock);
1368
1369 route_type_oaths[proto] = client->sock;
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001370 client->proto = proto;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001371 }
1372}
1373
Feng Luc99f3482014-10-16 09:52:36 +08001374/* Unregister all information in a VRF. */
1375static int
1376zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
1377{
1378 int i;
1379
1380 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1381 vrf_bitmap_unset (client->redist[i], vrf_id);
1382 vrf_bitmap_unset (client->redist_default, vrf_id);
1383 vrf_bitmap_unset (client->ifinfo, vrf_id);
1384 vrf_bitmap_unset (client->ridinfo, vrf_id);
1385
1386 return 0;
1387}
1388
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001389/* If client sent routes of specific type, zebra removes it
1390 * and returns number of deleted routes.
1391 */
1392static void
1393zebra_score_rib (int client_sock)
1394{
1395 int i;
1396
1397 for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
1398 if (client_sock == route_type_oaths[i])
1399 {
1400 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1401 client_sock, rib_score_proto (i), zebra_route_string (i));
1402 route_type_oaths[i] = 0;
1403 break;
1404 }
1405}
1406
paul718e3742002-12-13 20:15:29 +00001407/* Close zebra client. */
paulb9df2d22004-05-09 09:09:59 +00001408static void
paul718e3742002-12-13 20:15:29 +00001409zebra_client_close (struct zserv *client)
1410{
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001411 zebra_cleanup_rnh_client(0, AF_INET, client);
1412 zebra_cleanup_rnh_client(0, AF_INET6, client);
1413
paul718e3742002-12-13 20:15:29 +00001414 /* Close file descriptor. */
1415 if (client->sock)
1416 {
1417 close (client->sock);
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001418 zebra_score_rib (client->sock);
paul718e3742002-12-13 20:15:29 +00001419 client->sock = -1;
1420 }
1421
1422 /* Free stream buffers. */
1423 if (client->ibuf)
1424 stream_free (client->ibuf);
1425 if (client->obuf)
1426 stream_free (client->obuf);
ajs719e9742005-02-28 20:52:15 +00001427 if (client->wb)
1428 buffer_free(client->wb);
paul718e3742002-12-13 20:15:29 +00001429
1430 /* Release threads. */
1431 if (client->t_read)
1432 thread_cancel (client->t_read);
1433 if (client->t_write)
1434 thread_cancel (client->t_write);
ajs719e9742005-02-28 20:52:15 +00001435 if (client->t_suicide)
1436 thread_cancel (client->t_suicide);
paul718e3742002-12-13 20:15:29 +00001437
1438 /* Free client structure. */
paulb21b19c2003-06-15 01:28:29 +00001439 listnode_delete (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001440 XFREE (0, client);
1441}
1442
1443/* Make new client. */
paulb9df2d22004-05-09 09:09:59 +00001444static void
paul718e3742002-12-13 20:15:29 +00001445zebra_client_create (int sock)
1446{
1447 struct zserv *client;
Feng Luc99f3482014-10-16 09:52:36 +08001448 int i;
paul718e3742002-12-13 20:15:29 +00001449
David Lamparter23757db2016-02-24 06:26:02 +01001450 client = XCALLOC (MTYPE_TMP, sizeof (struct zserv));
paul718e3742002-12-13 20:15:29 +00001451
1452 /* Make client input/output buffer. */
1453 client->sock = sock;
1454 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1455 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
ajs719e9742005-02-28 20:52:15 +00001456 client->wb = buffer_new(0);
paul718e3742002-12-13 20:15:29 +00001457
1458 /* Set table number. */
paulb21b19c2003-06-15 01:28:29 +00001459 client->rtm_table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00001460
Feng Luc99f3482014-10-16 09:52:36 +08001461 /* Initialize flags */
1462 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1463 client->redist[i] = vrf_bitmap_init ();
1464 client->redist_default = vrf_bitmap_init ();
1465 client->ifinfo = vrf_bitmap_init ();
1466 client->ridinfo = vrf_bitmap_init ();
1467
paul718e3742002-12-13 20:15:29 +00001468 /* Add this client to linked list. */
paulb21b19c2003-06-15 01:28:29 +00001469 listnode_add (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001470
1471 /* Make new read thread. */
1472 zebra_event (ZEBRA_READ, sock, client);
1473}
1474
1475/* Handler of zebra service request. */
paulb9df2d22004-05-09 09:09:59 +00001476static int
paul718e3742002-12-13 20:15:29 +00001477zebra_client_read (struct thread *thread)
1478{
1479 int sock;
1480 struct zserv *client;
ajs57a14772005-04-10 15:01:56 +00001481 size_t already;
paulc1b98002006-01-16 01:54:02 +00001482 uint16_t length, command;
1483 uint8_t marker, version;
Feng Luc99f3482014-10-16 09:52:36 +08001484 vrf_id_t vrf_id;
paul718e3742002-12-13 20:15:29 +00001485
1486 /* Get thread data. Reset reading thread because I'm running. */
1487 sock = THREAD_FD (thread);
1488 client = THREAD_ARG (thread);
1489 client->t_read = NULL;
1490
ajs719e9742005-02-28 20:52:15 +00001491 if (client->t_suicide)
paul718e3742002-12-13 20:15:29 +00001492 {
ajs719e9742005-02-28 20:52:15 +00001493 zebra_client_close(client);
paul718e3742002-12-13 20:15:29 +00001494 return -1;
1495 }
ajs719e9742005-02-28 20:52:15 +00001496
1497 /* Read length and command (if we don't have it already). */
ajs57a14772005-04-10 15:01:56 +00001498 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
ajs719e9742005-02-28 20:52:15 +00001499 {
ajs57a14772005-04-10 15:01:56 +00001500 ssize_t nbyte;
ajs719e9742005-02-28 20:52:15 +00001501 if (((nbyte = stream_read_try (client->ibuf, sock,
ajs57a14772005-04-10 15:01:56 +00001502 ZEBRA_HEADER_SIZE-already)) == 0) ||
ajs719e9742005-02-28 20:52:15 +00001503 (nbyte == -1))
1504 {
1505 if (IS_ZEBRA_DEBUG_EVENT)
1506 zlog_debug ("connection closed socket [%d]", sock);
1507 zebra_client_close (client);
1508 return -1;
1509 }
ajs57a14772005-04-10 15:01:56 +00001510 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
ajs719e9742005-02-28 20:52:15 +00001511 {
1512 /* Try again later. */
1513 zebra_event (ZEBRA_READ, sock, client);
1514 return 0;
1515 }
ajs57a14772005-04-10 15:01:56 +00001516 already = ZEBRA_HEADER_SIZE;
ajs719e9742005-02-28 20:52:15 +00001517 }
1518
1519 /* Reset to read from the beginning of the incoming packet. */
1520 stream_set_getp(client->ibuf, 0);
1521
paulc1b98002006-01-16 01:54:02 +00001522 /* Fetch header values */
paul718e3742002-12-13 20:15:29 +00001523 length = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001524 marker = stream_getc (client->ibuf);
1525 version = stream_getc (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001526 vrf_id = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001527 command = stream_getw (client->ibuf);
paul718e3742002-12-13 20:15:29 +00001528
paulc1b98002006-01-16 01:54:02 +00001529 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1530 {
1531 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1532 __func__, sock, marker, version);
1533 zebra_client_close (client);
1534 return -1;
1535 }
ajs719e9742005-02-28 20:52:15 +00001536 if (length < ZEBRA_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00001537 {
ajs57a14772005-04-10 15:01:56 +00001538 zlog_warn("%s: socket %d message length %u is less than header size %d",
1539 __func__, sock, length, ZEBRA_HEADER_SIZE);
1540 zebra_client_close (client);
1541 return -1;
1542 }
1543 if (length > STREAM_SIZE(client->ibuf))
1544 {
1545 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1546 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
paul718e3742002-12-13 20:15:29 +00001547 zebra_client_close (client);
1548 return -1;
1549 }
1550
paul718e3742002-12-13 20:15:29 +00001551 /* Read rest of data. */
ajs57a14772005-04-10 15:01:56 +00001552 if (already < length)
paul718e3742002-12-13 20:15:29 +00001553 {
ajs57a14772005-04-10 15:01:56 +00001554 ssize_t nbyte;
1555 if (((nbyte = stream_read_try (client->ibuf, sock,
1556 length-already)) == 0) ||
1557 (nbyte == -1))
paul718e3742002-12-13 20:15:29 +00001558 {
1559 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001560 zlog_debug ("connection closed [%d] when reading zebra data", sock);
paul718e3742002-12-13 20:15:29 +00001561 zebra_client_close (client);
1562 return -1;
1563 }
ajs57a14772005-04-10 15:01:56 +00001564 if (nbyte != (ssize_t)(length-already))
ajs719e9742005-02-28 20:52:15 +00001565 {
1566 /* Try again later. */
1567 zebra_event (ZEBRA_READ, sock, client);
1568 return 0;
1569 }
paul718e3742002-12-13 20:15:29 +00001570 }
1571
ajs719e9742005-02-28 20:52:15 +00001572 length -= ZEBRA_HEADER_SIZE;
1573
paul718e3742002-12-13 20:15:29 +00001574 /* Debug packet information. */
1575 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001576 zlog_debug ("zebra message comes from socket [%d]", sock);
paul718e3742002-12-13 20:15:29 +00001577
1578 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
Feng Luc99f3482014-10-16 09:52:36 +08001579 zlog_debug ("zebra message received [%s] %d in VRF %u",
1580 zserv_command_string (command), length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001581
1582 switch (command)
1583 {
hasso18a6dce2004-10-03 18:18:34 +00001584 case ZEBRA_ROUTER_ID_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001585 zread_router_id_add (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001586 break;
1587 case ZEBRA_ROUTER_ID_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001588 zread_router_id_delete (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001589 break;
paul718e3742002-12-13 20:15:29 +00001590 case ZEBRA_INTERFACE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001591 zread_interface_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001592 break;
1593 case ZEBRA_INTERFACE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001594 zread_interface_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001595 break;
1596 case ZEBRA_IPV4_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001597 zread_ipv4_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001598 break;
1599 case ZEBRA_IPV4_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001600 zread_ipv4_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001601 break;
1602#ifdef HAVE_IPV6
1603 case ZEBRA_IPV6_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001604 zread_ipv6_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001605 break;
1606 case ZEBRA_IPV6_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001607 zread_ipv6_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001608 break;
1609#endif /* HAVE_IPV6 */
1610 case ZEBRA_REDISTRIBUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001611 zebra_redistribute_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001612 break;
1613 case ZEBRA_REDISTRIBUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001614 zebra_redistribute_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001615 break;
1616 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001617 zebra_redistribute_default_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001618 break;
1619 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001620 zebra_redistribute_default_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001621 break;
1622 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001623 zread_ipv4_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001624 break;
Everton Marques4e5275b2014-07-01 15:15:52 -03001625 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
Feng Luc99f3482014-10-16 09:52:36 +08001626 zread_ipv4_nexthop_lookup_mrib (client, length, vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -03001627 break;
paul718e3742002-12-13 20:15:29 +00001628#ifdef HAVE_IPV6
1629 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001630 zread_ipv6_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001631 break;
1632#endif /* HAVE_IPV6 */
1633 case ZEBRA_IPV4_IMPORT_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001634 zread_ipv4_import_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001635 break;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001636 case ZEBRA_HELLO:
1637 zread_hello (client);
1638 break;
Feng Luc99f3482014-10-16 09:52:36 +08001639 case ZEBRA_VRF_UNREGISTER:
1640 zread_vrf_unregister (client, length, vrf_id);
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001641 case ZEBRA_NEXTHOP_REGISTER:
1642 zserv_nexthop_register(client, sock, length, vrf_id);
1643 break;
1644 case ZEBRA_NEXTHOP_UNREGISTER:
1645 zserv_nexthop_unregister(client, sock, length);
Feng Luc99f3482014-10-16 09:52:36 +08001646 break;
paul718e3742002-12-13 20:15:29 +00001647 default:
1648 zlog_info ("Zebra received unknown command %d", command);
1649 break;
1650 }
1651
ajs719e9742005-02-28 20:52:15 +00001652 if (client->t_suicide)
1653 {
1654 /* No need to wait for thread callback, just kill immediately. */
1655 zebra_client_close(client);
1656 return -1;
1657 }
1658
paul718e3742002-12-13 20:15:29 +00001659 stream_reset (client->ibuf);
1660 zebra_event (ZEBRA_READ, sock, client);
paul718e3742002-12-13 20:15:29 +00001661 return 0;
1662}
1663
paul718e3742002-12-13 20:15:29 +00001664
1665/* Accept code of zebra server socket. */
paulb9df2d22004-05-09 09:09:59 +00001666static int
paul718e3742002-12-13 20:15:29 +00001667zebra_accept (struct thread *thread)
1668{
1669 int accept_sock;
1670 int client_sock;
1671 struct sockaddr_in client;
1672 socklen_t len;
1673
1674 accept_sock = THREAD_FD (thread);
1675
ajs719e9742005-02-28 20:52:15 +00001676 /* Reregister myself. */
1677 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1678
paul718e3742002-12-13 20:15:29 +00001679 len = sizeof (struct sockaddr_in);
1680 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1681
1682 if (client_sock < 0)
1683 {
ajs6099b3b2004-11-20 02:06:59 +00001684 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001685 return -1;
1686 }
1687
paulccf35572003-03-01 11:42:20 +00001688 /* Make client socket non-blocking. */
ajs719e9742005-02-28 20:52:15 +00001689 set_nonblocking(client_sock);
paul865b8522005-01-05 08:30:35 +00001690
paul718e3742002-12-13 20:15:29 +00001691 /* Create new zebra client. */
1692 zebra_client_create (client_sock);
1693
paul718e3742002-12-13 20:15:29 +00001694 return 0;
1695}
1696
paulb9df2d22004-05-09 09:09:59 +00001697#ifdef HAVE_TCP_ZEBRA
paul718e3742002-12-13 20:15:29 +00001698/* Make zebra's server socket. */
paulb9df2d22004-05-09 09:09:59 +00001699static void
paul718e3742002-12-13 20:15:29 +00001700zebra_serv ()
1701{
1702 int ret;
1703 int accept_sock;
1704 struct sockaddr_in addr;
1705
1706 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1707
1708 if (accept_sock < 0)
1709 {
paul3d1dc852005-04-05 00:45:23 +00001710 zlog_warn ("Can't create zserv stream socket: %s",
1711 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001712 zlog_warn ("zebra can't provice full functionality due to above error");
1713 return;
1714 }
1715
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001716 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
paul718e3742002-12-13 20:15:29 +00001717 memset (&addr, 0, sizeof (struct sockaddr_in));
1718 addr.sin_family = AF_INET;
1719 addr.sin_port = htons (ZEBRA_PORT);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001720#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +00001721 addr.sin_len = sizeof (struct sockaddr_in);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001722#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +00001723 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1724
1725 sockopt_reuseaddr (accept_sock);
1726 sockopt_reuseport (accept_sock);
1727
pauledd7c242003-06-04 13:59:38 +00001728 if ( zserv_privs.change(ZPRIVS_RAISE) )
1729 zlog (NULL, LOG_ERR, "Can't raise privileges");
1730
paul718e3742002-12-13 20:15:29 +00001731 ret = bind (accept_sock, (struct sockaddr *)&addr,
1732 sizeof (struct sockaddr_in));
1733 if (ret < 0)
1734 {
paul3d1dc852005-04-05 00:45:23 +00001735 zlog_warn ("Can't bind to stream socket: %s",
1736 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001737 zlog_warn ("zebra can't provice full functionality due to above error");
1738 close (accept_sock); /* Avoid sd leak. */
1739 return;
1740 }
pauledd7c242003-06-04 13:59:38 +00001741
1742 if ( zserv_privs.change(ZPRIVS_LOWER) )
1743 zlog (NULL, LOG_ERR, "Can't lower privileges");
paul718e3742002-12-13 20:15:29 +00001744
1745 ret = listen (accept_sock, 1);
1746 if (ret < 0)
1747 {
paul3d1dc852005-04-05 00:45:23 +00001748 zlog_warn ("Can't listen to stream socket: %s",
1749 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001750 zlog_warn ("zebra can't provice full functionality due to above error");
1751 close (accept_sock); /* Avoid sd leak. */
1752 return;
1753 }
1754
1755 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1756}
David Lamparter4b6c3322015-04-21 09:47:57 +02001757#else /* HAVE_TCP_ZEBRA */
paul718e3742002-12-13 20:15:29 +00001758
1759/* For sockaddr_un. */
1760#include <sys/un.h>
1761
1762/* zebra server UNIX domain socket. */
paulb9df2d22004-05-09 09:09:59 +00001763static void
hassofce954f2004-10-07 20:29:24 +00001764zebra_serv_un (const char *path)
paul718e3742002-12-13 20:15:29 +00001765{
1766 int ret;
1767 int sock, len;
1768 struct sockaddr_un serv;
1769 mode_t old_mask;
1770
1771 /* First of all, unlink existing socket */
1772 unlink (path);
1773
1774 /* Set umask */
1775 old_mask = umask (0077);
1776
1777 /* Make UNIX domain socket. */
1778 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1779 if (sock < 0)
1780 {
paul3d1dc852005-04-05 00:45:23 +00001781 zlog_warn ("Can't create zserv unix socket: %s",
1782 safe_strerror (errno));
1783 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001784 return;
1785 }
1786
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001787 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1788
paul718e3742002-12-13 20:15:29 +00001789 /* Make server socket. */
1790 memset (&serv, 0, sizeof (struct sockaddr_un));
1791 serv.sun_family = AF_UNIX;
1792 strncpy (serv.sun_path, path, strlen (path));
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001793#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
paul718e3742002-12-13 20:15:29 +00001794 len = serv.sun_len = SUN_LEN(&serv);
1795#else
1796 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001797#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
paul718e3742002-12-13 20:15:29 +00001798
1799 ret = bind (sock, (struct sockaddr *) &serv, len);
1800 if (ret < 0)
1801 {
paul3d1dc852005-04-05 00:45:23 +00001802 zlog_warn ("Can't bind to unix socket %s: %s",
1803 path, safe_strerror (errno));
1804 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001805 close (sock);
1806 return;
1807 }
1808
1809 ret = listen (sock, 5);
1810 if (ret < 0)
1811 {
paul3d1dc852005-04-05 00:45:23 +00001812 zlog_warn ("Can't listen to unix socket %s: %s",
1813 path, safe_strerror (errno));
1814 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001815 close (sock);
1816 return;
1817 }
1818
1819 umask (old_mask);
1820
1821 zebra_event (ZEBRA_SERV, sock, NULL);
1822}
David Lamparter4b6c3322015-04-21 09:47:57 +02001823#endif /* HAVE_TCP_ZEBRA */
David Lamparter6b0655a2014-06-04 06:53:35 +02001824
paul718e3742002-12-13 20:15:29 +00001825
paulb9df2d22004-05-09 09:09:59 +00001826static void
paul718e3742002-12-13 20:15:29 +00001827zebra_event (enum event event, int sock, struct zserv *client)
1828{
1829 switch (event)
1830 {
1831 case ZEBRA_SERV:
paulb21b19c2003-06-15 01:28:29 +00001832 thread_add_read (zebrad.master, zebra_accept, client, sock);
paul718e3742002-12-13 20:15:29 +00001833 break;
1834 case ZEBRA_READ:
1835 client->t_read =
paulb21b19c2003-06-15 01:28:29 +00001836 thread_add_read (zebrad.master, zebra_client_read, client, sock);
paul718e3742002-12-13 20:15:29 +00001837 break;
1838 case ZEBRA_WRITE:
1839 /**/
1840 break;
1841 }
1842}
David Lamparter6b0655a2014-06-04 06:53:35 +02001843
paul718e3742002-12-13 20:15:29 +00001844/* Display default rtm_table for all clients. */
1845DEFUN (show_table,
1846 show_table_cmd,
1847 "show table",
1848 SHOW_STR
1849 "default routing table to use for all clients\n")
1850{
paulb21b19c2003-06-15 01:28:29 +00001851 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001852 VTY_NEWLINE);
1853 return CMD_SUCCESS;
1854}
1855
1856DEFUN (config_table,
1857 config_table_cmd,
1858 "table TABLENO",
1859 "Configure target kernel routing table\n"
1860 "TABLE integer\n")
1861{
paulb21b19c2003-06-15 01:28:29 +00001862 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
paul718e3742002-12-13 20:15:29 +00001863 return CMD_SUCCESS;
1864}
1865
hasso647e4f12003-05-25 11:43:52 +00001866DEFUN (ip_forwarding,
1867 ip_forwarding_cmd,
1868 "ip forwarding",
1869 IP_STR
1870 "Turn on IP forwarding")
1871{
1872 int ret;
1873
1874 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001875 if (ret == 0)
1876 ret = ipforward_on ();
hasso647e4f12003-05-25 11:43:52 +00001877
hasso647e4f12003-05-25 11:43:52 +00001878 if (ret == 0)
1879 {
1880 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1881 return CMD_WARNING;
1882 }
1883
1884 return CMD_SUCCESS;
1885}
1886
paul718e3742002-12-13 20:15:29 +00001887DEFUN (no_ip_forwarding,
1888 no_ip_forwarding_cmd,
1889 "no ip forwarding",
1890 NO_STR
1891 IP_STR
1892 "Turn off IP forwarding")
1893{
1894 int ret;
1895
1896 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001897 if (ret != 0)
1898 ret = ipforward_off ();
paul718e3742002-12-13 20:15:29 +00001899
paul718e3742002-12-13 20:15:29 +00001900 if (ret != 0)
1901 {
1902 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1903 return CMD_WARNING;
1904 }
1905
1906 return CMD_SUCCESS;
1907}
1908
1909/* This command is for debugging purpose. */
1910DEFUN (show_zebra_client,
1911 show_zebra_client_cmd,
1912 "show zebra client",
1913 SHOW_STR
1914 "Zebra information"
1915 "Client information")
1916{
hasso52dc7ee2004-09-23 19:18:23 +00001917 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001918 struct zserv *client;
1919
paul1eb8ef22005-04-07 07:30:20 +00001920 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
Pradosh Mohapatra60cc9592015-11-09 20:21:41 -05001921 vty_out (vty, "Client %s fd %d%s",
1922 zebra_route_string(client->proto), client->sock,
1923 VTY_NEWLINE);
1924
paul718e3742002-12-13 20:15:29 +00001925 return CMD_SUCCESS;
1926}
1927
1928/* Table configuration write function. */
paulb9df2d22004-05-09 09:09:59 +00001929static int
paul718e3742002-12-13 20:15:29 +00001930config_write_table (struct vty *vty)
1931{
paulb21b19c2003-06-15 01:28:29 +00001932 if (zebrad.rtm_table_default)
1933 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001934 VTY_NEWLINE);
1935 return 0;
1936}
1937
1938/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001939static struct cmd_node table_node =
paul718e3742002-12-13 20:15:29 +00001940{
1941 TABLE_NODE,
1942 "", /* This node has no interface. */
1943 1
1944};
David Lamparter6b0655a2014-06-04 06:53:35 +02001945
paul718e3742002-12-13 20:15:29 +00001946/* Only display ip forwarding is enabled or not. */
1947DEFUN (show_ip_forwarding,
1948 show_ip_forwarding_cmd,
1949 "show ip forwarding",
1950 SHOW_STR
1951 IP_STR
1952 "IP forwarding status\n")
1953{
1954 int ret;
1955
1956 ret = ipforward ();
1957
1958 if (ret == 0)
1959 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1960 else
1961 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1962 return CMD_SUCCESS;
1963}
1964
1965#ifdef HAVE_IPV6
1966/* Only display ipv6 forwarding is enabled or not. */
1967DEFUN (show_ipv6_forwarding,
1968 show_ipv6_forwarding_cmd,
1969 "show ipv6 forwarding",
1970 SHOW_STR
1971 "IPv6 information\n"
1972 "Forwarding status\n")
1973{
1974 int ret;
1975
1976 ret = ipforward_ipv6 ();
1977
1978 switch (ret)
1979 {
1980 case -1:
1981 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1982 break;
1983 case 0:
1984 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1985 break;
1986 case 1:
1987 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1988 break;
1989 default:
1990 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1991 break;
1992 }
1993 return CMD_SUCCESS;
1994}
1995
hasso55906722004-02-11 22:42:16 +00001996DEFUN (ipv6_forwarding,
1997 ipv6_forwarding_cmd,
1998 "ipv6 forwarding",
1999 IPV6_STR
2000 "Turn on IPv6 forwarding")
2001{
2002 int ret;
2003
hasso41d3fc92004-04-06 11:59:00 +00002004 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00002005 if (ret == 0)
2006 ret = ipforward_ipv6_on ();
hasso41d3fc92004-04-06 11:59:00 +00002007
hasso41d3fc92004-04-06 11:59:00 +00002008 if (ret == 0)
2009 {
hasso55906722004-02-11 22:42:16 +00002010 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
2011 return CMD_WARNING;
2012 }
2013
2014 return CMD_SUCCESS;
2015}
2016
paul718e3742002-12-13 20:15:29 +00002017DEFUN (no_ipv6_forwarding,
2018 no_ipv6_forwarding_cmd,
2019 "no ipv6 forwarding",
2020 NO_STR
hasso55906722004-02-11 22:42:16 +00002021 IPV6_STR
2022 "Turn off IPv6 forwarding")
paul718e3742002-12-13 20:15:29 +00002023{
2024 int ret;
2025
hasso41d3fc92004-04-06 11:59:00 +00002026 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00002027 if (ret != 0)
2028 ret = ipforward_ipv6_off ();
hasso41d3fc92004-04-06 11:59:00 +00002029
paul718e3742002-12-13 20:15:29 +00002030 if (ret != 0)
2031 {
2032 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
2033 return CMD_WARNING;
2034 }
2035
2036 return CMD_SUCCESS;
2037}
2038
2039#endif /* HAVE_IPV6 */
2040
2041/* IPForwarding configuration write function. */
ajs719e9742005-02-28 20:52:15 +00002042static int
paul718e3742002-12-13 20:15:29 +00002043config_write_forwarding (struct vty *vty)
2044{
hasso18a6dce2004-10-03 18:18:34 +00002045 /* FIXME: Find better place for that. */
2046 router_id_write (vty);
2047
paul3e0b3a52004-08-23 18:58:32 +00002048 if (ipforward ())
2049 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002050#ifdef HAVE_IPV6
paul3e0b3a52004-08-23 18:58:32 +00002051 if (ipforward_ipv6 ())
2052 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002053#endif /* HAVE_IPV6 */
2054 vty_out (vty, "!%s", VTY_NEWLINE);
2055 return 0;
2056}
2057
2058/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002059static struct cmd_node forwarding_node =
paul718e3742002-12-13 20:15:29 +00002060{
2061 FORWARDING_NODE,
2062 "", /* This node has no interface. */
2063 1
2064};
2065
Udaya Shankara KSd869dbd2016-02-11 21:42:29 +05302066#ifdef HAVE_FPM
2067/* function to write the fpm config info */
2068static int
2069config_write_fpm (struct vty *vty)
2070{
2071 return
2072 fpm_remote_srv_write (vty);
2073}
2074
2075/* Zebra node */
2076static struct cmd_node zebra_node =
2077{
2078 ZEBRA_NODE,
2079 "",
2080 1
2081};
2082#endif
2083
David Lamparter6b0655a2014-06-04 06:53:35 +02002084
paul718e3742002-12-13 20:15:29 +00002085/* Initialisation of zebra and installation of commands. */
2086void
paula1ac18c2005-06-28 17:17:12 +00002087zebra_init (void)
paul718e3742002-12-13 20:15:29 +00002088{
2089 /* Client list init. */
paulb21b19c2003-06-15 01:28:29 +00002090 zebrad.client_list = list_new ();
paul718e3742002-12-13 20:15:29 +00002091
paul718e3742002-12-13 20:15:29 +00002092 /* Install configuration write function. */
2093 install_node (&table_node, config_write_table);
2094 install_node (&forwarding_node, config_write_forwarding);
Udaya Shankara KSd869dbd2016-02-11 21:42:29 +05302095#ifdef HAVE_FPM
2096 install_node (&zebra_node, config_write_fpm);
2097#endif
paul718e3742002-12-13 20:15:29 +00002098
2099 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00002100 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00002101 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
2102 install_element (ENABLE_NODE, &show_zebra_client_cmd);
2103
2104#ifdef HAVE_NETLINK
2105 install_element (VIEW_NODE, &show_table_cmd);
paul718e3742002-12-13 20:15:29 +00002106 install_element (CONFIG_NODE, &config_table_cmd);
2107#endif /* HAVE_NETLINK */
2108
2109#ifdef HAVE_IPV6
2110 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
hasso55906722004-02-11 22:42:16 +00002111 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00002112 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
2113#endif /* HAVE_IPV6 */
Paul Jakma7514fb72007-05-02 16:05:35 +00002114
2115 /* Route-map */
2116 zebra_route_map_init ();
paul718e3742002-12-13 20:15:29 +00002117}
Denis Ovsienko97be79f2009-07-24 20:45:31 +04002118
2119/* Make zebra server socket, wiping any existing one (see bug #403). */
2120void
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04002121zebra_zserv_socket_init (char *path)
Denis Ovsienko97be79f2009-07-24 20:45:31 +04002122{
2123#ifdef HAVE_TCP_ZEBRA
2124 zebra_serv ();
2125#else
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04002126 zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
Denis Ovsienko97be79f2009-07-24 20:45:31 +04002127#endif /* HAVE_TCP_ZEBRA */
2128}