diff options
Diffstat (limited to 'net/ipv6/xfrm6_policy.c')
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 08e4cbbe3f04..604bc0a96c05 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -144,6 +144,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) | |||
144 | static inline void | 144 | static inline void |
145 | _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | 145 | _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) |
146 | { | 146 | { |
147 | int onlyproto = 0; | ||
147 | u16 offset = skb_network_header_len(skb); | 148 | u16 offset = skb_network_header_len(skb); |
148 | struct ipv6hdr *hdr = ipv6_hdr(skb); | 149 | struct ipv6hdr *hdr = ipv6_hdr(skb); |
149 | struct ipv6_opt_hdr *exthdr; | 150 | struct ipv6_opt_hdr *exthdr; |
@@ -159,6 +160,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
159 | exthdr = (struct ipv6_opt_hdr *)(nh + offset); | 160 | exthdr = (struct ipv6_opt_hdr *)(nh + offset); |
160 | 161 | ||
161 | switch (nexthdr) { | 162 | switch (nexthdr) { |
163 | case NEXTHDR_FRAGMENT: | ||
164 | onlyproto = 1; | ||
162 | case NEXTHDR_ROUTING: | 165 | case NEXTHDR_ROUTING: |
163 | case NEXTHDR_HOP: | 166 | case NEXTHDR_HOP: |
164 | case NEXTHDR_DEST: | 167 | case NEXTHDR_DEST: |
@@ -172,7 +175,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
172 | case IPPROTO_TCP: | 175 | case IPPROTO_TCP: |
173 | case IPPROTO_SCTP: | 176 | case IPPROTO_SCTP: |
174 | case IPPROTO_DCCP: | 177 | case IPPROTO_DCCP: |
175 | if (pskb_may_pull(skb, nh + offset + 4 - skb->data)) { | 178 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 4 - skb->data)) { |
176 | __be16 *ports = (__be16 *)exthdr; | 179 | __be16 *ports = (__be16 *)exthdr; |
177 | 180 | ||
178 | fl->fl_ip_sport = ports[!!reverse]; | 181 | fl->fl_ip_sport = ports[!!reverse]; |
@@ -182,7 +185,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
182 | return; | 185 | return; |
183 | 186 | ||
184 | case IPPROTO_ICMPV6: | 187 | case IPPROTO_ICMPV6: |
185 | if (pskb_may_pull(skb, nh + offset + 2 - skb->data)) { | 188 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) { |
186 | u8 *icmp = (u8 *)exthdr; | 189 | u8 *icmp = (u8 *)exthdr; |
187 | 190 | ||
188 | fl->fl_icmp_type = icmp[0]; | 191 | fl->fl_icmp_type = icmp[0]; |
@@ -193,7 +196,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
193 | 196 | ||
194 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 197 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
195 | case IPPROTO_MH: | 198 | case IPPROTO_MH: |
196 | if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) { | 199 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { |
197 | struct ip6_mh *mh; | 200 | struct ip6_mh *mh; |
198 | mh = (struct ip6_mh *)exthdr; | 201 | mh = (struct ip6_mh *)exthdr; |
199 | 202 | ||