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