lib, zebra: Modify zebra to use STREAM_GET for zapi

This code modifies zebra to use the STREAM_GET functionality.
This will allow zebra to continue functioning in the case of
bad input data from higher level protocols instead of crashing.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2017-11-10 08:51:34 -05:00
parent 051cc28c8f
commit ec93aa120e
7 changed files with 521 additions and 240 deletions

View File

@ -297,11 +297,12 @@ int zclient_read_header(struct stream *s, int sock, u_int16_t *size,
if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE) if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
return -1; return -1;
*size = stream_getw(s) - ZEBRA_HEADER_SIZE; STREAM_GETW(s, *size);
*marker = stream_getc(s); *size -= ZEBRA_HEADER_SIZE;
*version = stream_getc(s); STREAM_GETC(s, *marker);
*vrf_id = stream_getw(s); STREAM_GETC(s, *version);
*cmd = stream_getw(s); STREAM_GETW(s, *vrf_id);
STREAM_GETW(s, *cmd);
if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) { if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
zlog_err( zlog_err(
@ -313,6 +314,7 @@ int zclient_read_header(struct stream *s, int sock, u_int16_t *size,
if (*size && stream_read(s, sock, *size) != *size) if (*size && stream_read(s, sock, *size) != *size)
return -1; return -1;
stream_failure:
return 0; return 0;
} }
@ -956,6 +958,10 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api)
16); 16);
stream_putl(s, api_nh->ifindex); stream_putl(s, api_nh->ifindex);
break; break;
default:
zlog_warn("%s: Specified Nexthop type %d does not exist",
__PRETTY_FUNCTION__, api_nh->type);
return -1;
} }
/* MPLS labels for BGP-LU or Segment Routing */ /* MPLS labels for BGP-LU or Segment Routing */
@ -1005,37 +1011,66 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
memset(api, 0, sizeof(*api)); memset(api, 0, sizeof(*api));
/* Type, flags, message. */ /* Type, flags, message. */
api->type = stream_getc(s); STREAM_GETC(s, api->type);
api->instance = stream_getw(s); if (api->type > ZEBRA_ROUTE_MAX) {
api->flags = stream_getl(s); zlog_warn("%s: Specified route type: %d is not a legal value\n",
api->message = stream_getc(s); __PRETTY_FUNCTION__, api->type);
api->safi = stream_getw(s); return -1;
}
STREAM_GETW(s, api->instance);
STREAM_GETL(s, api->flags);
STREAM_GETC(s, api->message);
STREAM_GETW(s, api->safi);
/* Prefix. */ /* Prefix. */
api->prefix.family = stream_getc(s); STREAM_GETC(s, api->prefix.family);
STREAM_GETC(s, api->prefix.prefixlen);
switch (api->prefix.family) { switch (api->prefix.family) {
case AF_INET: case AF_INET:
api->prefix.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
zlog_warn("%s: V4 prefixlen is %d which should not be more than 32",
__PRETTY_FUNCTION__, api->prefix.prefixlen);
return -1;
}
break; break;
case AF_INET6: case AF_INET6:
api->prefix.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
zlog_warn("%s: v6 prefixlen is %d which should not be more than 128",
__PRETTY_FUNCTION__, api->prefix.prefixlen);
return -1;
}
break; break;
default:
zlog_warn("%s: Specified family %d is not v4 or v6",
__PRETTY_FUNCTION__, api->prefix.family);
return -1;
} }
stream_get(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen)); STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) { if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
api->src_prefix.family = AF_INET6; api->src_prefix.family = AF_INET6;
api->src_prefix.prefixlen = stream_getc(s); STREAM_GETC(s, api->src_prefix.prefixlen);
stream_get(&api->src_prefix.prefix, s, if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
zlog_warn("%s: SRC Prefix prefixlen received: %d is too large",
__PRETTY_FUNCTION__,
api->src_prefix.prefixlen);
return -1;
}
STREAM_GET(&api->src_prefix.prefix, s,
PSIZE(api->src_prefix.prefixlen)); PSIZE(api->src_prefix.prefixlen));
if (api->prefix.family != AF_INET6 if (api->prefix.family != AF_INET6
|| api->src_prefix.prefixlen == 0) || api->src_prefix.prefixlen == 0) {
UNSET_FLAG(api->message, ZAPI_MESSAGE_SRCPFX); zlog_warn("%s: SRC prefix specified in some manner that makes no sense",
__PRETTY_FUNCTION__);
return -1;
}
} }
/* Nexthops. */ /* Nexthops. */
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
api->nexthop_num = stream_getw(s); STREAM_GETW(s, api->nexthop_num);
if (api->nexthop_num > MULTIPATH_NUM) { if (api->nexthop_num > MULTIPATH_NUM) {
zlog_warn("%s: invalid number of nexthops (%u)", zlog_warn("%s: invalid number of nexthops (%u)",
__func__, api->nexthop_num); __func__, api->nexthop_num);
@ -1045,33 +1080,40 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
for (i = 0; i < api->nexthop_num; i++) { for (i = 0; i < api->nexthop_num; i++) {
api_nh = &api->nexthops[i]; api_nh = &api->nexthops[i];
api_nh->type = stream_getc(s); STREAM_GETC(s, api_nh->type);
switch (api_nh->type) { switch (api_nh->type) {
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
api_nh->bh_type = stream_getc(s); STREAM_GETC(s, api_nh->bh_type);
break; break;
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
api_nh->gate.ipv4.s_addr = stream_get_ipv4(s); STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
IPV4_MAX_BYTELEN);
break; break;
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
api_nh->gate.ipv4.s_addr = stream_get_ipv4(s); STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
api_nh->ifindex = stream_getl(s); IPV4_MAX_BYTELEN);
STREAM_GETL(s, api_nh->ifindex);
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
api_nh->ifindex = stream_getl(s); STREAM_GETL(s, api_nh->ifindex);
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
stream_get(&api_nh->gate.ipv6, s, 16); STREAM_GET(&api_nh->gate.ipv6, s, 16);
break; break;
case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX:
stream_get(&api_nh->gate.ipv6, s, 16); STREAM_GET(&api_nh->gate.ipv6, s, 16);
api_nh->ifindex = stream_getl(s); STREAM_GETL(s, api_nh->ifindex);
break; break;
default:
zlog_warn("%s: Specified nexthop type %d does not exist",
__PRETTY_FUNCTION__,
api_nh->type);
return -1;
} }
/* MPLS labels for BGP-LU or Segment Routing */ /* MPLS labels for BGP-LU or Segment Routing */
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) { if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) {
api_nh->label_num = stream_getc(s); STREAM_GETC(s, api_nh->label_num);
if (api_nh->label_num > MPLS_MAX_LABELS) { if (api_nh->label_num > MPLS_MAX_LABELS) {
zlog_warn( zlog_warn(
@ -1081,7 +1123,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
return -1; return -1;
} }
stream_get(&api_nh->labels[0], s, STREAM_GET(&api_nh->labels[0], s,
api_nh->label_num api_nh->label_num
* sizeof(mpls_label_t)); * sizeof(mpls_label_t));
} }
@ -1090,14 +1132,15 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
/* Attributes. */ /* Attributes. */
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
api->distance = stream_getc(s); STREAM_GETC(s, api->distance);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC)) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
api->metric = stream_getl(s); STREAM_GETL(s, api->metric);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG)) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
api->tag = stream_getl(s); STREAM_GETL(s, api->tag);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU)) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
api->mtu = stream_getl(s); STREAM_GETL(s, api->mtu);
stream_failure:
return 0; return 0;
} }
@ -1136,17 +1179,23 @@ static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
return; return;
stream_get(&p->u.prefix, s, plen); stream_get(&p->u.prefix, s, plen);
c = stream_getc(s); STREAM_GETC(s, c);
p->prefixlen = MIN(plen * 8, c); p->prefixlen = MIN(plen * 8, c);
stream_failure:
return;
} }
/* Router-id update from zebra daemon. */ /* Router-id update from zebra daemon. */
void zebra_router_id_update_read(struct stream *s, struct prefix *rid) void zebra_router_id_update_read(struct stream *s, struct prefix *rid)
{ {
/* Fetch interface address. */ /* Fetch interface address. */
rid->family = stream_getc(s); STREAM_GETC(s, rid->family);
zclient_stream_get_prefix(s, rid); zclient_stream_get_prefix(s, rid);
stream_failure:
return;
} }
/* Interface addition from zebra daemon. */ /* Interface addition from zebra daemon. */

