]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zserv.c
bgpd-nht-connected-route.patch
[mirror_frr.git] / zebra / zserv.c
CommitLineData
718e3744 1/* 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"
edd7c245 36#include "privs.h"
719e9741 37#include "network.h"
38#include "buffer.h"
fb018d25 39#include "nexthop.h"
718e3744 40
41#include "zebra/zserv.h"
18a6dce6 42#include "zebra/router-id.h"
718e3744 43#include "zebra/redistribute.h"
44#include "zebra/debug.h"
45#include "zebra/ipforward.h"
fb018d25 46#include "zebra/zebra_rnh.h"
6b0655a2 47
718e3744 48/* Event list of zebra. */
49enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
50
b21b19c5 51extern struct zebra_t zebrad;
718e3744 52
b9df2d25 53static void zebra_event (enum event event, int sock, struct zserv *client);
ccf3557b 54
edd7c245 55extern struct zebra_privs_t zserv_privs;
6b0655a2 56
719e9741 57static void zebra_client_close (struct zserv *client);
ccf3557b 58
719e9741 59static int
60zserv_delayed_close(struct thread *thread)
ccf3557b 61{
719e9741 62 struct zserv *client = THREAD_ARG(thread);
ccf3557b 63
719e9741 64 client->t_suicide = NULL;
65 zebra_client_close(client);
ccf3557b 66 return 0;
67}
68
2ea1ab1c
VT
69/* When client connects, it sends hello message
70 * with promise to send zebra routes of specific type.
71 * Zebra stores a socket fd of the client into
72 * this array. And use it to clean up routes that
73 * client didn't remove for some reasons after closing
74 * connection.
75 */
76static int route_type_oaths[ZEBRA_ROUTE_MAX];
77
719e9741 78static int
79zserv_flush_data(struct thread *thread)
ccf3557b 80{
719e9741 81 struct zserv *client = THREAD_ARG(thread);
ccf3557b 82
719e9741 83 client->t_write = NULL;
84 if (client->t_suicide)
ccf3557b 85 {
719e9741 86 zebra_client_close(client);
87 return -1;
ccf3557b 88 }
719e9741 89 switch (buffer_flush_available(client->wb, client->sock))
ccf3557b 90 {
719e9741 91 case BUFFER_ERROR:
92 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
93 "closing", __func__, client->sock);
94 zebra_client_close(client);
95 break;
96 case BUFFER_PENDING:
97 client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
98 client, client->sock);
99 break;
100 case BUFFER_EMPTY:
101 break;
ccf3557b 102 }
719e9741 103 return 0;
104}
ccf3557b 105
fb018d25 106int
719e9741 107zebra_server_send_message(struct zserv *client)
108{
109 if (client->t_suicide)
110 return -1;
111 switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
112 stream_get_endp(client->obuf)))
113 {
114 case BUFFER_ERROR:
115 zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
116 __func__, client->sock);
117 /* Schedule a delayed close since many of the functions that call this
118 one do not check the return code. They do not allow for the
119 possibility that an I/O error may have caused the client to be
120 deleted. */
121 client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
122 client, 0);
123 return -1;
719e9741 124 case BUFFER_EMPTY:
125 THREAD_OFF(client->t_write);
126 break;
127 case BUFFER_PENDING:
128 THREAD_WRITE_ON(zebrad.master, client->t_write,
129 zserv_flush_data, client, client->sock);
130 break;
131 }
ccf3557b 132 return 0;
133}
134
fb018d25 135void
c1b9800a 136zserv_create_header (struct stream *s, uint16_t cmd)
137{
138 /* length placeholder, caller can update */
139 stream_putw (s, ZEBRA_HEADER_SIZE);
140 stream_putc (s, ZEBRA_HEADER_MARKER);
141 stream_putc (s, ZSERV_VERSION);
142 stream_putw (s, cmd);
143}
144
51d4ef83
JB
145static 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);
244c1cdc
DS
153 stream_putc (s, ifp->ptm_enable);
154 stream_putc (s, ifp->ptm_status);
51d4ef83
JB
155 stream_putl (s, ifp->metric);
156 stream_putl (s, ifp->mtu);
157 stream_putl (s, ifp->mtu6);
158 stream_putl (s, ifp->bandwidth);
159#ifdef HAVE_STRUCT_SOCKADDR_DL
ca3ccd87 160 stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
51d4ef83
JB
161#else
162 stream_putl (s, ifp->hw_addr_len);
163 if (ifp->hw_addr_len)
164 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
165#endif /* HAVE_STRUCT_SOCKADDR_DL */
166
167 /* Write packet size. */
168 stream_putw_at (s, 0, stream_get_endp (s));
169}
170
718e3744 171/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
b9df2d25 172/*
173 * This function is called in the following situations:
174 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
175 * from the client.
176 * - at startup, when zebra figures out the available interfaces
177 * - when an interface is added (where support for
178 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
179 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
180 * received)
181 */
718e3744 182int
183zsend_interface_add (struct zserv *client, struct interface *ifp)
184{
185 struct stream *s;
186
187 /* Check this client need interface information. */
188 if (! client->ifinfo)
719e9741 189 return 0;
718e3744 190
191 s = client->obuf;
192 stream_reset (s);
193
c1b9800a 194 zserv_create_header (s, ZEBRA_INTERFACE_ADD);
51d4ef83 195 zserv_encode_interface (s, ifp);
718e3744 196
719e9741 197 return zebra_server_send_message(client);
718e3744 198}
199
200/* Interface deletion from zebra daemon. */
201int
202zsend_interface_delete (struct zserv *client, struct interface *ifp)
203{
204 struct stream *s;
205
206 /* Check this client need interface information. */
207 if (! client->ifinfo)
719e9741 208 return 0;
718e3744 209
210 s = client->obuf;
211 stream_reset (s);
718e3744 212
51d4ef83
JB
213 zserv_create_header (s, ZEBRA_INTERFACE_DELETE);
214 zserv_encode_interface (s, ifp);
718e3744 215
719e9741 216 return zebra_server_send_message (client);
718e3744 217}
218
b9df2d25 219/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
220 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
221 *
222 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
223 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
224 * from the client, after the ZEBRA_INTERFACE_ADD has been
225 * sent from zebra to the client
226 * - redistribute new address info to all clients in the following situations
227 * - at startup, when zebra figures out the available interfaces
228 * - when an interface is added (where support for
229 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
230 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
231 * received)
232 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
233 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
234 * - when an RTM_NEWADDR message is received from the kernel,
235 *
236 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
237 *
238 * zsend_interface_address(DELETE)
239 * ^
240 * |
241 * zebra_interface_address_delete_update
242 * ^ ^ ^
6eb8827d 243 * | | if_delete_update
244 * | |
b9df2d25 245 * ip_address_uninstall connected_delete_ipv4
246 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
247 * ^ ^
248 * | |
249 * | RTM_NEWADDR on routing/netlink socket
250 * |
251 * vty commands:
252 * "no ip address A.B.C.D/M [label LINE]"
253 * "no ip address A.B.C.D/M secondary"
254 * ["no ipv6 address X:X::X:X/M"]
255 *
256 */
718e3744 257int
b9df2d25 258zsend_interface_address (int cmd, struct zserv *client,
259 struct interface *ifp, struct connected *ifc)
718e3744 260{
261 int blen;
262 struct stream *s;
263 struct prefix *p;
264
265 /* Check this client need interface information. */
266 if (! client->ifinfo)
719e9741 267 return 0;
718e3744 268
269 s = client->obuf;
270 stream_reset (s);
c1b9800a 271
272 zserv_create_header (s, cmd);
718e3744 273 stream_putl (s, ifp->ifindex);
274
275 /* Interface address flag. */
276 stream_putc (s, ifc->flags);
277
278 /* Prefix information. */
279 p = ifc->address;
280 stream_putc (s, p->family);
281 blen = prefix_blen (p);
282 stream_put (s, &p->u.prefix, blen);
b9df2d25 283
284 /*
285 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
286 * but zebra_interface_address_delete_read() in the gnu version
287 * expects to find it
288 */
718e3744 289 stream_putc (s, p->prefixlen);
290
291 /* Destination. */
292 p = ifc->destination;
293 if (p)
294 stream_put (s, &p->u.prefix, blen);
295 else
296 stream_put (s, NULL, blen);
297
298 /* Write packet size. */
299 stream_putw_at (s, 0, stream_get_endp (s));
300
719e9741 301 return zebra_server_send_message(client);
718e3744 302}
303
a80beece
DS
304static int
305zsend_interface_nbr_address (int cmd, struct zserv *client,
306 struct interface *ifp, struct nbr_connected *ifc)
307{
308 int blen;
309 struct stream *s;
310 struct prefix *p;
311
312 /* Check this client need interface information. */
313 if (! client->ifinfo)
314 return 0;
315
316 s = client->obuf;
317 stream_reset (s);
318
319 zserv_create_header (s, cmd);
320 stream_putl (s, ifp->ifindex);
321
322 /* Prefix information. */
323 p = ifc->address;
324 stream_putc (s, p->family);
325 blen = prefix_blen (p);
326 stream_put (s, &p->u.prefix, blen);
327
328 /*
329 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
330 * but zebra_interface_address_delete_read() in the gnu version
331 * expects to find it
332 */
333 stream_putc (s, p->prefixlen);
334
335 /* Write packet size. */
336 stream_putw_at (s, 0, stream_get_endp (s));
337
338 return zebra_server_send_message(client);
339}
340
341/* Interface address addition. */
342static void
343zebra_interface_nbr_address_add_update (struct interface *ifp,
344 struct nbr_connected *ifc)
345{
346 struct listnode *node, *nnode;
347 struct zserv *client;
348 struct prefix *p;
349
350 if (IS_ZEBRA_DEBUG_EVENT)
351 {
352 char buf[INET6_ADDRSTRLEN];
353
354 p = ifc->address;
355 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
356 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
357 p->prefixlen, ifc->ifp->name);
358 }
359
360 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
361 if (client->ifinfo)
362 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc);
363}
364
365/* Interface address deletion. */
366static void
367zebra_interface_nbr_address_delete_update (struct interface *ifp,
368 struct nbr_connected *ifc)
369{
370 struct listnode *node, *nnode;
371 struct zserv *client;
372 struct prefix *p;
373
374 if (IS_ZEBRA_DEBUG_EVENT)
375 {
376 char buf[INET6_ADDRSTRLEN];
377
378 p = ifc->address;
379 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
380 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
381 p->prefixlen, ifc->ifp->name);
382 }
383
384 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
385 if (client->ifinfo)
386 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc);
387}
388
389/* Add new nbr connected IPv6 address if none exists already, or replace the
390 existing one if an ifc entry is found on the interface. */
391void
392nbr_connected_replacement_add_ipv6 (struct interface *ifp, struct in6_addr *address,
393 u_char prefixlen)
394{
395 struct nbr_connected *ifc;
396 struct prefix p;
397
398 p.family = AF_INET6;
399 IPV6_ADDR_COPY (&p.u.prefix, address);
400 p.prefixlen = prefixlen;
401
402 if (nbr_connected_check(ifp, &p))
403 return;
404
405 if (!(ifc = listnode_head(ifp->nbr_connected)))
406 {
407 /* new addition */
408 ifc = nbr_connected_new ();
409 ifc->address = prefix_new();
410 ifc->ifp = ifp;
411 listnode_add (ifp->nbr_connected, ifc);
412 }
413
414 prefix_copy(ifc->address, &p);
415
416 zebra_interface_nbr_address_add_update (ifp, ifc);
417}
418
419void
420nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
421 u_char prefixlen)
422{
423 struct nbr_connected *ifc;
424 struct prefix p;
425
426 p.family = AF_INET6;
427 IPV6_ADDR_COPY (&p.u.prefix, address);
428 p.prefixlen = prefixlen;
429
430 ifc = nbr_connected_check(ifp, &p);
431 if (!ifc)
432 return;
433
434 listnode_delete (ifp->nbr_connected, ifc);
435
436 zebra_interface_nbr_address_delete_update (ifp, ifc);
437
438 nbr_connected_free (ifc);
439}
440
b9df2d25 441/*
442 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
443 * ZEBRA_INTERFACE_DOWN.
444 *
445 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
446 * the clients in one of 2 situations:
447 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
448 * - a vty command modifying the bandwidth of an interface is received.
449 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
450 */
718e3744 451int
b9df2d25 452zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
718e3744 453{
454 struct stream *s;
455
456 /* Check this client need interface information. */
457 if (! client->ifinfo)
719e9741 458 return 0;
718e3744 459
460 s = client->obuf;
461 stream_reset (s);
462
c1b9800a 463 zserv_create_header (s, cmd);
51d4ef83 464 zserv_encode_interface (s, ifp);
718e3744 465
719e9741 466 return zebra_server_send_message(client);
718e3744 467}
468
b9df2d25 469/*
470 * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
471 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
472 * situations:
473 * - when the client starts up, and requests default information
474 * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
475 * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
476 * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
477 * - when the zebra server redistributes routes after it updates its rib
478 *
479 * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
480 * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
481 * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
482 * - deleted from zebra's rib, and this info
483 * has to be redistributed to the clients
484 *
485 * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
486 * zebra server when the client wants to tell the zebra server to add a
487 * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
488 * same message being sent back and forth, this function and
489 * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
490 * duplication.
491 */
718e3744 492int
b9df2d25 493zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
494 struct rib *rib)
718e3744 495{
496 int psize;
497 struct stream *s;
498 struct nexthop *nexthop;
1dcb5172 499 unsigned long nhnummark = 0, messmark = 0;
b9df2d25 500 int nhnum = 0;
1dcb5172 501 u_char zapi_flags = 0;
b9df2d25 502
718e3744 503 s = client->obuf;
504 stream_reset (s);
c1b9800a 505
506 zserv_create_header (s, cmd);
507
508 /* Put type and nexthop. */
718e3744 509 stream_putc (s, rib->type);
510 stream_putc (s, rib->flags);
1dcb5172 511
512 /* marker for message flags field */
513 messmark = stream_get_endp (s);
514 stream_putc (s, 0);
718e3744 515
516 /* Prefix. */
517 psize = PSIZE (p->prefixlen);
518 stream_putc (s, p->prefixlen);
b9df2d25 519 stream_write (s, (u_char *) & p->u.prefix, psize);
520
521 /*
522 * XXX The message format sent by zebra below does not match the format
523 * of the corresponding message expected by the zebra server
524 * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
525 * (is there a bug on the client side if more than one segment is sent?)
526 * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
527 * is hard-coded.
528 */
718e3744 529 /* Nexthop */
1dcb5172 530
718e3744 531 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
532 {
fa713d9e
CF
533 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
534 || nexthop_has_fib_child(nexthop))
b9df2d25 535 {
1dcb5172 536 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
537 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
538
539 if (nhnummark == 0)
540 {
541 nhnummark = stream_get_endp (s);
542 stream_putc (s, 1); /* placeholder */
543 }
544
b9df2d25 545 nhnum++;
546
547 switch(nexthop->type)
548 {
549 case NEXTHOP_TYPE_IPV4:
550 case NEXTHOP_TYPE_IPV4_IFINDEX:
551 stream_put_in_addr (s, &nexthop->gate.ipv4);
552 break;
718e3744 553#ifdef HAVE_IPV6
b9df2d25 554 case NEXTHOP_TYPE_IPV6:
555 case NEXTHOP_TYPE_IPV6_IFINDEX:
556 case NEXTHOP_TYPE_IPV6_IFNAME:
557 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
558 break;
559#endif
560 default:
561 if (cmd == ZEBRA_IPV4_ROUTE_ADD
562 || cmd == ZEBRA_IPV4_ROUTE_DELETE)
563 {
564 struct in_addr empty;
44983cf8 565 memset (&empty, 0, sizeof (struct in_addr));
b9df2d25 566 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
567 }
568 else
569 {
570 struct in6_addr empty;
571 memset (&empty, 0, sizeof (struct in6_addr));
572 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
573 }
574 }
575
576 /* Interface index. */
577 stream_putc (s, 1);
578 stream_putl (s, nexthop->ifindex);
579
580 break;
581 }
718e3744 582 }
583
584 /* Metric */
cf8a831b 585 if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
1dcb5172 586 {
fbf5d033 587 SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
588 stream_putc (s, rib->distance);
1dcb5172 589 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
590 stream_putl (s, rib->metric);
0d9551dc
DS
591
592 /* tag */
593 if (rib->tag)
594 {
595 SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
596 stream_putw(s, rib->tag);
597 }
1dcb5172 598 }
599
600 /* write real message flags value */
601 stream_putc_at (s, messmark, zapi_flags);
602
b9df2d25 603 /* Write next-hop number */
604 if (nhnummark)
c1eaa442 605 stream_putc_at (s, nhnummark, nhnum);
b9df2d25 606
718e3744 607 /* Write packet size. */
608 stream_putw_at (s, 0, stream_get_endp (s));
609
719e9741 610 return zebra_server_send_message(client);
718e3744 611}
612
b9df2d25 613#ifdef HAVE_IPV6
719e9741 614static int
718e3744 615zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
616{
617 struct stream *s;
618 struct rib *rib;
619 unsigned long nump;
620 u_char num;
621 struct nexthop *nexthop;
622
623 /* Lookup nexthop. */
624 rib = rib_match_ipv6 (addr);
625
626 /* Get output stream. */
627 s = client->obuf;
628 stream_reset (s);
629
630 /* Fill in result. */
c1b9800a 631 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
718e3744 632 stream_put (s, &addr, 16);
633
634 if (rib)
635 {
636 stream_putl (s, rib->metric);
637 num = 0;
9985f83c 638 nump = stream_get_endp(s);
718e3744 639 stream_putc (s, 0);
fa713d9e
CF
640 /* Only non-recursive routes are elegible to resolve nexthop we
641 * are looking up. Therefore, we will just iterate over the top
642 * chain of nexthops. */
718e3744 643 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
644 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
645 {
646 stream_putc (s, nexthop->type);
647 switch (nexthop->type)
648 {
649 case ZEBRA_NEXTHOP_IPV6:
650 stream_put (s, &nexthop->gate.ipv6, 16);
651 break;
652 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
653 case ZEBRA_NEXTHOP_IPV6_IFNAME:
654 stream_put (s, &nexthop->gate.ipv6, 16);
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;
fa2b17e3 661 default:
662 /* do nothing */
663 break;
718e3744 664 }
665 num++;
666 }
667 stream_putc_at (s, nump, num);
668 }
669 else
670 {
671 stream_putl (s, 0);
672 stream_putc (s, 0);
673 }
674
675 stream_putw_at (s, 0, stream_get_endp (s));
676
719e9741 677 return zebra_server_send_message(client);
718e3744 678}
679#endif /* HAVE_IPV6 */
680
b9df2d25 681static int
718e3744 682zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
683{
684 struct stream *s;
685 struct rib *rib;
686 unsigned long nump;
687 u_char num;
688 struct nexthop *nexthop;
689
690 /* Lookup nexthop. */
691 rib = rib_match_ipv4 (addr);
692
693 /* Get output stream. */
694 s = client->obuf;
695 stream_reset (s);
696
697 /* Fill in result. */
c1b9800a 698 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
718e3744 699 stream_put_in_addr (s, &addr);
700
701 if (rib)
702 {
bb97e462
CF
703 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
704 zlog_debug("%s: Matching rib entry found.", __func__);
718e3744 705 stream_putl (s, rib->metric);
706 num = 0;
9985f83c 707 nump = stream_get_endp(s);
718e3744 708 stream_putc (s, 0);
fa713d9e
CF
709 /* Only non-recursive routes are elegible to resolve the nexthop we
710 * are looking up. Therefore, we will just iterate over the top
711 * chain of nexthops. */
718e3744 712 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
713 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
714 {
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;
bb97e462
CF
721 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
722 stream_put_in_addr (s, &nexthop->gate.ipv4);
723 stream_putl (s, nexthop->ifindex);
724 break;
718e3744 725 case ZEBRA_NEXTHOP_IFINDEX:
726 case ZEBRA_NEXTHOP_IFNAME:
727 stream_putl (s, nexthop->ifindex);
728 break;
fa2b17e3 729 default:
730 /* do nothing */
731 break;
718e3744 732 }
733 num++;
734 }
735 stream_putc_at (s, nump, num);
736 }
737 else
738 {
bb97e462
CF
739 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
740 zlog_debug("%s: No matching rib entry found.", __func__);
718e3744 741 stream_putl (s, 0);
742 stream_putc (s, 0);
743 }
744
745 stream_putw_at (s, 0, stream_get_endp (s));
746
719e9741 747 return zebra_server_send_message(client);
718e3744 748}
749
fb018d25
DS
750/* Nexthop register */
751static int
752zserv_nexthop_register (struct zserv *client, int sock, u_short length)
753{
754 struct rnh *rnh;
755 struct stream *s;
756 struct prefix p;
757 u_short l = 0;
fc9a856f 758 u_char connected;
fb018d25
DS
759
760 if (IS_ZEBRA_DEBUG_NHT)
761 zlog_debug("nexthop_register msg from client %s: length=%d\n",
762 zebra_route_string(client->proto), length);
763
764 s = client->ibuf;
765
766 while (l < length)
767 {
fc9a856f 768 connected = stream_getc(s);
fb018d25
DS
769 p.family = stream_getw(s);
770 p.prefixlen = stream_getc(s);
fc9a856f 771 l += 4;
fb018d25
DS
772 stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
773 l += PSIZE(p.prefixlen);
774 rnh = zebra_add_rnh(&p, 0);
fc9a856f
DS
775 if (connected)
776 SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
777
fb018d25
DS
778 zebra_add_rnh_client(rnh, client);
779 }
9f0ea7d4
DS
780 zebra_evaluate_rnh_table(0, AF_INET, 0);
781 zebra_evaluate_rnh_table(0, AF_INET6, 0);
fb018d25
DS
782 return 0;
783}
784
785/* Nexthop register */
786static int
787zserv_nexthop_unregister (struct zserv *client, int sock, u_short length)
788{
789 struct rnh *rnh;
790 struct stream *s;
791 struct prefix p;
792 u_short l = 0;
fc9a856f 793 u_char connected;
fb018d25
DS
794
795 if (IS_ZEBRA_DEBUG_NHT)
796 zlog_debug("nexthop_unregister msg from client %s: length=%d\n",
797 zebra_route_string(client->proto), length);
798
799 s = client->ibuf;
800
801 while (l < length)
802 {
fc9a856f 803 connected = stream_getc(s);
fb018d25
DS
804 p.family = stream_getw(s);
805 p.prefixlen = stream_getc(s);
fc9a856f 806 l += 4;
fb018d25
DS
807 stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
808 l += PSIZE(p.prefixlen);
809 rnh = zebra_lookup_rnh(&p, 0);
810 if (rnh)
811 zebra_remove_rnh_client(rnh, client);
812 }
813 return 0;
814}
815
b9df2d25 816static int
718e3744 817zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
818{
819 struct stream *s;
820 struct rib *rib;
821 unsigned long nump;
822 u_char num;
823 struct nexthop *nexthop;
824
825 /* Lookup nexthop. */
826 rib = rib_lookup_ipv4 (p);
827
828 /* Get output stream. */
829 s = client->obuf;
830 stream_reset (s);
831
832 /* Fill in result. */
c1b9800a 833 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP);
718e3744 834 stream_put_in_addr (s, &p->prefix);
835
836 if (rib)
837 {
838 stream_putl (s, rib->metric);
839 num = 0;
9985f83c 840 nump = stream_get_endp(s);
718e3744 841 stream_putc (s, 0);
842 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
fa713d9e
CF
843 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
844 || nexthop_has_fib_child(nexthop))
718e3744 845 {
846 stream_putc (s, nexthop->type);
847 switch (nexthop->type)
848 {
849 case ZEBRA_NEXTHOP_IPV4:
850 stream_put_in_addr (s, &nexthop->gate.ipv4);
851 break;
a12afd5e
CF
852 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
853 stream_put_in_addr (s, &nexthop->gate.ipv4);
854 stream_putl (s, nexthop->ifindex);
855 break;
718e3744 856 case ZEBRA_NEXTHOP_IFINDEX:
857 case ZEBRA_NEXTHOP_IFNAME:
858 stream_putl (s, nexthop->ifindex);
859 break;
fa2b17e3 860 default:
861 /* do nothing */
862 break;
718e3744 863 }
864 num++;
865 }
866 stream_putc_at (s, nump, num);
867 }
868 else
869 {
870 stream_putl (s, 0);
871 stream_putc (s, 0);
872 }
873
874 stream_putw_at (s, 0, stream_get_endp (s));
875
719e9741 876 return zebra_server_send_message(client);
718e3744 877}
6b0655a2 878
18a6dce6 879/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
880int
881zsend_router_id_update (struct zserv *client, struct prefix *p)
882{
883 struct stream *s;
884 int blen;
885
886 /* Check this client need interface information. */
887 if (!client->ridinfo)
719e9741 888 return 0;
18a6dce6 889
890 s = client->obuf;
891 stream_reset (s);
892
18a6dce6 893 /* Message type. */
c1b9800a 894 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE);
18a6dce6 895
896 /* Prefix information. */
897 stream_putc (s, p->family);
898 blen = prefix_blen (p);
899 stream_put (s, &p->u.prefix, blen);
900 stream_putc (s, p->prefixlen);
901
902 /* Write packet size. */
903 stream_putw_at (s, 0, stream_get_endp (s));
904
719e9741 905 return zebra_server_send_message(client);
18a6dce6 906}
6b0655a2 907
718e3744 908/* Register zebra server interface information. Send current all
909 interface and address information. */
719e9741 910static int
718e3744 911zread_interface_add (struct zserv *client, u_short length)
912{
1eb8ef25 913 struct listnode *ifnode, *ifnnode;
914 struct listnode *cnode, *cnnode;
718e3744 915 struct interface *ifp;
916 struct connected *c;
a80beece 917 struct nbr_connected *nc;
718e3744 918
919 /* Interface information is needed. */
920 client->ifinfo = 1;
921
1eb8ef25 922 for (ALL_LIST_ELEMENTS (iflist, ifnode, ifnnode, ifp))
718e3744 923 {
718e3744 924 /* Skip pseudo interface. */
925 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
926 continue;
927
719e9741 928 if (zsend_interface_add (client, ifp) < 0)
929 return -1;
718e3744 930
1eb8ef25 931 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
718e3744 932 {
719e9741 933 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
934 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
935 ifp, c) < 0))
936 return -1;
718e3744 937 }
a80beece
DS
938 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc))
939 {
940 if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client,
941 ifp, nc) < 0)
942 return -1;
943 }
944
718e3744 945 }
719e9741 946 return 0;
718e3744 947}
948
949/* Unregister zebra server interface information. */
719e9741 950static int
718e3744 951zread_interface_delete (struct zserv *client, u_short length)
952{
953 client->ifinfo = 0;
719e9741 954 return 0;
718e3744 955}
956
957/* This function support multiple nexthop. */
b9df2d25 958/*
959 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
960 * add kernel route.
961 */
719e9741 962static int
718e3744 963zread_ipv4_add (struct zserv *client, u_short length)
964{
965 int i;
966 struct rib *rib;
967 struct prefix_ipv4 p;
968 u_char message;
969 struct in_addr nexthop;
970 u_char nexthop_num;
971 u_char nexthop_type;
972 struct stream *s;
973 unsigned int ifindex;
974 u_char ifname_len;
cddf391b
B
975 safi_t safi;
976
718e3744 977
978 /* Get input stream. */
979 s = client->ibuf;
980
981 /* Allocate new rib. */
4d38fdb4 982 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
983
718e3744 984 /* Type, flags, message. */
985 rib->type = stream_getc (s);
986 rib->flags = stream_getc (s);
b9df2d25 987 message = stream_getc (s);
cddf391b 988 safi = stream_getw (s);
718e3744 989 rib->uptime = time (NULL);
990
991 /* IPv4 prefix. */
992 memset (&p, 0, sizeof (struct prefix_ipv4));
993 p.family = AF_INET;
994 p.prefixlen = stream_getc (s);
995 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
996
997 /* Nexthop parse. */
998 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
999 {
1000 nexthop_num = stream_getc (s);
1001
1002 for (i = 0; i < nexthop_num; i++)
1003 {
1004 nexthop_type = stream_getc (s);
1005
1006 switch (nexthop_type)
1007 {
1008 case ZEBRA_NEXTHOP_IFINDEX:
1009 ifindex = stream_getl (s);
1010 nexthop_ifindex_add (rib, ifindex);
1011 break;
1012 case ZEBRA_NEXTHOP_IFNAME:
1013 ifname_len = stream_getc (s);
9985f83c 1014 stream_forward_getp (s, ifname_len);
718e3744 1015 break;
1016 case ZEBRA_NEXTHOP_IPV4:
1017 nexthop.s_addr = stream_get_ipv4 (s);
7514fb77 1018 nexthop_ipv4_add (rib, &nexthop, NULL);
718e3744 1019 break;
c963c203
JT
1020 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
1021 nexthop.s_addr = stream_get_ipv4 (s);
1022 ifindex = stream_getl (s);
1023 nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
1024 break;
718e3744 1025 case ZEBRA_NEXTHOP_IPV6:
9985f83c 1026 stream_forward_getp (s, IPV6_MAX_BYTELEN);
718e3744 1027 break;
6902c69a
SV
1028 case ZEBRA_NEXTHOP_BLACKHOLE:
1029 nexthop_blackhole_add (rib);
1030 break;
1031 }
718e3744 1032 }
1033 }
1034
1035 /* Distance. */
1036 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1037 rib->distance = stream_getc (s);
1038
1039 /* Metric. */
1040 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1041 rib->metric = stream_getl (s);
1042
0d9551dc
DS
1043 /* Tag */
1044 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
1045 rib->tag = stream_getw (s);
1046 else
1047 rib->tag = 0;
1048
171eee31
PJ
1049 /* Table */
1050 rib->table=zebrad.rtm_table_default;
cddf391b 1051 rib_add_ipv4_multipath (&p, rib, safi);
719e9741 1052 return 0;
718e3744 1053}
1054
1055/* Zebra server IPv4 prefix delete function. */
719e9741 1056static int
718e3744 1057zread_ipv4_delete (struct zserv *client, u_short length)
1058{
1059 int i;
1060 struct stream *s;
1061 struct zapi_ipv4 api;
6902c69a 1062 struct in_addr nexthop, *nexthop_p;
718e3744 1063 unsigned long ifindex;
1064 struct prefix_ipv4 p;
1065 u_char nexthop_num;
1066 u_char nexthop_type;
1067 u_char ifname_len;
1068
1069 s = client->ibuf;
1070 ifindex = 0;
1071 nexthop.s_addr = 0;
6902c69a 1072 nexthop_p = NULL;
718e3744 1073
1074 /* Type, flags, message. */
1075 api.type = stream_getc (s);
1076 api.flags = stream_getc (s);
1077 api.message = stream_getc (s);
cddf391b 1078 api.safi = stream_getw (s);
718e3744 1079
1080 /* IPv4 prefix. */
1081 memset (&p, 0, sizeof (struct prefix_ipv4));
1082 p.family = AF_INET;
1083 p.prefixlen = stream_getc (s);
1084 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1085
1086 /* Nexthop, ifindex, distance, metric. */
1087 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1088 {
1089 nexthop_num = stream_getc (s);
1090
1091 for (i = 0; i < nexthop_num; i++)
1092 {
1093 nexthop_type = stream_getc (s);
1094
1095 switch (nexthop_type)
1096 {
1097 case ZEBRA_NEXTHOP_IFINDEX:
1098 ifindex = stream_getl (s);
1099 break;
1100 case ZEBRA_NEXTHOP_IFNAME:
1101 ifname_len = stream_getc (s);
9985f83c 1102 stream_forward_getp (s, ifname_len);
718e3744 1103 break;
1104 case ZEBRA_NEXTHOP_IPV4:
1105 nexthop.s_addr = stream_get_ipv4 (s);
6902c69a 1106 nexthop_p = &nexthop;
718e3744 1107 break;
c963c203
JT
1108 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
1109 nexthop.s_addr = stream_get_ipv4 (s);
23f5f7c3 1110 nexthop_p = &nexthop;
c963c203
JT
1111 ifindex = stream_getl (s);
1112 break;
718e3744 1113 case ZEBRA_NEXTHOP_IPV6:
9985f83c 1114 stream_forward_getp (s, IPV6_MAX_BYTELEN);
718e3744 1115 break;
1116 }
1117 }
1118 }
1119
1120 /* Distance. */
1121 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1122 api.distance = stream_getc (s);
1123 else
1124 api.distance = 0;
1125
1126 /* Metric. */
1127 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1128 api.metric = stream_getl (s);
1129 else
1130 api.metric = 0;
1131
0d9551dc
DS
1132 /* tag */
1133 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
1134 api.tag = stream_getw (s);
1135 else
1136 api.tag = 0;
1137
6902c69a 1138 rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
cddf391b 1139 client->rtm_table, api.safi);
719e9741 1140 return 0;
718e3744 1141}
1142
1143/* Nexthop lookup for IPv4. */
719e9741 1144static int
718e3744 1145zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
1146{
1147 struct in_addr addr;
bb97e462 1148 char buf[BUFSIZ];
718e3744 1149
1150 addr.s_addr = stream_get_ipv4 (client->ibuf);
bb97e462
CF
1151 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1152 zlog_debug("%s: looking up %s", __func__,
1153 inet_ntop (AF_INET, &addr, buf, BUFSIZ));
719e9741 1154 return zsend_ipv4_nexthop_lookup (client, addr);
718e3744 1155}
1156
1157/* Nexthop lookup for IPv4. */
719e9741 1158static int
718e3744 1159zread_ipv4_import_lookup (struct zserv *client, u_short length)
1160{
1161 struct prefix_ipv4 p;
1162
1163 p.family = AF_INET;
1164 p.prefixlen = stream_getc (client->ibuf);
1165 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1166
719e9741 1167 return zsend_ipv4_import_lookup (client, &p);
718e3744 1168}
1169
1170#ifdef HAVE_IPV6
1171/* Zebra server IPv6 prefix add function. */
719e9741 1172static int
718e3744 1173zread_ipv6_add (struct zserv *client, u_short length)
1174{
1175 int i;
1176 struct stream *s;
718e3744 1177 struct in6_addr nexthop;
41fc2714
DS
1178 struct rib *rib;
1179 u_char message;
1180 u_char nexthop_num;
1181 u_char nexthop_type;
718e3744 1182 unsigned long ifindex;
1183 struct prefix_ipv6 p;
41fc2714
DS
1184 u_char ifname_len;
1185 safi_t safi;
1186 static struct in6_addr nexthops[MULTIPATH_NUM];
1187 static unsigned int ifindices[MULTIPATH_NUM];
1188
1189 /* Get input stream. */
718e3744 1190 s = client->ibuf;
41fc2714 1191
718e3744 1192 ifindex = 0;
1193 memset (&nexthop, 0, sizeof (struct in6_addr));
1194
41fc2714
DS
1195 /* Allocate new rib. */
1196 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1197
718e3744 1198 /* Type, flags, message. */
41fc2714
DS
1199 rib->type = stream_getc (s);
1200 rib->flags = stream_getc (s);
1201 message = stream_getc (s);
1202 safi = stream_getw (s);
1203 rib->uptime = time (NULL);
718e3744 1204
41fc2714 1205 /* IPv6 prefix. */
718e3744 1206 memset (&p, 0, sizeof (struct prefix_ipv6));
1207 p.family = AF_INET6;
1208 p.prefixlen = stream_getc (s);
1209 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1210
41fc2714
DS
1211 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1212 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1213 * these. Clients should send the same number of paired set of
1214 * next-hop-addr/next-hop-ifindices. */
1215 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
718e3744 1216 {
41fc2714
DS
1217 int nh_count = 0;
1218 int if_count = 0;
1219 int max_nh_if = 0;
718e3744 1220
41fc2714
DS
1221 nexthop_num = stream_getc (s);
1222 for (i = 0; i < nexthop_num; i++)
718e3744 1223 {
1224 nexthop_type = stream_getc (s);
1225
1226 switch (nexthop_type)
1227 {
1228 case ZEBRA_NEXTHOP_IPV6:
1229 stream_get (&nexthop, s, 16);
41fc2714
DS
1230 if (nh_count < MULTIPATH_NUM) {
1231 nexthops[nh_count++] = nexthop;
1232 }
718e3744 1233 break;
1234 case ZEBRA_NEXTHOP_IFINDEX:
41fc2714
DS
1235 if (if_count < MULTIPATH_NUM) {
1236 ifindices[if_count++] = stream_getl (s);
1237 }
718e3744 1238 break;
1239 }
1240 }
41fc2714
DS
1241
1242 max_nh_if = (nh_count > if_count) ? nh_count : if_count;
1243 for (i = 0; i < max_nh_if; i++)
1244 {
1245 if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
1246 if ((i < if_count) && ifindices[i]) {
1247 if (rib_bogus_ipv6 (rib->type, &p, &nexthops[i], ifindices[i], 0)) {
1248 continue;
1249 }
1250 nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
1251 }
1252 else {
1253 if (rib_bogus_ipv6 (rib->type, &p, &nexthops[i], 0, 0)) {
1254 continue;
1255 }
1256 nexthop_ipv6_add (rib, &nexthops[i]);
1257 }
1258 }
1259 else {
1260 if ((i < if_count) && ifindices[i]) {
1261 if (rib_bogus_ipv6 (rib->type, &p, NULL, ifindices[i], 0)) {
1262 continue;
1263 }
1264 nexthop_ifindex_add (rib, ifindices[i]);
1265 }
1266 }
1267 }
718e3744 1268 }
1269
41fc2714
DS
1270 /* Distance. */
1271 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1272 rib->distance = stream_getc (s);
718e3744 1273
41fc2714
DS
1274 /* Metric. */
1275 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1276 rib->metric = stream_getl (s);
718e3744 1277
0d9551dc
DS
1278 /* Tag */
1279 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
1280 rib->tag = stream_getw (s);
1281 else
1282 rib->tag = 0;
1283
41fc2714
DS
1284 /* Table */
1285 rib->table=zebrad.rtm_table_default;
1286 rib_add_ipv6_multipath (&p, rib, safi, ifindex);
719e9741 1287 return 0;
718e3744 1288}
1289
1290/* Zebra server IPv6 prefix delete function. */
719e9741 1291static int
718e3744 1292zread_ipv6_delete (struct zserv *client, u_short length)
1293{
1294 int i;
1295 struct stream *s;
1296 struct zapi_ipv6 api;
1297 struct in6_addr nexthop;
1298 unsigned long ifindex;
1299 struct prefix_ipv6 p;
1300
1301 s = client->ibuf;
1302 ifindex = 0;
1303 memset (&nexthop, 0, sizeof (struct in6_addr));
1304
1305 /* Type, flags, message. */
1306 api.type = stream_getc (s);
1307 api.flags = stream_getc (s);
1308 api.message = stream_getc (s);
f768f367 1309 api.safi = stream_getw (s);
718e3744 1310
1311 /* IPv4 prefix. */
1312 memset (&p, 0, sizeof (struct prefix_ipv6));
1313 p.family = AF_INET6;
1314 p.prefixlen = stream_getc (s);
1315 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1316
1317 /* Nexthop, ifindex, distance, metric. */
1318 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1319 {
1320 u_char nexthop_type;
1321
1322 api.nexthop_num = stream_getc (s);
1323 for (i = 0; i < api.nexthop_num; i++)
1324 {
1325 nexthop_type = stream_getc (s);
1326
1327 switch (nexthop_type)
1328 {
1329 case ZEBRA_NEXTHOP_IPV6:
1330 stream_get (&nexthop, s, 16);
1331 break;
1332 case ZEBRA_NEXTHOP_IFINDEX:
1333 ifindex = stream_getl (s);
1334 break;
1335 }
1336 }
1337 }
1338
0d9551dc 1339 /* Distance. */
718e3744 1340 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1341 api.distance = stream_getc (s);
1342 else
1343 api.distance = 0;
0d9551dc
DS
1344
1345 /* Metric. */
718e3744 1346 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1347 api.metric = stream_getl (s);
1348 else
1349 api.metric = 0;
1350
0d9551dc
DS
1351 /* tag */
1352 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
1353 api.tag = stream_getw (s);
1354 else
1355 api.tag = 0;
1356
718e3744 1357 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
f768f367 1358 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
718e3744 1359 else
f768f367 1360 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
719e9741 1361 return 0;
718e3744 1362}
1363
719e9741 1364static int
718e3744 1365zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1366{
1367 struct in6_addr addr;
1368 char buf[BUFSIZ];
1369
1370 stream_get (&addr, client->ibuf, 16);
a5207089
CF
1371 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1372 zlog_debug("%s: looking up %s", __func__,
1373 inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
718e3744 1374
719e9741 1375 return zsend_ipv6_nexthop_lookup (client, &addr);
718e3744 1376}
1377#endif /* HAVE_IPV6 */
1378
18a6dce6 1379/* Register zebra server router-id information. Send current router-id */
719e9741 1380static int
18a6dce6 1381zread_router_id_add (struct zserv *client, u_short length)
1382{
1383 struct prefix p;
1384
1385 /* Router-id information is needed. */
1386 client->ridinfo = 1;
1387
1388 router_id_get (&p);
1389
719e9741 1390 return zsend_router_id_update (client,&p);
18a6dce6 1391}
1392
1393/* Unregister zebra server router-id information. */
719e9741 1394static int
18a6dce6 1395zread_router_id_delete (struct zserv *client, u_short length)
1396{
1397 client->ridinfo = 0;
719e9741 1398 return 0;
18a6dce6 1399}
1400
2ea1ab1c
VT
1401/* Tie up route-type and client->sock */
1402static void
1403zread_hello (struct zserv *client)
1404{
1405 /* type of protocol (lib/zebra.h) */
1406 u_char proto;
1407 proto = stream_getc (client->ibuf);
1408
1409 /* accept only dynamic routing protocols */
1410 if ((proto < ZEBRA_ROUTE_MAX)
1411 && (proto > ZEBRA_ROUTE_STATIC))
1412 {
1413 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1414 client->sock, zebra_route_string(proto));
1415
1416 /* if route-type was binded by other client */
1417 if (route_type_oaths[proto])
1418 zlog_warn ("sender of %s routes changed %c->%c",
1419 zebra_route_string(proto), route_type_oaths[proto],
1420 client->sock);
1421
1422 route_type_oaths[proto] = client->sock;
fb018d25 1423 client->proto = proto;
2ea1ab1c
VT
1424 }
1425}
1426
1427/* If client sent routes of specific type, zebra removes it
1428 * and returns number of deleted routes.
1429 */
1430static void
1431zebra_score_rib (int client_sock)
1432{
1433 int i;
1434
1435 for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
1436 if (client_sock == route_type_oaths[i])
1437 {
1438 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1439 client_sock, rib_score_proto (i), zebra_route_string (i));
1440 route_type_oaths[i] = 0;
1441 break;
1442 }
1443}
1444
718e3744 1445/* Close zebra client. */
b9df2d25 1446static void
718e3744 1447zebra_client_close (struct zserv *client)
1448{
fb018d25
DS
1449 zebra_cleanup_rnh_client(0, AF_INET, client);
1450 zebra_cleanup_rnh_client(0, AF_INET6, client);
1451
718e3744 1452 /* Close file descriptor. */
1453 if (client->sock)
1454 {
1455 close (client->sock);
2ea1ab1c 1456 zebra_score_rib (client->sock);
718e3744 1457 client->sock = -1;
1458 }
1459
1460 /* Free stream buffers. */
1461 if (client->ibuf)
1462 stream_free (client->ibuf);
1463 if (client->obuf)
1464 stream_free (client->obuf);
719e9741 1465 if (client->wb)
1466 buffer_free(client->wb);
718e3744 1467
1468 /* Release threads. */
1469 if (client->t_read)
1470 thread_cancel (client->t_read);
1471 if (client->t_write)
1472 thread_cancel (client->t_write);
719e9741 1473 if (client->t_suicide)
1474 thread_cancel (client->t_suicide);
718e3744 1475
1476 /* Free client structure. */
b21b19c5 1477 listnode_delete (zebrad.client_list, client);
718e3744 1478 XFREE (0, client);
1479}
1480
1481/* Make new client. */
b9df2d25 1482static void
718e3744 1483zebra_client_create (int sock)
1484{
1485 struct zserv *client;
1486
1487 client = XCALLOC (0, sizeof (struct zserv));
1488
1489 /* Make client input/output buffer. */
1490 client->sock = sock;
1491 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1492 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
719e9741 1493 client->wb = buffer_new(0);
718e3744 1494
1495 /* Set table number. */
b21b19c5 1496 client->rtm_table = zebrad.rtm_table_default;
718e3744 1497
1498 /* Add this client to linked list. */
b21b19c5 1499 listnode_add (zebrad.client_list, client);
718e3744 1500
1501 /* Make new read thread. */
1502 zebra_event (ZEBRA_READ, sock, client);
1503}
1504
1505/* Handler of zebra service request. */
b9df2d25 1506static int
718e3744 1507zebra_client_read (struct thread *thread)
1508{
1509 int sock;
1510 struct zserv *client;
57a1477b 1511 size_t already;
c1b9800a 1512 uint16_t length, command;
1513 uint8_t marker, version;
718e3744 1514
1515 /* Get thread data. Reset reading thread because I'm running. */
1516 sock = THREAD_FD (thread);
1517 client = THREAD_ARG (thread);
1518 client->t_read = NULL;
1519
719e9741 1520 if (client->t_suicide)
718e3744 1521 {
719e9741 1522 zebra_client_close(client);
718e3744 1523 return -1;
1524 }
719e9741 1525
1526 /* Read length and command (if we don't have it already). */
57a1477b 1527 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
719e9741 1528 {
57a1477b 1529 ssize_t nbyte;
719e9741 1530 if (((nbyte = stream_read_try (client->ibuf, sock,
57a1477b 1531 ZEBRA_HEADER_SIZE-already)) == 0) ||
719e9741 1532 (nbyte == -1))
1533 {
1534 if (IS_ZEBRA_DEBUG_EVENT)
1535 zlog_debug ("connection closed socket [%d]", sock);
1536 zebra_client_close (client);
1537 return -1;
1538 }
57a1477b 1539 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
719e9741 1540 {
1541 /* Try again later. */
1542 zebra_event (ZEBRA_READ, sock, client);
1543 return 0;
1544 }
57a1477b 1545 already = ZEBRA_HEADER_SIZE;
719e9741 1546 }
1547
1548 /* Reset to read from the beginning of the incoming packet. */
1549 stream_set_getp(client->ibuf, 0);
1550
c1b9800a 1551 /* Fetch header values */
718e3744 1552 length = stream_getw (client->ibuf);
c1b9800a 1553 marker = stream_getc (client->ibuf);
1554 version = stream_getc (client->ibuf);
1555 command = stream_getw (client->ibuf);
718e3744 1556
c1b9800a 1557 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1558 {
1559 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1560 __func__, sock, marker, version);
1561 zebra_client_close (client);
1562 return -1;
1563 }
719e9741 1564 if (length < ZEBRA_HEADER_SIZE)
718e3744 1565 {
57a1477b 1566 zlog_warn("%s: socket %d message length %u is less than header size %d",
1567 __func__, sock, length, ZEBRA_HEADER_SIZE);
1568 zebra_client_close (client);
1569 return -1;
1570 }
1571 if (length > STREAM_SIZE(client->ibuf))
1572 {
1573 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1574 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
718e3744 1575 zebra_client_close (client);
1576 return -1;
1577 }
1578
718e3744 1579 /* Read rest of data. */
57a1477b 1580 if (already < length)
718e3744 1581 {
57a1477b 1582 ssize_t nbyte;
1583 if (((nbyte = stream_read_try (client->ibuf, sock,
1584 length-already)) == 0) ||
1585 (nbyte == -1))
718e3744 1586 {
1587 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 1588 zlog_debug ("connection closed [%d] when reading zebra data", sock);
718e3744 1589 zebra_client_close (client);
1590 return -1;
1591 }
57a1477b 1592 if (nbyte != (ssize_t)(length-already))
719e9741 1593 {
1594 /* Try again later. */
1595 zebra_event (ZEBRA_READ, sock, client);
1596 return 0;
1597 }
718e3744 1598 }
1599
719e9741 1600 length -= ZEBRA_HEADER_SIZE;
1601
718e3744 1602 /* Debug packet information. */
1603 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 1604 zlog_debug ("zebra message comes from socket [%d]", sock);
718e3744 1605
1606 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
b6178002 1607 zlog_debug ("zebra message received [%s] %d",
66859780 1608 zserv_command_string (command), length);
718e3744 1609
1610 switch (command)
1611 {
18a6dce6 1612 case ZEBRA_ROUTER_ID_ADD:
1613 zread_router_id_add (client, length);
1614 break;
1615 case ZEBRA_ROUTER_ID_DELETE:
1616 zread_router_id_delete (client, length);
1617 break;
718e3744 1618 case ZEBRA_INTERFACE_ADD:
1619 zread_interface_add (client, length);
1620 break;
1621 case ZEBRA_INTERFACE_DELETE:
1622 zread_interface_delete (client, length);
1623 break;
1624 case ZEBRA_IPV4_ROUTE_ADD:
1625 zread_ipv4_add (client, length);
1626 break;
1627 case ZEBRA_IPV4_ROUTE_DELETE:
1628 zread_ipv4_delete (client, length);
1629 break;
1630#ifdef HAVE_IPV6
1631 case ZEBRA_IPV6_ROUTE_ADD:
1632 zread_ipv6_add (client, length);
1633 break;
1634 case ZEBRA_IPV6_ROUTE_DELETE:
1635 zread_ipv6_delete (client, length);
1636 break;
1637#endif /* HAVE_IPV6 */
1638 case ZEBRA_REDISTRIBUTE_ADD:
1639 zebra_redistribute_add (command, client, length);
1640 break;
1641 case ZEBRA_REDISTRIBUTE_DELETE:
1642 zebra_redistribute_delete (command, client, length);
1643 break;
1644 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1645 zebra_redistribute_default_add (command, client, length);
1646 break;
1647 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1648 zebra_redistribute_default_delete (command, client, length);
1649 break;
1650 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1651 zread_ipv4_nexthop_lookup (client, length);
1652 break;
1653#ifdef HAVE_IPV6
1654 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1655 zread_ipv6_nexthop_lookup (client, length);
1656 break;
1657#endif /* HAVE_IPV6 */
1658 case ZEBRA_IPV4_IMPORT_LOOKUP:
1659 zread_ipv4_import_lookup (client, length);
1660 break;
2ea1ab1c
VT
1661 case ZEBRA_HELLO:
1662 zread_hello (client);
1663 break;
fb018d25
DS
1664 case ZEBRA_NEXTHOP_REGISTER:
1665 zserv_nexthop_register(client, sock, length);
1666 break;
1667 case ZEBRA_NEXTHOP_UNREGISTER:
1668 zserv_nexthop_unregister(client, sock, length);
1669 break;
718e3744 1670 default:
1671 zlog_info ("Zebra received unknown command %d", command);
1672 break;
1673 }
1674
719e9741 1675 if (client->t_suicide)
1676 {
1677 /* No need to wait for thread callback, just kill immediately. */
1678 zebra_client_close(client);
1679 return -1;
1680 }
1681
718e3744 1682 stream_reset (client->ibuf);
1683 zebra_event (ZEBRA_READ, sock, client);
718e3744 1684 return 0;
1685}
1686
718e3744 1687
1688/* Accept code of zebra server socket. */
b9df2d25 1689static int
718e3744 1690zebra_accept (struct thread *thread)
1691{
1692 int accept_sock;
1693 int client_sock;
1694 struct sockaddr_in client;
1695 socklen_t len;
1696
1697 accept_sock = THREAD_FD (thread);
1698
719e9741 1699 /* Reregister myself. */
1700 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1701
718e3744 1702 len = sizeof (struct sockaddr_in);
1703 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1704
1705 if (client_sock < 0)
1706 {
6099b3b5 1707 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
718e3744 1708 return -1;
1709 }
1710
ccf3557b 1711 /* Make client socket non-blocking. */
719e9741 1712 set_nonblocking(client_sock);
865b852c 1713
718e3744 1714 /* Create new zebra client. */
1715 zebra_client_create (client_sock);
1716
718e3744 1717 return 0;
1718}
1719
b9df2d25 1720#ifdef HAVE_TCP_ZEBRA
718e3744 1721/* Make zebra's server socket. */
b9df2d25 1722static void
718e3744 1723zebra_serv ()
1724{
1725 int ret;
1726 int accept_sock;
1727 struct sockaddr_in addr;
1728
1729 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1730
1731 if (accept_sock < 0)
1732 {
3d1dc857 1733 zlog_warn ("Can't create zserv stream socket: %s",
1734 safe_strerror (errno));
718e3744 1735 zlog_warn ("zebra can't provice full functionality due to above error");
1736 return;
1737 }
1738
2ea1ab1c 1739 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
718e3744 1740 memset (&addr, 0, sizeof (struct sockaddr_in));
1741 addr.sin_family = AF_INET;
1742 addr.sin_port = htons (ZEBRA_PORT);
6f0e3f6e 1743#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
718e3744 1744 addr.sin_len = sizeof (struct sockaddr_in);
6f0e3f6e 1745#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 1746 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1747
1748 sockopt_reuseaddr (accept_sock);
1749 sockopt_reuseport (accept_sock);
1750
edd7c245 1751 if ( zserv_privs.change(ZPRIVS_RAISE) )
1752 zlog (NULL, LOG_ERR, "Can't raise privileges");
1753
718e3744 1754 ret = bind (accept_sock, (struct sockaddr *)&addr,
1755 sizeof (struct sockaddr_in));
1756 if (ret < 0)
1757 {
3d1dc857 1758 zlog_warn ("Can't bind to stream socket: %s",
1759 safe_strerror (errno));
718e3744 1760 zlog_warn ("zebra can't provice full functionality due to above error");
1761 close (accept_sock); /* Avoid sd leak. */
1762 return;
1763 }
edd7c245 1764
1765 if ( zserv_privs.change(ZPRIVS_LOWER) )
1766 zlog (NULL, LOG_ERR, "Can't lower privileges");
718e3744 1767
1768 ret = listen (accept_sock, 1);
1769 if (ret < 0)
1770 {
3d1dc857 1771 zlog_warn ("Can't listen to stream socket: %s",
1772 safe_strerror (errno));
718e3744 1773 zlog_warn ("zebra can't provice full functionality due to above error");
1774 close (accept_sock); /* Avoid sd leak. */
1775 return;
1776 }
1777
1778 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1779}
b9df2d25 1780#endif /* HAVE_TCP_ZEBRA */
718e3744 1781
1782/* For sockaddr_un. */
1783#include <sys/un.h>
1784
1785/* zebra server UNIX domain socket. */
b9df2d25 1786static void
fce954f8 1787zebra_serv_un (const char *path)
718e3744 1788{
1789 int ret;
1790 int sock, len;
1791 struct sockaddr_un serv;
1792 mode_t old_mask;
1793
1794 /* First of all, unlink existing socket */
1795 unlink (path);
1796
1797 /* Set umask */
1798 old_mask = umask (0077);
1799
1800 /* Make UNIX domain socket. */
1801 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1802 if (sock < 0)
1803 {
3d1dc857 1804 zlog_warn ("Can't create zserv unix socket: %s",
1805 safe_strerror (errno));
1806 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 1807 return;
1808 }
1809
2ea1ab1c
VT
1810 memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1811
718e3744 1812 /* Make server socket. */
1813 memset (&serv, 0, sizeof (struct sockaddr_un));
1814 serv.sun_family = AF_UNIX;
1815 strncpy (serv.sun_path, path, strlen (path));
6f0e3f6e 1816#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
718e3744 1817 len = serv.sun_len = SUN_LEN(&serv);
1818#else
1819 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
6f0e3f6e 1820#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
718e3744 1821
1822 ret = bind (sock, (struct sockaddr *) &serv, len);
1823 if (ret < 0)
1824 {
3d1dc857 1825 zlog_warn ("Can't bind to unix socket %s: %s",
1826 path, safe_strerror (errno));
1827 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 1828 close (sock);
1829 return;
1830 }
1831
1832 ret = listen (sock, 5);
1833 if (ret < 0)
1834 {
3d1dc857 1835 zlog_warn ("Can't listen to unix socket %s: %s",
1836 path, safe_strerror (errno));
1837 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 1838 close (sock);
1839 return;
1840 }
1841
1842 umask (old_mask);
1843
1844 zebra_event (ZEBRA_SERV, sock, NULL);
1845}
6b0655a2 1846
718e3744 1847
b9df2d25 1848static void
718e3744 1849zebra_event (enum event event, int sock, struct zserv *client)
1850{
1851 switch (event)
1852 {
1853 case ZEBRA_SERV:
b21b19c5 1854 thread_add_read (zebrad.master, zebra_accept, client, sock);
718e3744 1855 break;
1856 case ZEBRA_READ:
1857 client->t_read =
b21b19c5 1858 thread_add_read (zebrad.master, zebra_client_read, client, sock);
718e3744 1859 break;
1860 case ZEBRA_WRITE:
1861 /**/
1862 break;
1863 }
1864}
6b0655a2 1865
718e3744 1866/* Display default rtm_table for all clients. */
1867DEFUN (show_table,
1868 show_table_cmd,
1869 "show table",
1870 SHOW_STR
1871 "default routing table to use for all clients\n")
1872{
b21b19c5 1873 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
718e3744 1874 VTY_NEWLINE);
1875 return CMD_SUCCESS;
1876}
1877
1878DEFUN (config_table,
1879 config_table_cmd,
1880 "table TABLENO",
1881 "Configure target kernel routing table\n"
1882 "TABLE integer\n")
1883{
b21b19c5 1884 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
718e3744 1885 return CMD_SUCCESS;
1886}
1887
647e4f1f 1888DEFUN (ip_forwarding,
1889 ip_forwarding_cmd,
1890 "ip forwarding",
1891 IP_STR
1892 "Turn on IP forwarding")
1893{
1894 int ret;
1895
1896 ret = ipforward ();
b71f00f2 1897 if (ret == 0)
1898 ret = ipforward_on ();
647e4f1f 1899
647e4f1f 1900 if (ret == 0)
1901 {
1902 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1903 return CMD_WARNING;
1904 }
1905
1906 return CMD_SUCCESS;
1907}
1908
718e3744 1909DEFUN (no_ip_forwarding,
1910 no_ip_forwarding_cmd,
1911 "no ip forwarding",
1912 NO_STR
1913 IP_STR
1914 "Turn off IP forwarding")
1915{
1916 int ret;
1917
1918 ret = ipforward ();
b71f00f2 1919 if (ret != 0)
1920 ret = ipforward_off ();
718e3744 1921
718e3744 1922 if (ret != 0)
1923 {
1924 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1925 return CMD_WARNING;
1926 }
1927
1928 return CMD_SUCCESS;
1929}
1930
1931/* This command is for debugging purpose. */
1932DEFUN (show_zebra_client,
1933 show_zebra_client_cmd,
1934 "show zebra client",
1935 SHOW_STR
1936 "Zebra information"
1937 "Client information")
1938{
52dc7ee6 1939 struct listnode *node;
718e3744 1940 struct zserv *client;
1941
1eb8ef25 1942 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
fb018d25
DS
1943 vty_out (vty, "Client %s fd %d%s",
1944 zebra_route_string(client->proto), client->sock,
1945 VTY_NEWLINE);
1946
718e3744 1947 return CMD_SUCCESS;
1948}
1949
1950/* Table configuration write function. */
b9df2d25 1951static int
718e3744 1952config_write_table (struct vty *vty)
1953{
b21b19c5 1954 if (zebrad.rtm_table_default)
1955 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
718e3744 1956 VTY_NEWLINE);
1957 return 0;
1958}
1959
1960/* table node for routing tables. */
7fc626de 1961static struct cmd_node table_node =
718e3744 1962{
1963 TABLE_NODE,
1964 "", /* This node has no interface. */
1965 1
1966};
6b0655a2 1967
718e3744 1968/* Only display ip forwarding is enabled or not. */
1969DEFUN (show_ip_forwarding,
1970 show_ip_forwarding_cmd,
1971 "show ip forwarding",
1972 SHOW_STR
1973 IP_STR
1974 "IP forwarding status\n")
1975{
1976 int ret;
1977
1978 ret = ipforward ();
1979
1980 if (ret == 0)
1981 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1982 else
1983 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1984 return CMD_SUCCESS;
1985}
1986
1987#ifdef HAVE_IPV6
1988/* Only display ipv6 forwarding is enabled or not. */
1989DEFUN (show_ipv6_forwarding,
1990 show_ipv6_forwarding_cmd,
1991 "show ipv6 forwarding",
1992 SHOW_STR
1993 "IPv6 information\n"
1994 "Forwarding status\n")
1995{
1996 int ret;
1997
1998 ret = ipforward_ipv6 ();
1999
2000 switch (ret)
2001 {
2002 case -1:
2003 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
2004 break;
2005 case 0:
2006 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
2007 break;
2008 case 1:
2009 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
2010 break;
2011 default:
2012 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
2013 break;
2014 }
2015 return CMD_SUCCESS;
2016}
2017
55906724 2018DEFUN (ipv6_forwarding,
2019 ipv6_forwarding_cmd,
2020 "ipv6 forwarding",
2021 IPV6_STR
2022 "Turn on IPv6 forwarding")
2023{
2024 int ret;
2025
41d3fc96 2026 ret = ipforward_ipv6 ();
b71f00f2 2027 if (ret == 0)
2028 ret = ipforward_ipv6_on ();
41d3fc96 2029
41d3fc96 2030 if (ret == 0)
55906724 2031 {
2032 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
2033 return CMD_WARNING;
2034 }
2035
2036 return CMD_SUCCESS;
2037}
2038
718e3744 2039DEFUN (no_ipv6_forwarding,
2040 no_ipv6_forwarding_cmd,
2041 "no ipv6 forwarding",
2042 NO_STR
55906724 2043 IPV6_STR
2044 "Turn off IPv6 forwarding")
718e3744 2045{
2046 int ret;
2047
41d3fc96 2048 ret = ipforward_ipv6 ();
b71f00f2 2049 if (ret != 0)
2050 ret = ipforward_ipv6_off ();
41d3fc96 2051
718e3744 2052 if (ret != 0)
2053 {
2054 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
2055 return CMD_WARNING;
2056 }
2057
2058 return CMD_SUCCESS;
2059}
2060
2061#endif /* HAVE_IPV6 */
2062
2063/* IPForwarding configuration write function. */
719e9741 2064static int
718e3744 2065config_write_forwarding (struct vty *vty)
2066{
18a6dce6 2067 /* FIXME: Find better place for that. */
2068 router_id_write (vty);
2069
3e0b3a56 2070 if (ipforward ())
2071 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
718e3744 2072#ifdef HAVE_IPV6
3e0b3a56 2073 if (ipforward_ipv6 ())
2074 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
718e3744 2075#endif /* HAVE_IPV6 */
2076 vty_out (vty, "!%s", VTY_NEWLINE);
2077 return 0;
2078}
2079
2080/* table node for routing tables. */
7fc626de 2081static struct cmd_node forwarding_node =
718e3744 2082{
2083 FORWARDING_NODE,
2084 "", /* This node has no interface. */
2085 1
2086};
2087
6b0655a2 2088
718e3744 2089/* Initialisation of zebra and installation of commands. */
2090void
a1ac18c4 2091zebra_init (void)
718e3744 2092{
2093 /* Client list init. */
b21b19c5 2094 zebrad.client_list = list_new ();
718e3744 2095
718e3744 2096 /* Install configuration write function. */
2097 install_node (&table_node, config_write_table);
2098 install_node (&forwarding_node, config_write_forwarding);
2099
2100 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
2101 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
647e4f1f 2102 install_element (CONFIG_NODE, &ip_forwarding_cmd);
718e3744 2103 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
2104 install_element (ENABLE_NODE, &show_zebra_client_cmd);
2105
2106#ifdef HAVE_NETLINK
2107 install_element (VIEW_NODE, &show_table_cmd);
2108 install_element (ENABLE_NODE, &show_table_cmd);
2109 install_element (CONFIG_NODE, &config_table_cmd);
2110#endif /* HAVE_NETLINK */
2111
2112#ifdef HAVE_IPV6
2113 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
2114 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
55906724 2115 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
718e3744 2116 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
2117#endif /* HAVE_IPV6 */
7514fb77
PJ
2118
2119 /* Route-map */
2120 zebra_route_map_init ();
718e3744 2121}
97be79f9
DO
2122
2123/* Make zebra server socket, wiping any existing one (see bug #403). */
2124void
b5114685 2125zebra_zserv_socket_init (char *path)
97be79f9
DO
2126{
2127#ifdef HAVE_TCP_ZEBRA
2128 zebra_serv ();
2129#else
b5114685 2130 zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
97be79f9
DO
2131#endif /* HAVE_TCP_ZEBRA */
2132}