diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-28 09:00:39 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-28 09:00:39 -0400 |
| commit | f7da9cdf45cbbad5029d4858dcbc0134e06084ed (patch) | |
| tree | 27ec1333129f6b324426820429c4cdd32a695133 | |
| parent | 173f8654746c138a08f51a8a0db7747763a896a2 (diff) | |
| parent | 7b9b04fb728ec0b94464ed902f3395aa592c5bcf (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
"Several bug fixes, some to new features appearing in this merge
window, some that have been around for a while.
I have a short list of known problems that need to be sorted out, but
all of them can be solved easily during the run up to 3.6-final.
I'll be offline until Sunday afternoon, but nothing need hold up
3.6-rc1 and the close of the merge window, networking wise, at this
point.
1) Fix interface check in ipv4 TCP early demux, from Eric Dumazet.
2) Fix a long standing bug in TCP DMA to userspace offload that can
hang applications using MSG_TRUNC, from Jiri Kosina.
3) Don't allow TCP_USER_TIMEOUT to be negative, from Hangbin Liu.
4) Don't use GFP_KERNEL under spinlock in kaweth driver, from Dan
Carpenter"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
tcp: perform DMA to userspace only if there is a task waiting for it
Revert "openvswitch: potential NULL deref in sample()"
ipv4: fix TCP early demux
net: fix rtnetlink IFF_PROMISC and IFF_ALLMULTI handling
USB: kaweth.c: use GFP_ATOMIC under spin_lock
tcp: Add TCP_USER_TIMEOUT negative value check
bcma: add missing iounmap on error path
bcma: fix regression in interrupt assignment on mips
mac80211_hwsim: fix possible race condition in usage of info->control.sta & control.vif
| -rw-r--r-- | drivers/bcma/driver_mips.c | 6 | ||||
| -rw-r--r-- | drivers/bcma/scan.c | 15 | ||||
| -rw-r--r-- | drivers/net/usb/kaweth.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 5 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 8 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 5 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 5 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 14 | ||||
| -rw-r--r-- | net/ipv4/tcp_minisocks.c | 1 | ||||
| -rw-r--r-- | net/openvswitch/actions.c | 3 |
10 files changed, 36 insertions, 28 deletions
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index b013b049476d..cc65b45b4368 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c | |||
| @@ -131,7 +131,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) | |||
| 131 | /* backplane irq line is in use, find out who uses | 131 | /* backplane irq line is in use, find out who uses |
| 132 | * it and set user to irq 0 | 132 | * it and set user to irq 0 |
| 133 | */ | 133 | */ |
| 134 | list_for_each_entry_reverse(core, &bus->cores, list) { | 134 | list_for_each_entry(core, &bus->cores, list) { |
| 135 | if ((1 << bcma_core_mips_irqflag(core)) == | 135 | if ((1 << bcma_core_mips_irqflag(core)) == |
| 136 | oldirqflag) { | 136 | oldirqflag) { |
| 137 | bcma_core_mips_set_irq(core, 0); | 137 | bcma_core_mips_set_irq(core, 0); |
| @@ -161,7 +161,7 @@ static void bcma_core_mips_dump_irq(struct bcma_bus *bus) | |||
| 161 | { | 161 | { |
| 162 | struct bcma_device *core; | 162 | struct bcma_device *core; |
| 163 | 163 | ||
| 164 | list_for_each_entry_reverse(core, &bus->cores, list) { | 164 | list_for_each_entry(core, &bus->cores, list) { |
| 165 | bcma_core_mips_print_irq(core, bcma_core_mips_irq(core)); | 165 | bcma_core_mips_print_irq(core, bcma_core_mips_irq(core)); |
| 166 | } | 166 | } |
| 167 | } | 167 | } |
| @@ -224,7 +224,7 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore) | |||
| 224 | mcore->assigned_irqs = 1; | 224 | mcore->assigned_irqs = 1; |
| 225 | 225 | ||
| 226 | /* Assign IRQs to all cores on the bus */ | 226 | /* Assign IRQs to all cores on the bus */ |
| 227 | list_for_each_entry_reverse(core, &bus->cores, list) { | 227 | list_for_each_entry(core, &bus->cores, list) { |
| 228 | int mips_irq; | 228 | int mips_irq; |
| 229 | if (core->irq) | 229 | if (core->irq) |
| 230 | continue; | 230 | continue; |
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index 5672b13d0951..8d0b57164018 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c | |||
| @@ -462,8 +462,10 @@ int bcma_bus_scan(struct bcma_bus *bus) | |||
| 462 | while (eromptr < eromend) { | 462 | while (eromptr < eromend) { |
| 463 | struct bcma_device *other_core; | 463 | struct bcma_device *other_core; |
| 464 | struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL); | 464 | struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL); |
| 465 | if (!core) | 465 | if (!core) { |
| 466 | return -ENOMEM; | 466 | err = -ENOMEM; |
| 467 | goto out; | ||
| 468 | } | ||
| 467 | INIT_LIST_HEAD(&core->list); | 469 | INIT_LIST_HEAD(&core->list); |
| 468 | core->bus = bus; | 470 | core->bus = bus; |
| 469 | 471 | ||
| @@ -478,7 +480,7 @@ int bcma_bus_scan(struct bcma_bus *bus) | |||
| 478 | } else if (err == -ESPIPE) { | 480 | } else if (err == -ESPIPE) { |
| 479 | break; | 481 | break; |
| 480 | } | 482 | } |
| 481 | return err; | 483 | goto out; |
| 482 | } | 484 | } |
| 483 | 485 | ||
| 484 | core->core_index = core_num++; | 486 | core->core_index = core_num++; |
| @@ -494,10 +496,12 @@ int bcma_bus_scan(struct bcma_bus *bus) | |||
| 494 | list_add_tail(&core->list, &bus->cores); | 496 | list_add_tail(&core->list, &bus->cores); |
| 495 | } | 497 | } |
| 496 | 498 | ||
| 499 | err = 0; | ||
| 500 | out: | ||
| 497 | if (bus->hosttype == BCMA_HOSTTYPE_SOC) | 501 | if (bus->hosttype == BCMA_HOSTTYPE_SOC) |
| 498 | iounmap(eromptr); | 502 | iounmap(eromptr); |
| 499 | 503 | ||
| 500 | return 0; | 504 | return err; |
| 501 | } | 505 | } |
| 502 | 506 | ||
| 503 | int __init bcma_bus_scan_early(struct bcma_bus *bus, | 507 | int __init bcma_bus_scan_early(struct bcma_bus *bus, |
| @@ -537,7 +541,7 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus, | |||
| 537 | else if (err == -ESPIPE) | 541 | else if (err == -ESPIPE) |
| 538 | break; | 542 | break; |
| 539 | else if (err < 0) | 543 | else if (err < 0) |
| 540 | return err; | 544 | goto out; |
| 541 | 545 | ||
| 542 | core->core_index = core_num++; | 546 | core->core_index = core_num++; |
| 543 | bus->nr_cores++; | 547 | bus->nr_cores++; |
| @@ -551,6 +555,7 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus, | |||
| 551 | break; | 555 | break; |
| 552 | } | 556 | } |
| 553 | 557 | ||
| 558 | out: | ||
| 554 | if (bus->hosttype == BCMA_HOSTTYPE_SOC) | 559 | if (bus->hosttype == BCMA_HOSTTYPE_SOC) |
| 555 | iounmap(eromptr); | 560 | iounmap(eromptr); |
| 556 | 561 | ||
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index d8ad55284389..c3d03490c97d 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
| @@ -1314,7 +1314,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, | |||
| 1314 | int retv; | 1314 | int retv; |
| 1315 | int length = 0; /* shut up GCC */ | 1315 | int length = 0; /* shut up GCC */ |
| 1316 | 1316 | ||
| 1317 | urb = usb_alloc_urb(0, GFP_NOIO); | 1317 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
| 1318 | if (!urb) | 1318 | if (!urb) |
| 1319 | return -ENOMEM; | 1319 | return -ENOMEM; |
| 1320 | 1320 | ||
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 643f968b05ee..00838395778c 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
| @@ -739,11 +739,6 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 739 | 739 | ||
| 740 | txi = IEEE80211_SKB_CB(skb); | 740 | txi = IEEE80211_SKB_CB(skb); |
| 741 | 741 | ||
| 742 | if (txi->control.vif) | ||
| 743 | hwsim_check_magic(txi->control.vif); | ||
| 744 | if (txi->control.sta) | ||
| 745 | hwsim_check_sta_magic(txi->control.sta); | ||
| 746 | |||
| 747 | ieee80211_tx_info_clear_status(txi); | 742 | ieee80211_tx_info_clear_status(txi); |
| 748 | 743 | ||
| 749 | /* frame was transmitted at most favorable rate at first attempt */ | 744 | /* frame was transmitted at most favorable rate at first attempt */ |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 334b930e0de3..bc9e380f0abf 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -659,6 +659,12 @@ static void set_operstate(struct net_device *dev, unsigned char transition) | |||
| 659 | } | 659 | } |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | static unsigned int rtnl_dev_get_flags(const struct net_device *dev) | ||
| 663 | { | ||
| 664 | return (dev->flags & ~(IFF_PROMISC | IFF_ALLMULTI)) | | ||
| 665 | (dev->gflags & (IFF_PROMISC | IFF_ALLMULTI)); | ||
| 666 | } | ||
| 667 | |||
| 662 | static unsigned int rtnl_dev_combine_flags(const struct net_device *dev, | 668 | static unsigned int rtnl_dev_combine_flags(const struct net_device *dev, |
| 663 | const struct ifinfomsg *ifm) | 669 | const struct ifinfomsg *ifm) |
| 664 | { | 670 | { |
| @@ -667,7 +673,7 @@ static unsigned int rtnl_dev_combine_flags(const struct net_device *dev, | |||
| 667 | /* bugwards compatibility: ifi_change == 0 is treated as ~0 */ | 673 | /* bugwards compatibility: ifi_change == 0 is treated as ~0 */ |
| 668 | if (ifm->ifi_change) | 674 | if (ifm->ifi_change) |
| 669 | flags = (flags & ifm->ifi_change) | | 675 | flags = (flags & ifm->ifi_change) | |
| 670 | (dev->flags & ~ifm->ifi_change); | 676 | (rtnl_dev_get_flags(dev) & ~ifm->ifi_change); |
| 671 | 677 | ||
| 672 | return flags; | 678 | return flags; |
| 673 | } | 679 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 581ecf02c6b5..e7e6eeae49c0 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -2681,7 +2681,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2681 | /* Cap the max timeout in ms TCP will retry/retrans | 2681 | /* Cap the max timeout in ms TCP will retry/retrans |
| 2682 | * before giving up and aborting (ETIMEDOUT) a connection. | 2682 | * before giving up and aborting (ETIMEDOUT) a connection. |
| 2683 | */ | 2683 | */ |
| 2684 | icsk->icsk_user_timeout = msecs_to_jiffies(val); | 2684 | if (val < 0) |
| 2685 | err = -EINVAL; | ||
| 2686 | else | ||
| 2687 | icsk->icsk_user_timeout = msecs_to_jiffies(val); | ||
| 2685 | break; | 2688 | break; |
| 2686 | default: | 2689 | default: |
| 2687 | err = -ENOPROTOOPT; | 2690 | err = -ENOPROTOOPT; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3e07a64ca44e..a356e1fecf9a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -5475,7 +5475,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
| 5475 | if (tp->copied_seq == tp->rcv_nxt && | 5475 | if (tp->copied_seq == tp->rcv_nxt && |
| 5476 | len - tcp_header_len <= tp->ucopy.len) { | 5476 | len - tcp_header_len <= tp->ucopy.len) { |
| 5477 | #ifdef CONFIG_NET_DMA | 5477 | #ifdef CONFIG_NET_DMA |
| 5478 | if (tcp_dma_try_early_copy(sk, skb, tcp_header_len)) { | 5478 | if (tp->ucopy.task == current && |
| 5479 | sock_owned_by_user(sk) && | ||
| 5480 | tcp_dma_try_early_copy(sk, skb, tcp_header_len)) { | ||
| 5479 | copied_early = 1; | 5481 | copied_early = 1; |
| 5480 | eaten = 1; | 5482 | eaten = 1; |
| 5481 | } | 5483 | } |
| @@ -5603,6 +5605,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) | |||
| 5603 | 5605 | ||
| 5604 | if (skb != NULL) { | 5606 | if (skb != NULL) { |
| 5605 | sk->sk_rx_dst = dst_clone(skb_dst(skb)); | 5607 | sk->sk_rx_dst = dst_clone(skb_dst(skb)); |
| 5608 | inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; | ||
| 5606 | security_inet_conn_established(sk, skb); | 5609 | security_inet_conn_established(sk, skb); |
| 5607 | } | 5610 | } |
| 5608 | 5611 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index b6b07c93924c..2fbd9921253f 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1620,17 +1620,15 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1620 | sock_rps_save_rxhash(sk, skb); | 1620 | sock_rps_save_rxhash(sk, skb); |
| 1621 | if (sk->sk_rx_dst) { | 1621 | if (sk->sk_rx_dst) { |
| 1622 | struct dst_entry *dst = sk->sk_rx_dst; | 1622 | struct dst_entry *dst = sk->sk_rx_dst; |
| 1623 | if (dst->ops->check(dst, 0) == NULL) { | 1623 | if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || |
| 1624 | dst->ops->check(dst, 0) == NULL) { | ||
| 1624 | dst_release(dst); | 1625 | dst_release(dst); |
| 1625 | sk->sk_rx_dst = NULL; | 1626 | sk->sk_rx_dst = NULL; |
| 1626 | } | 1627 | } |
| 1627 | } | 1628 | } |
| 1628 | if (unlikely(sk->sk_rx_dst == NULL)) { | 1629 | if (unlikely(sk->sk_rx_dst == NULL)) { |
| 1629 | struct inet_sock *icsk = inet_sk(sk); | 1630 | sk->sk_rx_dst = dst_clone(skb_dst(skb)); |
| 1630 | struct rtable *rt = skb_rtable(skb); | 1631 | inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; |
| 1631 | |||
| 1632 | sk->sk_rx_dst = dst_clone(&rt->dst); | ||
| 1633 | icsk->rx_dst_ifindex = inet_iif(skb); | ||
| 1634 | } | 1632 | } |
| 1635 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { | 1633 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { |
| 1636 | rsk = sk; | 1634 | rsk = sk; |
| @@ -1709,11 +1707,11 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
| 1709 | skb->destructor = sock_edemux; | 1707 | skb->destructor = sock_edemux; |
| 1710 | if (sk->sk_state != TCP_TIME_WAIT) { | 1708 | if (sk->sk_state != TCP_TIME_WAIT) { |
| 1711 | struct dst_entry *dst = sk->sk_rx_dst; | 1709 | struct dst_entry *dst = sk->sk_rx_dst; |
| 1712 | struct inet_sock *icsk = inet_sk(sk); | 1710 | |
| 1713 | if (dst) | 1711 | if (dst) |
| 1714 | dst = dst_check(dst, 0); | 1712 | dst = dst_check(dst, 0); |
| 1715 | if (dst && | 1713 | if (dst && |
| 1716 | icsk->rx_dst_ifindex == skb->skb_iif) | 1714 | inet_sk(sk)->rx_dst_ifindex == skb->skb_iif) |
| 1717 | skb_dst_set_noref(skb, dst); | 1715 | skb_dst_set_noref(skb, dst); |
| 1718 | } | 1716 | } |
| 1719 | } | 1717 | } |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 5912ac3fd240..3f1cc2028edd 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
| @@ -388,6 +388,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
| 388 | struct tcp_cookie_values *oldcvp = oldtp->cookie_values; | 388 | struct tcp_cookie_values *oldcvp = oldtp->cookie_values; |
| 389 | 389 | ||
| 390 | newsk->sk_rx_dst = dst_clone(skb_dst(skb)); | 390 | newsk->sk_rx_dst = dst_clone(skb_dst(skb)); |
| 391 | inet_sk(newsk)->rx_dst_ifindex = skb->skb_iif; | ||
| 391 | 392 | ||
| 392 | /* TCP Cookie Transactions require space for the cookie pair, | 393 | /* TCP Cookie Transactions require space for the cookie pair, |
| 393 | * as it differs for each connection. There is no need to | 394 | * as it differs for each connection. There is no need to |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 320fa0e6951a..f3f96badf5aa 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
| @@ -325,9 +325,6 @@ static int sample(struct datapath *dp, struct sk_buff *skb, | |||
| 325 | } | 325 | } |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | if (!acts_list) | ||
| 329 | return 0; | ||
| 330 | |||
| 331 | return do_execute_actions(dp, skb, nla_data(acts_list), | 328 | return do_execute_actions(dp, skb, nla_data(acts_list), |
| 332 | nla_len(acts_list), true); | 329 | nla_len(acts_list), true); |
| 333 | } | 330 | } |
