Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Browse files Browse the repository at this point in the history
Pull networking changes from David Miller:
 "The most important bit here is the TCP syncookies issue, which seems
  to have been busted for some time.  That fix has been verified in
  production by the reporter.

  1) Persistent TUN devices erroneously hold on to the network namespace
     in such a way that it cannot be shutdown.  Fix from Stanislav
     Kinsbursky with help from Eric Dumazet.

  2) TCP SYN cookies have been broken for a while due to how the route
     lookup flow key is managed, connections can be delayed by as much
     as 20 seconds due to this bug.  Fix from Eric Dumazet.

  3) Missing jiffies.h include in lib/dynamic_queue_limits.c can break
     the build, from Tom Herbert.

  4) Add USB device ID for Sitecom LN-031, from Joerg Neikes.

  5) Fix OOPS in delayed workqueue in iwlegacy, from Stanislaw Gruszka.

  6) rt2x00 TX queue can be disabled forever due to races, fix by
     synchronizing pause/unpause with a lock.  Also from Stanislaw
     Gruszka.

  7) Statistics and endian fix in bnx2x driver from Yuval Mintz, Eilon
     Greenstein, and Ariel Elior."

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  tun: don't hold network namespace by tun sockets
  bnx2x: FCoE statistics id fixed
  bnx2x: dcb bit indices flags used as bits
  bnx2x: added cpu_to_le16 when preparing ramrod's data
  bnx2x: pfc statistics counts pfc events twice
  rt2x00: fix random stalls
  iwl3945: fix possible il->txq NULL pointer dereference in delayed works
  dql: Fix undefined jiffies
  tcp: fix syncookie regression
  usb: asix: Patch for Sitecom LN-031
  • Loading branch information
torvalds committed Mar 14, 2012
2 parents 69539ab + 750084b commit b8fa7d4
Show file tree
Hide file tree
Showing 15 changed files with 78 additions and 45 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
Expand Up @@ -1934,7 +1934,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
}

if (bp->port.pmf)
bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0);
bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0);
else
bnx2x__link_status_update(bp);

Expand Down
12 changes: 9 additions & 3 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
Expand Up @@ -1179,10 +1179,16 @@ static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
*/
static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp)
{
if (!CHIP_IS_E1x(fp->bp))
struct bnx2x *bp = fp->bp;
if (!CHIP_IS_E1x(bp)) {
#ifdef BCM_CNIC
/* there are special statistics counters for FCoE 136..140 */
if (IS_FCOE_FP(fp))
return bp->cnic_base_cl_id + (bp->pf_num >> 1);
#endif
return fp->cl_id;
else
return fp->cl_id + BP_PORT(fp->bp) * FP_SB_MAX_E1x;
}
return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x;
}

static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp,
Expand Down
8 changes: 5 additions & 3 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
Expand Up @@ -735,7 +735,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
bp->dcbx_error);

/* mark DCBX result for PMF migration */
bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 1);
bnx2x_update_drv_flags(bp,
1 << DRV_FLAGS_DCB_CONFIGURED,
1);
#ifdef BCM_DCBNL
/*
* Add new app tlvs to dcbnl
Expand Down Expand Up @@ -1020,7 +1022,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp)
DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n",
dcbx_lldp_params_offset);

bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0);
bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0);

if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) {
bnx2x_dcbx_admin_mib_updated_params(bp,
Expand Down Expand Up @@ -1857,7 +1859,7 @@ void bnx2x_dcbx_pmf_update(struct bnx2x *bp)
* read it from shmem and update bp and netdev accordingly
*/
if (SHMEM2_HAS(bp, drv_flags) &&
GET_FLAGS(SHMEM2_RD(bp, drv_flags), DRV_FLAGS_DCB_CONFIGURED)) {
GET_FLAGS(SHMEM2_RD(bp, drv_flags), 1 << DRV_FLAGS_DCB_CONFIGURED)) {
/* Read neg results if dcbx is in the FW */
if (bnx2x_dcbx_read_shmem_neg_results(bp))
return;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
Expand Up @@ -5601,7 +5601,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp,

/* Fill the ramrod data with provided parameters */
rdata->function_mode = cpu_to_le16(start_params->mf_mode);
rdata->sd_vlan_tag = start_params->sd_vlan_tag;
rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag);
rdata->path_id = BP_PATH(bp);
rdata->network_cos_mode = start_params->network_cos_mode;

Expand Down
12 changes: 0 additions & 12 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
Expand Up @@ -554,23 +554,11 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);

/* collect PFC stats */
DIFF_64(diff.hi, new->tx_stat_gtpp_hi,
pstats->pfc_frames_tx_hi,
diff.lo, new->tx_stat_gtpp_lo,
pstats->pfc_frames_tx_lo);
pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi;
pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo;
ADD_64(pstats->pfc_frames_tx_hi, diff.hi,
pstats->pfc_frames_tx_lo, diff.lo);

DIFF_64(diff.hi, new->rx_stat_grpp_hi,
pstats->pfc_frames_rx_hi,
diff.lo, new->rx_stat_grpp_lo,
pstats->pfc_frames_rx_lo);
pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi;
pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo;
ADD_64(pstats->pfc_frames_rx_hi, diff.hi,
pstats->pfc_frames_rx_lo, diff.lo);
}

estats->pause_frames_received_hi =
Expand Down
15 changes: 12 additions & 3 deletions drivers/net/tun.c
Expand Up @@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev)
{
struct tun_struct *tun = netdev_priv(dev);

sock_put(tun->socket.sk);
sk_release_kernel(tun->socket.sk);
}

/* Net device open. */
Expand Down Expand Up @@ -980,10 +980,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
return ret;
}

static int tun_release(struct socket *sock)
{
if (sock->sk)
sock_put(sock->sk);
return 0;
}

/* Ops structure to mimic raw sockets with tun */
static const struct proto_ops tun_socket_ops = {
.sendmsg = tun_sendmsg,
.recvmsg = tun_recvmsg,
.release = tun_release,
};

static struct proto tun_proto = {
Expand Down Expand Up @@ -1110,10 +1118,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);

err = -ENOMEM;
sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
if (!sk)
goto err_free_dev;

sk_change_net(sk, net);
tun->socket.wq = &tun->wq;
init_waitqueue_head(&tun->wq.wait);
tun->socket.ops = &tun_socket_ops;
Expand Down Expand Up @@ -1174,7 +1183,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return 0;

err_free_sk:
sock_put(sk);
tun_free_netdev(dev);
err_free_dev:
free_netdev(dev);
failed:
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/usb/asix.c
Expand Up @@ -1598,6 +1598,10 @@ static const struct usb_device_id products [] = {
// Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
USB_DEVICE (0x6189, 0x182d),
.driver_info = (unsigned long) &ax8817x_info,
}, {
// Sitecom LN-031 "USB 2.0 10/100/1000 Ethernet adapter"
USB_DEVICE (0x0df6, 0x0056),
.driver_info = (unsigned long) &ax88178_info,
}, {
// corega FEther USB2-TX
USB_DEVICE (0x07aa, 0x0017),
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlegacy/3945-mac.c
Expand Up @@ -2475,7 +2475,7 @@ il3945_bg_alive_start(struct work_struct *data)
container_of(data, struct il_priv, alive_start.work);

mutex_lock(&il->mutex);
if (test_bit(S_EXIT_PENDING, &il->status))
if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL)
goto out;

il3945_alive_start(il);
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/wireless/iwlegacy/3945.c
Expand Up @@ -1870,11 +1870,12 @@ il3945_bg_reg_txpower_periodic(struct work_struct *work)
struct il_priv *il = container_of(work, struct il_priv,
_3945.thermal_periodic.work);

if (test_bit(S_EXIT_PENDING, &il->status))
return;

mutex_lock(&il->mutex);
if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL)
goto out;

il3945_reg_txpower_periodic(il);
out:
mutex_unlock(&il->mutex);
}

