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