View File

@ -246,16 +246,25 @@ void redistribute_delete(struct prefix *p, struct prefix *src_p,
void zebra_redistribute_add(int command, struct zserv *client, int length, void zebra_redistribute_add(int command, struct zserv *client, int length,
struct zebra_vrf *zvrf) struct zebra_vrf *zvrf)
{ {
afi_t afi; afi_t afi = 0;
int type; int type = 0;
u_short instance; u_short instance;
afi = stream_getc(client->ibuf); STREAM_GETC(client->ibuf, afi);
type = stream_getc(client->ibuf); STREAM_GETC(client->ibuf, type);
instance = stream_getw(client->ibuf); STREAM_GETW(client->ibuf, instance);
if (type == 0 || type >= ZEBRA_ROUTE_MAX) if (afi == 0 || afi > AFI_MAX) {
zlog_warn("%s: Specified afi %d does not exist",
__PRETTY_FUNCTION__, afi);
return; return;
}
if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
zlog_warn("%s: Specified Route Type %d does not exist",
__PRETTY_FUNCTION__, type);
return;
}
if (instance) { if (instance) {
if (!redist_check_instance(&client->mi_redist[afi][type], if (!redist_check_instance(&client->mi_redist[afi][type],
@ -273,21 +282,33 @@ void zebra_redistribute_add(int command, struct zserv *client, int length,
zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi); zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
} }
} }
stream_failure:
return;
} }
void zebra_redistribute_delete(int command, struct zserv *client, int length, void zebra_redistribute_delete(int command, struct zserv *client, int length,
struct zebra_vrf *zvrf) struct zebra_vrf *zvrf)
{ {
afi_t afi; afi_t afi = 0;
int type; int type = 0;
u_short instance; u_short instance;
afi = stream_getc(client->ibuf); STREAM_GETC(client->ibuf, afi);
type = stream_getc(client->ibuf); STREAM_GETC(client->ibuf, type);
instance = stream_getw(client->ibuf); STREAM_GETW(client->ibuf, instance);
if (type == 0 || type >= ZEBRA_ROUTE_MAX) if (afi == 0 || afi > AFI_MAX) {
zlog_warn("%s: Specified afi %d does not exist",
__PRETTY_FUNCTION__, afi);
return; return;
}
if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
zlog_warn("%s: Specified Route Type %d does not exist",
__PRETTY_FUNCTION__, type);
return;
}
/* /*
* NOTE: no need to withdraw the previously advertised routes. The * NOTE: no need to withdraw the previously advertised routes. The
@ -299,6 +320,9 @@ void zebra_redistribute_delete(int command, struct zserv *client, int length,
redist_del_instance(&client->mi_redist[afi][type], instance); redist_del_instance(&client->mi_redist[afi][type], instance);
else else
vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf)); vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
stream_failure:
return;
} }
void zebra_redistribute_default_add(int command, struct zserv *client, void zebra_redistribute_default_add(int command, struct zserv *client,

View File

@ -804,7 +804,7 @@ void zebra_interface_radv_set(struct zserv *client, u_short length,
struct zebra_vrf *zvrf, int enable) struct zebra_vrf *zvrf, int enable)
{ {
struct stream *s; struct stream *s;
unsigned int ifindex; ifindex_t ifindex;
struct interface *ifp; struct interface *ifp;
struct zebra_if *zif; struct zebra_if *zif;
int ra_interval; int ra_interval;
@ -812,8 +812,8 @@ void zebra_interface_radv_set(struct zserv *client, u_short length,
s = client->ibuf; s = client->ibuf;
/* Get interface index and RA interval. */ /* Get interface index and RA interval. */
ifindex = stream_getl(s); STREAM_GETL(s, ifindex);
ra_interval = stream_getl(s); STREAM_GETL(s, ra_interval);
if (IS_ZEBRA_DEBUG_EVENT) if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%u: IF %u RA %s from client %s, interval %ds", zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
@ -849,6 +849,8 @@ void zebra_interface_radv_set(struct zserv *client, u_short length,
ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS); ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
} }
} }
stream_failure:
return;
} }
DEFUN (ipv6_nd_suppress_ra, DEFUN (ipv6_nd_suppress_ra,

View File

@ -37,12 +37,12 @@ int zebra_ipmr_route_stats(struct zserv *client, u_short length,
{ {
struct mcast_route_data mroute; struct mcast_route_data mroute;
struct stream *s; struct stream *s;
int suc; int suc = -1;
memset(&mroute, 0, sizeof(mroute)); memset(&mroute, 0, sizeof(mroute));
stream_get(&mroute.sg.src, client->ibuf, 4); STREAM_GET(&mroute.sg.src, client->ibuf, 4);
stream_get(&mroute.sg.grp, client->ibuf, 4); STREAM_GET(&mroute.sg.grp, client->ibuf, 4);
mroute.ifindex = stream_getl(client->ibuf); STREAM_GETL(client->ibuf, mroute.ifindex);
if (IS_ZEBRA_DEBUG_KERNEL) { if (IS_ZEBRA_DEBUG_KERNEL) {
char sbuf[40]; char sbuf[40];
@ -56,6 +56,7 @@ int zebra_ipmr_route_stats(struct zserv *client, u_short length,
suc = kernel_get_ipmr_sg_stats(zvrf, &mroute); suc = kernel_get_ipmr_sg_stats(zvrf, &mroute);
stream_failure:
s = client->obuf; s = client->obuf;
stream_reset(s); stream_reset(s);

View File

@ -705,19 +705,19 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
s = client->ibuf; s = client->ibuf;
pid = stream_getl(s); STREAM_GETL(s, pid);
sprintf(tmp_buf, "%d", pid); sprintf(tmp_buf, "%d", pid);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD,
tmp_buf); tmp_buf);
dst_p.family = stream_getw(s); STREAM_GETW(s, dst_p.family);
if (dst_p.family == AF_INET) if (dst_p.family == AF_INET)
dst_p.prefixlen = IPV4_MAX_BYTELEN; dst_p.prefixlen = IPV4_MAX_BYTELEN;
else else
dst_p.prefixlen = IPV6_MAX_BYTELEN; dst_p.prefixlen = IPV6_MAX_BYTELEN;
stream_get(&dst_p.u.prefix, s, dst_p.prefixlen); STREAM_GET(&dst_p.u.prefix, s, dst_p.prefixlen);
if (dst_p.family == AF_INET) { if (dst_p.family == AF_INET) {
inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf)); inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf));
ptm_lib_append_msg(ptm_hdl, out_ctxt, ptm_lib_append_msg(ptm_hdl, out_ctxt,
@ -728,32 +728,32 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
ZEBRA_PTM_BFD_DST_IP_FIELD, buf); ZEBRA_PTM_BFD_DST_IP_FIELD, buf);
} }
min_rx_timer = stream_getl(s); STREAM_GETL(s, min_rx_timer);
sprintf(tmp_buf, "%d", min_rx_timer); sprintf(tmp_buf, "%d", min_rx_timer);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_RX_FIELD, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_RX_FIELD,
tmp_buf); tmp_buf);
min_tx_timer = stream_getl(s); STREAM_GETL(s, min_tx_timer);
sprintf(tmp_buf, "%d", min_tx_timer); sprintf(tmp_buf, "%d", min_tx_timer);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_TX_FIELD, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_TX_FIELD,
tmp_buf); tmp_buf);
detect_mul = stream_getc(s); STREAM_GETC(s, detect_mul);
sprintf(tmp_buf, "%d", detect_mul); sprintf(tmp_buf, "%d", detect_mul);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DETECT_MULT_FIELD, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DETECT_MULT_FIELD,
tmp_buf); tmp_buf);
multi_hop = stream_getc(s); STREAM_GETC(s, multi_hop);
if (multi_hop) { if (multi_hop) {
sprintf(tmp_buf, "%d", 1); sprintf(tmp_buf, "%d", 1);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ptm_lib_append_msg(ptm_hdl, out_ctxt,
ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf); ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf);
src_p.family = stream_getw(s); STREAM_GETW(s, src_p.family);
if (src_p.family == AF_INET) if (src_p.family == AF_INET)
src_p.prefixlen = IPV4_MAX_BYTELEN; src_p.prefixlen = IPV4_MAX_BYTELEN;
else else
src_p.prefixlen = IPV6_MAX_BYTELEN; src_p.prefixlen = IPV6_MAX_BYTELEN;
stream_get(&src_p.u.prefix, s, src_p.prefixlen); STREAM_GET(&src_p.u.prefix, s, src_p.prefixlen);
if (src_p.family == AF_INET) { if (src_p.family == AF_INET) {
inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf)); inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf));
ptm_lib_append_msg(ptm_hdl, out_ctxt, ptm_lib_append_msg(ptm_hdl, out_ctxt,
@ -764,7 +764,7 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); ZEBRA_PTM_BFD_SRC_IP_FIELD, buf);
} }
multi_hop_cnt = stream_getc(s); STREAM_GETC(s, multi_hop_cnt);
sprintf(tmp_buf, "%d", multi_hop_cnt); sprintf(tmp_buf, "%d", multi_hop_cnt);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ptm_lib_append_msg(ptm_hdl, out_ctxt,
ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, tmp_buf); ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, tmp_buf);
@ -775,14 +775,14 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
zvrf_name(zvrf)); zvrf_name(zvrf));
} else { } else {
if (dst_p.family == AF_INET6) { if (dst_p.family == AF_INET6) {
src_p.family = stream_getw(s); STREAM_GETW(s, src_p.family);
if (src_p.family == AF_INET) if (src_p.family == AF_INET)
src_p.prefixlen = IPV4_MAX_BYTELEN; src_p.prefixlen = IPV4_MAX_BYTELEN;
else else
src_p.prefixlen = IPV6_MAX_BYTELEN; src_p.prefixlen = IPV6_MAX_BYTELEN;
stream_get(&src_p.u.prefix, s, src_p.prefixlen); STREAM_GET(&src_p.u.prefix, s, src_p.prefixlen);
if (src_p.family == AF_INET) { if (src_p.family == AF_INET) {
inet_ntop(AF_INET, &src_p.u.prefix4, buf, inet_ntop(AF_INET, &src_p.u.prefix4, buf,
sizeof(buf)); sizeof(buf));
@ -797,8 +797,8 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
buf); buf);
} }
} }
len = stream_getc(s); STREAM_GETC(s, len);
stream_get(if_name, s, len); STREAM_GET(if_name, s, len);
if_name[len] = '\0'; if_name[len] = '\0';
ptm_lib_append_msg(ptm_hdl, out_ctxt, ptm_lib_append_msg(ptm_hdl, out_ctxt,
@ -815,6 +815,8 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
zlog_debug("%s: Sent message (%d) %s", __func__, data_len, zlog_debug("%s: Sent message (%d) %s", __func__, data_len,
ptm_cb.out_data); ptm_cb.out_data);
zebra_ptm_send_message(ptm_cb.out_data, data_len); zebra_ptm_send_message(ptm_cb.out_data, data_len);
stream_failure:
return 0; return 0;
} }
@ -858,19 +860,19 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
s = client->ibuf; s = client->ibuf;
pid = stream_getl(s); STREAM_GETL(s, pid);
sprintf(tmp_buf, "%d", pid); sprintf(tmp_buf, "%d", pid);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD,
tmp_buf); tmp_buf);
dst_p.family = stream_getw(s); STREAM_GETW(s, dst_p.family);
if (dst_p.family == AF_INET) if (dst_p.family == AF_INET)
dst_p.prefixlen = IPV4_MAX_BYTELEN; dst_p.prefixlen = IPV4_MAX_BYTELEN;
else else
dst_p.prefixlen = IPV6_MAX_BYTELEN; dst_p.prefixlen = IPV6_MAX_BYTELEN;
stream_get(&dst_p.u.prefix, s, dst_p.prefixlen); STREAM_GET(&dst_p.u.prefix, s, dst_p.prefixlen);
if (dst_p.family == AF_INET) if (dst_p.family == AF_INET)
inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf)); inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf));
else else
@ -878,20 +880,20 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf);
multi_hop = stream_getc(s); STREAM_GETC(s, multi_hop);
if (multi_hop) { if (multi_hop) {
sprintf(tmp_buf, "%d", 1); sprintf(tmp_buf, "%d", 1);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ptm_lib_append_msg(ptm_hdl, out_ctxt,
ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf); ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf);
src_p.family = stream_getw(s); STREAM_GETW(s, src_p.family);
if (src_p.family == AF_INET) if (src_p.family == AF_INET)
src_p.prefixlen = IPV4_MAX_BYTELEN; src_p.prefixlen = IPV4_MAX_BYTELEN;
else else
src_p.prefixlen = IPV6_MAX_BYTELEN; src_p.prefixlen = IPV6_MAX_BYTELEN;
stream_get(&src_p.u.prefix, s, src_p.prefixlen); STREAM_GET(&src_p.u.prefix, s, src_p.prefixlen);
if (src_p.family == AF_INET) if (src_p.family == AF_INET)
inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf)); inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf));
else else
@ -905,14 +907,14 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
zvrf_name(zvrf)); zvrf_name(zvrf));
} else { } else {
if (dst_p.family == AF_INET6) { if (dst_p.family == AF_INET6) {
src_p.family = stream_getw(s); STREAM_GETW(s, src_p.family);
if (src_p.family == AF_INET) if (src_p.family == AF_INET)
src_p.prefixlen = IPV4_MAX_BYTELEN; src_p.prefixlen = IPV4_MAX_BYTELEN;
else else
src_p.prefixlen = IPV6_MAX_BYTELEN; src_p.prefixlen = IPV6_MAX_BYTELEN;
stream_get(&src_p.u.prefix, s, src_p.prefixlen); STREAM_GET(&src_p.u.prefix, s, src_p.prefixlen);
if (src_p.family == AF_INET) { if (src_p.family == AF_INET) {
inet_ntop(AF_INET, &src_p.u.prefix4, buf, inet_ntop(AF_INET, &src_p.u.prefix4, buf,
sizeof(buf)); sizeof(buf));
@ -928,8 +930,8 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
} }
} }
len = stream_getc(s); STREAM_GETC(s, len);
stream_get(if_name, s, len); STREAM_GET(if_name, s, len);
if_name[len] = '\0'; if_name[len] = '\0';
ptm_lib_append_msg(ptm_hdl, out_ctxt, ptm_lib_append_msg(ptm_hdl, out_ctxt,
@ -942,6 +944,8 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
ptm_cb.out_data); ptm_cb.out_data);
zebra_ptm_send_message(ptm_cb.out_data, data_len); zebra_ptm_send_message(ptm_cb.out_data, data_len);
stream_failure:
return 0; return 0;
} }
@ -962,7 +966,7 @@ int zebra_ptm_bfd_client_register(struct zserv *client,
zebra_route_string(client->proto), length); zebra_route_string(client->proto), length);
s = client->ibuf; s = client->ibuf;
pid = stream_getl(s); STREAM_GETL(s, pid);
if (ptm_cb.ptm_sock == -1) { if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL; ptm_cb.t_timer = NULL;
@ -993,6 +997,7 @@ int zebra_ptm_bfd_client_register(struct zserv *client,
SET_FLAG(ptm_cb.client_flags[client->proto], SET_FLAG(ptm_cb.client_flags[client->proto],
ZEBRA_PTM_BFD_CLIENT_FLAG_REG); ZEBRA_PTM_BFD_CLIENT_FLAG_REG);
stream_failure:
return 0; return 0;
} }

View File

@ -3055,16 +3055,16 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
mac = NULL; mac = NULL;
n = NULL; n = NULL;
memset(&ip, 0, sizeof(ip)); memset(&ip, 0, sizeof(ip));
vni = (vni_t)stream_getl(s); STREAM_GETL(s, vni);
stream_get(&macaddr.octet, s, ETH_ALEN); STREAM_GET(&macaddr.octet, s, ETH_ALEN);
ipa_len = stream_getl(s); STREAM_GETL(s, ipa_len);
if (ipa_len) { if (ipa_len) {
ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
: IPADDR_V6; : IPADDR_V6;
stream_get(&ip.ip.addr, s, ipa_len); STREAM_GET(&ip.ip.addr, s, ipa_len);
} }
l += 4 + ETH_ALEN + 4 + ipa_len; l += 4 + ETH_ALEN + 4 + ipa_len;
vtep_ip.s_addr = stream_get_ipv4(s); STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
l += IPV4_MAX_BYTELEN; l += IPV4_MAX_BYTELEN;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
@ -3160,6 +3160,7 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
} }
} }
stream_failure:
return 0; return 0;
} }
@ -3188,7 +3189,11 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
struct interface *ifp = NULL; struct interface *ifp = NULL;
struct zebra_if *zif = NULL; struct zebra_if *zif = NULL;
assert(EVPN_ENABLED(zvrf)); if (!EVPN_ENABLED(zvrf)) {
zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
__PRETTY_FUNCTION__);
return -1;
}
s = client->ibuf; s = client->ibuf;
@ -3201,20 +3206,20 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
mac = NULL; mac = NULL;
n = NULL; n = NULL;
memset(&ip, 0, sizeof(ip)); memset(&ip, 0, sizeof(ip));
vni = (vni_t)stream_getl(s); STREAM_GETL(s, vni);
stream_get(&macaddr.octet, s, ETH_ALEN); STREAM_GET(&macaddr.octet, s, ETH_ALEN);
ipa_len = stream_getl(s); STREAM_GETL(s, ipa_len);
if (ipa_len) { if (ipa_len) {
ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
: IPADDR_V6; : IPADDR_V6;
stream_get(&ip.ip.addr, s, ipa_len); STREAM_GET(&ip.ip.addr, s, ipa_len);
} }
l += 4 + ETH_ALEN + 4 + ipa_len; l += 4 + ETH_ALEN + 4 + ipa_len;
vtep_ip.s_addr = stream_get_ipv4(s); STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
l += IPV4_MAX_BYTELEN; l += IPV4_MAX_BYTELEN;
/* Get 'sticky' flag. */ /* Get 'sticky' flag. */
sticky = stream_getc(s); STREAM_GETC(s, sticky);
l++; l++;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
@ -3367,6 +3372,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
} }
} }
stream_failure:
return 0; return 0;
} }
@ -3683,7 +3689,12 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
struct interface *ifp; struct interface *ifp;
struct zebra_if *zif; struct zebra_if *zif;
assert(is_evpn_enabled()); if (!is_evpn_enabled()) {
zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
__PRETTY_FUNCTION__);
return -1;
}
if (zvrf_id(zvrf) != VRF_DEFAULT) { if (zvrf_id(zvrf) != VRF_DEFAULT) {
zlog_err("Recv MACIP DEL for non-default VRF %u", zlog_err("Recv MACIP DEL for non-default VRF %u",
zvrf_id(zvrf)); zvrf_id(zvrf));
@ -3694,9 +3705,9 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
while (l < length) { while (l < length) {
/* Obtain each remote VTEP and process. */ /* Obtain each remote VTEP and process. */
vni = (vni_t)stream_getl(s); STREAM_GETL(s, vni);
l += 4; l += 4;
vtep_ip.s_addr = stream_get_ipv4(s); STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
l += IPV4_MAX_BYTELEN; l += IPV4_MAX_BYTELEN;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
@ -3744,6 +3755,7 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
zvni_vtep_del(zvni, zvtep); zvni_vtep_del(zvni, zvtep);
} }
stream_failure:
return 0; return 0;
} }
@ -3761,7 +3773,12 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
struct interface *ifp; struct interface *ifp;
struct zebra_if *zif; struct zebra_if *zif;
assert(is_evpn_enabled()); if (!is_evpn_enabled()) {
zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
__PRETTY_FUNCTION__);
return -1;
}
if (zvrf_id(zvrf) != VRF_DEFAULT) { if (zvrf_id(zvrf) != VRF_DEFAULT) {
zlog_err("Recv MACIP ADD for non-default VRF %u", zlog_err("Recv MACIP ADD for non-default VRF %u",
zvrf_id(zvrf)); zvrf_id(zvrf));
@ -3772,9 +3789,9 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
while (l < length) { while (l < length) {
/* Obtain each remote VTEP and process. */ /* Obtain each remote VTEP and process. */
vni = (vni_t)stream_getl(s); STREAM_GETL(s, vni);
l += 4; l += 4;
vtep_ip.s_addr = stream_get_ipv4(s); STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
l += IPV4_MAX_BYTELEN; l += IPV4_MAX_BYTELEN;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
@ -3820,6 +3837,7 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
zvni_vtep_install(zvni, &vtep_ip); zvni_vtep_install(zvni, &vtep_ip);
} }
stream_failure:
return 0; return 0;
} }
@ -4296,8 +4314,8 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
} }
s = client->ibuf; s = client->ibuf;
advertise = stream_getc(s); STREAM_GETC(s, advertise);
vni = stream_get3(s); STREAM_GET(&vni, s, 3);
if (!vni) { if (!vni) {
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
@ -4378,6 +4396,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
} }
} }
stream_failure:
return 0; return 0;
} }
@ -4401,7 +4420,7 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client,
} }
s = client->ibuf; s = client->ibuf;
advertise = stream_getc(s); STREAM_GETC(s, advertise);
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("EVPN VNI Adv %s, currently %s", zlog_debug("EVPN VNI Adv %s, currently %s",
@ -4432,6 +4451,7 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client,
hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf); hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
} }
stream_failure:
return 0; return 0;
} }

