blob: 7a75ed420a825201d46b27e15f9a2967570452b8 [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 {
Christian Frankefa713d92013-07-05 15:35:37 +0000400 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
401 || nexthop_has_fib_child(nexthop))
paulb9df2d22004-05-09 09:09:59 +0000402 {
paul1dcb5172005-05-31 08:38:50 +0000403 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
404 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
405
406 if (nhnummark == 0)
407 {
408 nhnummark = stream_get_endp (s);
409 stream_putc (s, 1); /* placeholder */
410 }
411
paulb9df2d22004-05-09 09:09:59 +0000412 nhnum++;
paul718e3742002-12-13 20:15:29 +0000413
paulb9df2d22004-05-09 09:09:59 +0000414 switch(nexthop->type)
415 {
416 case NEXTHOP_TYPE_IPV4:
417 case NEXTHOP_TYPE_IPV4_IFINDEX:
418 stream_put_in_addr (s, &nexthop->gate.ipv4);
419 break;
420#ifdef HAVE_IPV6
421 case NEXTHOP_TYPE_IPV6:
422 case NEXTHOP_TYPE_IPV6_IFINDEX:
423 case NEXTHOP_TYPE_IPV6_IFNAME:
424 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
425 break;
426#endif
427 default:
428 if (cmd == ZEBRA_IPV4_ROUTE_ADD
429 || cmd == ZEBRA_IPV4_ROUTE_DELETE)
430 {
431 struct in_addr empty;
paul44983cf2004-09-22 13:15:58 +0000432 memset (&empty, 0, sizeof (struct in_addr));
paulb9df2d22004-05-09 09:09:59 +0000433 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
434 }
435 else
436 {
437 struct in6_addr empty;
438 memset (&empty, 0, sizeof (struct in6_addr));
439 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
440 }
441 }
paul718e3742002-12-13 20:15:29 +0000442
paulb9df2d22004-05-09 09:09:59 +0000443 /* Interface index. */
444 stream_putc (s, 1);
445 stream_putl (s, nexthop->ifindex);
paul718e3742002-12-13 20:15:29 +0000446
paulb9df2d22004-05-09 09:09:59 +0000447 break;
448 }
paul718e3742002-12-13 20:15:29 +0000449 }
450
451 /* Metric */
Stephen Hemmingercf8a8312010-08-18 15:56:46 -0700452 if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
paul1dcb5172005-05-31 08:38:50 +0000453 {
vincentfbf5d032005-09-29 11:25:50 +0000454 SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
455 stream_putc (s, rib->distance);
paul1dcb5172005-05-31 08:38:50 +0000456 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
457 stream_putl (s, rib->metric);
Timo Teräsb11f3b52015-11-02 16:50:07 +0200458 SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
459 stream_putl (s, rib->mtu);
paul1dcb5172005-05-31 08:38:50 +0000460 }
461
462 /* write real message flags value */
463 stream_putc_at (s, messmark, zapi_flags);
464
paulb9df2d22004-05-09 09:09:59 +0000465 /* Write next-hop number */
466 if (nhnummark)
hassoc1eaa442004-10-19 06:26:01 +0000467 stream_putc_at (s, nhnummark, nhnum);
paulb9df2d22004-05-09 09:09:59 +0000468
paul718e3742002-12-13 20:15:29 +0000469 /* Write packet size. */
470 stream_putw_at (s, 0, stream_get_endp (s));
471
ajs719e9742005-02-28 20:52:15 +0000472 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000473}
474
paul718e3742002-12-13 20:15:29 +0000475#ifdef HAVE_IPV6
ajs719e9742005-02-28 20:52:15 +0000476static int
Feng Luc99f3482014-10-16 09:52:36 +0800477zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
478 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000479{
480 struct stream *s;
481 struct rib *rib;
482 unsigned long nump;
483 u_char num;
484 struct nexthop *nexthop;
485
486 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800487 rib = rib_match_ipv6 (addr, vrf_id);
paul718e3742002-12-13 20:15:29 +0000488
489 /* Get output stream. */
490 s = client->obuf;
491 stream_reset (s);
492
493 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800494 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
Hiroshi Yokoi8ccd74c2015-09-08 11:52:20 +0900495 stream_put (s, addr, 16);
paul718e3742002-12-13 20:15:29 +0000496
497 if (rib)
498 {
499 stream_putl (s, rib->metric);
500 num = 0;
paul9985f832005-02-09 15:51:56 +0000501 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000502 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000503 /* Only non-recursive routes are elegible to resolve nexthop we
504 * are looking up. Therefore, we will just iterate over the top
505 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000506 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
507 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
508 {
509 stream_putc (s, nexthop->type);
510 switch (nexthop->type)
511 {
512 case ZEBRA_NEXTHOP_IPV6:
513 stream_put (s, &nexthop->gate.ipv6, 16);
514 break;
515 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
516 case ZEBRA_NEXTHOP_IPV6_IFNAME:
517 stream_put (s, &nexthop->gate.ipv6, 16);
518 stream_putl (s, nexthop->ifindex);
519 break;
520 case ZEBRA_NEXTHOP_IFINDEX:
521 case ZEBRA_NEXTHOP_IFNAME:
522 stream_putl (s, nexthop->ifindex);
523 break;
hassofa2b17e2004-03-04 17:45:00 +0000524 default:
525 /* do nothing */
526 break;
paul718e3742002-12-13 20:15:29 +0000527 }
528 num++;
529 }
530 stream_putc_at (s, nump, num);
531 }
532 else
533 {
534 stream_putl (s, 0);
535 stream_putc (s, 0);
536 }
537
538 stream_putw_at (s, 0, stream_get_endp (s));
539
ajs719e9742005-02-28 20:52:15 +0000540 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000541}
542#endif /* HAVE_IPV6 */
543
paulb9df2d22004-05-09 09:09:59 +0000544static int
Feng Luc99f3482014-10-16 09:52:36 +0800545zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
546 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000547{
548 struct stream *s;
549 struct rib *rib;
550 unsigned long nump;
551 u_char num;
552 struct nexthop *nexthop;
553
David Lamparterf598cf72014-11-22 14:44:20 -0800554 /* Lookup nexthop - eBGP excluded */
Feng Luc99f3482014-10-16 09:52:36 +0800555 rib = rib_match_ipv4_safi (addr, SAFI_UNICAST, 1, NULL, vrf_id);
paul718e3742002-12-13 20:15:29 +0000556
557 /* Get output stream. */
558 s = client->obuf;
559 stream_reset (s);
560
561 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800562 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000563 stream_put_in_addr (s, &addr);
564
565 if (rib)
566 {
Christian Frankebb97e462013-05-25 14:01:35 +0000567 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
568 zlog_debug("%s: Matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000569 stream_putl (s, rib->metric);
570 num = 0;
paul9985f832005-02-09 15:51:56 +0000571 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000572 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000573 /* Only non-recursive routes are elegible to resolve the nexthop we
574 * are looking up. Therefore, we will just iterate over the top
575 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000576 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
577 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
578 {
579 stream_putc (s, nexthop->type);
580 switch (nexthop->type)
581 {
582 case ZEBRA_NEXTHOP_IPV4:
583 stream_put_in_addr (s, &nexthop->gate.ipv4);
584 break;
Christian Frankebb97e462013-05-25 14:01:35 +0000585 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
586 stream_put_in_addr (s, &nexthop->gate.ipv4);
587 stream_putl (s, nexthop->ifindex);
588 break;
paul718e3742002-12-13 20:15:29 +0000589 case ZEBRA_NEXTHOP_IFINDEX:
590 case ZEBRA_NEXTHOP_IFNAME:
591 stream_putl (s, nexthop->ifindex);
592 break;
hassofa2b17e2004-03-04 17:45:00 +0000593 default:
594 /* do nothing */
595 break;
paul718e3742002-12-13 20:15:29 +0000596 }
597 num++;
598 }
599 stream_putc_at (s, nump, num);
600 }
601 else
602 {
Christian Frankebb97e462013-05-25 14:01:35 +0000603 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
604 zlog_debug("%s: No matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000605 stream_putl (s, 0);
606 stream_putc (s, 0);
607 }
608
609 stream_putw_at (s, 0, stream_get_endp (s));
610
ajs719e9742005-02-28 20:52:15 +0000611 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000612}
613
Everton Marques4e5275b2014-07-01 15:15:52 -0300614/*
615 Modified version of zsend_ipv4_nexthop_lookup():
616 Query unicast rib if nexthop is not found on mrib.
617 Returns both route metric and protocol distance.
618*/
619static int
David Lamparterbd078122015-01-06 19:53:24 +0100620zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr,
621 struct rib *rib)
Everton Marques4e5275b2014-07-01 15:15:52 -0300622{
623 struct stream *s;
Everton Marques4e5275b2014-07-01 15:15:52 -0300624 unsigned long nump;
625 u_char num;
626 struct nexthop *nexthop;
Everton Marques4e5275b2014-07-01 15:15:52 -0300627
628 /* Get output stream. */
629 s = client->obuf;
630 stream_reset (s);
631
632 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800633 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, rib->vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -0300634 stream_put_in_addr (s, &addr);
635
636 if (rib)
637 {
638 stream_putc (s, rib->distance);
639 stream_putl (s, rib->metric);
640 num = 0;
641 nump = stream_get_endp(s); /* remember position for nexthop_num */
642 stream_putc (s, 0); /* reserve room for nexthop_num */
643 /* Only non-recursive routes are elegible to resolve the nexthop we
644 * are looking up. Therefore, we will just iterate over the top
645 * chain of nexthops. */
646 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
647 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
648 {
649 stream_putc (s, nexthop->type);
650 switch (nexthop->type)
651 {
652 case ZEBRA_NEXTHOP_IPV4:
653 stream_put_in_addr (s, &nexthop->gate.ipv4);
654 break;
655 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
656 stream_put_in_addr (s, &nexthop->gate.ipv4);
657 stream_putl (s, nexthop->ifindex);
658 break;
659 case ZEBRA_NEXTHOP_IFINDEX:
660 case ZEBRA_NEXTHOP_IFNAME:
661 stream_putl (s, nexthop->ifindex);
662 break;
663 default:
664 /* do nothing */
665 break;
666 }
667 num++;
668 }
669
670 stream_putc_at (s, nump, num); /* store nexthop_num */
671 }
672 else
673 {
674 stream_putc (s, 0); /* distance */
675 stream_putl (s, 0); /* metric */
676 stream_putc (s, 0); /* nexthop_num */
677 }
678
679 stream_putw_at (s, 0, stream_get_endp (s));
680
681 return zebra_server_send_message(client);
682}
683
paulb9df2d22004-05-09 09:09:59 +0000684static int
Feng Luc99f3482014-10-16 09:52:36 +0800685zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
686 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000687{
688 struct stream *s;
689 struct rib *rib;
690 unsigned long nump;
691 u_char num;
692 struct nexthop *nexthop;
693
694 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800695 rib = rib_lookup_ipv4 (p, vrf_id);
paul718e3742002-12-13 20:15:29 +0000696
697 /* Get output stream. */
698 s = client->obuf;
699 stream_reset (s);
700
701 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800702 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000703 stream_put_in_addr (s, &p->prefix);
704
705 if (rib)
706 {
707 stream_putl (s, rib->metric);
708 num = 0;
paul9985f832005-02-09 15:51:56 +0000709 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000710 stream_putc (s, 0);
711 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Christian Frankefa713d92013-07-05 15:35:37 +0000712 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
713 || nexthop_has_fib_child(nexthop))
paul718e3742002-12-13 20:15:29 +0000714 {
715 stream_putc (s, nexthop->type);
716 switch (nexthop->type)
717 {
718 case ZEBRA_NEXTHOP_IPV4:
719 stream_put_in_addr (s, &nexthop->gate.ipv4);
720 break;
Christian Frankea12afd52013-05-25 14:01:36 +0000721 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
722 stream_put_in_addr (s, &nexthop->gate.ipv4);
723 stream_putl (s, nexthop->ifindex);
724 break;
paul718e3742002-12-13 20:15:29 +0000725 case ZEBRA_NEXTHOP_IFINDEX:
726 case ZEBRA_NEXTHOP_IFNAME:
727 stream_putl (s, nexthop->ifindex);
728 break;
hassofa2b17e2004-03-04 17:45:00 +0000729 default:
730 /* do nothing */
731 break;
paul718e3742002-12-13 20:15:29 +0000732 }
733 num++;
734 }
735 stream_putc_at (s, nump, num);
736 }
737 else
738 {
739 stream_putl (s, 0);
740 stream_putc (s, 0);
741 }
742
743 stream_putw_at (s, 0, stream_get_endp (s));
744
ajs719e9742005-02-28 20:52:15 +0000745 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000746}
David Lamparter6b0655a2014-06-04 06:53:35 +0200747
hasso18a6dce2004-10-03 18:18:34 +0000748/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
749int
Feng Luac19a442015-05-22 11:40:07 +0200750zsend_router_id_update (struct zserv *client, struct prefix *p,
751 vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +0000752{
753 struct stream *s;
754 int blen;
755
756 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800757 if (! vrf_bitmap_check (client->ridinfo, vrf_id))
ajs719e9742005-02-28 20:52:15 +0000758 return 0;
hasso18a6dce2004-10-03 18:18:34 +0000759
760 s = client->obuf;
761 stream_reset (s);
762
hasso18a6dce2004-10-03 18:18:34 +0000763 /* Message type. */
Feng Luc99f3482014-10-16 09:52:36 +0800764 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +0000765
766 /* Prefix information. */
767 stream_putc (s, p->family);
768 blen = prefix_blen (p);
769 stream_put (s, &p->u.prefix, blen);
770 stream_putc (s, p->prefixlen);
771
772 /* Write packet size. */
773 stream_putw_at (s, 0, stream_get_endp (s));
774
ajs719e9742005-02-28 20:52:15 +0000775 return zebra_server_send_message(client);
hasso18a6dce2004-10-03 18:18:34 +0000776}
David Lamparter6b0655a2014-06-04 06:53:35 +0200777
paul718e3742002-12-13 20:15:29 +0000778/* Register zebra server interface information. Send current all
779 interface and address information. */
ajs719e9742005-02-28 20:52:15 +0000780static int
Feng Luc99f3482014-10-16 09:52:36 +0800781zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000782{
paul1eb8ef22005-04-07 07:30:20 +0000783 struct listnode *ifnode, *ifnnode;
784 struct listnode *cnode, *cnnode;
paul718e3742002-12-13 20:15:29 +0000785 struct interface *ifp;
786 struct connected *c;
787
788 /* Interface information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +0800789 vrf_bitmap_set (client->ifinfo, vrf_id);
paul718e3742002-12-13 20:15:29 +0000790
Feng Luc99f3482014-10-16 09:52:36 +0800791 for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
paul718e3742002-12-13 20:15:29 +0000792 {
paul718e3742002-12-13 20:15:29 +0000793 /* Skip pseudo interface. */
794 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
795 continue;
796
ajs719e9742005-02-28 20:52:15 +0000797 if (zsend_interface_add (client, ifp) < 0)
798 return -1;
paul718e3742002-12-13 20:15:29 +0000799
paul1eb8ef22005-04-07 07:30:20 +0000800 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
paul718e3742002-12-13 20:15:29 +0000801 {
ajs719e9742005-02-28 20:52:15 +0000802 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
803 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
804 ifp, c) < 0))
805 return -1;
paul718e3742002-12-13 20:15:29 +0000806 }
807 }
ajs719e9742005-02-28 20:52:15 +0000808 return 0;
paul718e3742002-12-13 20:15:29 +0000809}
810
811/* Unregister zebra server interface information. */
ajs719e9742005-02-28 20:52:15 +0000812static int
Feng Luc99f3482014-10-16 09:52:36 +0800813zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000814{
Feng Luc99f3482014-10-16 09:52:36 +0800815 vrf_bitmap_unset (client->ifinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +0000816 return 0;
paul718e3742002-12-13 20:15:29 +0000817}
818
819/* This function support multiple nexthop. */
paulb9df2d22004-05-09 09:09:59 +0000820/*
821 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
822 * add kernel route.
823 */
ajs719e9742005-02-28 20:52:15 +0000824static int
Feng Luc99f3482014-10-16 09:52:36 +0800825zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000826{
827 int i;
828 struct rib *rib;
829 struct prefix_ipv4 p;
830 u_char message;
831 struct in_addr nexthop;
832 u_char nexthop_num;
833 u_char nexthop_type;
834 struct stream *s;
835 unsigned int ifindex;
836 u_char ifname_len;
G.Balajicddf3912011-11-26 21:59:32 +0400837 safi_t safi;
838
paul718e3742002-12-13 20:15:29 +0000839
840 /* Get input stream. */
841 s = client->ibuf;
842
843 /* Allocate new rib. */
paul4d38fdb2005-04-28 17:35:14 +0000844 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
845
paul718e3742002-12-13 20:15:29 +0000846 /* Type, flags, message. */
847 rib->type = stream_getc (s);
848 rib->flags = stream_getc (s);
paulb9df2d22004-05-09 09:09:59 +0000849 message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400850 safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000851 rib->uptime = time (NULL);
852
853 /* IPv4 prefix. */
854 memset (&p, 0, sizeof (struct prefix_ipv4));
855 p.family = AF_INET;
856 p.prefixlen = stream_getc (s);
857 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
858
Feng Lu0d0686f2015-05-22 11:40:02 +0200859 /* VRF ID */
Feng Luc99f3482014-10-16 09:52:36 +0800860 rib->vrf_id = vrf_id;
Feng Lu0d0686f2015-05-22 11:40:02 +0200861
paul718e3742002-12-13 20:15:29 +0000862 /* Nexthop parse. */
863 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
864 {
865 nexthop_num = stream_getc (s);
866
867 for (i = 0; i < nexthop_num; i++)
868 {
869 nexthop_type = stream_getc (s);
870
871 switch (nexthop_type)
872 {
873 case ZEBRA_NEXTHOP_IFINDEX:
874 ifindex = stream_getl (s);
875 nexthop_ifindex_add (rib, ifindex);
876 break;
877 case ZEBRA_NEXTHOP_IFNAME:
878 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000879 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000880 break;
881 case ZEBRA_NEXTHOP_IPV4:
882 nexthop.s_addr = stream_get_ipv4 (s);
Paul Jakma7514fb72007-05-02 16:05:35 +0000883 nexthop_ipv4_add (rib, &nexthop, NULL);
paul718e3742002-12-13 20:15:29 +0000884 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200885 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
886 nexthop.s_addr = stream_get_ipv4 (s);
887 ifindex = stream_getl (s);
888 nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
889 break;
paul718e3742002-12-13 20:15:29 +0000890 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000891 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000892 break;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700893 case ZEBRA_NEXTHOP_BLACKHOLE:
894 nexthop_blackhole_add (rib);
895 break;
896 }
paul718e3742002-12-13 20:15:29 +0000897 }
898 }
899
900 /* Distance. */
901 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
902 rib->distance = stream_getc (s);
903
904 /* Metric. */
905 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
906 rib->metric = stream_getl (s);
907
Timo Teräsb11f3b52015-11-02 16:50:07 +0200908 if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
909 rib->mtu = stream_getl (s);
910
Paul Jakma171eee32006-07-27 16:11:02 +0000911 /* Table */
912 rib->table=zebrad.rtm_table_default;
G.Balajicddf3912011-11-26 21:59:32 +0400913 rib_add_ipv4_multipath (&p, rib, safi);
ajs719e9742005-02-28 20:52:15 +0000914 return 0;
paul718e3742002-12-13 20:15:29 +0000915}
916
917/* Zebra server IPv4 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +0000918static int
Feng Luc99f3482014-10-16 09:52:36 +0800919zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000920{
921 int i;
922 struct stream *s;
923 struct zapi_ipv4 api;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700924 struct in_addr nexthop, *nexthop_p;
paul718e3742002-12-13 20:15:29 +0000925 unsigned long ifindex;
926 struct prefix_ipv4 p;
927 u_char nexthop_num;
928 u_char nexthop_type;
929 u_char ifname_len;
930
931 s = client->ibuf;
932 ifindex = 0;
933 nexthop.s_addr = 0;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700934 nexthop_p = NULL;
paul718e3742002-12-13 20:15:29 +0000935
936 /* Type, flags, message. */
937 api.type = stream_getc (s);
938 api.flags = stream_getc (s);
939 api.message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400940 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000941
942 /* IPv4 prefix. */
943 memset (&p, 0, sizeof (struct prefix_ipv4));
944 p.family = AF_INET;
945 p.prefixlen = stream_getc (s);
946 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
947
948 /* Nexthop, ifindex, distance, metric. */
949 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
950 {
951 nexthop_num = stream_getc (s);
952
953 for (i = 0; i < nexthop_num; i++)
954 {
955 nexthop_type = stream_getc (s);
956
957 switch (nexthop_type)
958 {
959 case ZEBRA_NEXTHOP_IFINDEX:
960 ifindex = stream_getl (s);
961 break;
962 case ZEBRA_NEXTHOP_IFNAME:
963 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000964 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000965 break;
966 case ZEBRA_NEXTHOP_IPV4:
967 nexthop.s_addr = stream_get_ipv4 (s);
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700968 nexthop_p = &nexthop;
paul718e3742002-12-13 20:15:29 +0000969 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200970 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
971 nexthop.s_addr = stream_get_ipv4 (s);
Christian Franke23f5f7c2013-11-27 17:06:14 +0000972 nexthop_p = &nexthop;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200973 ifindex = stream_getl (s);
974 break;
paul718e3742002-12-13 20:15:29 +0000975 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000976 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000977 break;
978 }
979 }
980 }
981
982 /* Distance. */
983 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
984 api.distance = stream_getc (s);
985 else
986 api.distance = 0;
987
988 /* Metric. */
989 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
990 api.metric = stream_getl (s);
991 else
992 api.metric = 0;
993
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700994 rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +0800995 vrf_id, api.safi);
ajs719e9742005-02-28 20:52:15 +0000996 return 0;
paul718e3742002-12-13 20:15:29 +0000997}
998
999/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +00001000static int
Feng Luc99f3482014-10-16 09:52:36 +08001001zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
1002 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001003{
1004 struct in_addr addr;
Christian Frankebb97e462013-05-25 14:01:35 +00001005 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00001006
1007 addr.s_addr = stream_get_ipv4 (client->ibuf);
Christian Frankebb97e462013-05-25 14:01:35 +00001008 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1009 zlog_debug("%s: looking up %s", __func__,
1010 inet_ntop (AF_INET, &addr, buf, BUFSIZ));
Feng Luc99f3482014-10-16 09:52:36 +08001011 return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001012}
1013
Everton Marques4e5275b2014-07-01 15:15:52 -03001014/* MRIB Nexthop lookup for IPv4. */
1015static int
Feng Luc99f3482014-10-16 09:52:36 +08001016zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length,
1017 vrf_id_t vrf_id)
Everton Marques4e5275b2014-07-01 15:15:52 -03001018{
1019 struct in_addr addr;
David Lamparterbd078122015-01-06 19:53:24 +01001020 struct rib *rib;
Everton Marques4e5275b2014-07-01 15:15:52 -03001021
1022 addr.s_addr = stream_get_ipv4 (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001023 rib = rib_match_ipv4_multicast (addr, NULL, vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +01001024 return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib);
Everton Marques4e5275b2014-07-01 15:15:52 -03001025}
1026
paul718e3742002-12-13 20:15:29 +00001027/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +00001028static int
Feng Luc99f3482014-10-16 09:52:36 +08001029zread_ipv4_import_lookup (struct zserv *client, u_short length,
1030 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001031{
1032 struct prefix_ipv4 p;
1033
1034 p.family = AF_INET;
1035 p.prefixlen = stream_getc (client->ibuf);
1036 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1037
Feng Luc99f3482014-10-16 09:52:36 +08001038 return zsend_ipv4_import_lookup (client, &p, vrf_id);
paul718e3742002-12-13 20:15:29 +00001039}
1040
1041#ifdef HAVE_IPV6
1042/* Zebra server IPv6 prefix add function. */
ajs719e9742005-02-28 20:52:15 +00001043static int
Feng Luc99f3482014-10-16 09:52:36 +08001044zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001045{
1046 int i;
1047 struct stream *s;
1048 struct zapi_ipv6 api;
1049 struct in6_addr nexthop;
1050 unsigned long ifindex;
1051 struct prefix_ipv6 p;
1052
1053 s = client->ibuf;
1054 ifindex = 0;
1055 memset (&nexthop, 0, sizeof (struct in6_addr));
1056
1057 /* Type, flags, message. */
1058 api.type = stream_getc (s);
1059 api.flags = stream_getc (s);
1060 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001061 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001062
1063 /* IPv4 prefix. */
1064 memset (&p, 0, sizeof (struct prefix_ipv6));
1065 p.family = AF_INET6;
1066 p.prefixlen = stream_getc (s);
1067 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1068
1069 /* Nexthop, ifindex, distance, metric. */
1070 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1071 {
1072 u_char nexthop_type;
1073
1074 api.nexthop_num = stream_getc (s);
1075 for (i = 0; i < api.nexthop_num; i++)
1076 {
1077 nexthop_type = stream_getc (s);
1078
1079 switch (nexthop_type)
1080 {
1081 case ZEBRA_NEXTHOP_IPV6:
1082 stream_get (&nexthop, s, 16);
1083 break;
1084 case ZEBRA_NEXTHOP_IFINDEX:
1085 ifindex = stream_getl (s);
1086 break;
1087 }
1088 }
1089 }
1090
1091 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1092 api.distance = stream_getc (s);
1093 else
1094 api.distance = 0;
1095
1096 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1097 api.metric = stream_getl (s);
1098 else
1099 api.metric = 0;
Timo Teräsb11f3b52015-11-02 16:50:07 +02001100
1101 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_MTU))
1102 api.mtu = stream_getl (s);
1103 else
1104 api.mtu = 0;
paul718e3742002-12-13 20:15:29 +00001105
1106 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Lu0d0686f2015-05-22 11:40:02 +02001107 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001108 vrf_id, zebrad.rtm_table_default, api.metric,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001109 api.mtu, api.distance, api.safi);
paul718e3742002-12-13 20:15:29 +00001110 else
Feng Lu0d0686f2015-05-22 11:40:02 +02001111 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001112 vrf_id, zebrad.rtm_table_default, api.metric,
Timo Teräsb11f3b52015-11-02 16:50:07 +02001113 api.mtu, api.distance, api.safi);
ajs719e9742005-02-28 20:52:15 +00001114 return 0;
paul718e3742002-12-13 20:15:29 +00001115}
1116
1117/* Zebra server IPv6 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +00001118static int
Feng Luc99f3482014-10-16 09:52:36 +08001119zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001120{
1121 int i;
1122 struct stream *s;
1123 struct zapi_ipv6 api;
1124 struct in6_addr nexthop;
1125 unsigned long ifindex;
1126 struct prefix_ipv6 p;
1127
1128 s = client->ibuf;
1129 ifindex = 0;
1130 memset (&nexthop, 0, sizeof (struct in6_addr));
1131
1132 /* Type, flags, message. */
1133 api.type = stream_getc (s);
1134 api.flags = stream_getc (s);
1135 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001136 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001137
1138 /* IPv4 prefix. */
1139 memset (&p, 0, sizeof (struct prefix_ipv6));
1140 p.family = AF_INET6;
1141 p.prefixlen = stream_getc (s);
1142 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1143
1144 /* Nexthop, ifindex, distance, metric. */
1145 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1146 {
1147 u_char nexthop_type;
1148
1149 api.nexthop_num = stream_getc (s);
1150 for (i = 0; i < api.nexthop_num; i++)
1151 {
1152 nexthop_type = stream_getc (s);
1153
1154 switch (nexthop_type)
1155 {
1156 case ZEBRA_NEXTHOP_IPV6:
1157 stream_get (&nexthop, s, 16);
1158 break;
1159 case ZEBRA_NEXTHOP_IFINDEX:
1160 ifindex = stream_getl (s);
1161 break;
1162 }
1163 }
1164 }
1165
1166 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1167 api.distance = stream_getc (s);
1168 else
1169 api.distance = 0;
1170 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1171 api.metric = stream_getl (s);
1172 else
1173 api.metric = 0;
1174
1175 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Luc99f3482014-10-16 09:52:36 +08001176 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001177 api.safi);
paul718e3742002-12-13 20:15:29 +00001178 else
Feng Luc99f3482014-10-16 09:52:36 +08001179 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001180 api.safi);
ajs719e9742005-02-28 20:52:15 +00001181 return 0;
paul718e3742002-12-13 20:15:29 +00001182}
1183
ajs719e9742005-02-28 20:52:15 +00001184static int
Feng Luc99f3482014-10-16 09:52:36 +08001185zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
1186 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001187{
1188 struct in6_addr addr;
1189 char buf[BUFSIZ];
1190
1191 stream_get (&addr, client->ibuf, 16);
Christian Frankea5207082013-04-11 08:24:29 +00001192 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1193 zlog_debug("%s: looking up %s", __func__,
1194 inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
paul718e3742002-12-13 20:15:29 +00001195
Feng Luc99f3482014-10-16 09:52:36 +08001196 return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001197}
1198#endif /* HAVE_IPV6 */
1199
hasso18a6dce2004-10-03 18:18:34 +00001200/* Register zebra server router-id information. Send current router-id */
ajs719e9742005-02-28 20:52:15 +00001201static int
Feng Luc99f3482014-10-16 09:52:36 +08001202zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001203{
1204 struct prefix p;
1205
1206 /* Router-id information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +08001207 vrf_bitmap_set (client->ridinfo, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001208
Feng Luc99f3482014-10-16 09:52:36 +08001209 router_id_get (&p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001210
Feng Luc99f3482014-10-16 09:52:36 +08001211 return zsend_router_id_update (client, &p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001212}
1213
1214/* Unregister zebra server router-id information. */
ajs719e9742005-02-28 20:52:15 +00001215static int
Feng Luc99f3482014-10-16 09:52:36 +08001216zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001217{
Feng Luc99f3482014-10-16 09:52:36 +08001218 vrf_bitmap_unset (client->ridinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +00001219 return 0;
hasso18a6dce2004-10-03 18:18:34 +00001220}
1221
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001222/* Tie up route-type and client->sock */
1223static void
1224zread_hello (struct zserv *client)
1225{
1226 /* type of protocol (lib/zebra.h) */
1227 u_char proto;
1228 proto = stream_getc (client->ibuf);
1229
1230 /* accept only dynamic routing protocols */
1231 if ((proto < ZEBRA_ROUTE_MAX)
1232 && (proto > ZEBRA_ROUTE_STATIC))
1233 {
1234 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1235 client->sock, zebra_route_string(proto));
1236
1237 /* if route-type was binded by other client */
1238 if (route_type_oaths[proto])
1239 zlog_warn ("sender of %s routes changed %c->%c",
1240 zebra_route_string(proto), route_type_oaths[proto],
1241 client->sock);
1242
1243 route_type_oaths[proto] = client->sock;
1244 }
1245}
1246
Feng Luc99f3482014-10-16 09:52:36 +08001247/* Unregister all information in a VRF. */
1248static int
1249zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
1250{
1251 int i;
1252
1253 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1254 vrf_bitmap_unset (client->redist[i], vrf_id);
1255 vrf_bitmap_unset (client->redist_default, vrf_id);
1256 vrf_bitmap_unset (client->ifinfo, vrf_id);
1257 vrf_bitmap_unset (client->ridinfo, vrf_id);
1258
1259 return 0;
1260}
1261
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001262/* If client sent routes of specific type, zebra removes it
1263 * and returns number of deleted routes.
1264 */
1265static void
1266zebra_score_rib (int client_sock)
1267{
1268 int i;
1269
1270 for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
1271 if (client_sock == route_type_oaths[i])
1272 {
1273 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1274 client_sock, rib_score_proto (i), zebra_route_string (i));
1275 route_type_oaths[i] = 0;
1276 break;
1277 }
1278}
1279
paul718e3742002-12-13 20:15:29 +00001280/* Close zebra client. */
paulb9df2d22004-05-09 09:09:59 +00001281static void
paul718e3742002-12-13 20:15:29 +00001282zebra_client_close (struct zserv *client)
1283{
1284 /* Close file descriptor. */
1285 if (client->sock)
1286 {
1287 close (client->sock);
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001288 zebra_score_rib (client->sock);
paul718e3742002-12-13 20:15:29 +00001289 client->sock = -1;
1290 }
1291
1292 /* Free stream buffers. */
1293 if (client->ibuf)
1294 stream_free (client->ibuf);
1295 if (client->obuf)
1296 stream_free (client->obuf);
ajs719e9742005-02-28 20:52:15 +00001297 if (client->wb)
1298 buffer_free(client->wb);
paul718e3742002-12-13 20:15:29 +00001299
1300 /* Release threads. */
1301 if (client->t_read)
1302 thread_cancel (client->t_read);
1303 if (client->t_write)
1304 thread_cancel (client->t_write);
ajs719e9742005-02-28 20:52:15 +00001305 if (client->t_suicide)
1306 thread_cancel (client->t_suicide);
paul718e3742002-12-13 20:15:29 +00001307
1308 /* Free client structure. */
paulb21b19c2003-06-15 01:28:29 +00001309 listnode_delete (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001310 XFREE (0, client);
1311}
1312
1313/* Make new client. */
paulb9df2d22004-05-09 09:09:59 +00001314static void
paul718e3742002-12-13 20:15:29 +00001315zebra_client_create (int sock)
1316{
1317 struct zserv *client;
Feng Luc99f3482014-10-16 09:52:36 +08001318 int i;
paul718e3742002-12-13 20:15:29 +00001319
1320 client = XCALLOC (0, sizeof (struct zserv));
1321
1322 /* Make client input/output buffer. */
1323 client->sock = sock;
1324 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1325 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
ajs719e9742005-02-28 20:52:15 +00001326 client->wb = buffer_new(0);
paul718e3742002-12-13 20:15:29 +00001327
1328 /* Set table number. */
paulb21b19c2003-06-15 01:28:29 +00001329 client->rtm_table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00001330
Feng Luc99f3482014-10-16 09:52:36 +08001331 /* Initialize flags */
1332 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1333 client->redist[i] = vrf_bitmap_init ();
1334 client->redist_default = vrf_bitmap_init ();
1335 client->ifinfo = vrf_bitmap_init ();
1336 client->ridinfo = vrf_bitmap_init ();
1337
paul718e3742002-12-13 20:15:29 +00001338 /* Add this client to linked list. */
paulb21b19c2003-06-15 01:28:29 +00001339 listnode_add (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001340
1341 /* Make new read thread. */
1342 zebra_event (ZEBRA_READ, sock, client);
1343}
1344
1345/* Handler of zebra service request. */
paulb9df2d22004-05-09 09:09:59 +00001346static int
paul718e3742002-12-13 20:15:29 +00001347zebra_client_read (struct thread *thread)
1348{
1349 int sock;
1350 struct zserv *client;
ajs57a14772005-04-10 15:01:56 +00001351 size_t already;
paulc1b98002006-01-16 01:54:02 +00001352 uint16_t length, command;
1353 uint8_t marker, version;
Feng Luc99f3482014-10-16 09:52:36 +08001354 vrf_id_t vrf_id;
paul718e3742002-12-13 20:15:29 +00001355
1356 /* Get thread data. Reset reading thread because I'm running. */
1357 sock = THREAD_FD (thread);
1358 client = THREAD_ARG (thread);
1359 client->t_read = NULL;
1360
ajs719e9742005-02-28 20:52:15 +00001361 if (client->t_suicide)
paul718e3742002-12-13 20:15:29 +00001362 {
ajs719e9742005-02-28 20:52:15 +00001363 zebra_client_close(client);
paul718e3742002-12-13 20:15:29 +00001364 return -1;
1365 }
ajs719e9742005-02-28 20:52:15 +00001366
1367 /* Read length and command (if we don't have it already). */
ajs57a14772005-04-10 15:01:56 +00001368 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
ajs719e9742005-02-28 20:52:15 +00001369 {
ajs57a14772005-04-10 15:01:56 +00001370 ssize_t nbyte;
ajs719e9742005-02-28 20:52:15 +00001371 if (((nbyte = stream_read_try (client->ibuf, sock,
ajs57a14772005-04-10 15:01:56 +00001372 ZEBRA_HEADER_SIZE-already)) == 0) ||
ajs719e9742005-02-28 20:52:15 +00001373 (nbyte == -1))
1374 {
1375 if (IS_ZEBRA_DEBUG_EVENT)
1376 zlog_debug ("connection closed socket [%d]", sock);
1377 zebra_client_close (client);
1378 return -1;
1379 }
ajs57a14772005-04-10 15:01:56 +00001380 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
ajs719e9742005-02-28 20:52:15 +00001381 {
1382 /* Try again later. */
1383 zebra_event (ZEBRA_READ, sock, client);
1384 return 0;
1385 }
ajs57a14772005-04-10 15:01:56 +00001386 already = ZEBRA_HEADER_SIZE;
ajs719e9742005-02-28 20:52:15 +00001387 }
1388
1389 /* Reset to read from the beginning of the incoming packet. */
1390 stream_set_getp(client->ibuf, 0);
1391
paulc1b98002006-01-16 01:54:02 +00001392 /* Fetch header values */
paul718e3742002-12-13 20:15:29 +00001393 length = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001394 marker = stream_getc (client->ibuf);
1395 version = stream_getc (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001396 vrf_id = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001397 command = stream_getw (client->ibuf);
paul718e3742002-12-13 20:15:29 +00001398
paulc1b98002006-01-16 01:54:02 +00001399 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1400 {
1401 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1402 __func__, sock, marker, version);
1403 zebra_client_close (client);
1404 return -1;
1405 }
ajs719e9742005-02-28 20:52:15 +00001406 if (length < ZEBRA_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00001407 {
ajs57a14772005-04-10 15:01:56 +00001408 zlog_warn("%s: socket %d message length %u is less than header size %d",
1409 __func__, sock, length, ZEBRA_HEADER_SIZE);
1410 zebra_client_close (client);
1411 return -1;
1412 }
1413 if (length > STREAM_SIZE(client->ibuf))
1414 {
1415 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1416 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
paul718e3742002-12-13 20:15:29 +00001417 zebra_client_close (client);
1418 return -1;
1419 }
1420
paul718e3742002-12-13 20:15:29 +00001421 /* Read rest of data. */
ajs57a14772005-04-10 15:01:56 +00001422 if (already < length)
paul718e3742002-12-13 20:15:29 +00001423 {
ajs57a14772005-04-10 15:01:56 +00001424 ssize_t nbyte;
1425 if (((nbyte = stream_read_try (client->ibuf, sock,
1426 length-already)) == 0) ||
1427 (nbyte == -1))
paul718e3742002-12-13 20:15:29 +00001428 {
1429 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001430 zlog_debug ("connection closed [%d] when reading zebra data", sock);
paul718e3742002-12-13 20:15:29 +00001431 zebra_client_close (client);
1432 return -1;
1433 }
ajs57a14772005-04-10 15:01:56 +00001434 if (nbyte != (ssize_t)(length-already))
ajs719e9742005-02-28 20:52:15 +00001435 {
1436 /* Try again later. */
1437 zebra_event (ZEBRA_READ, sock, client);
1438 return 0;
1439 }
paul718e3742002-12-13 20:15:29 +00001440 }
1441
ajs719e9742005-02-28 20:52:15 +00001442 length -= ZEBRA_HEADER_SIZE;
1443
paul718e3742002-12-13 20:15:29 +00001444 /* Debug packet information. */
1445 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001446 zlog_debug ("zebra message comes from socket [%d]", sock);
paul718e3742002-12-13 20:15:29 +00001447
1448 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
Feng Luc99f3482014-10-16 09:52:36 +08001449 zlog_debug ("zebra message received [%s] %d in VRF %u",
1450 zserv_command_string (command), length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001451
1452 switch (command)
1453 {
hasso18a6dce2004-10-03 18:18:34 +00001454 case ZEBRA_ROUTER_ID_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001455 zread_router_id_add (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001456 break;
1457 case ZEBRA_ROUTER_ID_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001458 zread_router_id_delete (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001459 break;
paul718e3742002-12-13 20:15:29 +00001460 case ZEBRA_INTERFACE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001461 zread_interface_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001462 break;
1463 case ZEBRA_INTERFACE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001464 zread_interface_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001465 break;
1466 case ZEBRA_IPV4_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001467 zread_ipv4_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001468 break;
1469 case ZEBRA_IPV4_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001470 zread_ipv4_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001471 break;
1472#ifdef HAVE_IPV6
1473 case ZEBRA_IPV6_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001474 zread_ipv6_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001475 break;
1476 case ZEBRA_IPV6_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001477 zread_ipv6_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001478 break;
1479#endif /* HAVE_IPV6 */
1480 case ZEBRA_REDISTRIBUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001481 zebra_redistribute_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001482 break;
1483 case ZEBRA_REDISTRIBUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001484 zebra_redistribute_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001485 break;
1486 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001487 zebra_redistribute_default_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001488 break;
1489 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001490 zebra_redistribute_default_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001491 break;
1492 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001493 zread_ipv4_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001494 break;
Everton Marques4e5275b2014-07-01 15:15:52 -03001495 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
Feng Luc99f3482014-10-16 09:52:36 +08001496 zread_ipv4_nexthop_lookup_mrib (client, length, vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -03001497 break;
paul718e3742002-12-13 20:15:29 +00001498#ifdef HAVE_IPV6
1499 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001500 zread_ipv6_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001501 break;
1502#endif /* HAVE_IPV6 */
1503 case ZEBRA_IPV4_IMPORT_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001504 zread_ipv4_import_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001505 break;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001506 case ZEBRA_HELLO:
1507 zread_hello (client);
1508 break;
Feng Luc99f3482014-10-16 09:52:36 +08001509 case ZEBRA_VRF_UNREGISTER:
1510 zread_vrf_unregister (client, length, vrf_id);
1511 break;
paul718e3742002-12-13 20:15:29 +00001512 default:
1513 zlog_info ("Zebra received unknown command %d", command);
1514 break;
1515 }
1516
ajs719e9742005-02-28 20:52:15 +00001517 if (client->t_suicide)
1518 {
1519 /* No need to wait for thread callback, just kill immediately. */
1520 zebra_client_close(client);
1521 return -1;
1522 }
1523
paul718e3742002-12-13 20:15:29 +00001524 stream_reset (client->ibuf);
1525 zebra_event (ZEBRA_READ, sock, client);
paul718e3742002-12-13 20:15:29 +00001526 return 0;
1527}
1528
paul718e3742002-12-13 20:15:29 +00001529
1530/* Accept code of zebra server socket. */
paulb9df2d22004-05-09 09:09:59 +00001531static int
paul718e3742002-12-13 20:15:29 +00001532zebra_accept (struct thread *thread)
1533{
1534 int accept_sock;
1535 int client_sock;
1536 struct sockaddr_in client;
1537 socklen_t len;
1538
1539 accept_sock = THREAD_FD (thread);
1540
ajs719e9742005-02-28 20:52:15 +00001541 /* Reregister myself. */
1542 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1543
paul718e3742002-12-13 20:15:29 +00001544 len = sizeof (struct sockaddr_in);
1545 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1546
1547 if (client_sock < 0)
1548 {
ajs6099b3b2004-11-20 02:06:59 +00001549 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001550 return -1;
1551 }
1552
paulccf35572003-03-01 11:42:20 +00001553 /* Make client socket non-blocking. */
ajs719e9742005-02-28 20:52:15 +00001554 set_nonblocking(client_sock);
paul865b8522005-01-05 08:30:35 +00001555
paul718e3742002-12-13 20:15:29 +00001556 /* Create new zebra client. */
1557 zebra_client_create (client_sock);
1558
paul718e3742002-12-13 20:15:29 +00001559 return 0;
1560}
1561
paulb9df2d22004-05-09 09:09:59 +00001562#ifdef HAVE_TCP_ZEBRA
paul718e3742002-12-13 20:15:29 +00001563/* Make zebra's server socket. */
paulb9df2d22004-05-09 09:09:59 +00001564static void
paul718e3742002-12-13 20:15:29 +00001565zebra_serv ()
1566{
1567 int ret;
1568 int accept_sock;
1569 struct sockaddr_in addr;
1570
1571 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1572
1573 if (accept_sock < 0)
1574 {
paul3d1dc852005-04-05 00:45:23 +00001575 zlog_warn ("Can't create zserv stream socket: %s",
1576 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001577 zlog_warn ("zebra can't provice full functionality due to above error");
1578 return;
1579 }
1580
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001581 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
paul718e3742002-12-13 20:15:29 +00001582 memset (&addr, 0, sizeof (struct sockaddr_in));
1583 addr.sin_family = AF_INET;
1584 addr.sin_port = htons (ZEBRA_PORT);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001585#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +00001586 addr.sin_len = sizeof (struct sockaddr_in);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001587#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +00001588 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1589
1590 sockopt_reuseaddr (accept_sock);
1591 sockopt_reuseport (accept_sock);
1592
pauledd7c242003-06-04 13:59:38 +00001593 if ( zserv_privs.change(ZPRIVS_RAISE) )
1594 zlog (NULL, LOG_ERR, "Can't raise privileges");
1595
paul718e3742002-12-13 20:15:29 +00001596 ret = bind (accept_sock, (struct sockaddr *)&addr,
1597 sizeof (struct sockaddr_in));
1598 if (ret < 0)
1599 {
paul3d1dc852005-04-05 00:45:23 +00001600 zlog_warn ("Can't bind to stream socket: %s",
1601 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001602 zlog_warn ("zebra can't provice full functionality due to above error");
1603 close (accept_sock); /* Avoid sd leak. */
1604 return;
1605 }
pauledd7c242003-06-04 13:59:38 +00001606
1607 if ( zserv_privs.change(ZPRIVS_LOWER) )
1608 zlog (NULL, LOG_ERR, "Can't lower privileges");
paul718e3742002-12-13 20:15:29 +00001609
1610 ret = listen (accept_sock, 1);
1611 if (ret < 0)
1612 {
paul3d1dc852005-04-05 00:45:23 +00001613 zlog_warn ("Can't listen to stream socket: %s",
1614 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001615 zlog_warn ("zebra can't provice full functionality due to above error");
1616 close (accept_sock); /* Avoid sd leak. */
1617 return;
1618 }
1619
1620 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1621}
David Lamparter4b6c3322015-04-21 09:47:57 +02001622#else /* HAVE_TCP_ZEBRA */
paul718e3742002-12-13 20:15:29 +00001623
1624/* For sockaddr_un. */
1625#include <sys/un.h>
1626
1627/* zebra server UNIX domain socket. */
paulb9df2d22004-05-09 09:09:59 +00001628static void
hassofce954f2004-10-07 20:29:24 +00001629zebra_serv_un (const char *path)
paul718e3742002-12-13 20:15:29 +00001630{
1631 int ret;
1632 int sock, len;
1633 struct sockaddr_un serv;
1634 mode_t old_mask;
1635
1636 /* First of all, unlink existing socket */
1637 unlink (path);
1638
1639 /* Set umask */
1640 old_mask = umask (0077);
1641
1642 /* Make UNIX domain socket. */
1643 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1644 if (sock < 0)
1645 {
paul3d1dc852005-04-05 00:45:23 +00001646 zlog_warn ("Can't create zserv unix socket: %s",
1647 safe_strerror (errno));
1648 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001649 return;
1650 }
1651
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001652 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1653
paul718e3742002-12-13 20:15:29 +00001654 /* Make server socket. */
1655 memset (&serv, 0, sizeof (struct sockaddr_un));
1656 serv.sun_family = AF_UNIX;
1657 strncpy (serv.sun_path, path, strlen (path));
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001658#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
paul718e3742002-12-13 20:15:29 +00001659 len = serv.sun_len = SUN_LEN(&serv);
1660#else
1661 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001662#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
paul718e3742002-12-13 20:15:29 +00001663
1664 ret = bind (sock, (struct sockaddr *) &serv, len);
1665 if (ret < 0)
1666 {
paul3d1dc852005-04-05 00:45:23 +00001667 zlog_warn ("Can't bind to unix socket %s: %s",
1668 path, safe_strerror (errno));
1669 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001670 close (sock);
1671 return;
1672 }
1673
1674 ret = listen (sock, 5);
1675 if (ret < 0)
1676 {
paul3d1dc852005-04-05 00:45:23 +00001677 zlog_warn ("Can't listen to unix socket %s: %s",
1678 path, safe_strerror (errno));
1679 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001680 close (sock);
1681 return;
1682 }
1683
1684 umask (old_mask);
1685
1686 zebra_event (ZEBRA_SERV, sock, NULL);
1687}
David Lamparter4b6c3322015-04-21 09:47:57 +02001688#endif /* HAVE_TCP_ZEBRA */
David Lamparter6b0655a2014-06-04 06:53:35 +02001689
paul718e3742002-12-13 20:15:29 +00001690
paulb9df2d22004-05-09 09:09:59 +00001691static void
paul718e3742002-12-13 20:15:29 +00001692zebra_event (enum event event, int sock, struct zserv *client)
1693{
1694 switch (event)
1695 {
1696 case ZEBRA_SERV:
paulb21b19c2003-06-15 01:28:29 +00001697 thread_add_read (zebrad.master, zebra_accept, client, sock);
paul718e3742002-12-13 20:15:29 +00001698 break;
1699 case ZEBRA_READ:
1700 client->t_read =
paulb21b19c2003-06-15 01:28:29 +00001701 thread_add_read (zebrad.master, zebra_client_read, client, sock);
paul718e3742002-12-13 20:15:29 +00001702 break;
1703 case ZEBRA_WRITE:
1704 /**/
1705 break;
1706 }
1707}
David Lamparter6b0655a2014-06-04 06:53:35 +02001708
paul718e3742002-12-13 20:15:29 +00001709/* Display default rtm_table for all clients. */
1710DEFUN (show_table,
1711 show_table_cmd,
1712 "show table",
1713 SHOW_STR
1714 "default routing table to use for all clients\n")
1715{
paulb21b19c2003-06-15 01:28:29 +00001716 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001717 VTY_NEWLINE);
1718 return CMD_SUCCESS;
1719}
1720
1721DEFUN (config_table,
1722 config_table_cmd,
1723 "table TABLENO",
1724 "Configure target kernel routing table\n"
1725 "TABLE integer\n")
1726{
paulb21b19c2003-06-15 01:28:29 +00001727 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
paul718e3742002-12-13 20:15:29 +00001728 return CMD_SUCCESS;
1729}
1730
hasso647e4f12003-05-25 11:43:52 +00001731DEFUN (ip_forwarding,
1732 ip_forwarding_cmd,
1733 "ip forwarding",
1734 IP_STR
1735 "Turn on IP forwarding")
1736{
1737 int ret;
1738
1739 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001740 if (ret == 0)
1741 ret = ipforward_on ();
hasso647e4f12003-05-25 11:43:52 +00001742
hasso647e4f12003-05-25 11:43:52 +00001743 if (ret == 0)
1744 {
1745 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1746 return CMD_WARNING;
1747 }
1748
1749 return CMD_SUCCESS;
1750}
1751
paul718e3742002-12-13 20:15:29 +00001752DEFUN (no_ip_forwarding,
1753 no_ip_forwarding_cmd,
1754 "no ip forwarding",
1755 NO_STR
1756 IP_STR
1757 "Turn off IP forwarding")
1758{
1759 int ret;
1760
1761 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001762 if (ret != 0)
1763 ret = ipforward_off ();
paul718e3742002-12-13 20:15:29 +00001764
paul718e3742002-12-13 20:15:29 +00001765 if (ret != 0)
1766 {
1767 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1768 return CMD_WARNING;
1769 }
1770
1771 return CMD_SUCCESS;
1772}
1773
1774/* This command is for debugging purpose. */
1775DEFUN (show_zebra_client,
1776 show_zebra_client_cmd,
1777 "show zebra client",
1778 SHOW_STR
1779 "Zebra information"
1780 "Client information")
1781{
hasso52dc7ee2004-09-23 19:18:23 +00001782 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001783 struct zserv *client;
1784
paul1eb8ef22005-04-07 07:30:20 +00001785 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1786 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1787
paul718e3742002-12-13 20:15:29 +00001788 return CMD_SUCCESS;
1789}
1790
1791/* Table configuration write function. */
paulb9df2d22004-05-09 09:09:59 +00001792static int
paul718e3742002-12-13 20:15:29 +00001793config_write_table (struct vty *vty)
1794{
paulb21b19c2003-06-15 01:28:29 +00001795 if (zebrad.rtm_table_default)
1796 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001797 VTY_NEWLINE);
1798 return 0;
1799}
1800
1801/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001802static struct cmd_node table_node =
paul718e3742002-12-13 20:15:29 +00001803{
1804 TABLE_NODE,
1805 "", /* This node has no interface. */
1806 1
1807};
David Lamparter6b0655a2014-06-04 06:53:35 +02001808
paul718e3742002-12-13 20:15:29 +00001809/* Only display ip forwarding is enabled or not. */
1810DEFUN (show_ip_forwarding,
1811 show_ip_forwarding_cmd,
1812 "show ip forwarding",
1813 SHOW_STR
1814 IP_STR
1815 "IP forwarding status\n")
1816{
1817 int ret;
1818
1819 ret = ipforward ();
1820
1821 if (ret == 0)
1822 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1823 else
1824 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1825 return CMD_SUCCESS;
1826}
1827
1828#ifdef HAVE_IPV6
1829/* Only display ipv6 forwarding is enabled or not. */
1830DEFUN (show_ipv6_forwarding,
1831 show_ipv6_forwarding_cmd,
1832 "show ipv6 forwarding",
1833 SHOW_STR
1834 "IPv6 information\n"
1835 "Forwarding status\n")
1836{
1837 int ret;
1838
1839 ret = ipforward_ipv6 ();
1840
1841 switch (ret)
1842 {
1843 case -1:
1844 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1845 break;
1846 case 0:
1847 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1848 break;
1849 case 1:
1850 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1851 break;
1852 default:
1853 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1854 break;
1855 }
1856 return CMD_SUCCESS;
1857}
1858
hasso55906722004-02-11 22:42:16 +00001859DEFUN (ipv6_forwarding,
1860 ipv6_forwarding_cmd,
1861 "ipv6 forwarding",
1862 IPV6_STR
1863 "Turn on IPv6 forwarding")
1864{
1865 int ret;
1866
hasso41d3fc92004-04-06 11:59:00 +00001867 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001868 if (ret == 0)
1869 ret = ipforward_ipv6_on ();
hasso41d3fc92004-04-06 11:59:00 +00001870
hasso41d3fc92004-04-06 11:59:00 +00001871 if (ret == 0)
1872 {
hasso55906722004-02-11 22:42:16 +00001873 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1874 return CMD_WARNING;
1875 }
1876
1877 return CMD_SUCCESS;
1878}
1879
paul718e3742002-12-13 20:15:29 +00001880DEFUN (no_ipv6_forwarding,
1881 no_ipv6_forwarding_cmd,
1882 "no ipv6 forwarding",
1883 NO_STR
hasso55906722004-02-11 22:42:16 +00001884 IPV6_STR
1885 "Turn off IPv6 forwarding")
paul718e3742002-12-13 20:15:29 +00001886{
1887 int ret;
1888
hasso41d3fc92004-04-06 11:59:00 +00001889 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001890 if (ret != 0)
1891 ret = ipforward_ipv6_off ();
hasso41d3fc92004-04-06 11:59:00 +00001892
paul718e3742002-12-13 20:15:29 +00001893 if (ret != 0)
1894 {
1895 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1896 return CMD_WARNING;
1897 }
1898
1899 return CMD_SUCCESS;
1900}
1901
1902#endif /* HAVE_IPV6 */
1903
1904/* IPForwarding configuration write function. */
ajs719e9742005-02-28 20:52:15 +00001905static int
paul718e3742002-12-13 20:15:29 +00001906config_write_forwarding (struct vty *vty)
1907{
hasso18a6dce2004-10-03 18:18:34 +00001908 /* FIXME: Find better place for that. */
1909 router_id_write (vty);
1910
paul3e0b3a52004-08-23 18:58:32 +00001911 if (ipforward ())
1912 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001913#ifdef HAVE_IPV6
paul3e0b3a52004-08-23 18:58:32 +00001914 if (ipforward_ipv6 ())
1915 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001916#endif /* HAVE_IPV6 */
1917 vty_out (vty, "!%s", VTY_NEWLINE);
1918 return 0;
1919}
1920
1921/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001922static struct cmd_node forwarding_node =
paul718e3742002-12-13 20:15:29 +00001923{
1924 FORWARDING_NODE,
1925 "", /* This node has no interface. */
1926 1
1927};
1928
David Lamparter6b0655a2014-06-04 06:53:35 +02001929
paul718e3742002-12-13 20:15:29 +00001930/* Initialisation of zebra and installation of commands. */
1931void
paula1ac18c2005-06-28 17:17:12 +00001932zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001933{
1934 /* Client list init. */
paulb21b19c2003-06-15 01:28:29 +00001935 zebrad.client_list = list_new ();
paul718e3742002-12-13 20:15:29 +00001936
paul718e3742002-12-13 20:15:29 +00001937 /* Install configuration write function. */
1938 install_node (&table_node, config_write_table);
1939 install_node (&forwarding_node, config_write_forwarding);
1940
1941 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1942 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00001943 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001944 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1945 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1946
1947#ifdef HAVE_NETLINK
1948 install_element (VIEW_NODE, &show_table_cmd);
1949 install_element (ENABLE_NODE, &show_table_cmd);
1950 install_element (CONFIG_NODE, &config_table_cmd);
1951#endif /* HAVE_NETLINK */
1952
1953#ifdef HAVE_IPV6
1954 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1955 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
hasso55906722004-02-11 22:42:16 +00001956 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001957 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1958#endif /* HAVE_IPV6 */
Paul Jakma7514fb72007-05-02 16:05:35 +00001959
1960 /* Route-map */
1961 zebra_route_map_init ();
paul718e3742002-12-13 20:15:29 +00001962}
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001963
1964/* Make zebra server socket, wiping any existing one (see bug #403). */
1965void
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04001966zebra_zserv_socket_init (char *path)
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001967{
1968#ifdef HAVE_TCP_ZEBRA
1969 zebra_serv ();
1970#else
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04001971 zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001972#endif /* HAVE_TCP_ZEBRA */
1973}