]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zapi_msg.c
Merge pull request #4075 from qlyoung/reduce-exported-vars
[mirror_frr.git] / zebra / zapi_msg.c
CommitLineData
bf094f69 1/*
d8647095 2 * Zebra API message creation & consumption.
bf094f69
QY
3 * Portions:
4 * Copyright (C) 1997-1999 Kunihiro Ishiguro
5 * Copyright (C) 2015-2018 Cumulus Networks, Inc.
6 * et al.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <zebra.h>
24#include <libgen.h>
25
26#include "lib/prefix.h"
27#include "lib/command.h"
28#include "lib/if.h"
29#include "lib/thread.h"
30#include "lib/stream.h"
31#include "lib/memory.h"
32#include "lib/table.h"
33#include "lib/network.h"
34#include "lib/sockunion.h"
35#include "lib/log.h"
36#include "lib/zclient.h"
37#include "lib/privs.h"
38#include "lib/network.h"
39#include "lib/buffer.h"
40#include "lib/nexthop.h"
41#include "lib/vrf.h"
42#include "lib/libfrr.h"
43#include "lib/sockopt.h"
44
161e9ab7 45#include "zebra/zebra_router.h"
bf094f69
QY
46#include "zebra/rib.h"
47#include "zebra/zebra_memory.h"
48#include "zebra/zebra_ns.h"
49#include "zebra/zebra_vrf.h"
50#include "zebra/router-id.h"
51#include "zebra/redistribute.h"
52#include "zebra/debug.h"
53#include "zebra/zebra_rnh.h"
54#include "zebra/rt_netlink.h"
55#include "zebra/interface.h"
56#include "zebra/zebra_ptm.h"
57#include "zebra/rtadv.h"
58#include "zebra/zebra_mpls.h"
59#include "zebra/zebra_mroute.h"
60#include "zebra/label_manager.h"
61#include "zebra/zebra_vxlan.h"
62#include "zebra/rt.h"
63#include "zebra/zebra_pbr.h"
64#include "zebra/table_manager.h"
65#include "zebra/zapi_msg.h"
364fed6b 66#include "zebra/zebra_errors.h"
02c0866d 67#include "zebra/zebra_mlag.h"
bf094f69
QY
68
69/* Encoding helpers -------------------------------------------------------- */
70
71static void zserv_encode_interface(struct stream *s, struct interface *ifp)
72{
73 /* Interface information. */
74 stream_put(s, ifp->name, INTERFACE_NAMSIZ);
75 stream_putl(s, ifp->ifindex);
76 stream_putc(s, ifp->status);
77 stream_putq(s, ifp->flags);
78 stream_putc(s, ifp->ptm_enable);
79 stream_putc(s, ifp->ptm_status);
80 stream_putl(s, ifp->metric);
81 stream_putl(s, ifp->speed);
82 stream_putl(s, ifp->mtu);
83 stream_putl(s, ifp->mtu6);
84 stream_putl(s, ifp->bandwidth);
85 stream_putl(s, ifp->ll_type);
86 stream_putl(s, ifp->hw_addr_len);
87 if (ifp->hw_addr_len)
88 stream_put(s, ifp->hw_addr, ifp->hw_addr_len);
89
90 /* Then, Traffic Engineering parameters if any */
91 if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params)) {
92 stream_putc(s, 1);
93 zebra_interface_link_params_write(s, ifp);
94 } else
95 stream_putc(s, 0);
96
97 /* Write packet size. */
98 stream_putw_at(s, 0, stream_get_endp(s));
99}
100
101static void zserv_encode_vrf(struct stream *s, struct zebra_vrf *zvrf)
102{
103 struct vrf_data data;
104 const char *netns_name = zvrf_ns_name(zvrf);
105
106 data.l.table_id = zvrf->table_id;
107
108 if (netns_name)
109 strlcpy(data.l.netns_name, basename((char *)netns_name),
110 NS_NAMSIZ);
111 else
112 memset(data.l.netns_name, 0, NS_NAMSIZ);
113 /* Pass the tableid and the netns NAME */
114 stream_put(s, &data, sizeof(struct vrf_data));
115 /* Interface information. */
116 stream_put(s, zvrf_name(zvrf), VRF_NAMSIZ);
117 /* Write packet size. */
118 stream_putw_at(s, 0, stream_get_endp(s));
119}
120
121static int zserv_encode_nexthop(struct stream *s, struct nexthop *nexthop)
122{
a756969d 123 stream_putl(s, nexthop->vrf_id);
bf094f69
QY
124 stream_putc(s, nexthop->type);
125 switch (nexthop->type) {
126 case NEXTHOP_TYPE_IPV4:
127 case NEXTHOP_TYPE_IPV4_IFINDEX:
128 stream_put_in_addr(s, &nexthop->gate.ipv4);
129 stream_putl(s, nexthop->ifindex);
130 break;
131 case NEXTHOP_TYPE_IPV6:
132 stream_put(s, &nexthop->gate.ipv6, 16);
133 break;
134 case NEXTHOP_TYPE_IPV6_IFINDEX:
135 stream_put(s, &nexthop->gate.ipv6, 16);
136 stream_putl(s, nexthop->ifindex);
137 break;
138 case NEXTHOP_TYPE_IFINDEX:
139 stream_putl(s, nexthop->ifindex);
140 break;
141 default:
142 /* do nothing */
143 break;
144 }
145 return 1;
146}
147
148/* Send handlers ----------------------------------------------------------- */
149
150/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
151/*
152 * This function is called in the following situations:
153 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
154 * from the client.
155 * - at startup, when zebra figures out the available interfaces
156 * - when an interface is added (where support for
157 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
158 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
159 * received)
160 */
161int zsend_interface_add(struct zserv *client, struct interface *ifp)
162{
163 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
164
165 zclient_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
166 zserv_encode_interface(s, ifp);
167
168 client->ifadd_cnt++;
21ccc0cf 169 return zserv_send_message(client, s);
bf094f69
QY
170}
171
172/* Interface deletion from zebra daemon. */
173int zsend_interface_delete(struct zserv *client, struct interface *ifp)
174{
175 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
176
177 zclient_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
178 zserv_encode_interface(s, ifp);
179
180 client->ifdel_cnt++;
21ccc0cf 181 return zserv_send_message(client, s);
bf094f69
QY
182}
183
184int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf)
185{
186 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
187
188 zclient_create_header(s, ZEBRA_VRF_ADD, zvrf_id(zvrf));
189 zserv_encode_vrf(s, zvrf);
190
191 client->vrfadd_cnt++;
21ccc0cf 192 return zserv_send_message(client, s);
bf094f69
QY
193}
194
195/* VRF deletion from zebra daemon. */
196int zsend_vrf_delete(struct zserv *client, struct zebra_vrf *zvrf)
197
198{
199 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
200
201 zclient_create_header(s, ZEBRA_VRF_DELETE, zvrf_id(zvrf));
202 zserv_encode_vrf(s, zvrf);
203
204 client->vrfdel_cnt++;
21ccc0cf 205 return zserv_send_message(client, s);
bf094f69
QY
206}
207
208int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
209{
210 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
211
bf094f69
QY
212 if (!ifp->link_params) {
213 stream_free(s);
214 return 0;
215 }
216
217 zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id);
218
219 /* Add Interface Index */
220 stream_putl(s, ifp->ifindex);
221
222 /* Then TE Link Parameters */
223 if (zebra_interface_link_params_write(s, ifp) == 0) {
224 stream_free(s);
225 return 0;
226 }
227
228 /* Write packet size. */
229 stream_putw_at(s, 0, stream_get_endp(s));
230
21ccc0cf 231 return zserv_send_message(client, s);
bf094f69
QY
232}
233
234/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
235 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
236 *
237 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
238 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
239 * from the client, after the ZEBRA_INTERFACE_ADD has been
240 * sent from zebra to the client
241 * - redistribute new address info to all clients in the following situations
242 * - at startup, when zebra figures out the available interfaces
243 * - when an interface is added (where support for
244 * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
245 * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
246 * received)
b1bd1015 247 * - for the vty commands "ip address A.B.C.D/M [<label LINE>]"
bf094f69
QY
248 * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
249 * - when an RTM_NEWADDR message is received from the kernel,
250 *
251 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
252 *
253 * zsend_interface_address(DELETE)
254 * ^
255 * |
256 * zebra_interface_address_delete_update
257 * ^ ^ ^
258 * | | if_delete_update
259 * | |
260 * ip_address_uninstall connected_delete_ipv4
261 * [ipv6_addresss_uninstall] [connected_delete_ipv6]
262 * ^ ^
263 * | |
264 * | RTM_NEWADDR on routing/netlink socket
265 * |
266 * vty commands:
267 * "no ip address A.B.C.D/M [label LINE]"
b1bd1015 268 * "no ip address A.B.C.D/M"
bf094f69
QY
269 * ["no ipv6 address X:X::X:X/M"]
270 *
271 */
272int zsend_interface_address(int cmd, struct zserv *client,
273 struct interface *ifp, struct connected *ifc)
274{
275 int blen;
276 struct prefix *p;
277 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
278
279 zclient_create_header(s, cmd, ifp->vrf_id);
280 stream_putl(s, ifp->ifindex);
281
282 /* Interface address flag. */
283 stream_putc(s, ifc->flags);
284
285 /* Prefix information. */
286 p = ifc->address;
287 stream_putc(s, p->family);
288 blen = prefix_blen(p);
289 stream_put(s, &p->u.prefix, blen);
290
291 /*
292 * XXX gnu version does not send prefixlen for
293 * ZEBRA_INTERFACE_ADDRESS_DELETE
294 * but zebra_interface_address_delete_read() in the gnu version
295 * expects to find it
296 */
297 stream_putc(s, p->prefixlen);
298
299 /* Destination. */
300 p = ifc->destination;
301 if (p)
302 stream_put(s, &p->u.prefix, blen);
303 else
304 stream_put(s, NULL, blen);
305
306 /* Write packet size. */
307 stream_putw_at(s, 0, stream_get_endp(s));
308
309 client->connected_rt_add_cnt++;
21ccc0cf 310 return zserv_send_message(client, s);
bf094f69
QY
311}
312
313static int zsend_interface_nbr_address(int cmd, struct zserv *client,
314 struct interface *ifp,
315 struct nbr_connected *ifc)
316{
317 int blen;
318 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
319 struct prefix *p;
320
321 zclient_create_header(s, cmd, ifp->vrf_id);
322 stream_putl(s, ifp->ifindex);
323
324 /* Prefix information. */
325 p = ifc->address;
326 stream_putc(s, p->family);
327 blen = prefix_blen(p);
328 stream_put(s, &p->u.prefix, blen);
329
330 /*
331 * XXX gnu version does not send prefixlen for
332 * ZEBRA_INTERFACE_ADDRESS_DELETE
333 * but zebra_interface_address_delete_read() in the gnu version
334 * expects to find it
335 */
336 stream_putc(s, p->prefixlen);
337
338 /* Write packet size. */
339 stream_putw_at(s, 0, stream_get_endp(s));
340
21ccc0cf 341 return zserv_send_message(client, s);
bf094f69
QY
342}
343
344/* Interface address addition. */
345static void zebra_interface_nbr_address_add_update(struct interface *ifp,
346 struct nbr_connected *ifc)
347{
348 struct listnode *node, *nnode;
349 struct zserv *client;
350 struct prefix *p;
351
352 if (IS_ZEBRA_DEBUG_EVENT) {
353 char buf[INET6_ADDRSTRLEN];
354
355 p = ifc->address;
356 zlog_debug(
357 "MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
358 inet_ntop(p->family, &p->u.prefix, buf,
359 INET6_ADDRSTRLEN),
360 p->prefixlen, ifc->ifp->name);
361 }
362
161e9ab7 363 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
bf094f69
QY
364 zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
365 client, ifp, ifc);
366}
367
368/* Interface address deletion. */
369static void zebra_interface_nbr_address_delete_update(struct interface *ifp,
370 struct nbr_connected *ifc)
371{
372 struct listnode *node, *nnode;
373 struct zserv *client;
374 struct prefix *p;
375
376 if (IS_ZEBRA_DEBUG_EVENT) {
377 char buf[INET6_ADDRSTRLEN];
378
379 p = ifc->address;
380 zlog_debug(
381 "MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
382 inet_ntop(p->family, &p->u.prefix, buf,
383 INET6_ADDRSTRLEN),
384 p->prefixlen, ifc->ifp->name);
385 }
386
161e9ab7 387 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
bf094f69
QY
388 zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
389 client, ifp, ifc);
390}
391
392/* Send addresses on interface to client */
393int zsend_interface_addresses(struct zserv *client, struct interface *ifp)
394{
395 struct listnode *cnode, *cnnode;
396 struct connected *c;
397 struct nbr_connected *nc;
398
399 /* Send interface addresses. */
400 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
401 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
402 continue;
403
404 if (zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD, client,
405 ifp, c)
406 < 0)
407 return -1;
408 }
409
410 /* Send interface neighbors. */
411 for (ALL_LIST_ELEMENTS(ifp->nbr_connected, cnode, cnnode, nc)) {
412 if (zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
413 client, ifp, nc)
414 < 0)
415 return -1;
416 }
417
418 return 0;
419}
420
421/* Notify client about interface moving from one VRF to another.
422 * Whether client is interested in old and new VRF is checked by caller.
423 */
424int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp,
425 vrf_id_t vrf_id)
426{
427 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
428
429 zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
430
91d227b7
RW
431 /* Fill in the name of the interface and its new VRF (id) */
432 stream_put(s, ifp->name, INTERFACE_NAMSIZ);
bf094f69
QY
433 stream_putl(s, vrf_id);
434
435 /* Write packet size. */
436 stream_putw_at(s, 0, stream_get_endp(s));
437
438 client->if_vrfchg_cnt++;
21ccc0cf 439 return zserv_send_message(client, s);
bf094f69
QY
440}
441
442/* Add new nbr connected IPv6 address */
443void nbr_connected_add_ipv6(struct interface *ifp, struct in6_addr *address)
444{
445 struct nbr_connected *ifc;
446 struct prefix p;
447
448 p.family = AF_INET6;
a85297a7 449 IPV6_ADDR_COPY(&p.u.prefix6, address);
bf094f69
QY
450 p.prefixlen = IPV6_MAX_PREFIXLEN;
451
8b1766b1
QY
452 ifc = listnode_head(ifp->nbr_connected);
453 if (!ifc) {
bf094f69
QY
454 /* new addition */
455 ifc = nbr_connected_new();
456 ifc->address = prefix_new();
457 ifc->ifp = ifp;
458 listnode_add(ifp->nbr_connected, ifc);
459 }
460
461 prefix_copy(ifc->address, &p);
462
463 zebra_interface_nbr_address_add_update(ifp, ifc);
464
465 if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, address, 1);
466}
467
468void nbr_connected_delete_ipv6(struct interface *ifp, struct in6_addr *address)
469{
470 struct nbr_connected *ifc;
471 struct prefix p;
472
473 p.family = AF_INET6;
a85297a7 474 IPV6_ADDR_COPY(&p.u.prefix6, address);
bf094f69
QY
475 p.prefixlen = IPV6_MAX_PREFIXLEN;
476
477 ifc = nbr_connected_check(ifp, &p);
478 if (!ifc)
479 return;
480
481 listnode_delete(ifp->nbr_connected, ifc);
482
483 zebra_interface_nbr_address_delete_update(ifp, ifc);
484
485 if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, address, 0);
486
487 nbr_connected_free(ifc);
488}
489
490/*
491 * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
492 * ZEBRA_INTERFACE_DOWN.
493 *
494 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
495 * the clients in one of 2 situations:
496 * - an if_up is detected e.g., as a result of an RTM_IFINFO message
497 * - a vty command modifying the bandwidth of an interface is received.
498 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
499 */
500int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp)
501{
502 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
503
504 zclient_create_header(s, cmd, ifp->vrf_id);
505 zserv_encode_interface(s, ifp);
506
507 if (cmd == ZEBRA_INTERFACE_UP)
508 client->ifup_cnt++;
509 else
510 client->ifdown_cnt++;
511
21ccc0cf 512 return zserv_send_message(client, s);
bf094f69
QY
513}
514
86391e56
MS
515int zsend_redistribute_route(int cmd, struct zserv *client,
516 const struct prefix *p,
517 const struct prefix *src_p, struct route_entry *re)
bf094f69
QY
518{
519 struct zapi_route api;
520 struct zapi_nexthop *api_nh;
521 struct nexthop *nexthop;
522 int count = 0;
34fa0870 523 afi_t afi;
bf094f69
QY
524
525 memset(&api, 0, sizeof(api));
526 api.vrf_id = re->vrf_id;
527 api.type = re->type;
e4081c0e 528 api.safi = SAFI_UNICAST;
bf094f69
QY
529 api.instance = re->instance;
530 api.flags = re->flags;
531
34fa0870
DS
532 afi = family2afi(p->family);
533 switch (afi) {
534 case AFI_IP:
535 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
536 client->redist_v4_add_cnt++;
537 else
538 client->redist_v4_del_cnt++;
539 break;
540 case AFI_IP6:
541 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
542 client->redist_v6_add_cnt++;
543 else
544 client->redist_v6_del_cnt++;
545 break;
546 default:
547 break;
548 }
549
bf094f69
QY
550 /* Prefix. */
551 api.prefix = *p;
552 if (src_p) {
553 SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
554 memcpy(&api.src_prefix, src_p, sizeof(api.src_prefix));
555 }
556
557 /* Nexthops. */
558 if (re->nexthop_active_num) {
559 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
560 api.nexthop_num = re->nexthop_active_num;
561 }
562 for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) {
563 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
564 continue;
565
566 api_nh = &api.nexthops[count];
567 api_nh->vrf_id = nexthop->vrf_id;
568 api_nh->type = nexthop->type;
569 switch (nexthop->type) {
570 case NEXTHOP_TYPE_BLACKHOLE:
571 api_nh->bh_type = nexthop->bh_type;
572 break;
573 case NEXTHOP_TYPE_IPV4:
574 api_nh->gate.ipv4 = nexthop->gate.ipv4;
575 break;
576 case NEXTHOP_TYPE_IPV4_IFINDEX:
577 api_nh->gate.ipv4 = nexthop->gate.ipv4;
578 api_nh->ifindex = nexthop->ifindex;
579 break;
580 case NEXTHOP_TYPE_IFINDEX:
581 api_nh->ifindex = nexthop->ifindex;
582 break;
583 case NEXTHOP_TYPE_IPV6:
584 api_nh->gate.ipv6 = nexthop->gate.ipv6;
585 break;
586 case NEXTHOP_TYPE_IPV6_IFINDEX:
587 api_nh->gate.ipv6 = nexthop->gate.ipv6;
588 api_nh->ifindex = nexthop->ifindex;
589 }
590 count++;
591 }
592
593 /* Attributes. */
594 SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
595 api.distance = re->distance;
596 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
597 api.metric = re->metric;
598 if (re->tag) {
599 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
600 api.tag = re->tag;
601 }
602 SET_FLAG(api.message, ZAPI_MESSAGE_MTU);
603 api.mtu = re->mtu;
604
605 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
606
607 /* Encode route and send. */
608 if (zapi_route_encode(cmd, s, &api) < 0) {
609 stream_free(s);
610 return -1;
611 }
612
613 if (IS_ZEBRA_DEBUG_SEND) {
614 char buf_prefix[PREFIX_STRLEN];
8b1766b1 615
bf094f69
QY
616 prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
617
618 zlog_debug("%s: %s to client %s: type %s, vrf_id %d, p %s",
619 __func__, zserv_command_string(cmd),
620 zebra_route_string(client->proto),
621 zebra_route_string(api.type), api.vrf_id,
622 buf_prefix);
623 }
21ccc0cf 624 return zserv_send_message(client, s);
bf094f69
QY
625}
626
627/*
628 * Modified version of zsend_ipv4_nexthop_lookup(): Query unicast rib if
629 * nexthop is not found on mrib. Returns both route metric and protocol
630 * distance.
631 */
632static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
633 struct in_addr addr,
634 struct route_entry *re,
635 struct zebra_vrf *zvrf)
636{
637 struct stream *s;
638 unsigned long nump;
639 uint8_t num;
640 struct nexthop *nexthop;
641
642 /* Get output stream. */
643 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
644 stream_reset(s);
645
646 /* Fill in result. */
647 zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf));
648 stream_put_in_addr(s, &addr);
649
650 if (re) {
651 stream_putc(s, re->distance);
652 stream_putl(s, re->metric);
653 num = 0;
8b1766b1
QY
654 /* remember position for nexthop_num */
655 nump = stream_get_endp(s);
656 /* reserve room for nexthop_num */
657 stream_putc(s, 0);
658 /*
659 * Only non-recursive routes are elegible to resolve the
660 * nexthop we are looking up. Therefore, we will just iterate
661 * over the top chain of nexthops.
662 */
bf094f69
QY
663 for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
664 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
665 num += zserv_encode_nexthop(s, nexthop);
666
8b1766b1
QY
667 /* store nexthop_num */
668 stream_putc_at(s, nump, num);
bf094f69
QY
669 } else {
670 stream_putc(s, 0); /* distance */
671 stream_putl(s, 0); /* metric */
672 stream_putc(s, 0); /* nexthop_num */
673 }
674
675 stream_putw_at(s, 0, stream_get_endp(s));
676
21ccc0cf 677 return zserv_send_message(client, s);
bf094f69
QY
678}
679
86391e56
MS
680/*
681 * Common utility send route notification, called from a path using a
682 * route_entry and from a path using a dataplane context.
683 */
684static int route_notify_internal(const struct prefix *p, int type,
685 uint16_t instance, vrf_id_t vrf_id,
686 uint32_t table_id,
687 enum zapi_route_notify_owner note)
bf094f69
QY
688{
689 struct zserv *client;
690 struct stream *s;
691 uint8_t blen;
692
86391e56 693 client = zserv_find_client(type, instance);
bf094f69
QY
694 if (!client || !client->notify_owner) {
695 if (IS_ZEBRA_DEBUG_PACKET) {
696 char buff[PREFIX_STRLEN];
697
698 zlog_debug(
699 "Not Notifying Owner: %u about prefix %s(%u) %d vrf: %u",
86391e56
MS
700 type, prefix2str(p, buff, sizeof(buff)),
701 table_id, note, vrf_id);
bf094f69
QY
702 }
703 return 0;
704 }
705
706 if (IS_ZEBRA_DEBUG_PACKET) {
707 char buff[PREFIX_STRLEN];
708
709 zlog_debug("Notifying Owner: %u about prefix %s(%u) %d vrf: %u",
86391e56
MS
710 type, prefix2str(p, buff, sizeof(buff)),
711 table_id, note, vrf_id);
bf094f69
QY
712 }
713
714 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
715 stream_reset(s);
716
86391e56 717 zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id);
bf094f69
QY
718
719 stream_put(s, &note, sizeof(note));
720
721 stream_putc(s, p->family);
722
723 blen = prefix_blen(p);
724 stream_putc(s, p->prefixlen);
725 stream_put(s, &p->u.prefix, blen);
726
86391e56 727 stream_putl(s, table_id);
bf094f69
QY
728
729 stream_putw_at(s, 0, stream_get_endp(s));
730
21ccc0cf 731 return zserv_send_message(client, s);
bf094f69
QY
732}
733
86391e56
MS
734int zsend_route_notify_owner(struct route_entry *re, const struct prefix *p,
735 enum zapi_route_notify_owner note)
736{
737 return (route_notify_internal(p, re->type, re->instance, re->vrf_id,
738 re->table, note));
739}
740
7cdb1a84
MS
741/*
742 * Route-owner notification using info from dataplane update context.
743 */
25779064 744int zsend_route_notify_owner_ctx(const struct zebra_dplane_ctx *ctx,
7cdb1a84
MS
745 enum zapi_route_notify_owner note)
746{
747 return (route_notify_internal(dplane_ctx_get_dest(ctx),
748 dplane_ctx_get_type(ctx),
749 dplane_ctx_get_instance(ctx),
750 dplane_ctx_get_vrf(ctx),
751 dplane_ctx_get_table(ctx),
752 note));
86391e56
MS
753}
754
bf094f69
QY
755void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
756 enum zapi_rule_notify_owner note)
757{
758 struct listnode *node;
759 struct zserv *client;
760 struct stream *s;
761
762 if (IS_ZEBRA_DEBUG_PACKET)
763 zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
764 rule->rule.unique);
765
161e9ab7 766 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
bf094f69
QY
767 if (rule->sock == client->sock)
768 break;
769 }
770
771 if (!client)
772 return;
773
774 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
775
776 zclient_create_header(s, ZEBRA_RULE_NOTIFY_OWNER, VRF_DEFAULT);
777 stream_put(s, &note, sizeof(note));
778 stream_putl(s, rule->rule.seq);
779 stream_putl(s, rule->rule.priority);
780 stream_putl(s, rule->rule.unique);
781 if (rule->ifp)
782 stream_putl(s, rule->ifp->ifindex);
783 else
784 stream_putl(s, 0);
785
786 stream_putw_at(s, 0, stream_get_endp(s));
787
21ccc0cf 788 zserv_send_message(client, s);
bf094f69
QY
789}
790
791void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset,
792 enum zapi_ipset_notify_owner note)
793{
794 struct listnode *node;
795 struct zserv *client;
796 struct stream *s;
797
798 if (IS_ZEBRA_DEBUG_PACKET)
799 zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
800 ipset->unique);
801
161e9ab7 802 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
bf094f69
QY
803 if (ipset->sock == client->sock)
804 break;
805 }
806
807 if (!client)
808 return;
809
810 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
811
812 zclient_create_header(s, ZEBRA_IPSET_NOTIFY_OWNER, VRF_DEFAULT);
813 stream_put(s, &note, sizeof(note));
814 stream_putl(s, ipset->unique);
815 stream_put(s, ipset->ipset_name, ZEBRA_IPSET_NAME_SIZE);
816 stream_putw_at(s, 0, stream_get_endp(s));
817
21ccc0cf 818 zserv_send_message(client, s);
bf094f69
QY
819}
820
821void zsend_ipset_entry_notify_owner(struct zebra_pbr_ipset_entry *ipset,
822 enum zapi_ipset_entry_notify_owner note)
823{
824 struct listnode *node;
825 struct zserv *client;
826 struct stream *s;
827
828 if (IS_ZEBRA_DEBUG_PACKET)
829 zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
830 ipset->unique);
831
161e9ab7 832 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
bf094f69
QY
833 if (ipset->sock == client->sock)
834 break;
835 }
836
837 if (!client)
838 return;
839
840 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
841
842 zclient_create_header(s, ZEBRA_IPSET_ENTRY_NOTIFY_OWNER, VRF_DEFAULT);
843 stream_put(s, &note, sizeof(note));
844 stream_putl(s, ipset->unique);
845 stream_put(s, ipset->backpointer->ipset_name, ZEBRA_IPSET_NAME_SIZE);
846 stream_putw_at(s, 0, stream_get_endp(s));
847
21ccc0cf 848 zserv_send_message(client, s);
bf094f69
QY
849}
850
851void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
852 enum zapi_iptable_notify_owner note)
853{
854 struct listnode *node;
855 struct zserv *client;
856 struct stream *s;
857
858 if (IS_ZEBRA_DEBUG_PACKET)
859 zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
860 iptable->unique);
861
161e9ab7 862 for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
bf094f69
QY
863 if (iptable->sock == client->sock)
864 break;
865 }
866
867 if (!client)
868 return;
869
870 s = stream_new(ZEBRA_MAX_PACKET_SIZ);
871
872 zclient_create_header(s, ZEBRA_IPTABLE_NOTIFY_OWNER, VRF_DEFAULT);
873 stream_put(s, &note, sizeof(note));
874 stream_putl(s, iptable->unique);
875 stream_putw_at(s, 0, stream_get_endp(s));
876
21ccc0cf 877 zserv_send_message(client, s);
bf094f69
QY
878}
879
880/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
881int zsend_router_id_update(struct zserv *client, struct prefix *p,
882 vrf_id_t vrf_id)
883{
884 int blen;
885
886 /* Check this client need interface information. */
887 if (!vrf_bitmap_check(client->ridinfo, vrf_id))
888 return 0;
889
890 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
891
892 /* Message type. */
893 zclient_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
894
895 /* Prefix information. */
896 stream_putc(s, p->family);
897 blen = prefix_blen(p);
898 stream_put(s, &p->u.prefix, blen);
899 stream_putc(s, p->prefixlen);
900
901 /* Write packet size. */
902 stream_putw_at(s, 0, stream_get_endp(s));
903
21ccc0cf 904 return zserv_send_message(client, s);
bf094f69
QY
905}
906
907/*
908 * Function used by Zebra to send a PW status update to LDP daemon
909 */
910int zsend_pw_update(struct zserv *client, struct zebra_pw *pw)
911{
912 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
913
914 zclient_create_header(s, ZEBRA_PW_STATUS_UPDATE, pw->vrf_id);
915 stream_write(s, pw->ifname, IF_NAMESIZE);
916 stream_putl(s, pw->ifindex);
917 stream_putl(s, pw->status);
918
919 /* Put length at the first point of the stream. */
920 stream_putw_at(s, 0, stream_get_endp(s));
921
21ccc0cf 922 return zserv_send_message(client, s);
bf094f69
QY
923}
924
925/* Send response to a get label chunk request to client */
926static int zsend_assign_label_chunk_response(struct zserv *client,
927 vrf_id_t vrf_id,
928 struct label_manager_chunk *lmc)
929{
930 int ret;
931 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
932
933 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id);
934
935 if (lmc) {
5dffb0e9
FR
936 /* proto */
937 stream_putc(s, lmc->proto);
938 /* instance */
939 stream_putw(s, lmc->instance);
bf094f69
QY
940 /* keep */
941 stream_putc(s, lmc->keep);
942 /* start and end labels */
943 stream_putl(s, lmc->start);
944 stream_putl(s, lmc->end);
945 }
946
947 /* Write packet size. */
948 stream_putw_at(s, 0, stream_get_endp(s));
949
950 ret = writen(client->sock, s->data, stream_get_endp(s));
951 stream_free(s);
952 return ret;
953}
954
955/* Send response to a label manager connect request to client */
956static int zsend_label_manager_connect_response(struct zserv *client,
957 vrf_id_t vrf_id,
958 unsigned short result)
959{
960 int ret;
961 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
962
963 zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id);
964
5dffb0e9
FR
965 /* proto */
966 stream_putc(s, client->proto);
967
968 /* instance */
969 stream_putw(s, client->instance);
970
bf094f69
QY
971 /* result */
972 stream_putc(s, result);
973
974 /* Write packet size. */
975 stream_putw_at(s, 0, stream_get_endp(s));
976
977 ret = writen(client->sock, s->data, stream_get_endp(s));
978 stream_free(s);
979
980 return ret;
981}
982
983/* Send response to a get table chunk request to client */
984static int zsend_assign_table_chunk_response(struct zserv *client,
985 vrf_id_t vrf_id,
986 struct table_manager_chunk *tmc)
987{
988 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
989
990 zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, vrf_id);
991
992 if (tmc) {
993 /* start and end labels */
994 stream_putl(s, tmc->start);
995 stream_putl(s, tmc->end);
996 }
997
998 /* Write packet size. */
999 stream_putw_at(s, 0, stream_get_endp(s));
1000
21ccc0cf 1001 return zserv_send_message(client, s);
bf094f69
QY
1002}
1003
1004static int zsend_table_manager_connect_response(struct zserv *client,
1005 vrf_id_t vrf_id,
1006 uint16_t result)
1007{
1008 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1009
1010 zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, vrf_id);
1011
1012 /* result */
1013 stream_putc(s, result);
1014
1015 stream_putw_at(s, 0, stream_get_endp(s));
1016
21ccc0cf 1017 return zserv_send_message(client, s);
bf094f69
QY
1018}
1019
1020/* Inbound message handling ------------------------------------------------ */
1021
1022int cmd2type[] = {
1023 [ZEBRA_NEXTHOP_REGISTER] = RNH_NEXTHOP_TYPE,
1024 [ZEBRA_NEXTHOP_UNREGISTER] = RNH_NEXTHOP_TYPE,
1025 [ZEBRA_IMPORT_ROUTE_REGISTER] = RNH_IMPORT_CHECK_TYPE,
1026 [ZEBRA_IMPORT_ROUTE_UNREGISTER] = RNH_IMPORT_CHECK_TYPE,
1027};
1028
1029/* Nexthop register */
1030static void zread_rnh_register(ZAPI_HANDLER_ARGS)
1031{
1032 struct rnh *rnh;
1033 struct stream *s;
1034 struct prefix p;
1035 unsigned short l = 0;
1036 uint8_t flags = 0;
1037 uint16_t type = cmd2type[hdr->command];
1d30d1f4 1038 bool exist;
906b54dd
DS
1039 bool flag_changed = false;
1040 uint8_t orig_flags;
bf094f69
QY
1041
1042 if (IS_ZEBRA_DEBUG_NHT)
1043 zlog_debug(
1044 "rnh_register msg from client %s: hdr->length=%d, type=%s vrf=%u\n",
1045 zebra_route_string(client->proto), hdr->length,
1046 (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route",
1047 zvrf->vrf->vrf_id);
1048
1049 s = msg;
1050
1051 client->nh_reg_time = monotime(NULL);
1052
1053 while (l < hdr->length) {
1054 STREAM_GETC(s, flags);
1055 STREAM_GETW(s, p.family);
1056 STREAM_GETC(s, p.prefixlen);
1057 l += 4;
1058 if (p.family == AF_INET) {
ab5990d8 1059 client->v4_nh_watch_add_cnt++;
bf094f69 1060 if (p.prefixlen > IPV4_MAX_BITLEN) {
9df414fe 1061 zlog_debug(
bf094f69
QY
1062 "%s: Specified prefix hdr->length %d is too large for a v4 address",
1063 __PRETTY_FUNCTION__, p.prefixlen);
1064 return;
1065 }
1066 STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1067 l += IPV4_MAX_BYTELEN;
1068 } else if (p.family == AF_INET6) {
ab5990d8 1069 client->v6_nh_watch_add_cnt++;
bf094f69 1070 if (p.prefixlen > IPV6_MAX_BITLEN) {
9df414fe 1071 zlog_debug(
bf094f69
QY
1072 "%s: Specified prefix hdr->length %d is to large for a v6 address",
1073 __PRETTY_FUNCTION__, p.prefixlen);
1074 return;
1075 }
1076 STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
1077 l += IPV6_MAX_BYTELEN;
1078 } else {
af4c2728 1079 flog_err(
e914ccbe 1080 EC_ZEBRA_UNKNOWN_FAMILY,
bf094f69
QY
1081 "rnh_register: Received unknown family type %d\n",
1082 p.family);
1083 return;
1084 }
1d30d1f4
DS
1085 rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type, &exist);
1086 if (!rnh)
1087 return;
1088
906b54dd 1089 orig_flags = rnh->flags;
bf094f69
QY
1090 if (type == RNH_NEXTHOP_TYPE) {
1091 if (flags
1092 && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
1093 SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
1094 else if (!flags
1095 && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
1096 UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
1097 } else if (type == RNH_IMPORT_CHECK_TYPE) {
1098 if (flags
1099 && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
1100 SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
1101 else if (!flags
1102 && CHECK_FLAG(rnh->flags,
1103 ZEBRA_NHT_EXACT_MATCH))
1104 UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
1105 }
1106
906b54dd
DS
1107 if (orig_flags != rnh->flags)
1108 flag_changed = true;
1109
bf094f69
QY
1110 zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
1111 /* Anything not AF_INET/INET6 has been filtered out above */
906b54dd 1112 if (!exist || flag_changed)
73bf60a0
RW
1113 zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, type,
1114 &p);
bf094f69
QY
1115 }
1116
1117stream_failure:
1118 return;
1119}
1120
1121/* Nexthop register */
1122static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
1123{
1124 struct rnh *rnh;
1125 struct stream *s;
1126 struct prefix p;
1127 unsigned short l = 0;
1128 uint16_t type = cmd2type[hdr->command];
1129
1130 if (IS_ZEBRA_DEBUG_NHT)
1131 zlog_debug(
1132 "rnh_unregister msg from client %s: hdr->length=%d vrf: %u\n",
1133 zebra_route_string(client->proto), hdr->length,
1134 zvrf->vrf->vrf_id);
1135
1136 s = msg;
1137
1138 while (l < hdr->length) {
1139 uint8_t flags;
1140
1141 STREAM_GETC(s, flags);
1142 if (flags != 0)
1143 goto stream_failure;
1144
1145 STREAM_GETW(s, p.family);
1146 STREAM_GETC(s, p.prefixlen);
1147 l += 4;
1148 if (p.family == AF_INET) {
ab5990d8 1149 client->v4_nh_watch_rem_cnt++;
bf094f69 1150 if (p.prefixlen > IPV4_MAX_BITLEN) {
9df414fe 1151 zlog_debug(
bf094f69
QY
1152 "%s: Specified prefix hdr->length %d is to large for a v4 address",
1153 __PRETTY_FUNCTION__, p.prefixlen);
1154 return;
1155 }
1156 STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1157 l += IPV4_MAX_BYTELEN;
1158 } else if (p.family == AF_INET6) {
ab5990d8 1159 client->v6_nh_watch_rem_cnt++;
bf094f69 1160 if (p.prefixlen > IPV6_MAX_BITLEN) {
9df414fe 1161 zlog_debug(
bf094f69
QY
1162 "%s: Specified prefix hdr->length %d is to large for a v6 address",
1163 __PRETTY_FUNCTION__, p.prefixlen);
1164 return;
1165 }
1166 STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
1167 l += IPV6_MAX_BYTELEN;
1168 } else {
af4c2728 1169 flog_err(
e914ccbe 1170 EC_ZEBRA_UNKNOWN_FAMILY,
bf094f69
QY
1171 "rnh_register: Received unknown family type %d\n",
1172 p.family);
1173 return;
1174 }
1175 rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), type);
1176 if (rnh) {
1177 client->nh_dereg_time = monotime(NULL);
1178 zebra_remove_rnh_client(rnh, client, type);
1179 }
1180 }
1181stream_failure:
1182 return;
1183}
1184
1185#define ZEBRA_MIN_FEC_LENGTH 5
1186
1187/* FEC register */
1188static void zread_fec_register(ZAPI_HANDLER_ARGS)
1189{
1190 struct stream *s;
1191 unsigned short l = 0;
1192 struct prefix p;
1193 uint16_t flags;
57592a53 1194 uint32_t label = MPLS_INVALID_LABEL;
bf094f69
QY
1195 uint32_t label_index = MPLS_INVALID_LABEL_INDEX;
1196
1197 s = msg;
1198 zvrf = vrf_info_lookup(VRF_DEFAULT);
1199 if (!zvrf)
8b1766b1 1200 return;
bf094f69
QY
1201
1202 /*
1203 * The minimum amount of data that can be sent for one fec
1204 * registration
1205 */
1206 if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
af4c2728 1207 flog_err(
e914ccbe 1208 EC_ZEBRA_IRDP_LEN_MISMATCH,
bf094f69
QY
1209 "fec_register: Received a fec register of hdr->length %d, it is of insufficient size to properly decode",
1210 hdr->length);
1211 return;
1212 }
1213
1214 while (l < hdr->length) {
1215 STREAM_GETW(s, flags);
1216 memset(&p, 0, sizeof(p));
1217 STREAM_GETW(s, p.family);
1218 if (p.family != AF_INET && p.family != AF_INET6) {
af4c2728 1219 flog_err(
e914ccbe 1220 EC_ZEBRA_UNKNOWN_FAMILY,
bf094f69
QY
1221 "fec_register: Received unknown family type %d\n",
1222 p.family);
1223 return;
1224 }
1225 STREAM_GETC(s, p.prefixlen);
1226 if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
1227 || (p.family == AF_INET6
1228 && p.prefixlen > IPV6_MAX_BITLEN)) {
9df414fe 1229 zlog_debug(
bf094f69
QY
1230 "%s: Specified prefix hdr->length: %d is to long for %d",
1231 __PRETTY_FUNCTION__, p.prefixlen, p.family);
1232 return;
1233 }
1234 l += 5;
1235 STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
1236 l += PSIZE(p.prefixlen);
57592a53
AD
1237 if (flags & ZEBRA_FEC_REGISTER_LABEL) {
1238 STREAM_GETL(s, label);
1239 l += 4;
1240 } else if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) {
bf094f69
QY
1241 STREAM_GETL(s, label_index);
1242 l += 4;
57592a53
AD
1243 }
1244
1245 zebra_mpls_fec_register(zvrf, &p, label, label_index, client);
bf094f69
QY
1246 }
1247
1248stream_failure:
1249 return;
1250}
1251
1252/* FEC unregister */
1253static void zread_fec_unregister(ZAPI_HANDLER_ARGS)
1254{
1255 struct stream *s;
1256 unsigned short l = 0;
1257 struct prefix p;
1258 uint16_t flags;
1259
1260 s = msg;
1261 zvrf = vrf_info_lookup(VRF_DEFAULT);
1262 if (!zvrf)
8b1766b1 1263 return;
bf094f69
QY
1264
1265 /*
1266 * The minimum amount of data that can be sent for one
1267 * fec unregistration
1268 */
1269 if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
af4c2728 1270 flog_err(
e914ccbe 1271 EC_ZEBRA_IRDP_LEN_MISMATCH,
bf094f69
QY
1272 "fec_unregister: Received a fec unregister of hdr->length %d, it is of insufficient size to properly decode",
1273 hdr->length);
1274 return;
1275 }
1276
1277 while (l < hdr->length) {
1278 STREAM_GETW(s, flags);
1279 if (flags != 0)
1280 goto stream_failure;
1281
1282 memset(&p, 0, sizeof(p));
1283 STREAM_GETW(s, p.family);
1284 if (p.family != AF_INET && p.family != AF_INET6) {
af4c2728 1285 flog_err(
e914ccbe 1286 EC_ZEBRA_UNKNOWN_FAMILY,
bf094f69
QY
1287 "fec_unregister: Received unknown family type %d\n",
1288 p.family);
1289 return;
1290 }
1291 STREAM_GETC(s, p.prefixlen);
1292 if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
1293 || (p.family == AF_INET6
1294 && p.prefixlen > IPV6_MAX_BITLEN)) {
9df414fe 1295 zlog_debug(
bf094f69
QY
1296 "%s: Received prefix hdr->length %d which is greater than %d can support",
1297 __PRETTY_FUNCTION__, p.prefixlen, p.family);
1298 return;
1299 }
1300 l += 5;
1301 STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
1302 l += PSIZE(p.prefixlen);
1303 zebra_mpls_fec_unregister(zvrf, &p, client);
1304 }
1305
1306stream_failure:
1307 return;
1308}
1309
1310
1311/*
1312 * Register zebra server interface information.
1313 * Send current all interface and address information.
1314 */
1315static void zread_interface_add(ZAPI_HANDLER_ARGS)
1316{
1317 struct vrf *vrf;
1318 struct interface *ifp;
1319
bf094f69
QY
1320 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
1321 FOR_ALL_INTERFACES (vrf, ifp) {
1322 /* Skip pseudo interface. */
1323 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
1324 continue;
1325
1326 zsend_interface_add(client, ifp);
27ecbea3 1327 zsend_interface_link_params(client, ifp);
bf094f69
QY
1328 zsend_interface_addresses(client, ifp);
1329 }
1330 }
1331}
1332
1333/* Unregister zebra server interface information. */
1334static void zread_interface_delete(ZAPI_HANDLER_ARGS)
1335{
bf094f69
QY
1336}
1337
1338void zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
1339 const unsigned int nexthop_num)
1340{
1341 if (nexthop_num > multipath_num) {
1342 char buff[PREFIX2STR_BUFFER];
8b1766b1 1343
bf094f69 1344 prefix2str(p, buff, sizeof(buff));
9df414fe 1345 flog_warn(
e914ccbe 1346 EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
bf094f69
QY
1347 "%s: Prefix %s has %d nexthops, but we can only use the first %d",
1348 caller, buff, nexthop_num, multipath_num);
1349 }
1350}
1351
1352static void zread_route_add(ZAPI_HANDLER_ARGS)
1353{
1354 struct stream *s;
1355 struct zapi_route api;
1356 struct zapi_nexthop *api_nh;
1357 afi_t afi;
1358 struct prefix_ipv6 *src_p = NULL;
1359 struct route_entry *re;
1360 struct nexthop *nexthop = NULL;
1361 int i, ret;
1362 vrf_id_t vrf_id = 0;
1363 struct ipaddr vtep_ip;
1364
1365 s = msg;
1366 if (zapi_route_decode(s, &api) < 0) {
1367 if (IS_ZEBRA_DEBUG_RECV)
1368 zlog_debug("%s: Unable to decode zapi_route sent",
1369 __PRETTY_FUNCTION__);
1370 return;
1371 }
1372
1373 if (IS_ZEBRA_DEBUG_RECV) {
1374 char buf_prefix[PREFIX_STRLEN];
8b1766b1 1375
bf094f69
QY
1376 prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
1377 zlog_debug("%s: p=%s, ZAPI_MESSAGE_LABEL: %sset, flags=0x%x",
1378 __func__, buf_prefix,
1379 (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL) ? ""
1380 : "un"),
1381 api.flags);
1382 }
1383
1384 /* Allocate new route. */
1385 vrf_id = zvrf_id(zvrf);
1386 re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
1387 re->type = api.type;
1388 re->instance = api.instance;
1389 re->flags = api.flags;
1390 re->uptime = time(NULL);
1391 re->vrf_id = vrf_id;
1392 if (api.tableid && vrf_id == VRF_DEFAULT)
1393 re->table = api.tableid;
1394 else
1395 re->table = zvrf->table_id;
1396
7fcb24bb
RW
1397 if (!CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)
1398 || api.nexthop_num == 0) {
1399 char buf_prefix[PREFIX_STRLEN];
1400
1401 prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
1402 flog_warn(EC_ZEBRA_RX_ROUTE_NO_NEXTHOPS,
1403 "%s: received a route without nexthops for prefix %s",
1404 __func__, buf_prefix);
1405 XFREE(MTYPE_RE, re);
1406 return;
1407 }
1408
bf094f69
QY
1409 /*
1410 * TBD should _all_ of the nexthop add operations use
1411 * api_nh->vrf_id instead of re->vrf_id ? I only changed
1412 * for cases NEXTHOP_TYPE_IPV4 and NEXTHOP_TYPE_IPV6.
1413 */
7fcb24bb
RW
1414 for (i = 0; i < api.nexthop_num; i++) {
1415 api_nh = &api.nexthops[i];
1416 ifindex_t ifindex = 0;
1417
1418 if (IS_ZEBRA_DEBUG_RECV)
1419 zlog_debug("nh type %d", api_nh->type);
1420
1421 switch (api_nh->type) {
1422 case NEXTHOP_TYPE_IFINDEX:
1423 nexthop = route_entry_nexthop_ifindex_add(
1424 re, api_nh->ifindex, api_nh->vrf_id);
1425 break;
1426 case NEXTHOP_TYPE_IPV4:
1427 if (IS_ZEBRA_DEBUG_RECV) {
1428 char nhbuf[INET6_ADDRSTRLEN] = {0};
1429
1430 inet_ntop(AF_INET, &api_nh->gate.ipv4, nhbuf,
1431 INET6_ADDRSTRLEN);
1432 zlog_debug("%s: nh=%s, vrf_id=%d", __func__,
1433 nhbuf, api_nh->vrf_id);
1434 }
1435 nexthop = route_entry_nexthop_ipv4_add(
1436 re, &api_nh->gate.ipv4, NULL, api_nh->vrf_id);
1437 break;
1438 case NEXTHOP_TYPE_IPV4_IFINDEX:
1439
1440 memset(&vtep_ip, 0, sizeof(struct ipaddr));
e1e71450 1441 ifindex = api_nh->ifindex;
7fcb24bb
RW
1442 if (IS_ZEBRA_DEBUG_RECV) {
1443 char nhbuf[INET6_ADDRSTRLEN] = {0};
1444
1445 inet_ntop(AF_INET, &api_nh->gate.ipv4, nhbuf,
1446 INET6_ADDRSTRLEN);
1447 zlog_debug(
1448 "%s: nh=%s, vrf_id=%d (re->vrf_id=%d), ifindex=%d",
1449 __func__, nhbuf, api_nh->vrf_id,
1450 re->vrf_id, ifindex);
bf094f69 1451 }
7fcb24bb
RW
1452 nexthop = route_entry_nexthop_ipv4_ifindex_add(
1453 re, &api_nh->gate.ipv4, NULL, ifindex,
1454 api_nh->vrf_id);
1455
2b83602b 1456 /* Special handling for IPv4 routes sourced from EVPN:
1457 * the nexthop and associated MAC need to be installed.
7fcb24bb
RW
1458 */
1459 if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
7fcb24bb
RW
1460 vtep_ip.ipa_type = IPADDR_V4;
1461 memcpy(&(vtep_ip.ipaddr_v4),
1462 &(api_nh->gate.ipv4),
1463 sizeof(struct in_addr));
1464 zebra_vxlan_evpn_vrf_route_add(
744c63be 1465 api_nh->vrf_id, &api_nh->rmac,
1466 &vtep_ip, &api.prefix);
bf094f69 1467 }
7fcb24bb
RW
1468 break;
1469 case NEXTHOP_TYPE_IPV6:
1470 nexthop = route_entry_nexthop_ipv6_add(
1471 re, &api_nh->gate.ipv6, api_nh->vrf_id);
1472 break;
1473 case NEXTHOP_TYPE_IPV6_IFINDEX:
1474 memset(&vtep_ip, 0, sizeof(struct ipaddr));
e1e71450 1475 ifindex = api_nh->ifindex;
7fcb24bb
RW
1476 nexthop = route_entry_nexthop_ipv6_ifindex_add(
1477 re, &api_nh->gate.ipv6, ifindex,
1478 api_nh->vrf_id);
1479
2b83602b 1480 /* Special handling for IPv6 routes sourced from EVPN:
1481 * the nexthop and associated MAC need to be installed.
7fcb24bb
RW
1482 */
1483 if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
7fcb24bb
RW
1484 vtep_ip.ipa_type = IPADDR_V6;
1485 memcpy(&vtep_ip.ipaddr_v6, &(api_nh->gate.ipv6),
1486 sizeof(struct in6_addr));
1487 zebra_vxlan_evpn_vrf_route_add(
744c63be 1488 api_nh->vrf_id, &api_nh->rmac,
1489 &vtep_ip, &api.prefix);
7fcb24bb
RW
1490 }
1491 break;
1492 case NEXTHOP_TYPE_BLACKHOLE:
1493 nexthop = route_entry_nexthop_blackhole_add(
1494 re, api_nh->bh_type);
1495 break;
bf094f69 1496 }
bf094f69 1497
7fcb24bb
RW
1498 if (!nexthop) {
1499 flog_warn(
1500 EC_ZEBRA_NEXTHOP_CREATION_FAILED,
1501 "%s: Nexthops Specified: %d but we failed to properly create one",
1502 __PRETTY_FUNCTION__, api.nexthop_num);
1503 nexthops_free(re->ng.nexthop);
1504 XFREE(MTYPE_RE, re);
1505 return;
1506 }
fe85601c
DS
1507 if (api_nh->onlink)
1508 SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
1509
7fcb24bb
RW
1510 /* MPLS labels for BGP-LU or Segment Routing */
1511 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)
1512 && api_nh->type != NEXTHOP_TYPE_IFINDEX
1513 && api_nh->type != NEXTHOP_TYPE_BLACKHOLE) {
1514 enum lsp_types_t label_type;
1515
1516 label_type = lsp_type_from_re_type(client->proto);
1517
1518 if (IS_ZEBRA_DEBUG_RECV) {
1519 zlog_debug(
1520 "%s: adding %d labels of type %d (1st=%u)",
1521 __func__, api_nh->label_num, label_type,
1522 api_nh->labels[0]);
1523 }
1524
1525 nexthop_add_labels(nexthop, label_type,
1526 api_nh->label_num,
1527 &api_nh->labels[0]);
1528 }
1529 }
1530
bf094f69
QY
1531 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
1532 re->distance = api.distance;
1533 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
1534 re->metric = api.metric;
1535 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG))
1536 re->tag = api.tag;
1537 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_MTU))
1538 re->mtu = api.mtu;
1539
1540 afi = family2afi(api.prefix.family);
1541 if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
e914ccbe 1542 flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
9df414fe 1543 "%s: Received SRC Prefix but afi is not v6",
bf094f69
QY
1544 __PRETTY_FUNCTION__);
1545 nexthops_free(re->ng.nexthop);
1546 XFREE(MTYPE_RE, re);
1547 return;
1548 }
1549 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
1550 src_p = &api.src_prefix;
1551
1552 ret = rib_add_multipath(afi, api.safi, &api.prefix, src_p, re);
1553
1554 /* Stats */
1555 switch (api.prefix.family) {
1556 case AF_INET:
1557 if (ret > 0)
1558 client->v4_route_add_cnt++;
1559 else if (ret < 0)
1560 client->v4_route_upd8_cnt++;
1561 break;
1562 case AF_INET6:
1563 if (ret > 0)
1564 client->v6_route_add_cnt++;
1565 else if (ret < 0)
1566 client->v6_route_upd8_cnt++;
1567 break;
1568 }
1569}
1570
1571static void zread_route_del(ZAPI_HANDLER_ARGS)
1572{
1573 struct stream *s;
1574 struct zapi_route api;
1575 afi_t afi;
1576 struct prefix_ipv6 *src_p = NULL;
1577 uint32_t table_id;
1578
1579 s = msg;
1580 if (zapi_route_decode(s, &api) < 0)
1581 return;
1582
1583 afi = family2afi(api.prefix.family);
1584 if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
e914ccbe 1585 flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
9df414fe 1586 "%s: Received a src prefix while afi is not v6",
bf094f69
QY
1587 __PRETTY_FUNCTION__);
1588 return;
1589 }
1590 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
1591 src_p = &api.src_prefix;
1592
1593 if (api.vrf_id == VRF_DEFAULT && api.tableid != 0)
1594 table_id = api.tableid;
1595 else
1596 table_id = zvrf->table_id;
1597
1598 rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
1599 api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
40ecd8e4 1600 api.distance, false);
bf094f69
QY
1601
1602 /* Stats */
1603 switch (api.prefix.family) {
1604 case AF_INET:
1605 client->v4_route_del_cnt++;
1606 break;
1607 case AF_INET6:
1608 client->v6_route_del_cnt++;
1609 break;
1610 }
1611}
1612
bf094f69
QY
1613/* MRIB Nexthop lookup for IPv4. */
1614static void zread_ipv4_nexthop_lookup_mrib(ZAPI_HANDLER_ARGS)
1615{
1616 struct in_addr addr;
1617 struct route_entry *re;
1618
1619 STREAM_GET(&addr.s_addr, msg, IPV4_MAX_BYTELEN);
1620 re = rib_match_ipv4_multicast(zvrf_id(zvrf), addr, NULL);
1621 zsend_ipv4_nexthop_lookup_mrib(client, addr, re, zvrf);
1622
1623stream_failure:
1624 return;
1625}
1626
bf094f69
QY
1627/* Register zebra server router-id information. Send current router-id */
1628static void zread_router_id_add(ZAPI_HANDLER_ARGS)
1629{
1630 struct prefix p;
1631
1632 /* Router-id information is needed. */
1633 vrf_bitmap_set(client->ridinfo, zvrf_id(zvrf));
1634
1635 router_id_get(&p, zvrf_id(zvrf));
1636
1637 zsend_router_id_update(client, &p, zvrf_id(zvrf));
1638}
1639
1640/* Unregister zebra server router-id information. */
1641static void zread_router_id_delete(ZAPI_HANDLER_ARGS)
1642{
1643 vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
1644}
1645
1646static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
1647{
1648 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1649
1650 zclient_create_header(s, ZEBRA_CAPABILITIES, zvrf->vrf->vrf_id);
bb6b7f79 1651 stream_putl(s, vrf_get_backend());
bf094f69
QY
1652 stream_putc(s, mpls_enabled);
1653 stream_putl(s, multipath_num);
02c0866d 1654 stream_putc(s, zebra_mlag_get_role());
bf094f69
QY
1655
1656 stream_putw_at(s, 0, stream_get_endp(s));
21ccc0cf 1657 zserv_send_message(client, s);
bf094f69
QY
1658}
1659
b120fe3b
DS
1660void zsend_capabilities_all_clients(void)
1661{
1662 struct listnode *node, *nnode;
1663 struct zebra_vrf *zvrf;
1664 struct zserv *client;
1665
1666 zvrf = vrf_info_lookup(VRF_DEFAULT);
1667 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
1668 zsend_capabilities(client, zvrf);
1669 }
1670}
1671
bf094f69
QY
1672/* Tie up route-type and client->sock */
1673static void zread_hello(ZAPI_HANDLER_ARGS)
1674{
1675 /* type of protocol (lib/zebra.h) */
1676 uint8_t proto;
1677 unsigned short instance;
1678 uint8_t notify;
1679
1680 STREAM_GETC(msg, proto);
1681 STREAM_GETW(msg, instance);
1682 STREAM_GETC(msg, notify);
1683 if (notify)
1684 client->notify_owner = true;
1685
1686 /* accept only dynamic routing protocols */
f23cbcda 1687 if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_CONNECT)) {
bf094f69
QY
1688 zlog_notice(
1689 "client %d says hello and bids fair to announce only %s routes vrf=%u",
1690 client->sock, zebra_route_string(proto),
1691 zvrf->vrf->vrf_id);
1692 if (instance)
1693 zlog_notice("client protocol instance %d", instance);
1694
1695 client->proto = proto;
1696 client->instance = instance;
1697 }
1698
1699 zsend_capabilities(client, zvrf);
bb6b7f79 1700 zebra_vrf_update_all(client);
bf094f69
QY
1701stream_failure:
1702 return;
1703}
1704
1705/* Unregister all information in a VRF. */
1706static void zread_vrf_unregister(ZAPI_HANDLER_ARGS)
1707{
1708 int i;
1709 afi_t afi;
1710
49db7a7b 1711 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
bf094f69
QY
1712 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1713 vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf));
49db7a7b
RW
1714 vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
1715 }
bf094f69
QY
1716 vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
1717}
1718
1719static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
1720{
1721 struct stream *s;
1722 enum lsp_types_t type;
1723 struct prefix prefix;
1724 enum nexthop_types_t gtype;
1725 union g_addr gate;
1726 ifindex_t ifindex;
1727 mpls_label_t in_label, out_label;
1728 uint8_t distance;
1729
1730 /* Get input stream. */
1731 s = msg;
1732
1733 /* Get data. */
1734 STREAM_GETC(s, type);
1735 STREAM_GETL(s, prefix.family);
1736 switch (prefix.family) {
1737 case AF_INET:
1738 STREAM_GET(&prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1739 STREAM_GETC(s, prefix.prefixlen);
1740 if (prefix.prefixlen > IPV4_MAX_BITLEN) {
9df414fe 1741 zlog_debug(
bf094f69
QY
1742 "%s: Specified prefix length %d is greater than a v4 address can support",
1743 __PRETTY_FUNCTION__, prefix.prefixlen);
1744 return;
1745 }
1746 STREAM_GET(&gate.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
1747 break;
1748 case AF_INET6:
1749 STREAM_GET(&prefix.u.prefix6, s, 16);
1750 STREAM_GETC(s, prefix.prefixlen);
1751 if (prefix.prefixlen > IPV6_MAX_BITLEN) {
9df414fe 1752 zlog_debug(
bf094f69
QY
1753 "%s: Specified prefix length %d is greater than a v6 address can support",
1754 __PRETTY_FUNCTION__, prefix.prefixlen);
1755 return;
1756 }
1757 STREAM_GET(&gate.ipv6, s, 16);
1758 break;
1759 default:
9df414fe
QY
1760 zlog_debug("%s: Specified AF %d is not supported for this call",
1761 __PRETTY_FUNCTION__, prefix.family);
bf094f69
QY
1762 return;
1763 }
1764 STREAM_GETL(s, ifindex);
1765 STREAM_GETC(s, distance);
1766 STREAM_GETL(s, in_label);
1767 STREAM_GETL(s, out_label);
1768
1769 switch (prefix.family) {
1770 case AF_INET:
1771 if (ifindex)
1772 gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
1773 else
1774 gtype = NEXTHOP_TYPE_IPV4;
1775 break;
1776 case AF_INET6:
1777 if (ifindex)
1778 gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
1779 else
1780 gtype = NEXTHOP_TYPE_IPV6;
1781 break;
1782 default:
1783 return;
1784 }
1785
1786 if (!mpls_enabled)
1787 return;
1788
1789 if (hdr->command == ZEBRA_MPLS_LABELS_ADD) {
1790 mpls_lsp_install(zvrf, type, in_label, out_label, gtype, &gate,
1791 ifindex);
1792 mpls_ftn_update(1, zvrf, type, &prefix, gtype, &gate, ifindex,
1793 distance, out_label);
1794 } else if (hdr->command == ZEBRA_MPLS_LABELS_DELETE) {
1795 mpls_lsp_uninstall(zvrf, type, in_label, gtype, &gate, ifindex);
1796 mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, ifindex,
1797 distance, out_label);
1798 }
1799stream_failure:
1800 return;
1801}
1802
1803/* Send response to a table manager connect request to client */
1804static void zread_table_manager_connect(struct zserv *client,
1805 struct stream *msg, vrf_id_t vrf_id)
1806{
1807 struct stream *s;
1808 uint8_t proto;
1809 uint16_t instance;
1810
1811 s = msg;
1812
1813 /* Get data. */
1814 STREAM_GETC(s, proto);
1815 STREAM_GETW(s, instance);
1816
1817 /* accept only dynamic routing protocols */
1818 if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
e914ccbe 1819 flog_err(EC_ZEBRA_TM_WRONG_PROTO,
1c50c1c0
QY
1820 "client %d has wrong protocol %s", client->sock,
1821 zebra_route_string(proto));
bf094f69
QY
1822 zsend_table_manager_connect_response(client, vrf_id, 1);
1823 return;
1824 }
1825 zlog_notice("client %d with vrf %u instance %u connected as %s",
1826 client->sock, vrf_id, instance, zebra_route_string(proto));
1827 client->proto = proto;
1828 client->instance = instance;
1829
1830 /*
1831 * Release previous labels of same protocol and instance.
1832 * This is done in case it restarted from an unexpected shutdown.
1833 */
453844ab 1834 release_daemon_table_chunks(client);
bf094f69
QY
1835
1836 zsend_table_manager_connect_response(client, vrf_id, 0);
1837
1838stream_failure:
1839 return;
1840}
1841
1842static void zread_label_manager_connect(struct zserv *client,
1843 struct stream *msg, vrf_id_t vrf_id)
1844{
1845 struct stream *s;
1846 /* type of protocol (lib/zebra.h) */
1847 uint8_t proto;
1848 unsigned short instance;
1849
1850 /* Get input stream. */
1851 s = msg;
1852
1853 /* Get data. */
1854 STREAM_GETC(s, proto);
1855 STREAM_GETW(s, instance);
1856
1857 /* accept only dynamic routing protocols */
1858 if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
e914ccbe 1859 flog_err(EC_ZEBRA_TM_WRONG_PROTO,
1c50c1c0
QY
1860 "client %d has wrong protocol %s", client->sock,
1861 zebra_route_string(proto));
f533be73 1862 if (client->is_synchronous)
1863 zsend_label_manager_connect_response(client, vrf_id, 1);
bf094f69
QY
1864 return;
1865 }
1866 zlog_notice("client %d with vrf %u instance %u connected as %s",
1867 client->sock, vrf_id, instance, zebra_route_string(proto));
1868 client->proto = proto;
1869 client->instance = instance;
1870
1871 /*
453844ab
QY
1872 * Release previous labels of same protocol and instance.
1873 * This is done in case it restarted from an unexpected shutdown.
1874 */
1875 release_daemon_label_chunks(client);
bf094f69
QY
1876
1877 zlog_debug(
1878 " Label Manager client connected: sock %d, proto %s, vrf %u instance %u",
1879 client->sock, zebra_route_string(proto), vrf_id, instance);
1880 /* send response back */
f533be73 1881 if (client->is_synchronous)
1882 zsend_label_manager_connect_response(client, vrf_id, 0);
bf094f69
QY
1883
1884stream_failure:
1885 return;
1886}
1887
1888static void zread_get_label_chunk(struct zserv *client, struct stream *msg,
1889 vrf_id_t vrf_id)
1890{
1891 struct stream *s;
1892 uint8_t keep;
1893 uint32_t size;
1894 struct label_manager_chunk *lmc;
5dffb0e9
FR
1895 uint8_t proto;
1896 unsigned short instance;
bf094f69
QY
1897
1898 /* Get input stream. */
1899 s = msg;
1900
1901 /* Get data. */
5dffb0e9
FR
1902 STREAM_GETC(s, proto);
1903 STREAM_GETW(s, instance);
bf094f69
QY
1904 STREAM_GETC(s, keep);
1905 STREAM_GETL(s, size);
1906
f533be73 1907 lmc = assign_label_chunk(proto, instance, keep, size);
bf094f69 1908 if (!lmc)
af4c2728 1909 flog_err(
e914ccbe 1910 EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK,
0313523d 1911 "Unable to assign Label Chunk of size %u to %s instance %u",
f533be73 1912 size, zebra_route_string(proto), instance);
bf094f69 1913 else
0313523d
FR
1914 zlog_debug("Assigned Label Chunk %u - %u to %s instance %u",
1915 lmc->start, lmc->end,
f533be73 1916 zebra_route_string(proto), instance);
bf094f69
QY
1917 /* send response back */
1918 zsend_assign_label_chunk_response(client, vrf_id, lmc);
1919
1920stream_failure:
1921 return;
1922}
1923
1924static void zread_release_label_chunk(struct zserv *client, struct stream *msg)
1925{
1926 struct stream *s;
1927 uint32_t start, end;
5dffb0e9
FR
1928 uint8_t proto;
1929 unsigned short instance;
bf094f69
QY
1930
1931 /* Get input stream. */
1932 s = msg;
1933
1934 /* Get data. */
5dffb0e9
FR
1935 STREAM_GETC(s, proto);
1936 STREAM_GETW(s, instance);
bf094f69
QY
1937 STREAM_GETL(s, start);
1938 STREAM_GETL(s, end);
1939
f533be73 1940 release_label_chunk(proto, instance, start, end);
bf094f69
QY
1941
1942stream_failure:
1943 return;
1944}
1945static void zread_label_manager_request(ZAPI_HANDLER_ARGS)
1946{
1947 /* to avoid sending other messages like ZERBA_INTERFACE_UP */
f533be73 1948 client->is_synchronous = hdr->command ==
1949 ZEBRA_LABEL_MANAGER_CONNECT;
bf094f69
QY
1950
1951 /* external label manager */
1952 if (lm_is_external)
0313523d 1953 zread_relay_label_manager_request(hdr->command, client, msg,
bf094f69
QY
1954 zvrf_id(zvrf));
1955 /* this is a label manager */
1956 else {
f533be73 1957 if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT ||
1958 hdr->command == ZEBRA_LABEL_MANAGER_CONNECT_ASYNC)
bf094f69
QY
1959 zread_label_manager_connect(client, msg, zvrf_id(zvrf));
1960 else {
bf094f69
QY
1961 if (hdr->command == ZEBRA_GET_LABEL_CHUNK)
1962 zread_get_label_chunk(client, msg,
1963 zvrf_id(zvrf));
1964 else if (hdr->command == ZEBRA_RELEASE_LABEL_CHUNK)
1965 zread_release_label_chunk(client, msg);
1966 }
1967 }
1968}
1969
1970static void zread_get_table_chunk(struct zserv *client, struct stream *msg,
1971 vrf_id_t vrf_id)
1972{
1973 struct stream *s;
1974 uint32_t size;
1975 struct table_manager_chunk *tmc;
1976
1977 /* Get input stream. */
1978 s = msg;
1979
1980 /* Get data. */
1981 STREAM_GETL(s, size);
1982
1983 tmc = assign_table_chunk(client->proto, client->instance, size);
1984 if (!tmc)
e914ccbe 1985 flog_err(EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
1c50c1c0
QY
1986 "%s: Unable to assign Table Chunk of size %u",
1987 __func__, size);
bf094f69
QY
1988 else
1989 zlog_debug("Assigned Table Chunk %u - %u", tmc->start,
1990 tmc->end);
1991 /* send response back */
1992 zsend_assign_table_chunk_response(client, vrf_id, tmc);
1993
1994stream_failure:
1995 return;
1996}
1997
1998static void zread_release_table_chunk(struct zserv *client, struct stream *msg)
1999{
2000 struct stream *s;
2001 uint32_t start, end;
2002
2003 /* Get input stream. */
2004 s = msg;
2005
2006 /* Get data. */
2007 STREAM_GETL(s, start);
2008 STREAM_GETL(s, end);
2009
2010 release_table_chunk(client->proto, client->instance, start, end);
2011
2012stream_failure:
2013 return;
2014}
2015
2016static void zread_table_manager_request(ZAPI_HANDLER_ARGS)
2017{
2018 /* to avoid sending other messages like ZERBA_INTERFACE_UP */
2019 if (hdr->command == ZEBRA_TABLE_MANAGER_CONNECT)
2020 zread_table_manager_connect(client, msg, zvrf_id(zvrf));
2021 else {
2022 /* Sanity: don't allow 'unidentified' requests */
2023 if (!client->proto) {
af4c2728 2024 flog_err(
e914ccbe 2025 EC_ZEBRA_TM_ALIENS,
bf094f69
QY
2026 "Got table request from an unidentified client");
2027 return;
2028 }
2029 if (hdr->command == ZEBRA_GET_TABLE_CHUNK)
2030 zread_get_table_chunk(client, msg, zvrf_id(zvrf));
2031 else if (hdr->command == ZEBRA_RELEASE_TABLE_CHUNK)
2032 zread_release_table_chunk(client, msg);
2033 }
2034}
2035
2036static void zread_pseudowire(ZAPI_HANDLER_ARGS)
2037{
2038 struct stream *s;
2039 char ifname[IF_NAMESIZE];
2040 ifindex_t ifindex;
2041 int type;
2042 int af;
2043 union g_addr nexthop;
2044 uint32_t local_label;
2045 uint32_t remote_label;
2046 uint8_t flags;
2047 union pw_protocol_fields data;
2048 uint8_t protocol;
2049 struct zebra_pw *pw;
2050
2051 /* Get input stream. */
2052 s = msg;
2053
2054 /* Get data. */
2055 STREAM_GET(ifname, s, IF_NAMESIZE);
2056 STREAM_GETL(s, ifindex);
2057 STREAM_GETL(s, type);
2058 STREAM_GETL(s, af);
2059 switch (af) {
2060 case AF_INET:
2061 STREAM_GET(&nexthop.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
2062 break;
2063 case AF_INET6:
2064 STREAM_GET(&nexthop.ipv6, s, 16);
2065 break;
2066 default:
2067 return;
2068 }
2069 STREAM_GETL(s, local_label);
2070 STREAM_GETL(s, remote_label);
2071 STREAM_GETC(s, flags);
2072 STREAM_GET(&data, s, sizeof(data));
2073 protocol = client->proto;
2074
2075 pw = zebra_pw_find(zvrf, ifname);
2076 switch (hdr->command) {
2077 case ZEBRA_PW_ADD:
2078 if (pw) {
e914ccbe 2079 flog_warn(EC_ZEBRA_PSEUDOWIRE_EXISTS,
9df414fe 2080 "%s: pseudowire %s already exists [%s]",
bf094f69
QY
2081 __func__, ifname,
2082 zserv_command_string(hdr->command));
2083 return;
2084 }
2085
2086 zebra_pw_add(zvrf, ifname, protocol, client);
2087 break;
2088 case ZEBRA_PW_DELETE:
2089 if (!pw) {
e914ccbe 2090 flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
9df414fe 2091 "%s: pseudowire %s not found [%s]", __func__,
bf094f69
QY
2092 ifname, zserv_command_string(hdr->command));
2093 return;
2094 }
2095
2096 zebra_pw_del(zvrf, pw);
2097 break;
2098 case ZEBRA_PW_SET:
2099 case ZEBRA_PW_UNSET:
2100 if (!pw) {
e914ccbe 2101 flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
9df414fe 2102 "%s: pseudowire %s not found [%s]", __func__,
bf094f69
QY
2103 ifname, zserv_command_string(hdr->command));
2104 return;
2105 }
2106
2107 switch (hdr->command) {
2108 case ZEBRA_PW_SET:
2109 pw->enabled = 1;
2110 break;
2111 case ZEBRA_PW_UNSET:
2112 pw->enabled = 0;
2113 break;
2114 }
2115
2116 zebra_pw_change(pw, ifindex, type, af, &nexthop, local_label,
2117 remote_label, flags, &data);
2118 break;
2119 }
2120
2121stream_failure:
2122 return;
2123}
2124
2125static void zread_interface_set_master(ZAPI_HANDLER_ARGS)
2126{
2127 struct interface *master;
2128 struct interface *slave;
2129 struct stream *s = msg;
2130 int ifindex;
2131 vrf_id_t vrf_id;
2132
2133 STREAM_GETL(s, vrf_id);
2134 STREAM_GETL(s, ifindex);
2135 master = if_lookup_by_index(ifindex, vrf_id);
2136
2137 STREAM_GETL(s, vrf_id);
2138 STREAM_GETL(s, ifindex);
2139 slave = if_lookup_by_index(ifindex, vrf_id);
2140
2141 if (!master || !slave)
2142 return;
2143
2144 kernel_interface_set_master(master, slave);
2145
2146stream_failure:
2147 return;
2148}
2149
2150
2151static void zread_vrf_label(ZAPI_HANDLER_ARGS)
2152{
2153 struct interface *ifp;
2154 mpls_label_t nlabel;
2155 afi_t afi;
2156 struct stream *s;
2157 struct zebra_vrf *def_zvrf;
2158 enum lsp_types_t ltype;
2159
2160 s = msg;
2161 STREAM_GETL(s, nlabel);
2162 STREAM_GETC(s, afi);
2163 if (nlabel == zvrf->label[afi]) {
2164 /*
2165 * Nothing to do here move along
2166 */
2167 return;
2168 }
2169
2170 STREAM_GETC(s, ltype);
2171
2172 if (zvrf->vrf->vrf_id != VRF_DEFAULT)
2173 ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id);
2174 else
2175 ifp = if_lookup_by_name("lo", VRF_DEFAULT);
2176
2177 if (!ifp) {
2178 zlog_debug("Unable to find specified Interface for %s",
2179 zvrf->vrf->name);
2180 return;
2181 }
2182
2183 def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
2184
2185 if (zvrf->label[afi] != MPLS_LABEL_NONE) {
2186 afi_t scrubber;
2187 bool really_remove;
2188
2189 really_remove = true;
2190 for (scrubber = AFI_IP; scrubber < AFI_MAX; scrubber++) {
2191 if (scrubber == afi)
2192 continue;
2193
2194 if (zvrf->label[scrubber] == MPLS_LABEL_NONE)
2195 continue;
2196
2197 if (zvrf->label[afi] == zvrf->label[scrubber]) {
2198 really_remove = false;
2199 break;
2200 }
2201 }
2202
2203 if (really_remove)
2204 mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi],
2205 NEXTHOP_TYPE_IFINDEX, NULL,
2206 ifp->ifindex);
2207 }
2208
2209 if (nlabel != MPLS_LABEL_NONE)
2210 mpls_lsp_install(def_zvrf, ltype, nlabel,
2211 MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX,
2212 NULL, ifp->ifindex);
2213
2214 zvrf->label[afi] = nlabel;
2215stream_failure:
2216 return;
2217}
2218
2219static inline void zread_rule(ZAPI_HANDLER_ARGS)
2220{
2221 struct zebra_pbr_rule zpr;
2222 struct stream *s;
2223 uint32_t total, i;
2224 ifindex_t ifindex;
2225
2226 s = msg;
2227 STREAM_GETL(s, total);
2228
2229 for (i = 0; i < total; i++) {
2230 memset(&zpr, 0, sizeof(zpr));
2231
2232 zpr.sock = client->sock;
2233 zpr.rule.vrf_id = hdr->vrf_id;
2234 STREAM_GETL(s, zpr.rule.seq);
2235 STREAM_GETL(s, zpr.rule.priority);
2236 STREAM_GETL(s, zpr.rule.unique);
2237 STREAM_GETC(s, zpr.rule.filter.src_ip.family);
2238 STREAM_GETC(s, zpr.rule.filter.src_ip.prefixlen);
2239 STREAM_GET(&zpr.rule.filter.src_ip.u.prefix, s,
2240 prefix_blen(&zpr.rule.filter.src_ip));
2241 STREAM_GETW(s, zpr.rule.filter.src_port);
2242 STREAM_GETC(s, zpr.rule.filter.dst_ip.family);
2243 STREAM_GETC(s, zpr.rule.filter.dst_ip.prefixlen);
2244 STREAM_GET(&zpr.rule.filter.dst_ip.u.prefix, s,
2245 prefix_blen(&zpr.rule.filter.dst_ip));
2246 STREAM_GETW(s, zpr.rule.filter.dst_port);
2247 STREAM_GETL(s, zpr.rule.filter.fwmark);
2248 STREAM_GETL(s, zpr.rule.action.table);
2249 STREAM_GETL(s, ifindex);
2250
2251 if (ifindex) {
06432d4e
PG
2252 zpr.ifp = if_lookup_by_index_per_ns(
2253 zvrf->zns,
2254 ifindex);
bf094f69
QY
2255 if (!zpr.ifp) {
2256 zlog_debug("Failed to lookup ifindex: %u",
2257 ifindex);
2258 return;
2259 }
2260 }
2261
2262 if (!is_default_prefix(&zpr.rule.filter.src_ip))
2263 zpr.rule.filter.filter_bm |= PBR_FILTER_SRC_IP;
2264
2265 if (!is_default_prefix(&zpr.rule.filter.dst_ip))
2266 zpr.rule.filter.filter_bm |= PBR_FILTER_DST_IP;
2267
2268 if (zpr.rule.filter.src_port)
2269 zpr.rule.filter.filter_bm |= PBR_FILTER_SRC_PORT;
2270
2271 if (zpr.rule.filter.dst_port)
2272 zpr.rule.filter.filter_bm |= PBR_FILTER_DST_PORT;
2273
2274 if (zpr.rule.filter.fwmark)
2275 zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK;
2276
7f0ea8a4 2277 zpr.vrf_id = zvrf->vrf->vrf_id;
bf094f69 2278 if (hdr->command == ZEBRA_RULE_ADD)
7f0ea8a4 2279 zebra_pbr_add_rule(&zpr);
bf094f69 2280 else
7f0ea8a4 2281 zebra_pbr_del_rule(&zpr);
bf094f69
QY
2282 }
2283
2284stream_failure:
2285 return;
2286}
2287
2288static inline void zread_ipset(ZAPI_HANDLER_ARGS)
2289{
2290 struct zebra_pbr_ipset zpi;
2291 struct stream *s;
2292 uint32_t total, i;
2293
2294 s = msg;
2295 STREAM_GETL(s, total);
2296
2297 for (i = 0; i < total; i++) {
2298 memset(&zpi, 0, sizeof(zpi));
2299
2300 zpi.sock = client->sock;
be2028d1 2301 zpi.vrf_id = zvrf->vrf->vrf_id;
bf094f69
QY
2302 STREAM_GETL(s, zpi.unique);
2303 STREAM_GETL(s, zpi.type);
2304 STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
2305
2306 if (hdr->command == ZEBRA_IPSET_CREATE)
62f20a52 2307 zebra_pbr_create_ipset(&zpi);
bf094f69 2308 else
62f20a52 2309 zebra_pbr_destroy_ipset(&zpi);
bf094f69
QY
2310 }
2311
2312stream_failure:
2313 return;
2314}
2315
2316static inline void zread_ipset_entry(ZAPI_HANDLER_ARGS)
2317{
2318 struct zebra_pbr_ipset_entry zpi;
2319 struct zebra_pbr_ipset ipset;
2320 struct stream *s;
2321 uint32_t total, i;
2322
2323 s = msg;
2324 STREAM_GETL(s, total);
2325
2326 for (i = 0; i < total; i++) {
2327 memset(&zpi, 0, sizeof(zpi));
2328 memset(&ipset, 0, sizeof(ipset));
2329
2330 zpi.sock = client->sock;
2331 STREAM_GETL(s, zpi.unique);
2332 STREAM_GET(&ipset.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
2333 STREAM_GETC(s, zpi.src.family);
2334 STREAM_GETC(s, zpi.src.prefixlen);
2335 STREAM_GET(&zpi.src.u.prefix, s, prefix_blen(&zpi.src));
2336 STREAM_GETC(s, zpi.dst.family);
2337 STREAM_GETC(s, zpi.dst.prefixlen);
2338 STREAM_GET(&zpi.dst.u.prefix, s, prefix_blen(&zpi.dst));
2339
25d760c5
PG
2340 STREAM_GETW(s, zpi.src_port_min);
2341 STREAM_GETW(s, zpi.src_port_max);
2342 STREAM_GETW(s, zpi.dst_port_min);
2343 STREAM_GETW(s, zpi.dst_port_max);
2344 STREAM_GETC(s, zpi.proto);
bf094f69
QY
2345 if (!is_default_prefix(&zpi.src))
2346 zpi.filter_bm |= PBR_FILTER_SRC_IP;
2347
2348 if (!is_default_prefix(&zpi.dst))
2349 zpi.filter_bm |= PBR_FILTER_DST_IP;
be729dd7 2350 if (zpi.dst_port_min != 0 || zpi.proto == IPPROTO_ICMP)
25d760c5 2351 zpi.filter_bm |= PBR_FILTER_DST_PORT;
be729dd7 2352 if (zpi.src_port_min != 0 || zpi.proto == IPPROTO_ICMP)
25d760c5
PG
2353 zpi.filter_bm |= PBR_FILTER_SRC_PORT;
2354 if (zpi.dst_port_max != 0)
2355 zpi.filter_bm |= PBR_FILTER_DST_PORT_RANGE;
2356 if (zpi.src_port_max != 0)
2357 zpi.filter_bm |= PBR_FILTER_SRC_PORT_RANGE;
2358 if (zpi.proto != 0)
2359 zpi.filter_bm |= PBR_FILTER_PROTO;
bf094f69
QY
2360
2361 /* calculate backpointer */
62f20a52
DS
2362 zpi.backpointer =
2363 zebra_pbr_lookup_ipset_pername(ipset.ipset_name);
bf094f69 2364 if (hdr->command == ZEBRA_IPSET_ENTRY_ADD)
62f20a52 2365 zebra_pbr_add_ipset_entry(&zpi);
bf094f69 2366 else
62f20a52 2367 zebra_pbr_del_ipset_entry(&zpi);
bf094f69
QY
2368 }
2369
2370stream_failure:
2371 return;
2372}
2373
2374static inline void zread_iptable(ZAPI_HANDLER_ARGS)
2375{
2376 struct zebra_pbr_iptable zpi;
2377 struct stream *s;
2378
2379 s = msg;
2380
2381 memset(&zpi, 0, sizeof(zpi));
2382
f80ec7e3 2383 zpi.interface_name_list = list_new();
bf094f69 2384 zpi.sock = client->sock;
be2028d1 2385 zpi.vrf_id = zvrf->vrf->vrf_id;
bf094f69
QY
2386 STREAM_GETL(s, zpi.unique);
2387 STREAM_GETL(s, zpi.type);
2388 STREAM_GETL(s, zpi.filter_bm);
2389 STREAM_GETL(s, zpi.action);
2390 STREAM_GETL(s, zpi.fwmark);
2391 STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
e7f7dad4
PG
2392 STREAM_GETW(s, zpi.pkt_len_min);
2393 STREAM_GETW(s, zpi.pkt_len_max);
dc993e76
PG
2394 STREAM_GETW(s, zpi.tcp_flags);
2395 STREAM_GETW(s, zpi.tcp_mask_flags);
4977bd6c 2396 STREAM_GETC(s, zpi.dscp_value);
5ac5b7cc 2397 STREAM_GETC(s, zpi.fragment);
f80ec7e3
PG
2398 STREAM_GETL(s, zpi.nb_interface);
2399 zebra_pbr_iptable_update_interfacelist(s, &zpi);
bf094f69
QY
2400
2401 if (hdr->command == ZEBRA_IPTABLE_ADD)
62f20a52 2402 zebra_pbr_add_iptable(&zpi);
bf094f69 2403 else
62f20a52 2404 zebra_pbr_del_iptable(&zpi);
bf094f69
QY
2405stream_failure:
2406 return;
2407}
2408
2409void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
2410 [ZEBRA_ROUTER_ID_ADD] = zread_router_id_add,
2411 [ZEBRA_ROUTER_ID_DELETE] = zread_router_id_delete,
2412 [ZEBRA_INTERFACE_ADD] = zread_interface_add,
2413 [ZEBRA_INTERFACE_DELETE] = zread_interface_delete,
2414 [ZEBRA_ROUTE_ADD] = zread_route_add,
2415 [ZEBRA_ROUTE_DELETE] = zread_route_del,
bf094f69
QY
2416 [ZEBRA_REDISTRIBUTE_ADD] = zebra_redistribute_add,
2417 [ZEBRA_REDISTRIBUTE_DELETE] = zebra_redistribute_delete,
2418 [ZEBRA_REDISTRIBUTE_DEFAULT_ADD] = zebra_redistribute_default_add,
2419 [ZEBRA_REDISTRIBUTE_DEFAULT_DELETE] = zebra_redistribute_default_delete,
2420 [ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB] = zread_ipv4_nexthop_lookup_mrib,
2421 [ZEBRA_HELLO] = zread_hello,
2422 [ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register,
2423 [ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister,
2424 [ZEBRA_IMPORT_ROUTE_REGISTER] = zread_rnh_register,
2425 [ZEBRA_IMPORT_ROUTE_UNREGISTER] = zread_rnh_unregister,
2426 [ZEBRA_BFD_DEST_UPDATE] = zebra_ptm_bfd_dst_register,
2427 [ZEBRA_BFD_DEST_REGISTER] = zebra_ptm_bfd_dst_register,
2428 [ZEBRA_BFD_DEST_DEREGISTER] = zebra_ptm_bfd_dst_deregister,
d3af6147
RZ
2429#if HAVE_BFDD > 0
2430 [ZEBRA_BFD_DEST_REPLAY] = zebra_ptm_bfd_dst_replay,
2431#endif /* HAVE_BFDD */
bf094f69
QY
2432 [ZEBRA_VRF_UNREGISTER] = zread_vrf_unregister,
2433 [ZEBRA_VRF_LABEL] = zread_vrf_label,
2434 [ZEBRA_BFD_CLIENT_REGISTER] = zebra_ptm_bfd_client_register,
2435#if defined(HAVE_RTADV)
2436 [ZEBRA_INTERFACE_ENABLE_RADV] = zebra_interface_radv_enable,
2437 [ZEBRA_INTERFACE_DISABLE_RADV] = zebra_interface_radv_disable,
2438#else
2439 [ZEBRA_INTERFACE_ENABLE_RADV] = NULL,
2440 [ZEBRA_INTERFACE_DISABLE_RADV] = NULL,
2441#endif
2442 [ZEBRA_MPLS_LABELS_ADD] = zread_mpls_labels,
2443 [ZEBRA_MPLS_LABELS_DELETE] = zread_mpls_labels,
2444 [ZEBRA_IPMR_ROUTE_STATS] = zebra_ipmr_route_stats,
2445 [ZEBRA_LABEL_MANAGER_CONNECT] = zread_label_manager_request,
f533be73 2446 [ZEBRA_LABEL_MANAGER_CONNECT_ASYNC] = zread_label_manager_request,
bf094f69
QY
2447 [ZEBRA_GET_LABEL_CHUNK] = zread_label_manager_request,
2448 [ZEBRA_RELEASE_LABEL_CHUNK] = zread_label_manager_request,
2449 [ZEBRA_FEC_REGISTER] = zread_fec_register,
2450 [ZEBRA_FEC_UNREGISTER] = zread_fec_unregister,
2451 [ZEBRA_ADVERTISE_DEFAULT_GW] = zebra_vxlan_advertise_gw_macip,
278e26de 2452 [ZEBRA_ADVERTISE_SVI_MACIP] = zebra_vxlan_advertise_svi_macip,
bf094f69
QY
2453 [ZEBRA_ADVERTISE_SUBNET] = zebra_vxlan_advertise_subnet,
2454 [ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni,
2455 [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add,
2456 [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del,
2457 [ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add,
2458 [ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del,
3950b52c 2459 [ZEBRA_DUPLICATE_ADDR_DETECTION] = zebra_vxlan_dup_addr_detection,
bf094f69
QY
2460 [ZEBRA_INTERFACE_SET_MASTER] = zread_interface_set_master,
2461 [ZEBRA_PW_ADD] = zread_pseudowire,
2462 [ZEBRA_PW_DELETE] = zread_pseudowire,
2463 [ZEBRA_PW_SET] = zread_pseudowire,
2464 [ZEBRA_PW_UNSET] = zread_pseudowire,
2465 [ZEBRA_RULE_ADD] = zread_rule,
2466 [ZEBRA_RULE_DELETE] = zread_rule,
2467 [ZEBRA_TABLE_MANAGER_CONNECT] = zread_table_manager_request,
2468 [ZEBRA_GET_TABLE_CHUNK] = zread_table_manager_request,
2469 [ZEBRA_RELEASE_TABLE_CHUNK] = zread_table_manager_request,
2470 [ZEBRA_IPSET_CREATE] = zread_ipset,
2471 [ZEBRA_IPSET_DESTROY] = zread_ipset,
2472 [ZEBRA_IPSET_ENTRY_ADD] = zread_ipset_entry,
2473 [ZEBRA_IPSET_ENTRY_DELETE] = zread_ipset_entry,
2474 [ZEBRA_IPTABLE_ADD] = zread_iptable,
2475 [ZEBRA_IPTABLE_DELETE] = zread_iptable,
fbac9605 2476 [ZEBRA_VXLAN_FLOOD_CONTROL] = zebra_vxlan_flood_control,
bf094f69
QY
2477};
2478
727c9b99
QY
2479#if defined(HANDLE_ZAPI_FUZZING)
2480extern struct zebra_privs_t zserv_privs;
2481
2482static void zserv_write_incoming(struct stream *orig, uint16_t command)
2483{
2484 char fname[MAXPATHLEN];
2485 struct stream *copy;
2486 int fd = -1;
2487
2488 copy = stream_dup(orig);
2489 stream_set_getp(copy, 0);
2490
727c9b99 2491 snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command);
6bb30c2c
DL
2492
2493 frr_elevate_privs(&zserv_privs) {
2494 fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
2495 }
727c9b99
QY
2496 stream_flush(copy, fd);
2497 close(fd);
727c9b99
QY
2498 stream_free(copy);
2499}
2500#endif
2501
904e0d88 2502void zserv_handle_commands(struct zserv *client, struct stream *msg)
bf094f69 2503{
904e0d88
QY
2504 struct zmsghdr hdr;
2505 struct zebra_vrf *zvrf;
2506
2507 zapi_parse_header(msg, &hdr);
bf094f69 2508
727c9b99
QY
2509#if defined(HANDLE_ZAPI_FUZZING)
2510 zserv_write_incoming(msg, hdr.command);
2511#endif
2512
904e0d88
QY
2513 hdr.length -= ZEBRA_HEADER_SIZE;
2514
2515 /* lookup vrf */
2516 zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
2517 if (!zvrf) {
2518 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
9df414fe
QY
2519 zlog_debug("ZAPI message specifies unknown VRF: %d",
2520 hdr.vrf_id);
904e0d88
QY
2521 return;
2522 }
2523
aa360de7 2524 if (hdr.command >= array_size(zserv_handlers)
904e0d88
QY
2525 || zserv_handlers[hdr.command] == NULL)
2526 zlog_info("Zebra received unknown command %d", hdr.command);
2527 else
2528 zserv_handlers[hdr.command](client, &hdr, msg, zvrf);
bf094f69 2529}