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

Pull networking fixes from David Miller:

 1) Really fix tuntap SKB use after free bug, from Eric Dumazet.

 2) Adjust SKB data pointer to point past the transport header before
    calling icmpv6_notify() so that the headers are in the state which
    that function expects.  From Duan Jiong.

 3) Fix ambiguities in the new tuntap multi-queue APIs.  From Jason
    Wang.

 4) mISDN needs to use del_timer_sync(), from Konstantin Khlebnikov.

 5) Don't destroy mutex after freeing up device private in mac802154,
    fix also from Konstantin Khlebnikov.

 6) Fix INET request socket leak in TCP and DCCP, from Christoph Paasch.

 7) SCTP HMAC kconfig rework, from Neil Horman.

 8) Fix SCTP jprobes function signature, otherwise things explode, from
    Daniel Borkmann.

 9) Fix typo in ipv6-offload Makefile variable reference, from Simon
    Arlott.

10) Don't fail USBNET open just because remote wakeup isn't supported,
    from Oliver Neukum.

11) be2net driver bug fixes from Sathya Perla.

12) SOLOS PCI ATM driver bug fixes from Nathan Williams and David
    Woodhouse.

13) Fix MTU changing regression in 8139cp driver, from John Greene.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (45 commits)
  solos-pci: ensure all TX packets are aligned to 4 bytes
  solos-pci: add firmware upgrade support for new models
  solos-pci: remove superfluous debug output
  solos-pci: add GPIO support for newer versions on Geos board
  8139cp: Prevent dev_close/cp_interrupt race on MTU change
  net: qmi_wwan: add ZTE MF880
  drivers/net: Use of_match_ptr() macro in smsc911x.c
  drivers/net: Use of_match_ptr() macro in smc91x.c
  ipv6: addrconf.c: remove unnecessary "if"
  bridge: Correctly encode addresses when dumping mdb entries
  bridge: Do not unregister all PF_BRIDGE rtnl operations
  use generic usbnet_manage_power()
  usbnet: generic manage_power()
  usbnet: handle PM failure gracefully
  ksz884x: fix receive polling race condition
  qlcnic: update driver version
  qlcnic: fix unused variable warnings
  net: fec: forbid FEC_PTP on SoCs that do not support
  be2net: fix wrong frag_idx reported by RX CQ
  be2net: fix be_close() to ensure all events are ack'ed
  ...
This commit is contained in:
Linus Torvalds 2012-12-19 20:29:15 -08:00
commit 9eb127cc04
52 changed files with 545 additions and 202 deletions

View file

