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