1 /* Zebra's client library.
2 * Copyright (C) 1999 Kunihiro Ishiguro
3 * Copyright (C) 2005 Andrew J. Schorr
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
40 #include "nexthop_group.h"
41 #include "lib_errors.h"
46 DEFINE_MTYPE_STATIC(LIB
, ZCLIENT
, "Zclient");
47 DEFINE_MTYPE_STATIC(LIB
, REDIST_INST
, "Redistribution instance IDs");
49 /* Zebra client events. */
50 enum zclient_event
{ ZCLIENT_SCHEDULE
, ZCLIENT_READ
, ZCLIENT_CONNECT
};
52 /* Prototype for event manager. */
53 static void zclient_event(enum zclient_event
, struct zclient
*);
55 static void zebra_interface_if_set_value(struct stream
*s
,
56 struct interface
*ifp
);
58 struct zclient_options zclient_options_default
= {.receive_notify
= false,
59 .synchronous
= false};
61 struct sockaddr_storage zclient_addr
;
62 socklen_t zclient_addr_len
;
64 /* This file local debug flag. */
65 static int zclient_debug
;
67 /* Allocate zclient structure. */
68 struct zclient
*zclient_new(struct thread_master
*master
,
69 struct zclient_options
*opt
,
70 zclient_handler
*const *handlers
, size_t n_handlers
)
72 struct zclient
*zclient
;
74 MAX(ZEBRA_MAX_PACKET_SIZ
, sizeof(struct zapi_route
));
76 zclient
= XCALLOC(MTYPE_ZCLIENT
, sizeof(struct zclient
));
78 zclient
->ibuf
= stream_new(stream_size
);
79 zclient
->obuf
= stream_new(stream_size
);
80 zclient
->wb
= buffer_new(0);
81 zclient
->master
= master
;
83 zclient
->handlers
= handlers
;
84 zclient
->n_handlers
= n_handlers
;
86 zclient
->receive_notify
= opt
->receive_notify
;
87 zclient
->synchronous
= opt
->synchronous
;
92 /* This function is only called when exiting, because
93 many parts of the code do not check for I/O errors, so they could
94 reference an invalid pointer if the structure was ever freed.
96 Free zclient structure. */
97 void zclient_free(struct zclient
*zclient
)
100 stream_free(zclient
->ibuf
);
102 stream_free(zclient
->obuf
);
104 buffer_free(zclient
->wb
);
106 XFREE(MTYPE_ZCLIENT
, zclient
);
109 unsigned short *redist_check_instance(struct redist_proto
*red
,
110 unsigned short instance
)
112 struct listnode
*node
;
118 for (ALL_LIST_ELEMENTS_RO(red
->instances
, node
, id
))
125 void redist_add_instance(struct redist_proto
*red
, unsigned short instance
)
132 red
->instances
= list_new();
134 in
= XMALLOC(MTYPE_REDIST_INST
, sizeof(unsigned short));
136 listnode_add(red
->instances
, in
);
139 void redist_del_instance(struct redist_proto
*red
, unsigned short instance
)
143 id
= redist_check_instance(red
, instance
);
147 listnode_delete(red
->instances
, id
);
148 XFREE(MTYPE_REDIST_INST
, id
);
149 if (!red
->instances
->count
) {
151 list_delete(&red
->instances
);
155 void redist_del_all_instances(struct redist_proto
*red
)
157 struct listnode
*ln
, *nn
;
163 for (ALL_LIST_ELEMENTS(red
->instances
, ln
, nn
, id
))
164 redist_del_instance(red
, *id
);
167 /* Stop zebra client services. */
168 void zclient_stop(struct zclient
*zclient
)
174 zlog_debug("zclient %p stopped", zclient
);
177 THREAD_OFF(zclient
->t_read
);
178 THREAD_OFF(zclient
->t_connect
);
179 THREAD_OFF(zclient
->t_write
);
182 stream_reset(zclient
->ibuf
);
183 stream_reset(zclient
->obuf
);
185 /* Empty the write buffer. */
186 buffer_reset(zclient
->wb
);
189 if (zclient
->sock
>= 0) {
190 close(zclient
->sock
);
195 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
196 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
197 vrf_bitmap_free(zclient
->redist
[afi
][i
]);
198 zclient
->redist
[afi
][i
] = VRF_BITMAP_NULL
;
201 &zclient
->mi_redist
[afi
][zclient
->redist_default
],
204 vrf_bitmap_free(zclient
->default_information
[afi
]);
205 zclient
->default_information
[afi
] = VRF_BITMAP_NULL
;
209 void zclient_reset(struct zclient
*zclient
)
213 zclient_stop(zclient
);
215 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
217 &zclient
->mi_redist
[afi
][zclient
->redist_default
],
220 zclient_init(zclient
, zclient
->redist_default
, zclient
->instance
,
225 * Connect to zebra daemon.
226 * @param zclient a pointer to zclient structure
227 * @return socket fd just to make sure that connection established
231 int zclient_socket_connect(struct zclient
*zclient
)
236 /* We should think about IPv6 connection. */
237 sock
= socket(zclient_addr
.ss_family
, SOCK_STREAM
, 0);
242 setsockopt_so_sendbuf(sock
, 1048576);
244 /* Connect to zebra. */
245 ret
= connect(sock
, (struct sockaddr
*)&zclient_addr
, zclient_addr_len
);
248 zlog_debug("%s connect failure: %d(%s)", __func__
,
249 errno
, safe_strerror(errno
));
254 zclient
->sock
= sock
;
258 static enum zclient_send_status
zclient_failed(struct zclient
*zclient
)
261 zclient_stop(zclient
);
262 zclient_event(ZCLIENT_CONNECT
, zclient
);
263 return ZCLIENT_SEND_FAILURE
;
266 static void zclient_flush_data(struct thread
*thread
)
268 struct zclient
*zclient
= THREAD_ARG(thread
);
270 zclient
->t_write
= NULL
;
271 if (zclient
->sock
< 0)
273 switch (buffer_flush_available(zclient
->wb
, zclient
->sock
)) {
277 "%s: buffer_flush_available failed on zclient fd %d, closing",
278 __func__
, zclient
->sock
);
279 zclient_failed(zclient
);
282 zclient
->t_write
= NULL
;
283 thread_add_write(zclient
->master
, zclient_flush_data
, zclient
,
284 zclient
->sock
, &zclient
->t_write
);
287 if (zclient
->zebra_buffer_write_ready
)
288 (*zclient
->zebra_buffer_write_ready
)();
295 * ZCLIENT_SEND_FAILED - is a failure
296 * ZCLIENT_SEND_SUCCESS - means we sent data to zebra
297 * ZCLIENT_SEND_BUFFERED - means we are buffering
299 enum zclient_send_status
zclient_send_message(struct zclient
*zclient
)
301 if (zclient
->sock
< 0)
302 return ZCLIENT_SEND_FAILURE
;
303 switch (buffer_write(zclient
->wb
, zclient
->sock
,
304 STREAM_DATA(zclient
->obuf
),
305 stream_get_endp(zclient
->obuf
))) {
307 flog_err(EC_LIB_ZAPI_SOCKET
,
308 "%s: buffer_write failed to zclient fd %d, closing",
309 __func__
, zclient
->sock
);
310 return zclient_failed(zclient
);
312 THREAD_OFF(zclient
->t_write
);
313 return ZCLIENT_SEND_SUCCESS
;
315 thread_add_write(zclient
->master
, zclient_flush_data
, zclient
,
316 zclient
->sock
, &zclient
->t_write
);
317 return ZCLIENT_SEND_BUFFERED
;
320 /* should not get here */
321 return ZCLIENT_SEND_SUCCESS
;
325 * If we add more data to this structure please ensure that
326 * struct zmsghdr in lib/zclient.h is updated as appropriate.
328 void zclient_create_header(struct stream
*s
, uint16_t command
, vrf_id_t vrf_id
)
330 /* length placeholder, caller can update */
331 stream_putw(s
, ZEBRA_HEADER_SIZE
);
332 stream_putc(s
, ZEBRA_HEADER_MARKER
);
333 stream_putc(s
, ZSERV_VERSION
);
334 stream_putl(s
, vrf_id
);
335 stream_putw(s
, command
);
338 int zclient_read_header(struct stream
*s
, int sock
, uint16_t *size
,
339 uint8_t *marker
, uint8_t *version
, vrf_id_t
*vrf_id
,
342 if (stream_read(s
, sock
, ZEBRA_HEADER_SIZE
) != ZEBRA_HEADER_SIZE
)
345 STREAM_GETW(s
, *size
);
346 *size
-= ZEBRA_HEADER_SIZE
;
347 STREAM_GETC(s
, *marker
);
348 STREAM_GETC(s
, *version
);
349 STREAM_GETL(s
, *vrf_id
);
350 STREAM_GETW(s
, *cmd
);
352 if (*version
!= ZSERV_VERSION
|| *marker
!= ZEBRA_HEADER_MARKER
) {
354 EC_LIB_ZAPI_MISSMATCH
,
355 "%s: socket %d version mismatch, marker %d, version %d",
356 __func__
, sock
, *marker
, *version
);
360 if (*size
&& stream_read(s
, sock
, *size
) != *size
)
368 bool zapi_parse_header(struct stream
*zmsg
, struct zmsghdr
*hdr
)
370 STREAM_GETW(zmsg
, hdr
->length
);
371 STREAM_GETC(zmsg
, hdr
->marker
);
372 STREAM_GETC(zmsg
, hdr
->version
);
373 STREAM_GETL(zmsg
, hdr
->vrf_id
);
374 STREAM_GETW(zmsg
, hdr
->command
);
380 /* Send simple Zebra message. */
381 static enum zclient_send_status
zebra_message_send(struct zclient
*zclient
,
382 int command
, vrf_id_t vrf_id
)
386 /* Get zclient output buffer. */
390 /* Send very simple command only Zebra message. */
391 zclient_create_header(s
, command
, vrf_id
);
393 return zclient_send_message(zclient
);
396 enum zclient_send_status
zclient_send_hello(struct zclient
*zclient
)
400 if (zclient
->redist_default
|| zclient
->synchronous
) {
404 /* The VRF ID in the HELLO message is always 0. */
405 zclient_create_header(s
, ZEBRA_HELLO
, VRF_DEFAULT
);
406 stream_putc(s
, zclient
->redist_default
);
407 stream_putw(s
, zclient
->instance
);
408 stream_putl(s
, zclient
->session_id
);
409 if (zclient
->receive_notify
)
413 if (zclient
->synchronous
)
418 stream_putw_at(s
, 0, stream_get_endp(s
));
419 return zclient_send_message(zclient
);
422 return ZCLIENT_SEND_SUCCESS
;
425 enum zclient_send_status
zclient_send_vrf_label(struct zclient
*zclient
,
426 vrf_id_t vrf_id
, afi_t afi
,
428 enum lsp_types_t ltype
)
435 zclient_create_header(s
, ZEBRA_VRF_LABEL
, vrf_id
);
436 stream_putl(s
, label
);
438 stream_putc(s
, ltype
);
439 stream_putw_at(s
, 0, stream_get_endp(s
));
440 return zclient_send_message(zclient
);
443 enum zclient_send_status
zclient_send_localsid(struct zclient
*zclient
,
444 const struct in6_addr
*sid
, ifindex_t oif
,
445 enum seg6local_action_t action
,
446 const struct seg6local_context
*context
)
448 struct prefix_ipv6 p
= {};
449 struct zapi_route api
= {};
450 struct zapi_nexthop
*znh
;
453 p
.prefixlen
= IPV6_MAX_BITLEN
;
456 api
.vrf_id
= VRF_DEFAULT
;
457 api
.type
= zclient
->redist_default
;
459 api
.safi
= SAFI_UNICAST
;
460 memcpy(&api
.prefix
, &p
, sizeof(p
));
462 if (action
== ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
)
463 return zclient_route_send(ZEBRA_ROUTE_DELETE
, zclient
, &api
);
465 SET_FLAG(api
.flags
, ZEBRA_FLAG_ALLOW_RECURSION
);
466 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
468 znh
= &api
.nexthops
[0];
470 memset(znh
, 0, sizeof(*znh
));
472 znh
->type
= NEXTHOP_TYPE_IFINDEX
;
474 SET_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_SEG6LOCAL
);
475 znh
->seg6local_action
= action
;
476 memcpy(&znh
->seg6local_ctx
, context
, sizeof(struct seg6local_context
));
480 return zclient_route_send(ZEBRA_ROUTE_ADD
, zclient
, &api
);
483 /* Send register requests to zebra daemon for the information in a VRF. */
484 void zclient_send_reg_requests(struct zclient
*zclient
, vrf_id_t vrf_id
)
489 /* If not connected to the zebra yet. */
490 if (zclient
->sock
< 0)
494 zlog_debug("%s: send register messages for VRF %u", __func__
,
497 /* We need router-id information. */
498 zclient_send_router_id_update(zclient
, ZEBRA_ROUTER_ID_ADD
, AFI_IP
,
501 /* We need interface information. */
502 zebra_message_send(zclient
, ZEBRA_INTERFACE_ADD
, vrf_id
);
504 /* Set unwanted redistribute route. */
505 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
506 vrf_bitmap_set(zclient
->redist
[afi
][zclient
->redist_default
],
509 /* Flush all redistribute request. */
510 if (vrf_id
== VRF_DEFAULT
) {
511 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
512 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
513 if (!zclient
->mi_redist
[afi
][i
].enabled
)
516 struct listnode
*node
;
519 for (ALL_LIST_ELEMENTS_RO(
520 zclient
->mi_redist
[afi
][i
]
523 if (!(i
== zclient
->redist_default
524 && *id
== zclient
->instance
))
525 zebra_redistribute_send(
526 ZEBRA_REDISTRIBUTE_ADD
,
527 zclient
, afi
, i
, *id
,
533 /* Resend all redistribute request. */
534 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
535 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
536 if (i
!= zclient
->redist_default
537 && vrf_bitmap_check(zclient
->redist
[afi
][i
],
539 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
,
543 /* If default information is needed. */
544 if (vrf_bitmap_check(zclient
->default_information
[afi
], vrf_id
))
545 zebra_redistribute_default_send(
546 ZEBRA_REDISTRIBUTE_DEFAULT_ADD
, zclient
, afi
,
551 /* Send unregister requests to zebra daemon for the information in a VRF. */
552 void zclient_send_dereg_requests(struct zclient
*zclient
, vrf_id_t vrf_id
)
557 /* If not connected to the zebra yet. */
558 if (zclient
->sock
< 0)
562 zlog_debug("%s: send deregister messages for VRF %u", __func__
,
565 /* We need router-id information. */
566 zclient_send_router_id_update(zclient
, ZEBRA_ROUTER_ID_DELETE
, AFI_IP
,
569 zebra_message_send(zclient
, ZEBRA_INTERFACE_DELETE
, vrf_id
);
571 /* Set unwanted redistribute route. */
572 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
573 vrf_bitmap_unset(zclient
->redist
[afi
][zclient
->redist_default
],
576 /* Flush all redistribute request. */
577 if (vrf_id
== VRF_DEFAULT
) {
578 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
579 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
580 if (!zclient
->mi_redist
[afi
][i
].enabled
)
583 struct listnode
*node
;
586 for (ALL_LIST_ELEMENTS_RO(
587 zclient
->mi_redist
[afi
][i
]
590 if (!(i
== zclient
->redist_default
591 && *id
== zclient
->instance
))
592 zebra_redistribute_send(
593 ZEBRA_REDISTRIBUTE_DELETE
,
594 zclient
, afi
, i
, *id
,
600 /* Flush all redistribute request. */
601 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
602 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
603 if (i
!= zclient
->redist_default
604 && vrf_bitmap_check(zclient
->redist
[afi
][i
],
606 zebra_redistribute_send(
607 ZEBRA_REDISTRIBUTE_DELETE
, zclient
, afi
,
610 /* If default information is needed. */
611 if (vrf_bitmap_check(zclient
->default_information
[afi
], vrf_id
))
612 zebra_redistribute_default_send(
613 ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
, zclient
, afi
,
618 enum zclient_send_status
619 zclient_send_router_id_update(struct zclient
*zclient
,
620 zebra_message_types_t type
, afi_t afi
,
623 struct stream
*s
= zclient
->obuf
;
625 zclient_create_header(s
, type
, vrf_id
);
627 stream_putw_at(s
, 0, stream_get_endp(s
));
628 return zclient_send_message(zclient
);
631 /* Send request to zebra daemon to start or stop RA. */
632 enum zclient_send_status
633 zclient_send_interface_radv_req(struct zclient
*zclient
, vrf_id_t vrf_id
,
634 struct interface
*ifp
, int enable
,
635 uint32_t ra_interval
)
639 /* If not connected to the zebra yet. */
640 if (zclient
->sock
< 0)
641 return ZCLIENT_SEND_FAILURE
;
643 /* Form and send message. */
648 zclient_create_header(s
, ZEBRA_INTERFACE_ENABLE_RADV
, vrf_id
);
650 zclient_create_header(s
, ZEBRA_INTERFACE_DISABLE_RADV
, vrf_id
);
652 stream_putl(s
, ifp
->ifindex
);
653 stream_putl(s
, ra_interval
);
655 stream_putw_at(s
, 0, stream_get_endp(s
));
657 return zclient_send_message(zclient
);
660 enum zclient_send_status
661 zclient_send_interface_protodown(struct zclient
*zclient
, vrf_id_t vrf_id
,
662 struct interface
*ifp
, bool down
)
666 if (zclient
->sock
< 0)
667 return ZCLIENT_SEND_FAILURE
;
671 zclient_create_header(s
, ZEBRA_INTERFACE_SET_PROTODOWN
, vrf_id
);
672 stream_putl(s
, ifp
->ifindex
);
673 stream_putc(s
, !!down
);
674 stream_putw_at(s
, 0, stream_get_endp(s
));
675 return zclient_send_message(zclient
);
678 /* Make connection to zebra daemon. */
679 int zclient_start(struct zclient
*zclient
)
682 zlog_info("zclient_start is called");
684 /* If already connected to the zebra. */
685 if (zclient
->sock
>= 0)
688 /* Check connect thread. */
689 if (zclient
->t_connect
)
692 if (zclient_socket_connect(zclient
) < 0) {
694 zlog_debug("zclient connection fail");
696 zclient_event(ZCLIENT_CONNECT
, zclient
);
700 if (set_nonblocking(zclient
->sock
) < 0)
701 flog_err(EC_LIB_ZAPI_SOCKET
, "%s: set_nonblocking(%d) failed",
702 __func__
, zclient
->sock
);
704 /* Clear fail count. */
707 zlog_debug("zclient connect success with socket [%d]",
710 /* Create read thread. */
711 zclient_event(ZCLIENT_READ
, zclient
);
713 zclient_send_hello(zclient
);
715 zebra_message_send(zclient
, ZEBRA_INTERFACE_ADD
, VRF_DEFAULT
);
717 /* Inform the successful connection. */
718 if (zclient
->zebra_connected
)
719 (*zclient
->zebra_connected
)(zclient
);
724 /* Initialize zebra client. Argument redist_default is unwanted
725 redistribute route type. */
726 void zclient_init(struct zclient
*zclient
, int redist_default
,
727 unsigned short instance
, struct zebra_privs_t
*privs
)
731 /* Set -1 to the default socket value. */
733 zclient
->privs
= privs
;
735 /* Clear redistribution flags. */
736 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
737 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
738 zclient
->redist
[afi
][i
] = vrf_bitmap_init();
740 /* Set unwanted redistribute route. bgpd does not need BGP route
742 zclient
->redist_default
= redist_default
;
743 zclient
->instance
= instance
;
744 /* Pending: make afi(s) an arg. */
745 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
746 redist_add_instance(&zclient
->mi_redist
[afi
][redist_default
],
749 /* Set default-information redistribute to zero. */
750 zclient
->default_information
[afi
] = vrf_bitmap_init();
754 zlog_debug("scheduling zclient connection");
756 zclient_event(ZCLIENT_SCHEDULE
, zclient
);
759 /* This function is a wrapper function for calling zclient_start from
760 timer or event thread. */
761 static void zclient_connect(struct thread
*t
)
763 struct zclient
*zclient
;
765 zclient
= THREAD_ARG(t
);
766 zclient
->t_connect
= NULL
;
769 zlog_debug("zclient_connect is called");
771 zclient_start(zclient
);
774 enum zclient_send_status
zclient_send_rnh(struct zclient
*zclient
, int command
,
775 const struct prefix
*p
, safi_t safi
,
776 bool connected
, bool resolve_via_def
,
783 zclient_create_header(s
, command
, vrf_id
);
784 stream_putc(s
, (connected
) ? 1 : 0);
785 stream_putc(s
, (resolve_via_def
) ? 1 : 0);
786 stream_putw(s
, safi
);
787 stream_putw(s
, PREFIX_FAMILY(p
));
788 stream_putc(s
, p
->prefixlen
);
789 switch (PREFIX_FAMILY(p
)) {
791 stream_put_in_addr(s
, &p
->u
.prefix4
);
794 stream_put(s
, &(p
->u
.prefix6
), 16);
799 stream_putw_at(s
, 0, stream_get_endp(s
));
801 return zclient_send_message(zclient
);
805 * "xdr_encode"-like interface that allows daemon (client) to send
806 * a message to zebra server for a route that needs to be
807 * added/deleted to the kernel. Info about the route is specified
808 * by the caller in a struct zapi_route. zapi_route_encode() then writes
809 * the info down the zclient socket using the stream_* functions.
811 * The corresponding read ("xdr_decode") function on the server
812 * side is zapi_route_decode().
814 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
817 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as a 4
820 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
822 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
824 * XXX: No attention paid to alignment.
826 enum zclient_send_status
827 zclient_route_send(uint8_t cmd
, struct zclient
*zclient
, struct zapi_route
*api
)
829 if (zapi_route_encode(cmd
, zclient
->obuf
, api
) < 0)
830 return ZCLIENT_SEND_FAILURE
;
831 return zclient_send_message(zclient
);
834 static int zapi_nexthop_labels_cmp(const struct zapi_nexthop
*next1
,
835 const struct zapi_nexthop
*next2
)
837 if (next1
->label_num
> next2
->label_num
)
840 if (next1
->label_num
< next2
->label_num
)
843 return memcmp(next1
->labels
, next2
->labels
, next1
->label_num
);
846 static int zapi_nexthop_srv6_cmp(const struct zapi_nexthop
*next1
,
847 const struct zapi_nexthop
*next2
)
851 ret
= memcmp(&next1
->seg6_segs
, &next2
->seg6_segs
,
852 sizeof(struct in6_addr
));
856 if (next1
->seg6local_action
> next2
->seg6local_action
)
859 if (next1
->seg6local_action
< next2
->seg6local_action
)
862 return memcmp(&next1
->seg6local_ctx
, &next2
->seg6local_ctx
,
863 sizeof(struct seg6local_context
));
866 static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop
*next1
,
867 const struct zapi_nexthop
*next2
)
871 if (next1
->vrf_id
< next2
->vrf_id
)
874 if (next1
->vrf_id
> next2
->vrf_id
)
877 if (next1
->type
< next2
->type
)
880 if (next1
->type
> next2
->type
)
883 if (next1
->weight
< next2
->weight
)
886 if (next1
->weight
> next2
->weight
)
889 switch (next1
->type
) {
890 case NEXTHOP_TYPE_IPV4
:
891 case NEXTHOP_TYPE_IPV6
:
892 ret
= nexthop_g_addr_cmp(next1
->type
, &next1
->gate
,
897 case NEXTHOP_TYPE_IPV4_IFINDEX
:
898 case NEXTHOP_TYPE_IPV6_IFINDEX
:
899 ret
= nexthop_g_addr_cmp(next1
->type
, &next1
->gate
,
903 /* Intentional Fall-Through */
904 case NEXTHOP_TYPE_IFINDEX
:
905 if (next1
->ifindex
< next2
->ifindex
)
908 if (next1
->ifindex
> next2
->ifindex
)
911 case NEXTHOP_TYPE_BLACKHOLE
:
912 if (next1
->bh_type
< next2
->bh_type
)
915 if (next1
->bh_type
> next2
->bh_type
)
920 if (next1
->srte_color
< next2
->srte_color
)
922 if (next1
->srte_color
> next2
->srte_color
)
925 if (CHECK_FLAG(next1
->flags
, NEXTHOP_FLAG_HAS_BACKUP
) ||
926 CHECK_FLAG(next2
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
928 if (!CHECK_FLAG(next1
->flags
, NEXTHOP_FLAG_HAS_BACKUP
) &&
929 CHECK_FLAG(next2
->flags
, NEXTHOP_FLAG_HAS_BACKUP
))
932 if (CHECK_FLAG(next1
->flags
, NEXTHOP_FLAG_HAS_BACKUP
) &&
933 !CHECK_FLAG(next2
->flags
, NEXTHOP_FLAG_HAS_BACKUP
))
936 if (next1
->backup_num
> 0 || next2
->backup_num
> 0) {
938 if (next1
->backup_num
< next2
->backup_num
)
941 if (next1
->backup_num
> next2
->backup_num
)
944 ret
= memcmp(next1
->backup_idx
,
945 next2
->backup_idx
, next1
->backup_num
);
954 static int zapi_nexthop_cmp(const void *item1
, const void *item2
)
958 const struct zapi_nexthop
*next1
= item1
;
959 const struct zapi_nexthop
*next2
= item2
;
961 ret
= zapi_nexthop_cmp_no_labels(next1
, next2
);
965 ret
= zapi_nexthop_labels_cmp(next1
, next2
);
969 ret
= zapi_nexthop_srv6_cmp(next1
, next2
);
974 static void zapi_nexthop_group_sort(struct zapi_nexthop
*nh_grp
,
975 uint16_t nexthop_num
)
977 qsort(nh_grp
, nexthop_num
, sizeof(struct zapi_nexthop
),
982 * Encode a single zapi nexthop
984 int zapi_nexthop_encode(struct stream
*s
, const struct zapi_nexthop
*api_nh
,
985 uint32_t api_flags
, uint32_t api_message
)
988 int nh_flags
= api_nh
->flags
;
990 stream_putl(s
, api_nh
->vrf_id
);
991 stream_putc(s
, api_nh
->type
);
993 /* If needed, set 'labelled nexthop' flag */
994 if (api_nh
->label_num
> 0) {
995 SET_FLAG(nh_flags
, ZAPI_NEXTHOP_FLAG_LABEL
);
997 /* Validate label count */
998 if (api_nh
->label_num
> MPLS_MAX_LABELS
) {
1004 /* If present, set 'weight' flag before encoding flags */
1006 SET_FLAG(nh_flags
, ZAPI_NEXTHOP_FLAG_WEIGHT
);
1008 /* Note that we're only encoding a single octet */
1009 stream_putc(s
, nh_flags
);
1011 switch (api_nh
->type
) {
1012 case NEXTHOP_TYPE_BLACKHOLE
:
1013 stream_putc(s
, api_nh
->bh_type
);
1015 case NEXTHOP_TYPE_IPV4
:
1016 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1017 stream_put_in_addr(s
, &api_nh
->gate
.ipv4
);
1018 stream_putl(s
, api_nh
->ifindex
);
1020 case NEXTHOP_TYPE_IFINDEX
:
1021 stream_putl(s
, api_nh
->ifindex
);
1023 case NEXTHOP_TYPE_IPV6
:
1024 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1025 stream_write(s
, (uint8_t *)&api_nh
->gate
.ipv6
,
1027 stream_putl(s
, api_nh
->ifindex
);
1031 /* We only encode labels if we have >0 - we use
1032 * the per-nexthop flag above to signal that the count
1033 * is present in the payload.
1035 if (api_nh
->label_num
> 0) {
1036 stream_putc(s
, api_nh
->label_num
);
1037 stream_put(s
, &api_nh
->labels
[0],
1038 api_nh
->label_num
* sizeof(mpls_label_t
));
1042 stream_putl(s
, api_nh
->weight
);
1044 /* Router MAC for EVPN routes. */
1045 if (CHECK_FLAG(nh_flags
, ZAPI_NEXTHOP_FLAG_EVPN
))
1046 stream_put(s
, &(api_nh
->rmac
),
1047 sizeof(struct ethaddr
));
1049 /* Color for Segment Routing TE. */
1050 if (CHECK_FLAG(api_message
, ZAPI_MESSAGE_SRTE
))
1051 stream_putl(s
, api_nh
->srte_color
);
1053 /* Index of backup nexthop */
1054 if (CHECK_FLAG(nh_flags
, ZAPI_NEXTHOP_FLAG_HAS_BACKUP
)) {
1055 /* Validate backup count */
1056 if (api_nh
->backup_num
> NEXTHOP_MAX_BACKUPS
) {
1061 stream_putc(s
, api_nh
->backup_num
);
1062 for (i
= 0; i
< api_nh
->backup_num
; i
++)
1063 stream_putc(s
, api_nh
->backup_idx
[i
]);
1066 if (CHECK_FLAG(nh_flags
, ZAPI_NEXTHOP_FLAG_SEG6LOCAL
)) {
1067 stream_putl(s
, api_nh
->seg6local_action
);
1068 stream_write(s
, &api_nh
->seg6local_ctx
,
1069 sizeof(struct seg6local_context
));
1072 if (CHECK_FLAG(nh_flags
, ZAPI_NEXTHOP_FLAG_SEG6
))
1073 stream_write(s
, &api_nh
->seg6_segs
,
1074 sizeof(struct in6_addr
));
1080 int zapi_srv6_locator_chunk_encode(struct stream
*s
,
1081 const struct srv6_locator_chunk
*c
)
1083 stream_putw(s
, strlen(c
->locator_name
));
1084 stream_put(s
, c
->locator_name
, strlen(c
->locator_name
));
1085 stream_putw(s
, c
->prefix
.prefixlen
);
1086 stream_put(s
, &c
->prefix
.prefix
, sizeof(c
->prefix
.prefix
));
1087 stream_putc(s
, c
->block_bits_length
);
1088 stream_putc(s
, c
->node_bits_length
);
1089 stream_putc(s
, c
->function_bits_length
);
1090 stream_putc(s
, c
->argument_bits_length
);
1091 stream_putc(s
, c
->flags
);
1095 int zapi_srv6_locator_chunk_decode(struct stream
*s
,
1096 struct srv6_locator_chunk
*c
)
1100 c
->prefix
.family
= AF_INET6
;
1102 STREAM_GETW(s
, len
);
1103 if (len
> SRV6_LOCNAME_SIZE
)
1104 goto stream_failure
;
1106 STREAM_GET(c
->locator_name
, s
, len
);
1107 STREAM_GETW(s
, c
->prefix
.prefixlen
);
1108 STREAM_GET(&c
->prefix
.prefix
, s
, sizeof(c
->prefix
.prefix
));
1109 STREAM_GETC(s
, c
->block_bits_length
);
1110 STREAM_GETC(s
, c
->node_bits_length
);
1111 STREAM_GETC(s
, c
->function_bits_length
);
1112 STREAM_GETC(s
, c
->argument_bits_length
);
1113 STREAM_GETC(s
, c
->flags
);
1120 int zapi_srv6_locator_encode(struct stream
*s
, const struct srv6_locator
*l
)
1122 stream_putw(s
, strlen(l
->name
));
1123 stream_put(s
, l
->name
, strlen(l
->name
));
1124 stream_putw(s
, l
->prefix
.prefixlen
);
1125 stream_put(s
, &l
->prefix
.prefix
, sizeof(l
->prefix
.prefix
));
1129 int zapi_srv6_locator_decode(struct stream
*s
, struct srv6_locator
*l
)
1133 STREAM_GETW(s
, len
);
1134 if (len
> SRV6_LOCNAME_SIZE
)
1135 goto stream_failure
;
1137 STREAM_GET(l
->name
, s
, len
);
1138 STREAM_GETW(s
, l
->prefix
.prefixlen
);
1139 STREAM_GET(&l
->prefix
.prefix
, s
, sizeof(l
->prefix
.prefix
));
1140 l
->prefix
.family
= AF_INET6
;
1147 static int zapi_nhg_encode(struct stream
*s
, int cmd
, struct zapi_nhg
*api_nhg
)
1151 if (cmd
!= ZEBRA_NHG_DEL
&& cmd
!= ZEBRA_NHG_ADD
) {
1152 flog_err(EC_LIB_ZAPI_ENCODE
,
1153 "%s: Specified zapi NHG command (%d) doesn't exist",
1158 if (api_nhg
->nexthop_num
>= MULTIPATH_NUM
||
1159 api_nhg
->backup_nexthop_num
>= MULTIPATH_NUM
) {
1160 flog_err(EC_LIB_ZAPI_ENCODE
,
1161 "%s: zapi NHG encode with invalid input", __func__
);
1166 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
1168 stream_putw(s
, api_nhg
->proto
);
1169 stream_putl(s
, api_nhg
->id
);
1171 if (cmd
== ZEBRA_NHG_ADD
) {
1173 zapi_nexthop_group_sort(api_nhg
->nexthops
,
1174 api_nhg
->nexthop_num
);
1176 stream_putw(s
, api_nhg
->nexthop_num
);
1178 for (i
= 0; i
< api_nhg
->nexthop_num
; i
++)
1179 zapi_nexthop_encode(s
, &api_nhg
->nexthops
[i
], 0, 0);
1181 /* Backup nexthops */
1182 stream_putw(s
, api_nhg
->backup_nexthop_num
);
1184 for (i
= 0; i
< api_nhg
->backup_nexthop_num
; i
++)
1185 zapi_nexthop_encode(s
, &api_nhg
->backup_nexthops
[i
], 0,
1189 stream_putw_at(s
, 0, stream_get_endp(s
));
1194 enum zclient_send_status
zclient_nhg_send(struct zclient
*zclient
, int cmd
,
1195 struct zapi_nhg
*api_nhg
)
1197 api_nhg
->proto
= zclient
->redist_default
;
1199 if (zapi_nhg_encode(zclient
->obuf
, cmd
, api_nhg
))
1202 return zclient_send_message(zclient
);
1205 int zapi_route_encode(uint8_t cmd
, struct stream
*s
, struct zapi_route
*api
)
1207 struct zapi_nexthop
*api_nh
;
1212 zclient_create_header(s
, cmd
, api
->vrf_id
);
1214 if (api
->type
>= ZEBRA_ROUTE_MAX
) {
1215 flog_err(EC_LIB_ZAPI_ENCODE
,
1216 "%s: Specified route type (%u) is not a legal value",
1217 __func__
, api
->type
);
1220 stream_putc(s
, api
->type
);
1222 stream_putw(s
, api
->instance
);
1223 stream_putl(s
, api
->flags
);
1224 stream_putl(s
, api
->message
);
1226 if (api
->safi
< SAFI_UNICAST
|| api
->safi
>= SAFI_MAX
) {
1227 flog_err(EC_LIB_ZAPI_ENCODE
,
1228 "%s: Specified route SAFI (%u) is not a legal value",
1229 __func__
, api
->safi
);
1232 stream_putc(s
, api
->safi
);
1234 /* Put prefix information. */
1235 stream_putc(s
, api
->prefix
.family
);
1236 psize
= PSIZE(api
->prefix
.prefixlen
);
1237 stream_putc(s
, api
->prefix
.prefixlen
);
1238 stream_write(s
, &api
->prefix
.u
.prefix
, psize
);
1240 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_SRCPFX
)) {
1241 psize
= PSIZE(api
->src_prefix
.prefixlen
);
1242 stream_putc(s
, api
->src_prefix
.prefixlen
);
1243 stream_write(s
, (uint8_t *)&api
->src_prefix
.prefix
, psize
);
1246 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_NHG
))
1247 stream_putl(s
, api
->nhgid
);
1250 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_NEXTHOP
)) {
1251 /* limit the number of nexthops if necessary */
1252 if (api
->nexthop_num
> MULTIPATH_NUM
) {
1255 "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)",
1256 __func__
, &api
->prefix
, api
->nexthop_num
,
1261 /* We canonicalize the nexthops by sorting them; this allows
1262 * zebra to resolve the list of nexthops to a nexthop-group
1265 zapi_nexthop_group_sort(api
->nexthops
, api
->nexthop_num
);
1267 stream_putw(s
, api
->nexthop_num
);
1269 for (i
= 0; i
< api
->nexthop_num
; i
++) {
1270 api_nh
= &api
->nexthops
[i
];
1272 /* MPLS labels for BGP-LU or Segment Routing */
1273 if (api_nh
->label_num
> MPLS_MAX_LABELS
) {
1276 "%s: prefix %pFX: can't encode %u labels (maximum is %u)",
1277 __func__
, &api
->prefix
,
1278 api_nh
->label_num
, MPLS_MAX_LABELS
);
1282 if (zapi_nexthop_encode(s
, api_nh
, api
->flags
,
1289 /* Backup nexthops */
1290 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_BACKUP_NEXTHOPS
)) {
1291 /* limit the number of nexthops if necessary */
1292 if (api
->backup_nexthop_num
> MULTIPATH_NUM
) {
1295 "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)",
1296 __func__
, &api
->prefix
, api
->backup_nexthop_num
,
1301 /* Note that we do not sort the list of backup nexthops -
1302 * this list is treated as an array and indexed by each
1303 * primary nexthop that is associated with a backup.
1306 stream_putw(s
, api
->backup_nexthop_num
);
1308 for (i
= 0; i
< api
->backup_nexthop_num
; i
++) {
1309 api_nh
= &api
->backup_nexthops
[i
];
1311 /* MPLS labels for BGP-LU or Segment Routing */
1312 if (api_nh
->label_num
> MPLS_MAX_LABELS
) {
1315 "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)",
1316 __func__
, &api
->prefix
,
1317 api_nh
->label_num
, MPLS_MAX_LABELS
);
1321 if (zapi_nexthop_encode(s
, api_nh
, api
->flags
,
1329 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_DISTANCE
))
1330 stream_putc(s
, api
->distance
);
1331 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_METRIC
))
1332 stream_putl(s
, api
->metric
);
1333 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_TAG
))
1334 stream_putl(s
, api
->tag
);
1335 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_MTU
))
1336 stream_putl(s
, api
->mtu
);
1337 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_TABLEID
))
1338 stream_putl(s
, api
->tableid
);
1340 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_OPAQUE
)) {
1341 if (api
->opaque
.length
> ZAPI_MESSAGE_OPAQUE_LENGTH
) {
1344 "%s: opaque length %u is greater than allowed value",
1345 __func__
, api
->opaque
.length
);
1349 stream_putw(s
, api
->opaque
.length
);
1350 stream_write(s
, api
->opaque
.data
, api
->opaque
.length
);
1352 /* Put length at the first point of the stream. */
1353 stream_putw_at(s
, 0, stream_get_endp(s
));
1359 * Decode a single zapi nexthop object
1361 int zapi_nexthop_decode(struct stream
*s
, struct zapi_nexthop
*api_nh
,
1362 uint32_t api_flags
, uint32_t api_message
)
1366 STREAM_GETL(s
, api_nh
->vrf_id
);
1367 STREAM_GETC(s
, api_nh
->type
);
1369 /* Note that we're only using a single octet of flags */
1370 STREAM_GETC(s
, api_nh
->flags
);
1372 switch (api_nh
->type
) {
1373 case NEXTHOP_TYPE_BLACKHOLE
:
1374 STREAM_GETC(s
, api_nh
->bh_type
);
1376 case NEXTHOP_TYPE_IPV4
:
1377 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1378 STREAM_GET(&api_nh
->gate
.ipv4
.s_addr
, s
,
1380 STREAM_GETL(s
, api_nh
->ifindex
);
1382 case NEXTHOP_TYPE_IFINDEX
:
1383 STREAM_GETL(s
, api_nh
->ifindex
);
1385 case NEXTHOP_TYPE_IPV6
:
1386 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1387 STREAM_GET(&api_nh
->gate
.ipv6
, s
, 16);
1388 STREAM_GETL(s
, api_nh
->ifindex
);
1392 /* MPLS labels for BGP-LU or Segment Routing */
1393 if (CHECK_FLAG(api_nh
->flags
, ZAPI_NEXTHOP_FLAG_LABEL
)) {
1394 STREAM_GETC(s
, api_nh
->label_num
);
1395 if (api_nh
->label_num
> MPLS_MAX_LABELS
) {
1398 "%s: invalid number of MPLS labels (%u)",
1399 __func__
, api_nh
->label_num
);
1403 STREAM_GET(&api_nh
->labels
[0], s
,
1404 api_nh
->label_num
* sizeof(mpls_label_t
));
1407 if (CHECK_FLAG(api_nh
->flags
, ZAPI_NEXTHOP_FLAG_WEIGHT
))
1408 STREAM_GETL(s
, api_nh
->weight
);
1410 /* Router MAC for EVPN routes. */
1411 if (CHECK_FLAG(api_nh
->flags
, ZAPI_NEXTHOP_FLAG_EVPN
))
1412 STREAM_GET(&(api_nh
->rmac
), s
,
1413 sizeof(struct ethaddr
));
1415 /* Color for Segment Routing TE. */
1416 if (CHECK_FLAG(api_message
, ZAPI_MESSAGE_SRTE
))
1417 STREAM_GETL(s
, api_nh
->srte_color
);
1419 /* Backup nexthop index */
1420 if (CHECK_FLAG(api_nh
->flags
, ZAPI_NEXTHOP_FLAG_HAS_BACKUP
)) {
1421 STREAM_GETC(s
, api_nh
->backup_num
);
1423 if (api_nh
->backup_num
> NEXTHOP_MAX_BACKUPS
)
1426 for (i
= 0; i
< api_nh
->backup_num
; i
++)
1427 STREAM_GETC(s
, api_nh
->backup_idx
[i
]);
1430 if (CHECK_FLAG(api_nh
->flags
, ZAPI_NEXTHOP_FLAG_SEG6LOCAL
)) {
1431 STREAM_GETL(s
, api_nh
->seg6local_action
);
1432 STREAM_GET(&api_nh
->seg6local_ctx
, s
,
1433 sizeof(struct seg6local_context
));
1436 if (CHECK_FLAG(api_nh
->flags
, ZAPI_NEXTHOP_FLAG_SEG6
))
1437 STREAM_GET(&api_nh
->seg6_segs
, s
,
1438 sizeof(struct in6_addr
));
1448 int zapi_route_decode(struct stream
*s
, struct zapi_route
*api
)
1450 struct zapi_nexthop
*api_nh
;
1453 memset(api
, 0, sizeof(*api
));
1455 /* Type, flags, message. */
1456 STREAM_GETC(s
, api
->type
);
1457 if (api
->type
>= ZEBRA_ROUTE_MAX
) {
1458 flog_err(EC_LIB_ZAPI_ENCODE
,
1459 "%s: Specified route type: %d is not a legal value",
1460 __func__
, api
->type
);
1464 STREAM_GETW(s
, api
->instance
);
1465 STREAM_GETL(s
, api
->flags
);
1466 STREAM_GETL(s
, api
->message
);
1467 STREAM_GETC(s
, api
->safi
);
1468 if (api
->safi
< SAFI_UNICAST
|| api
->safi
>= SAFI_MAX
) {
1469 flog_err(EC_LIB_ZAPI_ENCODE
,
1470 "%s: Specified route SAFI (%u) is not a legal value",
1471 __func__
, api
->safi
);
1476 STREAM_GETC(s
, api
->prefix
.family
);
1477 STREAM_GETC(s
, api
->prefix
.prefixlen
);
1478 switch (api
->prefix
.family
) {
1480 if (api
->prefix
.prefixlen
> IPV4_MAX_BITLEN
) {
1483 "%s: V4 prefixlen is %d which should not be more than 32",
1484 __func__
, api
->prefix
.prefixlen
);
1489 if (api
->prefix
.prefixlen
> IPV6_MAX_BITLEN
) {
1492 "%s: v6 prefixlen is %d which should not be more than 128",
1493 __func__
, api
->prefix
.prefixlen
);
1498 flog_err(EC_LIB_ZAPI_ENCODE
,
1499 "%s: Specified family %d is not v4 or v6", __func__
,
1500 api
->prefix
.family
);
1503 STREAM_GET(&api
->prefix
.u
.prefix
, s
, PSIZE(api
->prefix
.prefixlen
));
1505 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_SRCPFX
)) {
1506 api
->src_prefix
.family
= AF_INET6
;
1507 STREAM_GETC(s
, api
->src_prefix
.prefixlen
);
1508 if (api
->src_prefix
.prefixlen
> IPV6_MAX_BITLEN
) {
1511 "%s: SRC Prefix prefixlen received: %d is too large",
1512 __func__
, api
->src_prefix
.prefixlen
);
1515 STREAM_GET(&api
->src_prefix
.prefix
, s
,
1516 PSIZE(api
->src_prefix
.prefixlen
));
1518 if (api
->prefix
.family
!= AF_INET6
1519 || api
->src_prefix
.prefixlen
== 0) {
1522 "%s: SRC prefix specified in some manner that makes no sense",
1528 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_NHG
))
1529 STREAM_GETL(s
, api
->nhgid
);
1532 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_NEXTHOP
)) {
1533 STREAM_GETW(s
, api
->nexthop_num
);
1534 if (api
->nexthop_num
> MULTIPATH_NUM
) {
1535 flog_err(EC_LIB_ZAPI_ENCODE
,
1536 "%s: invalid number of nexthops (%u)",
1537 __func__
, api
->nexthop_num
);
1541 for (i
= 0; i
< api
->nexthop_num
; i
++) {
1542 api_nh
= &api
->nexthops
[i
];
1544 if (zapi_nexthop_decode(s
, api_nh
, api
->flags
,
1551 /* Backup nexthops. */
1552 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_BACKUP_NEXTHOPS
)) {
1553 STREAM_GETW(s
, api
->backup_nexthop_num
);
1554 if (api
->backup_nexthop_num
> MULTIPATH_NUM
) {
1555 flog_err(EC_LIB_ZAPI_ENCODE
,
1556 "%s: invalid number of backup nexthops (%u)",
1557 __func__
, api
->backup_nexthop_num
);
1561 for (i
= 0; i
< api
->backup_nexthop_num
; i
++) {
1562 api_nh
= &api
->backup_nexthops
[i
];
1564 if (zapi_nexthop_decode(s
, api_nh
, api
->flags
,
1572 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_DISTANCE
))
1573 STREAM_GETC(s
, api
->distance
);
1574 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_METRIC
))
1575 STREAM_GETL(s
, api
->metric
);
1576 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_TAG
))
1577 STREAM_GETL(s
, api
->tag
);
1578 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_MTU
))
1579 STREAM_GETL(s
, api
->mtu
);
1580 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_TABLEID
))
1581 STREAM_GETL(s
, api
->tableid
);
1583 if (CHECK_FLAG(api
->message
, ZAPI_MESSAGE_OPAQUE
)) {
1584 STREAM_GETW(s
, api
->opaque
.length
);
1585 if (api
->opaque
.length
> ZAPI_MESSAGE_OPAQUE_LENGTH
) {
1588 "%s: opaque length %u is greater than allowed value",
1589 __func__
, api
->opaque
.length
);
1593 STREAM_GET(api
->opaque
.data
, s
, api
->opaque
.length
);
1601 static void zapi_encode_prefix(struct stream
*s
, struct prefix
*p
,
1607 memset(&any
, 0, sizeof(any
));
1608 any
.family
= family
;
1612 stream_putc(s
, p
->family
);
1613 stream_putc(s
, p
->prefixlen
);
1614 stream_put(s
, &p
->u
.prefix
, prefix_blen(p
));
1617 int zapi_pbr_rule_encode(uint8_t cmd
, struct stream
*s
, struct pbr_rule
*zrule
)
1620 zclient_create_header(s
, cmd
, zrule
->vrf_id
);
1623 * We are sending one item at a time at the moment
1627 stream_putl(s
, zrule
->seq
);
1628 stream_putl(s
, zrule
->priority
);
1629 stream_putl(s
, zrule
->unique
);
1631 zapi_encode_prefix(s
, &(zrule
->filter
.src_ip
),
1632 zrule
->filter
.src_ip
.family
);
1633 stream_putw(s
, zrule
->filter
.src_port
); /* src port */
1634 zapi_encode_prefix(s
, &(zrule
->filter
.dst_ip
),
1635 zrule
->filter
.src_ip
.family
);
1636 stream_putw(s
, zrule
->filter
.dst_port
); /* dst port */
1637 stream_putw(s
, zrule
->filter
.fwmark
); /* fwmark */
1639 stream_putl(s
, zrule
->action
.table
);
1640 stream_put(s
, zrule
->ifname
, INTERFACE_NAMSIZ
);
1642 /* Put length at the first point of the stream. */
1643 stream_putw_at(s
, 0, stream_get_endp(s
));
1648 bool zapi_nhg_notify_decode(struct stream
*s
, uint32_t *id
,
1649 enum zapi_nhg_notify_owner
*note
)
1653 STREAM_GET(note
, s
, sizeof(*note
));
1654 STREAM_GETL(s
, read_id
);
1664 bool zapi_route_notify_decode(struct stream
*s
, struct prefix
*p
,
1666 enum zapi_route_notify_owner
*note
,
1667 afi_t
*afi
, safi_t
*safi
)
1673 STREAM_GET(note
, s
, sizeof(*note
));
1675 STREAM_GETC(s
, p
->family
);
1676 STREAM_GETC(s
, p
->prefixlen
);
1677 STREAM_GET(&p
->u
.prefix
, s
, prefix_blen(p
));
1679 STREAM_GETC(s
, afi_val
);
1680 STREAM_GETC(s
, safi_val
);
1695 bool zapi_rule_notify_decode(struct stream
*s
, uint32_t *seqno
,
1696 uint32_t *priority
, uint32_t *unique
, char *ifname
,
1697 enum zapi_rule_notify_owner
*note
)
1699 uint32_t prio
, seq
, uni
;
1701 STREAM_GET(note
, s
, sizeof(*note
));
1703 STREAM_GETL(s
, seq
);
1704 STREAM_GETL(s
, prio
);
1705 STREAM_GETL(s
, uni
);
1706 STREAM_GET(ifname
, s
, INTERFACE_NAMSIZ
);
1709 zlog_debug("%s: %u %u %u %s", __func__
, seq
, prio
, uni
, ifname
);
1720 bool zapi_ipset_notify_decode(struct stream
*s
, uint32_t *unique
,
1721 enum zapi_ipset_notify_owner
*note
)
1726 STREAM_GETW(s
, notew
);
1728 STREAM_GETL(s
, uni
);
1731 zlog_debug("%s: %u", __func__
, uni
);
1733 *note
= (enum zapi_ipset_notify_owner
)notew
;
1740 bool zapi_ipset_entry_notify_decode(struct stream
*s
, uint32_t *unique
,
1742 enum zapi_ipset_entry_notify_owner
*note
)
1747 STREAM_GETW(s
, notew
);
1749 STREAM_GETL(s
, uni
);
1751 STREAM_GET(ipset_name
, s
, ZEBRA_IPSET_NAME_SIZE
);
1754 zlog_debug("%s: %u", __func__
, uni
);
1756 *note
= (enum zapi_ipset_entry_notify_owner
)notew
;
1764 bool zapi_iptable_notify_decode(struct stream
*s
,
1766 enum zapi_iptable_notify_owner
*note
)
1771 STREAM_GETW(s
, notew
);
1773 STREAM_GETL(s
, uni
);
1776 zlog_debug("%s: %u", __func__
, uni
);
1778 *note
= (enum zapi_iptable_notify_owner
)notew
;
1786 struct nexthop
*nexthop_from_zapi_nexthop(const struct zapi_nexthop
*znh
)
1788 struct nexthop
*n
= nexthop_new();
1790 n
->type
= znh
->type
;
1791 n
->vrf_id
= znh
->vrf_id
;
1792 n
->ifindex
= znh
->ifindex
;
1793 n
->gate
= znh
->gate
;
1794 n
->srte_color
= znh
->srte_color
;
1797 * This function currently handles labels
1799 if (znh
->label_num
) {
1800 nexthop_add_labels(n
, ZEBRA_LSP_NONE
, znh
->label_num
,
1804 if (CHECK_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_HAS_BACKUP
)) {
1805 SET_FLAG(n
->flags
, NEXTHOP_FLAG_HAS_BACKUP
);
1806 n
->backup_num
= znh
->backup_num
;
1807 memcpy(n
->backup_idx
, znh
->backup_idx
, n
->backup_num
);
1810 if (znh
->seg6local_action
!= ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
)
1811 nexthop_add_srv6_seg6local(n
, znh
->seg6local_action
,
1812 &znh
->seg6local_ctx
);
1814 if (!sid_zero(&znh
->seg6_segs
))
1815 nexthop_add_srv6_seg6(n
, &znh
->seg6_segs
);
1821 * Convert nexthop to zapi nexthop
1823 int zapi_nexthop_from_nexthop(struct zapi_nexthop
*znh
,
1824 const struct nexthop
*nh
)
1828 memset(znh
, 0, sizeof(*znh
));
1830 znh
->type
= nh
->type
;
1831 znh
->vrf_id
= nh
->vrf_id
;
1832 znh
->weight
= nh
->weight
;
1833 znh
->ifindex
= nh
->ifindex
;
1834 znh
->gate
= nh
->gate
;
1836 if (CHECK_FLAG(nh
->flags
, NEXTHOP_FLAG_ONLINK
))
1837 SET_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_ONLINK
);
1839 if (CHECK_FLAG(nh
->flags
, NEXTHOP_FLAG_EVPN
))
1840 SET_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_EVPN
);
1842 if (nh
->nh_label
&& (nh
->nh_label
->num_labels
> 0)) {
1845 if (nh
->nh_label
->num_labels
> MPLS_MAX_LABELS
)
1848 for (i
= 0; i
< nh
->nh_label
->num_labels
; i
++)
1849 znh
->labels
[i
] = nh
->nh_label
->label
[i
];
1852 SET_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_LABEL
);
1855 if (CHECK_FLAG(nh
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
1856 if (nh
->backup_num
> NEXTHOP_MAX_BACKUPS
)
1859 SET_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_HAS_BACKUP
);
1860 znh
->backup_num
= nh
->backup_num
;
1861 memcpy(znh
->backup_idx
, nh
->backup_idx
, znh
->backup_num
);
1865 if (nh
->nh_srv6
->seg6local_action
!=
1866 ZEBRA_SEG6_LOCAL_ACTION_UNSPEC
) {
1867 SET_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_SEG6LOCAL
);
1868 znh
->seg6local_action
= nh
->nh_srv6
->seg6local_action
;
1869 memcpy(&znh
->seg6local_ctx
,
1870 &nh
->nh_srv6
->seg6local_ctx
,
1871 sizeof(struct seg6local_context
));
1874 if (!sid_zero(&nh
->nh_srv6
->seg6_segs
)) {
1875 SET_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_SEG6
);
1876 memcpy(&znh
->seg6_segs
, &nh
->nh_srv6
->seg6_segs
,
1877 sizeof(struct in6_addr
));
1885 * Wrapper that converts backup nexthop
1887 int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop
*znh
,
1888 const struct nexthop
*nh
)
1892 /* Ensure that zapi flags are correct: backups don't have backups */
1893 ret
= zapi_nexthop_from_nexthop(znh
, nh
);
1895 UNSET_FLAG(znh
->flags
, ZAPI_NEXTHOP_FLAG_HAS_BACKUP
);
1901 * Format some info about a zapi nexthop, for debug or logging.
1903 const char *zapi_nexthop2str(const struct zapi_nexthop
*znh
, char *buf
,
1906 char tmp
[INET6_ADDRSTRLEN
];
1908 switch (znh
->type
) {
1909 case NEXTHOP_TYPE_IFINDEX
:
1910 snprintf(buf
, bufsize
, "if %u", znh
->ifindex
);
1912 case NEXTHOP_TYPE_IPV4
:
1913 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1914 inet_ntop(AF_INET
, &znh
->gate
.ipv4
, tmp
, sizeof(tmp
));
1915 snprintf(buf
, bufsize
, "%s if %u", tmp
, znh
->ifindex
);
1917 case NEXTHOP_TYPE_IPV6
:
1918 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1919 inet_ntop(AF_INET6
, &znh
->gate
.ipv6
, tmp
, sizeof(tmp
));
1920 snprintf(buf
, bufsize
, "%s if %u", tmp
, znh
->ifindex
);
1922 case NEXTHOP_TYPE_BLACKHOLE
:
1923 snprintf(buf
, bufsize
, "blackhole");
1926 snprintf(buf
, bufsize
, "unknown");
1934 * Decode the nexthop-tracking update message
1936 bool zapi_nexthop_update_decode(struct stream
*s
, struct prefix
*match
,
1937 struct zapi_route
*nhr
)
1941 memset(nhr
, 0, sizeof(*nhr
));
1943 STREAM_GETL(s
, nhr
->message
);
1944 STREAM_GETW(s
, nhr
->safi
);
1945 STREAM_GETW(s
, match
->family
);
1946 STREAM_GETC(s
, match
->prefixlen
);
1948 * What we got told to match against
1950 switch (match
->family
) {
1952 STREAM_GET(&match
->u
.prefix4
.s_addr
, s
, IPV4_MAX_BYTELEN
);
1955 STREAM_GET(&match
->u
.prefix6
, s
, IPV6_MAX_BYTELEN
);
1959 * What we matched against
1961 STREAM_GETW(s
, nhr
->prefix
.family
);
1962 STREAM_GETC(s
, nhr
->prefix
.prefixlen
);
1963 switch (nhr
->prefix
.family
) {
1965 STREAM_GET(&nhr
->prefix
.u
.prefix4
.s_addr
, s
, IPV4_MAX_BYTELEN
);
1968 STREAM_GET(&nhr
->prefix
.u
.prefix6
, s
, IPV6_MAX_BYTELEN
);
1973 if (CHECK_FLAG(nhr
->message
, ZAPI_MESSAGE_SRTE
))
1974 STREAM_GETL(s
, nhr
->srte_color
);
1976 STREAM_GETC(s
, nhr
->type
);
1977 STREAM_GETW(s
, nhr
->instance
);
1978 STREAM_GETC(s
, nhr
->distance
);
1979 STREAM_GETL(s
, nhr
->metric
);
1980 STREAM_GETC(s
, nhr
->nexthop_num
);
1982 for (i
= 0; i
< nhr
->nexthop_num
; i
++) {
1983 if (zapi_nexthop_decode(s
, &(nhr
->nexthops
[i
]), 0, 0) != 0)
1992 bool zapi_error_decode(struct stream
*s
, enum zebra_error_types
*error
)
1994 memset(error
, 0, sizeof(*error
));
1996 STREAM_GET(error
, s
, sizeof(*error
));
1999 zlog_debug("%s: type: %s", __func__
,
2000 zebra_error_type2str(*error
));
2008 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
2009 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
2010 * then set/unset redist[type] in the client handle (a struct zserv) for the
2013 enum zclient_send_status
2014 zebra_redistribute_send(int command
, struct zclient
*zclient
, afi_t afi
,
2015 int type
, unsigned short instance
, vrf_id_t vrf_id
)
2022 zclient_create_header(s
, command
, vrf_id
);
2023 stream_putc(s
, afi
);
2024 stream_putc(s
, type
);
2025 stream_putw(s
, instance
);
2027 stream_putw_at(s
, 0, stream_get_endp(s
));
2029 return zclient_send_message(zclient
);
2032 enum zclient_send_status
2033 zebra_redistribute_default_send(int command
, struct zclient
*zclient
, afi_t afi
,
2041 zclient_create_header(s
, command
, vrf_id
);
2042 stream_putc(s
, afi
);
2044 stream_putw_at(s
, 0, stream_get_endp(s
));
2046 return zclient_send_message(zclient
);
2049 /* Send route notify request to zebra */
2050 int zebra_route_notify_send(int command
, struct zclient
*zclient
, bool set
)
2057 zclient_create_header(s
, command
, 0);
2058 stream_putc(s
, !!set
);
2060 stream_putw_at(s
, 0, stream_get_endp(s
));
2062 return zclient_send_message(zclient
);
2065 /* Get prefix in ZServ format; family should be filled in on prefix */
2066 static int zclient_stream_get_prefix(struct stream
*s
, struct prefix
*p
)
2068 size_t plen
= prefix_blen(p
);
2075 STREAM_GET(&p
->u
.prefix
, s
, plen
);
2077 p
->prefixlen
= MIN(plen
* 8, c
);
2084 /* Router-id update from zebra daemon. */
2085 int zebra_router_id_update_read(struct stream
*s
, struct prefix
*rid
)
2087 /* Fetch interface address. */
2088 STREAM_GETC(s
, rid
->family
);
2090 return zclient_stream_get_prefix(s
, rid
);
2096 /* Interface addition from zebra daemon. */
2098 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
2099 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
2101 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2102 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2108 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2110 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2112 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2115 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2117 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2119 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2121 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2123 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2125 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2126 * | parent ifindex |
2127 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2128 * | Link Layer Type |
2129 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2130 * | Harware Address Length |
2131 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2132 * | Hardware Address if HW length different from 0 |
2133 * | ... max INTERFACE_HWADDR_MAX |
2134 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2135 * | Link_params? | Whether a link-params follows: 1 or 0.
2136 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2137 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
2138 * | .... (struct if_link_params). |
2139 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2142 static int zclient_vrf_add(ZAPI_CALLBACK_ARGS
)
2145 char vrfname_tmp
[VRF_NAMSIZ
+ 1] = {};
2146 struct vrf_data data
;
2148 STREAM_GET(&data
, zclient
->ibuf
, sizeof(struct vrf_data
));
2149 /* Read interface name. */
2150 STREAM_GET(vrfname_tmp
, zclient
->ibuf
, VRF_NAMSIZ
);
2152 if (strlen(vrfname_tmp
) == 0)
2153 goto stream_failure
;
2155 /* Lookup/create vrf by name, then vrf_id. */
2156 vrf
= vrf_get(vrf_id
, vrfname_tmp
);
2158 /* If there's already a VRF with this name, don't create vrf */
2162 vrf
->data
.l
.table_id
= data
.l
.table_id
;
2163 memcpy(vrf
->data
.l
.netns_name
, data
.l
.netns_name
, NS_NAMSIZ
);
2171 static int zclient_vrf_delete(ZAPI_CALLBACK_ARGS
)
2175 /* Lookup vrf by vrf_id. */
2176 vrf
= vrf_lookup_by_id(vrf_id
);
2179 * If a routing protocol doesn't know about a
2180 * vrf that is about to be deleted. There is
2181 * no point in attempting to delete it.
2190 static int zclient_interface_add(ZAPI_CALLBACK_ARGS
)
2192 struct interface
*ifp
;
2193 char ifname_tmp
[INTERFACE_NAMSIZ
+ 1] = {};
2194 struct stream
*s
= zclient
->ibuf
;
2197 /* Read interface name. */
2198 STREAM_GET(ifname_tmp
, s
, INTERFACE_NAMSIZ
);
2200 /* Lookup/create interface by name. */
2201 vrf
= vrf_lookup_by_id(vrf_id
);
2204 "Rx'd interface add from Zebra, but VRF %u does not exist",
2209 ifp
= if_get_by_name(ifname_tmp
, vrf_id
, vrf
->name
);
2211 zebra_interface_if_set_value(s
, ifp
);
2213 if_new_via_zapi(ifp
);
2221 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
2222 * from zebra server. The format of this message is the same as
2223 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
2224 * except that no sockaddr_dl is sent at the tail of the message.
2226 struct interface
*zebra_interface_state_read(struct stream
*s
, vrf_id_t vrf_id
)
2228 struct interface
*ifp
;
2229 char ifname_tmp
[INTERFACE_NAMSIZ
+ 1] = {};
2231 /* Read interface name. */
2232 STREAM_GET(ifname_tmp
, s
, INTERFACE_NAMSIZ
);
2234 /* Lookup this by interface index. */
2235 ifp
= if_lookup_by_name(ifname_tmp
, vrf_id
);
2237 flog_err(EC_LIB_ZAPI_ENCODE
,
2238 "INTERFACE_STATE: Cannot find IF %s in VRF %d",
2239 ifname_tmp
, vrf_id
);
2243 zebra_interface_if_set_value(s
, ifp
);
2250 static int zclient_interface_delete(ZAPI_CALLBACK_ARGS
)
2252 struct interface
*ifp
;
2253 struct stream
*s
= zclient
->ibuf
;
2255 ifp
= zebra_interface_state_read(s
, vrf_id
);
2260 if_destroy_via_zapi(ifp
);
2264 static int zclient_interface_up(ZAPI_CALLBACK_ARGS
)
2266 struct interface
*ifp
;
2267 struct stream
*s
= zclient
->ibuf
;
2269 ifp
= zebra_interface_state_read(s
, vrf_id
);
2274 if_up_via_zapi(ifp
);
2278 static int zclient_interface_down(ZAPI_CALLBACK_ARGS
)
2280 struct interface
*ifp
;
2281 struct stream
*s
= zclient
->ibuf
;
2283 ifp
= zebra_interface_state_read(s
, vrf_id
);
2288 if_down_via_zapi(ifp
);
2292 static int zclient_handle_error(ZAPI_CALLBACK_ARGS
)
2294 enum zebra_error_types error
;
2295 struct stream
*s
= zclient
->ibuf
;
2297 zapi_error_decode(s
, &error
);
2299 if (zclient
->handle_error
)
2300 (*zclient
->handle_error
)(error
);
2304 static int link_params_set_value(struct stream
*s
, struct if_link_params
*iflp
)
2310 uint32_t bwclassnum
;
2312 STREAM_GETL(s
, iflp
->lp_status
);
2313 STREAM_GETL(s
, iflp
->te_metric
);
2314 STREAM_GETF(s
, iflp
->max_bw
);
2315 STREAM_GETF(s
, iflp
->max_rsv_bw
);
2316 STREAM_GETL(s
, bwclassnum
);
2319 for (i
= 0; i
< bwclassnum
&& i
< MAX_CLASS_TYPE
; i
++)
2320 STREAM_GETF(s
, iflp
->unrsv_bw
[i
]);
2323 EC_LIB_ZAPI_MISSMATCH
,
2324 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries - outdated library?",
2325 __func__
, bwclassnum
, MAX_CLASS_TYPE
);
2327 STREAM_GETL(s
, iflp
->admin_grp
);
2328 STREAM_GETL(s
, iflp
->rmt_as
);
2329 iflp
->rmt_ip
.s_addr
= stream_get_ipv4(s
);
2331 STREAM_GETL(s
, iflp
->av_delay
);
2332 STREAM_GETL(s
, iflp
->min_delay
);
2333 STREAM_GETL(s
, iflp
->max_delay
);
2334 STREAM_GETL(s
, iflp
->delay_var
);
2336 STREAM_GETF(s
, iflp
->pkt_loss
);
2337 STREAM_GETF(s
, iflp
->res_bw
);
2338 STREAM_GETF(s
, iflp
->ava_bw
);
2339 STREAM_GETF(s
, iflp
->use_bw
);
2346 struct interface
*zebra_interface_link_params_read(struct stream
*s
,
2350 struct if_link_params
*iflp
;
2351 struct if_link_params iflp_copy
;
2353 bool params_changed
= false;
2355 STREAM_GETL(s
, ifindex
);
2357 struct interface
*ifp
= if_lookup_by_index(ifindex
, vrf_id
);
2360 flog_err(EC_LIB_ZAPI_ENCODE
,
2361 "%s: unknown ifindex %u, shouldn't happen", __func__
,
2366 if (ifp
->link_params
== NULL
)
2367 params_changed
= true;
2369 if ((iflp
= if_link_params_get(ifp
)) == NULL
)
2372 memcpy(&iflp_copy
, iflp
, sizeof(iflp_copy
));
2374 if (link_params_set_value(s
, iflp
) != 0)
2375 goto stream_failure
;
2377 if (memcmp(&iflp_copy
, iflp
, sizeof(iflp_copy
)))
2378 params_changed
= true;
2381 *changed
= params_changed
;
2389 static void zebra_interface_if_set_value(struct stream
*s
,
2390 struct interface
*ifp
)
2392 uint8_t link_params_status
= 0;
2393 ifindex_t old_ifindex
, new_ifindex
;
2395 old_ifindex
= ifp
->oldifindex
;
2396 /* Read interface's index. */
2397 STREAM_GETL(s
, new_ifindex
);
2398 if_set_index(ifp
, new_ifindex
);
2399 STREAM_GETC(s
, ifp
->status
);
2401 /* Read interface's value. */
2402 STREAM_GETQ(s
, ifp
->flags
);
2403 STREAM_GETC(s
, ifp
->ptm_enable
);
2404 STREAM_GETC(s
, ifp
->ptm_status
);
2405 STREAM_GETL(s
, ifp
->metric
);
2406 STREAM_GETL(s
, ifp
->speed
);
2407 STREAM_GETL(s
, ifp
->mtu
);
2408 STREAM_GETL(s
, ifp
->mtu6
);
2409 STREAM_GETL(s
, ifp
->bandwidth
);
2410 STREAM_GETL(s
, ifp
->link_ifindex
);
2411 STREAM_GETL(s
, ifp
->ll_type
);
2412 STREAM_GETL(s
, ifp
->hw_addr_len
);
2413 if (ifp
->hw_addr_len
)
2414 STREAM_GET(ifp
->hw_addr
, s
,
2415 MIN(ifp
->hw_addr_len
, INTERFACE_HWADDR_MAX
));
2417 /* Read Traffic Engineering status */
2418 link_params_status
= stream_getc(s
);
2419 /* Then, Traffic Engineering parameters if any */
2420 if (link_params_status
) {
2421 struct if_link_params
*iflp
= if_link_params_get(ifp
);
2422 link_params_set_value(s
, iflp
);
2425 nexthop_group_interface_state_change(ifp
, old_ifindex
);
2429 zlog_err("Could not parse interface values; aborting");
2430 assert(!"Failed to parse interface values");
2433 size_t zebra_interface_link_params_write(struct stream
*s
,
2434 struct interface
*ifp
)
2437 struct if_link_params
*iflp
;
2440 if (s
== NULL
|| ifp
== NULL
|| ifp
->link_params
== NULL
)
2443 iflp
= ifp
->link_params
;
2446 w
+= stream_putl(s
, iflp
->lp_status
);
2448 w
+= stream_putl(s
, iflp
->te_metric
);
2449 w
+= stream_putf(s
, iflp
->max_bw
);
2450 w
+= stream_putf(s
, iflp
->max_rsv_bw
);
2452 w
+= stream_putl(s
, MAX_CLASS_TYPE
);
2453 for (i
= 0; i
< MAX_CLASS_TYPE
; i
++)
2454 w
+= stream_putf(s
, iflp
->unrsv_bw
[i
]);
2456 w
+= stream_putl(s
, iflp
->admin_grp
);
2457 w
+= stream_putl(s
, iflp
->rmt_as
);
2458 w
+= stream_put_in_addr(s
, &iflp
->rmt_ip
);
2460 w
+= stream_putl(s
, iflp
->av_delay
);
2461 w
+= stream_putl(s
, iflp
->min_delay
);
2462 w
+= stream_putl(s
, iflp
->max_delay
);
2463 w
+= stream_putl(s
, iflp
->delay_var
);
2465 w
+= stream_putf(s
, iflp
->pkt_loss
);
2466 w
+= stream_putf(s
, iflp
->res_bw
);
2467 w
+= stream_putf(s
, iflp
->ava_bw
);
2468 w
+= stream_putf(s
, iflp
->use_bw
);
2474 * format of message for address addition is:
2478 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
2479 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
2488 * | ifc_flags | flags for connected address
2496 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
2504 static int memconstant(const void *s
, int c
, size_t n
)
2506 const uint8_t *p
= s
;
2515 struct connected
*zebra_interface_address_read(int type
, struct stream
*s
,
2519 struct interface
*ifp
;
2520 struct connected
*ifc
;
2521 struct prefix p
, d
, *dp
;
2525 memset(&p
, 0, sizeof(p
));
2526 memset(&d
, 0, sizeof(d
));
2528 /* Get interface index. */
2529 STREAM_GETL(s
, ifindex
);
2532 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
2534 flog_err(EC_LIB_ZAPI_ENCODE
,
2535 "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
2536 (type
== ZEBRA_INTERFACE_ADDRESS_ADD
) ? "ADD" : "DEL",
2542 STREAM_GETC(s
, ifc_flags
);
2544 /* Fetch interface address. */
2545 STREAM_GETC(s
, d
.family
);
2546 p
.family
= d
.family
;
2547 plen
= prefix_blen(&d
);
2549 if (zclient_stream_get_prefix(s
, &p
) != 0)
2550 goto stream_failure
;
2552 /* Fetch destination address. */
2553 STREAM_GET(&d
.u
.prefix
, s
, plen
);
2555 /* N.B. NULL destination pointers are encoded as all zeroes */
2556 dp
= memconstant(&d
.u
.prefix
, 0, plen
) ? NULL
: &d
;
2558 if (type
== ZEBRA_INTERFACE_ADDRESS_ADD
) {
2559 ifc
= connected_lookup_prefix_exact(ifp
, &p
);
2561 /* N.B. NULL destination pointers are encoded as all
2563 ifc
= connected_add_by_prefix(ifp
, &p
, dp
);
2566 ifc
->flags
= ifc_flags
;
2567 if (ifc
->destination
)
2568 ifc
->destination
->prefixlen
=
2569 ifc
->address
->prefixlen
;
2570 else if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
)) {
2571 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
2575 "interface %s address %pFX with peer flag set, but no peer address!",
2576 ifp
->name
, ifc
->address
);
2577 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
2581 assert(type
== ZEBRA_INTERFACE_ADDRESS_DELETE
);
2582 ifc
= connected_delete_by_prefix(ifp
, &p
);
2592 * format of message for neighbor connected address is:
2596 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
2597 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
2612 * | addr_len | len of addr.
2615 struct nbr_connected
*
2616 zebra_interface_nbr_address_read(int type
, struct stream
*s
, vrf_id_t vrf_id
)
2618 unsigned int ifindex
;
2619 struct interface
*ifp
;
2621 struct nbr_connected
*ifc
;
2623 /* Get interface index. */
2624 STREAM_GETL(s
, ifindex
);
2627 ifp
= if_lookup_by_index(ifindex
, vrf_id
);
2629 flog_err(EC_LIB_ZAPI_ENCODE
,
2630 "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
2631 (type
== ZEBRA_INTERFACE_NBR_ADDRESS_ADD
) ? "ADD"
2637 STREAM_GETC(s
, p
.family
);
2638 STREAM_GET(&p
.u
.prefix
, s
, prefix_blen(&p
));
2639 STREAM_GETC(s
, p
.prefixlen
);
2641 if (type
== ZEBRA_INTERFACE_NBR_ADDRESS_ADD
) {
2642 /* Currently only supporting P2P links, so any new RA source
2644 considered as the replacement of the previously learnt
2645 Link-Local address. */
2646 if (!(ifc
= listnode_head(ifp
->nbr_connected
))) {
2647 ifc
= nbr_connected_new();
2648 ifc
->address
= prefix_new();
2650 listnode_add(ifp
->nbr_connected
, ifc
);
2653 prefix_copy(ifc
->address
, &p
);
2655 assert(type
== ZEBRA_INTERFACE_NBR_ADDRESS_DELETE
);
2657 ifc
= nbr_connected_check(ifp
, &p
);
2659 listnode_delete(ifp
->nbr_connected
, ifc
);
2668 struct interface
*zebra_interface_vrf_update_read(struct stream
*s
,
2670 vrf_id_t
*new_vrf_id
)
2672 char ifname
[INTERFACE_NAMSIZ
+ 1] = {};
2673 struct interface
*ifp
;
2676 /* Read interface name. */
2677 STREAM_GET(ifname
, s
, INTERFACE_NAMSIZ
);
2679 /* Lookup interface. */
2680 ifp
= if_lookup_by_name(ifname
, vrf_id
);
2682 flog_err(EC_LIB_ZAPI_ENCODE
,
2683 "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
2688 /* Fetch new VRF Id. */
2689 STREAM_GETL(s
, new_id
);
2691 *new_vrf_id
= new_id
;
2698 /* filter unwanted messages until the expected one arrives */
2699 static int zclient_read_sync_response(struct zclient
*zclient
,
2700 uint16_t expected_cmd
)
2712 cmd
= expected_cmd
+ 1;
2713 while (ret
== 0 && cmd
!= expected_cmd
) {
2717 /* wait until response arrives */
2719 FD_SET(zclient
->sock
, &readfds
);
2720 select(zclient
->sock
+ 1, &readfds
, NULL
, NULL
, NULL
);
2721 if (!FD_ISSET(zclient
->sock
, &readfds
))
2724 ret
= zclient_read_header(s
, zclient
->sock
, &size
, &marker
,
2725 &version
, &vrf_id
, &cmd
);
2727 zlog_debug("%s: Response (%d bytes) received", __func__
,
2731 flog_err(EC_LIB_ZAPI_ENCODE
, "%s: Invalid Sync Message Reply",
2739 * Connect to label manager in a synchronous way
2741 * It first writes the request to zclient output buffer and then
2742 * immediately reads the answer from the input buffer.
2744 * @param zclient Zclient used to connect to label manager (zebra)
2745 * @param async Synchronous (0) or asynchronous (1) operation
2746 * @result Result of response
2748 int lm_label_manager_connect(struct zclient
*zclient
, int async
)
2753 uint16_t cmd
= async
? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC
:
2754 ZEBRA_LABEL_MANAGER_CONNECT
;
2757 zlog_debug("Connecting to Label Manager (LM)");
2759 if (zclient
->sock
< 0) {
2760 zlog_debug("%s: invalid zclient socket", __func__
);
2767 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
2770 stream_putc(s
, zclient
->redist_default
);
2772 stream_putw(s
, zclient
->instance
);
2774 /* Put length at the first point of the stream. */
2775 stream_putw_at(s
, 0, stream_get_endp(s
));
2777 ret
= writen(zclient
->sock
, s
->data
, stream_get_endp(s
));
2779 flog_err(EC_LIB_ZAPI_SOCKET
, "Can't write to zclient sock");
2780 close(zclient
->sock
);
2785 flog_err(EC_LIB_ZAPI_SOCKET
, "Zclient sock closed");
2786 close(zclient
->sock
);
2791 zlog_debug("LM connect request sent (%d bytes)", ret
);
2797 if (zclient_read_sync_response(zclient
, cmd
)
2803 /* read instance and proto */
2807 STREAM_GETC(s
, proto
);
2808 STREAM_GETW(s
, instance
);
2811 if (proto
!= zclient
->redist_default
)
2814 "Wrong proto (%u) in LM connect response. Should be %u",
2815 proto
, zclient
->redist_default
);
2816 if (instance
!= zclient
->instance
)
2819 "Wrong instId (%u) in LM connect response. Should be %u",
2820 instance
, zclient
->instance
);
2823 STREAM_GETC(s
, result
);
2825 zlog_debug("LM connect-response received, result %u", result
);
2834 * Function to request a srv6-locator chunk in an asynchronous way
2836 * @param zclient Zclient used to connect to table manager (zebra)
2837 * @param locator_name Name of SRv6-locator
2838 * @result 0 on success, -1 otherwise
2840 int srv6_manager_get_locator_chunk(struct zclient
*zclient
,
2841 const char *locator_name
)
2844 const size_t len
= strlen(locator_name
);
2847 zlog_debug("Getting SRv6-Locator Chunk %s", locator_name
);
2849 if (zclient
->sock
< 0)
2855 zclient_create_header(s
, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK
,
2859 stream_putw(s
, len
);
2860 stream_put(s
, locator_name
, len
);
2862 /* Put length at the first point of the stream. */
2863 stream_putw_at(s
, 0, stream_get_endp(s
));
2865 return zclient_send_message(zclient
);
2869 * Function to release a srv6-locator chunk
2871 * @param zclient Zclient used to connect to table manager (zebra)
2872 * @param locator_name Name of SRv6-locator
2873 * @result 0 on success, -1 otherwise
2875 int srv6_manager_release_locator_chunk(struct zclient
*zclient
,
2876 const char *locator_name
)
2879 const size_t len
= strlen(locator_name
);
2882 zlog_debug("Releasing SRv6-Locator Chunk %s", locator_name
);
2884 if (zclient
->sock
< 0)
2890 zclient_create_header(s
, ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK
,
2894 stream_putw(s
, len
);
2895 stream_put(s
, locator_name
, len
);
2897 /* Put length at the first point of the stream. */
2898 stream_putw_at(s
, 0, stream_get_endp(s
));
2900 return zclient_send_message(zclient
);
2904 * Asynchronous label chunk request
2906 * @param zclient Zclient used to connect to label manager (zebra)
2907 * @param keep Avoid garbage collection
2908 * @param chunk_size Amount of labels requested
2909 * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
2910 * @result 0 on success, -1 otherwise
2912 enum zclient_send_status
zclient_send_get_label_chunk(struct zclient
*zclient
,
2914 uint32_t chunk_size
,
2920 zlog_debug("Getting Label Chunk");
2922 if (zclient
->sock
< 0)
2923 return ZCLIENT_SEND_FAILURE
;
2928 zclient_create_header(s
, ZEBRA_GET_LABEL_CHUNK
, VRF_DEFAULT
);
2930 stream_putc(s
, zclient
->redist_default
);
2932 stream_putw(s
, zclient
->instance
);
2933 stream_putc(s
, keep
);
2934 stream_putl(s
, chunk_size
);
2935 stream_putl(s
, base
);
2937 /* Put length at the first point of the stream. */
2938 stream_putw_at(s
, 0, stream_get_endp(s
));
2940 return zclient_send_message(zclient
);
2944 * Function to request a label chunk in a synchronous way
2946 * It first writes the request to zclient output buffer and then
2947 * immediately reads the answer from the input buffer.
2949 * @param zclient Zclient used to connect to label manager (zebra)
2950 * @param keep Avoid garbage collection
2951 * @param chunk_size Amount of labels requested
2952 * @param start To write first assigned chunk label to
2953 * @param end To write last assigned chunk label to
2954 * @result 0 on success, -1 otherwise
2956 int lm_get_label_chunk(struct zclient
*zclient
, uint8_t keep
, uint32_t base
,
2957 uint32_t chunk_size
, uint32_t *start
, uint32_t *end
)
2961 uint8_t response_keep
;
2964 zlog_debug("Getting Label Chunk");
2966 if (zclient
->sock
< 0)
2972 zclient_create_header(s
, ZEBRA_GET_LABEL_CHUNK
, VRF_DEFAULT
);
2974 stream_putc(s
, zclient
->redist_default
);
2976 stream_putw(s
, zclient
->instance
);
2978 stream_putc(s
, keep
);
2980 stream_putl(s
, chunk_size
);
2981 /* requested chunk base */
2982 stream_putl(s
, base
);
2983 /* Put length at the first point of the stream. */
2984 stream_putw_at(s
, 0, stream_get_endp(s
));
2986 ret
= writen(zclient
->sock
, s
->data
, stream_get_endp(s
));
2988 flog_err(EC_LIB_ZAPI_SOCKET
, "Can't write to zclient sock");
2989 close(zclient
->sock
);
2994 flog_err(EC_LIB_ZAPI_SOCKET
, "Zclient sock closed");
2995 close(zclient
->sock
);
3000 zlog_debug("Label chunk request (%d bytes) sent", ret
);
3003 if (zclient_read_sync_response(zclient
, ZEBRA_GET_LABEL_CHUNK
) != 0)
3006 /* parse response */
3009 /* read proto and instance */
3013 STREAM_GETC(s
, proto
);
3014 STREAM_GETW(s
, instance
);
3017 if (proto
!= zclient
->redist_default
)
3018 flog_err(EC_LIB_ZAPI_ENCODE
,
3019 "Wrong proto (%u) in get chunk response. Should be %u",
3020 proto
, zclient
->redist_default
);
3021 if (instance
!= zclient
->instance
)
3022 flog_err(EC_LIB_ZAPI_ENCODE
,
3023 "Wrong instId (%u) in get chunk response Should be %u",
3024 instance
, zclient
->instance
);
3026 /* if we requested a specific chunk and it could not be allocated, the
3027 * response message will end here
3029 if (!STREAM_READABLE(s
)) {
3030 zlog_info("Unable to assign Label Chunk to %s instance %u",
3031 zebra_route_string(proto
), instance
);
3036 STREAM_GETC(s
, response_keep
);
3037 /* start and end labels */
3038 STREAM_GETL(s
, *start
);
3039 STREAM_GETL(s
, *end
);
3041 /* not owning this response */
3042 if (keep
!= response_keep
) {
3045 "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
3046 *start
, *end
, keep
, response_keep
);
3049 if (*start
> *end
|| *start
< MPLS_LABEL_UNRESERVED_MIN
3050 || *end
> MPLS_LABEL_UNRESERVED_MAX
) {
3051 flog_err(EC_LIB_ZAPI_ENCODE
, "Invalid Label chunk: %u - %u",
3057 zlog_debug("Label Chunk assign: %u - %u (%u)", *start
, *end
,
3067 * Function to release a label chunk
3069 * @param zclient Zclient used to connect to label manager (zebra)
3070 * @param start First label of chunk
3071 * @param end Last label of chunk
3072 * @result 0 on success, -1 otherwise
3074 int lm_release_label_chunk(struct zclient
*zclient
, uint32_t start
,
3081 zlog_debug("Releasing Label Chunk %u - %u", start
, end
);
3083 if (zclient
->sock
< 0)
3089 zclient_create_header(s
, ZEBRA_RELEASE_LABEL_CHUNK
, VRF_DEFAULT
);
3092 stream_putc(s
, zclient
->redist_default
);
3094 stream_putw(s
, zclient
->instance
);
3096 stream_putl(s
, start
);
3098 stream_putl(s
, end
);
3100 /* Put length at the first point of the stream. */
3101 stream_putw_at(s
, 0, stream_get_endp(s
));
3103 ret
= writen(zclient
->sock
, s
->data
, stream_get_endp(s
));
3105 flog_err(EC_LIB_ZAPI_SOCKET
, "Can't write to zclient sock");
3106 close(zclient
->sock
);
3111 flog_err(EC_LIB_ZAPI_SOCKET
, "Zclient sock connection closed");
3112 close(zclient
->sock
);
3121 * Connect to table manager in a synchronous way
3123 * It first writes the request to zclient output buffer and then
3124 * immediately reads the answer from the input buffer.
3126 * @param zclient Zclient used to connect to table manager (zebra)
3127 * @result Result of response
3129 int tm_table_manager_connect(struct zclient
*zclient
)
3136 zlog_debug("Connecting to Table Manager");
3138 if (zclient
->sock
< 0)
3139 return ZCLIENT_SEND_FAILURE
;
3144 zclient_create_header(s
, ZEBRA_TABLE_MANAGER_CONNECT
, VRF_DEFAULT
);
3147 stream_putc(s
, zclient
->redist_default
);
3149 stream_putw(s
, zclient
->instance
);
3151 /* Put length at the first point of the stream. */
3152 stream_putw_at(s
, 0, stream_get_endp(s
));
3154 ret
= zclient_send_message(zclient
);
3155 if (ret
== ZCLIENT_SEND_FAILURE
)
3159 zlog_debug("%s: Table manager connect request sent", __func__
);
3162 if (zclient_read_sync_response(zclient
, ZEBRA_TABLE_MANAGER_CONNECT
)
3168 STREAM_GETC(s
, result
);
3171 "%s: Table Manager connect response received, result %u",
3180 * Function to request a table chunk in a synchronous way
3182 * It first writes the request to zclient output buffer and then
3183 * immediately reads the answer from the input buffer.
3185 * @param zclient Zclient used to connect to table manager (zebra)
3186 * @param chunk_size Amount of table requested
3187 * @param start to write first assigned chunk table RT ID to
3188 * @param end To write last assigned chunk table RT ID to
3189 * @result 0 on success, -1 otherwise
3191 int tm_get_table_chunk(struct zclient
*zclient
, uint32_t chunk_size
,
3192 uint32_t *start
, uint32_t *end
)
3198 zlog_debug("Getting Table Chunk");
3200 if (zclient
->sock
< 0)
3206 zclient_create_header(s
, ZEBRA_GET_TABLE_CHUNK
, VRF_DEFAULT
);
3208 stream_putl(s
, chunk_size
);
3209 /* Put length at the first point of the stream. */
3210 stream_putw_at(s
, 0, stream_get_endp(s
));
3212 ret
= writen(zclient
->sock
, s
->data
, stream_get_endp(s
));
3214 flog_err(EC_LIB_ZAPI_SOCKET
, "%s: can't write to zclient->sock",
3216 close(zclient
->sock
);
3221 flog_err(EC_LIB_ZAPI_SOCKET
,
3222 "%s: zclient->sock connection closed", __func__
);
3223 close(zclient
->sock
);
3228 zlog_debug("%s: Table chunk request (%d bytes) sent", __func__
,
3232 if (zclient_read_sync_response(zclient
, ZEBRA_GET_TABLE_CHUNK
) != 0)
3236 /* start and end table IDs */
3237 STREAM_GETL(s
, *start
);
3238 STREAM_GETL(s
, *end
);
3241 zlog_debug("Table Chunk assign: %u - %u ", *start
, *end
);
3249 * Function to release a table chunk
3251 * @param zclient Zclient used to connect to table manager (zebra)
3252 * @param start First label of table
3253 * @param end Last label of chunk
3254 * @result 0 on success, -1 otherwise
3256 int tm_release_table_chunk(struct zclient
*zclient
, uint32_t start
,
3262 zlog_debug("Releasing Table Chunk");
3264 if (zclient
->sock
< 0)
3270 zclient_create_header(s
, ZEBRA_RELEASE_TABLE_CHUNK
, VRF_DEFAULT
);
3273 stream_putl(s
, start
);
3275 stream_putl(s
, end
);
3277 /* Put length at the first point of the stream. */
3278 stream_putw_at(s
, 0, stream_get_endp(s
));
3280 if (zclient_send_message(zclient
) == ZCLIENT_SEND_FAILURE
)
3286 enum zclient_send_status
zebra_send_sr_policy(struct zclient
*zclient
, int cmd
,
3287 struct zapi_sr_policy
*zp
)
3289 if (zapi_sr_policy_encode(zclient
->obuf
, cmd
, zp
) < 0)
3290 return ZCLIENT_SEND_FAILURE
;
3291 return zclient_send_message(zclient
);
3294 int zapi_sr_policy_encode(struct stream
*s
, int cmd
, struct zapi_sr_policy
*zp
)
3296 struct zapi_srte_tunnel
*zt
= &zp
->segment_list
;
3300 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
3301 stream_putl(s
, zp
->color
);
3302 stream_put_ipaddr(s
, &zp
->endpoint
);
3303 stream_write(s
, &zp
->name
, SRTE_POLICY_NAME_MAX_LENGTH
);
3305 stream_putc(s
, zt
->type
);
3306 stream_putl(s
, zt
->local_label
);
3308 if (zt
->label_num
> MPLS_MAX_LABELS
) {
3309 flog_err(EC_LIB_ZAPI_ENCODE
,
3310 "%s: label %u: can't encode %u labels (maximum is %u)",
3311 __func__
, zt
->local_label
, zt
->label_num
,
3315 stream_putw(s
, zt
->label_num
);
3317 for (int i
= 0; i
< zt
->label_num
; i
++)
3318 stream_putl(s
, zt
->labels
[i
]);
3320 /* Put length at the first point of the stream. */
3321 stream_putw_at(s
, 0, stream_get_endp(s
));
3326 int zapi_sr_policy_decode(struct stream
*s
, struct zapi_sr_policy
*zp
)
3328 memset(zp
, 0, sizeof(*zp
));
3330 struct zapi_srte_tunnel
*zt
= &zp
->segment_list
;
3332 STREAM_GETL(s
, zp
->color
);
3333 STREAM_GET_IPADDR(s
, &zp
->endpoint
);
3334 STREAM_GET(&zp
->name
, s
, SRTE_POLICY_NAME_MAX_LENGTH
);
3336 /* segment list of active candidate path */
3337 STREAM_GETC(s
, zt
->type
);
3338 STREAM_GETL(s
, zt
->local_label
);
3339 STREAM_GETW(s
, zt
->label_num
);
3340 if (zt
->label_num
> MPLS_MAX_LABELS
) {
3341 flog_err(EC_LIB_ZAPI_ENCODE
,
3342 "%s: label %u: can't decode %u labels (maximum is %u)",
3343 __func__
, zt
->local_label
, zt
->label_num
,
3347 for (int i
= 0; i
< zt
->label_num
; i
++)
3348 STREAM_GETL(s
, zt
->labels
[i
]);
3356 int zapi_sr_policy_notify_status_decode(struct stream
*s
,
3357 struct zapi_sr_policy
*zp
)
3359 memset(zp
, 0, sizeof(*zp
));
3361 STREAM_GETL(s
, zp
->color
);
3362 STREAM_GET_IPADDR(s
, &zp
->endpoint
);
3363 STREAM_GET(&zp
->name
, s
, SRTE_POLICY_NAME_MAX_LENGTH
);
3364 STREAM_GETL(s
, zp
->status
);
3372 enum zclient_send_status
zebra_send_mpls_labels(struct zclient
*zclient
,
3373 int cmd
, struct zapi_labels
*zl
)
3375 if (zapi_labels_encode(zclient
->obuf
, cmd
, zl
) < 0)
3376 return ZCLIENT_SEND_FAILURE
;
3377 return zclient_send_message(zclient
);
3380 int zapi_labels_encode(struct stream
*s
, int cmd
, struct zapi_labels
*zl
)
3382 struct zapi_nexthop
*znh
;
3386 zclient_create_header(s
, cmd
, VRF_DEFAULT
);
3387 stream_putc(s
, zl
->message
);
3388 stream_putc(s
, zl
->type
);
3389 stream_putl(s
, zl
->local_label
);
3391 if (CHECK_FLAG(zl
->message
, ZAPI_LABELS_FTN
)) {
3392 stream_putw(s
, zl
->route
.prefix
.family
);
3393 stream_put_prefix(s
, &zl
->route
.prefix
);
3394 stream_putc(s
, zl
->route
.type
);
3395 stream_putw(s
, zl
->route
.instance
);
3398 if (zl
->nexthop_num
> MULTIPATH_NUM
) {
3401 "%s: label %u: can't encode %u nexthops (maximum is %u)",
3402 __func__
, zl
->local_label
, zl
->nexthop_num
,
3406 stream_putw(s
, zl
->nexthop_num
);
3408 for (int i
= 0; i
< zl
->nexthop_num
; i
++) {
3409 znh
= &zl
->nexthops
[i
];
3411 if (zapi_nexthop_encode(s
, znh
, 0, 0) < 0)
3415 if (CHECK_FLAG(zl
->message
, ZAPI_LABELS_HAS_BACKUPS
)) {
3417 if (zl
->backup_nexthop_num
> MULTIPATH_NUM
) {
3420 "%s: label %u: can't encode %u nexthops (maximum is %u)",
3421 __func__
, zl
->local_label
, zl
->nexthop_num
,
3425 stream_putw(s
, zl
->backup_nexthop_num
);
3427 for (int i
= 0; i
< zl
->backup_nexthop_num
; i
++) {
3428 znh
= &zl
->backup_nexthops
[i
];
3430 if (zapi_nexthop_encode(s
, znh
, 0, 0) < 0)
3436 /* Put length at the first point of the stream. */
3437 stream_putw_at(s
, 0, stream_get_endp(s
));
3442 int zapi_labels_decode(struct stream
*s
, struct zapi_labels
*zl
)
3444 struct zapi_nexthop
*znh
;
3446 memset(zl
, 0, sizeof(*zl
));
3449 STREAM_GETC(s
, zl
->message
);
3450 STREAM_GETC(s
, zl
->type
);
3451 STREAM_GETL(s
, zl
->local_label
);
3453 if (CHECK_FLAG(zl
->message
, ZAPI_LABELS_FTN
)) {
3456 STREAM_GETW(s
, zl
->route
.prefix
.family
);
3457 STREAM_GETC(s
, zl
->route
.prefix
.prefixlen
);
3459 psize
= PSIZE(zl
->route
.prefix
.prefixlen
);
3460 switch (zl
->route
.prefix
.family
) {
3462 if (zl
->route
.prefix
.prefixlen
> IPV4_MAX_BITLEN
) {
3464 "%s: Specified prefix length %d is greater than a v4 address can support",
3465 __func__
, zl
->route
.prefix
.prefixlen
);
3468 STREAM_GET(&zl
->route
.prefix
.u
.prefix4
.s_addr
, s
,
3472 if (zl
->route
.prefix
.prefixlen
> IPV6_MAX_BITLEN
) {
3474 "%s: Specified prefix length %d is greater than a v6 address can support",
3475 __func__
, zl
->route
.prefix
.prefixlen
);
3478 STREAM_GET(&zl
->route
.prefix
.u
.prefix6
, s
, psize
);
3481 flog_err(EC_LIB_ZAPI_ENCODE
,
3482 "%s: Specified family %u is not v4 or v6",
3483 __func__
, zl
->route
.prefix
.family
);
3487 STREAM_GETC(s
, zl
->route
.type
);
3488 STREAM_GETW(s
, zl
->route
.instance
);
3491 STREAM_GETW(s
, zl
->nexthop_num
);
3493 if (zl
->nexthop_num
> MULTIPATH_NUM
) {
3496 "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
3497 __func__
, &zl
->route
.prefix
, zl
->nexthop_num
,
3501 zl
->nexthop_num
= MIN(MULTIPATH_NUM
, zl
->nexthop_num
);
3503 for (int i
= 0; i
< zl
->nexthop_num
; i
++) {
3504 znh
= &zl
->nexthops
[i
];
3506 if (zapi_nexthop_decode(s
, znh
, 0, 0) < 0)
3509 if (znh
->type
== NEXTHOP_TYPE_BLACKHOLE
) {
3512 "%s: Prefix %pFX has a blackhole nexthop which we cannot use for a label",
3513 __func__
, &zl
->route
.prefix
);
3518 if (CHECK_FLAG(zl
->message
, ZAPI_LABELS_HAS_BACKUPS
)) {
3519 STREAM_GETW(s
, zl
->backup_nexthop_num
);
3521 if (zl
->backup_nexthop_num
> MULTIPATH_NUM
) {
3524 "%s: Prefix %pFX has %d backup nexthops, but we can only use the first %d",
3525 __func__
, &zl
->route
.prefix
,
3526 zl
->backup_nexthop_num
, MULTIPATH_NUM
);
3529 zl
->backup_nexthop_num
= MIN(MULTIPATH_NUM
,
3530 zl
->backup_nexthop_num
);
3532 for (int i
= 0; i
< zl
->backup_nexthop_num
; i
++) {
3533 znh
= &zl
->backup_nexthops
[i
];
3535 if (zapi_nexthop_decode(s
, znh
, 0, 0) < 0)
3538 if (znh
->type
== NEXTHOP_TYPE_BLACKHOLE
) {
3541 "%s: Prefix %pFX has a backup blackhole nexthop which we cannot use for a label",
3542 __func__
, &zl
->route
.prefix
);
3553 enum zclient_send_status
zebra_send_pw(struct zclient
*zclient
, int command
,
3562 zclient_create_header(s
, command
, VRF_DEFAULT
);
3563 stream_write(s
, pw
->ifname
, INTERFACE_NAMSIZ
);
3564 stream_putl(s
, pw
->ifindex
);
3567 stream_putl(s
, pw
->type
);
3570 stream_putl(s
, pw
->af
);
3573 stream_put_in_addr(s
, &pw
->nexthop
.ipv4
);
3576 stream_write(s
, (uint8_t *)&pw
->nexthop
.ipv6
, 16);
3579 flog_err(EC_LIB_ZAPI_ENCODE
, "%s: unknown af", __func__
);
3580 return ZCLIENT_SEND_FAILURE
;
3584 stream_putl(s
, pw
->local_label
);
3585 stream_putl(s
, pw
->remote_label
);
3588 stream_putc(s
, pw
->flags
);
3590 /* Protocol specific fields */
3591 stream_write(s
, &pw
->data
, sizeof(union pw_protocol_fields
));
3593 /* Put length at the first point of the stream. */
3594 stream_putw_at(s
, 0, stream_get_endp(s
));
3596 return zclient_send_message(zclient
);
3600 * Receive PW status update from Zebra and send it to LDE process.
3602 int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS
, struct zapi_pw_status
*pw
)
3606 memset(pw
, 0, sizeof(struct zapi_pw_status
));
3610 stream_get(pw
->ifname
, s
, INTERFACE_NAMSIZ
);
3611 STREAM_GETL(s
, pw
->ifindex
);
3612 STREAM_GETL(s
, pw
->status
);
3619 static int zclient_capability_decode(ZAPI_CALLBACK_ARGS
)
3621 struct zclient_capabilities cap
;
3622 struct stream
*s
= zclient
->ibuf
;
3624 uint8_t mpls_enabled
;
3626 STREAM_GETL(s
, vrf_backend
);
3628 if (vrf_backend
< 0 || vrf_configure_backend(vrf_backend
)) {
3629 flog_err(EC_LIB_ZAPI_ENCODE
,
3630 "%s: Garbage VRF backend type: %d", __func__
,
3632 goto stream_failure
;
3636 memset(&cap
, 0, sizeof(cap
));
3637 STREAM_GETC(s
, mpls_enabled
);
3638 cap
.mpls_enabled
= !!mpls_enabled
;
3639 STREAM_GETL(s
, cap
.ecmp
);
3640 STREAM_GETC(s
, cap
.role
);
3642 if (zclient
->zebra_capabilities
)
3643 (*zclient
->zebra_capabilities
)(&cap
);
3649 enum zclient_send_status
zclient_send_mlag_register(struct zclient
*client
,
3657 zclient_create_header(s
, ZEBRA_MLAG_CLIENT_REGISTER
, VRF_DEFAULT
);
3658 stream_putl(s
, bit_map
);
3660 stream_putw_at(s
, 0, stream_get_endp(s
));
3661 return zclient_send_message(client
);
3664 enum zclient_send_status
zclient_send_mlag_deregister(struct zclient
*client
)
3666 return zebra_message_send(client
, ZEBRA_MLAG_CLIENT_UNREGISTER
,
3670 enum zclient_send_status
zclient_send_mlag_data(struct zclient
*client
,
3671 struct stream
*client_s
)
3678 zclient_create_header(s
, ZEBRA_MLAG_FORWARD_MSG
, VRF_DEFAULT
);
3679 stream_put(s
, client_s
->data
, client_s
->endp
);
3681 stream_putw_at(s
, 0, stream_get_endp(s
));
3682 return zclient_send_message(client
);
3686 * Send an OPAQUE message, contents opaque to zebra. The message header
3687 * is a message subtype.
3689 enum zclient_send_status
zclient_send_opaque(struct zclient
*zclient
,
3690 uint32_t type
, const uint8_t *data
,
3696 /* Check buffer size */
3697 if (STREAM_SIZE(zclient
->obuf
) <
3698 (ZEBRA_HEADER_SIZE
+ sizeof(type
) + datasize
))
3699 return ZCLIENT_SEND_FAILURE
;
3704 zclient_create_header(s
, ZEBRA_OPAQUE_MESSAGE
, VRF_DEFAULT
);
3706 /* Send sub-type and flags */
3707 stream_putl(s
, type
);
3708 stream_putw(s
, flags
);
3710 /* Send opaque data */
3711 stream_write(s
, data
, datasize
);
3713 /* Put length into the header at the start of the stream. */
3714 stream_putw_at(s
, 0, stream_get_endp(s
));
3716 return zclient_send_message(zclient
);
3720 * Send an OPAQUE message to a specific zclient. The contents are opaque
3723 enum zclient_send_status
3724 zclient_send_opaque_unicast(struct zclient
*zclient
, uint32_t type
,
3725 uint8_t proto
, uint16_t instance
,
3726 uint32_t session_id
, const uint8_t *data
,
3732 /* Check buffer size */
3733 if (STREAM_SIZE(zclient
->obuf
) <
3734 (ZEBRA_HEADER_SIZE
+ sizeof(struct zapi_opaque_msg
) + datasize
))
3735 return ZCLIENT_SEND_FAILURE
;
3740 zclient_create_header(s
, ZEBRA_OPAQUE_MESSAGE
, VRF_DEFAULT
);
3742 /* Send sub-type and flags */
3743 SET_FLAG(flags
, ZAPI_OPAQUE_FLAG_UNICAST
);
3744 stream_putl(s
, type
);
3745 stream_putw(s
, flags
);
3747 /* Send destination client info */
3748 stream_putc(s
, proto
);
3749 stream_putw(s
, instance
);
3750 stream_putl(s
, session_id
);
3752 /* Send opaque data */
3753 stream_write(s
, data
, datasize
);
3755 /* Put length into the header at the start of the stream. */
3756 stream_putw_at(s
, 0, stream_get_endp(s
));
3758 return zclient_send_message(zclient
);
3762 * Decode incoming opaque message into info struct
3764 int zclient_opaque_decode(struct stream
*s
, struct zapi_opaque_msg
*info
)
3766 memset(info
, 0, sizeof(*info
));
3768 /* Decode subtype and flags */
3769 STREAM_GETL(s
, info
->type
);
3770 STREAM_GETW(s
, info
->flags
);
3772 /* Decode unicast client info if present */
3773 if (CHECK_FLAG(info
->flags
, ZAPI_OPAQUE_FLAG_UNICAST
)) {
3774 STREAM_GETC(s
, info
->proto
);
3775 STREAM_GETW(s
, info
->instance
);
3776 STREAM_GETL(s
, info
->session_id
);
3779 info
->len
= STREAM_READABLE(s
);
3789 * Send a registration request for opaque messages with a specified subtype.
3791 enum zclient_send_status
zclient_register_opaque(struct zclient
*zclient
,
3799 zclient_create_header(s
, ZEBRA_OPAQUE_REGISTER
, VRF_DEFAULT
);
3802 stream_putl(s
, type
);
3804 /* Add zclient info */
3805 stream_putc(s
, zclient
->redist_default
);
3806 stream_putw(s
, zclient
->instance
);
3807 stream_putl(s
, zclient
->session_id
);
3809 /* Put length at the first point of the stream. */
3810 stream_putw_at(s
, 0, stream_get_endp(s
));
3812 return zclient_send_message(zclient
);
3816 * Send an un-registration request for a specified opaque subtype.
3818 enum zclient_send_status
zclient_unregister_opaque(struct zclient
*zclient
,
3826 zclient_create_header(s
, ZEBRA_OPAQUE_UNREGISTER
, VRF_DEFAULT
);
3829 stream_putl(s
, type
);
3831 /* Add zclient info */
3832 stream_putc(s
, zclient
->redist_default
);
3833 stream_putw(s
, zclient
->instance
);
3834 stream_putl(s
, zclient
->session_id
);
3836 /* Put length at the first point of the stream. */
3837 stream_putw_at(s
, 0, stream_get_endp(s
));
3839 return zclient_send_message(zclient
);
3842 /* Utility to decode opaque registration info */
3843 int zapi_opaque_reg_decode(struct stream
*s
, struct zapi_opaque_reg_info
*info
)
3845 STREAM_GETL(s
, info
->type
);
3846 STREAM_GETC(s
, info
->proto
);
3847 STREAM_GETW(s
, info
->instance
);
3848 STREAM_GETL(s
, info
->session_id
);
3857 /* Utility to decode client close notify info */
3858 int zapi_client_close_notify_decode(struct stream
*s
,
3859 struct zapi_client_close_info
*info
)
3861 memset(info
, 0, sizeof(*info
));
3863 STREAM_GETC(s
, info
->proto
);
3864 STREAM_GETW(s
, info
->instance
);
3865 STREAM_GETL(s
, info
->session_id
);
3874 static zclient_handler
*const lib_handlers
[] = {
3876 [ZEBRA_CAPABILITIES
] = zclient_capability_decode
,
3877 [ZEBRA_ERROR
] = zclient_handle_error
,
3879 /* VRF & interface code is shared in lib */
3880 [ZEBRA_VRF_ADD
] = zclient_vrf_add
,
3881 [ZEBRA_VRF_DELETE
] = zclient_vrf_delete
,
3882 [ZEBRA_INTERFACE_ADD
] = zclient_interface_add
,
3883 [ZEBRA_INTERFACE_DELETE
] = zclient_interface_delete
,
3884 [ZEBRA_INTERFACE_UP
] = zclient_interface_up
,
3885 [ZEBRA_INTERFACE_DOWN
] = zclient_interface_down
,
3888 [ZEBRA_BFD_DEST_REPLAY
] = zclient_bfd_session_replay
,
3889 [ZEBRA_INTERFACE_BFD_DEST_UPDATE
] = zclient_bfd_session_update
,
3892 /* Zebra client message read function. */
3893 static void zclient_read(struct thread
*thread
)
3896 uint16_t length
, command
;
3897 uint8_t marker
, version
;
3899 struct zclient
*zclient
;
3901 /* Get socket to zebra. */
3902 zclient
= THREAD_ARG(thread
);
3903 zclient
->t_read
= NULL
;
3905 /* Read zebra header (if we don't have it already). */
3906 already
= stream_get_endp(zclient
->ibuf
);
3907 if (already
< ZEBRA_HEADER_SIZE
) {
3909 if (((nbyte
= stream_read_try(zclient
->ibuf
, zclient
->sock
,
3910 ZEBRA_HEADER_SIZE
- already
))
3915 "zclient connection closed socket [%d].",
3917 zclient_failed(zclient
);
3920 if (nbyte
!= (ssize_t
)(ZEBRA_HEADER_SIZE
- already
)) {
3921 zclient_event(ZCLIENT_READ
, zclient
);
3924 already
= ZEBRA_HEADER_SIZE
;
3927 /* Reset to read from the beginning of the incoming packet. */
3928 stream_set_getp(zclient
->ibuf
, 0);
3930 /* Fetch header values. */
3931 length
= stream_getw(zclient
->ibuf
);
3932 marker
= stream_getc(zclient
->ibuf
);
3933 version
= stream_getc(zclient
->ibuf
);
3934 vrf_id
= stream_getl(zclient
->ibuf
);
3935 command
= stream_getw(zclient
->ibuf
);
3937 if (marker
!= ZEBRA_HEADER_MARKER
|| version
!= ZSERV_VERSION
) {
3939 EC_LIB_ZAPI_MISSMATCH
,
3940 "%s: socket %d version mismatch, marker %d, version %d",
3941 __func__
, zclient
->sock
, marker
, version
);
3942 zclient_failed(zclient
);
3946 if (length
< ZEBRA_HEADER_SIZE
) {
3947 flog_err(EC_LIB_ZAPI_MISSMATCH
,
3948 "%s: socket %d message length %u is less than %d ",
3949 __func__
, zclient
->sock
, length
, ZEBRA_HEADER_SIZE
);
3950 zclient_failed(zclient
);
3955 if (length
> STREAM_SIZE(zclient
->ibuf
)) {
3959 "%s: message size %u exceeds buffer size %lu, expanding...",
3961 (unsigned long)STREAM_SIZE(zclient
->ibuf
));
3962 ns
= stream_new(length
);
3963 stream_copy(ns
, zclient
->ibuf
);
3964 stream_free(zclient
->ibuf
);
3968 /* Read rest of zebra packet. */
3969 if (already
< length
) {
3971 if (((nbyte
= stream_read_try(zclient
->ibuf
, zclient
->sock
,
3977 "zclient connection closed socket [%d].",
3979 zclient_failed(zclient
);
3982 if (nbyte
!= (ssize_t
)(length
- already
)) {
3983 /* Try again later. */
3984 zclient_event(ZCLIENT_READ
, zclient
);
3989 length
-= ZEBRA_HEADER_SIZE
;
3992 zlog_debug("zclient %p command %s VRF %u", zclient
,
3993 zserv_command_string(command
), vrf_id
);
3995 if (command
< array_size(lib_handlers
) && lib_handlers
[command
])
3996 lib_handlers
[command
](command
, zclient
, length
, vrf_id
);
3997 if (command
< zclient
->n_handlers
&& zclient
->handlers
[command
])
3998 zclient
->handlers
[command
](command
, zclient
, length
, vrf_id
);
4000 if (zclient
->sock
< 0)
4001 /* Connection was closed during packet processing. */
4004 /* Register read thread. */
4005 stream_reset(zclient
->ibuf
);
4006 zclient_event(ZCLIENT_READ
, zclient
);
4009 void zclient_redistribute(int command
, struct zclient
*zclient
, afi_t afi
,
4010 int type
, unsigned short instance
, vrf_id_t vrf_id
)
4014 if (command
== ZEBRA_REDISTRIBUTE_ADD
) {
4015 if (redist_check_instance(
4016 &zclient
->mi_redist
[afi
][type
], instance
))
4018 redist_add_instance(&zclient
->mi_redist
[afi
][type
],
4021 if (!redist_check_instance(
4022 &zclient
->mi_redist
[afi
][type
], instance
))
4024 redist_del_instance(&zclient
->mi_redist
[afi
][type
],
4029 if (command
== ZEBRA_REDISTRIBUTE_ADD
) {
4030 if (vrf_bitmap_check(zclient
->redist
[afi
][type
],
4033 vrf_bitmap_set(zclient
->redist
[afi
][type
], vrf_id
);
4035 if (!vrf_bitmap_check(zclient
->redist
[afi
][type
],
4038 vrf_bitmap_unset(zclient
->redist
[afi
][type
], vrf_id
);
4042 if (zclient
->sock
> 0)
4043 zebra_redistribute_send(command
, zclient
, afi
, type
, instance
,
4048 void zclient_redistribute_default(int command
, struct zclient
*zclient
,
4049 afi_t afi
, vrf_id_t vrf_id
)
4052 if (command
== ZEBRA_REDISTRIBUTE_DEFAULT_ADD
) {
4053 if (vrf_bitmap_check(zclient
->default_information
[afi
], vrf_id
))
4055 vrf_bitmap_set(zclient
->default_information
[afi
], vrf_id
);
4057 if (!vrf_bitmap_check(zclient
->default_information
[afi
],
4060 vrf_bitmap_unset(zclient
->default_information
[afi
], vrf_id
);
4063 if (zclient
->sock
> 0)
4064 zebra_redistribute_default_send(command
, zclient
, afi
, vrf_id
);
4067 static void zclient_event(enum zclient_event event
, struct zclient
*zclient
)
4070 case ZCLIENT_SCHEDULE
:
4071 thread_add_event(zclient
->master
, zclient_connect
, zclient
, 0,
4072 &zclient
->t_connect
);
4074 case ZCLIENT_CONNECT
:
4077 "zclient connect failures: %d schedule interval is now %d",
4078 zclient
->fail
, zclient
->fail
< 3 ? 10 : 60);
4079 thread_add_timer(zclient
->master
, zclient_connect
, zclient
,
4080 zclient
->fail
< 3 ? 10 : 60,
4081 &zclient
->t_connect
);
4084 zclient
->t_read
= NULL
;
4085 thread_add_read(zclient
->master
, zclient_read
, zclient
,
4086 zclient
->sock
, &zclient
->t_read
);
4091 enum zclient_send_status
zclient_interface_set_master(struct zclient
*client
,
4092 struct interface
*master
,
4093 struct interface
*slave
)
4100 zclient_create_header(s
, ZEBRA_INTERFACE_SET_MASTER
,
4101 master
->vrf
->vrf_id
);
4103 stream_putl(s
, master
->vrf
->vrf_id
);
4104 stream_putl(s
, master
->ifindex
);
4105 stream_putl(s
, slave
->vrf
->vrf_id
);
4106 stream_putl(s
, slave
->ifindex
);
4108 stream_putw_at(s
, 0, stream_get_endp(s
));
4109 return zclient_send_message(client
);
4113 * Send capabilities message to zebra
4115 enum zclient_send_status
zclient_capabilities_send(uint32_t cmd
,
4116 struct zclient
*zclient
,
4117 struct zapi_cap
*api
)
4122 if (zclient
== NULL
)
4123 return ZCLIENT_SEND_FAILURE
;
4127 zclient_create_header(s
, cmd
, 0);
4128 stream_putl(s
, api
->cap
);
4131 case ZEBRA_CLIENT_GR_CAPABILITIES
:
4132 case ZEBRA_CLIENT_RIB_STALE_TIME
:
4133 stream_putl(s
, api
->stale_removal_time
);
4134 stream_putl(s
, api
->vrf_id
);
4136 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE
:
4137 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING
:
4138 stream_putl(s
, api
->afi
);
4139 stream_putl(s
, api
->safi
);
4140 stream_putl(s
, api
->vrf_id
);
4142 case ZEBRA_CLIENT_GR_DISABLE
:
4143 stream_putl(s
, api
->vrf_id
);
4147 /* Put length at the first point of the stream */
4148 stream_putw_at(s
, 0, stream_get_endp(s
));
4150 return zclient_send_message(zclient
);
4154 * Process capabilities message from zebra
4156 int32_t zapi_capabilities_decode(struct stream
*s
, struct zapi_cap
*api
)
4159 memset(api
, 0, sizeof(*api
));
4161 STREAM_GETL(s
, api
->cap
);
4163 case ZEBRA_CLIENT_GR_CAPABILITIES
:
4164 case ZEBRA_CLIENT_RIB_STALE_TIME
:
4165 STREAM_GETL(s
, api
->stale_removal_time
);
4166 STREAM_GETL(s
, api
->vrf_id
);
4168 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE
:
4169 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING
:
4170 STREAM_GETL(s
, api
->afi
);
4171 STREAM_GETL(s
, api
->safi
);
4172 STREAM_GETL(s
, api
->vrf_id
);
4174 case ZEBRA_CLIENT_GR_DISABLE
:
4175 STREAM_GETL(s
, api
->vrf_id
);
4182 enum zclient_send_status
4183 zclient_send_neigh_discovery_req(struct zclient
*zclient
,
4184 const struct interface
*ifp
,
4185 const struct prefix
*p
)
4192 zclient_create_header(s
, ZEBRA_NEIGH_DISCOVER
, ifp
->vrf
->vrf_id
);
4193 stream_putl(s
, ifp
->ifindex
);
4195 stream_putc(s
, p
->family
);
4196 stream_putc(s
, p
->prefixlen
);
4197 stream_put(s
, &p
->u
.prefix
, prefix_blen(p
));
4199 stream_putw_at(s
, 0, stream_get_endp(s
));
4200 return zclient_send_message(zclient
);
4204 * Get a starting nhg point for a routing protocol
4206 uint32_t zclient_get_nhg_start(uint32_t proto
)
4208 assert(proto
< ZEBRA_ROUTE_MAX
);
4210 return ZEBRA_NHG_PROTO_SPACING
* proto
;
4213 char *zclient_dump_route_flags(uint32_t flags
, char *buf
, size_t len
)
4216 snprintfrr(buf
, len
, "None ");
4221 buf
, len
, "%s%s%s%s%s%s%s%s%s%s",
4222 CHECK_FLAG(flags
, ZEBRA_FLAG_ALLOW_RECURSION
) ? "Recursion "
4224 CHECK_FLAG(flags
, ZEBRA_FLAG_SELFROUTE
) ? "Self " : "",
4225 CHECK_FLAG(flags
, ZEBRA_FLAG_IBGP
) ? "iBGP " : "",
4226 CHECK_FLAG(flags
, ZEBRA_FLAG_SELECTED
) ? "Selected " : "",
4227 CHECK_FLAG(flags
, ZEBRA_FLAG_FIB_OVERRIDE
) ? "Override " : "",
4228 CHECK_FLAG(flags
, ZEBRA_FLAG_EVPN_ROUTE
) ? "Evpn " : "",
4229 CHECK_FLAG(flags
, ZEBRA_FLAG_RR_USE_DISTANCE
) ? "RR Distance "
4231 CHECK_FLAG(flags
, ZEBRA_FLAG_TRAPPED
) ? "Trapped " : "",
4232 CHECK_FLAG(flags
, ZEBRA_FLAG_OFFLOADED
) ? "Offloaded " : "",
4233 CHECK_FLAG(flags
, ZEBRA_FLAG_OFFLOAD_FAILED
) ? "Offload Failed "
4238 char *zclient_evpn_dump_macip_flags(uint8_t flags
, char *buf
, size_t len
)
4241 snprintfrr(buf
, len
, "None ");
4246 buf
, len
, "%s%s%s%s%s%s%s",
4247 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
) ? "Sticky MAC " : "",
4248 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
) ? "Gateway MAC " : "",
4249 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
) ? "Router "
4251 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_OVERRIDE_FLAG
) ? "Override "
4253 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_SVI_IP
) ? "SVI MAC " : "",
4254 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_PROXY_ADVERT
) ? "Proxy "
4256 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_SYNC_PATH
) ? "Sync " : "");
4261 static int zclient_neigh_ip_read_entry(struct stream
*s
, struct ipaddr
*add
)
4265 STREAM_GETC(s
, family
);
4266 if (family
!= AF_INET
&& family
!= AF_INET6
)
4269 STREAM_GET(&add
->ip
.addr
, s
, family2addrsize(family
));
4270 add
->ipa_type
= family
;
4276 int zclient_neigh_ip_encode(struct stream
*s
, uint16_t cmd
, union sockunion
*in
,
4277 union sockunion
*out
, struct interface
*ifp
,
4282 zclient_create_header(s
, cmd
, ifp
->vrf
->vrf_id
);
4283 stream_putc(s
, sockunion_family(in
));
4284 stream_write(s
, sockunion_get_addr(in
), sockunion_get_addrlen(in
));
4285 if (out
&& sockunion_family(out
) != AF_UNSPEC
) {
4286 stream_putc(s
, sockunion_family(out
));
4287 stream_write(s
, sockunion_get_addr(out
),
4288 sockunion_get_addrlen(out
));
4290 stream_putc(s
, AF_UNSPEC
);
4291 stream_putl(s
, ifp
->ifindex
);
4293 stream_putl(s
, ndm_state
);
4295 stream_putl(s
, ZEBRA_NEIGH_STATE_FAILED
);
4299 int zclient_neigh_ip_decode(struct stream
*s
, struct zapi_neigh_ip
*api
)
4303 ret
= zclient_neigh_ip_read_entry(s
, &api
->ip_in
);
4306 zclient_neigh_ip_read_entry(s
, &api
->ip_out
);
4308 STREAM_GETL(s
, api
->index
);
4309 STREAM_GETL(s
, api
->ndm_state
);
4315 int zclient_send_zebra_gre_request(struct zclient
*client
,
4316 struct interface
*ifp
)
4320 if (!client
|| client
->sock
< 0) {
4321 zlog_err("%s : zclient not ready", __func__
);
4326 zclient_create_header(s
, ZEBRA_GRE_GET
, ifp
->vrf
->vrf_id
);
4327 stream_putl(s
, ifp
->ifindex
);
4328 stream_putw_at(s
, 0, stream_get_endp(s
));
4329 zclient_send_message(client
);