]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zapi_msg.c
zebra: header changes for l2 vni bum-mcast-grp handling
[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 1110 /* Anything not AF_INET/INET6 has been filtered out above */
906b54dd 1111 if (!exist || flag_changed)
73bf60a0
RW
1112 zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, type,
1113 &p);
dd25a6b3
DS
1114
1115 zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
bf094f69
QY
1116 }
1117
1118stream_failure:
1119 return;
1120}
1121
1122/* Nexthop register */
1123static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
1124{
1125 struct rnh *rnh;
1126 struct stream *s;
1127 struct prefix p;
1128 unsigned short l = 0;
1129 uint16_t type = cmd2type[hdr->command];
1130
1131 if (IS_ZEBRA_DEBUG_NHT)
1132 zlog_debug(
1133 "rnh_unregister msg from client %s: hdr->length=%d vrf: %u\n",
1134 zebra_route_string(client->proto), hdr->length,
1135 zvrf->vrf->vrf_id);
1136
1137 s = msg;
1138
1139 while (l < hdr->length) {
1140 uint8_t flags;
1141
1142 STREAM_GETC(s, flags);
1143 if (flags != 0)
1144 goto stream_failure;
1145
1146 STREAM_GETW(s, p.family);
1147 STREAM_GETC(s, p.prefixlen);
1148 l += 4;
1149 if (p.family == AF_INET) {
ab5990d8 1150 client->v4_nh_watch_rem_cnt++;
bf094f69 1151 if (p.prefixlen > IPV4_MAX_BITLEN) {
9df414fe 1152 zlog_debug(
bf094f69
QY
1153 "%s: Specified prefix hdr->length %d is to large for a v4 address",
1154 __PRETTY_FUNCTION__, p.prefixlen);
1155 return;
1156 }
1157 STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1158 l += IPV4_MAX_BYTELEN;
1159 } else if (p.family == AF_INET6) {
ab5990d8 1160 client->v6_nh_watch_rem_cnt++;
bf094f69 1161 if (p.prefixlen > IPV6_MAX_BITLEN) {
9df414fe 1162 zlog_debug(
bf094f69
QY
1163 "%s: Specified prefix hdr->length %d is to large for a v6 address",
1164 __PRETTY_FUNCTION__, p.prefixlen);
1165 return;
1166 }
1167 STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
1168 l += IPV6_MAX_BYTELEN;
1169 } else {
af4c2728 1170 flog_err(
e914ccbe 1171 EC_ZEBRA_UNKNOWN_FAMILY,
bf094f69
QY
1172 "rnh_register: Received unknown family type %d\n",
1173 p.family);
1174 return;
1175 }
1176 rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), type);
1177 if (rnh) {
1178 client->nh_dereg_time = monotime(NULL);
1179 zebra_remove_rnh_client(rnh, client, type);
1180 }
1181 }
1182stream_failure:
1183 return;
1184}
1185
1186#define ZEBRA_MIN_FEC_LENGTH 5
1187
1188/* FEC register */
1189static void zread_fec_register(ZAPI_HANDLER_ARGS)
1190{
1191 struct stream *s;
1192 unsigned short l = 0;
1193 struct prefix p;
1194 uint16_t flags;
57592a53 1195 uint32_t label = MPLS_INVALID_LABEL;
bf094f69
QY
1196 uint32_t label_index = MPLS_INVALID_LABEL_INDEX;
1197
1198 s = msg;
1199 zvrf = vrf_info_lookup(VRF_DEFAULT);
1200 if (!zvrf)
8b1766b1 1201 return;
bf094f69
QY
1202
1203 /*
1204 * The minimum amount of data that can be sent for one fec
1205 * registration
1206 */
1207 if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
af4c2728 1208 flog_err(
e914ccbe 1209 EC_ZEBRA_IRDP_LEN_MISMATCH,
bf094f69
QY
1210 "fec_register: Received a fec register of hdr->length %d, it is of insufficient size to properly decode",
1211 hdr->length);
1212 return;
1213 }
1214
1215 while (l < hdr->length) {
1216 STREAM_GETW(s, flags);
1217 memset(&p, 0, sizeof(p));
1218 STREAM_GETW(s, p.family);
1219 if (p.family != AF_INET && p.family != AF_INET6) {
af4c2728 1220 flog_err(
e914ccbe 1221 EC_ZEBRA_UNKNOWN_FAMILY,
bf094f69
QY
1222 "fec_register: Received unknown family type %d\n",
1223 p.family);
1224 return;
1225 }
1226 STREAM_GETC(s, p.prefixlen);
1227 if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
1228 || (p.family == AF_INET6
1229 && p.prefixlen > IPV6_MAX_BITLEN)) {
9df414fe 1230 zlog_debug(
bf094f69
QY
1231 "%s: Specified prefix hdr->length: %d is to long for %d",
1232 __PRETTY_FUNCTION__, p.prefixlen, p.family);
1233 return;
1234 }
1235 l += 5;
1236 STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
1237 l += PSIZE(p.prefixlen);
57592a53
AD
1238 if (flags & ZEBRA_FEC_REGISTER_LABEL) {
1239 STREAM_GETL(s, label);
1240 l += 4;
1241 } else if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) {
bf094f69
QY
1242 STREAM_GETL(s, label_index);
1243 l += 4;
57592a53
AD
1244 }
1245
1246 zebra_mpls_fec_register(zvrf, &p, label, label_index, client);
bf094f69
QY
1247 }
1248
1249stream_failure:
1250 return;
1251}
1252
1253/* FEC unregister */
1254static void zread_fec_unregister(ZAPI_HANDLER_ARGS)
1255{
1256 struct stream *s;
1257 unsigned short l = 0;
1258 struct prefix p;
1259 uint16_t flags;
1260
1261 s = msg;
1262 zvrf = vrf_info_lookup(VRF_DEFAULT);
1263 if (!zvrf)
8b1766b1 1264 return;
bf094f69
QY
1265
1266 /*
1267 * The minimum amount of data that can be sent for one
1268 * fec unregistration
1269 */
1270 if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
af4c2728 1271 flog_err(
e914ccbe 1272 EC_ZEBRA_IRDP_LEN_MISMATCH,
bf094f69
QY
1273 "fec_unregister: Received a fec unregister of hdr->length %d, it is of insufficient size to properly decode",
1274 hdr->length);
1275 return;
1276 }
1277
1278 while (l < hdr->length) {
1279 STREAM_GETW(s, flags);
1280 if (flags != 0)
1281 goto stream_failure;
1282
1283 memset(&p, 0, sizeof(p));
1284 STREAM_GETW(s, p.family);
1285 if (p.family != AF_INET && p.family != AF_INET6) {
af4c2728 1286 flog_err(
e914ccbe 1287 EC_ZEBRA_UNKNOWN_FAMILY,
bf094f69
QY
1288 "fec_unregister: Received unknown family type %d\n",
1289 p.family);
1290 return;
1291 }
1292 STREAM_GETC(s, p.prefixlen);
1293 if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
1294 || (p.family == AF_INET6
1295 && p.prefixlen > IPV6_MAX_BITLEN)) {
9df414fe 1296 zlog_debug(
bf094f69
QY
1297 "%s: Received prefix hdr->length %d which is greater than %d can support",
1298 __PRETTY_FUNCTION__, p.prefixlen, p.family);
1299 return;
1300 }
1301 l += 5;
1302 STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
1303 l += PSIZE(p.prefixlen);
1304 zebra_mpls_fec_unregister(zvrf, &p, client);
1305 }
1306
1307stream_failure:
1308 return;
1309}
1310
1311
1312/*
1313 * Register zebra server interface information.
1314 * Send current all interface and address information.
1315 */
1316static void zread_interface_add(ZAPI_HANDLER_ARGS)
1317{
1318 struct vrf *vrf;
1319 struct interface *ifp;
1320
bf094f69
QY
1321 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
1322 FOR_ALL_INTERFACES (vrf, ifp) {
1323 /* Skip pseudo interface. */
1324 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
1325 continue;
1326
1327 zsend_interface_add(client, ifp);
27ecbea3 1328 zsend_interface_link_params(client, ifp);
bf094f69
QY
1329 zsend_interface_addresses(client, ifp);
1330 }
1331 }
1332}
1333
1334/* Unregister zebra server interface information. */
1335static void zread_interface_delete(ZAPI_HANDLER_ARGS)
1336{
bf094f69
QY
1337}
1338
1339void zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
1340 const unsigned int nexthop_num)
1341{
1342 if (nexthop_num > multipath_num) {
1343 char buff[PREFIX2STR_BUFFER];
8b1766b1 1344
bf094f69 1345 prefix2str(p, buff, sizeof(buff));
9df414fe 1346 flog_warn(
e914ccbe 1347 EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
bf094f69
QY
1348 "%s: Prefix %s has %d nexthops, but we can only use the first %d",
1349 caller, buff, nexthop_num, multipath_num);
1350 }
1351}
1352
1353static void zread_route_add(ZAPI_HANDLER_ARGS)
1354{
1355 struct stream *s;
1356 struct zapi_route api;
1357 struct zapi_nexthop *api_nh;
1358 afi_t afi;
1359 struct prefix_ipv6 *src_p = NULL;
1360 struct route_entry *re;
1361 struct nexthop *nexthop = NULL;
1362 int i, ret;
1363 vrf_id_t vrf_id = 0;
1364 struct ipaddr vtep_ip;
1365
1366 s = msg;
1367 if (zapi_route_decode(s, &api) < 0) {
1368 if (IS_ZEBRA_DEBUG_RECV)
1369 zlog_debug("%s: Unable to decode zapi_route sent",
1370 __PRETTY_FUNCTION__);
1371 return;
1372 }
1373
1374 if (IS_ZEBRA_DEBUG_RECV) {
1375 char buf_prefix[PREFIX_STRLEN];
8b1766b1 1376
bf094f69
QY
1377 prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
1378 zlog_debug("%s: p=%s, ZAPI_MESSAGE_LABEL: %sset, flags=0x%x",
1379 __func__, buf_prefix,
1380 (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL) ? ""
1381 : "un"),
1382 api.flags);
1383 }
1384
1385 /* Allocate new route. */
1386 vrf_id = zvrf_id(zvrf);
1387 re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
1388 re->type = api.type;
1389 re->instance = api.instance;
1390 re->flags = api.flags;
1391 re->uptime = time(NULL);
1392 re->vrf_id = vrf_id;
1393 if (api.tableid && vrf_id == VRF_DEFAULT)
1394 re->table = api.tableid;
1395 else
1396 re->table = zvrf->table_id;
1397
7fcb24bb
RW
1398 if (!CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)
1399 || api.nexthop_num == 0) {
1400 char buf_prefix[PREFIX_STRLEN];
1401
1402 prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
1403 flog_warn(EC_ZEBRA_RX_ROUTE_NO_NEXTHOPS,
1404 "%s: received a route without nexthops for prefix %s",
1405 __func__, buf_prefix);
1406 XFREE(MTYPE_RE, re);
1407 return;
1408 }
1409
bf094f69
QY
1410 /*
1411 * TBD should _all_ of the nexthop add operations use
1412 * api_nh->vrf_id instead of re->vrf_id ? I only changed
1413 * for cases NEXTHOP_TYPE_IPV4 and NEXTHOP_TYPE_IPV6.
1414 */
7fcb24bb
RW
1415 for (i = 0; i < api.nexthop_num; i++) {
1416 api_nh = &api.nexthops[i];
1417 ifindex_t ifindex = 0;
1418
1419 if (IS_ZEBRA_DEBUG_RECV)
1420 zlog_debug("nh type %d", api_nh->type);
1421
1422 switch (api_nh->type) {
1423 case NEXTHOP_TYPE_IFINDEX:
1424 nexthop = route_entry_nexthop_ifindex_add(
1425 re, api_nh->ifindex, api_nh->vrf_id);
1426 break;
1427 case NEXTHOP_TYPE_IPV4:
1428 if (IS_ZEBRA_DEBUG_RECV) {
1429 char nhbuf[INET6_ADDRSTRLEN] = {0};
1430
1431 inet_ntop(AF_INET, &api_nh->gate.ipv4, nhbuf,
1432 INET6_ADDRSTRLEN);
1433 zlog_debug("%s: nh=%s, vrf_id=%d", __func__,
1434 nhbuf, api_nh->vrf_id);
1435 }
1436 nexthop = route_entry_nexthop_ipv4_add(
1437 re, &api_nh->gate.ipv4, NULL, api_nh->vrf_id);
1438 break;
1439 case NEXTHOP_TYPE_IPV4_IFINDEX:
1440
1441 memset(&vtep_ip, 0, sizeof(struct ipaddr));
e1e71450 1442 ifindex = api_nh->ifindex;
7fcb24bb
RW
1443 if (IS_ZEBRA_DEBUG_RECV) {
1444 char nhbuf[INET6_ADDRSTRLEN] = {0};
1445
1446 inet_ntop(AF_INET, &api_nh->gate.ipv4, nhbuf,
1447 INET6_ADDRSTRLEN);
1448 zlog_debug(
1449 "%s: nh=%s, vrf_id=%d (re->vrf_id=%d), ifindex=%d",
1450 __func__, nhbuf, api_nh->vrf_id,
1451 re->vrf_id, ifindex);
bf094f69 1452 }
7fcb24bb
RW
1453 nexthop = route_entry_nexthop_ipv4_ifindex_add(
1454 re, &api_nh->gate.ipv4, NULL, ifindex,
1455 api_nh->vrf_id);
1456
2b83602b 1457 /* Special handling for IPv4 routes sourced from EVPN:
1458 * the nexthop and associated MAC need to be installed.
7fcb24bb
RW
1459 */
1460 if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
7fcb24bb
RW
1461 vtep_ip.ipa_type = IPADDR_V4;
1462 memcpy(&(vtep_ip.ipaddr_v4),
1463 &(api_nh->gate.ipv4),
1464 sizeof(struct in_addr));
1465 zebra_vxlan_evpn_vrf_route_add(
744c63be 1466 api_nh->vrf_id, &api_nh->rmac,
1467 &vtep_ip, &api.prefix);
bf094f69 1468 }
7fcb24bb
RW
1469 break;
1470 case NEXTHOP_TYPE_IPV6:
1471 nexthop = route_entry_nexthop_ipv6_add(
1472 re, &api_nh->gate.ipv6, api_nh->vrf_id);
1473 break;
1474 case NEXTHOP_TYPE_IPV6_IFINDEX:
1475 memset(&vtep_ip, 0, sizeof(struct ipaddr));
e1e71450 1476 ifindex = api_nh->ifindex;
7fcb24bb
RW
1477 nexthop = route_entry_nexthop_ipv6_ifindex_add(
1478 re, &api_nh->gate.ipv6, ifindex,
1479 api_nh->vrf_id);
1480
2b83602b 1481 /* Special handling for IPv6 routes sourced from EVPN:
1482 * the nexthop and associated MAC need to be installed.
7fcb24bb
RW
1483 */
1484 if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
7fcb24bb
RW
1485 vtep_ip.ipa_type = IPADDR_V6;
1486 memcpy(&vtep_ip.ipaddr_v6, &(api_nh->gate.ipv6),
1487 sizeof(struct in6_addr));
1488 zebra_vxlan_evpn_vrf_route_add(
744c63be 1489 api_nh->vrf_id, &api_nh->rmac,
1490 &vtep_ip, &api.prefix);
7fcb24bb
RW
1491 }
1492 break;
1493 case NEXTHOP_TYPE_BLACKHOLE:
1494 nexthop = route_entry_nexthop_blackhole_add(
1495 re, api_nh->bh_type);
1496 break;
bf094f69 1497 }
bf094f69 1498
7fcb24bb
RW
1499 if (!nexthop) {
1500 flog_warn(
1501 EC_ZEBRA_NEXTHOP_CREATION_FAILED,
1502 "%s: Nexthops Specified: %d but we failed to properly create one",
1503 __PRETTY_FUNCTION__, api.nexthop_num);
1504 nexthops_free(re->ng.nexthop);
1505 XFREE(MTYPE_RE, re);
1506 return;
1507 }
fe85601c
DS
1508 if (api_nh->onlink)
1509 SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
1510
7fcb24bb
RW
1511 /* MPLS labels for BGP-LU or Segment Routing */
1512 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)
1513 && api_nh->type != NEXTHOP_TYPE_IFINDEX
1514 && api_nh->type != NEXTHOP_TYPE_BLACKHOLE) {
1515 enum lsp_types_t label_type;
1516
1517 label_type = lsp_type_from_re_type(client->proto);
1518
1519 if (IS_ZEBRA_DEBUG_RECV) {
1520 zlog_debug(
1521 "%s: adding %d labels of type %d (1st=%u)",
1522 __func__, api_nh->label_num, label_type,
1523 api_nh->labels[0]);
1524 }
1525
1526 nexthop_add_labels(nexthop, label_type,
1527 api_nh->label_num,
1528 &api_nh->labels[0]);
1529 }
1530 }
1531
bf094f69
QY
1532 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
1533 re->distance = api.distance;
1534 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
1535 re->metric = api.metric;
1536 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG))
1537 re->tag = api.tag;
1538 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_MTU))
1539 re->mtu = api.mtu;
1540
1541 afi = family2afi(api.prefix.family);
1542 if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
e914ccbe 1543 flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
9df414fe 1544 "%s: Received SRC Prefix but afi is not v6",
bf094f69
QY
1545 __PRETTY_FUNCTION__);
1546 nexthops_free(re->ng.nexthop);
1547 XFREE(MTYPE_RE, re);
1548 return;
1549 }
1550 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
1551 src_p = &api.src_prefix;
1552
1553 ret = rib_add_multipath(afi, api.safi, &api.prefix, src_p, re);
1554
1555 /* Stats */
1556 switch (api.prefix.family) {
1557 case AF_INET:
1558 if (ret > 0)
1559 client->v4_route_add_cnt++;
1560 else if (ret < 0)
1561 client->v4_route_upd8_cnt++;
1562 break;
1563 case AF_INET6:
1564 if (ret > 0)
1565 client->v6_route_add_cnt++;
1566 else if (ret < 0)
1567 client->v6_route_upd8_cnt++;
1568 break;
1569 }
1570}
1571
1572static void zread_route_del(ZAPI_HANDLER_ARGS)
1573{
1574 struct stream *s;
1575 struct zapi_route api;
1576 afi_t afi;
1577 struct prefix_ipv6 *src_p = NULL;
1578 uint32_t table_id;
1579
1580 s = msg;
1581 if (zapi_route_decode(s, &api) < 0)
1582 return;
1583
1584 afi = family2afi(api.prefix.family);
1585 if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
e914ccbe 1586 flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
9df414fe 1587 "%s: Received a src prefix while afi is not v6",
bf094f69
QY
1588 __PRETTY_FUNCTION__);
1589 return;
1590 }
1591 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
1592 src_p = &api.src_prefix;
1593
1594 if (api.vrf_id == VRF_DEFAULT && api.tableid != 0)
1595 table_id = api.tableid;
1596 else
1597 table_id = zvrf->table_id;
1598
1599 rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
1600 api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
40ecd8e4 1601 api.distance, false);
bf094f69
QY
1602
1603 /* Stats */
1604 switch (api.prefix.family) {
1605 case AF_INET:
1606 client->v4_route_del_cnt++;
1607 break;
1608 case AF_INET6:
1609 client->v6_route_del_cnt++;
1610 break;
1611 }
1612}
1613
bf094f69
QY
1614/* MRIB Nexthop lookup for IPv4. */
1615static void zread_ipv4_nexthop_lookup_mrib(ZAPI_HANDLER_ARGS)
1616{
1617 struct in_addr addr;
1618 struct route_entry *re;
1619
1620 STREAM_GET(&addr.s_addr, msg, IPV4_MAX_BYTELEN);
1621 re = rib_match_ipv4_multicast(zvrf_id(zvrf), addr, NULL);
1622 zsend_ipv4_nexthop_lookup_mrib(client, addr, re, zvrf);
1623
1624stream_failure:
1625 return;
1626}
1627
bf094f69
QY
1628/* Register zebra server router-id information. Send current router-id */
1629static void zread_router_id_add(ZAPI_HANDLER_ARGS)
1630{
1631 struct prefix p;
1632
1633 /* Router-id information is needed. */
1634 vrf_bitmap_set(client->ridinfo, zvrf_id(zvrf));
1635
1636 router_id_get(&p, zvrf_id(zvrf));
1637
1638 zsend_router_id_update(client, &p, zvrf_id(zvrf));
1639}
1640
1641/* Unregister zebra server router-id information. */
1642static void zread_router_id_delete(ZAPI_HANDLER_ARGS)
1643{
1644 vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
1645}
1646
1647static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
1648{
1649 struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1650
1651 zclient_create_header(s, ZEBRA_CAPABILITIES, zvrf->vrf->vrf_id);
bb6b7f79 1652 stream_putl(s, vrf_get_backend());
bf094f69
QY
1653 stream_putc(s, mpls_enabled);
1654 stream_putl(s, multipath_num);
02c0866d 1655 stream_putc(s, zebra_mlag_get_role());
bf094f69
QY
1656
1657 stream_putw_at(s, 0, stream_get_endp(s));
21ccc0cf 1658 zserv_send_message(client, s);
bf094f69
QY
1659}
1660
b120fe3b
DS
1661void zsend_capabilities_all_clients(void)
1662{
1663 struct listnode *node, *nnode;
1664 struct zebra_vrf *zvrf;
1665 struct zserv *client;
1666
1667 zvrf = vrf_info_lookup(VRF_DEFAULT);
1668 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
1669 zsend_capabilities(client, zvrf);
1670 }
1671}
1672
bf094f69
QY
1673/* Tie up route-type and client->sock */
1674static void zread_hello(ZAPI_HANDLER_ARGS)
1675{
1676 /* type of protocol (lib/zebra.h) */
1677 uint8_t proto;
1678 unsigned short instance;
1679 uint8_t notify;
1680
1681 STREAM_GETC(msg, proto);
1682 STREAM_GETW(msg, instance);
1683 STREAM_GETC(msg, notify);
1684 if (notify)
1685 client->notify_owner = true;
1686
1687 /* accept only dynamic routing protocols */
f23cbcda 1688 if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_CONNECT)) {
bf094f69
QY
1689 zlog_notice(
1690 "client %d says hello and bids fair to announce only %s routes vrf=%u",
1691 client->sock, zebra_route_string(proto),
1692 zvrf->vrf->vrf_id);
1693 if (instance)
1694 zlog_notice("client protocol instance %d", instance);
1695
1696 client->proto = proto;
1697 client->instance = instance;
1698 }
1699
1700 zsend_capabilities(client, zvrf);
bb6b7f79 1701 zebra_vrf_update_all(client);
bf094f69
QY
1702stream_failure:
1703 return;
1704}
1705
1706/* Unregister all information in a VRF. */
1707static void zread_vrf_unregister(ZAPI_HANDLER_ARGS)
1708{
1709 int i;
1710 afi_t afi;
1711
49db7a7b 1712 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
bf094f69
QY
1713 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
1714 vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf));
49db7a7b
RW
1715 vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
1716 }
bf094f69
QY
1717 vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
1718}
1719
1720static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
1721{
1722 struct stream *s;
1723 enum lsp_types_t type;
1724 struct prefix prefix;
1725 enum nexthop_types_t gtype;
1726 union g_addr gate;
1727 ifindex_t ifindex;
1728 mpls_label_t in_label, out_label;
1729 uint8_t distance;
1730
1731 /* Get input stream. */
1732 s = msg;
1733
1734 /* Get data. */
1735 STREAM_GETC(s, type);
1736 STREAM_GETL(s, prefix.family);
1737 switch (prefix.family) {
1738 case AF_INET:
1739 STREAM_GET(&prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1740 STREAM_GETC(s, prefix.prefixlen);
1741 if (prefix.prefixlen > IPV4_MAX_BITLEN) {
9df414fe 1742 zlog_debug(
bf094f69
QY
1743 "%s: Specified prefix length %d is greater than a v4 address can support",
1744 __PRETTY_FUNCTION__, prefix.prefixlen);
1745 return;
1746 }
1747 STREAM_GET(&gate.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
1748 break;
1749 case AF_INET6:
1750 STREAM_GET(&prefix.u.prefix6, s, 16);
1751 STREAM_GETC(s, prefix.prefixlen);
1752 if (prefix.prefixlen > IPV6_MAX_BITLEN) {
9df414fe 1753 zlog_debug(
bf094f69
QY
1754 "%s: Specified prefix length %d is greater than a v6 address can support",
1755 __PRETTY_FUNCTION__, prefix.prefixlen);
1756 return;
1757 }
1758 STREAM_GET(&gate.ipv6, s, 16);
1759 break;
1760 default:
9df414fe
QY
1761 zlog_debug("%s: Specified AF %d is not supported for this call",
1762 __PRETTY_FUNCTION__, prefix.family);
bf094f69
QY
1763 return;
1764 }
1765 STREAM_GETL(s, ifindex);
1766 STREAM_GETC(s, distance);
1767 STREAM_GETL(s, in_label);
1768 STREAM_GETL(s, out_label);
1769
1770 switch (prefix.family) {
1771 case AF_INET:
1772 if (ifindex)
1773 gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
1774 else
1775 gtype = NEXTHOP_TYPE_IPV4;
1776 break;
1777 case AF_INET6:
1778 if (ifindex)
1779 gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
1780 else
1781 gtype = NEXTHOP_TYPE_IPV6;
1782 break;
1783 default:
1784 return;
1785 }
1786
1787 if (!mpls_enabled)
1788 return;
1789
1790 if (hdr->command == ZEBRA_MPLS_LABELS_ADD) {
1791 mpls_lsp_install(zvrf, type, in_label, out_label, gtype, &gate,
1792 ifindex);
1793 mpls_ftn_update(1, zvrf, type, &prefix, gtype, &gate, ifindex,
1794 distance, out_label);
1795 } else if (hdr->command == ZEBRA_MPLS_LABELS_DELETE) {
1796 mpls_lsp_uninstall(zvrf, type, in_label, gtype, &gate, ifindex);
1797 mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, ifindex,
1798 distance, out_label);
1799 }
1800stream_failure:
1801 return;
1802}
1803
1804/* Send response to a table manager connect request to client */
1805static void zread_table_manager_connect(struct zserv *client,
1806 struct stream *msg, vrf_id_t vrf_id)
1807{
1808 struct stream *s;
1809 uint8_t proto;
1810 uint16_t instance;
1811
1812 s = msg;
1813
1814 /* Get data. */
1815 STREAM_GETC(s, proto);
1816 STREAM_GETW(s, instance);
1817
1818 /* accept only dynamic routing protocols */
1819 if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
e914ccbe 1820 flog_err(EC_ZEBRA_TM_WRONG_PROTO,
1c50c1c0
QY
1821 "client %d has wrong protocol %s", client->sock,
1822 zebra_route_string(proto));
bf094f69
QY
1823 zsend_table_manager_connect_response(client, vrf_id, 1);
1824 return;
1825 }
1826 zlog_notice("client %d with vrf %u instance %u connected as %s",
1827 client->sock, vrf_id, instance, zebra_route_string(proto));
1828 client->proto = proto;
1829 client->instance = instance;
1830
1831 /*
1832 * Release previous labels of same protocol and instance.
1833 * This is done in case it restarted from an unexpected shutdown.
1834 */
453844ab 1835 release_daemon_table_chunks(client);
bf094f69
QY
1836
1837 zsend_table_manager_connect_response(client, vrf_id, 0);
1838
1839stream_failure:
1840 return;
1841}
1842
1843static void zread_label_manager_connect(struct zserv *client,
1844 struct stream *msg, vrf_id_t vrf_id)
1845{
1846 struct stream *s;
1847 /* type of protocol (lib/zebra.h) */
1848 uint8_t proto;
1849 unsigned short instance;
1850
1851 /* Get input stream. */
1852 s = msg;
1853
1854 /* Get data. */
1855 STREAM_GETC(s, proto);
1856 STREAM_GETW(s, instance);
1857
1858 /* accept only dynamic routing protocols */
1859 if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
e914ccbe 1860 flog_err(EC_ZEBRA_TM_WRONG_PROTO,
1c50c1c0
QY
1861 "client %d has wrong protocol %s", client->sock,
1862 zebra_route_string(proto));
f533be73 1863 if (client->is_synchronous)
1864 zsend_label_manager_connect_response(client, vrf_id, 1);
bf094f69
QY
1865 return;
1866 }
1867 zlog_notice("client %d with vrf %u instance %u connected as %s",
1868 client->sock, vrf_id, instance, zebra_route_string(proto));
1869 client->proto = proto;
1870 client->instance = instance;
1871
1872 /*
453844ab
QY
1873 * Release previous labels of same protocol and instance.
1874 * This is done in case it restarted from an unexpected shutdown.
1875 */
1876 release_daemon_label_chunks(client);
bf094f69
QY
1877
1878 zlog_debug(
1879 " Label Manager client connected: sock %d, proto %s, vrf %u instance %u",
1880 client->sock, zebra_route_string(proto), vrf_id, instance);
1881 /* send response back */
f533be73 1882 if (client->is_synchronous)
1883 zsend_label_manager_connect_response(client, vrf_id, 0);
bf094f69
QY
1884
1885stream_failure:
1886 return;
1887}
1888
1889static void zread_get_label_chunk(struct zserv *client, struct stream *msg,
1890 vrf_id_t vrf_id)
1891{
1892 struct stream *s;
1893 uint8_t keep;
1894 uint32_t size;
1895 struct label_manager_chunk *lmc;
5dffb0e9
FR
1896 uint8_t proto;
1897 unsigned short instance;
bf094f69
QY
1898
1899 /* Get input stream. */
1900 s = msg;
1901
1902 /* Get data. */
5dffb0e9
FR
1903 STREAM_GETC(s, proto);
1904 STREAM_GETW(s, instance);
bf094f69
QY
1905 STREAM_GETC(s, keep);
1906 STREAM_GETL(s, size);
1907
f533be73 1908 lmc = assign_label_chunk(proto, instance, keep, size);
bf094f69 1909 if (!lmc)
af4c2728 1910 flog_err(
e914ccbe 1911 EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK,
0313523d 1912 "Unable to assign Label Chunk of size %u to %s instance %u",
f533be73 1913 size, zebra_route_string(proto), instance);
bf094f69 1914 else
0313523d
FR
1915 zlog_debug("Assigned Label Chunk %u - %u to %s instance %u",
1916 lmc->start, lmc->end,
f533be73 1917 zebra_route_string(proto), instance);
bf094f69
QY
1918 /* send response back */
1919 zsend_assign_label_chunk_response(client, vrf_id, lmc);
1920
1921stream_failure:
1922 return;
1923}
1924
1925static void zread_release_label_chunk(struct zserv *client, struct stream *msg)
1926{
1927 struct stream *s;
1928 uint32_t start, end;
5dffb0e9
FR
1929 uint8_t proto;
1930 unsigned short instance;
bf094f69
QY
1931
1932 /* Get input stream. */
1933 s = msg;
1934
1935 /* Get data. */
5dffb0e9
FR
1936 STREAM_GETC(s, proto);
1937 STREAM_GETW(s, instance);
bf094f69
QY
1938 STREAM_GETL(s, start);
1939 STREAM_GETL(s, end);
1940
f533be73 1941 release_label_chunk(proto, instance, start, end);
bf094f69
QY
1942
1943stream_failure:
1944 return;
1945}
1946static void zread_label_manager_request(ZAPI_HANDLER_ARGS)
1947{
1948 /* to avoid sending other messages like ZERBA_INTERFACE_UP */
f533be73 1949 client->is_synchronous = hdr->command ==
1950 ZEBRA_LABEL_MANAGER_CONNECT;
bf094f69
QY
1951
1952 /* external label manager */
1953 if (lm_is_external)
0313523d 1954 zread_relay_label_manager_request(hdr->command, client, msg,
bf094f69
QY
1955 zvrf_id(zvrf));
1956 /* this is a label manager */
1957 else {
f533be73 1958 if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT ||
1959 hdr->command == ZEBRA_LABEL_MANAGER_CONNECT_ASYNC)
bf094f69
QY
1960 zread_label_manager_connect(client, msg, zvrf_id(zvrf));
1961 else {
bf094f69
QY
1962 if (hdr->command == ZEBRA_GET_LABEL_CHUNK)
1963 zread_get_label_chunk(client, msg,
1964 zvrf_id(zvrf));
1965 else if (hdr->command == ZEBRA_RELEASE_LABEL_CHUNK)
1966 zread_release_label_chunk(client, msg);
1967 }
1968 }
1969}
1970
1971static void zread_get_table_chunk(struct zserv *client, struct stream *msg,
1972 vrf_id_t vrf_id)
1973{
1974 struct stream *s;
1975 uint32_t size;
1976 struct table_manager_chunk *tmc;
1977
1978 /* Get input stream. */
1979 s = msg;
1980
1981 /* Get data. */
1982 STREAM_GETL(s, size);
1983
1984 tmc = assign_table_chunk(client->proto, client->instance, size);
1985 if (!tmc)
e914ccbe 1986 flog_err(EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
1c50c1c0
QY
1987 "%s: Unable to assign Table Chunk of size %u",
1988 __func__, size);
bf094f69
QY
1989 else
1990 zlog_debug("Assigned Table Chunk %u - %u", tmc->start,
1991 tmc->end);
1992 /* send response back */
1993 zsend_assign_table_chunk_response(client, vrf_id, tmc);
1994
1995stream_failure:
1996 return;
1997}
1998
1999static void zread_release_table_chunk(struct zserv *client, struct stream *msg)
2000{
2001 struct stream *s;
2002 uint32_t start, end;
2003
2004 /* Get input stream. */
2005 s = msg;
2006
2007 /* Get data. */
2008 STREAM_GETL(s, start);
2009 STREAM_GETL(s, end);
2010
2011 release_table_chunk(client->proto, client->instance, start, end);
2012
2013stream_failure:
2014 return;
2015}
2016
2017static void zread_table_manager_request(ZAPI_HANDLER_ARGS)
2018{
2019 /* to avoid sending other messages like ZERBA_INTERFACE_UP */
2020 if (hdr->command == ZEBRA_TABLE_MANAGER_CONNECT)
2021 zread_table_manager_connect(client, msg, zvrf_id(zvrf));
2022 else {
2023 /* Sanity: don't allow 'unidentified' requests */
2024 if (!client->proto) {
af4c2728 2025 flog_err(
e914ccbe 2026 EC_ZEBRA_TM_ALIENS,
bf094f69
QY
2027 "Got table request from an unidentified client");
2028 return;
2029 }
2030 if (hdr->command == ZEBRA_GET_TABLE_CHUNK)
2031 zread_get_table_chunk(client, msg, zvrf_id(zvrf));
2032 else if (hdr->command == ZEBRA_RELEASE_TABLE_CHUNK)
2033 zread_release_table_chunk(client, msg);
2034 }
2035}
2036
2037static void zread_pseudowire(ZAPI_HANDLER_ARGS)
2038{
2039 struct stream *s;
2040 char ifname[IF_NAMESIZE];
2041 ifindex_t ifindex;
2042 int type;
2043 int af;
2044 union g_addr nexthop;
2045 uint32_t local_label;
2046 uint32_t remote_label;
2047 uint8_t flags;
2048 union pw_protocol_fields data;
2049 uint8_t protocol;
2050 struct zebra_pw *pw;
2051
2052 /* Get input stream. */
2053 s = msg;
2054
2055 /* Get data. */
2056 STREAM_GET(ifname, s, IF_NAMESIZE);
2057 STREAM_GETL(s, ifindex);
2058 STREAM_GETL(s, type);
2059 STREAM_GETL(s, af);
2060 switch (af) {
2061 case AF_INET:
2062 STREAM_GET(&nexthop.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
2063 break;
2064 case AF_INET6:
2065 STREAM_GET(&nexthop.ipv6, s, 16);
2066 break;
2067 default:
2068 return;
2069 }
2070 STREAM_GETL(s, local_label);
2071 STREAM_GETL(s, remote_label);
2072 STREAM_GETC(s, flags);
2073 STREAM_GET(&data, s, sizeof(data));
2074 protocol = client->proto;
2075
2076 pw = zebra_pw_find(zvrf, ifname);
2077 switch (hdr->command) {
2078 case ZEBRA_PW_ADD:
2079 if (pw) {
e914ccbe 2080 flog_warn(EC_ZEBRA_PSEUDOWIRE_EXISTS,
9df414fe 2081 "%s: pseudowire %s already exists [%s]",
bf094f69
QY
2082 __func__, ifname,
2083 zserv_command_string(hdr->command));
2084 return;
2085 }
2086
2087 zebra_pw_add(zvrf, ifname, protocol, client);
2088 break;
2089 case ZEBRA_PW_DELETE:
2090 if (!pw) {
e914ccbe 2091 flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
9df414fe 2092 "%s: pseudowire %s not found [%s]", __func__,
bf094f69
QY
2093 ifname, zserv_command_string(hdr->command));
2094 return;
2095 }
2096
2097 zebra_pw_del(zvrf, pw);
2098 break;
2099 case ZEBRA_PW_SET:
2100 case ZEBRA_PW_UNSET:
2101 if (!pw) {
e914ccbe 2102 flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
9df414fe 2103 "%s: pseudowire %s not found [%s]", __func__,
bf094f69
QY
2104 ifname, zserv_command_string(hdr->command));
2105 return;
2106 }
2107
2108 switch (hdr->command) {
2109 case ZEBRA_PW_SET:
2110 pw->enabled = 1;
2111 break;
2112 case ZEBRA_PW_UNSET:
2113 pw->enabled = 0;
2114 break;
2115 }
2116
2117 zebra_pw_change(pw, ifindex, type, af, &nexthop, local_label,
2118 remote_label, flags, &data);
2119 break;
2120 }
2121
2122stream_failure:
2123 return;
2124}
2125
2126static void zread_interface_set_master(ZAPI_HANDLER_ARGS)
2127{
2128 struct interface *master;
2129 struct interface *slave;
2130 struct stream *s = msg;
2131 int ifindex;
2132 vrf_id_t vrf_id;
2133
2134 STREAM_GETL(s, vrf_id);
2135 STREAM_GETL(s, ifindex);
2136 master = if_lookup_by_index(ifindex, vrf_id);
2137
2138 STREAM_GETL(s, vrf_id);
2139 STREAM_GETL(s, ifindex);
2140 slave = if_lookup_by_index(ifindex, vrf_id);
2141
2142 if (!master || !slave)
2143 return;
2144
2145 kernel_interface_set_master(master, slave);
2146
2147stream_failure:
2148 return;
2149}
2150
2151
2152static void zread_vrf_label(ZAPI_HANDLER_ARGS)
2153{
2154 struct interface *ifp;
2155 mpls_label_t nlabel;
2156 afi_t afi;
2157 struct stream *s;
2158 struct zebra_vrf *def_zvrf;
2159 enum lsp_types_t ltype;
2160
2161 s = msg;
2162 STREAM_GETL(s, nlabel);
2163 STREAM_GETC(s, afi);
2164 if (nlabel == zvrf->label[afi]) {
2165 /*
2166 * Nothing to do here move along
2167 */
2168 return;
2169 }
2170
2171 STREAM_GETC(s, ltype);
2172
2173 if (zvrf->vrf->vrf_id != VRF_DEFAULT)
2174 ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id);
2175 else
2176 ifp = if_lookup_by_name("lo", VRF_DEFAULT);
2177
2178 if (!ifp) {
2179 zlog_debug("Unable to find specified Interface for %s",
2180 zvrf->vrf->name);
2181 return;
2182 }
2183
2184 def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
2185
2186 if (zvrf->label[afi] != MPLS_LABEL_NONE) {
2187 afi_t scrubber;
2188 bool really_remove;
2189
2190 really_remove = true;
2191 for (scrubber = AFI_IP; scrubber < AFI_MAX; scrubber++) {
2192 if (scrubber == afi)
2193 continue;
2194
2195 if (zvrf->label[scrubber] == MPLS_LABEL_NONE)
2196 continue;
2197
2198 if (zvrf->label[afi] == zvrf->label[scrubber]) {
2199 really_remove = false;
2200 break;
2201 }
2202 }
2203
2204 if (really_remove)
2205 mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi],
2206 NEXTHOP_TYPE_IFINDEX, NULL,
2207 ifp->ifindex);
2208 }
2209
2210 if (nlabel != MPLS_LABEL_NONE)
2211 mpls_lsp_install(def_zvrf, ltype, nlabel,
2212 MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX,
2213 NULL, ifp->ifindex);
2214
2215 zvrf->label[afi] = nlabel;
2216stream_failure:
2217 return;
2218}
2219
2220static inline void zread_rule(ZAPI_HANDLER_ARGS)
2221{
2222 struct zebra_pbr_rule zpr;
2223 struct stream *s;
2224 uint32_t total, i;
2225 ifindex_t ifindex;
2226
2227 s = msg;
2228 STREAM_GETL(s, total);
2229
2230 for (i = 0; i < total; i++) {
2231 memset(&zpr, 0, sizeof(zpr));
2232
2233 zpr.sock = client->sock;
2234 zpr.rule.vrf_id = hdr->vrf_id;
2235 STREAM_GETL(s, zpr.rule.seq);
2236 STREAM_GETL(s, zpr.rule.priority);
2237 STREAM_GETL(s, zpr.rule.unique);
2238 STREAM_GETC(s, zpr.rule.filter.src_ip.family);
2239 STREAM_GETC(s, zpr.rule.filter.src_ip.prefixlen);
2240 STREAM_GET(&zpr.rule.filter.src_ip.u.prefix, s,
2241 prefix_blen(&zpr.rule.filter.src_ip));
2242 STREAM_GETW(s, zpr.rule.filter.src_port);
2243 STREAM_GETC(s, zpr.rule.filter.dst_ip.family);
2244 STREAM_GETC(s, zpr.rule.filter.dst_ip.prefixlen);
2245 STREAM_GET(&zpr.rule.filter.dst_ip.u.prefix, s,
2246 prefix_blen(&zpr.rule.filter.dst_ip));
2247 STREAM_GETW(s, zpr.rule.filter.dst_port);
2248 STREAM_GETL(s, zpr.rule.filter.fwmark);
2249 STREAM_GETL(s, zpr.rule.action.table);
2250 STREAM_GETL(s, ifindex);
2251
2252 if (ifindex) {
06432d4e
PG
2253 zpr.ifp = if_lookup_by_index_per_ns(
2254 zvrf->zns,
2255 ifindex);
bf094f69
QY
2256 if (!zpr.ifp) {
2257 zlog_debug("Failed to lookup ifindex: %u",
2258 ifindex);
2259 return;
2260 }
2261 }
2262
2263 if (!is_default_prefix(&zpr.rule.filter.src_ip))
2264 zpr.rule.filter.filter_bm |= PBR_FILTER_SRC_IP;
2265
2266 if (!is_default_prefix(&zpr.rule.filter.dst_ip))
2267 zpr.rule.filter.filter_bm |= PBR_FILTER_DST_IP;
2268
2269 if (zpr.rule.filter.src_port)
2270 zpr.rule.filter.filter_bm |= PBR_FILTER_SRC_PORT;
2271
2272 if (zpr.rule.filter.dst_port)
2273 zpr.rule.filter.filter_bm |= PBR_FILTER_DST_PORT;
2274
2275 if (zpr.rule.filter.fwmark)
2276 zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK;
2277
7f0ea8a4 2278 zpr.vrf_id = zvrf->vrf->vrf_id;
bf094f69 2279 if (hdr->command == ZEBRA_RULE_ADD)
7f0ea8a4 2280 zebra_pbr_add_rule(&zpr);
bf094f69 2281 else
7f0ea8a4 2282 zebra_pbr_del_rule(&zpr);
bf094f69
QY
2283 }
2284
2285stream_failure:
2286 return;
2287}
2288
2289static inline void zread_ipset(ZAPI_HANDLER_ARGS)
2290{
2291 struct zebra_pbr_ipset zpi;
2292 struct stream *s;
2293 uint32_t total, i;
2294
2295 s = msg;
2296 STREAM_GETL(s, total);
2297
2298 for (i = 0; i < total; i++) {
2299 memset(&zpi, 0, sizeof(zpi));
2300
2301 zpi.sock = client->sock;
be2028d1 2302 zpi.vrf_id = zvrf->vrf->vrf_id;
bf094f69
QY
2303 STREAM_GETL(s, zpi.unique);
2304 STREAM_GETL(s, zpi.type);
2305 STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
2306
2307 if (hdr->command == ZEBRA_IPSET_CREATE)
62f20a52 2308 zebra_pbr_create_ipset(&zpi);
bf094f69 2309 else
62f20a52 2310 zebra_pbr_destroy_ipset(&zpi);
bf094f69
QY
2311 }
2312
2313stream_failure:
2314 return;
2315}
2316
2317static inline void zread_ipset_entry(ZAPI_HANDLER_ARGS)
2318{
2319 struct zebra_pbr_ipset_entry zpi;
2320 struct zebra_pbr_ipset ipset;
2321 struct stream *s;
2322 uint32_t total, i;
2323
2324 s = msg;
2325 STREAM_GETL(s, total);
2326
2327 for (i = 0; i < total; i++) {
2328 memset(&zpi, 0, sizeof(zpi));
2329 memset(&ipset, 0, sizeof(ipset));
2330
2331 zpi.sock = client->sock;
2332 STREAM_GETL(s, zpi.unique);
2333 STREAM_GET(&ipset.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
2334 STREAM_GETC(s, zpi.src.family);
2335 STREAM_GETC(s, zpi.src.prefixlen);
2336 STREAM_GET(&zpi.src.u.prefix, s, prefix_blen(&zpi.src));
2337 STREAM_GETC(s, zpi.dst.family);
2338 STREAM_GETC(s, zpi.dst.prefixlen);
2339 STREAM_GET(&zpi.dst.u.prefix, s, prefix_blen(&zpi.dst));
2340
25d760c5
PG
2341 STREAM_GETW(s, zpi.src_port_min);
2342 STREAM_GETW(s, zpi.src_port_max);
2343 STREAM_GETW(s, zpi.dst_port_min);
2344 STREAM_GETW(s, zpi.dst_port_max);
2345 STREAM_GETC(s, zpi.proto);
bf094f69
QY
2346 if (!is_default_prefix(&zpi.src))
2347 zpi.filter_bm |= PBR_FILTER_SRC_IP;
2348
2349 if (!is_default_prefix(&zpi.dst))
2350 zpi.filter_bm |= PBR_FILTER_DST_IP;
be729dd7 2351 if (zpi.dst_port_min != 0 || zpi.proto == IPPROTO_ICMP)
25d760c5 2352 zpi.filter_bm |= PBR_FILTER_DST_PORT;
be729dd7 2353 if (zpi.src_port_min != 0 || zpi.proto == IPPROTO_ICMP)
25d760c5
PG
2354 zpi.filter_bm |= PBR_FILTER_SRC_PORT;
2355 if (zpi.dst_port_max != 0)
2356 zpi.filter_bm |= PBR_FILTER_DST_PORT_RANGE;
2357 if (zpi.src_port_max != 0)
2358 zpi.filter_bm |= PBR_FILTER_SRC_PORT_RANGE;
2359 if (zpi.proto != 0)
2360 zpi.filter_bm |= PBR_FILTER_PROTO;
bf094f69
QY
2361
2362 /* calculate backpointer */
62f20a52
DS
2363 zpi.backpointer =
2364 zebra_pbr_lookup_ipset_pername(ipset.ipset_name);
bf094f69 2365 if (hdr->command == ZEBRA_IPSET_ENTRY_ADD)
62f20a52 2366 zebra_pbr_add_ipset_entry(&zpi);
bf094f69 2367 else
62f20a52 2368 zebra_pbr_del_ipset_entry(&zpi);
bf094f69
QY
2369 }
2370
2371stream_failure:
2372 return;
2373}
2374
2375static inline void zread_iptable(ZAPI_HANDLER_ARGS)
2376{
2377 struct zebra_pbr_iptable zpi;
2378 struct stream *s;
2379
2380 s = msg;
2381
2382 memset(&zpi, 0, sizeof(zpi));
2383
f80ec7e3 2384 zpi.interface_name_list = list_new();
bf094f69 2385 zpi.sock = client->sock;
be2028d1 2386 zpi.vrf_id = zvrf->vrf->vrf_id;
bf094f69
QY
2387 STREAM_GETL(s, zpi.unique);
2388 STREAM_GETL(s, zpi.type);
2389 STREAM_GETL(s, zpi.filter_bm);
2390 STREAM_GETL(s, zpi.action);
2391 STREAM_GETL(s, zpi.fwmark);
2392 STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
e7f7dad4
PG
2393 STREAM_GETW(s, zpi.pkt_len_min);
2394 STREAM_GETW(s, zpi.pkt_len_max);
dc993e76
PG
2395 STREAM_GETW(s, zpi.tcp_flags);
2396 STREAM_GETW(s, zpi.tcp_mask_flags);
4977bd6c 2397 STREAM_GETC(s, zpi.dscp_value);
5ac5b7cc 2398 STREAM_GETC(s, zpi.fragment);
f80ec7e3
PG
2399 STREAM_GETL(s, zpi.nb_interface);
2400 zebra_pbr_iptable_update_interfacelist(s, &zpi);
bf094f69
QY
2401
2402 if (hdr->command == ZEBRA_IPTABLE_ADD)
62f20a52 2403 zebra_pbr_add_iptable(&zpi);
bf094f69 2404 else
62f20a52 2405 zebra_pbr_del_iptable(&zpi);
bf094f69
QY
2406stream_failure:
2407 return;
2408}
2409
2410void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
2411 [ZEBRA_ROUTER_ID_ADD] = zread_router_id_add,
2412 [ZEBRA_ROUTER_ID_DELETE] = zread_router_id_delete,
2413 [ZEBRA_INTERFACE_ADD] = zread_interface_add,
2414 [ZEBRA_INTERFACE_DELETE] = zread_interface_delete,
2415 [ZEBRA_ROUTE_ADD] = zread_route_add,
2416 [ZEBRA_ROUTE_DELETE] = zread_route_del,
bf094f69
QY
2417 [ZEBRA_REDISTRIBUTE_ADD] = zebra_redistribute_add,
2418 [ZEBRA_REDISTRIBUTE_DELETE] = zebra_redistribute_delete,
2419 [ZEBRA_REDISTRIBUTE_DEFAULT_ADD] = zebra_redistribute_default_add,
2420 [ZEBRA_REDISTRIBUTE_DEFAULT_DELETE] = zebra_redistribute_default_delete,
2421 [ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB] = zread_ipv4_nexthop_lookup_mrib,
2422 [ZEBRA_HELLO] = zread_hello,
2423 [ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register,
2424 [ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister,
2425 [ZEBRA_IMPORT_ROUTE_REGISTER] = zread_rnh_register,
2426 [ZEBRA_IMPORT_ROUTE_UNREGISTER] = zread_rnh_unregister,
2427 [ZEBRA_BFD_DEST_UPDATE] = zebra_ptm_bfd_dst_register,
2428 [ZEBRA_BFD_DEST_REGISTER] = zebra_ptm_bfd_dst_register,
2429 [ZEBRA_BFD_DEST_DEREGISTER] = zebra_ptm_bfd_dst_deregister,
d3af6147
RZ
2430#if HAVE_BFDD > 0
2431 [ZEBRA_BFD_DEST_REPLAY] = zebra_ptm_bfd_dst_replay,
2432#endif /* HAVE_BFDD */
bf094f69
QY
2433 [ZEBRA_VRF_UNREGISTER] = zread_vrf_unregister,
2434 [ZEBRA_VRF_LABEL] = zread_vrf_label,
2435 [ZEBRA_BFD_CLIENT_REGISTER] = zebra_ptm_bfd_client_register,
2436#if defined(HAVE_RTADV)
2437 [ZEBRA_INTERFACE_ENABLE_RADV] = zebra_interface_radv_enable,
2438 [ZEBRA_INTERFACE_DISABLE_RADV] = zebra_interface_radv_disable,
2439#else
2440 [ZEBRA_INTERFACE_ENABLE_RADV] = NULL,
2441 [ZEBRA_INTERFACE_DISABLE_RADV] = NULL,
2442#endif
2443 [ZEBRA_MPLS_LABELS_ADD] = zread_mpls_labels,
2444 [ZEBRA_MPLS_LABELS_DELETE] = zread_mpls_labels,
2445 [ZEBRA_IPMR_ROUTE_STATS] = zebra_ipmr_route_stats,
2446 [ZEBRA_LABEL_MANAGER_CONNECT] = zread_label_manager_request,
f533be73 2447 [ZEBRA_LABEL_MANAGER_CONNECT_ASYNC] = zread_label_manager_request,
bf094f69
QY
2448 [ZEBRA_GET_LABEL_CHUNK] = zread_label_manager_request,
2449 [ZEBRA_RELEASE_LABEL_CHUNK] = zread_label_manager_request,
2450 [ZEBRA_FEC_REGISTER] = zread_fec_register,
2451 [ZEBRA_FEC_UNREGISTER] = zread_fec_unregister,
2452 [ZEBRA_ADVERTISE_DEFAULT_GW] = zebra_vxlan_advertise_gw_macip,
278e26de 2453 [ZEBRA_ADVERTISE_SVI_MACIP] = zebra_vxlan_advertise_svi_macip,
bf094f69
QY
2454 [ZEBRA_ADVERTISE_SUBNET] = zebra_vxlan_advertise_subnet,
2455 [ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni,
2456 [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add,
2457 [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del,
2458 [ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add,
2459 [ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del,
3950b52c 2460 [ZEBRA_DUPLICATE_ADDR_DETECTION] = zebra_vxlan_dup_addr_detection,
bf094f69
QY
2461 [ZEBRA_INTERFACE_SET_MASTER] = zread_interface_set_master,
2462 [ZEBRA_PW_ADD] = zread_pseudowire,
2463 [ZEBRA_PW_DELETE] = zread_pseudowire,
2464 [ZEBRA_PW_SET] = zread_pseudowire,
2465 [ZEBRA_PW_UNSET] = zread_pseudowire,
2466 [ZEBRA_RULE_ADD] = zread_rule,
2467 [ZEBRA_RULE_DELETE] = zread_rule,
2468 [ZEBRA_TABLE_MANAGER_CONNECT] = zread_table_manager_request,
2469 [ZEBRA_GET_TABLE_CHUNK] = zread_table_manager_request,
2470 [ZEBRA_RELEASE_TABLE_CHUNK] = zread_table_manager_request,
2471 [ZEBRA_IPSET_CREATE] = zread_ipset,
2472 [ZEBRA_IPSET_DESTROY] = zread_ipset,
2473 [ZEBRA_IPSET_ENTRY_ADD] = zread_ipset_entry,
2474 [ZEBRA_IPSET_ENTRY_DELETE] = zread_ipset_entry,
2475 [ZEBRA_IPTABLE_ADD] = zread_iptable,
2476 [ZEBRA_IPTABLE_DELETE] = zread_iptable,
fbac9605 2477 [ZEBRA_VXLAN_FLOOD_CONTROL] = zebra_vxlan_flood_control,
bf094f69
QY
2478};
2479
727c9b99
QY
2480#if defined(HANDLE_ZAPI_FUZZING)
2481extern struct zebra_privs_t zserv_privs;
2482
2483static void zserv_write_incoming(struct stream *orig, uint16_t command)
2484{
2485 char fname[MAXPATHLEN];
2486 struct stream *copy;
2487 int fd = -1;
2488
2489 copy = stream_dup(orig);
2490 stream_set_getp(copy, 0);
2491
727c9b99 2492 snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command);
6bb30c2c
DL
2493
2494 frr_elevate_privs(&zserv_privs) {
2495 fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
2496 }
727c9b99
QY
2497 stream_flush(copy, fd);
2498 close(fd);
727c9b99
QY
2499 stream_free(copy);
2500}
2501#endif
2502
904e0d88 2503void zserv_handle_commands(struct zserv *client, struct stream *msg)
bf094f69 2504{
904e0d88
QY
2505 struct zmsghdr hdr;
2506 struct zebra_vrf *zvrf;
2507
2508 zapi_parse_header(msg, &hdr);
bf094f69 2509
727c9b99
QY
2510#if defined(HANDLE_ZAPI_FUZZING)
2511 zserv_write_incoming(msg, hdr.command);
2512#endif
2513
904e0d88
QY
2514 hdr.length -= ZEBRA_HEADER_SIZE;
2515
2516 /* lookup vrf */
2517 zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
2518 if (!zvrf) {
2519 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
9df414fe
QY
2520 zlog_debug("ZAPI message specifies unknown VRF: %d",
2521 hdr.vrf_id);
904e0d88
QY
2522 return;
2523 }
2524
aa360de7 2525 if (hdr.command >= array_size(zserv_handlers)
904e0d88
QY
2526 || zserv_handlers[hdr.command] == NULL)
2527 zlog_info("Zebra received unknown command %d", hdr.command);
2528 else
2529 zserv_handlers[hdr.command](client, &hdr, msg, zvrf);
bf094f69 2530}