diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2020-01-03 19:30:37 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2020-01-07 02:25:51 +0100 |
commit | 0bd371c61e485d67fd1d228cc0e9d329277bed40 (patch) | |
tree | 238656c4459b1404869aefeb51ca47c97c9472ca /zebra/zebra_vxlan.c | |
parent | zebra: Prevent zebra vxlan remote macip del buffer overflow (diff) | |
download | frr-0bd371c61e485d67fd1d228cc0e9d329277bed40.tar.xz frr-0bd371c61e485d67fd1d228cc0e9d329277bed40.zip |
zebra: Refactor _add and _del to use a common function
The decoding of _add and _del functions is practically identical
do a bit of work and make them so.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to '')
-rw-r--r-- | zebra/zebra_vxlan.c | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 55baa8e68..564573dcb 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,34 +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) { - 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; - } + int res_length = zebra_vxlan_remote_macip_helper( + false, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, NULL, + NULL); - 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 (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", @@ -7780,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", |