aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/Kbuild1
-rw-r--r--net/core/dev.c10
-rw-r--r--net/core/net-sysfs.c8
-rw-r--r--net/core/skbuff.c5
-rw-r--r--net/ipv4/icmp.c5
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c2
-rw-r--r--net/ipv4/tcp_input.c3
-rw-r--r--net/key/af_key.c2
-rw-r--r--net/netfilter/nf_conntrack_core.c8
-rw-r--r--net/rfkill/rfkill.c2
-rw-r--r--net/xfrm/xfrm_algo.c140
11 files changed, 103 insertions, 83 deletions
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index bcd01f269f60..e1013156c25e 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -239,6 +239,7 @@ unifdef-y += ipc.h
239unifdef-y += ipmi.h 239unifdef-y += ipmi.h
240unifdef-y += ipv6.h 240unifdef-y += ipv6.h
241unifdef-y += ipv6_route.h 241unifdef-y += ipv6_route.h
242unifdef-y += ip6_tunnel.h
242unifdef-y += isdn.h 243unifdef-y += isdn.h
243unifdef-y += isdnif.h 244unifdef-y += isdnif.h
244unifdef-y += isdn_divertif.h 245unifdef-y += isdn_divertif.h
diff --git a/net/core/dev.c b/net/core/dev.c
index f2b61111e26d..5a7f20f78574 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3314,7 +3314,6 @@ void netdev_run_todo(void)
3314 continue; 3314 continue;
3315 } 3315 }
3316 3316
3317 netdev_unregister_sysfs(dev);
3318 dev->reg_state = NETREG_UNREGISTERED; 3317 dev->reg_state = NETREG_UNREGISTERED;
3319 3318
3320 netdev_wait_allrefs(dev); 3319 netdev_wait_allrefs(dev);
@@ -3325,11 +3324,11 @@ void netdev_run_todo(void)
3325 BUG_TRAP(!dev->ip6_ptr); 3324 BUG_TRAP(!dev->ip6_ptr);
3326 BUG_TRAP(!dev->dn_ptr); 3325 BUG_TRAP(!dev->dn_ptr);
3327 3326
3328 /* It must be the very last action,
3329 * after this 'dev' may point to freed up memory.
3330 */
3331 if (dev->destructor) 3327 if (dev->destructor)
3332 dev->destructor(dev); 3328 dev->destructor(dev);
3329
3330 /* Free network device */
3331 kobject_put(&dev->dev.kobj);
3333 } 3332 }
3334 3333
3335out: 3334out:
@@ -3480,6 +3479,9 @@ void unregister_netdevice(struct net_device *dev)
3480 /* Notifier chain MUST detach us from master device. */ 3479 /* Notifier chain MUST detach us from master device. */
3481 BUG_TRAP(!dev->master); 3480 BUG_TRAP(!dev->master);
3482 3481
3482 /* Remove entries from sysfs */
3483 netdev_unregister_sysfs(dev);
3484
3483 /* Finish processing unregister after unlock */ 3485 /* Finish processing unregister after unlock */
3484 net_set_todo(dev); 3486 net_set_todo(dev);
3485 3487
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index b21307b15b82..5c19b0646d7a 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -456,9 +456,15 @@ static struct class net_class = {
456#endif 456#endif
457}; 457};
458 458
459/* Delete sysfs entries but hold kobject reference until after all
460 * netdev references are gone.
461 */
459void netdev_unregister_sysfs(struct net_device * net) 462void netdev_unregister_sysfs(struct net_device * net)
460{ 463{
461 device_del(&(net->dev)); 464 struct device *dev = &(net->dev);
465
466 kobject_get(&dev->kobj);
467 device_del(dev);
462} 468}
463 469
464/* Create sysfs entries for network device. */ 470/* Create sysfs entries for network device. */
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 142257307fa2..7c6a34e21eee 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -644,11 +644,10 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
644 644
645 /* Copy only real data... and, alas, header. This should be 645 /* Copy only real data... and, alas, header. This should be
646 * optimized for the cases when header is void. */ 646 * optimized for the cases when header is void. */
647 memcpy(data + nhead, skb->head,
648#ifdef NET_SKBUFF_DATA_USES_OFFSET 647#ifdef NET_SKBUFF_DATA_USES_OFFSET
649 skb->tail); 648 memcpy(data + nhead, skb->head, skb->tail);
650#else 649#else
651 skb->tail - skb->head); 650 memcpy(data + nhead, skb->head, skb->tail - skb->head);
652#endif 651#endif
653 memcpy(data + size, skb_end_pointer(skb), 652 memcpy(data + size, skb_end_pointer(skb),
654 sizeof(struct skb_shared_info)); 653 sizeof(struct skb_shared_info));
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index d38cbba92a4d..e238b17f554c 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -514,7 +514,10 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
514 514
515 saddr = iph->daddr; 515 saddr = iph->daddr;
516 if (!(rt->rt_flags & RTCF_LOCAL)) { 516 if (!(rt->rt_flags & RTCF_LOCAL)) {
517 if (sysctl_icmp_errors_use_inbound_ifaddr) 517 /* This is broken, skb_in->dev points to the outgoing device
518 * after the packet passes through ip_output().
519 */
520 if (skb_in->dev && sysctl_icmp_errors_use_inbound_ifaddr)
518 saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK); 521 saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
519 else 522 else
520 saddr = 0; 523 saddr = 0;
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 0654eaae70c9..fd62a41d69cc 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -154,12 +154,10 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
154 const struct net_device *out, 154 const struct net_device *out,
155 int (*okfn)(struct sk_buff *)) 155 int (*okfn)(struct sk_buff *))
156{ 156{
157#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
158 /* Previously seen (loopback)? Ignore. Do this before 157 /* Previously seen (loopback)? Ignore. Do this before
159 fragment check. */ 158 fragment check. */
160 if ((*pskb)->nfct) 159 if ((*pskb)->nfct)
161 return NF_ACCEPT; 160 return NF_ACCEPT;
162#endif
163 161
164 /* Gather fragments. */ 162 /* Gather fragments. */
165 if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) { 163 if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 7641b2761a14..38cb25b48bf3 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1501,6 +1501,8 @@ void tcp_enter_loss(struct sock *sk, int how)
1501 tcp_set_ca_state(sk, TCP_CA_Loss); 1501 tcp_set_ca_state(sk, TCP_CA_Loss);
1502 tp->high_seq = tp->snd_nxt; 1502 tp->high_seq = tp->snd_nxt;
1503 TCP_ECN_queue_cwr(tp); 1503 TCP_ECN_queue_cwr(tp);
1504 /* Abort FRTO algorithm if one is in progress */
1505 tp->frto_counter = 0;
1504 1506
1505 clear_all_retrans_hints(tp); 1507 clear_all_retrans_hints(tp);
1506} 1508}
@@ -2608,6 +2610,7 @@ static void tcp_conservative_spur_to_response(struct tcp_sock *tp)
2608{ 2610{
2609 tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); 2611 tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
2610 tp->snd_cwnd_cnt = 0; 2612 tp->snd_cwnd_cnt = 0;
2613 TCP_ECN_queue_cwr(tp);
2611 tcp_moderate_cwnd(tp); 2614 tcp_moderate_cwnd(tp);
2612} 2615}
2613 2616
diff --git a/net/key/af_key.c b/net/key/af_key.c
index a99444142dc7..d302ddae580c 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1448,8 +1448,6 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
1448 int err; 1448 int err;
1449 struct km_event c; 1449 struct km_event c;
1450 1450
1451 xfrm_probe_algs();
1452
1453 x = pfkey_msg2xfrm_state(hdr, ext_hdrs); 1451 x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
1454 if (IS_ERR(x)) 1452 if (IS_ERR(x))
1455 return PTR_ERR(x); 1453 return PTR_ERR(x);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index e8b5c2d7db62..483e927a9ca4 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -298,7 +298,6 @@ static void
298destroy_conntrack(struct nf_conntrack *nfct) 298destroy_conntrack(struct nf_conntrack *nfct)
299{ 299{
300 struct nf_conn *ct = (struct nf_conn *)nfct; 300 struct nf_conn *ct = (struct nf_conn *)nfct;
301 struct nf_conn_help *help = nfct_help(ct);
302 struct nf_conntrack_l4proto *l4proto; 301 struct nf_conntrack_l4proto *l4proto;
303 typeof(nf_conntrack_destroyed) destroyed; 302 typeof(nf_conntrack_destroyed) destroyed;
304 303
@@ -309,9 +308,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
309 nf_conntrack_event(IPCT_DESTROY, ct); 308 nf_conntrack_event(IPCT_DESTROY, ct);
310 set_bit(IPS_DYING_BIT, &ct->status); 309 set_bit(IPS_DYING_BIT, &ct->status);
311 310
312 if (help && help->helper && help->helper->destroy)
313 help->helper->destroy(ct);
314
315 /* To make sure we don't get any weird locking issues here: 311 /* To make sure we don't get any weird locking issues here:
316 * destroy_conntrack() MUST NOT be called with a write lock 312 * destroy_conntrack() MUST NOT be called with a write lock
317 * to nf_conntrack_lock!!! -HW */ 313 * to nf_conntrack_lock!!! -HW */
@@ -353,6 +349,10 @@ destroy_conntrack(struct nf_conntrack *nfct)
353static void death_by_timeout(unsigned long ul_conntrack) 349static void death_by_timeout(unsigned long ul_conntrack)
354{ 350{
355 struct nf_conn *ct = (void *)ul_conntrack; 351 struct nf_conn *ct = (void *)ul_conntrack;
352 struct nf_conn_help *help = nfct_help(ct);
353
354 if (help && help->helper && help->helper->destroy)
355 help->helper->destroy(ct);
356 356
357 write_lock_bh(&nf_conntrack_lock); 357 write_lock_bh(&nf_conntrack_lock);
358 /* Inside lock so preempt is disabled on module removal path. 358 /* Inside lock so preempt is disabled on module removal path.
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index a973603e3880..f3986d498b40 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -296,7 +296,7 @@ struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type)
296 struct device *dev; 296 struct device *dev;
297 297
298 rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL); 298 rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
299 if (rfkill) 299 if (!rfkill)
300 return NULL; 300 return NULL;
301 301
302 mutex_init(&rfkill->mutex); 302 mutex_init(&rfkill->mutex);
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 6249a9405bb8..8a72def25a34 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -347,67 +347,44 @@ static inline int calg_entries(void)
347 return ARRAY_SIZE(calg_list); 347 return ARRAY_SIZE(calg_list);
348} 348}
349 349
350/* Todo: generic iterators */ 350struct xfrm_algo_list {
351struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) 351 struct xfrm_algo_desc *algs;
352{ 352 int entries;
353 int i; 353 u32 type;
354 354 u32 mask;
355 for (i = 0; i < aalg_entries(); i++) { 355};
356 if (aalg_list[i].desc.sadb_alg_id == alg_id) {
357 if (aalg_list[i].available)
358 return &aalg_list[i];
359 else
360 break;
361 }
362 }
363 return NULL;
364}
365EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
366
367struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
368{
369 int i;
370 356
371 for (i = 0; i < ealg_entries(); i++) { 357static const struct xfrm_algo_list xfrm_aalg_list = {
372 if (ealg_list[i].desc.sadb_alg_id == alg_id) { 358 .algs = aalg_list,
373 if (ealg_list[i].available) 359 .entries = ARRAY_SIZE(aalg_list),
374 return &ealg_list[i]; 360 .type = CRYPTO_ALG_TYPE_HASH,
375 else 361 .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
376 break; 362};
377 }
378 }
379 return NULL;
380}
381EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
382 363
383struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) 364static const struct xfrm_algo_list xfrm_ealg_list = {
384{ 365 .algs = ealg_list,
385 int i; 366 .entries = ARRAY_SIZE(ealg_list),
367 .type = CRYPTO_ALG_TYPE_BLKCIPHER,
368 .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
369};
386 370
387 for (i = 0; i < calg_entries(); i++) { 371static const struct xfrm_algo_list xfrm_calg_list = {
388 if (calg_list[i].desc.sadb_alg_id == alg_id) { 372 .algs = calg_list,
389 if (calg_list[i].available) 373 .entries = ARRAY_SIZE(calg_list),
390 return &calg_list[i]; 374 .type = CRYPTO_ALG_TYPE_COMPRESS,
391 else 375 .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
392 break; 376};
393 }
394 }
395 return NULL;
396}
397EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
398 377
399static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, 378static struct xfrm_algo_desc *xfrm_find_algo(
400 int entries, u32 type, u32 mask, 379 const struct xfrm_algo_list *algo_list,
401 char *name, int probe) 380 int match(const struct xfrm_algo_desc *entry, const void *data),
381 const void *data, int probe)
402{ 382{
383 struct xfrm_algo_desc *list = algo_list->algs;
403 int i, status; 384 int i, status;
404 385
405 if (!name) 386 for (i = 0; i < algo_list->entries; i++) {
406 return NULL; 387 if (!match(list + i, data))
407
408 for (i = 0; i < entries; i++) {
409 if (strcmp(name, list[i].name) &&
410 (!list[i].compat || strcmp(name, list[i].compat)))
411 continue; 388 continue;
412 389
413 if (list[i].available) 390 if (list[i].available)
@@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
416 if (!probe) 393 if (!probe)
417 break; 394 break;
418 395
419 status = crypto_has_alg(list[i].name, type, 396 status = crypto_has_alg(list[i].name, algo_list->type,
420 mask | CRYPTO_ALG_ASYNC); 397 algo_list->mask);
421 if (!status) 398 if (!status)
422 break; 399 break;
423 400
@@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
427 return NULL; 404 return NULL;
428} 405}
429 406
407static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
408 const void *data)
409{
410 return entry->desc.sadb_alg_id == (int)data;
411}
412
413struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
414{
415 return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
416 (void *)alg_id, 1);
417}
418EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
419
420struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
421{
422 return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
423 (void *)alg_id, 1);
424}
425EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
426
427struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
428{
429 return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
430 (void *)alg_id, 1);
431}
432EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
433
434static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
435 const void *data)
436{
437 const char *name = data;
438
439 return name && (!strcmp(name, entry->name) ||
440 (entry->compat && !strcmp(name, entry->compat)));
441}
442
430struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) 443struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
431{ 444{
432 return xfrm_get_byname(aalg_list, aalg_entries(), 445 return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
433 CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK, 446 probe);
434 name, probe);
435} 447}
436EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); 448EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
437 449
438struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) 450struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
439{ 451{
440 return xfrm_get_byname(ealg_list, ealg_entries(), 452 return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
441 CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK, 453 probe);
442 name, probe);
443} 454}
444EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); 455EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
445 456
446struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) 457struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
447{ 458{
448 return xfrm_get_byname(calg_list, calg_entries(), 459 return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
449 CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK, 460 probe);
450 name, probe);
451} 461}
452EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); 462EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
453 463