diff options
Diffstat (limited to 'net/ipv4/ip_fragment.c')
-rw-r--r-- | net/ipv4/ip_fragment.c | 54 |
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) | |||
108 | static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | 108 | static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, |
109 | struct net_device *dev); | 109 | struct net_device *dev); |
110 | 110 | ||
111 | struct ip4_create_arg { | ||
112 | struct iphdr *iph; | ||
113 | u32 user; | ||
114 | }; | ||
115 | |||
111 | static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot) | 116 | static 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 | ||
154 | static 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 | |||
149 | static __inline__ void ip4_frag_free(struct inet_frag_queue *q) | 168 | static __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 | ||
159 | static __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 | ||
229 | static 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. */ |
238 | static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h) | 241 | static 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 | ||
254 | out_nomem: | 255 | out_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); |