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