diff options
Diffstat (limited to 'net/ipv4/ip_fragment.c')
| -rw-r--r-- | net/ipv4/ip_fragment.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2a8adda15e11..da734c439179 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -304,13 +304,17 @@ out: | |||
| 304 | 304 | ||
| 305 | /* Creation primitives. */ | 305 | /* Creation primitives. */ |
| 306 | 306 | ||
| 307 | static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) | 307 | static struct ipq *ip_frag_intern(struct ipq *qp_in) |
| 308 | { | 308 | { |
| 309 | struct ipq *qp; | 309 | struct ipq *qp; |
| 310 | #ifdef CONFIG_SMP | 310 | #ifdef CONFIG_SMP |
| 311 | struct hlist_node *n; | 311 | struct hlist_node *n; |
| 312 | #endif | 312 | #endif |
| 313 | unsigned int hash; | ||
| 314 | |||
| 313 | write_lock(&ipfrag_lock); | 315 | write_lock(&ipfrag_lock); |
| 316 | hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr, | ||
| 317 | qp_in->protocol); | ||
| 314 | #ifdef CONFIG_SMP | 318 | #ifdef CONFIG_SMP |
| 315 | /* With SMP race we have to recheck hash table, because | 319 | /* With SMP race we have to recheck hash table, because |
| 316 | * such entry could be created on other cpu, while we | 320 | * such entry could be created on other cpu, while we |
| @@ -345,7 +349,7 @@ static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) | |||
| 345 | } | 349 | } |
| 346 | 350 | ||
| 347 | /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ | 351 | /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ |
| 348 | static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) | 352 | static struct ipq *ip_frag_create(struct iphdr *iph, u32 user) |
| 349 | { | 353 | { |
| 350 | struct ipq *qp; | 354 | struct ipq *qp; |
| 351 | 355 | ||
| @@ -371,7 +375,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) | |||
| 371 | spin_lock_init(&qp->lock); | 375 | spin_lock_init(&qp->lock); |
| 372 | atomic_set(&qp->refcnt, 1); | 376 | atomic_set(&qp->refcnt, 1); |
| 373 | 377 | ||
| 374 | return ip_frag_intern(hash, qp); | 378 | return ip_frag_intern(qp); |
| 375 | 379 | ||
| 376 | out_nomem: | 380 | out_nomem: |
| 377 | LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); | 381 | LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); |
| @@ -387,11 +391,12 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | |||
| 387 | __u32 saddr = iph->saddr; | 391 | __u32 saddr = iph->saddr; |
| 388 | __u32 daddr = iph->daddr; | 392 | __u32 daddr = iph->daddr; |
| 389 | __u8 protocol = iph->protocol; | 393 | __u8 protocol = iph->protocol; |
| 390 | unsigned int hash = ipqhashfn(id, saddr, daddr, protocol); | 394 | unsigned int hash; |
| 391 | struct ipq *qp; | 395 | struct ipq *qp; |
| 392 | struct hlist_node *n; | 396 | struct hlist_node *n; |
| 393 | 397 | ||
| 394 | read_lock(&ipfrag_lock); | 398 | read_lock(&ipfrag_lock); |
| 399 | hash = ipqhashfn(id, saddr, daddr, protocol); | ||
| 395 | hlist_for_each_entry(qp, n, &ipq_hash[hash], list) { | 400 | hlist_for_each_entry(qp, n, &ipq_hash[hash], list) { |
| 396 | if(qp->id == id && | 401 | if(qp->id == id && |
| 397 | qp->saddr == saddr && | 402 | qp->saddr == saddr && |
| @@ -405,7 +410,7 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | |||
| 405 | } | 410 | } |
| 406 | read_unlock(&ipfrag_lock); | 411 | read_unlock(&ipfrag_lock); |
| 407 | 412 | ||
| 408 | return ip_frag_create(hash, iph, user); | 413 | return ip_frag_create(iph, user); |
| 409 | } | 414 | } |
| 410 | 415 | ||
| 411 | /* Is the fragment too far ahead to be part of ipq? */ | 416 | /* Is the fragment too far ahead to be part of ipq? */ |
