Commit 6456a043 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking fixes from David Miller:
 "This fixes the most immediate fallout from yesterday's networking
  merge:

   1) sock_tx_timestamp() must not clear the passed in tx_flags, but
      rather add to them.  Fix from Eric Dumazet.

   2) The hyperv driver sendbuf region increase needs to be decreased
      slightly to handle older backends.  From KY Srinivasan.

   3) Fix RCU lockdep splats in netlink diag after recent hashing
      changes, from Thomas Graf.

   4) The new IPV6_FLOWLABEL was given a socket option number that
      overlapped with an existing IP6 tables one, breaking ip6_tables.
      Fixed by Pablo Neira Ayuso"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  netlink: hold nl_sock_hash_lock during diag dump
  tcp: md5: check md5 signature without socket lock
  net: fix USB network driver config option.
  net: reallocate new socket option number for IPV6_AUTOFLOWLABEL
  vmxnet3: fix decimal printf format specifiers prefixed with 0x
  net-timestamp: cumulative tcp timestamping fixes
  hyperv: Adjust the size of sendbuf region to support ws2008r2
  cxgb4: Fix for SR-IOV VF initialization
  net-timestamp: sock_tx_timestamp() fix
parents 158c1294 6c8f7e70
...@@ -6527,11 +6527,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -6527,11 +6527,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* We control everything through one PF */ /* We control everything through one PF */
func = SOURCEPF_GET(readl(adapter->regs + PL_WHOAMI)); func = SOURCEPF_GET(readl(adapter->regs + PL_WHOAMI));
if ((pdev->device == 0xa000 && func != 0) || if (func != ent->driver_data) {
func != ent->driver_data) {
pci_save_state(pdev); /* to restore SR-IOV later */ pci_save_state(pdev); /* to restore SR-IOV later */
err = 0; goto sriov;
goto out_unmap_bar0;
} }
adapter->pdev = pdev; adapter->pdev = pdev;
...@@ -6697,6 +6695,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -6697,6 +6695,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (is_offload(adapter)) if (is_offload(adapter))
attach_ulds(adapter); attach_ulds(adapter);
sriov:
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0) if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
if (pci_enable_sriov(pdev, num_vf[func]) == 0) if (pci_enable_sriov(pdev, num_vf[func]) == 0)
......
...@@ -585,7 +585,7 @@ struct nvsp_message { ...@@ -585,7 +585,7 @@ struct nvsp_message {
#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */ #define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */
#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */ #define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */
#define NETVSC_SEND_BUFFER_SIZE (1024 * 1024 * 16) /* 16MB */ #define NETVSC_SEND_BUFFER_SIZE (1024 * 1024 * 15) /* 15MB */
#define NETVSC_INVALID_INDEX -1 #define NETVSC_INVALID_INDEX -1
......
...@@ -5,8 +5,8 @@ comment "Host-side USB support is needed for USB Network Adapter support" ...@@ -5,8 +5,8 @@ comment "Host-side USB support is needed for USB Network Adapter support"
depends on !USB && NET depends on !USB && NET
menuconfig USB_NET_DRIVERS menuconfig USB_NET_DRIVERS
bool "USB Network Adapters" tristate "USB Network Adapters"
default y default USB if USB
depends on USB && NET depends on USB && NET
if USB_NET_DRIVERS if USB_NET_DRIVERS
......
...@@ -766,7 +766,7 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, ...@@ -766,7 +766,7 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
gdesc->dword[3] = 0; gdesc->dword[3] = 0;
netdev_dbg(adapter->netdev, netdev_dbg(adapter->netdev,
"txd[%u]: 0x%llu %u %u\n", "txd[%u]: 0x%llx %u %u\n",
tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr),
le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]);
vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
......
...@@ -189,6 +189,7 @@ config USB_NET_RNDIS_WLAN ...@@ -189,6 +189,7 @@ config USB_NET_RNDIS_WLAN
tristate "Wireless RNDIS USB support" tristate "Wireless RNDIS USB support"
depends on USB depends on USB
depends on CFG80211 depends on CFG80211
select USB_NET_DRIVERS
select USB_USBNET select USB_USBNET
select USB_NET_CDCETHER select USB_NET_CDCETHER
select USB_NET_RNDIS_HOST select USB_NET_RNDIS_HOST
......
...@@ -2199,9 +2199,11 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, ...@@ -2199,9 +2199,11 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
/** /**
* sock_tx_timestamp - checks whether the outgoing packet is to be time stamped * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped
* @sk: socket sending this packet * @sk: socket sending this packet
* @tx_flags: filled with instructions for time stamping * @tx_flags: completed with instructions for time stamping
*
* Note : callers should take care of initial *tx_flags value (usually 0)
*/ */
void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags); void sock_tx_timestamp(const struct sock *sk, __u8 *tx_flags);
/** /**
* sk_eat_skb - Release a skb if it is no longer needed * sk_eat_skb - Release a skb if it is no longer needed
......
...@@ -233,7 +233,6 @@ struct in6_flowlabel_req { ...@@ -233,7 +233,6 @@ struct in6_flowlabel_req {
#if 0 /* not yet */ #if 0 /* not yet */
#define IPV6_USE_MIN_MTU 63 #define IPV6_USE_MIN_MTU 63
#endif #endif
#define IPV6_AUTOFLOWLABEL 64
/* /*
* Netfilter (1) * Netfilter (1)
...@@ -262,6 +261,7 @@ struct in6_flowlabel_req { ...@@ -262,6 +261,7 @@ struct in6_flowlabel_req {
* IP6T_SO_ORIGINAL_DST 80 * IP6T_SO_ORIGINAL_DST 80
*/ */
#define IPV6_AUTOFLOWLABEL 70
/* RFC5014: Source address selection */ /* RFC5014: Source address selection */
#define IPV6_ADDR_PREFERENCES 72 #define IPV6_ADDR_PREFERENCES 72
......
...@@ -426,13 +426,15 @@ void tcp_init_sock(struct sock *sk) ...@@ -426,13 +426,15 @@ void tcp_init_sock(struct sock *sk)
} }
EXPORT_SYMBOL(tcp_init_sock); EXPORT_SYMBOL(tcp_init_sock);
void tcp_tx_timestamp(struct sock *sk, struct sk_buff *skb) static void tcp_tx_timestamp(struct sock *sk, struct sk_buff *skb)
{ {
if (sk->sk_tsflags) {
struct skb_shared_info *shinfo = skb_shinfo(skb); struct skb_shared_info *shinfo = skb_shinfo(skb);
sock_tx_timestamp(sk, &shinfo->tx_flags); sock_tx_timestamp(sk, &shinfo->tx_flags);
if (shinfo->tx_flags & SKBTX_ANY_SW_TSTAMP) if (shinfo->tx_flags & SKBTX_ANY_TSTAMP)
shinfo->tskey = TCP_SKB_CB(skb)->seq + skb->len - 1; shinfo->tskey = TCP_SKB_CB(skb)->seq + skb->len - 1;
}
} }
/* /*
......
...@@ -1167,7 +1167,8 @@ int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, ...@@ -1167,7 +1167,8 @@ int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
} }
EXPORT_SYMBOL(tcp_v4_md5_hash_skb); EXPORT_SYMBOL(tcp_v4_md5_hash_skb);
static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) static bool __tcp_v4_inbound_md5_hash(struct sock *sk,
const struct sk_buff *skb)
{ {
/* /*
* This gets called for each TCP segment that arrives * This gets called for each TCP segment that arrives
...@@ -1220,6 +1221,17 @@ static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) ...@@ -1220,6 +1221,17 @@ static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
return false; return false;
} }
static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
{
bool ret;
rcu_read_lock();
ret = __tcp_v4_inbound_md5_hash(sk, skb);
rcu_read_unlock();
return ret;
}
#endif #endif
static void tcp_v4_init_req(struct request_sock *req, struct sock *sk, static void tcp_v4_init_req(struct request_sock *req, struct sock *sk,
...@@ -1432,16 +1444,6 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) ...@@ -1432,16 +1444,6 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
{ {
struct sock *rsk; struct sock *rsk;
#ifdef CONFIG_TCP_MD5SIG
/*
* We really want to reject the packet as early as possible
* if:
* o We're expecting an MD5'd packet and this is no MD5 tcp option
* o There is an MD5 option and we're not expecting one
*/
if (tcp_v4_inbound_md5_hash(sk, skb))
goto discard;
#endif
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
struct dst_entry *dst = sk->sk_rx_dst; struct dst_entry *dst = sk->sk_rx_dst;
...@@ -1644,6 +1646,18 @@ int tcp_v4_rcv(struct sk_buff *skb) ...@@ -1644,6 +1646,18 @@ int tcp_v4_rcv(struct sk_buff *skb)
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_and_relse; goto discard_and_relse;
#ifdef CONFIG_TCP_MD5SIG
/*
* We really want to reject the packet as early as possible
* if:
* o We're expecting an MD5'd packet and this is no MD5 tcp option
* o There is an MD5 option and we're not expecting one
*/
if (tcp_v4_inbound_md5_hash(sk, skb))
goto discard_and_relse;
#endif
nf_reset(skb); nf_reset(skb);
if (sk_filter(sk, skb)) if (sk_filter(sk, skb))
......
...@@ -14,12 +14,12 @@ ...@@ -14,12 +14,12 @@
#include <net/tcp.h> #include <net/tcp.h>
#include <net/protocol.h> #include <net/protocol.h>
void tcp_gso_tstamp(struct sk_buff *skb, unsigned int ts_seq, unsigned int seq, static void tcp_gso_tstamp(struct sk_buff *skb, unsigned int ts_seq,
unsigned int mss) unsigned int seq, unsigned int mss)
{ {
while (skb) { while (skb) {
if (ts_seq < (__u64) seq + mss) { if (before(ts_seq, seq + mss)) {
skb_shinfo(skb)->tx_flags = SKBTX_SW_TSTAMP; skb_shinfo(skb)->tx_flags |= SKBTX_SW_TSTAMP;
skb_shinfo(skb)->tskey = ts_seq; skb_shinfo(skb)->tskey = ts_seq;
return; return;
} }
......
...@@ -667,7 +667,8 @@ static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, ...@@ -667,7 +667,8 @@ static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
return 1; return 1;
} }
static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) static int __tcp_v6_inbound_md5_hash(struct sock *sk,
const struct sk_buff *skb)
{ {
const __u8 *hash_location = NULL; const __u8 *hash_location = NULL;
struct tcp_md5sig_key *hash_expected; struct tcp_md5sig_key *hash_expected;
...@@ -707,6 +708,18 @@ static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) ...@@ -707,6 +708,18 @@ static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
} }
return 0; return 0;
} }
static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
{
int ret;
rcu_read_lock();
ret = __tcp_v6_inbound_md5_hash(sk, skb);
rcu_read_unlock();
return ret;
}
#endif #endif
static void tcp_v6_init_req(struct request_sock *req, struct sock *sk, static void tcp_v6_init_req(struct request_sock *req, struct sock *sk,
...@@ -1247,11 +1260,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) ...@@ -1247,11 +1260,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
if (skb->protocol == htons(ETH_P_IP)) if (skb->protocol == htons(ETH_P_IP))
return tcp_v4_do_rcv(sk, skb); return tcp_v4_do_rcv(sk, skb);
#ifdef CONFIG_TCP_MD5SIG
if (tcp_v6_inbound_md5_hash(sk, skb))
goto discard;
#endif
if (sk_filter(sk, skb)) if (sk_filter(sk, skb))
goto discard; goto discard;
...@@ -1424,6 +1432,11 @@ static int tcp_v6_rcv(struct sk_buff *skb) ...@@ -1424,6 +1432,11 @@ static int tcp_v6_rcv(struct sk_buff *skb)
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_and_relse; goto discard_and_relse;
#ifdef CONFIG_TCP_MD5SIG
if (tcp_v6_inbound_md5_hash(sk, skb))
goto discard_and_relse;
#endif
if (sk_filter(sk, skb)) if (sk_filter(sk, skb))
goto discard_and_relse; goto discard_and_relse;
......
...@@ -104,6 +104,7 @@ static atomic_t nl_table_users = ATOMIC_INIT(0); ...@@ -104,6 +104,7 @@ static atomic_t nl_table_users = ATOMIC_INIT(0);
/* Protects netlink socket hash table mutations */ /* Protects netlink socket hash table mutations */
DEFINE_MUTEX(nl_sk_hash_lock); DEFINE_MUTEX(nl_sk_hash_lock);
EXPORT_SYMBOL_GPL(nl_sk_hash_lock);
static int lockdep_nl_sk_hash_is_held(void) static int lockdep_nl_sk_hash_is_held(void)
{ {
......
...@@ -73,5 +73,6 @@ struct netlink_table { ...@@ -73,5 +73,6 @@ struct netlink_table {
extern struct netlink_table *nl_table; extern struct netlink_table *nl_table;
extern rwlock_t nl_table_lock; extern rwlock_t nl_table_lock;
extern struct mutex nl_sk_hash_lock;
#endif #endif
...@@ -170,6 +170,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -170,6 +170,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
req = nlmsg_data(cb->nlh); req = nlmsg_data(cb->nlh);
mutex_lock(&nl_sk_hash_lock);
read_lock(&nl_table_lock); read_lock(&nl_table_lock);
if (req->sdiag_protocol == NDIAG_PROTO_ALL) { if (req->sdiag_protocol == NDIAG_PROTO_ALL) {
...@@ -183,6 +184,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -183,6 +184,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
} else { } else {
if (req->sdiag_protocol >= MAX_LINKS) { if (req->sdiag_protocol >= MAX_LINKS) {
read_unlock(&nl_table_lock); read_unlock(&nl_table_lock);
mutex_unlock(&nl_sk_hash_lock);
return -ENOENT; return -ENOENT;
} }
...@@ -190,6 +192,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -190,6 +192,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
} }
read_unlock(&nl_table_lock); read_unlock(&nl_table_lock);
mutex_unlock(&nl_sk_hash_lock);
return skb->len; return skb->len;
} }
......
...@@ -610,20 +610,26 @@ void sock_release(struct socket *sock) ...@@ -610,20 +610,26 @@ void sock_release(struct socket *sock)
} }
EXPORT_SYMBOL(sock_release); EXPORT_SYMBOL(sock_release);
void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) void sock_tx_timestamp(const struct sock *sk, __u8 *tx_flags)
{ {
*tx_flags = 0; u8 flags = *tx_flags;
if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_HARDWARE) if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_HARDWARE)
*tx_flags |= SKBTX_HW_TSTAMP; flags |= SKBTX_HW_TSTAMP;
if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SOFTWARE) if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
*tx_flags |= SKBTX_SW_TSTAMP; flags |= SKBTX_SW_TSTAMP;
if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED) if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED)
*tx_flags |= SKBTX_SCHED_TSTAMP; flags |= SKBTX_SCHED_TSTAMP;
if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK) if (sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK)
*tx_flags |= SKBTX_ACK_TSTAMP; flags |= SKBTX_ACK_TSTAMP;
if (sock_flag(sk, SOCK_WIFI_STATUS)) if (sock_flag(sk, SOCK_WIFI_STATUS))
*tx_flags |= SKBTX_WIFI_STATUS; flags |= SKBTX_WIFI_STATUS;
*tx_flags = flags;
} }
EXPORT_SYMBOL(sock_tx_timestamp); EXPORT_SYMBOL(sock_tx_timestamp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment