aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_fragment.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_fragment.c')
-rw-r--r--net/ipv4/ip_fragment.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index fc0d530df522..0d6cff1de5a3 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -108,6 +108,11 @@ int ip_frag_mem(void)
108static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, 108static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
109 struct net_device *dev); 109 struct net_device *dev);
110 110
111struct ip4_create_arg {
112 struct iphdr *iph;
113 u32 user;
114};
115
111static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot) 116static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
112{ 117{
113 return jhash_3words((__force u32)id << 16 | prot, 118 return jhash_3words((__force u32)id << 16 | prot,
@@ -146,6 +151,20 @@ static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
146 kfree_skb(skb); 151 kfree_skb(skb);
147} 152}
148 153
154static void ip4_frag_init(struct inet_frag_queue *q, void *a)
155{
156 struct ipq *qp = container_of(q, struct ipq, q);
157 struct ip4_create_arg *arg = a;
158
159 qp->protocol = arg->iph->protocol;
160 qp->id = arg->iph->id;
161 qp->saddr = arg->iph->saddr;
162 qp->daddr = arg->iph->daddr;
163 qp->user = arg->user;
164 qp->peer = sysctl_ipfrag_max_dist ?
165 inet_getpeer(arg->iph->saddr, 1) : NULL;
166}
167
149static __inline__ void ip4_frag_free(struct inet_frag_queue *q) 168static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
150{ 169{
151 struct ipq *qp; 170 struct ipq *qp;
@@ -156,14 +175,6 @@ static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
156 kfree(qp); 175 kfree(qp);
157} 176}
158 177
159static __inline__ struct ipq *frag_alloc_queue(void)
160{
161 struct inet_frag_queue *q;
162
163 q = inet_frag_alloc(&ip4_frags);
164 return q ? container_of(q, struct ipq, q) : NULL;
165}
166
167 178
168/* Destruction primitives. */ 179/* Destruction primitives. */
169 180
@@ -226,30 +237,20 @@ out:
226 237
227/* Creation primitives. */ 238/* Creation primitives. */
228 239
229static struct ipq *ip_frag_intern(struct ipq *qp_in, unsigned int hash)
230{
231 struct inet_frag_queue *q;
232
233 q = inet_frag_intern(&qp_in->q, &ip4_frags, hash);
234 return container_of(q, struct ipq, q);
235}
236
237/* Add an entry to the 'ipq' queue for a newly received IP datagram. */ 240/* Add an entry to the 'ipq' queue for a newly received IP datagram. */
238static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h) 241static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h)
239{ 242{
240 struct ipq *qp; 243 struct inet_frag_queue *q;
244 struct ip4_create_arg arg;
241 245
242 if ((qp = frag_alloc_queue()) == NULL) 246 arg.iph = iph;
243 goto out_nomem; 247 arg.user = user;
244 248
245 qp->protocol = iph->protocol; 249 q = inet_frag_create(&ip4_frags, &arg, h);
246 qp->id = iph->id; 250 if (q == NULL)
247 qp->saddr = iph->saddr; 251 goto out_nomem;
248 qp->daddr = iph->daddr;
249 qp->user = user;
250 qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
251 252
252 return ip_frag_intern(qp, h); 253 return container_of(q, struct ipq, q);
253 254
254out_nomem: 255out_nomem:
255 LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); 256 LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
@@ -642,6 +643,7 @@ void __init ipfrag_init(void)
642{ 643{
643 ip4_frags.ctl = &ip4_frags_ctl; 644 ip4_frags.ctl = &ip4_frags_ctl;
644 ip4_frags.hashfn = ip4_hashfn; 645 ip4_frags.hashfn = ip4_hashfn;
646 ip4_frags.constructor = ip4_frag_init;
645 ip4_frags.destructor = ip4_frag_free; 647 ip4_frags.destructor = ip4_frag_free;
646 ip4_frags.skb_free = NULL; 648 ip4_frags.skb_free = NULL;
647 ip4_frags.qsize = sizeof(struct ipq); 649 ip4_frags.qsize = sizeof(struct ipq);