Commit 093ba729 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

inet: frags: add a pointer to struct netns_frags

In order to simplify the API, add a pointer to struct inet_frags.
This will allow us to make things less complex.

These functions no longer have a struct inet_frags parameter :

inet_frag_destroy(struct inet_frag_queue *q  /*, struct inet_frags *f */)
inet_frag_put(struct inet_frag_queue *q /*, struct inet_frags *f */)
inet_frag_kill(struct inet_frag_queue *q /*, struct inet_frags *f */)
inet_frags_exit_net(struct netns_frags *nf /*, struct inet_frags *f */)
ip6_expire_frag_queue(struct net *net, struct frag_queue *fq)
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 787bea77
...@@ -10,6 +10,7 @@ struct netns_frags { ...@@ -10,6 +10,7 @@ struct netns_frags {
int high_thresh; int high_thresh;
int low_thresh; int low_thresh;
int max_dist; int max_dist;
struct inet_frags *f;
}; };
/** /**
...@@ -109,20 +110,20 @@ static inline int inet_frags_init_net(struct netns_frags *nf) ...@@ -109,20 +110,20 @@ static inline int inet_frags_init_net(struct netns_frags *nf)
atomic_set(&nf->mem, 0); atomic_set(&nf->mem, 0);
return 0; return 0;
} }
void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f); void inet_frags_exit_net(struct netns_frags *nf);
void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); void inet_frag_kill(struct inet_frag_queue *q);
void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f); void inet_frag_destroy(struct inet_frag_queue *q);
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
struct inet_frags *f, void *key, unsigned int hash); struct inet_frags *f, void *key, unsigned int hash);
void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q, void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
const char *prefix); const char *prefix);
static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f) static inline void inet_frag_put(struct inet_frag_queue *q)
{ {
if (refcount_dec_and_test(&q->refcnt)) if (refcount_dec_and_test(&q->refcnt))
inet_frag_destroy(q, f); inet_frag_destroy(q);
} }
static inline bool inet_frag_evicting(struct inet_frag_queue *q) static inline bool inet_frag_evicting(struct inet_frag_queue *q)
......
...@@ -607,8 +607,7 @@ struct frag_queue { ...@@ -607,8 +607,7 @@ struct frag_queue {
u8 ecn; u8 ecn;
}; };
void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq);
struct inet_frags *frags);
static inline bool ipv6_addr_any(const struct in6_addr *a) static inline bool ipv6_addr_any(const struct in6_addr *a)
{ {
......
...@@ -94,10 +94,10 @@ static void lowpan_frag_expire(struct timer_list *t) ...@@ -94,10 +94,10 @@ static void lowpan_frag_expire(struct timer_list *t)
if (fq->q.flags & INET_FRAG_COMPLETE) if (fq->q.flags & INET_FRAG_COMPLETE)
goto out; goto out;
inet_frag_kill(&fq->q, &lowpan_frags); inet_frag_kill(&fq->q);
out: out:
spin_unlock(&fq->q.lock); spin_unlock(&fq->q.lock);
inet_frag_put(&fq->q, &lowpan_frags); inet_frag_put(&fq->q);
} }
static inline struct lowpan_frag_queue * static inline struct lowpan_frag_queue *
...@@ -230,7 +230,7 @@ static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev, ...@@ -230,7 +230,7 @@ static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev,
struct sk_buff *fp, *head = fq->q.fragments; struct sk_buff *fp, *head = fq->q.fragments;
int sum_truesize; int sum_truesize;
inet_frag_kill(&fq->q, &lowpan_frags); inet_frag_kill(&fq->q);
/* Make the one we just received the head. */ /* Make the one we just received the head. */
if (prev) { if (prev) {
...@@ -438,7 +438,7 @@ int lowpan_frag_rcv(struct sk_buff *skb, u8 frag_type) ...@@ -438,7 +438,7 @@ int lowpan_frag_rcv(struct sk_buff *skb, u8 frag_type)
ret = lowpan_frag_queue(fq, skb, frag_type); ret = lowpan_frag_queue(fq, skb, frag_type);
spin_unlock(&fq->q.lock); spin_unlock(&fq->q.lock);
inet_frag_put(&fq->q, &lowpan_frags); inet_frag_put(&fq->q);
return ret; return ret;
} }
...@@ -586,13 +586,14 @@ static int __net_init lowpan_frags_init_net(struct net *net) ...@@ -586,13 +586,14 @@ static int __net_init lowpan_frags_init_net(struct net *net)
ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH; ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH; ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT; ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
ieee802154_lowpan->frags.f = &lowpan_frags;
res = inet_frags_init_net(&ieee802154_lowpan->frags); res = inet_frags_init_net(&ieee802154_lowpan->frags);
if (res < 0) if (res < 0)
return res; return res;
res = lowpan_frags_ns_sysctl_register(net); res = lowpan_frags_ns_sysctl_register(net);
if (res < 0) if (res < 0)
inet_frags_exit_net(&ieee802154_lowpan->frags, &lowpan_frags); inet_frags_exit_net(&ieee802154_lowpan->frags);
return res; return res;
} }
...@@ -602,7 +603,7 @@ static void __net_exit lowpan_frags_exit_net(struct net *net) ...@@ -602,7 +603,7 @@ static void __net_exit lowpan_frags_exit_net(struct net *net)
net_ieee802154_lowpan(net); net_ieee802154_lowpan(net);
lowpan_frags_ns_sysctl_unregister(net); lowpan_frags_ns_sysctl_unregister(net);
inet_frags_exit_net(&ieee802154_lowpan->frags, &lowpan_frags); inet_frags_exit_net(&ieee802154_lowpan->frags);
} }
static struct pernet_operations lowpan_frags_ops = { static struct pernet_operations lowpan_frags_ops = {
......
...@@ -219,8 +219,9 @@ void inet_frags_fini(struct inet_frags *f) ...@@ -219,8 +219,9 @@ void inet_frags_fini(struct inet_frags *f)
} }
EXPORT_SYMBOL(inet_frags_fini); EXPORT_SYMBOL(inet_frags_fini);
void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f) void inet_frags_exit_net(struct netns_frags *nf)
{ {
struct inet_frags *f =nf->f;
unsigned int seq; unsigned int seq;
int i; int i;
...@@ -264,33 +265,34 @@ __acquires(hb->chain_lock) ...@@ -264,33 +265,34 @@ __acquires(hb->chain_lock)
return hb; return hb;
} }
static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f) static inline void fq_unlink(struct inet_frag_queue *fq)
{ {
struct inet_frag_bucket *hb; struct inet_frag_bucket *hb;
hb = get_frag_bucket_locked(fq, f); hb = get_frag_bucket_locked(fq, fq->net->f);
hlist_del(&fq->list); hlist_del(&fq->list);
fq->flags |= INET_FRAG_COMPLETE; fq->flags |= INET_FRAG_COMPLETE;
spin_unlock(&hb->chain_lock); spin_unlock(&hb->chain_lock);
} }
void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f) void inet_frag_kill(struct inet_frag_queue *fq)
{ {
if (del_timer(&fq->timer)) if (del_timer(&fq->timer))
refcount_dec(&fq->refcnt); refcount_dec(&fq->refcnt);
if (!(fq->flags & INET_FRAG_COMPLETE)) { if (!(fq->flags & INET_FRAG_COMPLETE)) {
fq_unlink(fq, f); fq_unlink(fq);
refcount_dec(&fq->refcnt); refcount_dec(&fq->refcnt);
} }
} }
EXPORT_SYMBOL(inet_frag_kill); EXPORT_SYMBOL(inet_frag_kill);
void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f) void inet_frag_destroy(struct inet_frag_queue *q)
{ {
struct sk_buff *fp; struct sk_buff *fp;
struct netns_frags *nf; struct netns_frags *nf;
unsigned int sum, sum_truesize = 0; unsigned int sum, sum_truesize = 0;
struct inet_frags *f;
WARN_ON(!(q->flags & INET_FRAG_COMPLETE)); WARN_ON(!(q->flags & INET_FRAG_COMPLETE));
WARN_ON(del_timer(&q->timer) != 0); WARN_ON(del_timer(&q->timer) != 0);
...@@ -298,6 +300,7 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f) ...@@ -298,6 +300,7 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f)
/* Release all fragment data. */ /* Release all fragment data. */
fp = q->fragments; fp = q->fragments;
nf = q->net; nf = q->net;
f = nf->f;
while (fp) { while (fp) {
struct sk_buff *xp = fp->next; struct sk_buff *xp = fp->next;
...@@ -333,7 +336,7 @@ static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, ...@@ -333,7 +336,7 @@ static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf,
refcount_inc(&qp->refcnt); refcount_inc(&qp->refcnt);
spin_unlock(&hb->chain_lock); spin_unlock(&hb->chain_lock);
qp_in->flags |= INET_FRAG_COMPLETE; qp_in->flags |= INET_FRAG_COMPLETE;
inet_frag_put(qp_in, f); inet_frag_put(qp_in);
return qp; return qp;
} }
} }
......
...@@ -168,7 +168,7 @@ static void ip4_frag_free(struct inet_frag_queue *q) ...@@ -168,7 +168,7 @@ static void ip4_frag_free(struct inet_frag_queue *q)
static void ipq_put(struct ipq *ipq) static void ipq_put(struct ipq *ipq)
{ {
inet_frag_put(&ipq->q, &ip4_frags); inet_frag_put(&ipq->q);
} }
/* Kill ipq entry. It is not destroyed immediately, /* Kill ipq entry. It is not destroyed immediately,
...@@ -176,7 +176,7 @@ static void ipq_put(struct ipq *ipq) ...@@ -176,7 +176,7 @@ static void ipq_put(struct ipq *ipq)
*/ */
static void ipq_kill(struct ipq *ipq) static void ipq_kill(struct ipq *ipq)
{ {
inet_frag_kill(&ipq->q, &ip4_frags); inet_frag_kill(&ipq->q);
} }
static bool frag_expire_skip_icmp(u32 user) static bool frag_expire_skip_icmp(u32 user)
...@@ -872,20 +872,21 @@ static int __net_init ipv4_frags_init_net(struct net *net) ...@@ -872,20 +872,21 @@ static int __net_init ipv4_frags_init_net(struct net *net)
net->ipv4.frags.timeout = IP_FRAG_TIME; net->ipv4.frags.timeout = IP_FRAG_TIME;
net->ipv4.frags.max_dist = 64; net->ipv4.frags.max_dist = 64;
net->ipv4.frags.f = &ip4_frags;
res = inet_frags_init_net(&net->ipv4.frags); res = inet_frags_init_net(&net->ipv4.frags);
if (res < 0) if (res < 0)
return res; return res;
res = ip4_frags_ns_ctl_register(net); res = ip4_frags_ns_ctl_register(net);
if (res < 0) if (res < 0)
inet_frags_exit_net(&net->ipv4.frags, &ip4_frags); inet_frags_exit_net(&net->ipv4.frags);
return res; return res;
} }
static void __net_exit ipv4_frags_exit_net(struct net *net) static void __net_exit ipv4_frags_exit_net(struct net *net)
{ {
ip4_frags_ns_ctl_unregister(net); ip4_frags_ns_ctl_unregister(net);
inet_frags_exit_net(&net->ipv4.frags, &ip4_frags); inet_frags_exit_net(&net->ipv4.frags);
} }
static struct pernet_operations ip4_frags_ops = { static struct pernet_operations ip4_frags_ops = {
......
...@@ -178,7 +178,7 @@ static void nf_ct_frag6_expire(struct timer_list *t) ...@@ -178,7 +178,7 @@ static void nf_ct_frag6_expire(struct timer_list *t)
fq = container_of(frag, struct frag_queue, q); fq = container_of(frag, struct frag_queue, q);
net = container_of(fq->q.net, struct net, nf_frag.frags); net = container_of(fq->q.net, struct net, nf_frag.frags);
ip6_expire_frag_queue(net, fq, &nf_frags); ip6_expire_frag_queue(net, fq);
} }
/* Creation primitives. */ /* Creation primitives. */
...@@ -264,7 +264,7 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb, ...@@ -264,7 +264,7 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
* this case. -DaveM * this case. -DaveM
*/ */
pr_debug("end of fragment not rounded to 8 bytes.\n"); pr_debug("end of fragment not rounded to 8 bytes.\n");
inet_frag_kill(&fq->q, &nf_frags); inet_frag_kill(&fq->q);
return -EPROTO; return -EPROTO;
} }
if (end > fq->q.len) { if (end > fq->q.len) {
...@@ -357,7 +357,7 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb, ...@@ -357,7 +357,7 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
return 0; return 0;
discard_fq: discard_fq:
inet_frag_kill(&fq->q, &nf_frags); inet_frag_kill(&fq->q);
err: err:
return -EINVAL; return -EINVAL;
} }
...@@ -379,7 +379,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *prev, struct net_devic ...@@ -379,7 +379,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *prev, struct net_devic
int payload_len; int payload_len;
u8 ecn; u8 ecn;
inet_frag_kill(&fq->q, &nf_frags); inet_frag_kill(&fq->q);
WARN_ON(head == NULL); WARN_ON(head == NULL);
WARN_ON(NFCT_FRAG6_CB(head)->offset != 0); WARN_ON(NFCT_FRAG6_CB(head)->offset != 0);
...@@ -622,7 +622,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) ...@@ -622,7 +622,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
out_unlock: out_unlock:
spin_unlock_bh(&fq->q.lock); spin_unlock_bh(&fq->q.lock);
inet_frag_put(&fq->q, &nf_frags); inet_frag_put(&fq->q);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(nf_ct_frag6_gather); EXPORT_SYMBOL_GPL(nf_ct_frag6_gather);
...@@ -634,19 +634,21 @@ static int nf_ct_net_init(struct net *net) ...@@ -634,19 +634,21 @@ static int nf_ct_net_init(struct net *net)
net->nf_frag.frags.high_thresh = IPV6_FRAG_HIGH_THRESH; net->nf_frag.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
net->nf_frag.frags.low_thresh = IPV6_FRAG_LOW_THRESH; net->nf_frag.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
net->nf_frag.frags.timeout = IPV6_FRAG_TIMEOUT; net->nf_frag.frags.timeout = IPV6_FRAG_TIMEOUT;
net->nf_frag.frags.f = &nf_frags;
res = inet_frags_init_net(&net->nf_frag.frags); res = inet_frags_init_net(&net->nf_frag.frags);
if (res < 0) if (res < 0)
return res; return res;
res = nf_ct_frag6_sysctl_register(net); res = nf_ct_frag6_sysctl_register(net);
if (res < 0) if (res < 0)
inet_frags_exit_net(&net->nf_frag.frags, &nf_frags); inet_frags_exit_net(&net->nf_frag.frags);
return res; return res;
} }
static void nf_ct_net_exit(struct net *net) static void nf_ct_net_exit(struct net *net)
{ {
nf_ct_frags6_sysctl_unregister(net); nf_ct_frags6_sysctl_unregister(net);
inet_frags_exit_net(&net->nf_frag.frags, &nf_frags); inet_frags_exit_net(&net->nf_frag.frags);
} }
static struct pernet_operations nf_ct_net_ops = { static struct pernet_operations nf_ct_net_ops = {
......
...@@ -128,8 +128,7 @@ void ip6_frag_init(struct inet_frag_queue *q, const void *a) ...@@ -128,8 +128,7 @@ void ip6_frag_init(struct inet_frag_queue *q, const void *a)
} }
EXPORT_SYMBOL(ip6_frag_init); EXPORT_SYMBOL(ip6_frag_init);
void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq)
struct inet_frags *frags)
{ {
struct net_device *dev = NULL; struct net_device *dev = NULL;
...@@ -138,7 +137,7 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, ...@@ -138,7 +137,7 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
if (fq->q.flags & INET_FRAG_COMPLETE) if (fq->q.flags & INET_FRAG_COMPLETE)
goto out; goto out;
inet_frag_kill(&fq->q, frags); inet_frag_kill(&fq->q);
rcu_read_lock(); rcu_read_lock();
dev = dev_get_by_index_rcu(net, fq->iif); dev = dev_get_by_index_rcu(net, fq->iif);
...@@ -166,7 +165,7 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, ...@@ -166,7 +165,7 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
rcu_read_unlock(); rcu_read_unlock();
out: out:
spin_unlock(&fq->q.lock); spin_unlock(&fq->q.lock);
inet_frag_put(&fq->q, frags); inet_frag_put(&fq->q);
} }
EXPORT_SYMBOL(ip6_expire_frag_queue); EXPORT_SYMBOL(ip6_expire_frag_queue);
...@@ -179,7 +178,7 @@ static void ip6_frag_expire(struct timer_list *t) ...@@ -179,7 +178,7 @@ static void ip6_frag_expire(struct timer_list *t)
fq = container_of(frag, struct frag_queue, q); fq = container_of(frag, struct frag_queue, q);
net = container_of(fq->q.net, struct net, ipv6.frags); net = container_of(fq->q.net, struct net, ipv6.frags);
ip6_expire_frag_queue(net, fq, &ip6_frags); ip6_expire_frag_queue(net, fq);
} }
static struct frag_queue * static struct frag_queue *
...@@ -364,7 +363,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, ...@@ -364,7 +363,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
return -1; return -1;
discard_fq: discard_fq:
inet_frag_kill(&fq->q, &ip6_frags); inet_frag_kill(&fq->q);
err: err:
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_REASMFAILS); IPSTATS_MIB_REASMFAILS);
...@@ -391,7 +390,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, ...@@ -391,7 +390,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
int sum_truesize; int sum_truesize;
u8 ecn; u8 ecn;
inet_frag_kill(&fq->q, &ip6_frags); inet_frag_kill(&fq->q);
ecn = ip_frag_ecn_table[fq->ecn]; ecn = ip_frag_ecn_table[fq->ecn];
if (unlikely(ecn == 0xff)) if (unlikely(ecn == 0xff))
...@@ -569,7 +568,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) ...@@ -569,7 +568,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff); ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
spin_unlock(&fq->q.lock); spin_unlock(&fq->q.lock);
inet_frag_put(&fq->q, &ip6_frags); inet_frag_put(&fq->q);
return ret; return ret;
} }
...@@ -716,6 +715,7 @@ static int __net_init ipv6_frags_init_net(struct net *net) ...@@ -716,6 +715,7 @@ static int __net_init ipv6_frags_init_net(struct net *net)
net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH; net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH; net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT; net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
net->ipv6.frags.f = &ip6_frags;
res = inet_frags_init_net(&net->ipv6.frags); res = inet_frags_init_net(&net->ipv6.frags);
if (res < 0) if (res < 0)
...@@ -723,14 +723,14 @@ static int __net_init ipv6_frags_init_net(struct net *net) ...@@ -723,14 +723,14 @@ static int __net_init ipv6_frags_init_net(struct net *net)
res = ip6_frags_ns_sysctl_register(net); res = ip6_frags_ns_sysctl_register(net);
if (res < 0) if (res < 0)
inet_frags_exit_net(&net->ipv6.frags, &ip6_frags); inet_frags_exit_net(&net->ipv6.frags);
return res; return res;
} }
static void __net_exit ipv6_frags_exit_net(struct net *net) static void __net_exit ipv6_frags_exit_net(struct net *net)
{ {
ip6_frags_ns_sysctl_unregister(net); ip6_frags_ns_sysctl_unregister(net);
inet_frags_exit_net(&net->ipv6.frags, &ip6_frags); inet_frags_exit_net(&net->ipv6.frags);
} }
static struct pernet_operations ip6_frags_ops = { static struct pernet_operations ip6_frags_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment