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