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