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