blob: e26c8cac8253812220dbc4b3b6791a857d3810f2 [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);
458 }
459
460 /* write real message flags value */
461 stream_putc_at (s, messmark, zapi_flags);
462
paulb9df2d22004-05-09 09:09:59 +0000463 /* Write next-hop number */
464 if (nhnummark)
hassoc1eaa442004-10-19 06:26:01 +0000465 stream_putc_at (s, nhnummark, nhnum);
paulb9df2d22004-05-09 09:09:59 +0000466
paul718e3742002-12-13 20:15:29 +0000467 /* Write packet size. */
468 stream_putw_at (s, 0, stream_get_endp (s));
469
ajs719e9742005-02-28 20:52:15 +0000470 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000471}
472
paul718e3742002-12-13 20:15:29 +0000473#ifdef HAVE_IPV6
ajs719e9742005-02-28 20:52:15 +0000474static int
Feng Luc99f3482014-10-16 09:52:36 +0800475zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
476 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000477{
478 struct stream *s;
479 struct rib *rib;
480 unsigned long nump;
481 u_char num;
482 struct nexthop *nexthop;
483
484 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800485 rib = rib_match_ipv6 (addr, vrf_id);
paul718e3742002-12-13 20:15:29 +0000486
487 /* Get output stream. */
488 s = client->obuf;
489 stream_reset (s);
490
491 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800492 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
Hiroshi Yokoi8ccd74c2015-09-08 11:52:20 +0900493 stream_put (s, addr, 16);
paul718e3742002-12-13 20:15:29 +0000494
495 if (rib)
496 {
497 stream_putl (s, rib->metric);
498 num = 0;
paul9985f832005-02-09 15:51:56 +0000499 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000500 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000501 /* Only non-recursive routes are elegible to resolve nexthop we
502 * are looking up. Therefore, we will just iterate over the top
503 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000504 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
505 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
506 {
507 stream_putc (s, nexthop->type);
508 switch (nexthop->type)
509 {
510 case ZEBRA_NEXTHOP_IPV6:
511 stream_put (s, &nexthop->gate.ipv6, 16);
512 break;
513 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
514 case ZEBRA_NEXTHOP_IPV6_IFNAME:
515 stream_put (s, &nexthop->gate.ipv6, 16);
516 stream_putl (s, nexthop->ifindex);
517 break;
518 case ZEBRA_NEXTHOP_IFINDEX:
519 case ZEBRA_NEXTHOP_IFNAME:
520 stream_putl (s, nexthop->ifindex);
521 break;
hassofa2b17e2004-03-04 17:45:00 +0000522 default:
523 /* do nothing */
524 break;
paul718e3742002-12-13 20:15:29 +0000525 }
526 num++;
527 }
528 stream_putc_at (s, nump, num);
529 }
530 else
531 {
532 stream_putl (s, 0);
533 stream_putc (s, 0);
534 }
535
536 stream_putw_at (s, 0, stream_get_endp (s));
537
ajs719e9742005-02-28 20:52:15 +0000538 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000539}
540#endif /* HAVE_IPV6 */
541
paulb9df2d22004-05-09 09:09:59 +0000542static int
Feng Luc99f3482014-10-16 09:52:36 +0800543zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
544 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000545{
546 struct stream *s;
547 struct rib *rib;
548 unsigned long nump;
549 u_char num;
550 struct nexthop *nexthop;
551
David Lamparterf598cf72014-11-22 14:44:20 -0800552 /* Lookup nexthop - eBGP excluded */
Feng Luc99f3482014-10-16 09:52:36 +0800553 rib = rib_match_ipv4_safi (addr, SAFI_UNICAST, 1, NULL, vrf_id);
paul718e3742002-12-13 20:15:29 +0000554
555 /* Get output stream. */
556 s = client->obuf;
557 stream_reset (s);
558
559 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800560 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000561 stream_put_in_addr (s, &addr);
562
563 if (rib)
564 {
Christian Frankebb97e462013-05-25 14:01:35 +0000565 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
566 zlog_debug("%s: Matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000567 stream_putl (s, rib->metric);
568 num = 0;
paul9985f832005-02-09 15:51:56 +0000569 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000570 stream_putc (s, 0);
Christian Frankefa713d92013-07-05 15:35:37 +0000571 /* Only non-recursive routes are elegible to resolve the nexthop we
572 * are looking up. Therefore, we will just iterate over the top
573 * chain of nexthops. */
paul718e3742002-12-13 20:15:29 +0000574 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
575 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
576 {
577 stream_putc (s, nexthop->type);
578 switch (nexthop->type)
579 {
580 case ZEBRA_NEXTHOP_IPV4:
581 stream_put_in_addr (s, &nexthop->gate.ipv4);
582 break;
Christian Frankebb97e462013-05-25 14:01:35 +0000583 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
584 stream_put_in_addr (s, &nexthop->gate.ipv4);
585 stream_putl (s, nexthop->ifindex);
586 break;
paul718e3742002-12-13 20:15:29 +0000587 case ZEBRA_NEXTHOP_IFINDEX:
588 case ZEBRA_NEXTHOP_IFNAME:
589 stream_putl (s, nexthop->ifindex);
590 break;
hassofa2b17e2004-03-04 17:45:00 +0000591 default:
592 /* do nothing */
593 break;
paul718e3742002-12-13 20:15:29 +0000594 }
595 num++;
596 }
597 stream_putc_at (s, nump, num);
598 }
599 else
600 {
Christian Frankebb97e462013-05-25 14:01:35 +0000601 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
602 zlog_debug("%s: No matching rib entry found.", __func__);
paul718e3742002-12-13 20:15:29 +0000603 stream_putl (s, 0);
604 stream_putc (s, 0);
605 }
606
607 stream_putw_at (s, 0, stream_get_endp (s));
608
ajs719e9742005-02-28 20:52:15 +0000609 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000610}
611
Everton Marques4e5275b2014-07-01 15:15:52 -0300612/*
613 Modified version of zsend_ipv4_nexthop_lookup():
614 Query unicast rib if nexthop is not found on mrib.
615 Returns both route metric and protocol distance.
616*/
617static int
David Lamparterbd078122015-01-06 19:53:24 +0100618zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr,
619 struct rib *rib)
Everton Marques4e5275b2014-07-01 15:15:52 -0300620{
621 struct stream *s;
Everton Marques4e5275b2014-07-01 15:15:52 -0300622 unsigned long nump;
623 u_char num;
624 struct nexthop *nexthop;
Everton Marques4e5275b2014-07-01 15:15:52 -0300625
626 /* Get output stream. */
627 s = client->obuf;
628 stream_reset (s);
629
630 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800631 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, rib->vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -0300632 stream_put_in_addr (s, &addr);
633
634 if (rib)
635 {
636 stream_putc (s, rib->distance);
637 stream_putl (s, rib->metric);
638 num = 0;
639 nump = stream_get_endp(s); /* remember position for nexthop_num */
640 stream_putc (s, 0); /* reserve room for nexthop_num */
641 /* Only non-recursive routes are elegible to resolve the nexthop we
642 * are looking up. Therefore, we will just iterate over the top
643 * chain of nexthops. */
644 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
645 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
646 {
647 stream_putc (s, nexthop->type);
648 switch (nexthop->type)
649 {
650 case ZEBRA_NEXTHOP_IPV4:
651 stream_put_in_addr (s, &nexthop->gate.ipv4);
652 break;
653 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
654 stream_put_in_addr (s, &nexthop->gate.ipv4);
655 stream_putl (s, nexthop->ifindex);
656 break;
657 case ZEBRA_NEXTHOP_IFINDEX:
658 case ZEBRA_NEXTHOP_IFNAME:
659 stream_putl (s, nexthop->ifindex);
660 break;
661 default:
662 /* do nothing */
663 break;
664 }
665 num++;
666 }
667
668 stream_putc_at (s, nump, num); /* store nexthop_num */
669 }
670 else
671 {
672 stream_putc (s, 0); /* distance */
673 stream_putl (s, 0); /* metric */
674 stream_putc (s, 0); /* nexthop_num */
675 }
676
677 stream_putw_at (s, 0, stream_get_endp (s));
678
679 return zebra_server_send_message(client);
680}
681
paulb9df2d22004-05-09 09:09:59 +0000682static int
Feng Luc99f3482014-10-16 09:52:36 +0800683zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
684 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000685{
686 struct stream *s;
687 struct rib *rib;
688 unsigned long nump;
689 u_char num;
690 struct nexthop *nexthop;
691
692 /* Lookup nexthop. */
Feng Luc99f3482014-10-16 09:52:36 +0800693 rib = rib_lookup_ipv4 (p, vrf_id);
paul718e3742002-12-13 20:15:29 +0000694
695 /* Get output stream. */
696 s = client->obuf;
697 stream_reset (s);
698
699 /* Fill in result. */
Feng Luc99f3482014-10-16 09:52:36 +0800700 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
paul718e3742002-12-13 20:15:29 +0000701 stream_put_in_addr (s, &p->prefix);
702
703 if (rib)
704 {
705 stream_putl (s, rib->metric);
706 num = 0;
paul9985f832005-02-09 15:51:56 +0000707 nump = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000708 stream_putc (s, 0);
709 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
Christian Frankefa713d92013-07-05 15:35:37 +0000710 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
711 || nexthop_has_fib_child(nexthop))
paul718e3742002-12-13 20:15:29 +0000712 {
713 stream_putc (s, nexthop->type);
714 switch (nexthop->type)
715 {
716 case ZEBRA_NEXTHOP_IPV4:
717 stream_put_in_addr (s, &nexthop->gate.ipv4);
718 break;
Christian Frankea12afd52013-05-25 14:01:36 +0000719 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
720 stream_put_in_addr (s, &nexthop->gate.ipv4);
721 stream_putl (s, nexthop->ifindex);
722 break;
paul718e3742002-12-13 20:15:29 +0000723 case ZEBRA_NEXTHOP_IFINDEX:
724 case ZEBRA_NEXTHOP_IFNAME:
725 stream_putl (s, nexthop->ifindex);
726 break;
hassofa2b17e2004-03-04 17:45:00 +0000727 default:
728 /* do nothing */
729 break;
paul718e3742002-12-13 20:15:29 +0000730 }
731 num++;
732 }
733 stream_putc_at (s, nump, num);
734 }
735 else
736 {
737 stream_putl (s, 0);
738 stream_putc (s, 0);
739 }
740
741 stream_putw_at (s, 0, stream_get_endp (s));
742
ajs719e9742005-02-28 20:52:15 +0000743 return zebra_server_send_message(client);
paul718e3742002-12-13 20:15:29 +0000744}
David Lamparter6b0655a2014-06-04 06:53:35 +0200745
hasso18a6dce2004-10-03 18:18:34 +0000746/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
747int
Feng Luac19a442015-05-22 11:40:07 +0200748zsend_router_id_update (struct zserv *client, struct prefix *p,
749 vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +0000750{
751 struct stream *s;
752 int blen;
753
754 /* Check this client need interface information. */
Feng Luc99f3482014-10-16 09:52:36 +0800755 if (! vrf_bitmap_check (client->ridinfo, vrf_id))
ajs719e9742005-02-28 20:52:15 +0000756 return 0;
hasso18a6dce2004-10-03 18:18:34 +0000757
758 s = client->obuf;
759 stream_reset (s);
760
hasso18a6dce2004-10-03 18:18:34 +0000761 /* Message type. */
Feng Luc99f3482014-10-16 09:52:36 +0800762 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +0000763
764 /* Prefix information. */
765 stream_putc (s, p->family);
766 blen = prefix_blen (p);
767 stream_put (s, &p->u.prefix, blen);
768 stream_putc (s, p->prefixlen);
769
770 /* Write packet size. */
771 stream_putw_at (s, 0, stream_get_endp (s));
772
ajs719e9742005-02-28 20:52:15 +0000773 return zebra_server_send_message(client);
hasso18a6dce2004-10-03 18:18:34 +0000774}
David Lamparter6b0655a2014-06-04 06:53:35 +0200775
paul718e3742002-12-13 20:15:29 +0000776/* Register zebra server interface information. Send current all
777 interface and address information. */
ajs719e9742005-02-28 20:52:15 +0000778static int
Feng Luc99f3482014-10-16 09:52:36 +0800779zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000780{
paul1eb8ef22005-04-07 07:30:20 +0000781 struct listnode *ifnode, *ifnnode;
782 struct listnode *cnode, *cnnode;
paul718e3742002-12-13 20:15:29 +0000783 struct interface *ifp;
784 struct connected *c;
785
786 /* Interface information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +0800787 vrf_bitmap_set (client->ifinfo, vrf_id);
paul718e3742002-12-13 20:15:29 +0000788
Feng Luc99f3482014-10-16 09:52:36 +0800789 for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
paul718e3742002-12-13 20:15:29 +0000790 {
paul718e3742002-12-13 20:15:29 +0000791 /* Skip pseudo interface. */
792 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
793 continue;
794
ajs719e9742005-02-28 20:52:15 +0000795 if (zsend_interface_add (client, ifp) < 0)
796 return -1;
paul718e3742002-12-13 20:15:29 +0000797
paul1eb8ef22005-04-07 07:30:20 +0000798 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
paul718e3742002-12-13 20:15:29 +0000799 {
ajs719e9742005-02-28 20:52:15 +0000800 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
801 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
802 ifp, c) < 0))
803 return -1;
paul718e3742002-12-13 20:15:29 +0000804 }
805 }
ajs719e9742005-02-28 20:52:15 +0000806 return 0;
paul718e3742002-12-13 20:15:29 +0000807}
808
809/* Unregister zebra server interface information. */
ajs719e9742005-02-28 20:52:15 +0000810static int
Feng Luc99f3482014-10-16 09:52:36 +0800811zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000812{
Feng Luc99f3482014-10-16 09:52:36 +0800813 vrf_bitmap_unset (client->ifinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +0000814 return 0;
paul718e3742002-12-13 20:15:29 +0000815}
816
817/* This function support multiple nexthop. */
paulb9df2d22004-05-09 09:09:59 +0000818/*
819 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
820 * add kernel route.
821 */
ajs719e9742005-02-28 20:52:15 +0000822static int
Feng Luc99f3482014-10-16 09:52:36 +0800823zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000824{
825 int i;
826 struct rib *rib;
827 struct prefix_ipv4 p;
828 u_char message;
829 struct in_addr nexthop;
830 u_char nexthop_num;
831 u_char nexthop_type;
832 struct stream *s;
833 unsigned int ifindex;
834 u_char ifname_len;
G.Balajicddf3912011-11-26 21:59:32 +0400835 safi_t safi;
836
paul718e3742002-12-13 20:15:29 +0000837
838 /* Get input stream. */
839 s = client->ibuf;
840
841 /* Allocate new rib. */
paul4d38fdb2005-04-28 17:35:14 +0000842 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
843
paul718e3742002-12-13 20:15:29 +0000844 /* Type, flags, message. */
845 rib->type = stream_getc (s);
846 rib->flags = stream_getc (s);
paulb9df2d22004-05-09 09:09:59 +0000847 message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400848 safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000849 rib->uptime = time (NULL);
850
851 /* IPv4 prefix. */
852 memset (&p, 0, sizeof (struct prefix_ipv4));
853 p.family = AF_INET;
854 p.prefixlen = stream_getc (s);
855 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
856
Feng Lu0d0686f2015-05-22 11:40:02 +0200857 /* VRF ID */
Feng Luc99f3482014-10-16 09:52:36 +0800858 rib->vrf_id = vrf_id;
Feng Lu0d0686f2015-05-22 11:40:02 +0200859
paul718e3742002-12-13 20:15:29 +0000860 /* Nexthop parse. */
861 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
862 {
863 nexthop_num = stream_getc (s);
864
865 for (i = 0; i < nexthop_num; i++)
866 {
867 nexthop_type = stream_getc (s);
868
869 switch (nexthop_type)
870 {
871 case ZEBRA_NEXTHOP_IFINDEX:
872 ifindex = stream_getl (s);
873 nexthop_ifindex_add (rib, ifindex);
874 break;
875 case ZEBRA_NEXTHOP_IFNAME:
876 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000877 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000878 break;
879 case ZEBRA_NEXTHOP_IPV4:
880 nexthop.s_addr = stream_get_ipv4 (s);
Paul Jakma7514fb72007-05-02 16:05:35 +0000881 nexthop_ipv4_add (rib, &nexthop, NULL);
paul718e3742002-12-13 20:15:29 +0000882 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200883 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
884 nexthop.s_addr = stream_get_ipv4 (s);
885 ifindex = stream_getl (s);
886 nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
887 break;
paul718e3742002-12-13 20:15:29 +0000888 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000889 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000890 break;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700891 case ZEBRA_NEXTHOP_BLACKHOLE:
892 nexthop_blackhole_add (rib);
893 break;
894 }
paul718e3742002-12-13 20:15:29 +0000895 }
896 }
897
898 /* Distance. */
899 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
900 rib->distance = stream_getc (s);
901
902 /* Metric. */
903 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
904 rib->metric = stream_getl (s);
905
Paul Jakma171eee32006-07-27 16:11:02 +0000906 /* Table */
907 rib->table=zebrad.rtm_table_default;
G.Balajicddf3912011-11-26 21:59:32 +0400908 rib_add_ipv4_multipath (&p, rib, safi);
ajs719e9742005-02-28 20:52:15 +0000909 return 0;
paul718e3742002-12-13 20:15:29 +0000910}
911
912/* Zebra server IPv4 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +0000913static int
Feng Luc99f3482014-10-16 09:52:36 +0800914zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000915{
916 int i;
917 struct stream *s;
918 struct zapi_ipv4 api;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700919 struct in_addr nexthop, *nexthop_p;
paul718e3742002-12-13 20:15:29 +0000920 unsigned long ifindex;
921 struct prefix_ipv4 p;
922 u_char nexthop_num;
923 u_char nexthop_type;
924 u_char ifname_len;
925
926 s = client->ibuf;
927 ifindex = 0;
928 nexthop.s_addr = 0;
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700929 nexthop_p = NULL;
paul718e3742002-12-13 20:15:29 +0000930
931 /* Type, flags, message. */
932 api.type = stream_getc (s);
933 api.flags = stream_getc (s);
934 api.message = stream_getc (s);
G.Balajicddf3912011-11-26 21:59:32 +0400935 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +0000936
937 /* IPv4 prefix. */
938 memset (&p, 0, sizeof (struct prefix_ipv4));
939 p.family = AF_INET;
940 p.prefixlen = stream_getc (s);
941 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
942
943 /* Nexthop, ifindex, distance, metric. */
944 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
945 {
946 nexthop_num = stream_getc (s);
947
948 for (i = 0; i < nexthop_num; i++)
949 {
950 nexthop_type = stream_getc (s);
951
952 switch (nexthop_type)
953 {
954 case ZEBRA_NEXTHOP_IFINDEX:
955 ifindex = stream_getl (s);
956 break;
957 case ZEBRA_NEXTHOP_IFNAME:
958 ifname_len = stream_getc (s);
paul9985f832005-02-09 15:51:56 +0000959 stream_forward_getp (s, ifname_len);
paul718e3742002-12-13 20:15:29 +0000960 break;
961 case ZEBRA_NEXTHOP_IPV4:
962 nexthop.s_addr = stream_get_ipv4 (s);
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700963 nexthop_p = &nexthop;
paul718e3742002-12-13 20:15:29 +0000964 break;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200965 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
966 nexthop.s_addr = stream_get_ipv4 (s);
Christian Franke23f5f7c2013-11-27 17:06:14 +0000967 nexthop_p = &nexthop;
Joakim Tjernlundc963c202012-07-07 17:06:13 +0200968 ifindex = stream_getl (s);
969 break;
paul718e3742002-12-13 20:15:29 +0000970 case ZEBRA_NEXTHOP_IPV6:
paul9985f832005-02-09 15:51:56 +0000971 stream_forward_getp (s, IPV6_MAX_BYTELEN);
paul718e3742002-12-13 20:15:29 +0000972 break;
973 }
974 }
975 }
976
977 /* Distance. */
978 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
979 api.distance = stream_getc (s);
980 else
981 api.distance = 0;
982
983 /* Metric. */
984 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
985 api.metric = stream_getl (s);
986 else
987 api.metric = 0;
988
Subbaiah Venkata6902c692012-03-27 19:21:29 -0700989 rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +0800990 vrf_id, api.safi);
ajs719e9742005-02-28 20:52:15 +0000991 return 0;
paul718e3742002-12-13 20:15:29 +0000992}
993
994/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +0000995static int
Feng Luc99f3482014-10-16 09:52:36 +0800996zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
997 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000998{
999 struct in_addr addr;
Christian Frankebb97e462013-05-25 14:01:35 +00001000 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00001001
1002 addr.s_addr = stream_get_ipv4 (client->ibuf);
Christian Frankebb97e462013-05-25 14:01:35 +00001003 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1004 zlog_debug("%s: looking up %s", __func__,
1005 inet_ntop (AF_INET, &addr, buf, BUFSIZ));
Feng Luc99f3482014-10-16 09:52:36 +08001006 return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001007}
1008
Everton Marques4e5275b2014-07-01 15:15:52 -03001009/* MRIB Nexthop lookup for IPv4. */
1010static int
Feng Luc99f3482014-10-16 09:52:36 +08001011zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length,
1012 vrf_id_t vrf_id)
Everton Marques4e5275b2014-07-01 15:15:52 -03001013{
1014 struct in_addr addr;
David Lamparterbd078122015-01-06 19:53:24 +01001015 struct rib *rib;
Everton Marques4e5275b2014-07-01 15:15:52 -03001016
1017 addr.s_addr = stream_get_ipv4 (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001018 rib = rib_match_ipv4_multicast (addr, NULL, vrf_id);
David Lamparterbd078122015-01-06 19:53:24 +01001019 return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib);
Everton Marques4e5275b2014-07-01 15:15:52 -03001020}
1021
paul718e3742002-12-13 20:15:29 +00001022/* Nexthop lookup for IPv4. */
ajs719e9742005-02-28 20:52:15 +00001023static int
Feng Luc99f3482014-10-16 09:52:36 +08001024zread_ipv4_import_lookup (struct zserv *client, u_short length,
1025 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001026{
1027 struct prefix_ipv4 p;
1028
1029 p.family = AF_INET;
1030 p.prefixlen = stream_getc (client->ibuf);
1031 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1032
Feng Luc99f3482014-10-16 09:52:36 +08001033 return zsend_ipv4_import_lookup (client, &p, vrf_id);
paul718e3742002-12-13 20:15:29 +00001034}
1035
1036#ifdef HAVE_IPV6
1037/* Zebra server IPv6 prefix add function. */
ajs719e9742005-02-28 20:52:15 +00001038static int
Feng Luc99f3482014-10-16 09:52:36 +08001039zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001040{
1041 int i;
1042 struct stream *s;
1043 struct zapi_ipv6 api;
1044 struct in6_addr nexthop;
1045 unsigned long ifindex;
1046 struct prefix_ipv6 p;
1047
1048 s = client->ibuf;
1049 ifindex = 0;
1050 memset (&nexthop, 0, sizeof (struct in6_addr));
1051
1052 /* Type, flags, message. */
1053 api.type = stream_getc (s);
1054 api.flags = stream_getc (s);
1055 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001056 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001057
1058 /* IPv4 prefix. */
1059 memset (&p, 0, sizeof (struct prefix_ipv6));
1060 p.family = AF_INET6;
1061 p.prefixlen = stream_getc (s);
1062 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1063
1064 /* Nexthop, ifindex, distance, metric. */
1065 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1066 {
1067 u_char nexthop_type;
1068
1069 api.nexthop_num = stream_getc (s);
1070 for (i = 0; i < api.nexthop_num; i++)
1071 {
1072 nexthop_type = stream_getc (s);
1073
1074 switch (nexthop_type)
1075 {
1076 case ZEBRA_NEXTHOP_IPV6:
1077 stream_get (&nexthop, s, 16);
1078 break;
1079 case ZEBRA_NEXTHOP_IFINDEX:
1080 ifindex = stream_getl (s);
1081 break;
1082 }
1083 }
1084 }
1085
1086 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1087 api.distance = stream_getc (s);
1088 else
1089 api.distance = 0;
1090
1091 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1092 api.metric = stream_getl (s);
1093 else
1094 api.metric = 0;
1095
1096 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Lu0d0686f2015-05-22 11:40:02 +02001097 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001098 vrf_id, zebrad.rtm_table_default, api.metric,
Feng Lu0d0686f2015-05-22 11:40:02 +02001099 api.distance, api.safi);
paul718e3742002-12-13 20:15:29 +00001100 else
Feng Lu0d0686f2015-05-22 11:40:02 +02001101 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex,
Feng Luc99f3482014-10-16 09:52:36 +08001102 vrf_id, zebrad.rtm_table_default, api.metric,
Feng Lu0d0686f2015-05-22 11:40:02 +02001103 api.distance, api.safi);
ajs719e9742005-02-28 20:52:15 +00001104 return 0;
paul718e3742002-12-13 20:15:29 +00001105}
1106
1107/* Zebra server IPv6 prefix delete function. */
ajs719e9742005-02-28 20:52:15 +00001108static int
Feng Luc99f3482014-10-16 09:52:36 +08001109zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001110{
1111 int i;
1112 struct stream *s;
1113 struct zapi_ipv6 api;
1114 struct in6_addr nexthop;
1115 unsigned long ifindex;
1116 struct prefix_ipv6 p;
1117
1118 s = client->ibuf;
1119 ifindex = 0;
1120 memset (&nexthop, 0, sizeof (struct in6_addr));
1121
1122 /* Type, flags, message. */
1123 api.type = stream_getc (s);
1124 api.flags = stream_getc (s);
1125 api.message = stream_getc (s);
G.Balajif768f362011-11-26 22:10:39 +04001126 api.safi = stream_getw (s);
paul718e3742002-12-13 20:15:29 +00001127
1128 /* IPv4 prefix. */
1129 memset (&p, 0, sizeof (struct prefix_ipv6));
1130 p.family = AF_INET6;
1131 p.prefixlen = stream_getc (s);
1132 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1133
1134 /* Nexthop, ifindex, distance, metric. */
1135 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1136 {
1137 u_char nexthop_type;
1138
1139 api.nexthop_num = stream_getc (s);
1140 for (i = 0; i < api.nexthop_num; i++)
1141 {
1142 nexthop_type = stream_getc (s);
1143
1144 switch (nexthop_type)
1145 {
1146 case ZEBRA_NEXTHOP_IPV6:
1147 stream_get (&nexthop, s, 16);
1148 break;
1149 case ZEBRA_NEXTHOP_IFINDEX:
1150 ifindex = stream_getl (s);
1151 break;
1152 }
1153 }
1154 }
1155
1156 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1157 api.distance = stream_getc (s);
1158 else
1159 api.distance = 0;
1160 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1161 api.metric = stream_getl (s);
1162 else
1163 api.metric = 0;
1164
1165 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
Feng Luc99f3482014-10-16 09:52:36 +08001166 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001167 api.safi);
paul718e3742002-12-13 20:15:29 +00001168 else
Feng Luc99f3482014-10-16 09:52:36 +08001169 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, vrf_id,
Feng Lu0d0686f2015-05-22 11:40:02 +02001170 api.safi);
ajs719e9742005-02-28 20:52:15 +00001171 return 0;
paul718e3742002-12-13 20:15:29 +00001172}
1173
ajs719e9742005-02-28 20:52:15 +00001174static int
Feng Luc99f3482014-10-16 09:52:36 +08001175zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
1176 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +00001177{
1178 struct in6_addr addr;
1179 char buf[BUFSIZ];
1180
1181 stream_get (&addr, client->ibuf, 16);
Christian Frankea5207082013-04-11 08:24:29 +00001182 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1183 zlog_debug("%s: looking up %s", __func__,
1184 inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
paul718e3742002-12-13 20:15:29 +00001185
Feng Luc99f3482014-10-16 09:52:36 +08001186 return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
paul718e3742002-12-13 20:15:29 +00001187}
1188#endif /* HAVE_IPV6 */
1189
hasso18a6dce2004-10-03 18:18:34 +00001190/* Register zebra server router-id information. Send current router-id */
ajs719e9742005-02-28 20:52:15 +00001191static int
Feng Luc99f3482014-10-16 09:52:36 +08001192zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001193{
1194 struct prefix p;
1195
1196 /* Router-id information is needed. */
Feng Luc99f3482014-10-16 09:52:36 +08001197 vrf_bitmap_set (client->ridinfo, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001198
Feng Luc99f3482014-10-16 09:52:36 +08001199 router_id_get (&p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001200
Feng Luc99f3482014-10-16 09:52:36 +08001201 return zsend_router_id_update (client, &p, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001202}
1203
1204/* Unregister zebra server router-id information. */
ajs719e9742005-02-28 20:52:15 +00001205static int
Feng Luc99f3482014-10-16 09:52:36 +08001206zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
hasso18a6dce2004-10-03 18:18:34 +00001207{
Feng Luc99f3482014-10-16 09:52:36 +08001208 vrf_bitmap_unset (client->ridinfo, vrf_id);
ajs719e9742005-02-28 20:52:15 +00001209 return 0;
hasso18a6dce2004-10-03 18:18:34 +00001210}
1211
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001212/* Tie up route-type and client->sock */
1213static void
1214zread_hello (struct zserv *client)
1215{
1216 /* type of protocol (lib/zebra.h) */
1217 u_char proto;
1218 proto = stream_getc (client->ibuf);
1219
1220 /* accept only dynamic routing protocols */
1221 if ((proto < ZEBRA_ROUTE_MAX)
1222 && (proto > ZEBRA_ROUTE_STATIC))
1223 {
1224 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1225 client->sock, zebra_route_string(proto));
1226
1227 /* if route-type was binded by other client */
1228 if (route_type_oaths[proto])
1229 zlog_warn ("sender of %s routes changed %c->%c",
1230 zebra_route_string(proto), route_type_oaths[proto],
1231 client->sock);
1232
1233 route_type_oaths[proto] = client->sock;
1234 }
1235}
1236
Feng Luc99f3482014-10-16 09:52:36 +08001237/* Unregister all information in a VRF. */
1238static int
1239zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
1240{
1241 int i;
1242
1243 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1244 vrf_bitmap_unset (client->redist[i], vrf_id);
1245 vrf_bitmap_unset (client->redist_default, vrf_id);
1246 vrf_bitmap_unset (client->ifinfo, vrf_id);
1247 vrf_bitmap_unset (client->ridinfo, vrf_id);
1248
1249 return 0;
1250}
1251
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001252/* If client sent routes of specific type, zebra removes it
1253 * and returns number of deleted routes.
1254 */
1255static void
1256zebra_score_rib (int client_sock)
1257{
1258 int i;
1259
1260 for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
1261 if (client_sock == route_type_oaths[i])
1262 {
1263 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1264 client_sock, rib_score_proto (i), zebra_route_string (i));
1265 route_type_oaths[i] = 0;
1266 break;
1267 }
1268}
1269
paul718e3742002-12-13 20:15:29 +00001270/* Close zebra client. */
paulb9df2d22004-05-09 09:09:59 +00001271static void
paul718e3742002-12-13 20:15:29 +00001272zebra_client_close (struct zserv *client)
1273{
1274 /* Close file descriptor. */
1275 if (client->sock)
1276 {
1277 close (client->sock);
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001278 zebra_score_rib (client->sock);
paul718e3742002-12-13 20:15:29 +00001279 client->sock = -1;
1280 }
1281
1282 /* Free stream buffers. */
1283 if (client->ibuf)
1284 stream_free (client->ibuf);
1285 if (client->obuf)
1286 stream_free (client->obuf);
ajs719e9742005-02-28 20:52:15 +00001287 if (client->wb)
1288 buffer_free(client->wb);
paul718e3742002-12-13 20:15:29 +00001289
1290 /* Release threads. */
1291 if (client->t_read)
1292 thread_cancel (client->t_read);
1293 if (client->t_write)
1294 thread_cancel (client->t_write);
ajs719e9742005-02-28 20:52:15 +00001295 if (client->t_suicide)
1296 thread_cancel (client->t_suicide);
paul718e3742002-12-13 20:15:29 +00001297
1298 /* Free client structure. */
paulb21b19c2003-06-15 01:28:29 +00001299 listnode_delete (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001300 XFREE (0, client);
1301}
1302
1303/* Make new client. */
paulb9df2d22004-05-09 09:09:59 +00001304static void
paul718e3742002-12-13 20:15:29 +00001305zebra_client_create (int sock)
1306{
1307 struct zserv *client;
Feng Luc99f3482014-10-16 09:52:36 +08001308 int i;
paul718e3742002-12-13 20:15:29 +00001309
1310 client = XCALLOC (0, sizeof (struct zserv));
1311
1312 /* Make client input/output buffer. */
1313 client->sock = sock;
1314 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1315 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
ajs719e9742005-02-28 20:52:15 +00001316 client->wb = buffer_new(0);
paul718e3742002-12-13 20:15:29 +00001317
1318 /* Set table number. */
paulb21b19c2003-06-15 01:28:29 +00001319 client->rtm_table = zebrad.rtm_table_default;
paul718e3742002-12-13 20:15:29 +00001320
Feng Luc99f3482014-10-16 09:52:36 +08001321 /* Initialize flags */
1322 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1323 client->redist[i] = vrf_bitmap_init ();
1324 client->redist_default = vrf_bitmap_init ();
1325 client->ifinfo = vrf_bitmap_init ();
1326 client->ridinfo = vrf_bitmap_init ();
1327
paul718e3742002-12-13 20:15:29 +00001328 /* Add this client to linked list. */
paulb21b19c2003-06-15 01:28:29 +00001329 listnode_add (zebrad.client_list, client);
paul718e3742002-12-13 20:15:29 +00001330
1331 /* Make new read thread. */
1332 zebra_event (ZEBRA_READ, sock, client);
1333}
1334
1335/* Handler of zebra service request. */
paulb9df2d22004-05-09 09:09:59 +00001336static int
paul718e3742002-12-13 20:15:29 +00001337zebra_client_read (struct thread *thread)
1338{
1339 int sock;
1340 struct zserv *client;
ajs57a14772005-04-10 15:01:56 +00001341 size_t already;
paulc1b98002006-01-16 01:54:02 +00001342 uint16_t length, command;
1343 uint8_t marker, version;
Feng Luc99f3482014-10-16 09:52:36 +08001344 vrf_id_t vrf_id;
paul718e3742002-12-13 20:15:29 +00001345
1346 /* Get thread data. Reset reading thread because I'm running. */
1347 sock = THREAD_FD (thread);
1348 client = THREAD_ARG (thread);
1349 client->t_read = NULL;
1350
ajs719e9742005-02-28 20:52:15 +00001351 if (client->t_suicide)
paul718e3742002-12-13 20:15:29 +00001352 {
ajs719e9742005-02-28 20:52:15 +00001353 zebra_client_close(client);
paul718e3742002-12-13 20:15:29 +00001354 return -1;
1355 }
ajs719e9742005-02-28 20:52:15 +00001356
1357 /* Read length and command (if we don't have it already). */
ajs57a14772005-04-10 15:01:56 +00001358 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
ajs719e9742005-02-28 20:52:15 +00001359 {
ajs57a14772005-04-10 15:01:56 +00001360 ssize_t nbyte;
ajs719e9742005-02-28 20:52:15 +00001361 if (((nbyte = stream_read_try (client->ibuf, sock,
ajs57a14772005-04-10 15:01:56 +00001362 ZEBRA_HEADER_SIZE-already)) == 0) ||
ajs719e9742005-02-28 20:52:15 +00001363 (nbyte == -1))
1364 {
1365 if (IS_ZEBRA_DEBUG_EVENT)
1366 zlog_debug ("connection closed socket [%d]", sock);
1367 zebra_client_close (client);
1368 return -1;
1369 }
ajs57a14772005-04-10 15:01:56 +00001370 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
ajs719e9742005-02-28 20:52:15 +00001371 {
1372 /* Try again later. */
1373 zebra_event (ZEBRA_READ, sock, client);
1374 return 0;
1375 }
ajs57a14772005-04-10 15:01:56 +00001376 already = ZEBRA_HEADER_SIZE;
ajs719e9742005-02-28 20:52:15 +00001377 }
1378
1379 /* Reset to read from the beginning of the incoming packet. */
1380 stream_set_getp(client->ibuf, 0);
1381
paulc1b98002006-01-16 01:54:02 +00001382 /* Fetch header values */
paul718e3742002-12-13 20:15:29 +00001383 length = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001384 marker = stream_getc (client->ibuf);
1385 version = stream_getc (client->ibuf);
Feng Luc99f3482014-10-16 09:52:36 +08001386 vrf_id = stream_getw (client->ibuf);
paulc1b98002006-01-16 01:54:02 +00001387 command = stream_getw (client->ibuf);
paul718e3742002-12-13 20:15:29 +00001388
paulc1b98002006-01-16 01:54:02 +00001389 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1390 {
1391 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1392 __func__, sock, marker, version);
1393 zebra_client_close (client);
1394 return -1;
1395 }
ajs719e9742005-02-28 20:52:15 +00001396 if (length < ZEBRA_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00001397 {
ajs57a14772005-04-10 15:01:56 +00001398 zlog_warn("%s: socket %d message length %u is less than header size %d",
1399 __func__, sock, length, ZEBRA_HEADER_SIZE);
1400 zebra_client_close (client);
1401 return -1;
1402 }
1403 if (length > STREAM_SIZE(client->ibuf))
1404 {
1405 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1406 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
paul718e3742002-12-13 20:15:29 +00001407 zebra_client_close (client);
1408 return -1;
1409 }
1410
paul718e3742002-12-13 20:15:29 +00001411 /* Read rest of data. */
ajs57a14772005-04-10 15:01:56 +00001412 if (already < length)
paul718e3742002-12-13 20:15:29 +00001413 {
ajs57a14772005-04-10 15:01:56 +00001414 ssize_t nbyte;
1415 if (((nbyte = stream_read_try (client->ibuf, sock,
1416 length-already)) == 0) ||
1417 (nbyte == -1))
paul718e3742002-12-13 20:15:29 +00001418 {
1419 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001420 zlog_debug ("connection closed [%d] when reading zebra data", sock);
paul718e3742002-12-13 20:15:29 +00001421 zebra_client_close (client);
1422 return -1;
1423 }
ajs57a14772005-04-10 15:01:56 +00001424 if (nbyte != (ssize_t)(length-already))
ajs719e9742005-02-28 20:52:15 +00001425 {
1426 /* Try again later. */
1427 zebra_event (ZEBRA_READ, sock, client);
1428 return 0;
1429 }
paul718e3742002-12-13 20:15:29 +00001430 }
1431
ajs719e9742005-02-28 20:52:15 +00001432 length -= ZEBRA_HEADER_SIZE;
1433
paul718e3742002-12-13 20:15:29 +00001434 /* Debug packet information. */
1435 if (IS_ZEBRA_DEBUG_EVENT)
ajsb6178002004-12-07 21:12:56 +00001436 zlog_debug ("zebra message comes from socket [%d]", sock);
paul718e3742002-12-13 20:15:29 +00001437
1438 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
Feng Luc99f3482014-10-16 09:52:36 +08001439 zlog_debug ("zebra message received [%s] %d in VRF %u",
1440 zserv_command_string (command), length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001441
1442 switch (command)
1443 {
hasso18a6dce2004-10-03 18:18:34 +00001444 case ZEBRA_ROUTER_ID_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001445 zread_router_id_add (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001446 break;
1447 case ZEBRA_ROUTER_ID_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001448 zread_router_id_delete (client, length, vrf_id);
hasso18a6dce2004-10-03 18:18:34 +00001449 break;
paul718e3742002-12-13 20:15:29 +00001450 case ZEBRA_INTERFACE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001451 zread_interface_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001452 break;
1453 case ZEBRA_INTERFACE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001454 zread_interface_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001455 break;
1456 case ZEBRA_IPV4_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001457 zread_ipv4_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001458 break;
1459 case ZEBRA_IPV4_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001460 zread_ipv4_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001461 break;
1462#ifdef HAVE_IPV6
1463 case ZEBRA_IPV6_ROUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001464 zread_ipv6_add (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001465 break;
1466 case ZEBRA_IPV6_ROUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001467 zread_ipv6_delete (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001468 break;
1469#endif /* HAVE_IPV6 */
1470 case ZEBRA_REDISTRIBUTE_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001471 zebra_redistribute_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001472 break;
1473 case ZEBRA_REDISTRIBUTE_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001474 zebra_redistribute_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001475 break;
1476 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
Feng Luc99f3482014-10-16 09:52:36 +08001477 zebra_redistribute_default_add (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001478 break;
1479 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
Feng Luc99f3482014-10-16 09:52:36 +08001480 zebra_redistribute_default_delete (command, client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001481 break;
1482 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001483 zread_ipv4_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001484 break;
Everton Marques4e5275b2014-07-01 15:15:52 -03001485 case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
Feng Luc99f3482014-10-16 09:52:36 +08001486 zread_ipv4_nexthop_lookup_mrib (client, length, vrf_id);
Everton Marques4e5275b2014-07-01 15:15:52 -03001487 break;
paul718e3742002-12-13 20:15:29 +00001488#ifdef HAVE_IPV6
1489 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001490 zread_ipv6_nexthop_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001491 break;
1492#endif /* HAVE_IPV6 */
1493 case ZEBRA_IPV4_IMPORT_LOOKUP:
Feng Luc99f3482014-10-16 09:52:36 +08001494 zread_ipv4_import_lookup (client, length, vrf_id);
paul718e3742002-12-13 20:15:29 +00001495 break;
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001496 case ZEBRA_HELLO:
1497 zread_hello (client);
1498 break;
Feng Luc99f3482014-10-16 09:52:36 +08001499 case ZEBRA_VRF_UNREGISTER:
1500 zread_vrf_unregister (client, length, vrf_id);
1501 break;
paul718e3742002-12-13 20:15:29 +00001502 default:
1503 zlog_info ("Zebra received unknown command %d", command);
1504 break;
1505 }
1506
ajs719e9742005-02-28 20:52:15 +00001507 if (client->t_suicide)
1508 {
1509 /* No need to wait for thread callback, just kill immediately. */
1510 zebra_client_close(client);
1511 return -1;
1512 }
1513
paul718e3742002-12-13 20:15:29 +00001514 stream_reset (client->ibuf);
1515 zebra_event (ZEBRA_READ, sock, client);
paul718e3742002-12-13 20:15:29 +00001516 return 0;
1517}
1518
paul718e3742002-12-13 20:15:29 +00001519
1520/* Accept code of zebra server socket. */
paulb9df2d22004-05-09 09:09:59 +00001521static int
paul718e3742002-12-13 20:15:29 +00001522zebra_accept (struct thread *thread)
1523{
1524 int accept_sock;
1525 int client_sock;
1526 struct sockaddr_in client;
1527 socklen_t len;
1528
1529 accept_sock = THREAD_FD (thread);
1530
ajs719e9742005-02-28 20:52:15 +00001531 /* Reregister myself. */
1532 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1533
paul718e3742002-12-13 20:15:29 +00001534 len = sizeof (struct sockaddr_in);
1535 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1536
1537 if (client_sock < 0)
1538 {
ajs6099b3b2004-11-20 02:06:59 +00001539 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001540 return -1;
1541 }
1542
paulccf35572003-03-01 11:42:20 +00001543 /* Make client socket non-blocking. */
ajs719e9742005-02-28 20:52:15 +00001544 set_nonblocking(client_sock);
paul865b8522005-01-05 08:30:35 +00001545
paul718e3742002-12-13 20:15:29 +00001546 /* Create new zebra client. */
1547 zebra_client_create (client_sock);
1548
paul718e3742002-12-13 20:15:29 +00001549 return 0;
1550}
1551
paulb9df2d22004-05-09 09:09:59 +00001552#ifdef HAVE_TCP_ZEBRA
paul718e3742002-12-13 20:15:29 +00001553/* Make zebra's server socket. */
paulb9df2d22004-05-09 09:09:59 +00001554static void
paul718e3742002-12-13 20:15:29 +00001555zebra_serv ()
1556{
1557 int ret;
1558 int accept_sock;
1559 struct sockaddr_in addr;
1560
1561 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1562
1563 if (accept_sock < 0)
1564 {
paul3d1dc852005-04-05 00:45:23 +00001565 zlog_warn ("Can't create zserv stream socket: %s",
1566 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001567 zlog_warn ("zebra can't provice full functionality due to above error");
1568 return;
1569 }
1570
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001571 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
paul718e3742002-12-13 20:15:29 +00001572 memset (&addr, 0, sizeof (struct sockaddr_in));
1573 addr.sin_family = AF_INET;
1574 addr.sin_port = htons (ZEBRA_PORT);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001575#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +00001576 addr.sin_len = sizeof (struct sockaddr_in);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001577#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +00001578 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1579
1580 sockopt_reuseaddr (accept_sock);
1581 sockopt_reuseport (accept_sock);
1582
pauledd7c242003-06-04 13:59:38 +00001583 if ( zserv_privs.change(ZPRIVS_RAISE) )
1584 zlog (NULL, LOG_ERR, "Can't raise privileges");
1585
paul718e3742002-12-13 20:15:29 +00001586 ret = bind (accept_sock, (struct sockaddr *)&addr,
1587 sizeof (struct sockaddr_in));
1588 if (ret < 0)
1589 {
paul3d1dc852005-04-05 00:45:23 +00001590 zlog_warn ("Can't bind to stream socket: %s",
1591 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001592 zlog_warn ("zebra can't provice full functionality due to above error");
1593 close (accept_sock); /* Avoid sd leak. */
1594 return;
1595 }
pauledd7c242003-06-04 13:59:38 +00001596
1597 if ( zserv_privs.change(ZPRIVS_LOWER) )
1598 zlog (NULL, LOG_ERR, "Can't lower privileges");
paul718e3742002-12-13 20:15:29 +00001599
1600 ret = listen (accept_sock, 1);
1601 if (ret < 0)
1602 {
paul3d1dc852005-04-05 00:45:23 +00001603 zlog_warn ("Can't listen to stream socket: %s",
1604 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +00001605 zlog_warn ("zebra can't provice full functionality due to above error");
1606 close (accept_sock); /* Avoid sd leak. */
1607 return;
1608 }
1609
1610 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1611}
David Lamparter4b6c3322015-04-21 09:47:57 +02001612#else /* HAVE_TCP_ZEBRA */
paul718e3742002-12-13 20:15:29 +00001613
1614/* For sockaddr_un. */
1615#include <sys/un.h>
1616
1617/* zebra server UNIX domain socket. */
paulb9df2d22004-05-09 09:09:59 +00001618static void
hassofce954f2004-10-07 20:29:24 +00001619zebra_serv_un (const char *path)
paul718e3742002-12-13 20:15:29 +00001620{
1621 int ret;
1622 int sock, len;
1623 struct sockaddr_un serv;
1624 mode_t old_mask;
1625
1626 /* First of all, unlink existing socket */
1627 unlink (path);
1628
1629 /* Set umask */
1630 old_mask = umask (0077);
1631
1632 /* Make UNIX domain socket. */
1633 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1634 if (sock < 0)
1635 {
paul3d1dc852005-04-05 00:45:23 +00001636 zlog_warn ("Can't create zserv unix socket: %s",
1637 safe_strerror (errno));
1638 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001639 return;
1640 }
1641
Vyacheslav Trushkin2ea1ab12011-12-11 18:48:47 +04001642 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1643
paul718e3742002-12-13 20:15:29 +00001644 /* Make server socket. */
1645 memset (&serv, 0, sizeof (struct sockaddr_un));
1646 serv.sun_family = AF_UNIX;
1647 strncpy (serv.sun_path, path, strlen (path));
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001648#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
paul718e3742002-12-13 20:15:29 +00001649 len = serv.sun_len = SUN_LEN(&serv);
1650#else
1651 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
Paul Jakma6f0e3f62007-05-10 02:38:51 +00001652#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
paul718e3742002-12-13 20:15:29 +00001653
1654 ret = bind (sock, (struct sockaddr *) &serv, len);
1655 if (ret < 0)
1656 {
paul3d1dc852005-04-05 00:45:23 +00001657 zlog_warn ("Can't bind to unix socket %s: %s",
1658 path, safe_strerror (errno));
1659 zlog_warn ("zebra can't provide full functionality due to above error");
paul718e3742002-12-13 20:15:29 +00001660 close (sock);
1661 return;
1662 }
1663
1664 ret = listen (sock, 5);
1665 if (ret < 0)
1666 {
paul3d1dc852005-04-05 00:45:23 +00001667 zlog_warn ("Can't listen 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 umask (old_mask);
1675
1676 zebra_event (ZEBRA_SERV, sock, NULL);
1677}
David Lamparter4b6c3322015-04-21 09:47:57 +02001678#endif /* HAVE_TCP_ZEBRA */
David Lamparter6b0655a2014-06-04 06:53:35 +02001679
paul718e3742002-12-13 20:15:29 +00001680
paulb9df2d22004-05-09 09:09:59 +00001681static void
paul718e3742002-12-13 20:15:29 +00001682zebra_event (enum event event, int sock, struct zserv *client)
1683{
1684 switch (event)
1685 {
1686 case ZEBRA_SERV:
paulb21b19c2003-06-15 01:28:29 +00001687 thread_add_read (zebrad.master, zebra_accept, client, sock);
paul718e3742002-12-13 20:15:29 +00001688 break;
1689 case ZEBRA_READ:
1690 client->t_read =
paulb21b19c2003-06-15 01:28:29 +00001691 thread_add_read (zebrad.master, zebra_client_read, client, sock);
paul718e3742002-12-13 20:15:29 +00001692 break;
1693 case ZEBRA_WRITE:
1694 /**/
1695 break;
1696 }
1697}
David Lamparter6b0655a2014-06-04 06:53:35 +02001698
paul718e3742002-12-13 20:15:29 +00001699/* Display default rtm_table for all clients. */
1700DEFUN (show_table,
1701 show_table_cmd,
1702 "show table",
1703 SHOW_STR
1704 "default routing table to use for all clients\n")
1705{
paulb21b19c2003-06-15 01:28:29 +00001706 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001707 VTY_NEWLINE);
1708 return CMD_SUCCESS;
1709}
1710
1711DEFUN (config_table,
1712 config_table_cmd,
1713 "table TABLENO",
1714 "Configure target kernel routing table\n"
1715 "TABLE integer\n")
1716{
paulb21b19c2003-06-15 01:28:29 +00001717 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
paul718e3742002-12-13 20:15:29 +00001718 return CMD_SUCCESS;
1719}
1720
hasso647e4f12003-05-25 11:43:52 +00001721DEFUN (ip_forwarding,
1722 ip_forwarding_cmd,
1723 "ip forwarding",
1724 IP_STR
1725 "Turn on IP forwarding")
1726{
1727 int ret;
1728
1729 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001730 if (ret == 0)
1731 ret = ipforward_on ();
hasso647e4f12003-05-25 11:43:52 +00001732
hasso647e4f12003-05-25 11:43:52 +00001733 if (ret == 0)
1734 {
1735 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1736 return CMD_WARNING;
1737 }
1738
1739 return CMD_SUCCESS;
1740}
1741
paul718e3742002-12-13 20:15:29 +00001742DEFUN (no_ip_forwarding,
1743 no_ip_forwarding_cmd,
1744 "no ip forwarding",
1745 NO_STR
1746 IP_STR
1747 "Turn off IP forwarding")
1748{
1749 int ret;
1750
1751 ret = ipforward ();
hassob71f00f2004-10-13 12:20:35 +00001752 if (ret != 0)
1753 ret = ipforward_off ();
paul718e3742002-12-13 20:15:29 +00001754
paul718e3742002-12-13 20:15:29 +00001755 if (ret != 0)
1756 {
1757 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1758 return CMD_WARNING;
1759 }
1760
1761 return CMD_SUCCESS;
1762}
1763
1764/* This command is for debugging purpose. */
1765DEFUN (show_zebra_client,
1766 show_zebra_client_cmd,
1767 "show zebra client",
1768 SHOW_STR
1769 "Zebra information"
1770 "Client information")
1771{
hasso52dc7ee2004-09-23 19:18:23 +00001772 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001773 struct zserv *client;
1774
paul1eb8ef22005-04-07 07:30:20 +00001775 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1776 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1777
paul718e3742002-12-13 20:15:29 +00001778 return CMD_SUCCESS;
1779}
1780
1781/* Table configuration write function. */
paulb9df2d22004-05-09 09:09:59 +00001782static int
paul718e3742002-12-13 20:15:29 +00001783config_write_table (struct vty *vty)
1784{
paulb21b19c2003-06-15 01:28:29 +00001785 if (zebrad.rtm_table_default)
1786 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
paul718e3742002-12-13 20:15:29 +00001787 VTY_NEWLINE);
1788 return 0;
1789}
1790
1791/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001792static struct cmd_node table_node =
paul718e3742002-12-13 20:15:29 +00001793{
1794 TABLE_NODE,
1795 "", /* This node has no interface. */
1796 1
1797};
David Lamparter6b0655a2014-06-04 06:53:35 +02001798
paul718e3742002-12-13 20:15:29 +00001799/* Only display ip forwarding is enabled or not. */
1800DEFUN (show_ip_forwarding,
1801 show_ip_forwarding_cmd,
1802 "show ip forwarding",
1803 SHOW_STR
1804 IP_STR
1805 "IP forwarding status\n")
1806{
1807 int ret;
1808
1809 ret = ipforward ();
1810
1811 if (ret == 0)
1812 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1813 else
1814 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1815 return CMD_SUCCESS;
1816}
1817
1818#ifdef HAVE_IPV6
1819/* Only display ipv6 forwarding is enabled or not. */
1820DEFUN (show_ipv6_forwarding,
1821 show_ipv6_forwarding_cmd,
1822 "show ipv6 forwarding",
1823 SHOW_STR
1824 "IPv6 information\n"
1825 "Forwarding status\n")
1826{
1827 int ret;
1828
1829 ret = ipforward_ipv6 ();
1830
1831 switch (ret)
1832 {
1833 case -1:
1834 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1835 break;
1836 case 0:
1837 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1838 break;
1839 case 1:
1840 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1841 break;
1842 default:
1843 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1844 break;
1845 }
1846 return CMD_SUCCESS;
1847}
1848
hasso55906722004-02-11 22:42:16 +00001849DEFUN (ipv6_forwarding,
1850 ipv6_forwarding_cmd,
1851 "ipv6 forwarding",
1852 IPV6_STR
1853 "Turn on IPv6 forwarding")
1854{
1855 int ret;
1856
hasso41d3fc92004-04-06 11:59:00 +00001857 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001858 if (ret == 0)
1859 ret = ipforward_ipv6_on ();
hasso41d3fc92004-04-06 11:59:00 +00001860
hasso41d3fc92004-04-06 11:59:00 +00001861 if (ret == 0)
1862 {
hasso55906722004-02-11 22:42:16 +00001863 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1864 return CMD_WARNING;
1865 }
1866
1867 return CMD_SUCCESS;
1868}
1869
paul718e3742002-12-13 20:15:29 +00001870DEFUN (no_ipv6_forwarding,
1871 no_ipv6_forwarding_cmd,
1872 "no ipv6 forwarding",
1873 NO_STR
hasso55906722004-02-11 22:42:16 +00001874 IPV6_STR
1875 "Turn off IPv6 forwarding")
paul718e3742002-12-13 20:15:29 +00001876{
1877 int ret;
1878
hasso41d3fc92004-04-06 11:59:00 +00001879 ret = ipforward_ipv6 ();
hassob71f00f2004-10-13 12:20:35 +00001880 if (ret != 0)
1881 ret = ipforward_ipv6_off ();
hasso41d3fc92004-04-06 11:59:00 +00001882
paul718e3742002-12-13 20:15:29 +00001883 if (ret != 0)
1884 {
1885 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1886 return CMD_WARNING;
1887 }
1888
1889 return CMD_SUCCESS;
1890}
1891
1892#endif /* HAVE_IPV6 */
1893
1894/* IPForwarding configuration write function. */
ajs719e9742005-02-28 20:52:15 +00001895static int
paul718e3742002-12-13 20:15:29 +00001896config_write_forwarding (struct vty *vty)
1897{
hasso18a6dce2004-10-03 18:18:34 +00001898 /* FIXME: Find better place for that. */
1899 router_id_write (vty);
1900
paul3e0b3a52004-08-23 18:58:32 +00001901 if (ipforward ())
1902 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001903#ifdef HAVE_IPV6
paul3e0b3a52004-08-23 18:58:32 +00001904 if (ipforward_ipv6 ())
1905 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001906#endif /* HAVE_IPV6 */
1907 vty_out (vty, "!%s", VTY_NEWLINE);
1908 return 0;
1909}
1910
1911/* table node for routing tables. */
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08001912static struct cmd_node forwarding_node =
paul718e3742002-12-13 20:15:29 +00001913{
1914 FORWARDING_NODE,
1915 "", /* This node has no interface. */
1916 1
1917};
1918
David Lamparter6b0655a2014-06-04 06:53:35 +02001919
paul718e3742002-12-13 20:15:29 +00001920/* Initialisation of zebra and installation of commands. */
1921void
paula1ac18c2005-06-28 17:17:12 +00001922zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001923{
1924 /* Client list init. */
paulb21b19c2003-06-15 01:28:29 +00001925 zebrad.client_list = list_new ();
paul718e3742002-12-13 20:15:29 +00001926
paul718e3742002-12-13 20:15:29 +00001927 /* Install configuration write function. */
1928 install_node (&table_node, config_write_table);
1929 install_node (&forwarding_node, config_write_forwarding);
1930
1931 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1932 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
hasso647e4f12003-05-25 11:43:52 +00001933 install_element (CONFIG_NODE, &ip_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001934 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1935 install_element (ENABLE_NODE, &show_zebra_client_cmd);
1936
1937#ifdef HAVE_NETLINK
1938 install_element (VIEW_NODE, &show_table_cmd);
1939 install_element (ENABLE_NODE, &show_table_cmd);
1940 install_element (CONFIG_NODE, &config_table_cmd);
1941#endif /* HAVE_NETLINK */
1942
1943#ifdef HAVE_IPV6
1944 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1945 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
hasso55906722004-02-11 22:42:16 +00001946 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
paul718e3742002-12-13 20:15:29 +00001947 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1948#endif /* HAVE_IPV6 */
Paul Jakma7514fb72007-05-02 16:05:35 +00001949
1950 /* Route-map */
1951 zebra_route_map_init ();
paul718e3742002-12-13 20:15:29 +00001952}
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001953
1954/* Make zebra server socket, wiping any existing one (see bug #403). */
1955void
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04001956zebra_zserv_socket_init (char *path)
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001957{
1958#ifdef HAVE_TCP_ZEBRA
1959 zebra_serv ();
1960#else
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +04001961 zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
Denis Ovsienko97be79f2009-07-24 20:45:31 +04001962#endif /* HAVE_TCP_ZEBRA */
1963}