diff options
Diffstat (limited to 'net/openvswitch/flow.c')
| -rw-r--r-- | net/openvswitch/flow.c | 22 | 
1 files changed, 9 insertions, 13 deletions
| diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 56b8e7167790..35966da84769 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -254,21 +254,18 @@ static bool icmphdr_ok(struct sk_buff *skb)  static int parse_ipv6hdr(struct sk_buff *skb, struct sw_flow_key *key)  { +	unsigned short frag_off; +	unsigned int payload_ofs = 0;  	unsigned int nh_ofs = skb_network_offset(skb);  	unsigned int nh_len; -	int payload_ofs;  	struct ipv6hdr *nh; -	uint8_t nexthdr; -	__be16 frag_off; -	int err; +	int err, nexthdr, flags = 0;  	err = check_header(skb, nh_ofs + sizeof(*nh));  	if (unlikely(err))  		return err;  	nh = ipv6_hdr(skb); -	nexthdr = nh->nexthdr; -	payload_ofs = (u8 *)(nh + 1) - skb->data;  	key->ip.proto = NEXTHDR_NONE;  	key->ip.tos = ipv6_get_dsfield(nh); @@ -277,10 +274,9 @@ static int parse_ipv6hdr(struct sk_buff *skb, struct sw_flow_key *key)  	key->ipv6.addr.src = nh->saddr;  	key->ipv6.addr.dst = nh->daddr; -	payload_ofs = ipv6_skip_exthdr(skb, payload_ofs, &nexthdr, &frag_off); - -	if (frag_off) { -		if (frag_off & htons(~0x7)) +	nexthdr = ipv6_find_hdr(skb, &payload_ofs, -1, &frag_off, &flags); +	if (flags & IP6_FH_F_FRAG) { +		if (frag_off)  			key->ip.frag = OVS_FRAG_TYPE_LATER;  		else  			key->ip.frag = OVS_FRAG_TYPE_FIRST; @@ -288,11 +284,11 @@ static int parse_ipv6hdr(struct sk_buff *skb, struct sw_flow_key *key)  		key->ip.frag = OVS_FRAG_TYPE_NONE;  	} -	/* Delayed handling of error in ipv6_skip_exthdr() as it -	 * always sets frag_off to a valid value which may be +	/* Delayed handling of error in ipv6_find_hdr() as it +	 * always sets flags and frag_off to a valid value which may be  	 * used to set key->ip.frag above.  	 */ -	if (unlikely(payload_ofs < 0)) +	if (unlikely(nexthdr < 0))  		return -EPROTO;  	nh_len = payload_ofs - nh_ofs; |