@ -14,49 +14,45 @@ static ssize_t show_type(struct device *cdev,
struct device_attribute *attr, char *buf)
{
struct atm_dev *adev = to_atm_dev(cdev);
return sprintf(buf, "%s\n", adev->type);
return scnprintf(buf, PAGE_SIZE, "%s\n", adev->type);
}
static ssize_t show_address(struct device *cdev,
struct device_attribute *attr, char *buf)
{
char *pos = buf;
struct atm_dev *adev = to_atm_dev(cdev);
int i;
for (i = 0; i < (ESI_LEN - 1); i++)
pos += sprintf(pos, "%02x:", adev->esi[i]);
pos += sprintf(pos, "%02x\n", adev->esi[i]);
return pos - buf;
return scnprintf(buf, PAGE_SIZE, "%pM\n", adev->esi);
}
static ssize_t show_atmaddress(struct device *cdev,
struct device_attribute *attr, char *buf)
{
unsigned long flags;
char *pos = buf;
struct atm_dev *adev = to_atm_dev(cdev);
struct atm_dev_addr *aaddr;
int bin[] = { 1, 2, 10, 6, 1 }, *fmt = bin;
int i, j;
int i, j, count = 0;
spin_lock_irqsave(&adev->lock, flags);
list_for_each_entry(aaddr, &adev->local, entry) {
for (i = 0, j = 0; i < ATM_ESA_LEN; ++i, ++j) {
if (j == *fmt) {
pos += sprintf(pos, ".");
count += scnprintf(buf + count,
PAGE_SIZE - count, ".");
++fmt;
j = 0;
}
pos += sprintf(pos, "%02x",
aaddr->addr.sas_addr.prv[i]);
count += scnprintf(buf + count,
PAGE_SIZE - count, "%02x",
aaddr->addr.sas_addr.prv[i]);
}
pos += sprintf(pos, "\n");
count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
}
spin_unlock_irqrestore(&adev->lock, flags);
return pos - buf;
return count;
}
static ssize_t show_atmindex(struct device *cdev,
@ -64,25 +60,21 @@ static ssize_t show_atmindex(struct device *cdev,
{
struct atm_dev *adev = to_atm_dev(cdev);
return sprintf(buf, "%d\n", adev->number);
return scnprintf(buf, PAGE_SIZE, "%d\n", adev->number);
}
static ssize_t show_carrier(struct device *cdev,
struct device_attribute *attr, char *buf)
{
char *pos = buf;
struct atm_dev *adev = to_atm_dev(cdev);
pos += sprintf(pos, "%d\n",
adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
return pos - buf;
return scnprintf(buf, PAGE_SIZE, "%d\n",
adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
}
static ssize_t show_link_rate(struct device *cdev,
struct device_attribute *attr, char *buf)
{
char *pos = buf;
struct atm_dev *adev = to_atm_dev(cdev);
int link_rate;
@ -100,9 +92,7 @@ static ssize_t show_link_rate(struct device *cdev,
default:
link_rate = adev->link_rate * 8 * 53;
}
pos += sprintf(pos, "%d\n", link_rate);
return pos - buf;
return scnprintf(buf, PAGE_SIZE, "%d\n", link_rate);
}
static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);

View file

@ -83,9 +83,12 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
if (port) {
struct br_mdb_entry e;
e.ifindex = port->dev->ifindex;
e.addr.u.ip4 = p->addr.u.ip4;
e.state = p->state;
if (p->addr.proto == htons(ETH_P_IP))
e.addr.u.ip4 = p->addr.u.ip4;
#if IS_ENABLED(CONFIG_IPV6)
e.addr.u.ip6 = p->addr.u.ip6;
if (p->addr.proto == htons(ETH_P_IPV6))
e.addr.u.ip6 = p->addr.u.ip6;
#endif
e.addr.proto = p->addr.proto;
if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) {
@ -253,6 +256,8 @@ static bool is_valid_mdb_entry(struct br_mdb_entry *entry)
#endif
} else
return false;
if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY)
return false;
return true;
}
@ -310,7 +315,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
struct br_ip *group)
struct br_ip *group, unsigned char state)
{
struct net_bridge_mdb_entry *mp;
struct net_bridge_port_group *p;
@ -336,7 +341,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
break;
}
p = br_multicast_new_port_group(port, group, *pp);
p = br_multicast_new_port_group(port, group, *pp, state);
if (unlikely(!p))
return -ENOMEM;
rcu_assign_pointer(*pp, p);
@ -373,7 +378,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
#endif
spin_lock_bh(&br->multicast_lock);
ret = br_mdb_add_group(br, p, &ip);
ret = br_mdb_add_group(br, p, &ip, entry->state);
spin_unlock_bh(&br->multicast_lock);
return ret;
}
@ -479,3 +484,10 @@ void br_mdb_init(void)
rtnl_register(PF_BRIDGE, RTM_NEWMDB, br_mdb_add, NULL, NULL);
rtnl_register(PF_BRIDGE, RTM_DELMDB, br_mdb_del, NULL, NULL);
}
void br_mdb_uninit(void)
{
rtnl_unregister(PF_BRIDGE, RTM_GETMDB);
rtnl_unregister(PF_BRIDGE, RTM_NEWMDB);
rtnl_unregister(PF_BRIDGE, RTM_DELMDB);
}

View file

