unsigned int nh_ofs = skb_network_offset(skb);
unsigned int nh_len;
int payload_ofs;
- int payload_len;
struct ipv6hdr *nh;
uint8_t nexthdr;
nh = ipv6_hdr(skb);
nexthdr = nh->nexthdr;
payload_ofs = (u8 *)(nh + 1) - skb->data;
- payload_len = ntohs(nh->payload_len);
memcpy(key->ipv6_src, nh->saddr.in6_u.u6_addr8, sizeof(key->ipv6_src));
memcpy(key->ipv6_dst, nh->daddr.in6_u.u6_addr8, sizeof(key->ipv6_dst));
key->nw_tos = ipv6_get_dsfield(nh) & ~INET_ECN_MASK;
key->nw_proto = NEXTHDR_NONE;
- /* We don't process jumbograms. */
- if (!payload_len)
- return -EINVAL;
-
- if (unlikely(skb->len < nh_ofs + sizeof(*nh) + payload_len))
- return -EINVAL;
-
payload_ofs = ipv6_skip_exthdr(skb, payload_ofs, &nexthdr);
if (payload_ofs < 0) {
return -EINVAL;
}
nh_len = payload_ofs - nh_ofs;
- /* Ensure that the payload length claimed is at least large enough
- * for the headers we've already processed. */
- if (payload_len < nh_len - sizeof(*nh))
- return -EINVAL;
-
/* Pull enough header bytes to account for the IP header plus the
* longest transport header that we parse, currently 20 bytes for TCP.
* To dig deeper than the transport header, transport parsers may need
static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
int nh_len)
{
- struct ipv6hdr *nh = ipv6_hdr(skb);
- int icmp_len = ntohs(nh->payload_len) + sizeof(*nh) - nh_len;
struct icmp6hdr *icmp = icmp6_hdr(skb);
/* The ICMPv6 type and code fields use the 16-bit transport port
if (!icmp->icmp6_code
&& ((icmp->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
|| (icmp->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT))) {
+ int icmp_len = skb->len - skb_transport_offset(skb);
struct nd_msg *nd;
int offset;
* entire packet. */
if (icmp_len < sizeof(*nd))
goto invalid;
- if (!pskb_may_pull(skb, skb_transport_offset(skb) + icmp_len))
+ if (unlikely(!pskb_may_pull(skb, skb->len)))
return -ENOMEM;
nd = (struct nd_msg *)skb_transport_header(skb);
{
struct ip6_hdr *nh;
int nh_len = sizeof(struct ip6_hdr);
- int payload_len;
ovs_be32 tc_flow;
int nexthdr;
nh = packet->data;
nexthdr = nh->ip6_nxt;
- payload_len = ntohs(nh->ip6_plen);
flow->ipv6_src = nh->ip6_src;
flow->ipv6_dst = nh->ip6_dst;
flow->nw_tos = (ntohl(tc_flow) >> 4) & IP_DSCP_MASK;
flow->nw_proto = IPPROTO_NONE;
- /* We don't process jumbograms. */
- if (!payload_len) {
- return -EINVAL;
- }
-
- if (packet->size < sizeof *nh + payload_len) {
- return -EINVAL;
- }
-
while (1) {
if ((nexthdr != IPPROTO_HOPOPTS)
&& (nexthdr != IPPROTO_ROUTING)
}
}
- /* The payload length claims to be smaller than the size of the
- * headers we've already processed. */
- if (payload_len < nh_len - sizeof *nh) {
- return -EINVAL;
- }
-
flow->nw_proto = nexthdr;
return nh_len;
}
packet->l7 = b.data;
}
} else if (flow->nw_proto == IPPROTO_ICMPV6) {
- int icmp_len = ntohs(nh->ip6_plen) + sizeof *nh - nh_len;
- if (parse_icmpv6(&b, flow, icmp_len)) {
+ if (parse_icmpv6(&b, flow, b.size)) {
packet->l7 = b.data;
}
}