diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2007-10-17 19:46:47 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-10-17 19:46:47 -0700 |
commit | c6fda282294da882f8d8cc4c513940277dd380f5 (patch) | |
tree | 29ef5fbc59320851c8db28e7f2c0a8c3fd85c231 /net/ipv4 | |
parent | e521db9d790aaa60ae8920e21cb7faedc280fc36 (diff) |
[INET]: Consolidate xxx_frag_create()
This one uses the xxx_frag_intern() and xxx_frag_alloc()
routines, which are already consolidated, so remove them
from protocol code (as promised).
The ->constructor callback is used to init the rest of
the frag queue and it is the same for netfilter and ipv6.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/inet_fragment.c | 20 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 54 |
2 files changed, 44 insertions, 30 deletions
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 57e15fa307d..b531f803cda 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -173,7 +173,7 @@ int inet_frag_evictor(struct inet_frags *f) } EXPORT_SYMBOL(inet_frag_evictor); -struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, +static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, struct inet_frags *f, unsigned int hash) { struct inet_frag_queue *qp; @@ -208,9 +208,8 @@ struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, write_unlock(&f->lock); return qp; } -EXPORT_SYMBOL(inet_frag_intern); -struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f) +static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg) { struct inet_frag_queue *q; @@ -218,6 +217,7 @@ struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f) if (q == NULL) return NULL; + f->constructor(q, arg); atomic_add(f->qsize, &f->mem); setup_timer(&q->timer, f->frag_expire, (unsigned long)q); spin_lock_init(&q->lock); @@ -225,4 +225,16 @@ struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f) return q; } -EXPORT_SYMBOL(inet_frag_alloc); + +struct inet_frag_queue *inet_frag_create(struct inet_frags *f, void *arg, + unsigned int hash) +{ + struct inet_frag_queue *q; + + q = inet_frag_alloc(f, arg); + if (q == NULL) + return NULL; + + return inet_frag_intern(q, f, hash); +} +EXPORT_SYMBOL(inet_frag_create); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index fc0d530df52..0d6cff1de5a 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -108,6 +108,11 @@ int ip_frag_mem(void) static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, struct net_device *dev); +struct ip4_create_arg { + struct iphdr *iph; + u32 user; +}; + static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot) { return jhash_3words((__force u32)id << 16 | prot, @@ -146,6 +151,20 @@ static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work) kfree_skb(skb); } +static void ip4_frag_init(struct inet_frag_queue *q, void *a) +{ + struct ipq *qp = container_of(q, struct ipq, q); + struct ip4_create_arg *arg = a; + + qp->protocol = arg->iph->protocol; + qp->id = arg->iph->id; + qp->saddr = arg->iph->saddr; + qp->daddr = arg->iph->daddr; + qp->user = arg->user; + qp->peer = sysctl_ipfrag_max_dist ? + inet_getpeer(arg->iph->saddr, 1) : NULL; +} + static __inline__ void ip4_frag_free(struct inet_frag_queue *q) { struct ipq *qp; @@ -156,14 +175,6 @@ static __inline__ void ip4_frag_free(struct inet_frag_queue *q) kfree(qp); } -static __inline__ struct ipq *frag_alloc_queue(void) -{ - struct inet_frag_queue *q; - - q = inet_frag_alloc(&ip4_frags); - return q ? container_of(q, struct ipq, q) : NULL; -} - /* Destruction primitives. */ @@ -226,30 +237,20 @@ out: /* Creation primitives. */ -static struct ipq *ip_frag_intern(struct ipq *qp_in, unsigned int hash) -{ - struct inet_frag_queue *q; - - q = inet_frag_intern(&qp_in->q, &ip4_frags, hash); - return container_of(q, struct ipq, q); -} - /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h) { - struct ipq *qp; + struct inet_frag_queue *q; + struct ip4_create_arg arg; - if ((qp = frag_alloc_queue()) == NULL) - goto out_nomem; + arg.iph = iph; + arg.user = user; - qp->protocol = iph->protocol; - qp->id = iph->id; - qp->saddr = iph->saddr; - qp->daddr = iph->daddr; - qp->user = user; - qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL; + q = inet_frag_create(&ip4_frags, &arg, h); + if (q == NULL) + goto out_nomem; - return ip_frag_intern(qp, h); + return container_of(q, struct ipq, q); out_nomem: LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); @@ -642,6 +643,7 @@ void __init ipfrag_init(void) { ip4_frags.ctl = &ip4_frags_ctl; ip4_frags.hashfn = ip4_hashfn; + ip4_frags.constructor = ip4_frag_init; ip4_frags.destructor = ip4_frag_free; ip4_frags.skb_free = NULL; ip4_frags.qsize = sizeof(struct ipq); |