diff options
Diffstat (limited to 'lib/netdev-vport.c')
-rw-r--r-- | lib/netdev-vport.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index eceaa813e..ff505637e 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; |