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