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

Reply via email to