diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index eceaa81..ff50563 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -844,6 +844,7 @@ ip_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl)
 {
     struct ip_header *nh;
     void *l4;
+    int l3_size;
 
     nh = dp_packet_l3(packet);
     l4 = dp_packet_l4(packet);
@@ -852,6 +853,32 @@ ip_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl)
         return NULL;
     }
 
+    if (csum(nh, IP_IHL(nh->ip_ihl_ver) * 4)) {
+        VLOG_WARN_RL(&err_rl, "ip packet has invalid checksum");
+        return NULL;
+    }
+
+    if (IP_VER(nh->ip_ihl_ver) != 4) {
+        VLOG_WARN_RL(&err_rl, "ipv4 packet has invalid version (%d)",
+                     IP_VER(nh->ip_ihl_ver));
+        return NULL;
+    }
+
+    l3_size = dp_packet_size(packet) -
+              ((char *)nh - (char *)dp_packet_data(packet));
+
+    if (ntohs(nh->ip_tot_len) > l3_size) {
+        VLOG_WARN_RL(&err_rl, "ip packet is truncated (IP length %d, actual %d)",
+                     ntohs(nh->ip_tot_len), l3_size);
+        return NULL;
+    }
+
+    if (IP_IHL(nh->ip_ihl_ver) * 4 > sizeof(struct ip_header)) {
+        VLOG_WARN_RL(&err_rl, "ip options not supported on tunnel packets "
+                     "(%d bytes)", IP_IHL(nh->ip_ihl_ver) * 4);
+        return NULL;
+    }
+
     tnl->ip_src = get_16aligned_be32(&nh->ip_src);
     tnl->ip_dst = get_16aligned_be32(&nh->ip_dst);
     tnl->ip_tos = nh->ip_tos;
diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
index 502e41f..98f22ea 100644
--- a/tests/tunnel-push-pop.at
+++ b/tests/tunnel-push-pop.at
@@ -109,7 +109,7 @@ AT_CHECK([tail -1 stdout], [0],
 ])
 
 dnl Check decapsulation of GRE packet
-AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab6408004500007e79464000402f99080101025c0101025820006558000001c8fe71d883724fbeb6f4e1494a080045000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
+AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab6408004500007e79464000402fba550101025c0101025820006558000001c8fe71d883724fbeb6f4e1494a080045000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
 ovs-appctl time/warp 1000
 
 AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port  3'], [0], [dnl
@@ -117,7 +117,7 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port  3'], [0], [dnl
 ])
 
 dnl Check GRE only accepts encapsulated Ethernet frames
-AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab6408004500007e79464000402f99080101025c0101025820000800000001c8fe71d883724fbeb6f4e1494a080045000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
+AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab6408004500007e79464000402fba550101025c0101025820000800000001c8fe71d883724fbeb6f4e1494a080045000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
 ovs-appctl time/warp 1000
 
 AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port  3'], [0], [dnl
@@ -130,7 +130,7 @@ AT_CHECK([ovs-ofctl monitor int-br 65534 --detach --no-chdir --pidfile 2> ofctl_
 
 AT_CHECK([ovs-ofctl del-flows int-br])
 AT_CHECK([ovs-ofctl add-flow int-br "tun_metadata0=0xa/0xf,actions=5,controller"])
-AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab64080045000096794640004011ba630101025c01010258308817c1008200000400655800007b00ffff80010000000affff00010000000bfe71d883724fbeb6f4e1494a080045000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
+AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab64080045000096794640004011ba5b0101025c01010258308817c1008200000400655800007b00ffff80010000000affff00010000000bfe71d883724fbeb6f4e1494a080045000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
 
 OVS_WAIT_UNTIL([test `wc -l < ofctl_monitor.log` -ge 2])
 OVS_APP_EXIT_AND_WAIT(ovs-ofctl)
