]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zserv.c
Quagga: Fixup some compile warnings
[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"
78104b9b 40#include "vrf.h"
718e3744 41
42#include "zebra/zserv.h"
18a6dce6 43#include "zebra/router-id.h"
718e3744 44#include "zebra/redistribute.h"
45#include "zebra/debug.h"
46#include "zebra/ipforward.h"
fb018d25 47#include "zebra/zebra_rnh.h"
5c610faf 48#include "zebra/rt_netlink.h"
88177fe3
DS
49#include "zebra/interface.h"
50#include "zebra/zebra_ptm.h"
6b0655a2 51
718e3744 52/* Event list of zebra. */
53enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
54
b21b19c5 55extern struct zebra_t zebrad;
718e3744 56
b9df2d25 57static void zebra_event (enum event event, int sock, struct zserv *client);
ccf3557b 58
edd7c245 59extern struct zebra_privs_t zserv_privs;
6b0655a2 60
719e9741 61static void zebra_client_close (struct zserv *client);
ccf3557b 62
719e9741 63static int
64zserv_delayed_close(struct thread *thread)
ccf3557b 65{
719e9741 66 struct zserv *client = THREAD_ARG(thread);
ccf3557b 67
719e9741 68 client->t_suicide = NULL;
69 zebra_client_close(client);
ccf3557b 70 return 0;
71}
72
719e9741 73static int
74zserv_flush_data(struct thread *thread)
ccf3557b 75{
719e9741 76 struct zserv *client = THREAD_ARG(thread);
ccf3557b 77
719e9741 78 client->t_write = NULL;
79 if (client->t_suicide)
ccf3557b 80 {
719e9741 81 zebra_client_close(client);
82 return -1;
ccf3557b 83 }
719e9741 84 switch (buffer_flush_available(client->wb, client->sock))
ccf3557b 85 {
719e9741 86 case BUFFER_ERROR:
87 zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
88 "closing", __func__, client->sock);
89 zebra_client_close(client);
90 break;
91 case BUFFER_PENDING:
92 client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
93 client, client->sock);
94 break;
95 case BUFFER_EMPTY:
96 break;
ccf3557b 97 }
04b02fda
DS
98
99 client->last_write_time = quagga_time(NULL);
719e9741 100 return 0;
101}
ccf3557b 102
fb018d25 103int
719e9741 104zebra_server_send_message(struct zserv *client)
105{
106 if (client->t_suicide)
107 return -1;
04b02fda
DS
108
109 stream_set_getp(client->obuf, 0);
110 client->last_write_cmd = stream_getw_from(client->obuf, 4);
719e9741 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 }
04b02fda
DS
132
133 client->last_write_time = quagga_time(NULL);
ccf3557b 134 return 0;
135}
136
fb018d25 137void
7076bb2f 138zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
c1b9800a 139{
140 /* length placeholder, caller can update */
141 stream_putw (s, ZEBRA_HEADER_SIZE);
142 stream_putc (s, ZEBRA_HEADER_MARKER);
143 stream_putc (s, ZSERV_VERSION);
7076bb2f 144 stream_putw (s, vrf_id);
c1b9800a 145 stream_putw (s, cmd);
146}
147
51d4ef83
JB
148static void
149zserv_encode_interface (struct stream *s, struct interface *ifp)
150{
151 /* Interface information. */
152 stream_put (s, ifp->name, INTERFACE_NAMSIZ);
153 stream_putl (s, ifp->ifindex);
154 stream_putc (s, ifp->status);
155 stream_putq (s, ifp->flags);
244c1cdc
DS
156 stream_putc (s, ifp->ptm_enable);
157 stream_putc (s, ifp->ptm_status);
51d4ef83
JB
158 stream_putl (s, ifp->metric);
159 stream_putl (s, ifp->mtu);
160 stream_putl (s, ifp->mtu6);
161 stream_putl (s, ifp->bandwidth);
162#ifdef HAVE_STRUCT_SOCKADDR_DL
ca3ccd87 163 stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
51d4ef83
JB
164#else
165 stream_putl (s, ifp->hw_addr_len);
166 if (ifp->hw_addr_len)
167 stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
168#endif /* HAVE_STRUCT_SOCKADDR_DL */
169
170 /* Write packet size. */
171 stream_putw_at (s, 0, stream_get_endp (s));
172}
173
718e3744 174/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
b9df2d25 175/*
176 * This function is called in the following situations:
177 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
178 * from the client.
179 * - at startup, when zebra figures out the available interfaces
180 * - when an interface is added (where support for
181 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
182 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
183 * received)
184 */
718e3744 185int
186zsend_interface_add (struct zserv *client, struct interface *ifp)
187{
188 struct stream *s;
189
190 /* Check this client need interface information. */
7076bb2f 191 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
719e9741 192 return 0;
718e3744 193
194 s = client->obuf;
195 stream_reset (s);
196
7076bb2f 197 zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
51d4ef83 198 zserv_encode_interface (s, ifp);
718e3744 199
04b02fda 200 client->ifadd_cnt++;
719e9741 201 return zebra_server_send_message(client);
718e3744 202}
203
204/* Interface deletion from zebra daemon. */
205int
206zsend_interface_delete (struct zserv *client, struct interface *ifp)
207{
208 struct stream *s;
209
210 /* Check this client need interface information. */
7076bb2f 211 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
719e9741 212 return 0;
718e3744 213
214 s = client->obuf;
215 stream_reset (s);
718e3744 216
7076bb2f 217 zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
51d4ef83 218 zserv_encode_interface (s, ifp);
718e3744 219
04b02fda 220 client->ifdel_cnt++;
719e9741 221 return zebra_server_send_message (client);
718e3744 222}
223
b9df2d25 224/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
225 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
226 *
227 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
228 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
229 * from the client, after the ZEBRA_INTERFACE_ADD has been
230 * sent from zebra to the client
231 * - redistribute new address info to all clients in the following situations
232 * - at startup, when zebra figures out the available interfaces
233 * - when an interface is added (where support for
234 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
235 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
236 * received)
237 * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
238 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
239 * - when an RTM_NEWADDR message is received from the kernel,
240 *
241 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
242 *
243 * zsend_interface_address(DELETE)
244 * ^
245 * |
246 * zebra_interface_address_delete_update
247 * ^ ^ ^
6eb8827d 248 * | | if_delete_update
249 * | |
b9df2d25 250 * ip_address_uninstall connected_delete_ipv4
251 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
252 * ^ ^
253 * | |
254 * | RTM_NEWADDR on routing/netlink socket
255 * |
256 * vty commands:
257 * "no ip address A.B.C.D/M [label LINE]"
258 * "no ip address A.B.C.D/M secondary"
259 * ["no ipv6 address X:X::X:X/M"]
260 *
261 */
718e3744 262int
b9df2d25 263zsend_interface_address (int cmd, struct zserv *client,
264 struct interface *ifp, struct connected *ifc)
718e3744 265{
266 int blen;
267 struct stream *s;
268 struct prefix *p;
269
270 /* Check this client need interface information. */
7076bb2f 271 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
719e9741 272 return 0;
718e3744 273
274 s = client->obuf;
275 stream_reset (s);
c1b9800a 276
7076bb2f 277 zserv_create_header (s, cmd, ifp->vrf_id);
718e3744 278 stream_putl (s, ifp->ifindex);
279
280 /* Interface address flag. */
281 stream_putc (s, ifc->flags);
282
283 /* Prefix information. */
284 p = ifc->address;
285 stream_putc (s, p->family);
286 blen = prefix_blen (p);
287 stream_put (s, &p->u.prefix, blen);
b9df2d25 288
289 /*
290 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
291 * but zebra_interface_address_delete_read() in the gnu version
292 * expects to find it
293 */
718e3744 294 stream_putc (s, p->prefixlen);
295
296 /* Destination. */
297 p = ifc->destination;
298 if (p)
299 stream_put (s, &p->u.prefix, blen);
300 else
301 stream_put (s, NULL, blen);
302
303 /* Write packet size. */
304 stream_putw_at (s, 0, stream_get_endp (s));
305
04b02fda 306 client->connected_rt_add_cnt++;
719e9741 307 return zebra_server_send_message(client);
718e3744 308}
309
a80beece
DS
310static int
311zsend_interface_nbr_address (int cmd, struct zserv *client,
312 struct interface *ifp, struct nbr_connected *ifc)
313{
314 int blen;
315 struct stream *s;
316 struct prefix *p;
317
318 /* Check this client need interface information. */
319 if (! client->ifinfo)
320 return 0;
321
322 s = client->obuf;
323 stream_reset (s);
324
7076bb2f 325 zserv_create_header (s, cmd, ifp->vrf_id);
a80beece
DS
326 stream_putl (s, ifp->ifindex);
327
328 /* Prefix information. */
329 p = ifc->address;
330 stream_putc (s, p->family);
331 blen = prefix_blen (p);
332 stream_put (s, &p->u.prefix, blen);
333
334 /*
335 * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
336 * but zebra_interface_address_delete_read() in the gnu version
337 * expects to find it
338 */
339 stream_putc (s, p->prefixlen);
340
341 /* Write packet size. */
342 stream_putw_at (s, 0, stream_get_endp (s));
343
344 return zebra_server_send_message(client);
345}
346
347/* Interface address addition. */
348static void
349zebra_interface_nbr_address_add_update (struct interface *ifp,
350 struct nbr_connected *ifc)
351{
352 struct listnode *node, *nnode;
353 struct zserv *client;
354 struct prefix *p;
355
356 if (IS_ZEBRA_DEBUG_EVENT)
357 {
358 char buf[INET6_ADDRSTRLEN];
359
360 p = ifc->address;
361 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
362 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
363 p->prefixlen, ifc->ifp->name);
364 }
365
366 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
367 if (client->ifinfo)
368 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc);
369}
370
371/* Interface address deletion. */
372static void
373zebra_interface_nbr_address_delete_update (struct interface *ifp,
374 struct nbr_connected *ifc)
375{
376 struct listnode *node, *nnode;
377 struct zserv *client;
378 struct prefix *p;
379
380 if (IS_ZEBRA_DEBUG_EVENT)
381 {
382 char buf[INET6_ADDRSTRLEN];
383
384 p = ifc->address;
385 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
386 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
387 p->prefixlen, ifc->ifp->name);
388 }
389
390 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
391 if (client->ifinfo)
392 zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc);
393}
394
395/* Add new nbr connected IPv6 address if none exists already, or replace the
396 existing one if an ifc entry is found on the interface. */
397void
398nbr_connected_replacement_add_ipv6 (struct interface *ifp, struct in6_addr *address,
399 u_char prefixlen)
400{
401 struct nbr_connected *ifc;
402 struct prefix p;
403
404 p.family = AF_INET6;
405 IPV6_ADDR_COPY (&p.u.prefix, address);
406 p.prefixlen = prefixlen;
407
408 if (nbr_connected_check(ifp, &p))
409 return;
410
411 if (!(ifc = listnode_head(ifp->nbr_connected)))
412 {
413 /* new addition */
414 ifc = nbr_connected_new ();
415 ifc->address = prefix_new();
416 ifc->ifp = ifp;
417 listnode_add (ifp->nbr_connected, ifc);
418 }
419
420 prefix_copy(ifc->address, &p);
421
422 zebra_interface_nbr_address_add_update (ifp, ifc);
5c610faf
DS
423
424 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 1);
a80beece
DS
425}
426
427void
428nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
429 u_char prefixlen)
430{
431 struct nbr_connected *ifc;
432 struct prefix p;
433
434 p.family = AF_INET6;
435 IPV6_ADDR_COPY (&p.u.prefix, address);
436 p.prefixlen = prefixlen;
437
438 ifc = nbr_connected_check(ifp, &p);
439 if (!ifc)
440 return;
441
442 listnode_delete (ifp->nbr_connected, ifc);
443
444 zebra_interface_nbr_address_delete_update (ifp, ifc);
445
5c610faf
DS
446 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 0);
447
a80beece
DS
448 nbr_connected_free (ifc);
449}
450
b9df2d25 451/*
452 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
453 * ZEBRA_INTERFACE_DOWN.
454 *
455 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
456 * the clients in one of 2 situations:
457 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
458 * - a vty command modifying the bandwidth of an interface is received.
459 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
460 */
718e3744 461int
b9df2d25 462zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
718e3744 463{
464 struct stream *s;
465
466 /* Check this client need interface information. */
7076bb2f 467 if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
719e9741 468 return 0;
718e3744 469
470 s = client->obuf;
471 stream_reset (s);
472
7076bb2f 473 zserv_create_header (s, cmd, ifp->vrf_id);
51d4ef83 474 zserv_encode_interface (s, ifp);
718e3744 475
04b02fda
DS
476 if (cmd == ZEBRA_INTERFACE_UP)
477 client->ifup_cnt++;
478 else
479 client->ifdown_cnt++;
480
719e9741 481 return zebra_server_send_message(client);
718e3744 482}
483
b9df2d25 484/*
5048fe14 485 * This is the new function to announce and withdraw redistributed routes, used
486 * by Zebra. This is the old zsend_route_multipath() function. That function
487 * was duplicating code to send a lot of information that was essentially thrown
488 * away or ignored by the receiver. This is the leaner function that is not a
489 * duplicate of the zapi_ipv4_route_add/del.
b9df2d25 490 *
5048fe14 491 * The primary difference is that this function merely sends a single NH instead of
492 * all the nexthops.
b9df2d25 493 */
718e3744 494int
5048fe14 495zsend_redistribute_route (int cmd, struct zserv *client, struct prefix *p,
496 struct rib *rib)
718e3744 497{
498 int psize;
499 struct stream *s;
500 struct nexthop *nexthop;
1dcb5172 501 unsigned long nhnummark = 0, messmark = 0;
b9df2d25 502 int nhnum = 0;
1dcb5172 503 u_char zapi_flags = 0;
5048fe14 504 struct nexthop dummy_nh;
505
7076bb2f
FL
506 /* Came from VRF lib patch, is this really needed? callers of this routine
507 do check for redist.., so may be its not needed.
508 Check this client need this route.
509 if (!vrf_bitmap_check (client->redist[family2afi(p->family)][rib->type],
510 rib->vrf_id) &&
511 !(is_default (p) &&
512 vrf_bitmap_check (client->redist_default, rib->vrf_id)))
513 return 0;
514 */
515
718e3744 516 s = client->obuf;
517 stream_reset (s);
5048fe14 518 memset(&dummy_nh, 0, sizeof(struct nexthop));
519
7076bb2f
FL
520 zserv_create_header (s, cmd, rib->vrf_id);
521
c1b9800a 522 /* Put type and nexthop. */
718e3744 523 stream_putc (s, rib->type);
7c8ff89e 524 stream_putw (s, rib->instance);
718e3744 525 stream_putc (s, rib->flags);
5048fe14 526
1dcb5172 527 /* marker for message flags field */
528 messmark = stream_get_endp (s);
529 stream_putc (s, 0);
718e3744 530
531 /* Prefix. */
532 psize = PSIZE (p->prefixlen);
533 stream_putc (s, p->prefixlen);
b9df2d25 534 stream_write (s, (u_char *) & p->u.prefix, psize);
535
718e3744 536 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
537 {
5048fe14 538 /* We don't send any nexthops when there's a multipath */
539 if (rib->nexthop_active_num > 1)
540 {
541 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
542 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
543
544 stream_putc(s, 1);
545 if (p->family == AF_INET)
546 {
547 stream_put_in_addr (s, &dummy_nh.gate.ipv4);
548 }
549 else if (p->family == AF_INET6)
550 {
551 stream_write (s, (u_char *) &dummy_nh.gate.ipv6, 16);
552 }
553 else
554 {
555 /* We don't handle anything else now, abort */
556 zlog_err("%s: Unable to redistribute route of unknown family, %d\n",
557 __func__, p->family);
558 return -1;
559 }
560 stream_putc (s, 1);
561 stream_putl (s, 0); /* dummy ifindex */
562 break;
563 }
564
fa713d9e
CF
565 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
566 || nexthop_has_fib_child(nexthop))
b9df2d25 567 {
1dcb5172 568 SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
569 SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
1dcb5172 570 if (nhnummark == 0)
571 {
572 nhnummark = stream_get_endp (s);
573 stream_putc (s, 1); /* placeholder */
574 }
b9df2d25 575 nhnum++;
576
577 switch(nexthop->type)
578 {
579 case NEXTHOP_TYPE_IPV4:
580 case NEXTHOP_TYPE_IPV4_IFINDEX:
581 stream_put_in_addr (s, &nexthop->gate.ipv4);
582 break;
718e3744 583#ifdef HAVE_IPV6
b9df2d25 584 case NEXTHOP_TYPE_IPV6:
585 case NEXTHOP_TYPE_IPV6_IFINDEX:
586 case NEXTHOP_TYPE_IPV6_IFNAME:
5048fe14 587 /* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */
588 if (p->family == AF_INET)
589 stream_put_in_addr(s, &dummy_nh.gate.ipv4);
590 else
591 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
b9df2d25 592 break;
593#endif
594 default:
5048fe14 595 if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD
596 || cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL)
b9df2d25 597 {
598 struct in_addr empty;
44983cf8 599 memset (&empty, 0, sizeof (struct in_addr));
b9df2d25 600 stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
601 }
602 else
603 {
604 struct in6_addr empty;
605 memset (&empty, 0, sizeof (struct in6_addr));
606 stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
607 }
608 }
609
610 /* Interface index. */
611 stream_putc (s, 1);
612 stream_putl (s, nexthop->ifindex);
613
614 break;
615 }
718e3744 616 }
617
618 /* Metric */
5048fe14 619 if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD || cmd == ZEBRA_REDISTRIBUTE_IPV6_ADD)
1dcb5172 620 {
fbf5d033 621 SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
622 stream_putc (s, rib->distance);
1dcb5172 623 SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
624 stream_putl (s, rib->metric);
0d9551dc
DS
625
626 /* tag */
627 if (rib->tag)
628 {
629 SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
630 stream_putw(s, rib->tag);
631 }
1dcb5172 632 }
5048fe14 633
1dcb5172 634 /* write real message flags value */
635 stream_putc_at (s, messmark, zapi_flags);
5048fe14 636
b9df2d25 637 /* Write next-hop number */
638 if (nhnummark)
c1eaa442 639 stream_putc_at (s, nhnummark, nhnum);
5048fe14 640
718e3744 641 /* Write packet size. */
642 stream_putw_at (s, 0, stream_get_endp (s));
643
719e9741 644 return zebra_server_send_message(client);
718e3744 645}
646
b9df2d25 647#ifdef HAVE_IPV6
719e9741 648static int
7076bb2f
FL
649zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
650 vrf_id_t vrf_id)
718e3744 651{
652 struct stream *s;
653 struct rib *rib;
654 unsigned long nump;
655 u_char num;
656 struct nexthop *nexthop;
657
658 /* Lookup nexthop. */
7076bb2f 659 rib = rib_match_ipv6 (addr, vrf_id);
718e3744 660
661 /* Get output stream. */
662 s = client->obuf;
663 stream_reset (s);
664
665 /* Fill in result. */
7076bb2f 666 zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
718e3744 667 stream_put (s, &addr, 16);
668
669 if (rib)
670 {
671 stream_putl (s, rib->metric);
672 num = 0;
9985f83c 673 nump = stream_get_endp(s);
718e3744 674 stream_putc (s, 0);
fa713d9e
CF
675 /* Only non-recursive routes are elegible to resolve nexthop we
676 * are looking up. Therefore, we will just iterate over the top
677 * chain of nexthops. */
718e3744 678 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
679 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
680 {
681 stream_putc (s, nexthop->type);
682 switch (nexthop->type)
683 {
684 case ZEBRA_NEXTHOP_IPV6:
685 stream_put (s, &nexthop->gate.ipv6, 16);
686 break;
687 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
688 case ZEBRA_NEXTHOP_IPV6_IFNAME:
689 stream_put (s, &nexthop->gate.ipv6, 16);
690 stream_putl (s, nexthop->ifindex);
691 break;
692 case ZEBRA_NEXTHOP_IFINDEX:
693 case ZEBRA_NEXTHOP_IFNAME:
694 stream_putl (s, nexthop->ifindex);
695 break;
fa2b17e3 696 default:
697 /* do nothing */
698 break;
718e3744 699 }
700 num++;
701 }
702 stream_putc_at (s, nump, num);
703 }
704 else
705 {
706 stream_putl (s, 0);
707 stream_putc (s, 0);
708 }
709
710 stream_putw_at (s, 0, stream_get_endp (s));
04b02fda 711
719e9741 712 return zebra_server_send_message(client);
718e3744 713}
714#endif /* HAVE_IPV6 */
715
b9df2d25 716static int
7076bb2f
FL
717zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
718 vrf_id_t vrf_id)
718e3744 719{
720 struct stream *s;
721 struct rib *rib;
722 unsigned long nump;
723 u_char num;
724 struct nexthop *nexthop;
725
726 /* Lookup nexthop. */
7076bb2f 727 rib = rib_match_ipv4 (addr, vrf_id);
718e3744 728
729 /* Get output stream. */
730 s = client->obuf;
731 stream_reset (s);
732
733 /* Fill in result. */
7076bb2f 734 zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
718e3744 735 stream_put_in_addr (s, &addr);
736
737 if (rib)
738 {
bb97e462
CF
739 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
740 zlog_debug("%s: Matching rib entry found.", __func__);
718e3744 741 stream_putl (s, rib->metric);
742 num = 0;
9985f83c 743 nump = stream_get_endp(s);
718e3744 744 stream_putc (s, 0);
fa713d9e
CF
745 /* Only non-recursive routes are elegible to resolve the nexthop we
746 * are looking up. Therefore, we will just iterate over the top
747 * chain of nexthops. */
718e3744 748 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
749 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
750 {
751 stream_putc (s, nexthop->type);
752 switch (nexthop->type)
753 {
754 case ZEBRA_NEXTHOP_IPV4:
755 stream_put_in_addr (s, &nexthop->gate.ipv4);
756 break;
bb97e462
CF
757 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
758 stream_put_in_addr (s, &nexthop->gate.ipv4);
759 stream_putl (s, nexthop->ifindex);
760 break;
718e3744 761 case ZEBRA_NEXTHOP_IFINDEX:
762 case ZEBRA_NEXTHOP_IFNAME:
763 stream_putl (s, nexthop->ifindex);
764 break;
fa2b17e3 765 default:
766 /* do nothing */
767 break;
718e3744 768 }
769 num++;
770 }
771 stream_putc_at (s, nump, num);
772 }
773 else
774 {
bb97e462
CF
775 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
776 zlog_debug("%s: No matching rib entry found.", __func__);
718e3744 777 stream_putl (s, 0);
778 stream_putc (s, 0);
779 }
780
781 stream_putw_at (s, 0, stream_get_endp (s));
782
719e9741 783 return zebra_server_send_message(client);
718e3744 784}
785
fb018d25
DS
786/* Nexthop register */
787static int
078430f6 788zserv_rnh_register (struct zserv *client, int sock, u_short length,
7076bb2f 789 rnh_type_t type, vrf_id_t vrf_id)
fb018d25
DS
790{
791 struct rnh *rnh;
792 struct stream *s;
793 struct prefix p;
794 u_short l = 0;
078430f6 795 u_char flags = 0;
fb018d25
DS
796
797 if (IS_ZEBRA_DEBUG_NHT)
078430f6
DS
798 zlog_debug("rnh_register msg from client %s: length=%d, type=%s\n",
799 zebra_route_string(client->proto), length,
800 (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route");
fb018d25
DS
801
802 s = client->ibuf;
803
078430f6
DS
804 client->nh_reg_time = quagga_time(NULL);
805
fb018d25
DS
806 while (l < length)
807 {
078430f6 808 flags = stream_getc(s);
fb018d25
DS
809 p.family = stream_getw(s);
810 p.prefixlen = stream_getc(s);
fc9a856f 811 l += 4;
078430f6
DS
812 if (p.family == AF_INET)
813 {
814 p.u.prefix4.s_addr = stream_get_ipv4(s);
815 l += IPV4_MAX_BYTELEN;
816 }
817 else if (p.family == AF_INET6)
818 {
819 stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
820 l += IPV6_MAX_BYTELEN;
821 }
822 else
823 {
824 zlog_err("rnh_register: Received unknown family type %d\n",
825 p.family);
826 return -1;
827 }
828 rnh = zebra_add_rnh(&p, 0, type);
829 if (type == RNH_NEXTHOP_TYPE)
830 {
831 if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
832 SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
833 else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
834 UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
835 }
836 else if (type == RNH_IMPORT_CHECK_TYPE)
837 {
838 if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
839 SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
840 else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
841 UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
842 }
843
7076bb2f 844 zebra_add_rnh_client(rnh, client, type, vrf_id);
078430f6
DS
845 /* Anything not AF_INET/INET6 has been filtered out above */
846 zebra_evaluate_rnh(0, p.family, 1, type, &p);
fb018d25 847 }
fb018d25
DS
848 return 0;
849}
850
851/* Nexthop register */
852static int
078430f6
DS
853zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
854 rnh_type_t type)
fb018d25
DS
855{
856 struct rnh *rnh;
857 struct stream *s;
858 struct prefix p;
859 u_short l = 0;
860
861 if (IS_ZEBRA_DEBUG_NHT)
078430f6 862 zlog_debug("rnh_unregister msg from client %s: length=%d\n",
fb018d25
DS
863 zebra_route_string(client->proto), length);
864
865 s = client->ibuf;
866
867 while (l < length)
868 {
4e3afb14 869 (void)stream_getc(s); //Connected or not. Not used in this function
fb018d25
DS
870 p.family = stream_getw(s);
871 p.prefixlen = stream_getc(s);
fc9a856f 872 l += 4;
078430f6
DS
873 if (p.family == AF_INET)
874 {
875 p.u.prefix4.s_addr = stream_get_ipv4(s);
876 l += IPV4_MAX_BYTELEN;
877 }
878 else if (p.family == AF_INET6)
879 {
880 stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
881 l += IPV6_MAX_BYTELEN;
882 }
883 else
884 {
885 zlog_err("rnh_register: Received unknown family type %d\n",
886 p.family);
887 return -1;
888 }
889 rnh = zebra_lookup_rnh(&p, 0, type);
fb018d25 890 if (rnh)
04b02fda
DS
891 {
892 client->nh_dereg_time = quagga_time(NULL);
078430f6 893 zebra_remove_rnh_client(rnh, client, type);
04b02fda 894 }
fb018d25
DS
895 }
896 return 0;
897}
898
b9df2d25 899static int
7076bb2f
FL
900zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
901 vrf_id_t vrf_id)
718e3744 902{
903 struct stream *s;
904 struct rib *rib;
905 unsigned long nump;
906 u_char num;
907 struct nexthop *nexthop;
908
909 /* Lookup nexthop. */
7076bb2f 910 rib = rib_lookup_ipv4 (p, vrf_id);
718e3744 911
912 /* Get output stream. */
913 s = client->obuf;
914 stream_reset (s);
915
916 /* Fill in result. */
7076bb2f 917 zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
718e3744 918 stream_put_in_addr (s, &p->prefix);
919
920 if (rib)
921 {
922 stream_putl (s, rib->metric);
923 num = 0;
9985f83c 924 nump = stream_get_endp(s);
718e3744 925 stream_putc (s, 0);
926 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
fa713d9e
CF
927 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
928 || nexthop_has_fib_child(nexthop))
718e3744 929 {
930 stream_putc (s, nexthop->type);
931 switch (nexthop->type)
932 {
933 case ZEBRA_NEXTHOP_IPV4:
934 stream_put_in_addr (s, &nexthop->gate.ipv4);
935 break;
a12afd5e
CF
936 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
937 stream_put_in_addr (s, &nexthop->gate.ipv4);
938 stream_putl (s, nexthop->ifindex);
939 break;
718e3744 940 case ZEBRA_NEXTHOP_IFINDEX:
941 case ZEBRA_NEXTHOP_IFNAME:
942 stream_putl (s, nexthop->ifindex);
943 break;
fa2b17e3 944 default:
945 /* do nothing */
946 break;
718e3744 947 }
948 num++;
949 }
950 stream_putc_at (s, nump, num);
951 }
952 else
953 {
954 stream_putl (s, 0);
955 stream_putc (s, 0);
956 }
957
958 stream_putw_at (s, 0, stream_get_endp (s));
04b02fda 959
719e9741 960 return zebra_server_send_message(client);
718e3744 961}
6b0655a2 962
18a6dce6 963/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
964int
c6ffe645
FL
965zsend_router_id_update (struct zserv *client, struct prefix *p,
966 vrf_id_t vrf_id)
18a6dce6 967{
968 struct stream *s;
969 int blen;
970
971 /* Check this client need interface information. */
7076bb2f 972 if (! vrf_bitmap_check (client->ridinfo, vrf_id))
719e9741 973 return 0;
18a6dce6 974
975 s = client->obuf;
976 stream_reset (s);
977
18a6dce6 978 /* Message type. */
7076bb2f 979 zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
18a6dce6 980
981 /* Prefix information. */
982 stream_putc (s, p->family);
983 blen = prefix_blen (p);
984 stream_put (s, &p->u.prefix, blen);
985 stream_putc (s, p->prefixlen);
986
987 /* Write packet size. */
988 stream_putw_at (s, 0, stream_get_endp (s));
989
719e9741 990 return zebra_server_send_message(client);
18a6dce6 991}
6b0655a2 992
718e3744 993/* Register zebra server interface information. Send current all
994 interface and address information. */
719e9741 995static int
7076bb2f 996zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
718e3744 997{
1eb8ef25 998 struct listnode *ifnode, *ifnnode;
999 struct listnode *cnode, *cnnode;
718e3744 1000 struct interface *ifp;
1001 struct connected *c;
a80beece 1002 struct nbr_connected *nc;
718e3744 1003
1004 /* Interface information is needed. */
7076bb2f 1005 vrf_bitmap_set (client->ifinfo, vrf_id);
718e3744 1006
7076bb2f 1007 for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
718e3744 1008 {
718e3744 1009 /* Skip pseudo interface. */
1010 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1011 continue;
1012
719e9741 1013 if (zsend_interface_add (client, ifp) < 0)
1014 return -1;
718e3744 1015
1eb8ef25 1016 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
718e3744 1017 {
719e9741 1018 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
1019 (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
1020 ifp, c) < 0))
1021 return -1;
718e3744 1022 }
a80beece
DS
1023 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc))
1024 {
1025 if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client,
1026 ifp, nc) < 0)
1027 return -1;
1028 }
1029
718e3744 1030 }
719e9741 1031 return 0;
718e3744 1032}
1033
1034/* Unregister zebra server interface information. */
719e9741 1035static int
7076bb2f 1036zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
718e3744 1037{
7076bb2f 1038 vrf_bitmap_unset (client->ifinfo, vrf_id);
719e9741 1039 return 0;
718e3744 1040}
1041
6878b9db
DS
1042void
1043zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const u_char nexthop_num)
1044{
7c5d2b76 1045 if (nexthop_num > MULTIPATH_NUM)
6878b9db
DS
1046 {
1047 char buff[80];
1048 prefix2str(p, buff, 80);
1049 zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d",
1050 caller, buff, nexthop_num, MULTIPATH_NUM);
1051 }
1052}
1053
718e3744 1054/* This function support multiple nexthop. */
b9df2d25 1055/*
1056 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
1057 * add kernel route.
1058 */
719e9741 1059static int
7076bb2f 1060zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
718e3744 1061{
1062 int i;
1063 struct rib *rib;
1064 struct prefix_ipv4 p;
1065 u_char message;
1066 struct in_addr nexthop;
1067 u_char nexthop_num;
1068 u_char nexthop_type;
1069 struct stream *s;
1070 unsigned int ifindex;
1071 u_char ifname_len;
d44ca835 1072 safi_t safi;
04b02fda 1073 int ret;
718e3744 1074
1075 /* Get input stream. */
1076 s = client->ibuf;
1077
1078 /* Allocate new rib. */
4d38fdb4 1079 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1080
718e3744 1081 /* Type, flags, message. */
1082 rib->type = stream_getc (s);
7c8ff89e 1083 rib->instance = stream_getw (s);
718e3744 1084 rib->flags = stream_getc (s);
b9df2d25 1085 message = stream_getc (s);
cddf391b 1086 safi = stream_getw (s);
718e3744 1087 rib->uptime = time (NULL);
1088
1089 /* IPv4 prefix. */
1090 memset (&p, 0, sizeof (struct prefix_ipv4));
1091 p.family = AF_INET;
1092 p.prefixlen = stream_getc (s);
1093 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1094
78104b9b 1095 /* VRF ID */
7076bb2f 1096 rib->vrf_id = vrf_id;
78104b9b 1097
718e3744 1098 /* Nexthop parse. */
1099 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1100 {
1101 nexthop_num = stream_getc (s);
6878b9db 1102 zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
718e3744 1103
1104 for (i = 0; i < nexthop_num; i++)
1105 {
1106 nexthop_type = stream_getc (s);
1107
1108 switch (nexthop_type)
1109 {
1110 case ZEBRA_NEXTHOP_IFINDEX:
1111 ifindex = stream_getl (s);
1112 nexthop_ifindex_add (rib, ifindex);
1113 break;
1114 case ZEBRA_NEXTHOP_IFNAME:
1115 ifname_len = stream_getc (s);
9985f83c 1116 stream_forward_getp (s, ifname_len);
718e3744 1117 break;
1118 case ZEBRA_NEXTHOP_IPV4:
1119 nexthop.s_addr = stream_get_ipv4 (s);
7514fb77 1120 nexthop_ipv4_add (rib, &nexthop, NULL);
718e3744 1121 break;
c963c203
JT
1122 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
1123 nexthop.s_addr = stream_get_ipv4 (s);
1124 ifindex = stream_getl (s);
1125 nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
1126 break;
718e3744 1127 case ZEBRA_NEXTHOP_IPV6:
9985f83c 1128 stream_forward_getp (s, IPV6_MAX_BYTELEN);
718e3744 1129 break;
6902c69a
SV
1130 case ZEBRA_NEXTHOP_BLACKHOLE:
1131 nexthop_blackhole_add (rib);
1132 break;
1133 }
718e3744 1134 }
1135 }
1136
1137 /* Distance. */
1138 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1139 rib->distance = stream_getc (s);
1140
1141 /* Metric. */
1142 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1143 rib->metric = stream_getl (s);
1144
0d9551dc
DS
1145 /* Tag */
1146 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
1147 rib->tag = stream_getw (s);
1148 else
1149 rib->tag = 0;
1150
171eee31
PJ
1151 /* Table */
1152 rib->table=zebrad.rtm_table_default;
04b02fda
DS
1153 ret = rib_add_ipv4_multipath (&p, rib, safi);
1154
1155 /* Stats */
1156 if (ret > 0)
1157 client->v4_route_add_cnt++;
1158 else if (ret < 0)
1159 client->v4_route_upd8_cnt++;
719e9741 1160 return 0;
718e3744 1161}
1162
1163/* Zebra server IPv4 prefix delete function. */
719e9741 1164static int
7076bb2f 1165zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
718e3744 1166{
1167 int i;
1168 struct stream *s;
1169 struct zapi_ipv4 api;
6902c69a 1170 struct in_addr nexthop, *nexthop_p;
718e3744 1171 unsigned long ifindex;
1172 struct prefix_ipv4 p;
1173 u_char nexthop_num;
1174 u_char nexthop_type;
1175 u_char ifname_len;
1176
1177 s = client->ibuf;
1178 ifindex = 0;
1179 nexthop.s_addr = 0;
6902c69a 1180 nexthop_p = NULL;
718e3744 1181
1182 /* Type, flags, message. */
1183 api.type = stream_getc (s);
7c8ff89e 1184 api.instance = stream_getw (s);
718e3744 1185 api.flags = stream_getc (s);
1186 api.message = stream_getc (s);
cddf391b 1187 api.safi = stream_getw (s);
718e3744 1188
1189 /* IPv4 prefix. */
1190 memset (&p, 0, sizeof (struct prefix_ipv4));
1191 p.family = AF_INET;
1192 p.prefixlen = stream_getc (s);
1193 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1194
1195 /* Nexthop, ifindex, distance, metric. */
1196 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1197 {
1198 nexthop_num = stream_getc (s);
1199
1200 for (i = 0; i < nexthop_num; i++)
1201 {
1202 nexthop_type = stream_getc (s);
1203
1204 switch (nexthop_type)
1205 {
1206 case ZEBRA_NEXTHOP_IFINDEX:
1207 ifindex = stream_getl (s);
1208 break;
1209 case ZEBRA_NEXTHOP_IFNAME:
1210 ifname_len = stream_getc (s);
9985f83c 1211 stream_forward_getp (s, ifname_len);
718e3744 1212 break;
1213 case ZEBRA_NEXTHOP_IPV4:
1214 nexthop.s_addr = stream_get_ipv4 (s);
6902c69a 1215 nexthop_p = &nexthop;
718e3744 1216 break;
c963c203
JT
1217 case ZEBRA_NEXTHOP_IPV4_IFINDEX:
1218 nexthop.s_addr = stream_get_ipv4 (s);
23f5f7c3 1219 nexthop_p = &nexthop;
c963c203
JT
1220 ifindex = stream_getl (s);
1221 break;
718e3744 1222 case ZEBRA_NEXTHOP_IPV6:
9985f83c 1223 stream_forward_getp (s, IPV6_MAX_BYTELEN);
718e3744 1224 break;
1225 }
1226 }
1227 }
1228
1229 /* Distance. */
1230 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1231 api.distance = stream_getc (s);
1232 else
1233 api.distance = 0;
1234
1235 /* Metric. */
1236 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1237 api.metric = stream_getl (s);
1238 else
1239 api.metric = 0;
1240
0d9551dc
DS
1241 /* tag */
1242 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
1243 api.tag = stream_getw (s);
1244 else
1245 api.tag = 0;
1246
7c8ff89e 1247 rib_delete_ipv4 (api.type, api.instance, api.flags, &p, nexthop_p, ifindex,
7076bb2f 1248 vrf_id, client->rtm_table, api.safi);
04b02fda 1249 client->v4_route_del_cnt++;
719e9741 1250 return 0;
718e3744 1251}
1252
1253/* Nexthop lookup for IPv4. */
719e9741 1254static int
7076bb2f
FL
1255zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
1256 vrf_id_t vrf_id)
718e3744 1257{
1258 struct in_addr addr;
bb97e462 1259 char buf[BUFSIZ];
718e3744 1260
1261 addr.s_addr = stream_get_ipv4 (client->ibuf);
bb97e462
CF
1262 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1263 zlog_debug("%s: looking up %s", __func__,
1264 inet_ntop (AF_INET, &addr, buf, BUFSIZ));
7076bb2f 1265 return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
718e3744 1266}
1267
1268/* Nexthop lookup for IPv4. */
719e9741 1269static int
7076bb2f
FL
1270zread_ipv4_import_lookup (struct zserv *client, u_short length,
1271 vrf_id_t vrf_id)
718e3744 1272{
1273 struct prefix_ipv4 p;
1274
1275 p.family = AF_INET;
1276 p.prefixlen = stream_getc (client->ibuf);
1277 p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
1278
7076bb2f 1279 return zsend_ipv4_import_lookup (client, &p, vrf_id);
718e3744 1280}
1281
1282#ifdef HAVE_IPV6
8a92a8a0
DS
1283/* Zebra server IPv6 prefix add function. */
1284static int
1285zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length)
1286{
1287 int i;
1288 struct stream *s;
1289 struct in6_addr nexthop;
1290 struct rib *rib;
1291 u_char message;
1292 u_char nexthop_num;
1293 u_char nexthop_type;
1294 unsigned long ifindex;
1295 struct prefix_ipv4 p;
8a92a8a0
DS
1296 safi_t safi;
1297 static struct in6_addr nexthops[MULTIPATH_NUM];
1298 static unsigned int ifindices[MULTIPATH_NUM];
1299 int ret;
1300
1301 /* Get input stream. */
1302 s = client->ibuf;
1303
1304 ifindex = 0;
1305 memset (&nexthop, 0, sizeof (struct in6_addr));
1306
1307 /* Allocate new rib. */
1308 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1309
1310 /* Type, flags, message. */
1311 rib->type = stream_getc (s);
1312 rib->instance = stream_getw (s);
1313 rib->flags = stream_getc (s);
1314 message = stream_getc (s);
1315 safi = stream_getw (s);
1316 rib->uptime = time (NULL);
1317
1318 /* IPv4 prefix. */
1319 memset (&p, 0, sizeof (struct prefix_ipv4));
1320 p.family = AF_INET;
1321 p.prefixlen = stream_getc (s);
1322 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1323
1324 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1325 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1326 * these. Clients should send the same number of paired set of
1327 * next-hop-addr/next-hop-ifindices. */
1328 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
1329 {
1330 int nh_count = 0;
1331 int if_count = 0;
1332 int max_nh_if = 0;
1333
1334 nexthop_num = stream_getc (s);
6878b9db 1335 zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
8a92a8a0
DS
1336 for (i = 0; i < nexthop_num; i++)
1337 {
1338 nexthop_type = stream_getc (s);
1339
1340 switch (nexthop_type)
1341 {
1342 case ZEBRA_NEXTHOP_IPV6:
1343 stream_get (&nexthop, s, 16);
1344 if (nh_count < MULTIPATH_NUM) {
1345 nexthops[nh_count++] = nexthop;
1346 }
1347 break;
1348 case ZEBRA_NEXTHOP_IFINDEX:
1349 if (if_count < MULTIPATH_NUM) {
1350 ifindices[if_count++] = stream_getl (s);
1351 }
1352 break;
1353 case ZEBRA_NEXTHOP_BLACKHOLE:
1354 nexthop_blackhole_add (rib);
1355 break;
1356 }
1357 }
1358
1359 max_nh_if = (nh_count > if_count) ? nh_count : if_count;
1360 for (i = 0; i < max_nh_if; i++)
1361 {
1362 if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
1363 if ((i < if_count) && ifindices[i]) {
1364 nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
1365 }
1366 else {
1367 nexthop_ipv6_add (rib, &nexthops[i]);
1368 }
1369 }
1370 else {
1371 if ((i < if_count) && ifindices[i]) {
1372 nexthop_ifindex_add (rib, ifindices[i]);
1373 }
1374 }
1375 }
1376 }
1377
1378 /* Distance. */
1379 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1380 rib->distance = stream_getc (s);
1381
1382 /* Metric. */
1383 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1384 rib->metric = stream_getl (s);
1385
1386 /* Tag */
1387 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
1388 rib->tag = stream_getw (s);
1389 else
1390 rib->tag = 0;
1391
1392 /* Table */
1393 rib->table=zebrad.rtm_table_default;
1394 ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
1395 /* Stats */
1396 if (ret > 0)
1397 client->v4_route_add_cnt++;
1398 else if (ret < 0)
1399 client->v4_route_upd8_cnt++;
1400
1401 return 0;
1402}
1403
719e9741 1404static int
7076bb2f 1405zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
718e3744 1406{
1407 int i;
1408 struct stream *s;
718e3744 1409 struct in6_addr nexthop;
41fc2714
DS
1410 struct rib *rib;
1411 u_char message;
1412 u_char nexthop_num;
1413 u_char nexthop_type;
718e3744 1414 unsigned long ifindex;
1415 struct prefix_ipv6 p;
41fc2714
DS
1416 safi_t safi;
1417 static struct in6_addr nexthops[MULTIPATH_NUM];
1418 static unsigned int ifindices[MULTIPATH_NUM];
04b02fda 1419 int ret;
41fc2714
DS
1420
1421 /* Get input stream. */
718e3744 1422 s = client->ibuf;
41fc2714 1423
718e3744 1424 ifindex = 0;
1425 memset (&nexthop, 0, sizeof (struct in6_addr));
1426
41fc2714
DS
1427 /* Allocate new rib. */
1428 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
1429
718e3744 1430 /* Type, flags, message. */
41fc2714 1431 rib->type = stream_getc (s);
7c8ff89e 1432 rib->instance = stream_getw (s);
41fc2714
DS
1433 rib->flags = stream_getc (s);
1434 message = stream_getc (s);
1435 safi = stream_getw (s);
1436 rib->uptime = time (NULL);
718e3744 1437
41fc2714 1438 /* IPv6 prefix. */
718e3744 1439 memset (&p, 0, sizeof (struct prefix_ipv6));
1440 p.family = AF_INET6;
1441 p.prefixlen = stream_getc (s);
1442 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1443
41fc2714
DS
1444 /* We need to give nh-addr, nh-ifindex with the same next-hop object
1445 * to the rib to ensure that IPv6 multipathing works; need to coalesce
1446 * these. Clients should send the same number of paired set of
1447 * next-hop-addr/next-hop-ifindices. */
1448 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
718e3744 1449 {
41fc2714
DS
1450 int nh_count = 0;
1451 int if_count = 0;
1452 int max_nh_if = 0;
718e3744 1453
41fc2714 1454 nexthop_num = stream_getc (s);
6878b9db
DS
1455 zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
1456 for (i = 0; i < nexthop_num; i++)
718e3744 1457 {
1458 nexthop_type = stream_getc (s);
1459
1460 switch (nexthop_type)
1461 {
1462 case ZEBRA_NEXTHOP_IPV6:
1463 stream_get (&nexthop, s, 16);
41fc2714
DS
1464 if (nh_count < MULTIPATH_NUM) {
1465 nexthops[nh_count++] = nexthop;
1466 }
718e3744 1467 break;
1468 case ZEBRA_NEXTHOP_IFINDEX:
41fc2714
DS
1469 if (if_count < MULTIPATH_NUM) {
1470 ifindices[if_count++] = stream_getl (s);
1471 }
718e3744 1472 break;
c3c0ac83
DS
1473 case ZEBRA_NEXTHOP_BLACKHOLE:
1474 nexthop_blackhole_add (rib);
1475 break;
718e3744 1476 }
1477 }
41fc2714
DS
1478
1479 max_nh_if = (nh_count > if_count) ? nh_count : if_count;
1480 for (i = 0; i < max_nh_if; i++)
1481 {
1482 if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
6f20b80d 1483 if ((i < if_count) && ifindices[i])
41fc2714 1484 nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
6f20b80d 1485 else
41fc2714 1486 nexthop_ipv6_add (rib, &nexthops[i]);
41fc2714
DS
1487 }
1488 else {
6f20b80d 1489 if ((i < if_count) && ifindices[i])
41fc2714 1490 nexthop_ifindex_add (rib, ifindices[i]);
41fc2714
DS
1491 }
1492 }
718e3744 1493 }
1494
41fc2714
DS
1495 /* Distance. */
1496 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
1497 rib->distance = stream_getc (s);
718e3744 1498
41fc2714
DS
1499 /* Metric. */
1500 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
1501 rib->metric = stream_getl (s);
718e3744 1502
0d9551dc
DS
1503 /* Tag */
1504 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
1505 rib->tag = stream_getw (s);
1506 else
1507 rib->tag = 0;
1508
41fc2714
DS
1509 /* Table */
1510 rib->table=zebrad.rtm_table_default;
7076bb2f 1511 rib->vrf_id = vrf_id;
8a92a8a0 1512 ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
04b02fda
DS
1513 /* Stats */
1514 if (ret > 0)
1515 client->v6_route_add_cnt++;
1516 else if (ret < 0)
1517 client->v6_route_upd8_cnt++;
1518
719e9741 1519 return 0;
718e3744 1520}
1521
1522/* Zebra server IPv6 prefix delete function. */
719e9741 1523static int
7076bb2f 1524zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
718e3744 1525{
1526 int i;
1527 struct stream *s;
1528 struct zapi_ipv6 api;
1529 struct in6_addr nexthop;
1530 unsigned long ifindex;
1531 struct prefix_ipv6 p;
1532
1533 s = client->ibuf;
1534 ifindex = 0;
1535 memset (&nexthop, 0, sizeof (struct in6_addr));
1536
1537 /* Type, flags, message. */
1538 api.type = stream_getc (s);
7c8ff89e 1539 api.instance = stream_getw (s);
718e3744 1540 api.flags = stream_getc (s);
1541 api.message = stream_getc (s);
f768f367 1542 api.safi = stream_getw (s);
718e3744 1543
1544 /* IPv4 prefix. */
1545 memset (&p, 0, sizeof (struct prefix_ipv6));
1546 p.family = AF_INET6;
1547 p.prefixlen = stream_getc (s);
1548 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1549
1550 /* Nexthop, ifindex, distance, metric. */
1551 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1552 {
1553 u_char nexthop_type;
1554
1555 api.nexthop_num = stream_getc (s);
1556 for (i = 0; i < api.nexthop_num; i++)
1557 {
1558 nexthop_type = stream_getc (s);
1559
1560 switch (nexthop_type)
1561 {
1562 case ZEBRA_NEXTHOP_IPV6:
1563 stream_get (&nexthop, s, 16);
1564 break;
1565 case ZEBRA_NEXTHOP_IFINDEX:
1566 ifindex = stream_getl (s);
1567 break;
1568 }
1569 }
1570 }
1571
0d9551dc 1572 /* Distance. */
718e3744 1573 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1574 api.distance = stream_getc (s);
1575 else
1576 api.distance = 0;
0d9551dc
DS
1577
1578 /* Metric. */
718e3744 1579 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1580 api.metric = stream_getl (s);
1581 else
1582 api.metric = 0;
1583
0d9551dc
DS
1584 /* tag */
1585 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
1586 api.tag = stream_getw (s);
1587 else
1588 api.tag = 0;
1589
718e3744 1590 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
78104b9b 1591 rib_delete_ipv6 (api.type, api.instance, api.flags, &p, NULL, ifindex,
7076bb2f 1592 vrf_id, client->rtm_table, api.safi);
718e3744 1593 else
78104b9b 1594 rib_delete_ipv6 (api.type, api.instance, api.flags, &p, &nexthop, ifindex,
7076bb2f 1595 vrf_id, client->rtm_table, api.safi);
04b02fda
DS
1596
1597 client->v6_route_del_cnt++;
719e9741 1598 return 0;
718e3744 1599}
1600
719e9741 1601static int
7076bb2f
FL
1602zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
1603 vrf_id_t vrf_id)
718e3744 1604{
1605 struct in6_addr addr;
1606 char buf[BUFSIZ];
1607
1608 stream_get (&addr, client->ibuf, 16);
a5207089
CF
1609 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1610 zlog_debug("%s: looking up %s", __func__,
1611 inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
718e3744 1612
7076bb2f 1613 return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
718e3744 1614}
1615#endif /* HAVE_IPV6 */
1616
18a6dce6 1617/* Register zebra server router-id information. Send current router-id */
719e9741 1618static int
7076bb2f 1619zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
18a6dce6 1620{
1621 struct prefix p;
1622
1623 /* Router-id information is needed. */
7076bb2f 1624 vrf_bitmap_set (client->ridinfo, vrf_id);
18a6dce6 1625
7076bb2f 1626 router_id_get (&p, vrf_id);
18a6dce6 1627
7076bb2f 1628 return zsend_router_id_update (client, &p, vrf_id);
18a6dce6 1629}
1630
1631/* Unregister zebra server router-id information. */
719e9741 1632static int
7076bb2f 1633zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
18a6dce6 1634{
7076bb2f 1635 vrf_bitmap_unset (client->ridinfo, vrf_id);
719e9741 1636 return 0;
18a6dce6 1637}
1638
2ea1ab1c
VT
1639/* Tie up route-type and client->sock */
1640static void
1641zread_hello (struct zserv *client)
1642{
1643 /* type of protocol (lib/zebra.h) */
1644 u_char proto;
7c8ff89e
DS
1645 u_short instance;
1646
2ea1ab1c 1647 proto = stream_getc (client->ibuf);
7c8ff89e 1648 instance = stream_getw (client->ibuf);
2ea1ab1c
VT
1649
1650 /* accept only dynamic routing protocols */
1651 if ((proto < ZEBRA_ROUTE_MAX)
1652 && (proto > ZEBRA_ROUTE_STATIC))
1653 {
1654 zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1655 client->sock, zebra_route_string(proto));
7c8ff89e
DS
1656 if (instance)
1657 zlog_notice ("client protocol instance %d", instance);
2ea1ab1c 1658
fb018d25 1659 client->proto = proto;
7c8ff89e 1660 client->instance = instance;
2ea1ab1c
VT
1661 }
1662}
1663
7076bb2f
FL
1664/* Unregister all information in a VRF. */
1665static int
1666zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
1667{
1668 int i;
1669 afi_t afi;
1670
1671 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1672 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1673 vrf_bitmap_unset (client->redist[afi][i], vrf_id);
1674 vrf_bitmap_unset (client->redist_default, vrf_id);
1675 vrf_bitmap_unset (client->ifinfo, vrf_id);
1676 vrf_bitmap_unset (client->ridinfo, vrf_id);
1677
1678 return 0;
1679}
1680
718e3744 1681/* Close zebra client. */
b9df2d25 1682static void
718e3744 1683zebra_client_close (struct zserv *client)
1684{
078430f6
DS
1685 zebra_cleanup_rnh_client(0, AF_INET, client, RNH_NEXTHOP_TYPE);
1686 zebra_cleanup_rnh_client(0, AF_INET6, client, RNH_NEXTHOP_TYPE);
1687 zebra_cleanup_rnh_client(0, AF_INET, client, RNH_IMPORT_CHECK_TYPE);
1688 zebra_cleanup_rnh_client(0, AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
fb018d25 1689
718e3744 1690 /* Close file descriptor. */
1691 if (client->sock)
1692 {
7c8ff89e
DS
1693 unsigned long nroutes;
1694
718e3744 1695 close (client->sock);
7c8ff89e
DS
1696 nroutes = rib_score_proto (client->proto, client->instance);
1697 zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1698 client->sock, nroutes, zebra_route_string (client->proto));
718e3744 1699 client->sock = -1;
1700 }
1701
1702 /* Free stream buffers. */
1703 if (client->ibuf)
1704 stream_free (client->ibuf);
1705 if (client->obuf)
1706 stream_free (client->obuf);
719e9741 1707 if (client->wb)
1708 buffer_free(client->wb);
718e3744 1709
1710 /* Release threads. */
1711 if (client->t_read)
1712 thread_cancel (client->t_read);
1713 if (client->t_write)
1714 thread_cancel (client->t_write);
719e9741 1715 if (client->t_suicide)
1716 thread_cancel (client->t_suicide);
718e3744 1717
1718 /* Free client structure. */
b21b19c5 1719 listnode_delete (zebrad.client_list, client);
718e3744 1720 XFREE (0, client);
1721}
1722
1723/* Make new client. */
b9df2d25 1724static void
718e3744 1725zebra_client_create (int sock)
1726{
1727 struct zserv *client;
7076bb2f
FL
1728 int i;
1729 afi_t afi;
718e3744 1730
1731 client = XCALLOC (0, sizeof (struct zserv));
1732
1733 /* Make client input/output buffer. */
1734 client->sock = sock;
1735 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1736 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
719e9741 1737 client->wb = buffer_new(0);
718e3744 1738
1739 /* Set table number. */
b21b19c5 1740 client->rtm_table = zebrad.rtm_table_default;
718e3744 1741
04b02fda 1742 client->connect_time = quagga_time(NULL);
7076bb2f
FL
1743 /* Initialize flags */
1744 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1745 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1746 client->redist[afi][i] = vrf_bitmap_init ();
1747 client->redist_default = vrf_bitmap_init ();
1748 client->ifinfo = vrf_bitmap_init ();
1749 client->ridinfo = vrf_bitmap_init ();
04b02fda 1750
718e3744 1751 /* Add this client to linked list. */
b21b19c5 1752 listnode_add (zebrad.client_list, client);
718e3744 1753
1754 /* Make new read thread. */
1755 zebra_event (ZEBRA_READ, sock, client);
1756}
1757
1758/* Handler of zebra service request. */
b9df2d25 1759static int
718e3744 1760zebra_client_read (struct thread *thread)
1761{
1762 int sock;
1763 struct zserv *client;
57a1477b 1764 size_t already;
c1b9800a 1765 uint16_t length, command;
1766 uint8_t marker, version;
7076bb2f 1767 vrf_id_t vrf_id;
718e3744 1768
1769 /* Get thread data. Reset reading thread because I'm running. */
1770 sock = THREAD_FD (thread);
1771 client = THREAD_ARG (thread);
1772 client->t_read = NULL;
1773
719e9741 1774 if (client->t_suicide)
718e3744 1775 {
719e9741 1776 zebra_client_close(client);
718e3744 1777 return -1;
1778 }
719e9741 1779
1780 /* Read length and command (if we don't have it already). */
57a1477b 1781 if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
719e9741 1782 {
57a1477b 1783 ssize_t nbyte;
719e9741 1784 if (((nbyte = stream_read_try (client->ibuf, sock,
57a1477b 1785 ZEBRA_HEADER_SIZE-already)) == 0) ||
719e9741 1786 (nbyte == -1))
1787 {
1788 if (IS_ZEBRA_DEBUG_EVENT)
1789 zlog_debug ("connection closed socket [%d]", sock);
1790 zebra_client_close (client);
1791 return -1;
1792 }
57a1477b 1793 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
719e9741 1794 {
1795 /* Try again later. */
1796 zebra_event (ZEBRA_READ, sock, client);
1797 return 0;
1798 }
57a1477b 1799 already = ZEBRA_HEADER_SIZE;
719e9741 1800 }
1801
1802 /* Reset to read from the beginning of the incoming packet. */
1803 stream_set_getp(client->ibuf, 0);
1804
c1b9800a 1805 /* Fetch header values */
718e3744 1806 length = stream_getw (client->ibuf);
c1b9800a 1807 marker = stream_getc (client->ibuf);
1808 version = stream_getc (client->ibuf);
7076bb2f 1809 vrf_id = stream_getw (client->ibuf);
c1b9800a 1810 command = stream_getw (client->ibuf);
718e3744 1811
c1b9800a 1812 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1813 {
1814 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1815 __func__, sock, marker, version);
1816 zebra_client_close (client);
1817 return -1;
1818 }
719e9741 1819 if (length < ZEBRA_HEADER_SIZE)
718e3744 1820 {
57a1477b 1821 zlog_warn("%s: socket %d message length %u is less than header size %d",
1822 __func__, sock, length, ZEBRA_HEADER_SIZE);
1823 zebra_client_close (client);
1824 return -1;
1825 }
1826 if (length > STREAM_SIZE(client->ibuf))
1827 {
1828 zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1829 __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
718e3744 1830 zebra_client_close (client);
1831 return -1;
1832 }
1833
718e3744 1834 /* Read rest of data. */
57a1477b 1835 if (already < length)
718e3744 1836 {
57a1477b 1837 ssize_t nbyte;
1838 if (((nbyte = stream_read_try (client->ibuf, sock,
1839 length-already)) == 0) ||
1840 (nbyte == -1))
718e3744 1841 {
1842 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 1843 zlog_debug ("connection closed [%d] when reading zebra data", sock);
718e3744 1844 zebra_client_close (client);
1845 return -1;
1846 }
57a1477b 1847 if (nbyte != (ssize_t)(length-already))
719e9741 1848 {
1849 /* Try again later. */
1850 zebra_event (ZEBRA_READ, sock, client);
1851 return 0;
1852 }
718e3744 1853 }
1854
719e9741 1855 length -= ZEBRA_HEADER_SIZE;
1856
718e3744 1857 /* Debug packet information. */
1858 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 1859 zlog_debug ("zebra message comes from socket [%d]", sock);
718e3744 1860
1861 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
7076bb2f
FL
1862 zlog_debug ("zebra message received [%s] %d in VRF %u",
1863 zserv_command_string (command), length, vrf_id);
718e3744 1864
04b02fda
DS
1865 client->last_read_time = quagga_time(NULL);
1866 client->last_read_cmd = command;
1867
718e3744 1868 switch (command)
1869 {
18a6dce6 1870 case ZEBRA_ROUTER_ID_ADD:
7076bb2f 1871 zread_router_id_add (client, length, vrf_id);
18a6dce6 1872 break;
1873 case ZEBRA_ROUTER_ID_DELETE:
7076bb2f 1874 zread_router_id_delete (client, length, vrf_id);
18a6dce6 1875 break;
718e3744 1876 case ZEBRA_INTERFACE_ADD:
7076bb2f 1877 zread_interface_add (client, length, vrf_id);
718e3744 1878 break;
1879 case ZEBRA_INTERFACE_DELETE:
7076bb2f 1880 zread_interface_delete (client, length, vrf_id);
718e3744 1881 break;
1882 case ZEBRA_IPV4_ROUTE_ADD:
7076bb2f 1883 zread_ipv4_add (client, length, vrf_id);
718e3744 1884 break;
1885 case ZEBRA_IPV4_ROUTE_DELETE:
7076bb2f 1886 zread_ipv4_delete (client, length, vrf_id);
718e3744 1887 break;
1888#ifdef HAVE_IPV6
8a92a8a0
DS
1889 case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD:
1890 zread_ipv4_route_ipv6_nexthop_add (client, length);
1891 break;
718e3744 1892 case ZEBRA_IPV6_ROUTE_ADD:
7076bb2f 1893 zread_ipv6_add (client, length, vrf_id);
718e3744 1894 break;
1895 case ZEBRA_IPV6_ROUTE_DELETE:
7076bb2f 1896 zread_ipv6_delete (client, length, vrf_id);
718e3744 1897 break;
1898#endif /* HAVE_IPV6 */
1899 case ZEBRA_REDISTRIBUTE_ADD:
7076bb2f 1900 zebra_redistribute_add (command, client, length, vrf_id);
718e3744 1901 break;
1902 case ZEBRA_REDISTRIBUTE_DELETE:
7076bb2f 1903 zebra_redistribute_delete (command, client, length, vrf_id);
718e3744 1904 break;
1905 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
7076bb2f 1906 zebra_redistribute_default_add (command, client, length, vrf_id);
718e3744 1907 break;
1908 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
7076bb2f 1909 zebra_redistribute_default_delete (command, client, length, vrf_id);
718e3744 1910 break;
1911 case ZEBRA_IPV4_NEXTHOP_LOOKUP:
7076bb2f 1912 zread_ipv4_nexthop_lookup (client, length, vrf_id);
718e3744 1913 break;
1914#ifdef HAVE_IPV6
1915 case ZEBRA_IPV6_NEXTHOP_LOOKUP:
7076bb2f 1916 zread_ipv6_nexthop_lookup (client, length, vrf_id);
718e3744 1917 break;
1918#endif /* HAVE_IPV6 */
1919 case ZEBRA_IPV4_IMPORT_LOOKUP:
7076bb2f 1920 zread_ipv4_import_lookup (client, length, vrf_id);
718e3744 1921 break;
2ea1ab1c
VT
1922 case ZEBRA_HELLO:
1923 zread_hello (client);
1924 break;
fb018d25 1925 case ZEBRA_NEXTHOP_REGISTER:
7076bb2f 1926 zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, vrf_id);
fb018d25
DS
1927 break;
1928 case ZEBRA_NEXTHOP_UNREGISTER:
078430f6
DS
1929 zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE);
1930 break;
1931 case ZEBRA_IMPORT_ROUTE_REGISTER:
7076bb2f 1932 zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, vrf_id);
078430f6
DS
1933 break;
1934 case ZEBRA_IMPORT_ROUTE_UNREGISTER:
1935 zserv_rnh_unregister(client, sock, length, RNH_IMPORT_CHECK_TYPE);
fb018d25 1936 break;
c43ed2e4
DS
1937 case ZEBRA_BFD_DEST_UPDATE:
1938 case ZEBRA_BFD_DEST_REGISTER:
1939 zebra_ptm_bfd_dst_register(client, sock, length, command);
1940 break;
1941 case ZEBRA_BFD_DEST_DEREGISTER:
1942 zebra_ptm_bfd_dst_deregister(client, sock, length);
1943 break;
7076bb2f
FL
1944 case ZEBRA_VRF_UNREGISTER:
1945 zread_vrf_unregister (client, length, vrf_id);
1946 break;
718e3744 1947 default:
1948 zlog_info ("Zebra received unknown command %d", command);
1949 break;
1950 }
1951
719e9741 1952 if (client->t_suicide)
1953 {
1954 /* No need to wait for thread callback, just kill immediately. */
1955 zebra_client_close(client);
1956 return -1;
1957 }
1958
718e3744 1959 stream_reset (client->ibuf);
1960 zebra_event (ZEBRA_READ, sock, client);
718e3744 1961 return 0;
1962}
1963
718e3744 1964
1965/* Accept code of zebra server socket. */
b9df2d25 1966static int
718e3744 1967zebra_accept (struct thread *thread)
1968{
1969 int accept_sock;
1970 int client_sock;
1971 struct sockaddr_in client;
1972 socklen_t len;
1973
1974 accept_sock = THREAD_FD (thread);
1975
719e9741 1976 /* Reregister myself. */
1977 zebra_event (ZEBRA_SERV, accept_sock, NULL);
1978
718e3744 1979 len = sizeof (struct sockaddr_in);
1980 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1981
1982 if (client_sock < 0)
1983 {
6099b3b5 1984 zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
718e3744 1985 return -1;
1986 }
1987
ccf3557b 1988 /* Make client socket non-blocking. */
719e9741 1989 set_nonblocking(client_sock);
865b852c 1990
718e3744 1991 /* Create new zebra client. */
1992 zebra_client_create (client_sock);
1993
718e3744 1994 return 0;
1995}
1996
b9df2d25 1997#ifdef HAVE_TCP_ZEBRA
718e3744 1998/* Make zebra's server socket. */
b9df2d25 1999static void
718e3744 2000zebra_serv ()
2001{
2002 int ret;
2003 int accept_sock;
2004 struct sockaddr_in addr;
2005
2006 accept_sock = socket (AF_INET, SOCK_STREAM, 0);
2007
2008 if (accept_sock < 0)
2009 {
3d1dc857 2010 zlog_warn ("Can't create zserv stream socket: %s",
2011 safe_strerror (errno));
718e3744 2012 zlog_warn ("zebra can't provice full functionality due to above error");
2013 return;
2014 }
2015
2016 memset (&addr, 0, sizeof (struct sockaddr_in));
2017 addr.sin_family = AF_INET;
2018 addr.sin_port = htons (ZEBRA_PORT);
6f0e3f6e 2019#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
718e3744 2020 addr.sin_len = sizeof (struct sockaddr_in);
6f0e3f6e 2021#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 2022 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
2023
2024 sockopt_reuseaddr (accept_sock);
2025 sockopt_reuseport (accept_sock);
2026
edd7c245 2027 if ( zserv_privs.change(ZPRIVS_RAISE) )
2028 zlog (NULL, LOG_ERR, "Can't raise privileges");
2029
718e3744 2030 ret = bind (accept_sock, (struct sockaddr *)&addr,
2031 sizeof (struct sockaddr_in));
2032 if (ret < 0)
2033 {
3d1dc857 2034 zlog_warn ("Can't bind to stream socket: %s",
2035 safe_strerror (errno));
718e3744 2036 zlog_warn ("zebra can't provice full functionality due to above error");
2037 close (accept_sock); /* Avoid sd leak. */
2038 return;
2039 }
edd7c245 2040
2041 if ( zserv_privs.change(ZPRIVS_LOWER) )
2042 zlog (NULL, LOG_ERR, "Can't lower privileges");
718e3744 2043
2044 ret = listen (accept_sock, 1);
2045 if (ret < 0)
2046 {
3d1dc857 2047 zlog_warn ("Can't listen to stream socket: %s",
2048 safe_strerror (errno));
718e3744 2049 zlog_warn ("zebra can't provice full functionality due to above error");
2050 close (accept_sock); /* Avoid sd leak. */
2051 return;
2052 }
2053
2054 zebra_event (ZEBRA_SERV, accept_sock, NULL);
2055}
b9df2d25 2056#endif /* HAVE_TCP_ZEBRA */
718e3744 2057
2058/* For sockaddr_un. */
2059#include <sys/un.h>
2060
2061/* zebra server UNIX domain socket. */
b9df2d25 2062static void
fce954f8 2063zebra_serv_un (const char *path)
718e3744 2064{
2065 int ret;
2066 int sock, len;
2067 struct sockaddr_un serv;
2068 mode_t old_mask;
2069
2070 /* First of all, unlink existing socket */
2071 unlink (path);
2072
2073 /* Set umask */
2074 old_mask = umask (0077);
2075
2076 /* Make UNIX domain socket. */
2077 sock = socket (AF_UNIX, SOCK_STREAM, 0);
2078 if (sock < 0)
2079 {
3d1dc857 2080 zlog_warn ("Can't create zserv unix socket: %s",
2081 safe_strerror (errno));
2082 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 2083 return;
2084 }
2085
2086 /* Make server socket. */
2087 memset (&serv, 0, sizeof (struct sockaddr_un));
2088 serv.sun_family = AF_UNIX;
2089 strncpy (serv.sun_path, path, strlen (path));
6f0e3f6e 2090#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
718e3744 2091 len = serv.sun_len = SUN_LEN(&serv);
2092#else
2093 len = sizeof (serv.sun_family) + strlen (serv.sun_path);
6f0e3f6e 2094#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
718e3744 2095
2096 ret = bind (sock, (struct sockaddr *) &serv, len);
2097 if (ret < 0)
2098 {
3d1dc857 2099 zlog_warn ("Can't bind to unix socket %s: %s",
2100 path, safe_strerror (errno));
2101 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 2102 close (sock);
2103 return;
2104 }
2105
2106 ret = listen (sock, 5);
2107 if (ret < 0)
2108 {
3d1dc857 2109 zlog_warn ("Can't listen to unix socket %s: %s",
2110 path, safe_strerror (errno));
2111 zlog_warn ("zebra can't provide full functionality due to above error");
718e3744 2112 close (sock);
2113 return;
2114 }
2115
2116 umask (old_mask);
2117
2118 zebra_event (ZEBRA_SERV, sock, NULL);
2119}
6b0655a2 2120
718e3744 2121
b9df2d25 2122static void
718e3744 2123zebra_event (enum event event, int sock, struct zserv *client)
2124{
2125 switch (event)
2126 {
2127 case ZEBRA_SERV:
b21b19c5 2128 thread_add_read (zebrad.master, zebra_accept, client, sock);
718e3744 2129 break;
2130 case ZEBRA_READ:
2131 client->t_read =
b21b19c5 2132 thread_add_read (zebrad.master, zebra_client_read, client, sock);
718e3744 2133 break;
2134 case ZEBRA_WRITE:
2135 /**/
2136 break;
2137 }
2138}
6b0655a2 2139
04b02fda
DS
2140#define ZEBRA_TIME_BUF 32
2141static char *
2142zserv_time_buf(time_t *time1, char *buf, int buflen)
2143{
2144 struct tm *tm;
2145 time_t now;
2146
2147 assert (buf != NULL);
2148 assert (buflen >= ZEBRA_TIME_BUF);
2149 assert (time1 != NULL);
2150
2151 if (!*time1)
2152 {
2153 snprintf(buf, buflen, "never ");
2154 return (buf);
2155 }
2156
2157 now = quagga_time(NULL);
2158 now -= *time1;
2159 tm = gmtime(&now);
2160
2161 /* Making formatted timer strings. */
2162#define ONE_DAY_SECOND 60*60*24
2163#define ONE_WEEK_SECOND 60*60*24*7
2164
2165 if (now < ONE_DAY_SECOND)
2166 snprintf (buf, buflen, "%02d:%02d:%02d",
2167 tm->tm_hour, tm->tm_min, tm->tm_sec);
2168 else if (now < ONE_WEEK_SECOND)
2169 snprintf (buf, buflen, "%dd%02dh%02dm",
2170 tm->tm_yday, tm->tm_hour, tm->tm_min);
2171 else
2172 snprintf (buf, buflen, "%02dw%dd%02dh",
2173 tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
2174 return buf;
2175}
2176
2177static void
2178zebra_show_client_detail (struct vty *vty, struct zserv *client)
2179{
2180 char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
2181 char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF];
2182
7c8ff89e
DS
2183 vty_out (vty, "Client: %s", zebra_route_string(client->proto));
2184 if (client->instance)
2185 vty_out (vty, " Instance: %d", client->instance);
2186 vty_out (vty, "%s", VTY_NEWLINE);
2187
04b02fda
DS
2188 vty_out (vty, "------------------------ %s", VTY_NEWLINE);
2189 vty_out (vty, "FD: %d %s", client->sock, VTY_NEWLINE);
2190 vty_out (vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE);
2191
2192 vty_out (vty, "Connect Time: %s %s",
2193 zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF),
2194 VTY_NEWLINE);
2195 if (client->nh_reg_time)
2196 {
2197 vty_out (vty, "Nexthop Registry Time: %s %s",
2198 zserv_time_buf(&client->nh_reg_time, nhbuf, ZEBRA_TIME_BUF),
2199 VTY_NEWLINE);
2200 if (client->nh_last_upd_time)
2201 vty_out (vty, "Nexthop Last Update Time: %s %s",
2202 zserv_time_buf(&client->nh_last_upd_time, mbuf, ZEBRA_TIME_BUF),
2203 VTY_NEWLINE);
2204 else
2205 vty_out (vty, "No Nexthop Update sent%s", VTY_NEWLINE);
2206 }
2207 else
2208 vty_out (vty, "Not registered for Nexthop Updates%s", VTY_NEWLINE);
2209
2210 vty_out (vty, "Last Msg Rx Time: %s %s",
2211 zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF),
2212 VTY_NEWLINE);
2213 vty_out (vty, "Last Msg Tx Time: %s %s",
2214 zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF),
2215 VTY_NEWLINE);
2216 if (client->last_read_time)
2217 vty_out (vty, "Last Rcvd Cmd: %s %s",
2218 zserv_command_string(client->last_read_cmd), VTY_NEWLINE);
2219 if (client->last_write_time)
2220 vty_out (vty, "Last Sent Cmd: %s %s",
2221 zserv_command_string(client->last_write_cmd), VTY_NEWLINE);
2222 vty_out (vty, "%s", VTY_NEWLINE);
2223
2224 vty_out (vty, "Type Add Update Del %s", VTY_NEWLINE);
2225 vty_out (vty, "================================================== %s", VTY_NEWLINE);
2226 vty_out (vty, "IPv4 %-12d%-12d%-12d%s", client->v4_route_add_cnt,
2227 client->v4_route_upd8_cnt, client->v4_route_del_cnt, VTY_NEWLINE);
2228 vty_out (vty, "IPv6 %-12d%-12d%-12d%s", client->v6_route_add_cnt,
2229 client->v6_route_upd8_cnt, client->v6_route_del_cnt, VTY_NEWLINE);
2230 vty_out (vty, "Redist:v4 %-12d%-12d%-12d%s", client->redist_v4_add_cnt, 0,
2231 client->redist_v4_del_cnt, VTY_NEWLINE);
2232 vty_out (vty, "Redist:v6 %-12d%-12d%-12d%s", client->redist_v6_add_cnt, 0,
2233 client->redist_v6_del_cnt, VTY_NEWLINE);
2234 vty_out (vty, "Connected %-12d%-12d%-12d%s", client->ifadd_cnt, 0,
2235 client->ifdel_cnt, VTY_NEWLINE);
c43ed2e4
DS
2236 vty_out (vty, "BFD peer %-12d%-12d%-12d%s", client->bfd_peer_add_cnt,
2237 client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt, VTY_NEWLINE);
04b02fda
DS
2238 vty_out (vty, "Interface Up Notifications: %d%s", client->ifup_cnt,
2239 VTY_NEWLINE);
2240 vty_out (vty, "Interface Down Notifications: %d%s", client->ifdown_cnt,
2241 VTY_NEWLINE);
2242
2243 vty_out (vty, "%s", VTY_NEWLINE);
2244 return;
2245}
2246
2247static void
2248zebra_show_client_brief (struct vty *vty, struct zserv *client)
2249{
2250 char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
2251 char wbuf[ZEBRA_TIME_BUF];
2252
2253 vty_out (vty, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d%s",
2254 zebra_route_string(client->proto),
2255 zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF),
2256 zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF),
2257 zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF),
2258 client->v4_route_add_cnt+client->v4_route_upd8_cnt,
2259 client->v4_route_del_cnt,
2260 client->v6_route_add_cnt+client->v6_route_upd8_cnt,
2261 client->v6_route_del_cnt, VTY_NEWLINE);
2262
2263}
2264
2265
718e3744 2266/* Display default rtm_table for all clients. */
2267DEFUN (show_table,
2268 show_table_cmd,
2269 "show table",
2270 SHOW_STR
2271 "default routing table to use for all clients\n")
2272{
b21b19c5 2273 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
718e3744 2274 VTY_NEWLINE);
2275 return CMD_SUCCESS;
2276}
2277
2278DEFUN (config_table,
2279 config_table_cmd,
2280 "table TABLENO",
2281 "Configure target kernel routing table\n"
2282 "TABLE integer\n")
2283{
b21b19c5 2284 zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
718e3744 2285 return CMD_SUCCESS;
2286}
2287
647e4f1f 2288DEFUN (ip_forwarding,
2289 ip_forwarding_cmd,
2290 "ip forwarding",
2291 IP_STR
2292 "Turn on IP forwarding")
2293{
2294 int ret;
2295
2296 ret = ipforward ();
b71f00f2 2297 if (ret == 0)
2298 ret = ipforward_on ();
647e4f1f 2299
647e4f1f 2300 if (ret == 0)
2301 {
2302 vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
2303 return CMD_WARNING;
2304 }
2305
2306 return CMD_SUCCESS;
2307}
2308
718e3744 2309DEFUN (no_ip_forwarding,
2310 no_ip_forwarding_cmd,
2311 "no ip forwarding",
2312 NO_STR
2313 IP_STR
2314 "Turn off IP forwarding")
2315{
2316 int ret;
2317
2318 ret = ipforward ();
b71f00f2 2319 if (ret != 0)
2320 ret = ipforward_off ();
718e3744 2321
718e3744 2322 if (ret != 0)
2323 {
2324 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
2325 return CMD_WARNING;
2326 }
2327
2328 return CMD_SUCCESS;
2329}
2330
2331/* This command is for debugging purpose. */
2332DEFUN (show_zebra_client,
2333 show_zebra_client_cmd,
2334 "show zebra client",
2335 SHOW_STR
2336 "Zebra information"
2337 "Client information")
2338{
52dc7ee6 2339 struct listnode *node;
718e3744 2340 struct zserv *client;
2341
1eb8ef25 2342 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
04b02fda
DS
2343 zebra_show_client_detail(vty, client);
2344
2345 return CMD_SUCCESS;
2346}
2347
2348/* This command is for debugging purpose. */
2349DEFUN (show_zebra_client_summary,
2350 show_zebra_client_summary_cmd,
2351 "show zebra client summary",
2352 SHOW_STR
2353 "Zebra information brief"
2354 "Client information brief")
2355{
2356 struct listnode *node;
2357 struct zserv *client;
2358
2359 vty_out (vty, "Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes %s",
2360 VTY_NEWLINE);
2361 vty_out (vty,"--------------------------------------------------------------------------------%s",
2362 VTY_NEWLINE);
2363
2364 for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
2365 zebra_show_client_brief(vty, client);
fb018d25 2366
04b02fda 2367 vty_out (vty, "Routes column shows (added+updated)/deleted%s", VTY_NEWLINE);
718e3744 2368 return CMD_SUCCESS;
2369}
2370
2371/* Table configuration write function. */
b9df2d25 2372static int
718e3744 2373config_write_table (struct vty *vty)
2374{
b21b19c5 2375 if (zebrad.rtm_table_default)
2376 vty_out (vty, "table %d%s", zebrad.rtm_table_default,
718e3744 2377 VTY_NEWLINE);
2378 return 0;
2379}
2380
2381/* table node for routing tables. */
7fc626de 2382static struct cmd_node table_node =
718e3744 2383{
2384 TABLE_NODE,
2385 "", /* This node has no interface. */
2386 1
2387};
6b0655a2 2388
718e3744 2389/* Only display ip forwarding is enabled or not. */
2390DEFUN (show_ip_forwarding,
2391 show_ip_forwarding_cmd,
2392 "show ip forwarding",
2393 SHOW_STR
2394 IP_STR
2395 "IP forwarding status\n")
2396{
2397 int ret;
2398
2399 ret = ipforward ();
2400
2401 if (ret == 0)
2402 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
2403 else
2404 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
2405 return CMD_SUCCESS;
2406}
2407
2408#ifdef HAVE_IPV6
2409/* Only display ipv6 forwarding is enabled or not. */
2410DEFUN (show_ipv6_forwarding,
2411 show_ipv6_forwarding_cmd,
2412 "show ipv6 forwarding",
2413 SHOW_STR
2414 "IPv6 information\n"
2415 "Forwarding status\n")
2416{
2417 int ret;
2418
2419 ret = ipforward_ipv6 ();
2420
2421 switch (ret)
2422 {
2423 case -1:
2424 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
2425 break;
2426 case 0:
2427 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
2428 break;
2429 case 1:
2430 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
2431 break;
2432 default:
2433 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
2434 break;
2435 }
2436 return CMD_SUCCESS;
2437}
2438
55906724 2439DEFUN (ipv6_forwarding,
2440 ipv6_forwarding_cmd,
2441 "ipv6 forwarding",
2442 IPV6_STR
2443 "Turn on IPv6 forwarding")
2444{
2445 int ret;
2446
41d3fc96 2447 ret = ipforward_ipv6 ();
b71f00f2 2448 if (ret == 0)
2449 ret = ipforward_ipv6_on ();
41d3fc96 2450
41d3fc96 2451 if (ret == 0)
55906724 2452 {
2453 vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
2454 return CMD_WARNING;
2455 }
2456
2457 return CMD_SUCCESS;
2458}
2459
718e3744 2460DEFUN (no_ipv6_forwarding,
2461 no_ipv6_forwarding_cmd,
2462 "no ipv6 forwarding",
2463 NO_STR
55906724 2464 IPV6_STR
2465 "Turn off IPv6 forwarding")
718e3744 2466{
2467 int ret;
2468
41d3fc96 2469 ret = ipforward_ipv6 ();
b71f00f2 2470 if (ret != 0)
2471 ret = ipforward_ipv6_off ();
41d3fc96 2472
718e3744 2473 if (ret != 0)
2474 {
2475 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
2476 return CMD_WARNING;
2477 }
2478
2479 return CMD_SUCCESS;
2480}
2481
2482#endif /* HAVE_IPV6 */
2483
2484/* IPForwarding configuration write function. */
719e9741 2485static int
718e3744 2486config_write_forwarding (struct vty *vty)
2487{
18a6dce6 2488 /* FIXME: Find better place for that. */
2489 router_id_write (vty);
2490
3e0b3a56 2491 if (ipforward ())
2492 vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
718e3744 2493#ifdef HAVE_IPV6
3e0b3a56 2494 if (ipforward_ipv6 ())
2495 vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
718e3744 2496#endif /* HAVE_IPV6 */
2497 vty_out (vty, "!%s", VTY_NEWLINE);
2498 return 0;
2499}
2500
2501/* table node for routing tables. */
7fc626de 2502static struct cmd_node forwarding_node =
718e3744 2503{
2504 FORWARDING_NODE,
2505 "", /* This node has no interface. */
2506 1
2507};
2508
6b0655a2 2509
718e3744 2510/* Initialisation of zebra and installation of commands. */
2511void
a1ac18c4 2512zebra_init (void)
718e3744 2513{
2514 /* Client list init. */
b21b19c5 2515 zebrad.client_list = list_new ();
718e3744 2516
718e3744 2517 /* Install configuration write function. */
2518 install_node (&table_node, config_write_table);
2519 install_node (&forwarding_node, config_write_forwarding);
2520
2521 install_element (VIEW_NODE, &show_ip_forwarding_cmd);
2522 install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
647e4f1f 2523 install_element (CONFIG_NODE, &ip_forwarding_cmd);
718e3744 2524 install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
2525 install_element (ENABLE_NODE, &show_zebra_client_cmd);
04b02fda 2526 install_element (ENABLE_NODE, &show_zebra_client_summary_cmd);
718e3744 2527
2528#ifdef HAVE_NETLINK
2529 install_element (VIEW_NODE, &show_table_cmd);
2530 install_element (ENABLE_NODE, &show_table_cmd);
2531 install_element (CONFIG_NODE, &config_table_cmd);
2532#endif /* HAVE_NETLINK */
2533
2534#ifdef HAVE_IPV6
2535 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
2536 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
55906724 2537 install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
718e3744 2538 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
2539#endif /* HAVE_IPV6 */
7514fb77
PJ
2540
2541 /* Route-map */
2542 zebra_route_map_init ();
718e3744 2543}
97be79f9
DO
2544
2545/* Make zebra server socket, wiping any existing one (see bug #403). */
2546void
b5114685 2547zebra_zserv_socket_init (char *path)
97be79f9
DO
2548{
2549#ifdef HAVE_TCP_ZEBRA
2550 zebra_serv ();
2551#else
b5114685 2552 zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
97be79f9
DO
2553#endif /* HAVE_TCP_ZEBRA */
2554}