Hi, On Fri, 13 May 2016 09:28:50 +0300 Shmulik Ladkani <shmulik.ladk...@gmail.com> wrote: > On Thu, 12 May 2016 14:45:36 -0700 Tom Herbert <t...@herbertland.com> wrote: > > Is there any reason why the EH handlers can't read the nexthdr and return > > that? > > One additional thing: > > Seems the > > if (!pskb_pull(skb, skb_transport_offset(skb))) > > located at the original resubmit label was also necessary, as the EH > handlers may increment skb->transport_header (both ipv6_destopt_rcv and > ipv6_rthdr_rcv do so). > > So if we'd like to read the nexthdr at the EH handlers we should repeat > the "skb pull; read nexthdr from skb_network_header(skb)[new nhoff]; > return nexhdr;" prior each positive return from EH handlers.
Alternatively, instead of modifying EH handlers adding this repeated logic, we can rearrange ip6_input_finish code, under the premise that "EH handling iff !INET6_PROTO_FINAL", as follows: @@ -229,13 +229,14 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk */ rcu_read_lock(); -resubmit: +nexthdr_read: idev = ip6_dst_idev(skb_dst(skb)); if (!pskb_pull(skb, skb_transport_offset(skb))) goto discard; nhoff = IP6CB(skb)->nhoff; nexthdr = skb_network_header(skb)[nhoff]; +resubmit: raw = raw6_local_deliver(skb, nexthdr); ipprot = rcu_dereference(inet6_protos[nexthdr]); if (ipprot) { @@ -263,8 +264,12 @@ resubmit: goto discard; ret = ipprot->handler(skb); - if (ret > 0) + if (ret > 0) { + if (!(ipprot->flags & INET6_PROTO_FINAL)) + goto nexthdr_read; + nexthdr = ret; goto resubmit; + } else if (ret == 0) __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS); Meaning, for EH (identified by !INET6_PROTO_FINAL), act as originally was (skbpull and refetch nexthdr); For non INET6_PROTO_FINAL, ret code is the proto itself, so go directly to resubmit. Less modifications, but (1) creates a coupling (wasn't there already?) between EH handlers and the !INET6_PROTO_FINAL flag, (2) anchors the dual semantics WRT ret code of inet6_protocol->handler. Regards, Shmulik