View File

@ -714,15 +714,25 @@ static int zserv_rnh_register(struct zserv *client, u_short length,
client->nh_reg_time = monotime(NULL); client->nh_reg_time = monotime(NULL);
while (l < length) { while (l < length) {
flags = stream_getc(s); STREAM_GETC(s, flags);
p.family = stream_getw(s); STREAM_GETW(s, p.family);
p.prefixlen = stream_getc(s); STREAM_GETC(s, p.prefixlen);
l += 4; l += 4;
if (p.family == AF_INET) { if (p.family == AF_INET) {
p.u.prefix4.s_addr = stream_get_ipv4(s); if (p.prefixlen > IPV4_MAX_BITLEN) {
zlog_warn("%s: Specified prefix length %d is too large for a v4 address",
__PRETTY_FUNCTION__, p.prefixlen);
return -1;
}
STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
l += IPV4_MAX_BYTELEN; l += IPV4_MAX_BYTELEN;
} else if (p.family == AF_INET6) { } else if (p.family == AF_INET6) {
stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); if (p.prefixlen > IPV6_MAX_BITLEN) {
zlog_warn("%s: Specified prefix length %d is to large for a v6 address",
__PRETTY_FUNCTION__, p.prefixlen);
return -1;
}
STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
l += IPV6_MAX_BYTELEN; l += IPV6_MAX_BYTELEN;
} else { } else {
zlog_err( zlog_err(
@ -751,6 +761,8 @@ static int zserv_rnh_register(struct zserv *client, u_short length,
/* Anything not AF_INET/INET6 has been filtered out above */ /* Anything not AF_INET/INET6 has been filtered out above */
zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p); zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p);
} }
stream_failure:
return 0; return 0;
} }
@ -770,16 +782,27 @@ static int zserv_rnh_unregister(struct zserv *client, u_short length,
s = client->ibuf; s = client->ibuf;
while (l < length) { while (l < length) {
(void)stream_getc( u_char noval;
s); // Connected or not. Not used in this function
p.family = stream_getw(s); STREAM_GETC(s, noval);
p.prefixlen = stream_getc(s); STREAM_GETW(s, p.family);
STREAM_GETC(s, p.prefixlen);
l += 4; l += 4;
if (p.family == AF_INET) { if (p.family == AF_INET) {
p.u.prefix4.s_addr = stream_get_ipv4(s); if (p.prefixlen > IPV4_MAX_BITLEN) {
zlog_warn("%s: Specified prefix length %d is to large for a v4 address",
__PRETTY_FUNCTION__, p.prefixlen);
return -1;
}
STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
l += IPV4_MAX_BYTELEN; l += IPV4_MAX_BYTELEN;
} else if (p.family == AF_INET6) { } else if (p.family == AF_INET6) {
stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); if (p.prefixlen > IPV6_MAX_BITLEN) {
zlog_warn("%s: Specified prefix length %d is to large for a v6 address",
__PRETTY_FUNCTION__, p.prefixlen);
return -1;
}
STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
l += IPV6_MAX_BYTELEN; l += IPV6_MAX_BYTELEN;
} else { } else {
zlog_err( zlog_err(
@ -793,6 +816,7 @@ static int zserv_rnh_unregister(struct zserv *client, u_short length,
zebra_remove_rnh_client(rnh, client, type); zebra_remove_rnh_client(rnh, client, type);
} }
} }
stream_failure:
return 0; return 0;
} }
@ -825,27 +849,34 @@ static int zserv_fec_register(struct zserv *client, u_short length)
} }
while (l < length) { while (l < length) {
flags = stream_getw(s); STREAM_GETW(s, flags);
memset(&p, 0, sizeof(p)); memset(&p, 0, sizeof(p));
p.family = stream_getw(s); STREAM_GETW(s, p.family);
if (p.family != AF_INET && p.family != AF_INET6) { if (p.family != AF_INET && p.family != AF_INET6) {
zlog_err( zlog_err(
"fec_register: Received unknown family type %d\n", "fec_register: Received unknown family type %d\n",
p.family); p.family);
return -1; return -1;
} }
p.prefixlen = stream_getc(s); STREAM_GETC(s, p.prefixlen);
if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN) ||
(p.family == AF_INET6 && p.prefixlen > IPV6_MAX_BITLEN)) {
zlog_warn("%s: Specified prefix length: %d is to long for %d",
__PRETTY_FUNCTION__, p.prefixlen, p.family);
return -1;
}
l += 5; l += 5;
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
l += PSIZE(p.prefixlen); l += PSIZE(p.prefixlen);
if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) { if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) {
label_index = stream_getl(s); STREAM_GETL(s, label_index);
l += 4; l += 4;
} else } else
label_index = MPLS_INVALID_LABEL_INDEX; label_index = MPLS_INVALID_LABEL_INDEX;
zebra_mpls_fec_register(zvrf, &p, label_index, client); zebra_mpls_fec_register(zvrf, &p, label_index, client);
} }
stream_failure:
return 0; return 0;
} }
@ -856,7 +887,7 @@ static int zserv_fec_unregister(struct zserv *client, u_short length)
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
u_short l = 0; u_short l = 0;
struct prefix p; struct prefix p;
// u_int16_t flags; uint16_t flags;
s = client->ibuf; s = client->ibuf;
zvrf = vrf_info_lookup(VRF_DEFAULT); zvrf = vrf_info_lookup(VRF_DEFAULT);
@ -875,23 +906,29 @@ static int zserv_fec_unregister(struct zserv *client, u_short length)
} }
while (l < length) { while (l < length) {
// flags = stream_getw(s); STREAM_GETW(s, flags);
(void)stream_getw(s);
memset(&p, 0, sizeof(p)); memset(&p, 0, sizeof(p));
p.family = stream_getw(s); STREAM_GETW(s, p.family);
if (p.family != AF_INET && p.family != AF_INET6) { if (p.family != AF_INET && p.family != AF_INET6) {
zlog_err( zlog_err(
"fec_unregister: Received unknown family type %d\n", "fec_unregister: Received unknown family type %d\n",
p.family); p.family);
return -1; return -1;
} }
p.prefixlen = stream_getc(s); STREAM_GETC(s, p.prefixlen);
if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN) ||
(p.family == AF_INET6 && p.prefixlen > IPV6_MAX_BITLEN)) {
zlog_warn("%s: Received prefix length %d which is greater than %d can support",
__PRETTY_FUNCTION__, p.prefixlen, p.family);
return -1;
}
l += 5; l += 5;
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
l += PSIZE(p.prefixlen); l += PSIZE(p.prefixlen);
zebra_mpls_fec_unregister(zvrf, &p, client); zebra_mpls_fec_unregister(zvrf, &p, client);
} }
stream_failure:
return 0; return 0;
} }
@ -1073,7 +1110,7 @@ static int zread_route_add(struct zserv *client, u_short length,
switch (api_nh->type) { switch (api_nh->type) {
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
route_entry_nexthop_ifindex_add( nexthop = route_entry_nexthop_ifindex_add(
re, api_nh->ifindex); re, api_nh->ifindex);
break; break;
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
@ -1095,11 +1132,18 @@ static int zread_route_add(struct zserv *client, u_short length,
api_nh->ifindex); api_nh->ifindex);
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
route_entry_nexthop_blackhole_add( nexthop = route_entry_nexthop_blackhole_add(
re, api_nh->bh_type); re, api_nh->bh_type);
break; break;
} }
if (!nexthop) {
zlog_warn("%s: Nexthops Specified: %d but we failed to properly create one",
__PRETTY_FUNCTION__, api.nexthop_num);
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
}
/* MPLS labels for BGP-LU or Segment Routing */ /* MPLS labels for BGP-LU or Segment Routing */
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL) if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)
&& api_nh->type != NEXTHOP_TYPE_IFINDEX && api_nh->type != NEXTHOP_TYPE_IFINDEX
@ -1125,6 +1169,13 @@ static int zread_route_add(struct zserv *client, u_short length,
re->mtu = api.mtu; re->mtu = api.mtu;
afi = family2afi(api.prefix.family); afi = family2afi(api.prefix.family);
if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
zlog_warn("%s: Received SRC Prefix but afi is not v6",
__PRETTY_FUNCTION__);
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
}
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
src_p = &api.src_prefix; src_p = &api.src_prefix;
@ -1162,6 +1213,11 @@ static int zread_route_del(struct zserv *client, u_short length,
return -1; return -1;
afi = family2afi(api.prefix.family); afi = family2afi(api.prefix.family);
if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
zlog_warn("%s: Received a src prefix while afi is not v6",
__PRETTY_FUNCTION__);
return -1;
}
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
src_p = &api.src_prefix; src_p = &api.src_prefix;
@ -1213,25 +1269,37 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
/* Type, flags, message. */ /* Type, flags, message. */
re->type = stream_getc(s); STREAM_GETC(s, re->type);
re->instance = stream_getw(s); if (re->type > ZEBRA_ROUTE_MAX) {
re->flags = stream_getl(s); zlog_warn("%s: Specified route type %d is not a legal value\n",
message = stream_getc(s); __PRETTY_FUNCTION__, re->type);
safi = stream_getw(s); XFREE(MTYPE_RE, re);
return -1;
}
STREAM_GETW(s, re->instance);
STREAM_GETL(s, re->flags);
STREAM_GETC(s, message);
STREAM_GETW(s, safi);
re->uptime = time(NULL); re->uptime = time(NULL);
/* IPv4 prefix. */ /* IPv4 prefix. */
memset(&p, 0, sizeof(struct prefix_ipv4)); memset(&p, 0, sizeof(struct prefix_ipv4));
p.family = AF_INET; p.family = AF_INET;
p.prefixlen = stream_getc(s); STREAM_GETC(s, p.prefixlen);
stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); if (p.prefixlen > IPV4_MAX_BITLEN) {
zlog_warn("%s: Specified prefix length %d is greater than what v4 can be",
__PRETTY_FUNCTION__, p.prefixlen);
XFREE(MTYPE_RE, re);
return -1;
}
STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
/* VRF ID */ /* VRF ID */
re->vrf_id = zvrf_id(zvrf); re->vrf_id = zvrf_id(zvrf);
/* Nexthop parse. */ /* Nexthop parse. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) {
nexthop_num = stream_getc(s); STREAM_GETC(s, nexthop_num);
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
nexthop_num); nexthop_num);
@ -1239,57 +1307,69 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
label_type = lsp_type_from_re_type(client->proto); label_type = lsp_type_from_re_type(client->proto);
for (i = 0; i < nexthop_num; i++) { for (i = 0; i < nexthop_num; i++) {
nexthop_type = stream_getc(s); STREAM_GETC(s, nexthop_type);
switch (nexthop_type) { switch (nexthop_type) {
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
ifindex = stream_getl(s); STREAM_GETL(s, ifindex);
route_entry_nexthop_ifindex_add(re, ifindex); route_entry_nexthop_ifindex_add(re, ifindex);
break; break;
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
nhop_addr.s_addr = stream_get_ipv4(s); STREAM_GET(&nhop_addr.s_addr, s,
IPV4_MAX_BYTELEN);
nexthop = route_entry_nexthop_ipv4_add( nexthop = route_entry_nexthop_ipv4_add(
re, &nhop_addr, NULL); re, &nhop_addr, NULL);
/* For labeled-unicast, each nexthop is followed /* For labeled-unicast, each nexthop is followed
* by label. */ * by label. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) { if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) {
label = (mpls_label_t)stream_getl(s); STREAM_GETL(s, label);
nexthop_add_labels(nexthop, label_type, nexthop_add_labels(nexthop, label_type,
1, &label); 1, &label);
} }
break; break;
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
nhop_addr.s_addr = stream_get_ipv4(s); STREAM_GET(&nhop_addr.s_addr, s,
ifindex = stream_getl(s); IPV4_MAX_BYTELEN);
STREAM_GETL(s, ifindex);
route_entry_nexthop_ipv4_ifindex_add( route_entry_nexthop_ipv4_ifindex_add(
re, &nhop_addr, NULL, ifindex); re, &nhop_addr, NULL, ifindex);
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
stream_forward_getp(s, IPV6_MAX_BYTELEN); zlog_warn("%s: Please use ZEBRA_ROUTE_ADD if you want to pass v6 nexthops",
__PRETTY_FUNCTION__);
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
route_entry_nexthop_blackhole_add(re, bh_type); route_entry_nexthop_blackhole_add(re, bh_type);
break; break;
default:
zlog_warn("%s: Specified nexthop type: %d does not exist",
__PRETTY_FUNCTION__, nexthop_type);
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
} }
} }
} }
/* Distance. */ /* Distance. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
re->distance = stream_getc(s); STREAM_GETC(s, re->distance);
/* Metric. */ /* Metric. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
re->metric = stream_getl(s); STREAM_GETL(s, re->metric);
/* Tag */ /* Tag */
if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
re->tag = stream_getl(s); STREAM_GETL(s, re->tag);
else else
re->tag = 0; re->tag = 0;
if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
re->mtu = stream_getl(s); STREAM_GETL(s, re->mtu);
else else
re->mtu = 0; re->mtu = 0;
@ -1303,7 +1383,13 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
client->v4_route_add_cnt++; client->v4_route_add_cnt++;
else if (ret < 0) else if (ret < 0)
client->v4_route_upd8_cnt++; client->v4_route_upd8_cnt++;
return 0; return 0;
stream_failure:
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
} }
/* Zebra server IPv4 prefix delete function. */ /* Zebra server IPv4 prefix delete function. */
@ -1318,23 +1404,30 @@ static int zread_ipv4_delete(struct zserv *client, u_short length,
s = client->ibuf; s = client->ibuf;
/* Type, flags, message. */ /* Type, flags, message. */
api.type = stream_getc(s); STREAM_GETC(s, api.type);
api.instance = stream_getw(s); STREAM_GETW(s, api.instance);
api.flags = stream_getl(s); STREAM_GETL(s, api.flags);
api.message = stream_getc(s); STREAM_GETC(s, api.message);
api.safi = stream_getw(s); STREAM_GETW(s, api.safi);
/* IPv4 prefix. */ /* IPv4 prefix. */
memset(&p, 0, sizeof(struct prefix)); memset(&p, 0, sizeof(struct prefix));
p.family = AF_INET; p.family = AF_INET;
p.prefixlen = stream_getc(s); STREAM_GETC(s, p.prefixlen);
stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); if (p.prefixlen > IPV4_MAX_BITLEN) {
zlog_warn("%s: Passed in prefixlen %d is impossible",
__PRETTY_FUNCTION__, p.prefixlen);
return -1;
}
STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
table_id = zvrf->table_id; table_id = zvrf->table_id;
rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance, rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &p, NULL, NULL, table_id, 0, false); api.flags, &p, NULL, NULL, table_id, 0, false);
client->v4_route_del_cnt++; client->v4_route_del_cnt++;
stream_failure:
return 0; return 0;
} }
@ -1345,9 +1438,12 @@ static int zread_ipv4_nexthop_lookup_mrib(struct zserv *client, u_short length,
struct in_addr addr; struct in_addr addr;
struct route_entry *re; struct route_entry *re;
addr.s_addr = stream_get_ipv4(client->ibuf); STREAM_GET(&addr.s_addr, client->ibuf, IPV4_MAX_BYTELEN);
re = rib_match_ipv4_multicast(zvrf_id(zvrf), addr, NULL); re = rib_match_ipv4_multicast(zvrf_id(zvrf), addr, NULL);
return zsend_ipv4_nexthop_lookup_mrib(client, addr, re, zvrf); return zsend_ipv4_nexthop_lookup_mrib(client, addr, re, zvrf);
stream_failure:
return -1;
} }
/* Zebra server IPv6 prefix add function. */ /* Zebra server IPv6 prefix add function. */
@ -1382,18 +1478,30 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
/* Type, flags, message. */ /* Type, flags, message. */
re->type = stream_getc(s); STREAM_GETC(s, re->type);
re->instance = stream_getw(s); if (re->type > ZEBRA_ROUTE_MAX) {
re->flags = stream_getl(s); zlog_warn("%s: Specified route type: %d is not a legal value\n",
message = stream_getc(s); __PRETTY_FUNCTION__, re->type);
safi = stream_getw(s); XFREE(MTYPE_RE, re);
return -1;
}
STREAM_GETW(s, re->instance);
STREAM_GETL(s, re->flags);
STREAM_GETC(s, message);
STREAM_GETW(s, safi);
re->uptime = time(NULL); re->uptime = time(NULL);
/* IPv4 prefix. */ /* IPv4 prefix. */
memset(&p, 0, sizeof(struct prefix_ipv4)); memset(&p, 0, sizeof(struct prefix_ipv4));
p.family = AF_INET; p.family = AF_INET;
p.prefixlen = stream_getc(s); STREAM_GETC(s, p.prefixlen);
stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); if (p.prefixlen > IPV4_MAX_BITLEN) {
zlog_warn("%s: Prefix Length %d is greater than what a v4 address can use",
__PRETTY_FUNCTION__, p.prefixlen);
XFREE(MTYPE_RE, re);
return -1;
}
STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
/* VRF ID */ /* VRF ID */
re->vrf_id = zvrf_id(zvrf); re->vrf_id = zvrf_id(zvrf);
@ -1407,7 +1515,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
unsigned int if_count = 0; unsigned int if_count = 0;
unsigned int max_nh_if = 0; unsigned int max_nh_if = 0;
nexthop_num = stream_getc(s); STREAM_GETC(s, nexthop_num);
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
nexthop_num); nexthop_num);
@ -1415,18 +1523,17 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
label_type = lsp_type_from_re_type(client->proto); label_type = lsp_type_from_re_type(client->proto);
for (i = 0; i < nexthop_num; i++) { for (i = 0; i < nexthop_num; i++) {
nexthop_type = stream_getc(s); STREAM_GETC(s, nexthop_type);
switch (nexthop_type) { switch (nexthop_type) {
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
stream_get(&nhop_addr, s, 16); STREAM_GET(&nhop_addr, s, 16);
if (nh_count < MULTIPATH_NUM) { if (nh_count < MULTIPATH_NUM) {
/* For labeled-unicast, each nexthop is /* For labeled-unicast, each nexthop is
* followed by label. */ * followed by label. */
if (CHECK_FLAG(message, if (CHECK_FLAG(message,
ZAPI_MESSAGE_LABEL)) { ZAPI_MESSAGE_LABEL)) {
label = (mpls_label_t) STREAM_GETL(s, label);
stream_getl(s);
labels[nh_count] = label; labels[nh_count] = label;
} }
nexthops[nh_count] = nhop_addr; nexthops[nh_count] = nhop_addr;
@ -1435,12 +1542,18 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
if (if_count < multipath_num) { if (if_count < multipath_num) {
ifindices[if_count++] = stream_getl(s); STREAM_GETL(s, ifindices[if_count++]);
} }
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
route_entry_nexthop_blackhole_add(re, bh_type); route_entry_nexthop_blackhole_add(re, bh_type);
break; break;
default:
zlog_warn("%s: Please use ZEBRA_ROUTE_ADD if you want to pass non v6 nexthops",
__PRETTY_FUNCTION__);
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
} }
} }
@ -1470,20 +1583,20 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
/* Distance. */ /* Distance. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
re->distance = stream_getc(s); STREAM_GETC(s, re->distance);
/* Metric. */ /* Metric. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
re->metric = stream_getl(s); STREAM_GETL(s, re->metric);
/* Tag */ /* Tag */
if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
re->tag = stream_getl(s); STREAM_GETL(s, re->tag);
else else
re->tag = 0; re->tag = 0;
if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
re->mtu = stream_getl(s); STREAM_GETL(s, re->mtu);
else else
re->mtu = 0; re->mtu = 0;
@ -1498,6 +1611,11 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
client->v4_route_upd8_cnt++; client->v4_route_upd8_cnt++;
return 0; return 0;
stream_failure:
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
} }
static int zread_ipv6_add(struct zserv *client, u_short length, static int zread_ipv6_add(struct zserv *client, u_short length,
@ -1532,24 +1650,42 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
/* Type, flags, message. */ /* Type, flags, message. */
re->type = stream_getc(s); STREAM_GETC(s, re->type);
re->instance = stream_getw(s); if (re->type > ZEBRA_ROUTE_MAX) {
re->flags = stream_getl(s); zlog_warn("%s: Specified route type: %d is not a legal value\n",
message = stream_getc(s); __PRETTY_FUNCTION__, re->type);
safi = stream_getw(s); XFREE(MTYPE_RE, re);
return -1;
}
STREAM_GETW(s, re->instance);
STREAM_GETL(s, re->flags);
STREAM_GETC(s, message);
STREAM_GETW(s, safi);
re->uptime = time(NULL); re->uptime = time(NULL);
/* IPv6 prefix. */ /* IPv6 prefix. */
memset(&p, 0, sizeof(struct prefix_ipv6)); memset(&p, 0, sizeof(p));
p.family = AF_INET6; p.family = AF_INET6;
p.prefixlen = stream_getc(s); STREAM_GETC(s, p.prefixlen);
stream_get(&p.u.prefix6, s, PSIZE(p.prefixlen)); if (p.prefixlen > IPV6_MAX_BITLEN) {
zlog_warn("%s: Specified prefix length %d is to large for v6 prefix",
__PRETTY_FUNCTION__, p.prefixlen);
XFREE(MTYPE_RE, re);
return -1;
}
STREAM_GET(&p.u.prefix6, s, PSIZE(p.prefixlen));
if (CHECK_FLAG(message, ZAPI_MESSAGE_SRCPFX)) { if (CHECK_FLAG(message, ZAPI_MESSAGE_SRCPFX)) {
memset(&src_p, 0, sizeof(struct prefix_ipv6)); memset(&src_p, 0, sizeof(src_p));
src_p.family = AF_INET6; src_p.family = AF_INET6;
src_p.prefixlen = stream_getc(s); STREAM_GETC(s, src_p.prefixlen);
stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); if (src_p.prefixlen > IPV6_MAX_BITLEN) {
zlog_warn("%s: Specified src prefix length %d is to large for v6 prefix",
__PRETTY_FUNCTION__, src_p.prefixlen);
XFREE(MTYPE_RE, re);
return -1;
}
STREAM_GET(&src_p.prefix, s, PSIZE(src_p.prefixlen));
src_pp = &src_p; src_pp = &src_p;
} else } else
src_pp = NULL; src_pp = NULL;
@ -1563,7 +1699,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
unsigned int if_count = 0; unsigned int if_count = 0;
unsigned int max_nh_if = 0; unsigned int max_nh_if = 0;
nexthop_num = stream_getc(s); STREAM_GETC(s, nexthop_num);
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
nexthop_num); nexthop_num);
@ -1571,37 +1707,42 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
label_type = lsp_type_from_re_type(client->proto); label_type = lsp_type_from_re_type(client->proto);
for (i = 0; i < nexthop_num; i++) { for (i = 0; i < nexthop_num; i++) {
nexthop_type = stream_getc(s); STREAM_GETC(s, nexthop_type);
switch (nexthop_type) { switch (nexthop_type) {
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
stream_get(&nhop_addr, s, 16); STREAM_GET(&nhop_addr, s, 16);
if (nh_count < MULTIPATH_NUM) { if (nh_count < MULTIPATH_NUM) {
/* For labeled-unicast, each nexthop is /* For labeled-unicast, each nexthop is
* followed by label. */ * followed by label. */
if (CHECK_FLAG(message, if (CHECK_FLAG(message,
ZAPI_MESSAGE_LABEL)) { ZAPI_MESSAGE_LABEL)) {
label = (mpls_label_t) STREAM_GETL(s, label);
stream_getl(s);
labels[nh_count] = label; labels[nh_count] = label;
} }
nexthops[nh_count++] = nhop_addr; nexthops[nh_count++] = nhop_addr;
} }
break; break;
case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX:
stream_get(&nhop_addr, s, 16); STREAM_GET(&nhop_addr, s, 16);
ifindex = stream_getl(s); STREAM_GETL(s, ifindex);
route_entry_nexthop_ipv6_ifindex_add( route_entry_nexthop_ipv6_ifindex_add(
re, &nhop_addr, ifindex); re, &nhop_addr, ifindex);
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
if (if_count < multipath_num) { if (if_count < multipath_num) {
ifindices[if_count++] = stream_getl(s); STREAM_GETL(s, ifindices[if_count++]);
} }
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
route_entry_nexthop_blackhole_add(re, bh_type); route_entry_nexthop_blackhole_add(re, bh_type);
break; break;
default:
zlog_warn("%s: Please use ZEBRA_ROUTE_ADD if you want to pass non v6 nexthops",
__PRETTY_FUNCTION__);
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
} }
} }
@ -1630,20 +1771,20 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
/* Distance. */ /* Distance. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
re->distance = stream_getc(s); STREAM_GETC(s, re->distance);
/* Metric. */ /* Metric. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
re->metric = stream_getl(s); STREAM_GETL(s, re->metric);
/* Tag */ /* Tag */
if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
re->tag = stream_getl(s); STREAM_GETL(s, re->tag);
else else
re->tag = 0; re->tag = 0;
if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
re->mtu = stream_getl(s); STREAM_GETL(s, re->mtu);
else else
re->mtu = 0; re->mtu = 0;
@ -1659,6 +1800,12 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
client->v6_route_upd8_cnt++; client->v6_route_upd8_cnt++;
return 0; return 0;
stream_failure:
nexthops_free(re->nexthop);
XFREE(MTYPE_RE, re);
return -1;
} }
/* Zebra server IPv6 prefix delete function. */ /* Zebra server IPv6 prefix delete function. */
@ -1673,23 +1820,23 @@ static int zread_ipv6_delete(struct zserv *client, u_short length,
s = client->ibuf; s = client->ibuf;
/* Type, flags, message. */ /* Type, flags, message. */
api.type = stream_getc(s); STREAM_GETC(s, api.type);
api.instance = stream_getw(s); STREAM_GETW(s, api.instance);
api.flags = stream_getl(s); STREAM_GETL(s, api.flags);
api.message = stream_getc(s); STREAM_GETC(s, api.message);
api.safi = stream_getw(s); STREAM_GETW(s, api.safi);
/* IPv4 prefix. */ /* IPv4 prefix. */
memset(&p, 0, sizeof(struct prefix)); memset(&p, 0, sizeof(struct prefix));
p.family = AF_INET6; p.family = AF_INET6;
p.prefixlen = stream_getc(s); STREAM_GETC(s, p.prefixlen);
stream_get(&p.u.prefix6, s, PSIZE(p.prefixlen)); STREAM_GET(&p.u.prefix6, s, PSIZE(p.prefixlen));
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
memset(&src_p, 0, sizeof(struct prefix_ipv6)); memset(&src_p, 0, sizeof(struct prefix_ipv6));
src_p.family = AF_INET6; src_p.family = AF_INET6;
src_p.prefixlen = stream_getc(s); STREAM_GETC(s, src_p.prefixlen);
stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); STREAM_GET(&src_p.prefix, s, PSIZE(src_p.prefixlen));
src_pp = &src_p; src_pp = &src_p;
} else } else
src_pp = NULL; src_pp = NULL;
@ -1698,6 +1845,8 @@ static int zread_ipv6_delete(struct zserv *client, u_short length,
api.flags, &p, src_pp, NULL, client->rtm_table, 0, false); api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
client->v6_route_del_cnt++; client->v6_route_del_cnt++;
stream_failure:
return 0; return 0;
} }
@ -1730,8 +1879,8 @@ static void zread_hello(struct zserv *client)
u_char proto; u_char proto;
u_short instance; u_short instance;
proto = stream_getc(client->ibuf); STREAM_GETC(client->ibuf, proto);
instance = stream_getw(client->ibuf); STREAM_GETW(client->ibuf, instance);
/* accept only dynamic routing protocols */ /* accept only dynamic routing protocols */
if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) { if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) {
@ -1744,6 +1893,9 @@ static void zread_hello(struct zserv *client)
client->proto = proto; client->proto = proto;
client->instance = instance; client->instance = instance;
} }
stream_failure:
return;
} }
/* Unregister all information in a VRF. */ /* Unregister all information in a VRF. */
@ -1779,26 +1931,40 @@ static void zread_mpls_labels(int command, struct zserv *client, u_short length,
s = client->ibuf; s = client->ibuf;
/* Get data. */ /* Get data. */
type = stream_getc(s); STREAM_GETC(s, type);
prefix.family = stream_getl(s); STREAM_GETL(s, prefix.family);
switch (prefix.family) { switch (prefix.family) {
case AF_INET: case AF_INET:
prefix.u.prefix4.s_addr = stream_get_ipv4(s); STREAM_GET(&prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
prefix.prefixlen = stream_getc(s); STREAM_GETC(s, prefix.prefixlen);
gate.ipv4.s_addr = stream_get_ipv4(s); if (prefix.prefixlen > IPV4_MAX_BITLEN) {
zlog_warn("%s: Specified prefix length %d is greater than a v4 address can support",
__PRETTY_FUNCTION__,
prefix.prefixlen);
return;
}
STREAM_GET(&gate.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
break; break;
case AF_INET6: case AF_INET6:
stream_get(&prefix.u.prefix6, s, 16); STREAM_GET(&prefix.u.prefix6, s, 16);
prefix.prefixlen = stream_getc(s); STREAM_GETC(s, prefix.prefixlen);
stream_get(&gate.ipv6, s, 16); if (prefix.prefixlen > IPV6_MAX_BITLEN) {
zlog_warn("%s: Specified prefix length %d is greater than a v6 address can support",
__PRETTY_FUNCTION__,
prefix.prefixlen);
return;
}
STREAM_GET(&gate.ipv6, s, 16);
break; break;
default: default:
zlog_warn("%s: Specified AF %d is not supported for this call",
__PRETTY_FUNCTION__, prefix.family);
return; return;
} }
ifindex = stream_getl(s); STREAM_GETL(s, ifindex);
distance = stream_getc(s); STREAM_GETC(s, distance);
in_label = stream_getl(s); STREAM_GETL(s, in_label);
out_label = stream_getl(s); STREAM_GETL(s, out_label);
switch (prefix.family) { switch (prefix.family) {
case AF_INET: case AF_INET:
@ -1830,6 +1996,8 @@ static void zread_mpls_labels(int command, struct zserv *client, u_short length,
mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, ifindex, mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, ifindex,
distance, out_label); distance, out_label);
} }
stream_failure:
return;
} }
/* Send response to a label manager connect request to client */ /* Send response to a label manager connect request to client */
static int zsend_label_manager_connect_response(struct zserv *client, static int zsend_label_manager_connect_response(struct zserv *client,
@ -1862,8 +2030,8 @@ static void zread_label_manager_connect(struct zserv *client, vrf_id_t vrf_id)
s = client->ibuf; s = client->ibuf;
/* Get data. */ /* Get data. */
proto = stream_getc(s); STREAM_GETC(s, proto);
instance = stream_getw(s); STREAM_GETW(s, instance);
/* accept only dynamic routing protocols */ /* accept only dynamic routing protocols */
if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) { if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
@ -1888,6 +2056,9 @@ static void zread_label_manager_connect(struct zserv *client, vrf_id_t vrf_id)
client->sock, zebra_route_string(proto), instance); client->sock, zebra_route_string(proto), instance);
/* send response back */ /* send response back */
zsend_label_manager_connect_response(client, vrf_id, 0); zsend_label_manager_connect_response(client, vrf_id, 0);
stream_failure:
return;
} }
/* Send response to a get label chunk request to client */ /* Send response to a get label chunk request to client */
static int zsend_assign_label_chunk_response(struct zserv *client, static int zsend_assign_label_chunk_response(struct zserv *client,
@ -1926,8 +2097,8 @@ static void zread_get_label_chunk(struct zserv *client, vrf_id_t vrf_id)
s = client->ibuf; s = client->ibuf;
/* Get data. */ /* Get data. */
keep = stream_getc(s); STREAM_GETC(s, keep);
size = stream_getl(s); STREAM_GETL(s, size);
lmc = assign_label_chunk(client->proto, client->instance, keep, size); lmc = assign_label_chunk(client->proto, client->instance, keep, size);
if (!lmc) if (!lmc)
@ -1938,6 +2109,9 @@ static void zread_get_label_chunk(struct zserv *client, vrf_id_t vrf_id)
lmc->end, keep); lmc->end, keep);
/* send response back */ /* send response back */
zsend_assign_label_chunk_response(client, vrf_id, lmc); zsend_assign_label_chunk_response(client, vrf_id, lmc);
stream_failure:
return;
} }
static void zread_release_label_chunk(struct zserv *client) static void zread_release_label_chunk(struct zserv *client)
@ -1949,10 +2123,13 @@ static void zread_release_label_chunk(struct zserv *client)
s = client->ibuf; s = client->ibuf;
/* Get data. */ /* Get data. */
start = stream_getl(s); STREAM_GETL(s, start);
end = stream_getl(s); STREAM_GETL(s, end);
release_label_chunk(client->proto, client->instance, start, end); release_label_chunk(client->proto, client->instance, start, end);
stream_failure:
return;
} }
static void zread_label_manager_request(int cmd, struct zserv *client, static void zread_label_manager_request(int cmd, struct zserv *client,
struct zebra_vrf *zvrf) struct zebra_vrf *zvrf)
@ -2006,24 +2183,24 @@ static int zread_pseudowire(int command, struct zserv *client, u_short length,
s = client->ibuf; s = client->ibuf;
/* Get data. */ /* Get data. */
stream_get(ifname, s, IF_NAMESIZE); STREAM_GET(ifname, s, IF_NAMESIZE);
ifindex = stream_getl(s); STREAM_GETL(s, ifindex);
type = stream_getl(s); STREAM_GETL(s, type);
af = stream_getl(s); STREAM_GETL(s, af);
switch (af) { switch (af) {
case AF_INET: case AF_INET:
nexthop.ipv4.s_addr = stream_get_ipv4(s); STREAM_GET(&nexthop.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
break; break;
case AF_INET6: case AF_INET6:
stream_get(&nexthop.ipv6, s, 16); STREAM_GET(&nexthop.ipv6, s, 16);
break; break;
default: default:
return -1; return -1;
} }
local_label = stream_getl(s); STREAM_GETL(s, local_label);
remote_label = stream_getl(s); STREAM_GETL(s, remote_label);
flags = stream_getc(s); STREAM_GETC(s, flags);
stream_get(&data, s, sizeof(data)); STREAM_GET(&data, s, sizeof(data));
protocol = client->proto; protocol = client->proto;
pw = zebra_pw_find(zvrf, ifname); pw = zebra_pw_find(zvrf, ifname);
@ -2069,6 +2246,7 @@ static int zread_pseudowire(int command, struct zserv *client, u_short length,
break; break;
} }
stream_failure:
return 0; return 0;
} }
@ -2213,12 +2391,12 @@ static int zread_interface_set_master(struct zserv *client,
int ifindex; int ifindex;
vrf_id_t vrf_id; vrf_id_t vrf_id;
vrf_id = stream_getw(s); STREAM_GETW(s, vrf_id);
ifindex = stream_getl(s); STREAM_GETL(s, ifindex);
master = if_lookup_by_index(ifindex, vrf_id); master = if_lookup_by_index(ifindex, vrf_id);
vrf_id = stream_getw(s); STREAM_GETW(s, vrf_id);
ifindex = stream_getl(s); STREAM_GETL(s, ifindex);
slave = if_lookup_by_index(ifindex, vrf_id); slave = if_lookup_by_index(ifindex, vrf_id);
if (!master || !slave) if (!master || !slave)
@ -2226,6 +2404,7 @@ static int zread_interface_set_master(struct zserv *client,
kernel_interface_set_master(master, slave); kernel_interface_set_master(master, slave);
stream_failure:
return 1; return 1;
} }
@ -2427,11 +2606,11 @@ static int zebra_client_read(struct thread *thread)
stream_set_getp(client->ibuf, 0); stream_set_getp(client->ibuf, 0);
/* Fetch header values */ /* Fetch header values */
length = stream_getw(client->ibuf); STREAM_GETW(client->ibuf, length);
marker = stream_getc(client->ibuf); STREAM_GETC(client->ibuf, marker);
version = stream_getc(client->ibuf); STREAM_GETC(client->ibuf, version);
vrf_id = stream_getw(client->ibuf); STREAM_GETW(client->ibuf, vrf_id);
command = stream_getw(client->ibuf); STREAM_GETW(client->ibuf, command);
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
zlog_err( zlog_err(
@ -2509,6 +2688,7 @@ static int zebra_client_read(struct thread *thread)
stream_reset(client->ibuf); stream_reset(client->ibuf);
} }
stream_failure:
zclient_read_out: zclient_read_out:
stream_reset(client->ibuf); stream_reset(client->ibuf);
zebra_event(ZEBRA_READ, sock, client); zebra_event(ZEBRA_READ, sock, client);