diff mbox

[v3] packet parsing modifications

Message ID 1396027434-23054-1-git-send-email-ciprian.barbu@linaro.org
State Superseded
Headers show

Commit Message

Ciprian Barbu March 28, 2014, 5:23 p.m. UTC
This patch version makes sure the header length is big enough to hold known
protocol headers. I also corrected a problem with ethertype for vlan packets.

Signed-off-by: Ciprian Barbu <ciprian.barbu@linaro.org>
---
 platform/linux-generic/source/odp_packet.c        | 22 +++++++++++++++++++---
 platform/linux-generic/source/odp_packet_netmap.c |  2 +-
 2 files changed, 20 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/platform/linux-generic/source/odp_packet.c b/platform/linux-generic/source/odp_packet.c
index e60f96c..0e29746 100644
--- a/platform/linux-generic/source/odp_packet.c
+++ b/platform/linux-generic/source/odp_packet.c
@@ -154,7 +154,7 @@  void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
 	pkt_hdr->frame_offset = frame_offset;
 	pkt_hdr->frame_len = len;
 
-	if (odp_unlikely(len < ODP_ETH_LEN_MIN)) {
+	if (odp_unlikely(len < ODP_ETHHDR_LEN)) {
 		pkt_hdr->error_flags.frame_len = 1;
 		return;
 	} else if (len > ODP_ETH_LEN_MAX) {
@@ -171,20 +171,32 @@  void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
 
 	if (ethtype == ODP_ETHTYPE_VLAN_OUTER) {
 		pkt_hdr->input_flags.vlan_qinq = 1;
-		ethtype = odp_be_to_cpu_16(vlan->tpid);
+		ethtype = odp_be_to_cpu_16(vlan[1].tpid);
+		if (len < ODP_ETHHDR_LEN + ODP_VLANHDR_LEN) {
+			pkt_hdr->error_flags.frame_len = 1;
+			return;
+		}
 		offset += sizeof(odp_vlanhdr_t);
 		vlan = &vlan[1];
 	}
 
 	if (ethtype == ODP_ETHTYPE_VLAN) {
 		pkt_hdr->input_flags.vlan = 1;
-		ethtype = odp_be_to_cpu_16(vlan->tpid);
+		ethtype = odp_be_to_cpu_16(vlan[1].tpid);
+		if (len < ODP_ETHHDR_LEN + ODP_VLANHDR_LEN) {
+			pkt_hdr->error_flags.frame_len = 1;
+			return;
+		}
 		offset += sizeof(odp_vlanhdr_t);
 	}
 
 	/* Set l3_offset+flag only for known ethtypes */
 	switch (ethtype) {
 	case ODP_ETHTYPE_IPV4:
+		if (len < ODP_ETHHDR_LEN + offset + sizeof(odp_ipv4hdr_t*)) {
+			pkt_hdr->error_flags.frame_len = 1;
+			return;
+		}
 		pkt_hdr->input_flags.ipv4 = 1;
 		pkt_hdr->input_flags.l3 = 1;
 		pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset;
@@ -192,6 +204,10 @@  void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
 		ip_proto = parse_ipv4(pkt_hdr, ipv4, &offset);
 		break;
 	case ODP_ETHTYPE_IPV6:
+		if (len < ODP_ETHHDR_LEN + offset + sizeof(odp_ipv6hdr_t*)) {
+			pkt_hdr->error_flags.frame_len = 1;
+			return;
+		}
 		pkt_hdr->input_flags.ipv6 = 1;
 		pkt_hdr->input_flags.l3 = 1;
 		pkt_hdr->l3_offset = frame_offset + ODP_ETHHDR_LEN + offset;
diff --git a/platform/linux-generic/source/odp_packet_netmap.c b/platform/linux-generic/source/odp_packet_netmap.c
index 1cbd84c..a6b75f5 100644
--- a/platform/linux-generic/source/odp_packet_netmap.c
+++ b/platform/linux-generic/source/odp_packet_netmap.c
@@ -361,7 +361,7 @@  int send_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[],
 		txbuf = NETMAP_BUF(txring, slot->buf_idx);
 
 		pkt = pkt_table[i];
-		frame = odp_packet_l2(pkt);
+		frame = odp_packet_start(pkt);
 		frame_len = odp_packet_get_len(pkt);
 
 		memcpy(txbuf, frame, frame_len);