aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorJosh Hunt <johunt@akamai.com>2015-06-08 12:00:59 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-08 15:13:17 -0400
commit0243508edd317ff1fa63b495643a7c192fbfcd92 (patch)
treead7aed1bf7565af3f7220b76ba579880df4f79f3 /net/ipv6
parent27e41fcfa6b326ad44eee7e0b1930d080b270895 (diff)
ipv6: Fix protocol resubmission
UDP encapsulation is broken on IPv6. This is because the logic to resubmit the nexthdr is inverted, checking for a ret value > 0 instead of < 0. Also, the resubmit label is in the wrong position since we already get the nexthdr value when performing decapsulation. In addition the skb pull is no longer necessary either. This changes the return value check to look for < 0, using it for the nexthdr on the next iteration, and moves the resubmit label to the proper location. With these changes the v6 code now matches what we do in the v4 ip input code wrt resubmitting when decapsulating. Signed-off-by: Josh Hunt <johunt@akamai.com> Acked-by: "Tom Herbert" <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_input.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index f2e464eba5ef..41a73da371a9 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -212,13 +212,13 @@ static int ip6_input_finish(struct sock *sk, struct sk_buff *skb)
212 */ 212 */
213 213
214 rcu_read_lock(); 214 rcu_read_lock();
215resubmit:
216 idev = ip6_dst_idev(skb_dst(skb)); 215 idev = ip6_dst_idev(skb_dst(skb));
217 if (!pskb_pull(skb, skb_transport_offset(skb))) 216 if (!pskb_pull(skb, skb_transport_offset(skb)))
218 goto discard; 217 goto discard;
219 nhoff = IP6CB(skb)->nhoff; 218 nhoff = IP6CB(skb)->nhoff;
220 nexthdr = skb_network_header(skb)[nhoff]; 219 nexthdr = skb_network_header(skb)[nhoff];
221 220
221resubmit:
222 raw = raw6_local_deliver(skb, nexthdr); 222 raw = raw6_local_deliver(skb, nexthdr);
223 ipprot = rcu_dereference(inet6_protos[nexthdr]); 223 ipprot = rcu_dereference(inet6_protos[nexthdr]);
224 if (ipprot) { 224 if (ipprot) {
@@ -246,10 +246,12 @@ resubmit:
246 goto discard; 246 goto discard;
247 247
248 ret = ipprot->handler(skb); 248 ret = ipprot->handler(skb);
249 if (ret > 0) 249 if (ret < 0) {
250 nexthdr = -ret;
250 goto resubmit; 251 goto resubmit;
251 else if (ret == 0) 252 } else if (ret == 0) {
252 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS); 253 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
254 }
253 } else { 255 } else {
254 if (!raw) { 256 if (!raw) {
255 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 257 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {