ipv6: factor out protocol delivery helper

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>
This commit is contained in:
Paolo Abeni 2018-11-07 12:38:32 +01:00 committed by David S. Miller
parent 68cb7d531e
commit 80bde363f9
2 changed files with 18 additions and 12 deletions

View 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_forward(struct sk_buff *skb);
int ip6_input(struct sk_buff *skb); int ip6_input(struct sk_buff *skb);
int ip6_mc_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);
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);

View File

@ -319,28 +319,26 @@ void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
/* /*
* Deliver the packet to the host * Deliver the packet to the host
*/ */
void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
bool have_final)
static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{ {
const struct inet6_protocol *ipprot; const struct inet6_protocol *ipprot;
struct inet6_dev *idev; struct inet6_dev *idev;
unsigned int nhoff; unsigned int nhoff;
int nexthdr;
bool raw; bool raw;
bool have_final = false;
/* /*
* Parse extension headers * Parse extension headers
*/ */
rcu_read_lock();
resubmit: resubmit:
idev = ip6_dst_idev(skb_dst(skb)); idev = ip6_dst_idev(skb_dst(skb));
if (!pskb_pull(skb, skb_transport_offset(skb)))
goto discard;
nhoff = IP6CB(skb)->nhoff; 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: resubmit_final:
raw = raw6_local_deliver(skb, nexthdr); raw = raw6_local_deliver(skb, nexthdr);
@ -423,13 +421,19 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
consume_skb(skb); consume_skb(skb);
} }
} }
rcu_read_unlock(); return;
return 0;
discard: discard:
__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS); __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
rcu_read_unlock();
kfree_skb(skb); 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; return 0;
} }