#include "sockopt.h"
#include "pbr.h"
#include "nexthop_group.h"
+#include "lib_errors.h"
DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
set_cloexec(sock);
- zclient->privs->change(ZPRIVS_RAISE);
- setsockopt_so_sendbuf(sock, 1048576);
- zclient->privs->change(ZPRIVS_LOWER);
+ frr_elevate_privs(zclient->privs) {
+ setsockopt_so_sendbuf(sock, 1048576);
+ }
/* Connect to zebra. */
ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
STREAM_GETW(s, *cmd);
if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
- zlog_err(
- "%s: socket %d version mismatch, marker %d, version %d",
- __func__, sock, *marker, *version);
+ flog_err(LIB_ERR_ZAPI_MISSMATCH,
+ "%s: socket %d version mismatch, marker %d, version %d",
+ __func__, sock, *marker, *version);
return -1;
}
* "xdr_encode"-like interface that allows daemon (client) to send
* a message to zebra server for a route that needs to be
* added/deleted to the kernel. Info about the route is specified
- * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
+ * by the caller in a struct zapi_route. zapi_route_encode() then writes
* the info down the zclient socket using the stream_* functions.
*
* The corresponding read ("xdr_decode") function on the server
- * side is zread_ipv4_add()/zread_ipv4_delete().
+ * side is zapi_route_decode().
*
* 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole
* nexthop.
*
- * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*()
- * infrastructure was built around the traditional (32-bit "gate OR
- * ifindex") nexthop data unit. A special encoding can be used to feed
- * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route()
- * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4
- * fields as follows:
+ * The original struct zapi_route_*() infrastructure was built around
+ * the traditional (32-bit "gate OR ifindex") nexthop data unit.
+ * A special encoding can be used to feed onlink (64-bit "gate AND ifindex")
+ * nexthops into zapi_route_encode() using the same zapi_route structure.
+ * This is done by setting zapi_route fields as follows:
* - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
* - .nexthop_num == .ifindex_num
* - .nexthop and .ifindex are filled with gate and ifindex parts of
* each compound nexthop, both in the same order
*
- * zapi_ipv4_route() will produce two nexthop data units for each such
- * interleaved 64-bit nexthop. On the zserv side of the socket it will be
- * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop structure.
- *
* If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
* byte value.
*
*
* XXX: No attention paid to alignment.
*/
-int zapi_ipv4_route(uint8_t cmd, struct zclient *zclient, struct prefix_ipv4 *p,
- struct zapi_ipv4 *api)
-{
- int i;
- int psize;
- struct stream *s;
-
- /* Reset stream. */
- s = zclient->obuf;
- stream_reset(s);
-
- /* Some checks for labeled-unicast. The current expectation is that each
- * nexthop is accompanied by a label in the case of labeled-unicast.
- */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
- && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
- /* We expect prefixes installed with labels and the number to
- * match
- * the number of nexthops.
- */
- assert(api->label_num == api->nexthop_num);
- }
-
- zclient_create_header(s, cmd, api->vrf_id);
-
- /* Put type and nexthop. */
- stream_putc(s, api->type);
- stream_putw(s, api->instance);
- stream_putl(s, api->flags);
- stream_putc(s, api->message);
- stream_putw(s, api->safi);
-
- /* Put prefix information. */
- psize = PSIZE(p->prefixlen);
- stream_putc(s, p->prefixlen);
- stream_write(s, (uint8_t *)&p->prefix, psize);
-
- /* Nexthop, ifindex, distance and metric information. */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
- stream_putc(s, api->nexthop_num + api->ifindex_num);
-
- for (i = 0; i < api->nexthop_num; i++) {
- stream_putc(s, NEXTHOP_TYPE_IPV4);
- stream_put_in_addr(s, api->nexthop[i]);
- /* For labeled-unicast, each nexthop is followed by
- * label. */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
- stream_putl(s, api->label[i]);
- }
- for (i = 0; i < api->ifindex_num; i++) {
- stream_putc(s, NEXTHOP_TYPE_IFINDEX);
- stream_putl(s, api->ifindex[i]);
- }
- }
-
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
- stream_putc(s, api->distance);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
- stream_putl(s, api->metric);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
- stream_putl(s, api->tag);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
- stream_putl(s, api->mtu);
-
- /* Put length at the first point of the stream. */
- stream_putw_at(s, 0, stream_get_endp(s));
-
- return zclient_send_message(zclient);
-}
-
-int zapi_ipv4_route_ipv6_nexthop(uint8_t cmd, struct zclient *zclient,
- struct prefix_ipv4 *p, struct zapi_ipv6 *api)
-{
- int i;
- int psize;
- struct stream *s;
-
- /* Reset stream. */
- s = zclient->obuf;
- stream_reset(s);
-
- /* Some checks for labeled-unicast. The current expectation is that each
- * nexthop is accompanied by a label in the case of labeled-unicast.
- */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
- && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
- /* We expect prefixes installed with labels and the number to
- * match
- * the number of nexthops.
- */
- assert(api->label_num == api->nexthop_num);
- }
-
- zclient_create_header(s, cmd, api->vrf_id);
-
- /* Put type and nexthop. */
- stream_putc(s, api->type);
- stream_putw(s, api->instance);
- stream_putl(s, api->flags);
- stream_putc(s, api->message);
- stream_putw(s, api->safi);
-
- /* Put prefix information. */
- psize = PSIZE(p->prefixlen);
- stream_putc(s, p->prefixlen);
- stream_write(s, (uint8_t *)&p->prefix, psize);
-
- /* Nexthop, ifindex, distance and metric information. */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
- stream_putc(s, api->nexthop_num + api->ifindex_num);
-
- for (i = 0; i < api->nexthop_num; i++) {
- stream_putc(s, NEXTHOP_TYPE_IPV6);
- stream_write(s, (uint8_t *)api->nexthop[i], 16);
- /* For labeled-unicast, each nexthop is followed by
- * label. */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
- stream_putl(s, api->label[i]);
- }
- for (i = 0; i < api->ifindex_num; i++) {
- stream_putc(s, NEXTHOP_TYPE_IFINDEX);
- stream_putl(s, api->ifindex[i]);
- }
- }
-
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
- stream_putc(s, api->distance);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
- stream_putl(s, api->metric);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
- stream_putl(s, api->tag);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
- stream_putl(s, api->mtu);
-
- /* Put length at the first point of the stream. */
- stream_putw_at(s, 0, stream_get_endp(s));
-
- return zclient_send_message(zclient);
-}
-
-int zapi_ipv6_route(uint8_t cmd, struct zclient *zclient, struct prefix_ipv6 *p,
- struct prefix_ipv6 *src_p, struct zapi_ipv6 *api)
-{
- int i;
- int psize;
- struct stream *s;
-
- /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL
- */
- assert(!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p);
-
- /* Reset stream. */
- s = zclient->obuf;
- stream_reset(s);
-
- /* Some checks for labeled-unicast. The current expectation is that each
- * nexthop is accompanied by a label in the case of labeled-unicast.
- */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
- && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
- /* We expect prefixes installed with labels and the number to
- * match
- * the number of nexthops.
- */
- assert(api->label_num == api->nexthop_num);
- }
-
- zclient_create_header(s, cmd, api->vrf_id);
-
- /* Put type and nexthop. */
- stream_putc(s, api->type);
- stream_putw(s, api->instance);
- stream_putl(s, api->flags);
- stream_putc(s, api->message);
- stream_putw(s, api->safi);
-
- /* Put prefix information. */
- psize = PSIZE(p->prefixlen);
- stream_putc(s, p->prefixlen);
- stream_write(s, (uint8_t *)&p->prefix, psize);
-
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
- psize = PSIZE(src_p->prefixlen);
- stream_putc(s, src_p->prefixlen);
- stream_write(s, (uint8_t *)&src_p->prefix, psize);
- }
-
- /* Nexthop, ifindex, distance and metric information. */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
- stream_putc(s, api->nexthop_num + api->ifindex_num);
-
- for (i = 0; i < api->nexthop_num; i++) {
- stream_putc(s, NEXTHOP_TYPE_IPV6);
- stream_write(s, (uint8_t *)api->nexthop[i], 16);
- /* For labeled-unicast, each nexthop is followed by
- * label. */
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
- stream_putl(s, api->label[i]);
- }
- for (i = 0; i < api->ifindex_num; i++) {
- stream_putc(s, NEXTHOP_TYPE_IFINDEX);
- stream_putl(s, api->ifindex[i]);
- }
- }
-
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
- stream_putc(s, api->distance);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
- stream_putl(s, api->metric);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
- stream_putl(s, api->tag);
- if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
- stream_putl(s, api->mtu);
-
- /* Put length at the first point of the stream. */
- stream_putw_at(s, 0, stream_get_endp(s));
-
- return zclient_send_message(zclient);
-}
-
int zclient_route_send(uint8_t cmd, struct zclient *zclient,
struct zapi_route *api)
{
stream_putl(s, api->flags);
stream_putc(s, api->message);
stream_putc(s, api->safi);
- if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
- stream_put(s, &(api->rmac), sizeof(struct ethaddr));
/* Put prefix information. */
stream_putc(s, api->prefix.family);
char buf[PREFIX2STR_BUFFER];
prefix2str(&api->prefix, buf,
sizeof(buf));
- zlog_err(
- "%s: prefix %s: can't encode "
- "%u labels (maximum is %u)",
- __func__, buf,
- api_nh->label_num,
- MPLS_MAX_LABELS);
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "%s: prefix %s: can't encode "
+ "%u labels (maximum is %u)",
+ __func__, buf,
+ api_nh->label_num,
+ MPLS_MAX_LABELS);
return -1;
}
api_nh->label_num
* sizeof(mpls_label_t));
}
+
+ /* Router MAC for EVPN routes. */
+ if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ stream_put(s, &(api_nh->rmac),
+ sizeof(struct ethaddr));
}
}
STREAM_GETL(s, api->flags);
STREAM_GETC(s, api->message);
STREAM_GETC(s, api->safi);
- if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
- STREAM_GET(&(api->rmac), s, sizeof(struct ethaddr));
/* Prefix. */
STREAM_GETC(s, api->prefix.family);
api_nh->label_num
* sizeof(mpls_label_t));
}
+
+ /* Router MAC for EVPN routes. */
+ if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ stream_get(&(api_nh->rmac), s,
+ sizeof(struct ethaddr));
}
}
return 0;
}
-static void zapi_encode_prefix(struct stream *s,
- struct prefix *p,
- uint8_t family)
+static void zapi_encode_prefix(struct stream *s, struct prefix *p,
+ uint8_t family)
{
struct prefix any;
stream_put(s, &p->u.prefix, prefix_blen(p));
}
-int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s,
- struct pbr_rule *zrule)
+int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
{
stream_reset(s);
zclient_create_header(s, cmd, zrule->vrf_id);
zapi_encode_prefix(s, &(zrule->filter.src_ip),
zrule->filter.src_ip.family);
- stream_putw(s, zrule->filter.src_port); /* src port */
+ stream_putw(s, zrule->filter.src_port); /* src port */
zapi_encode_prefix(s, &(zrule->filter.dst_ip),
zrule->filter.src_ip.family);
- stream_putw(s, zrule->filter.dst_port); /* dst port */
- stream_putw(s, zrule->filter.fwmark); /* fwmark */
+ stream_putw(s, zrule->filter.dst_port); /* dst port */
+ stream_putw(s, zrule->filter.fwmark); /* fwmark */
stream_putl(s, zrule->action.table);
stream_putl(s, zrule->ifindex);
STREAM_GETL(s, ifi);
if (zclient_debug)
- zlog_debug("%s: %u %u %u %u", __PRETTY_FUNCTION__,
- seq, prio, uni, ifi);
+ zlog_debug("%s: %u %u %u %u", __PRETTY_FUNCTION__, seq, prio,
+ uni, ifi);
*seqno = seq;
*priority = prio;
*unique = uni;
return false;
}
-bool zapi_ipset_notify_decode(struct stream *s,
- uint32_t *unique,
- enum zapi_ipset_notify_owner *note)
+bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
+ enum zapi_ipset_notify_owner *note)
{
uint32_t uni;
return false;
}
-bool zapi_ipset_entry_notify_decode(struct stream *s,
- uint32_t *unique,
- char *ipset_name,
- enum zapi_ipset_entry_notify_owner *note)
+bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
+ char *ipset_name,
+ enum zapi_ipset_entry_notify_owner *note)
{
uint32_t uni;
STREAM_GETL(s, uni);
- STREAM_GET(ipset_name, s,
- ZEBRA_IPSET_NAME_SIZE);
+ STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
+
+ if (zclient_debug)
+ zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
+ *unique = uni;
+
+ return true;
+
+stream_failure:
+ return false;
+}
+
+bool zapi_iptable_notify_decode(struct stream *s,
+ uint32_t *unique,
+ enum zapi_iptable_notify_owner *note)
+{
+ uint32_t uni;
+
+ STREAM_GET(note, s, sizeof(*note));
+
+ STREAM_GETL(s, uni);
if (zclient_debug)
zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
*/
if (znh->label_num) {
nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
- znh->labels);
+ znh->labels);
}
return n;
if (nhr->nexthops[i].label_num)
STREAM_GET(&nhr->nexthops[i].labels[0], s,
nhr->nexthops[i].label_num
- * sizeof(mpls_label_t));
+ * sizeof(mpls_label_t));
}
return true;
for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
iflp->unrsv_bw[i] = stream_getf(s);
if (i < bwclassnum)
- zlog_err(
- "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
- " - outdated library?",
- __func__, bwclassnum, MAX_CLASS_TYPE);
+ flog_err(LIB_ERR_ZAPI_MISSMATCH,
+ "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
+ " - outdated library?",
+ __func__, bwclassnum, MAX_CLASS_TYPE);
}
iflp->admin_grp = stream_getl(s);
iflp->rmt_as = stream_getl(s);
struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
if (ifp == NULL) {
- zlog_err("%s: unknown ifindex %u, shouldn't happen", __func__,
- ifindex);
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "%s: unknown ifindex %u, shouldn't happen", __func__,
+ ifindex);
return NULL;
}
zlog_warn(
"warning: interface %s address %s "
"with peer flag set, but no peer address!",
- ifp->name, prefix2str(ifc->address, buf,
- sizeof buf));
+ ifp->name,
+ prefix2str(ifc->address, buf,
+ sizeof buf));
UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
}
}
size);
}
if (ret != 0) {
- zlog_err("%s: Invalid Sync Message Reply", __func__);
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "%s: Invalid Sync Message Reply", __func__);
return -1;
}
uint8_t result;
if (zclient_debug)
- zlog_debug("Connecting to Label Manager");
+ zlog_debug("Connecting to Label Manager (LM)");
if (zclient->sock < 0)
return -1;
ret = writen(zclient->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- zlog_err("%s: can't write to zclient->sock", __func__);
+ flog_err(LIB_ERR_ZAPI_SOCKET, "Can't write to zclient sock");
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (ret == 0) {
- zlog_err("%s: zclient->sock connection closed", __func__);
+ flog_err(LIB_ERR_ZAPI_SOCKET, "Zclient sock closed");
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (zclient_debug)
- zlog_debug("%s: Label manager connect request (%d bytes) sent",
- __func__, ret);
+ zlog_debug("LM connect request sent (%d bytes)", ret);
/* read response */
if (zclient_read_sync_response(zclient, ZEBRA_LABEL_MANAGER_CONNECT)
!= 0)
return -1;
- /* result */
s = zclient->ibuf;
+
+ /* read instance and proto */
+ uint8_t proto = stream_getc(s);
+ uint16_t instance = stream_getw(s);
+
+ /* sanity */
+ if (proto != zclient->redist_default)
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "Wrong proto (%u) in LM connect response. Should be %u",
+ proto, zclient->redist_default);
+ if (instance != zclient->instance)
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "Wrong instId (%u) in LM connect response. Should be %u",
+ instance, zclient->instance);
+
+ /* result code */
result = stream_getc(s);
if (zclient_debug)
- zlog_debug(
- "%s: Label Manager connect response received, result %u",
- __func__, result);
+ zlog_debug("LM connect-response received, result %u", result);
return (int)result;
}
* @param chunk_size Amount of labels requested
* @result 0 on success, -1 otherwise
*/
-int zclient_send_get_label_chunk(
- struct zclient *zclient,
- uint8_t keep,
- uint32_t chunk_size)
+int zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
+ uint32_t chunk_size)
{
struct stream *s;
stream_reset(s);
zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
+ /* proto */
+ stream_putc(s, zclient->redist_default);
+ /* instance */
+ stream_putw(s, zclient->instance);
stream_putc(s, keep);
stream_putl(s, chunk_size);
s = zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
+ /* proto */
+ stream_putc(s, zclient->redist_default);
+ /* instance */
+ stream_putw(s, zclient->instance);
/* keep */
stream_putc(s, keep);
/* chunk size */
ret = writen(zclient->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- zlog_err("%s: can't write to zclient->sock", __func__);
+ flog_err(LIB_ERR_ZAPI_SOCKET,
+ "Can't write to zclient sock");
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (ret == 0) {
- zlog_err("%s: zclient->sock connection closed", __func__);
+ flog_err(LIB_ERR_ZAPI_SOCKET,
+ "Zclient sock closed");
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (zclient_debug)
- zlog_debug("%s: Label chunk request (%d bytes) sent", __func__,
- ret);
+ zlog_debug("Label chunk request (%d bytes) sent", ret);
/* read response */
if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
return -1;
+ /* parse response */
s = zclient->ibuf;
+
+ /* read proto and instance */
+ uint8_t proto = stream_getc(s);
+ uint16_t instance = stream_getw(s);
+
+ /* sanities */
+ if (proto != zclient->redist_default)
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "Wrong proto (%u) in get chunk response. Should be %u",
+ proto, zclient->redist_default);
+ if (instance != zclient->instance)
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "Wrong instId (%u) in get chunk response Should be %u",
+ instance, zclient->instance);
+
/* keep */
response_keep = stream_getc(s);
/* start and end labels */
/* not owning this response */
if (keep != response_keep) {
- zlog_err(
- "%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
- __func__, *start, *end, keep, response_keep);
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
+ *start, *end, keep, response_keep);
}
/* sanity */
if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
|| *end > MPLS_LABEL_UNRESERVED_MAX) {
- zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start,
- *end);
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "Invalid Label chunk: %u - %u", *start, *end);
return -1;
}
if (zclient_debug)
- zlog_debug("Label Chunk assign: %u - %u (%u) ", *start, *end,
+ zlog_debug("Label Chunk assign: %u - %u (%u)", *start, *end,
response_keep);
return 0;
struct stream *s;
if (zclient_debug)
- zlog_debug("Releasing Label Chunk");
+ zlog_debug("Releasing Label Chunk %u - %u", start, end);
if (zclient->sock < 0)
return -1;
stream_reset(s);
zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
+ /* proto */
+ stream_putc(s, zclient->redist_default);
+ /* instance */
+ stream_putw(s, zclient->instance);
/* start */
stream_putl(s, start);
/* end */
ret = writen(zclient->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- zlog_err("%s: can't write to zclient->sock", __func__);
+ flog_err(LIB_ERR_ZAPI_SOCKET, "Can't write to zclient sock");
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (ret == 0) {
- zlog_err("%s: zclient->sock connection closed", __func__);
+ flog_err(LIB_ERR_ZAPI_SOCKET,
+ "Zclient sock connection closed");
close(zclient->sock);
zclient->sock = -1;
return -1;
return -1;
if (zclient_debug)
- zlog_debug("%s: Table manager connect request sent",
- __func__);
+ zlog_debug("%s: Table manager connect request sent", __func__);
/* read response */
if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
ret = writen(zclient->sock, s->data, stream_get_endp(s));
if (ret < 0) {
- zlog_err("%s: can't write to zclient->sock", __func__);
+ flog_err(LIB_ERR_ZAPI_SOCKET,
+ "%s: can't write to zclient->sock", __func__);
close(zclient->sock);
zclient->sock = -1;
return -1;
}
if (ret == 0) {
- zlog_err("%s: zclient->sock connection closed", __func__);
+ flog_err(LIB_ERR_ZAPI_SOCKET,
+ "%s: zclient->sock connection closed", __func__);
close(zclient->sock);
zclient->sock = -1;
return -1;
stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
break;
default:
- zlog_err("%s: unknown af", __func__);
+ flog_err(LIB_ERR_ZAPI_ENCODE,
+ "%s: unknown af", __func__);
return -1;
}
pw->status = stream_getl(s);
}
+static void zclient_capability_decode(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct zclient_capabilities cap;
+ struct stream *s = zclient->ibuf;
+ uint8_t mpls_enabled;
+
+ memset(&cap, 0, sizeof(cap));
+ STREAM_GETC(s, mpls_enabled);
+ cap.mpls_enabled = !!mpls_enabled;
+ STREAM_GETL(s, cap.ecmp);
+
+ if (zclient->zebra_capabilities)
+ (*zclient->zebra_capabilities)(&cap);
+
+stream_failure:
+ return;
+}
+
/* Zebra client message read function. */
static int zclient_read(struct thread *thread)
{
command = stream_getw(zclient->ibuf);
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
- zlog_err(
- "%s: socket %d version mismatch, marker %d, version %d",
- __func__, zclient->sock, marker, version);
+ flog_err(LIB_ERR_ZAPI_MISSMATCH,
+ "%s: socket %d version mismatch, marker %d, version %d",
+ __func__, zclient->sock, marker, version);
return zclient_failed(zclient);
}
if (length < ZEBRA_HEADER_SIZE) {
- zlog_err("%s: socket %d message length %u is less than %d ",
- __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
+ flog_err(LIB_ERR_ZAPI_MISSMATCH,
+ "%s: socket %d message length %u is less than %d ",
+ __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
return zclient_failed(zclient);
}
(void *)zclient, command, vrf_id);
switch (command) {
+ case ZEBRA_CAPABILITIES:
+ zclient_capability_decode(command, zclient, length, vrf_id);
+ break;
case ZEBRA_ROUTER_ID_UPDATE:
if (zclient->router_id_update)
(*zclient->router_id_update)(command, zclient, length,
if (zclient->fec_update)
(*zclient->fec_update)(command, zclient, length);
break;
+ case ZEBRA_LOCAL_ES_ADD:
+ if (zclient->local_es_add)
+ (*zclient->local_es_add)(command, zclient, length,
+ vrf_id);
+ break;
+ case ZEBRA_LOCAL_ES_DEL:
+ if (zclient->local_es_del)
+ (*zclient->local_es_del)(command, zclient, length,
+ vrf_id);
+ break;
case ZEBRA_VNI_ADD:
if (zclient->local_vni_add)
(*zclient->local_vni_add)(command, zclient, length,
case ZEBRA_GET_LABEL_CHUNK:
if (zclient->label_chunk)
(*zclient->label_chunk)(command, zclient, length,
+ vrf_id);
+ break;
+ case ZEBRA_IPSET_NOTIFY_OWNER:
+ if (zclient->ipset_notify_owner)
+ (*zclient->ipset_notify_owner)(command, zclient, length,
vrf_id);
break;
+ case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
+ if (zclient->ipset_entry_notify_owner)
+ (*zclient->ipset_entry_notify_owner)(command,
+ zclient, length,
+ vrf_id);
+ break;
+ case ZEBRA_IPTABLE_NOTIFY_OWNER:
+ if (zclient->iptable_notify_owner)
+ (*zclient->iptable_notify_owner)(command,
+ zclient, length,
+ vrf_id);
default:
break;
}