Commit 0243508e authored by Josh Hunt's avatar Josh Hunt Committed by David S. Miller

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: default avatarJosh Hunt <johunt@akamai.com>
Acked-by: default avatar"Tom Herbert" <tom@herbertland.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 27e41fcf
...@@ -212,13 +212,13 @@ static int ip6_input_finish(struct sock *sk, struct sk_buff *skb) ...@@ -212,13 +212,13 @@ static int ip6_input_finish(struct sock *sk, struct sk_buff *skb)
*/ */
rcu_read_lock(); rcu_read_lock();
resubmit:
idev = ip6_dst_idev(skb_dst(skb)); idev = ip6_dst_idev(skb_dst(skb));
if (!pskb_pull(skb, skb_transport_offset(skb))) if (!pskb_pull(skb, skb_transport_offset(skb)))
goto discard; goto discard;
nhoff = IP6CB(skb)->nhoff; nhoff = IP6CB(skb)->nhoff;
nexthdr = skb_network_header(skb)[nhoff]; nexthdr = skb_network_header(skb)[nhoff];
resubmit:
raw = raw6_local_deliver(skb, nexthdr); raw = raw6_local_deliver(skb, nexthdr);
ipprot = rcu_dereference(inet6_protos[nexthdr]); ipprot = rcu_dereference(inet6_protos[nexthdr]);
if (ipprot) { if (ipprot) {
...@@ -246,10 +246,12 @@ static int ip6_input_finish(struct sock *sk, struct sk_buff *skb) ...@@ -246,10 +246,12 @@ static int ip6_input_finish(struct sock *sk, struct sk_buff *skb)
goto discard; goto discard;
ret = ipprot->handler(skb); ret = ipprot->handler(skb);
if (ret > 0) if (ret < 0) {
nexthdr = -ret;
goto resubmit; goto resubmit;
else if (ret == 0) } else if (ret == 0) {
IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS); IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
}
} else { } else {
if (!raw) { if (!raw) {
if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment