X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=net%2Fipv4%2Fip_fragment.c;h=7f68e27eb4ea894c21f36e2d99f7f9423f1ba657;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=df083ded1109392721501a958087e9e652748e6f;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index df083ded1..7f68e27eb 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -73,6 +73,7 @@ struct ipfrag_skb_cb struct ipq { struct ipq *next; /* linked list pointers */ struct list_head lru_list; /* lru list member */ + u32 user; u32 saddr; u32 daddr; u16 id; @@ -99,7 +100,7 @@ struct ipq { /* Per-bucket lock is easy to add now. */ static struct ipq *ipq_hash[IPQ_HASHSZ]; -static rwlock_t ipfrag_lock = RW_LOCK_UNLOCKED; +static DEFINE_RWLOCK(ipfrag_lock); static u32 ipfrag_hash_rnd; static LIST_HEAD(ipq_lru_list); int ip_frag_nqueues = 0; @@ -243,13 +244,13 @@ static void ipq_kill(struct ipq *ipq) /* Memory limiting on fragments. Evictor trashes the oldest * fragment queue until we are back under the threshold. */ -static void __ip_evictor(int threshold) +static void ip_evictor(void) { struct ipq *qp; struct list_head *tmp; int work; - work = atomic_read(&ip_frag_mem) - threshold; + work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh; if (work <= 0) return; @@ -274,11 +275,6 @@ static void __ip_evictor(int threshold) } } -static inline void ip_evictor(void) -{ - __ip_evictor(sysctl_ipfrag_low_thresh); -} - /* * Oops, a fragment queue timed out. Kill it and send an ICMP reply. */ @@ -325,7 +321,8 @@ static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) if(qp->id == qp_in->id && qp->saddr == qp_in->saddr && qp->daddr == qp_in->daddr && - qp->protocol == qp_in->protocol) { + qp->protocol == qp_in->protocol && + qp->user == qp_in->user) { atomic_inc(&qp->refcnt); write_unlock(&ipfrag_lock); qp_in->last_in |= COMPLETE; @@ -352,7 +349,7 @@ static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) } /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ -static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph) +static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) { struct ipq *qp; @@ -364,6 +361,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph) qp->id = iph->id; qp->saddr = iph->saddr; qp->daddr = iph->daddr; + qp->user = user; qp->len = 0; qp->meat = 0; qp->fragments = NULL; @@ -373,7 +371,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph) init_timer(&qp->timer); qp->timer.data = (unsigned long) qp; /* pointer to queue */ qp->timer.function = ip_expire; /* expire function */ - qp->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&qp->lock); atomic_set(&qp->refcnt, 1); return ip_frag_intern(hash, qp); @@ -386,7 +384,7 @@ out_nomem: /* Find the correct entry in the "incomplete datagrams" queue for * this IP datagram, and create new one, if nothing is found. */ -static inline struct ipq *ip_find(struct iphdr *iph) +static inline struct ipq *ip_find(struct iphdr *iph, u32 user) { __u16 id = iph->id; __u32 saddr = iph->saddr; @@ -400,7 +398,8 @@ static inline struct ipq *ip_find(struct iphdr *iph) if(qp->id == id && qp->saddr == saddr && qp->daddr == daddr && - qp->protocol == protocol) { + qp->protocol == protocol && + qp->user == user) { atomic_inc(&qp->refcnt); read_unlock(&ipfrag_lock); return qp; @@ -408,7 +407,7 @@ static inline struct ipq *ip_find(struct iphdr *iph) } read_unlock(&ipfrag_lock); - return ip_frag_create(hash, iph); + return ip_frag_create(hash, iph, user); } /* Add new segment to existing queue. */ @@ -642,7 +641,7 @@ out_fail: } /* Process an incoming IP datagram fragment. */ -struct sk_buff *ip_defrag(struct sk_buff *skb) +struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user) { struct iphdr *iph = skb->nh.iph; struct ipq *qp; @@ -657,7 +656,7 @@ struct sk_buff *ip_defrag(struct sk_buff *skb) dev = skb->dev; /* Lookup (or create) queue header */ - if ((qp = ip_find(iph)) != NULL) { + if ((qp = ip_find(iph, user)) != NULL) { struct sk_buff *ret = NULL; spin_lock(&qp->lock); @@ -689,10 +688,4 @@ void ipfrag_init(void) add_timer(&ipfrag_secret_timer); } -void ipfrag_flush(void) -{ - __ip_evictor(0); -} - EXPORT_SYMBOL(ip_defrag); -EXPORT_SYMBOL(ipfrag_flush);