summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c3
-rw-r--r--bgpd/bgp_label.c3
-rw-r--r--bgpd/bgp_mplsvpn.c3
-rw-r--r--bgpd/bgp_route.c2
-rw-r--r--zebra/zapi_msg.c15
-rw-r--r--zebra/zebra_ptm.c39
-rw-r--r--zebra/zebra_vxlan.c99
7 files changed, 98 insertions, 66 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index b8798a7ced..79a8fae530 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -5100,7 +5100,8 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
if (pnt + BGP_ADDPATH_ID_LEN > lim)
return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
- addpath_id = ntohl(*((uint32_t *)pnt));
+ memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
+ addpath_id = ntohl(addpath_id);
pnt += BGP_ADDPATH_ID_LEN;
}
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index 489ac6ea9f..ff1ab1a37d 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -368,7 +368,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
if (pnt + BGP_ADDPATH_ID_LEN > lim)
return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
- addpath_id = ntohl(*((uint32_t *)pnt));
+ memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
+ addpath_id = ntohl(addpath_id);
pnt += BGP_ADDPATH_ID_LEN;
}
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 59ed433e58..86c04b71f0 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -142,7 +142,8 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
if (pnt + BGP_ADDPATH_ID_LEN > lim)
return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
- addpath_id = ntohl(*((uint32_t *)pnt));
+ memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
+ addpath_id = ntohl(addpath_id);
pnt += BGP_ADDPATH_ID_LEN;
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index b216f85c40..5f4486b800 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4515,7 +4515,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
if (pnt + BGP_ADDPATH_ID_LEN >= lim)
return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
- memcpy(&addpath_id, pnt, 4);
+ memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
addpath_id = ntohl(addpath_id);
pnt += BGP_ADDPATH_ID_LEN;
}
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index df41220c5d..5a63c1e4f6 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -2463,6 +2463,13 @@ static inline void zread_ipset_entry(ZAPI_HANDLER_ARGS)
/* calculate backpointer */
zpi.backpointer =
zebra_pbr_lookup_ipset_pername(ipset.ipset_name);
+
+ if (!zpi.backpointer) {
+ zlog_warn("ipset name specified: %s does not exist",
+ ipset.ipset_name);
+ goto stream_failure;
+ }
+
if (hdr->command == ZEBRA_IPSET_ENTRY_ADD)
zebra_pbr_add_ipset_entry(&zpi);
else
@@ -2615,6 +2622,14 @@ void zserv_handle_commands(struct zserv *client, struct stream *msg)
struct zmsghdr hdr;
struct zebra_vrf *zvrf;
+ if (STREAM_READABLE(msg) > ZEBRA_MAX_PACKET_SIZ) {
+ if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
+ zlog_debug(
+ "ZAPI message is %zu bytes long but the maximum packet size is %u; dropping",
+ STREAM_READABLE(msg), ZEBRA_MAX_PACKET_SIZ);
+ return;
+ }
+
zapi_parse_header(msg, &hdr);
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index 8640a4a720..b48756302a 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -1400,37 +1400,25 @@ static void _zebra_ptm_reroute(struct zserv *zs, struct zebra_vrf *zvrf,
struct stream *msg, uint32_t command)
{
struct stream *msgc;
- size_t zmsglen, zhdrlen;
+ char buf[ZEBRA_MAX_PACKET_SIZ];
pid_t ppid;
- /*
- * Don't modify message in the zebra API. In order to do that we
- * need to allocate a new message stream and copy the message
- * provided by zebra.
- */
+ /* Create BFD header */
msgc = stream_new(ZEBRA_MAX_PACKET_SIZ);
- if (msgc == NULL) {
- zlog_debug("%s: not enough memory", __func__);
- return;
- }
-
- /* Calculate our header size plus the message contents. */
- zhdrlen = ZEBRA_HEADER_SIZE + sizeof(uint32_t);
- zmsglen = msg->endp - msg->getp;
- memcpy(msgc->data + zhdrlen, msg->data + msg->getp, zmsglen);
-
- /*
- * The message type will be BFD_DEST_REPLY so we can use only
- * one callback at the `bfdd` side, however the real command
- * number will be included right after the zebra header.
- */
zclient_create_header(msgc, ZEBRA_BFD_DEST_REPLAY, zvrf->vrf->vrf_id);
stream_putl(msgc, command);
- /* Update the data pointers. */
- msgc->getp = 0;
- msgc->endp = zhdrlen + zmsglen;
- stream_putw_at(msgc, 0, stream_get_endp(msgc));
+ if (STREAM_READABLE(msg) > STREAM_WRITEABLE(msgc)) {
+ zlog_warn("Cannot fit extended BFD header plus original message contents into ZAPI packet; dropping message");
+ goto stream_failure;
+ }
+
+ /* Copy original message, excluding header, into new message */
+ stream_get_from(buf, msg, stream_get_getp(msg), STREAM_READABLE(msg));
+ stream_put(msgc, buf, STREAM_READABLE(msg));
+
+ /* Update length field */
+ stream_putw_at(msgc, 0, STREAM_READABLE(msgc));
zebra_ptm_send_bfdd(msgc);
@@ -1441,6 +1429,7 @@ static void _zebra_ptm_reroute(struct zserv *zs, struct zebra_vrf *zvrf,
return;
stream_failure:
+ stream_free(msgc);
zlog_err("%s:%d failed to registrate client pid", __FILE__, __LINE__);
}
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 086b13d670..564573dcb3 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -7682,6 +7682,55 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state);
}
+static int32_t
+zebra_vxlan_remote_macip_helper(bool add, struct stream *s, vni_t *vni,
+ struct ethaddr *macaddr, uint16_t *ipa_len,
+ struct ipaddr *ip, struct in_addr *vtep_ip,
+ uint8_t *flags, uint32_t *seq)
+{
+ uint16_t l = 0;
+
+ /*
+ * Obtain each remote MACIP and process.
+ * Message contains VNI, followed by MAC followed by IP (if any)
+ * followed by remote VTEP IP.
+ */
+ memset(ip, 0, sizeof(*ip));
+ STREAM_GETL(s, *vni);
+ STREAM_GET(macaddr->octet, s, ETH_ALEN);
+ STREAM_GETL(s, *ipa_len);
+
+ if (*ipa_len) {
+ if (*ipa_len == IPV4_MAX_BYTELEN)
+ ip->ipa_type = IPADDR_V4;
+ else if (*ipa_len == IPV6_MAX_BYTELEN)
+ ip->ipa_type = IPADDR_V6;
+ else {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "ipa_len *must* be %d or %d bytes in length not %d",
+ IPV4_MAX_BYTELEN, IPV6_MAX_BYTELEN,
+ *ipa_len);
+ goto stream_failure;
+ }
+
+ STREAM_GET(&ip->ip.addr, s, *ipa_len);
+ }
+ l += 4 + ETH_ALEN + 4 + *ipa_len;
+ STREAM_GET(&vtep_ip->s_addr, s, IPV4_MAX_BYTELEN);
+ l += IPV4_MAX_BYTELEN;
+
+ if (add) {
+ STREAM_GETC(s, *flags);
+ STREAM_GETL(s, *seq);
+ l += 5;
+ }
+
+ return l;
+
+stream_failure:
+ return -1;
+}
/*
* Handle message from client to delete a remote MACIP for a VNI.
@@ -7704,23 +7753,14 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
s = msg;
while (l < hdr->length) {
- /* Obtain each remote MACIP and process. */
- /* Message contains VNI, followed by MAC followed by IP (if any)
- * followed by remote VTEP IP.
- */
- memset(&ip, 0, sizeof(ip));
- STREAM_GETL(s, vni);
- STREAM_GET(&macaddr.octet, s, ETH_ALEN);
- STREAM_GETL(s, ipa_len);
- if (ipa_len) {
- ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
- : IPADDR_V6;
- STREAM_GET(&ip.ip.addr, s, ipa_len);
- }
- l += 4 + ETH_ALEN + 4 + ipa_len;
- STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
- l += IPV4_MAX_BYTELEN;
+ int res_length = zebra_vxlan_remote_macip_helper(
+ false, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, NULL,
+ NULL);
+ if (res_length == -1)
+ goto stream_failure;
+
+ l += res_length;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
@@ -7769,29 +7809,14 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
s = msg;
while (l < hdr->length) {
- /* Obtain each remote MACIP and process. */
- /* Message contains VNI, followed by MAC followed by IP (if any)
- * followed by remote VTEP IP.
- */
- memset(&ip, 0, sizeof(ip));
- STREAM_GETL(s, vni);
- STREAM_GET(&macaddr.octet, s, ETH_ALEN);
- STREAM_GETL(s, ipa_len);
- if (ipa_len) {
- ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
- : IPADDR_V6;
- STREAM_GET(&ip.ip.addr, s, ipa_len);
- }
- l += 4 + ETH_ALEN + 4 + ipa_len;
- STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
- l += IPV4_MAX_BYTELEN;
+ int res_length = zebra_vxlan_remote_macip_helper(
+ true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip,
+ &flags, &seq);
- /* Get flags - sticky mac and/or gateway mac */
- STREAM_GETC(s, flags);
- l++;
- STREAM_GETL(s, seq);
- l += 4;
+ if (res_length == -1)
+ goto stream_failure;
+ l += res_length;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s",