Factor _ipv6_frag_rcv() out of ipv6_frag_rcv() such that the former takes a netns and user field. We do this so that the BPF interface for ipv6 defrag can have the same semantics as ipv4 defrag (see ip_check_defrag()). Signed-off-by: Daniel Xu <dxu@xxxxxxxxx> --- include/net/ipv6.h | 1 + net/ipv6/reassembly.c | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 7332296eca44..9bbdf82ca6c0 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -1238,6 +1238,7 @@ int inet6_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, extern const struct proto_ops inet6_stream_ops; extern const struct proto_ops inet6_dgram_ops; extern const struct proto_ops inet6_sockraw_ops; +int _ipv6_frag_rcv(struct net *net, struct sk_buff *skb, u32 user); struct group_source_req; struct group_filter; diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 5bc8a28e67f9..5100430eb982 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -81,13 +81,13 @@ static void ip6_frag_expire(struct timer_list *t) } static struct frag_queue * -fq_find(struct net *net, __be32 id, const struct ipv6hdr *hdr, int iif) +fq_find(struct net *net, __be32 id, const struct ipv6hdr *hdr, int iif, u32 user) { struct frag_v6_compare_key key = { .id = id, .saddr = hdr->saddr, .daddr = hdr->daddr, - .user = IP6_DEFRAG_LOCAL_DELIVER, + .user = user, .iif = iif, }; struct inet_frag_queue *q; @@ -324,12 +324,11 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *skb, return -1; } -static int ipv6_frag_rcv(struct sk_buff *skb) +int _ipv6_frag_rcv(struct net *net, struct sk_buff *skb, u32 user) { struct frag_hdr *fhdr; struct frag_queue *fq; const struct ipv6hdr *hdr = ipv6_hdr(skb); - struct net *net = dev_net(skb_dst(skb)->dev); u8 nexthdr; int iif; @@ -377,7 +376,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) } iif = skb->dev ? skb->dev->ifindex : 0; - fq = fq_find(net, fhdr->identification, hdr, iif); + fq = fq_find(net, fhdr->identification, hdr, iif, user); if (fq) { u32 prob_offset = 0; int ret; @@ -410,6 +409,13 @@ static int ipv6_frag_rcv(struct sk_buff *skb) return -1; } +static int ipv6_frag_rcv(struct sk_buff *skb) +{ + struct net *net = dev_net(skb_dst(skb)->dev); + + return _ipv6_frag_rcv(net, skb, IP6_DEFRAG_LOCAL_DELIVER); +} + static const struct inet6_protocol frag_protocol = { .handler = ipv6_frag_rcv, .flags = INET6_PROTO_NOPOLICY, -- 2.39.1