@ -279,7 +279,7 @@ static void br_multicast_port_group_expired(unsigned long data)
spin_lock(&br->multicast_lock);
if (!netif_running(br->dev) || timer_pending(&pg->timer) ||
hlist_unhashed(&pg->mglist))
hlist_unhashed(&pg->mglist) || pg->state & MDB_PERMANENT)
goto out;
br_multicast_del_pg(br, pg);
@ -622,7 +622,8 @@ out:
struct net_bridge_port_group *br_multicast_new_port_group(
struct net_bridge_port *port,
struct br_ip *group,
struct net_bridge_port_group __rcu *next)
struct net_bridge_port_group __rcu *next,
unsigned char state)
{
struct net_bridge_port_group *p;
@ -632,6 +633,7 @@ struct net_bridge_port_group *br_multicast_new_port_group(
p->addr = *group;
p->port = port;
p->state = state;
rcu_assign_pointer(p->next, next);
hlist_add_head(&p->mglist, &port->mglist);
setup_timer(&p->timer, br_multicast_port_group_expired,
@ -674,7 +676,7 @@ static int br_multicast_add_group(struct net_bridge *br,
break;
}
p = br_multicast_new_port_group(port, group, *pp);
p = br_multicast_new_port_group(port, group, *pp, MDB_TEMPORARY);
if (unlikely(!p))
goto err;
rcu_assign_pointer(*pp, p);
@ -1165,7 +1167,6 @@ static int br_ip6_multicast_query(struct net_bridge *br,
if (max_delay)
group = &mld->mld_mca;
} else if (skb->len >= sizeof(*mld2q)) {
u16 mrc;
if (!pskb_may_pull(skb, sizeof(*mld2q))) {
err = -EINVAL;
goto out;
@ -1173,8 +1174,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
mld2q = (struct mld2_query *)icmp6_hdr(skb);
if (!mld2q->mld2q_nsrcs)
group = &mld2q->mld2q_mca;
mrc = ntohs(mld2q->mld2q_mrc);
max_delay = mrc ? MLDV2_MRC(mrc) : 1;
max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(ntohs(mld2q->mld2q_mrc)) : 1;
}
if (!group)
@ -1633,6 +1633,7 @@ void br_multicast_stop(struct net_bridge *br)
del_timer_sync(&br->multicast_querier_timer);
del_timer_sync(&br->multicast_query_timer);
br_mdb_uninit();
spin_lock_bh(&br->multicast_lock);
mdb = mlock_dereference(br->mdb, br);
if (!mdb)

View file

@ -305,5 +305,4 @@ int __init br_netlink_init(void)
void __exit br_netlink_fini(void)
{
rtnl_link_unregister(&br_link_ops);
rtnl_unregister_all(PF_BRIDGE);
}

View file

@ -83,6 +83,7 @@ struct net_bridge_port_group {
struct rcu_head rcu;
struct timer_list timer;
struct br_ip addr;
unsigned char state;
};
struct net_bridge_mdb_entry
@ -443,8 +444,10 @@ extern void br_multicast_free_pg(struct rcu_head *head);
extern struct net_bridge_port_group *br_multicast_new_port_group(
struct net_bridge_port *port,
struct br_ip *group,
struct net_bridge_port_group *next);
struct net_bridge_port_group *next,
unsigned char state);
extern void br_mdb_init(void);
extern void br_mdb_uninit(void);
extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
struct br_ip *group, int type);

View file

@ -439,8 +439,8 @@ exit:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
return NULL;
put_and_exit:
bh_unlock_sock(newsk);
sock_put(newsk);
inet_csk_prepare_forced_close(newsk);
dccp_done(newsk);
goto exit;
}

View file

@ -585,7 +585,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
if (__inet_inherit_port(sk, newsk) < 0) {
sock_put(newsk);
inet_csk_prepare_forced_close(newsk);
dccp_done(newsk);
goto out;
}
__inet6_hash(newsk, NULL);

View file

@ -710,6 +710,22 @@ void inet_csk_destroy_sock(struct sock *sk)
}
EXPORT_SYMBOL(inet_csk_destroy_sock);
/* This function allows to force a closure of a socket after the call to
* tcp/dccp_create_openreq_child().
*/
void inet_csk_prepare_forced_close(struct sock *sk)
{
/* sk_clone_lock locked the socket and set refcnt to 2 */
bh_unlock_sock(sk);
sock_put(sk);
/* The below has to be done to allow calling inet_csk_destroy_sock */
sock_set_flag(sk, SOCK_DEAD);
percpu_counter_inc(sk->sk_prot->orphan_count);
inet_sk(sk)->inet_num = 0;
}
EXPORT_SYMBOL(inet_csk_prepare_forced_close);
int inet_csk_listen_start(struct sock *sk, const int nr_table_entries)
{
struct inet_sock *inet = inet_sk(sk);

View file

@ -1767,10 +1767,8 @@ exit:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
return NULL;
put_and_exit:
tcp_clear_xmit_timers(newsk);
tcp_cleanup_congestion_control(newsk);
bh_unlock_sock(newsk);
sock_put(newsk);
inet_csk_prepare_forced_close(newsk);
tcp_done(newsk);
goto exit;
}
EXPORT_SYMBOL(tcp_v4_syn_recv_sock);

View file

@ -41,6 +41,6 @@ obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
obj-y += addrconf_core.o exthdrs_core.o
obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6_offload)
obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload)
obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o

View file

