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