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