@ -534,8 +534,7 @@ void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_ATOMIC);
return;
errout:
if (err < 0)
rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
}
static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {

View file

@ -1314,6 +1314,12 @@ out:
static void ndisc_redirect_rcv(struct sk_buff *skb)
{
u8 *hdr;
struct ndisc_options ndopts;
struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb);
u32 ndoptlen = skb->tail - (skb->transport_header +
offsetof(struct rd_msg, opt));
#ifdef CONFIG_IPV6_NDISC_NODETYPE
switch (skb->ndisc_nodetype) {
case NDISC_NODETYPE_HOST:
@ -1330,6 +1336,17 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
return;
}
if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts))
return;
if (!ndopts.nd_opts_rh)
return;
hdr = (u8 *)ndopts.nd_opts_rh;
hdr += 8;
if (!pskb_pull(skb, hdr - skb_transport_header(skb)))
return;
icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
}

View file

@ -1288,7 +1288,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
#endif
if (__inet_inherit_port(sk, newsk) < 0) {
sock_put(newsk);
inet_csk_prepare_forced_close(newsk);
tcp_done(newsk);
goto out;
}
__inet6_hash(newsk, NULL);

View file

@ -224,9 +224,9 @@ void ieee802154_free_device(struct ieee802154_dev *hw)
BUG_ON(!list_empty(&priv->slaves));
wpan_phy_free(priv->phy);
mutex_destroy(&priv->slaves_mtx);
wpan_phy_free(priv->phy);
}
EXPORT_SYMBOL(ieee802154_free_device);

View file

@ -669,6 +669,9 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
int err;
if (addr_len < sizeof(struct sockaddr_nl))
return -EINVAL;
if (nladdr->nl_family != AF_NETLINK)
return -EINVAL;
@ -2059,7 +2062,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
struct sock *s = v;
struct netlink_sock *nlk = nlk_sk(s);
seq_printf(seq, "%pK %-3d %-6d %08x %-8d %-8d %pK %-8d %-8d %-8lu\n",
seq_printf(seq, "%pK %-3d %-6u %08x %-8d %-8d %pK %-8d %-8d %-8lu\n",
s,
s->sk_protocol,
nlk->portid,

View file

@ -66,12 +66,36 @@ config SCTP_DBG_OBJCNT
'cat /proc/net/sctp/sctp_dbg_objcnt'
If unsure, say N
choice
prompt "Default SCTP cookie HMAC encoding"
default SCTP_COOKIE_HMAC_MD5
help
This option sets the default sctp cookie hmac algorithm
when in doubt select 'md5'
config SCTP_DEFAULT_COOKIE_HMAC_MD5
bool "Enable optional MD5 hmac cookie generation"
help
Enable optional MD5 hmac based SCTP cookie generation
select SCTP_COOKIE_HMAC_MD5
config SCTP_DEFAULT_COOKIE_HMAC_SHA1
bool "Enable optional SHA1 hmac cookie generation"
help
Enable optional SHA1 hmac based SCTP cookie generation
select SCTP_COOKIE_HMAC_SHA1
config SCTP_DEFAULT_COOKIE_HMAC_NONE
bool "Use no hmac alg in SCTP cookie generation"
help
Use no hmac algorithm in SCTP cookie generation
endchoice
config SCTP_COOKIE_HMAC_MD5
bool "Enable optional MD5 hmac cookie generation"
help
Enable optional MD5 hmac based SCTP cookie generation
default y
select CRYPTO_HMAC if SCTP_COOKIE_HMAC_MD5
select CRYPTO_MD5 if SCTP_COOKIE_HMAC_MD5
@ -79,7 +103,6 @@ config SCTP_COOKIE_HMAC_SHA1
bool "Enable optional SHA1 hmac cookie generation"
help
Enable optional SHA1 hmac based SCTP cookie generation
default y
select CRYPTO_HMAC if SCTP_COOKIE_HMAC_SHA1
select CRYPTO_SHA1 if SCTP_COOKIE_HMAC_SHA1

View file

@ -122,7 +122,8 @@ static const struct file_operations sctpprobe_fops = {
.llseek = noop_llseek,
};
sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep,
sctp_disposition_t jsctp_sf_eat_sack(struct net *net,
const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
const sctp_subtype_t type,
void *arg,

View file

@ -1191,9 +1191,9 @@ static int __net_init sctp_net_init(struct net *net)
net->sctp.cookie_preserve_enable = 1;
/* Default sctp sockets to use md5 as their hmac alg */
#if defined (CONFIG_CRYPTO_MD5)
#if defined (CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5)
net->sctp.sctp_hmac_alg = "md5";
#elif defined (CONFIG_CRYPTO_SHA1)
#elif defined (CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1)
net->sctp.sctp_hmac_alg = "sha1";
#else
net->sctp.sctp_hmac_alg = NULL;