Expand Down
6 changes: 5 additions & 1 deletion drivers/net/wireless/rt2x00/rt2x00dev.c
Expand Up @@ -426,10 +426,14 @@ void rt2x00lib_txdone(struct queue_entry *entry,
/*
* If the data queue was below the threshold before the txdone
* handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished.
* is reenabled when the txdone handler has finished. This has to be
* serialized with rt2x00mac_tx(), otherwise we can wake up queue
* before it was stopped.
*/
spin_lock_bh(&entry->queue->tx_lock);
if (!rt2x00queue_threshold(entry->queue))
rt2x00queue_unpause_queue(entry->queue);
spin_unlock_bh(&entry->queue->tx_lock);
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);

Expand Down
9 changes: 9 additions & 0 deletions drivers/net/wireless/rt2x00/rt2x00mac.c
Expand Up @@ -152,13 +152,22 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false)))
goto exit_fail;

/*
* Pausing queue has to be serialized with rt2x00lib_txdone(). Note
* we should not use spin_lock_bh variant as bottom halve was already
* disabled before ieee80211_xmit() call.
*/
spin_lock(&queue->tx_lock);
if (rt2x00queue_threshold(queue))
rt2x00queue_pause_queue(queue);
spin_unlock(&queue->tx_lock);

return;

exit_fail:
spin_lock(&queue->tx_lock);
rt2x00queue_pause_queue(queue);
spin_unlock(&queue->tx_lock);
exit_free_skb:
ieee80211_free_txskb(hw, skb);
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/rt2x00/rt2x00queue.c
Expand Up @@ -619,6 +619,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags))
rt2x00queue_align_frame(skb);

/*
* That function must be called with bh disabled.
*/
spin_lock(&queue->tx_lock);

if (unlikely(rt2x00queue_full(queue))) {
Expand Down
1 change: 1 addition & 0 deletions lib/dynamic_queue_limits.c
Expand Up @@ -7,6 +7,7 @@
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/dynamic_queue_limits.h>

#define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
Expand Down
30 changes: 16 additions & 14 deletions net/ipv4/syncookies.c
Expand Up @@ -278,6 +278,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
struct rtable *rt;
__u8 rcv_wscale;
bool ecn_ok = false;
struct flowi4 fl4;

if (!sysctl_tcp_syncookies || !th->ack || th->rst)
goto out;
Expand Down Expand Up @@ -346,20 +347,16 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
* hasn't changed since we received the original syn, but I see
* no easy way to do this.
*/
{
struct flowi4 fl4;

flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk),
RT_SCOPE_UNIVERSE, IPPROTO_TCP,
inet_sk_flowi_flags(sk),
(opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
ireq->loc_addr, th->source, th->dest);
security_req_classify_flow(req, flowi4_to_flowi(&fl4));
rt = ip_route_output_key(sock_net(sk), &fl4);
if (IS_ERR(rt)) {
reqsk_free(req);
goto out;
}
flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk),
RT_SCOPE_UNIVERSE, IPPROTO_TCP,
inet_sk_flowi_flags(sk),
(opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
ireq->loc_addr, th->source, th->dest);
security_req_classify_flow(req, flowi4_to_flowi(&fl4));
rt = ip_route_output_key(sock_net(sk), &fl4);
if (IS_ERR(rt)) {
reqsk_free(req);
goto out;
}

/* Try to redo what tcp_v4_send_synack did. */
Expand All @@ -373,5 +370,10 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
ireq->rcv_wscale = rcv_wscale;

ret = get_cookie_sock(sk, skb, req, &rt->dst);
/* ip_queue_xmit() depends on our flow being setup
* Normal sockets get it right from inet_csk_route_child_sock()
*/
if (ret)
inet_sk(ret)->cork.fl.u.ip4 = fl4;
out: return ret;
}
10 changes: 7 additions & 3 deletions net/ipv4/tcp_ipv4.c
Expand Up @@ -1466,9 +1466,13 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
newinet->inet_id = newtp->write_seq ^ jiffies;

if (!dst && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL)
goto put_and_exit;

if (!dst) {
dst = inet_csk_route_child_sock(sk, newsk, req);
if (!dst)
goto put_and_exit;
} else {
/* syncookie case : see end of cookie_v4_check() */
}
sk_setup_caps(newsk, dst);

tcp_mtup_init(newsk);
Expand Down

0 comments on commit b8fa7d4

Please sign in to comment.