aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-16 00:29:07 +0200
committerIngo Molnar <mingo@elte.hu>2008-07-16 00:29:07 +0200
commit82638844d9a8581bbf33201cc209a14876eca167 (patch)
tree961d7f9360194421a71aa644a9d0c176a960ce49 /net
parent9982fbface82893e77d211fbabfbd229da6bdde6 (diff)
parent63cf13b77ab785e87c867defa8545e6d4a989774 (diff)
Merge branch 'linus' into cpus4096
Conflicts: arch/x86/xen/smp.c kernel/sched_rt.c net/iucv/iucv.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net')
-rw-r--r--net/802/psnap.c1
-rw-r--r--net/8021q/vlan.c1
-rw-r--r--net/bridge/br_fdb.c1
-rw-r--r--net/bridge/br_if.c10
-rw-r--r--net/bridge/br_stp.c1
-rw-r--r--net/can/af_can.c10
-rw-r--r--net/can/bcm.c23
-rw-r--r--net/can/raw.c3
-rw-r--r--net/core/dev.c4
-rw-r--r--net/core/flow.c2
-rw-r--r--net/ipv4/fib_trie.c17
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c2
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_probe.c2
-rw-r--r--net/ipv6/addrconf.c4
-rw-r--r--net/ipv6/exthdrs.c2
-rw-r--r--net/irda/irnet/irnet.h1
-rw-r--r--net/irda/irnet/irnet_ppp.c3
-rw-r--r--net/irda/irnetlink.c4
-rw-r--r--net/iucv/af_iucv.c8
-rw-r--r--net/iucv/iucv.c25
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mlme.c13
-rw-r--r--net/mac80211/rc80211_pid.h5
-rw-r--r--net/mac80211/rc80211_pid_algo.c31
-rw-r--r--net/netfilter/nf_conntrack_helper.c1
-rw-r--r--net/netfilter/nf_conntrack_netlink.c1
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c10
-rw-r--r--net/netlabel/netlabel_cipso_v4.c7
-rw-r--r--net/netlabel/netlabel_domainhash.c3
-rw-r--r--net/netlabel/netlabel_mgmt.c12
-rw-r--r--net/netlabel/netlabel_unlabeled.c6
-rw-r--r--net/sctp/sm_statefuns.c9
-rw-r--r--net/sctp/ulpevent.c5
-rw-r--r--net/sunrpc/rpcb_clnt.c23
-rw-r--r--net/xfrm/xfrm_user.c3
36 files changed, 137 insertions, 124 deletions
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 31128cb92a2..ea464393144 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -20,6 +20,7 @@
#include <linux/mm.h>
#include <linux/in.h>
#include <linux/init.h>
+#include <linux/rculist.h>
static LIST_HEAD(snap_list);
static DEFINE_SPINLOCK(snap_lock);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index ab2225da0ee..08f14f6c5fd 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -27,6 +27,7 @@
#include <linux/mm.h>
#include <linux/in.h>
#include <linux/init.h>
+#include <linux/rculist.h>
#include <net/p8022.h>
#include <net/arp.h>
#include <linux/rtnetlink.h>
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 72c5976a5ce..142060f0205 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/rculist.h>
#include <linux/spinlock.h>
#include <linux/times.h>
#include <linux/netdevice.h>
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index c2397f503b0..f38cc5317b8 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -442,12 +442,16 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
void __exit br_cleanup_bridges(void)
{
- struct net_device *dev, *nxt;
+ struct net_device *dev;
rtnl_lock();
- for_each_netdev_safe(&init_net, dev, nxt)
- if (dev->priv_flags & IFF_EBRIDGE)
+restart:
+ for_each_netdev(&init_net, dev) {
+ if (dev->priv_flags & IFF_EBRIDGE) {
del_br(dev->priv);
+ goto restart;
+ }
+ }
rtnl_unlock();
}
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index e38034aa56f..9e96ffcd29a 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -13,6 +13,7 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/kernel.h>
+#include <linux/rculist.h>
#include "br_private.h"
#include "br_private_stp.h"
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 7e8ca283645..484bbf6dd03 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -205,12 +205,19 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
* -ENOBUFS on full driver queue (see net_xmit_errno())
* -ENOMEM when local loopback failed at calling skb_clone()
* -EPERM when trying to send on a non-CAN interface
+ * -EINVAL when the skb->data does not contain a valid CAN frame
*/
int can_send(struct sk_buff *skb, int loop)
{
struct sk_buff *newskb = NULL;
+ struct can_frame *cf = (struct can_frame *)skb->data;
int err;
+ if (skb->len != sizeof(struct can_frame) || cf->can_dlc > 8) {
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+
if (skb->dev->type != ARPHRD_CAN) {
kfree_skb(skb);
return -EPERM;
@@ -605,6 +612,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
struct dev_rcv_lists *d;
+ struct can_frame *cf = (struct can_frame *)skb->data;
int matches;
if (dev->type != ARPHRD_CAN || dev_net(dev) != &init_net) {
@@ -612,6 +620,8 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
return 0;
}
+ BUG_ON(skb->len != sizeof(struct can_frame) || cf->can_dlc > 8);
+
/* update statistics */
can_stats.rx_frames++;
can_stats.rx_frames_delta++;
diff --git a/net/can/bcm.c b/net/can/bcm.c
index d9a3a9d13be..72c2ce904f8 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -298,7 +298,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
if (head->nframes) {
/* can_frames starting here */
- firstframe = (struct can_frame *) skb_tail_pointer(skb);
+ firstframe = (struct can_frame *)skb_tail_pointer(skb);
memcpy(skb_put(skb, datalen), frames, datalen);
@@ -826,6 +826,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
for (i = 0; i < msg_head->nframes; i++) {
err = memcpy_fromiovec((u8 *)&op->frames[i],
msg->msg_iov, CFSIZ);
+
+ if (op->frames[i].can_dlc > 8)
+ err = -EINVAL;
+
if (err < 0)
return err;
@@ -858,6 +862,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
for (i = 0; i < msg_head->nframes; i++) {
err = memcpy_fromiovec((u8 *)&op->frames[i],
msg->msg_iov, CFSIZ);
+
+ if (op->frames[i].can_dlc > 8)
+ err = -EINVAL;
+
if (err < 0) {
if (op->frames != &op->sframe)
kfree(op->frames);
@@ -1164,9 +1172,12 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
skb->dev = dev;
skb->sk = sk;
- can_send(skb, 1); /* send with loopback */
+ err = can_send(skb, 1); /* send with loopback */
dev_put(dev);
+ if (err)
+ return err;
+
return CFSIZ + MHSIZ;
}
@@ -1185,6 +1196,10 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
if (!bo->bound)
return -ENOTCONN;
+ /* check for valid message length from userspace */
+ if (size < MHSIZ || (size - MHSIZ) % CFSIZ)
+ return -EINVAL;
+
/* check for alternative ifindex for this bcm_op */
if (!ifindex && msg->msg_name) {
@@ -1259,8 +1274,8 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
break;
case TX_SEND:
- /* we need at least one can_frame */
- if (msg_head.nframes < 1)
+ /* we need exactly one can_frame behind the msg head */
+ if ((msg_head.nframes != 1) || (size != CFSIZ + MHSIZ))
ret = -EINVAL;
else
ret = bcm_tx_send(msg, ifindex, sk);
diff --git a/net/can/raw.c b/net/can/raw.c
index 69877b8e7e9..3e46ee36a1a 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -632,6 +632,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
} else
ifindex = ro->ifindex;
+ if (size != sizeof(struct can_frame))
+ return -EINVAL;
+
dev = dev_get_by_index(&init_net, ifindex);
if (!dev)
return -ENXIO;
diff --git a/net/core/dev.c b/net/core/dev.c
index 94d9d6f77e0..df5520a60b9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4585,8 +4585,8 @@ static int __init net_dev_init(void)
dev_boot_phase = 0;
- open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
- open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);
+ open_softirq(NET_TX_SOFTIRQ, net_tx_action);
+ open_softirq(NET_RX_SOFTIRQ, net_rx_action);
hotcpu_notifier(dev_cpu_callback, 0);
dst_init();
diff --git a/net/core/flow.c b/net/core/flow.c
index 19991175fde..5cf81052d04 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -298,7 +298,7 @@ void flow_cache_flush(void)
init_completion(&info.completion);
local_bh_disable();
- smp_call_function(flow_cache_flush_per_cpu, &info, 1, 0);
+ smp_call_function(flow_cache_flush_per_cpu, &info, 0);
flow_cache_flush_tasklet((unsigned long)&info);
local_bh_enable();
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 4b02d14e7ab..e1600ad8fb0 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1359,17 +1359,17 @@ static int check_leaf(struct trie *t, struct leaf *l,
t->stats.semantic_match_miss++;
#endif
if (err <= 0)
- return plen;
+ return err;
}
- return -1;
+ return 1;
}
static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
struct fib_result *res)
{
struct trie *t = (struct trie *) tb->tb_data;
- int plen, ret = 0;
+ int ret;
struct node *n;
struct tnode *pn;
int pos, bits;
@@ -1393,10 +1393,7 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
/* Just a leaf? */
if (IS_LEAF(n)) {
- plen = check_leaf(t, (struct leaf *)n, key, flp, res);
- if (plen < 0)
- goto failed;
- ret = 0;
+ ret = check_leaf(t, (struct leaf *)n, key, flp, res);
goto found;
}
@@ -1421,11 +1418,9 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
}
if (IS_LEAF(n)) {
- plen = check_leaf(t, (struct leaf *)n, key, flp, res);
- if (plen < 0)
+ ret = check_leaf(t, (struct leaf *)n, key, flp, res);
+ if (ret > 0)
goto backtrace;
-
- ret = 0;
goto found;
}
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 7750c97fde7..ffeaffc3fff 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -439,8 +439,8 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,
unsigned int *len)
{
unsigned long subid;
- unsigned int size;
unsigned long *optr;
+ size_t size;
size = eoc - ctx->pointer + 1;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 850825dc86e..1d723de1868 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -255,6 +255,7 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/skbuff.h>
+#include <linux/scatterlist.h>
#include <linux/splice.h>
#include <linux/net.h>
#include <linux/socket.h>
@@ -1208,7 +1209,8 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
return -ENOTCONN;
while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
if (offset < skb->len) {
- size_t used, len;
+ int used;
+ size_t len;
len = skb->len - offset;
/* Stop reading if we hit a patch of urgent data */
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index 5ff0ce6e9d3..7ddc30f0744 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -224,7 +224,7 @@ static __init int tcpprobe_init(void)
if (bufsize < 0)
return -EINVAL;
- tcp_probe.log = kcalloc(sizeof(struct tcp_log), bufsize, GFP_KERNEL);
+ tcp_probe.log = kcalloc(bufsize, sizeof(struct tcp_log), GFP_KERNEL);
if (!tcp_probe.log)
goto err0;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 147588f4c7c..ff61a5cdb0b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -749,12 +749,12 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
}
write_unlock_bh(&idev->lock);
+ addrconf_del_timer(ifp);
+
ipv6_ifa_notify(RTM_DELADDR, ifp);
atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp);
- addrconf_del_timer(ifp);
-
/*
* Purge or update corresponding prefix
*
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 3cd1c993d52..dcf94fdfb86 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -445,7 +445,7 @@ looped_back:
kfree_skb(skb);
return -1;
}
- if (!ipv6_chk_home_addr(&init_net, addr)) {
+ if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) {
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
IPSTATS_MIB_INADDRERRORS);
kfree_skb(skb);
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
index b001c361ad3..bccf4d0059f 100644
--- a/net/irda/irnet/irnet.h
+++ b/net/irda/irnet/irnet.h
@@ -241,6 +241,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include <linux/tty.h>
#include <linux/proc_fs.h>
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index e0eab5927c4..e84a70dd346 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -479,6 +479,7 @@ dev_irnet_open(struct inode * inode,
ap = kzalloc(sizeof(*ap), GFP_KERNEL);
DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n");
+ lock_kernel();
/* initialize the irnet structure */
ap->file = file;
@@ -500,6 +501,7 @@ dev_irnet_open(struct inode * inode,
{
DERROR(FS_ERROR, "Can't setup IrDA link...\n");
kfree(ap);
+ unlock_kernel();
return err;
}
@@ -510,6 +512,7 @@ dev_irnet_open(struct inode * inode,
file->private_data = ap;
DEXIT(FS_TRACE, " - ap=0x%p\n", ap);
+ unlock_kernel();
return 0;
}
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index 9e1fb82e322..2f05ec1037a 100644
--- a/net/irda/irnetlink.c
+++ b/net/irda/irnetlink.c
@@ -101,8 +101,8 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
&irda_nl_family, 0, IRDA_NL_CMD_GET_MODE);
- if (IS_ERR(hdr)) {
- ret = PTR_ERR(hdr);
+ if (hdr == NULL) {
+ ret = -EMSGSIZE;
goto err_out;
}
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 7b0038f45b1..bda71015885 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1135,8 +1135,7 @@ static void iucv_callback_txdone(struct iucv_path *path,
if (this)
kfree_skb(this);
}
- if (!this)
- printk(KERN_ERR "AF_IUCV msg tag %u not found\n", msg->tag);
+ BUG_ON(!this);
if (sk->sk_state == IUCV_CLOSING) {
if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) {
@@ -1196,7 +1195,7 @@ static int __init afiucv_init(void)
}
cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err);
if (unlikely(err)) {
- printk(KERN_ERR "AF_IUCV needs the VM userid\n");
+ WARN_ON(err);
err = -EPROTONOSUPPORT;
goto out;
}
@@ -1210,7 +1209,6 @@ static int __init afiucv_init(void)
err = sock_register(&iucv_sock_family_ops);
if (err)
goto out_proto;
- printk(KERN_INFO "AF_IUCV lowlevel driver initialized\n");
return 0;
out_proto:
@@ -1226,8 +1224,6 @@ static void __exit afiucv_exit(void)
sock_unregister(PF_IUCV);
proto_unregister(&iucv_proto);
iucv_unregister(&af_iucv_handler, 0);
-
- printk(KERN_INFO "AF_IUCV lowlevel driver unloaded\n");
}
module_init(afiucv_init);
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 8de51107059..411b339a0c8 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -480,7 +480,7 @@ static void iucv_setmask_mp(void)
if (cpu_isset(cpu, iucv_buffer_cpumask) &&
!cpu_isset(cpu, iucv_irq_cpumask))
smp_call_function_single(cpu, iucv_allow_cpu,
- NULL, 0, 1);
+ NULL, 1);
preempt_enable();
}
@@ -498,7 +498,7 @@ static void iucv_setmask_up(void)
cpumask = iucv_irq_cpumask;
cpu_clear(first_cpu(iucv_irq_cpumask), cpumask);
for_each_cpu_mask_nr(cpu, cpumask)
- smp_call_function_single(cpu, iucv_block_cpu, NULL, 0, 1);
+ smp_call_function_single(cpu, iucv_block_cpu, NULL, 1);
}
/**
@@ -523,7 +523,7 @@ static int iucv_enable(void)
rc = -EIO;
preempt_disable();
for_each_online_cpu(cpu)
- smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1);
+ smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1);
preempt_enable();
if (cpus_empty(iucv_buffer_cpumask))
/* No cpu could declare an iucv buffer. */
@@ -545,7 +545,7 @@ out:
*/
static void iucv_disable(void)
{
- on_each_cpu(iucv_retrieve_cpu, NULL, 0, 1);
+ on_each_cpu(iucv_retrieve_cpu, NULL, 1);
kfree(iucv_path_table);
}
@@ -580,7 +580,7 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
case CPU_ONLINE_FROZEN:
case CPU_DOWN_FAILED:
case CPU_DOWN_FAILED_FROZEN:
- smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1);
+ smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1);
break;
case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN:
@@ -589,10 +589,10 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
if (cpus_empty(cpumask))
/* Can't offline last IUCV enabled cpu. */
return NOTIFY_BAD;
- smp_call_function_single(cpu, iucv_retrieve_cpu, NULL, 0, 1);
+ smp_call_function_single(cpu, iucv_retrieve_cpu, NULL, 1);
if (cpus_empty(iucv_irq_cpumask))
smp_call_function_single(first_cpu(iucv_buffer_cpumask),
- iucv_allow_cpu, NULL, 0, 1);
+ iucv_allow_cpu, NULL, 1);
break;
}
return NOTIFY_OK;
@@ -652,7 +652,7 @@ static void iucv_cleanup_queue(void)
* pending interrupts force them to the work queue by calling
* an empty function on all cpus.
*/
- smp_call_function(__iucv_cleanup_queue, NULL, 0, 1);
+ smp_call_function(__iucv_cleanup_queue, NULL, 1);
spin_lock_irq(&iucv_queue_lock);
list_for_each_entry_safe(p, n, &iucv_task_queue, list) {
/* Remove stale work items from the task queue. */
@@ -1559,16 +1559,11 @@ static void iucv_external_interrupt(u16 code)
p = iucv_irq_data[smp_processor_id()];
if (p->ippathid >= iucv_max_pathid) {
- printk(KERN_WARNING "iucv_do_int: Got interrupt with "
- "pathid %d > max_connections (%ld)\n",
- p->ippathid, iucv_max_pathid - 1);
+ WARN_ON(p->ippathid >= iucv_max_pathid);
iucv_sever_pathid(p->ippathid, iucv_error_no_listener);
return;
}
- if (p->iptype < 0x01 || p->iptype > 0x09) {
- printk(KERN_ERR "iucv_do_int: unknown iucv interrupt\n");
- return;
- }
+ BUG_ON(p->iptype < 0x01 || p->iptype > 0x09);
work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC);
if (!work) {
printk(KERN_WARNING "iucv_external_interrupt: out of memory\n");
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 98c0b5e56ec..df0836ff1a2 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -530,8 +530,6 @@ static int ieee80211_stop(struct net_device *dev)
local->sta_hw_scanning = 0;
}
- flush_workqueue(local->hw.workqueue);
-
sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
kfree(sdata->u.sta.extra_ie);
sdata->u.sta.extra_ie = NULL;
@@ -555,6 +553,8 @@ static int ieee80211_stop(struct net_device *dev)
ieee80211_led_radio(local, 0);
+ flush_workqueue(local->hw.workqueue);
+
tasklet_disable(&local->tx_pending_tasklet);
tasklet_disable(&local->tasklet);
}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4d2b582dd05..b404537c0bc 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -547,15 +547,14 @@ static void ieee80211_set_associated(struct net_device *dev,
sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
}
- netif_carrier_on(dev);
ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
ieee80211_sta_send_associnfo(dev, ifsta);
} else {
+ netif_carrier_off(dev);
ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid);
ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
- netif_carrier_off(dev);
ieee80211_reset_erp_info(dev);
sdata->bss_conf.assoc_ht = 0;
@@ -569,6 +568,10 @@ static void ieee80211_set_associated(struct net_device *dev,
sdata->bss_conf.assoc = assoc;
ieee80211_bss_info_change_notify(sdata, changed);
+
+ if (assoc)
+ netif_carrier_on(dev);
+
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
}
@@ -3611,8 +3614,10 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
spin_unlock_bh(&local->sta_bss_lock);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
- printk(KERN_DEBUG " sta_find_ibss: selected %s current "
- "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid));
+ if (found)
+ printk(KERN_DEBUG " sta_find_ibss: selected %s current "
+ "%s\n", print_mac(mac, bssid),
+ print_mac(mac2, ifsta->bssid));
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
(bss = ieee80211_rx_bss_get(dev, bssid,
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h
index 04afc13ed82..4ea7b97d1af 100644
--- a/net/mac80211/rc80211_pid.h
+++ b/net/mac80211/rc80211_pid.h
@@ -141,7 +141,6 @@ struct rc_pid_events_file_info {
* rate behaviour values (lower means we should trust more what we learnt
* about behaviour of rates, higher means we should trust more the natural
* ordering of rates)
- * @fast_start: if Y, push high rates right after initialization
*/
struct rc_pid_debugfs_entries {
struct dentry *dir;
@@ -154,7 +153,6 @@ struct rc_pid_debugfs_entries {
struct dentry *sharpen_factor;
struct dentry *sharpen_duration;
struct dentry *norm_offset;
- struct dentry *fast_start;
};
void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
@@ -267,9 +265,6 @@ struct rc_pid_info {
/* Normalization offset. */
unsigned int norm_offset;
- /* Fast starst parameter. */
- unsigned int fast_start;
-
/* Rates information. */
struct rc_pid_rateinfo *rinfo;
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index a849b745bdb..bcd27c1d759 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -398,13 +398,25 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
return NULL;
}
+ pinfo->target = RC_PID_TARGET_PF;
+ pinfo->sampling_period = RC_PID_INTERVAL;
+ pinfo->coeff_p = RC_PID_COEFF_P;
+ pinfo->coeff_i = RC_PID_COEFF_I;
+ pinfo->coeff_d = RC_PID_COEFF_D;
+ pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
+ pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
+ pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
+ pinfo->norm_offset = RC_PID_NORM_OFFSET;
+ pinfo->rinfo = rinfo;
+ pinfo->oldrate = 0;
+
/* Sort the rates. This is optimized for the most common case (i.e.
* almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
* mapping too. */
for (i = 0; i < sband->n_bitrates; i++) {
rinfo[i].index = i;
rinfo[i].rev_index = i;
- if (pinfo->fast_start)
+ if (RC_PID_FAST_START)
rinfo[i].diff = 0;
else
rinfo[i].diff = i * pinfo->norm_offset;
@@ -425,19 +437,6 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
break;
}
- pinfo->target = RC_PID_TARGET_PF;
- pinfo->sampling_period = RC_PID_INTERVAL;
- pinfo->coeff_p = RC_PID_COEFF_P;
- pinfo->coeff_i = RC_PID_COEFF_I;
- pinfo->coeff_d = RC_PID_COEFF_D;
- pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
- pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
- pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
- pinfo->norm_offset = RC_PID_NORM_OFFSET;
- pinfo->fast_start = RC_PID_FAST_START;
- pinfo->rinfo = rinfo;
- pinfo->oldrate = 0;
-
#ifdef CONFIG_MAC80211_DEBUGFS
de = &pinfo->dentries;
de->dir = debugfs_create_dir("rc80211_pid",
@@ -465,9 +464,6 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
de->norm_offset = debugfs_create_u32("norm_offset",
S_IRUSR | S_IWUSR, de->dir,
&pinfo->norm_offset);
- de->fast_start = debugfs_create_bool("fast_start",
- S_IRUSR | S_IWUSR, de->dir,
- &pinfo->fast_start);
#endif
return pinfo;
@@ -479,7 +475,6 @@ static void rate_control_pid_free(void *priv)
#ifdef CONFIG_MAC80211_DEBUGFS
struct rc_pid_debugfs_entries *de = &pinfo->dentries;
- debugfs_remove(de->fast_start);
debugfs_remove(de->norm_offset);
debugfs_remove(de->sharpen_duration);
debugfs_remove(de->sharpen_factor);
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 7d1b1170374..8e0b4c8f62a 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -20,6 +20,7 @@
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/rculist.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_l3proto.h>
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 0edefcfc594..077bcd22879 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/rculist.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/skbuff.h>
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 271cd01d57a..dd28fb239a6 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -844,9 +844,15 @@ static int tcp_packet(struct nf_conn *ct,
/* Attempt to reopen a closed/aborted connection.
* Delete this connection and look up again. */
write_unlock_bh(&tcp_lock);
- if (del_timer(&ct->timeout))
+ /* Only repeat if we can actually remove the timer.
+ * Destruction may already be in progress in process
+ * context and we must give it a chance to terminate.
+ */
+ if (del_timer(&ct->timeout)) {
ct->timeout.function((unsigned long)ct);
- return -NF_REPEAT;
+ return -NF_REPEAT;
+ }
+ return -NF_DROP;
}
/* Fall through */
case TCP_CONNTRACK_IGNORE:
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index fdc14a0d21a..9080c61b71a 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -584,12 +584,7 @@ list_start:
rcu_read_unlock();
genlmsg_end(ans_skb, data);
-
- ret_val = genlmsg_reply(ans_skb, info);
- if (ret_val != 0)
- goto list_failure;
-
- return 0;
+ return genlmsg_reply(ans_skb, info);
list_retry:
/* XXX - this limit is a guesstimate */
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 02c2f7c0b25..643c032a3a5 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -30,8 +30,7 @@
*/
#include <linux/types.h>
-#include <linux/rcupdate.h>
-#include <linux/list.h>
+#include <linux/rculist.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/string.h>
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 22c19126780..44be5d5261f 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -386,11 +386,7 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
rcu_read_unlock();
genlmsg_end(ans_skb, data);
-
- ret_val = genlmsg_reply(ans_skb, info);
- if (ret_val != 0)
- goto listdef_failure;
- return 0;
+ return genlmsg_reply(ans_skb, info);
listdef_failure_lock:
rcu_read_unlock();
@@ -501,11 +497,7 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
goto version_failure;
genlmsg_end(ans_skb, data);
-
- ret_val = genlmsg_reply(ans_skb, info);
- if (ret_val != 0)
- goto version_failure;
- return 0;
+ return genlmsg_reply(ans_skb, info);
version_failure:
kfree_skb(ans_skb);
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 52b2611a6eb..56f80872924 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1107,11 +1107,7 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info)
goto list_failure;
genlmsg_end(ans_skb, data);
-
- ret_val = genlmsg_reply(ans_skb, info);
- if (ret_val != 0)
- goto list_failure;
- return 0;
+ return genlmsg_reply(ans_skb, info);
list_failure:
kfree_skb(ans_skb);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 0c9d5a6950f..fcdb45d1071 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -5899,12 +5899,6 @@ static int sctp_eat_data(const struct sctp_association *asoc,
return SCTP_IERROR_NO_DATA;
}
- /* If definately accepting the DATA chunk, record its TSN, otherwise
- * wait for renege processing.
- */
- if (SCTP_CMD_CHUNK_ULP == deliver)
- sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
-
chunk->data_accepted = 1;
/* Note: Some chunks may get overcounted (if we drop) or overcounted
@@ -5924,6 +5918,9 @@ static int sctp_eat_data(const struct sctp_association *asoc,
* and discard the DATA chunk.
*/
if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) {
+ /* Mark tsn as received even though we drop it */
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
+
err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
&data_hdr->stream,
sizeof(data_hdr->stream));
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index ce6cda6b699..a1f654aea26 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -710,6 +710,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
if (!skb)
goto fail;
+ /* Now that all memory allocations for this chunk succeeded, we
+ * can mark it as received so the tsn_map is updated correctly.
+ */
+ sctp_tsnmap_mark(&asoc->peer.tsn_map, ntohl(chunk->subh.data_hdr->tsn));
+
/* First calculate the padding, so we don't inadvertently
* pass up the wrong length to the user.
*
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 0517967a68b..e6fb21b19b8 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -243,10 +243,10 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
}
EXPORT_SYMBOL_GPL(rpcb_getport_sync);
-static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, int version)
+static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc)
{
struct rpc_message msg = {
- .rpc_proc = rpcb_next_version[version].rpc_proc,
+ .rpc_proc = proc,
.rpc_argp = map,
.rpc_resp = &map->r_port,
};
@@ -271,6 +271,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
void rpcb_getport_async(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
+ struct rpc_procinfo *proc;
u32 bind_version;
struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_clnt *rpcb_clnt;
@@ -280,7 +281,6 @@ void rpcb_getport_async(struct rpc_task *task)
struct sockaddr *sap = (struct sockaddr *)&addr;
size_t salen;
int status;
- struct rpcb_info *info;
dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
task->tk_pid, __func__,
@@ -313,10 +313,12 @@ void rpcb_getport_async(struct rpc_task *task)
/* Don't ever use rpcbind v2 for AF_INET6 requests */
switch (sap->sa_family) {
case AF_INET:
- info = rpcb_next_version;
+ proc = rpcb_next_version[xprt->bind_index].rpc_proc;
+ bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
break;
case AF_INET6:
- info = rpcb_next_version6;
+ proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
+ bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
break;
default:
status = -EAFNOSUPPORT;
@@ -324,14 +326,13 @@ void rpcb_getport_async(struct rpc_task *task)
task->tk_pid, __func__);
goto bailout_nofree;
}
- if (info[xprt->bind_index].rpc_proc == NULL) {
+ if (proc == NULL) {
xprt->bind_index = 0;
status = -EPFNOSUPPORT;
dprintk("RPC: %5u %s: no more getport versions available\n",
task->tk_pid, __func__);
goto bailout_nofree;
}
- bind_version = info[xprt->bind_index].rpc_vers;
dprintk("RPC: %5u %s: trying rpcbind version %u\n",
task->tk_pid, __func__, bind_version);
@@ -361,22 +362,20 @@ void rpcb_getport_async(struct rpc_task *task)
map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */
- child = rpcb_call_async(rpcb_clnt, map, xprt->bind_index);
+ child = rpcb_call_async(rpcb_clnt, map, proc);
rpc_release_client(rpcb_clnt);
if (IS_ERR(child)) {
status = -EIO;
+ /* rpcb_map_release() has freed the arguments */
dprintk("RPC: %5u %s: rpc_run_task failed\n",
task->tk_pid, __func__);
- goto bailout;
+ goto bailout_nofree;
}
rpc_put_task(child);
task->tk_xprt->stat.bind_count++;
return;
-bailout:
- kfree(map);
- xprt_put(xprt);
bailout_nofree:
rpcb_wake_rpcbind_waiters(xprt, status);
bailout_nowake:
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b976d9ed10e..04c41504f84 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -277,9 +277,8 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr));
x->props.flags = p->flags;
- if (!x->sel.family)
+ if (!x->sel.family && !(p->flags & XFRM_STATE_AF_UNSPEC))
x->sel.family = p->family;
-
}
/*