ipv6: factor out protocol delivery helper
authorPaolo Abeni <pabeni@redhat.com>
Wed, 7 Nov 2018 11:38:32 +0000 (12:38 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 8 Nov 2018 00:23:05 +0000 (16:23 -0800)
So that we can re-use it at the UDP level in the next patch

rfc v3 -> v1:
 - add the helper declaration into the ipv6 header

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ipv6.h
net/ipv6/ip6_input.c

index 829650540780c9e091dc7c6ea01201d68548ca23..daf80863d3a5037c8defe820908a4fbdfb4817e3 100644 (file)
@@ -975,6 +975,8 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
 int ip6_forward(struct sk_buff *skb);
 int ip6_input(struct sk_buff *skb);
 int ip6_mc_input(struct sk_buff *skb);
+void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
+                             bool have_final);
 
 int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
 int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
index df58e1100226e26e79726250b30e5e8fa86e3f1e..3c06cc9e9b796e4e549e30404494f4588a6a8f46 100644 (file)
@@ -319,28 +319,26 @@ void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
 /*
  *     Deliver the packet to the host
  */
-
-
-static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
+void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
+                             bool have_final)
 {
        const struct inet6_protocol *ipprot;
        struct inet6_dev *idev;
        unsigned int nhoff;
-       int nexthdr;
        bool raw;
-       bool have_final = false;
 
        /*
         *      Parse extension headers
         */
 
-       rcu_read_lock();
 resubmit:
        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];
+       if (!have_final) {
+               if (!pskb_pull(skb, skb_transport_offset(skb)))
+                       goto discard;
+               nexthdr = skb_network_header(skb)[nhoff];
+       }
 
 resubmit_final:
        raw = raw6_local_deliver(skb, nexthdr);
@@ -423,13 +421,19 @@ resubmit_final:
                        consume_skb(skb);
                }
        }
-       rcu_read_unlock();
-       return 0;
+       return;
 
 discard:
        __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
-       rcu_read_unlock();
        kfree_skb(skb);
+}
+
+static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
+{
+       rcu_read_lock();
+       ip6_protocol_deliver_rcu(net, skb, 0, false);
+       rcu_read_unlock();
+
        return 0;
 }