aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/bnep/bnep.h4
-rw-r--r--net/bluetooth/bnep/core.c4
-rw-r--r--net/bluetooth/bnep/netdev.c4
-rw-r--r--net/bluetooth/bnep/sock.c4
-rw-r--r--net/bluetooth/rfcomm/core.c2
-rw-r--r--net/bluetooth/rfcomm/sock.c2
-rw-r--r--net/bluetooth/rfcomm/tty.c2
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/bridge/br_device.c13
-rw-r--r--net/bridge/br_fdb.c2
-rw-r--r--net/bridge/br_forward.c4
-rw-r--r--net/bridge/br_if.c2
-rw-r--r--net/bridge/br_input.c12
-rw-r--r--net/bridge/br_ioctl.c2
-rw-r--r--net/bridge/br_notify.c2
-rw-r--r--net/bridge/br_private.h3
-rw-r--r--net/bridge/br_private_stp.h2
-rw-r--r--net/bridge/br_stp.c2
-rw-r--r--net/bridge/br_stp_bpdu.c2
-rw-r--r--net/bridge/br_stp_if.c2
-rw-r--r--net/bridge/br_stp_timer.c2
-rw-r--r--net/bridge/netfilter/Kconfig9
-rw-r--r--net/bridge/netfilter/Makefile1
-rw-r--r--net/bridge/netfilter/ebt_ip6.c144
-rw-r--r--net/bridge/netfilter/ebt_log.c64
-rw-r--r--net/core/net-sysfs.c9
-rw-r--r--net/core/rtnetlink.c20
-rw-r--r--net/core/skbuff.c2
-rw-r--r--net/core/sock.c2
-rw-r--r--net/core/sysctl_net_core.c39
-rw-r--r--net/ieee80211/ieee80211_rx.c2
-rw-r--r--net/ieee80211/ieee80211_tx.c86
-rw-r--r--net/ieee80211/ieee80211_wx.c89
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/arp.c2
-rw-r--r--net/ipv4/devinet.c6
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/fib_hash.c2
-rw-r--r--net/ipv4/fib_semantics.c2
-rw-r--r--net/ipv4/fib_trie.c2
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/inetpeer.c2
-rw-r--r--net/ipv4/ip_forward.c2
-rw-r--r--net/ipv4/ip_fragment.c36
-rw-r--r--net/ipv4/ip_gre.c32
-rw-r--r--net/ipv4/ip_input.c2
-rw-r--r--net/ipv4/ip_options.c2
-rw-r--r--net/ipv4/ip_output.c2
-rw-r--r--net/ipv4/ip_sockglue.c2
-rw-r--r--net/ipv4/ipconfig.c2
-rw-r--r--net/ipv4/ipip.c24
-rw-r--r--net/ipv4/ipmr.c31
-rw-r--r--net/ipv4/ipvs/ip_vs_app.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_dh.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_est.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_ftp.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_lblc.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_lblcr.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_lc.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_nq.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_ah.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_esp.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_tcp.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_rr.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_sched.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_sed.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_sh.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_wlc.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_wrr.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_xmit.c2
-rw-r--r--net/ipv4/netfilter/Kconfig12
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/ip_queue.c3
-rw-r--r--net/ipv4/netfilter/iptable_security.c180
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c5
-rw-r--r--net/ipv4/proc.c2
-rw-r--r--net/ipv4/protocol.c2
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/ipv4/syncookies.c2
-rw-r--r--net/ipv4/sysctl_net_ipv4.c2
-rw-r--r--net/ipv4/tcp.c72
-rw-r--r--net/ipv4/tcp_diag.c2
-rw-r--r--net/ipv4/tcp_input.c42
-rw-r--r--net/ipv4/tcp_ipv4.c166
-rw-r--r--net/ipv4/tcp_minisocks.c2
-rw-r--r--net/ipv4/tcp_output.c5
-rw-r--r--net/ipv4/tcp_timer.c2
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv4/udplite.c2
-rw-r--r--net/ipv6/addrconf.c24
-rw-r--r--net/ipv6/addrlabel.c106
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/datagram.c2
-rw-r--r--net/ipv6/exthdrs.c2
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_input.c2
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ip6_tunnel.c28
-rw-r--r--net/ipv6/ip6mr.c24
-rw-r--r--net/ipv6/ipv6_sockglue.c2
-rw-r--r--net/ipv6/mcast.c3
-rw-r--r--net/ipv6/netfilter/Kconfig12
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/ip6_queue.c3
-rw-r--r--net/ipv6/netfilter/ip6table_security.c172
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c5
-rw-r--r--net/ipv6/proc.c2
-rw-r--r--net/ipv6/protocol.c2
-rw-r--r--net/ipv6/raw.c2
-rw-r--r--net/ipv6/reassembly.c63
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/sit.c26
-rw-r--r--net/ipv6/sysctl_net_ipv6.c29
-rw-r--r--net/ipv6/tcp_ipv6.c138
-rw-r--r--net/ipv6/udp.c2
-rw-r--r--net/ipv6/udplite.c2
-rw-r--r--net/irda/irnet/irnet_ppp.c54
-rw-r--r--net/irda/irnet/irnet_ppp.h7
-rw-r--r--net/iucv/af_iucv.c1
-rw-r--r--net/iucv/iucv.c13
-rw-r--r--net/key/af_key.c622
-rw-r--r--net/mac80211/Kconfig14
-rw-r--r--net/mac80211/Makefile2
-rw-r--r--net/mac80211/aes_ccm.c2
-rw-r--r--net/mac80211/aes_ccm.h2
-rw-r--r--net/mac80211/cfg.c6
-rw-r--r--net/mac80211/debugfs.c43
-rw-r--r--net/mac80211/debugfs_key.c8
-rw-r--r--net/mac80211/debugfs_netdev.c11
-rw-r--r--net/mac80211/debugfs_sta.c56
-rw-r--r--net/mac80211/ieee80211_i.h92
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac80211/key.c11
-rw-r--r--net/mac80211/key.h17
-rw-r--r--net/mac80211/main.c329
-rw-r--r--net/mac80211/mesh.c38
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_hwmp.c2
-rw-r--r--net/mac80211/mesh_pathtbl.c53
-rw-r--r--net/mac80211/mesh_plink.c88
-rw-r--r--net/mac80211/michael.c106
-rw-r--r--net/mac80211/michael.h8
-rw-r--r--net/mac80211/mlme.c225
-rw-r--r--net/mac80211/rate.c12
-rw-r--r--net/mac80211/rate.h33
-rw-r--r--net/mac80211/rc80211_pid.h4
-rw-r--r--net/mac80211/rc80211_pid_algo.c22
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c8
-rw-r--r--net/mac80211/rx.c291
-rw-r--r--net/mac80211/sta_info.c22
-rw-r--r--net/mac80211/sta_info.h80
-rw-r--r--net/mac80211/tkip.c229
-rw-r--r--net/mac80211/tkip.h8
-rw-r--r--net/mac80211/tx.c863
-rw-r--r--net/mac80211/util.c59
-rw-r--r--net/mac80211/wep.c19
-rw-r--r--net/mac80211/wep.h2
-rw-r--r--net/mac80211/wext.c28
-rw-r--r--net/mac80211/wme.c147
-rw-r--r--net/mac80211/wme.h2
-rw-r--r--net/mac80211/wpa.c135
-rw-r--r--net/netfilter/nf_conntrack_core.c19
-rw-r--r--net/netfilter/nf_conntrack_extend.c10
-rw-r--r--net/netfilter/nf_conntrack_netlink.c30
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c3
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c80
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c9
-rw-r--r--net/netfilter/nfnetlink_queue.c1
-rw-r--r--net/netfilter/xt_CONNSECMARK.c10
-rw-r--r--net/netfilter/xt_SECMARK.c10
-rw-r--r--net/netlink/af_netlink.c4
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/sched/sch_htb.c2
-rw-r--r--net/sctp/associola.c3
-rw-r--r--net/sctp/proc.c141
-rw-r--r--net/sctp/protocol.c3
-rw-r--r--net/sctp/sm_sideeffect.c17
-rw-r--r--net/sctp/socket.c306
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sysctl_net.c31
-rw-r--r--net/tipc/bcast.c4
-rw-r--r--net/tipc/cluster.c2
-rw-r--r--net/tipc/config.c11
-rw-r--r--net/tipc/core.c13
-rw-r--r--net/tipc/core.h126
-rw-r--r--net/tipc/dbg.c231
-rw-r--r--net/tipc/dbg.h12
-rw-r--r--net/tipc/discover.c14
-rw-r--r--net/tipc/discover.h2
-rw-r--r--net/tipc/link.c80
-rw-r--r--net/tipc/msg.c13
-rw-r--r--net/tipc/msg.h42
-rw-r--r--net/tipc/name_distr.c6
-rw-r--r--net/tipc/name_table.c14
-rw-r--r--net/tipc/net.c10
-rw-r--r--net/tipc/net.h2
-rw-r--r--net/tipc/netlink.c16
-rw-r--r--net/tipc/node.c26
-rw-r--r--net/tipc/port.c79
-rw-r--r--net/tipc/ref.c12
-rw-r--r--net/tipc/socket.c5
-rw-r--r--net/tipc/subscr.c249
-rw-r--r--net/tipc/subscr.h34
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--net/wanrouter/wanmain.c6
-rw-r--r--net/wanrouter/wanproc.c2
-rw-r--r--net/wireless/core.c33
-rw-r--r--net/wireless/radiotap.c16
218 files changed, 3854 insertions, 3593 deletions
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h
index e69244dd8de8..b69bf4e7c48b 100644
--- a/net/bluetooth/bnep/bnep.h
+++ b/net/bluetooth/bnep/bnep.h
@@ -16,10 +16,6 @@
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/ 17*/
18 18
19/*
20 * $Id: bnep.h,v 1.5 2002/08/04 21:23:58 maxk Exp $
21 */
22
23#ifndef _BNEP_H 19#ifndef _BNEP_H
24#define _BNEP_H 20#define _BNEP_H
25 21
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index f85d94643aaf..1d98a1b80da7 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -25,10 +25,6 @@
25 SOFTWARE IS DISCLAIMED. 25 SOFTWARE IS DISCLAIMED.
26*/ 26*/
27 27
28/*
29 * $Id: core.c,v 1.20 2002/08/04 21:23:58 maxk Exp $
30 */
31
32#include <linux/module.h> 28#include <linux/module.h>
33 29
34#include <linux/kernel.h> 30#include <linux/kernel.h>
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index 95e3837e4312..d9fa0ab2c87f 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -25,10 +25,6 @@
25 SOFTWARE IS DISCLAIMED. 25 SOFTWARE IS DISCLAIMED.
26*/ 26*/
27 27
28/*
29 * $Id: netdev.c,v 1.8 2002/08/04 21:23:58 maxk Exp $
30 */
31
32#include <linux/module.h> 28#include <linux/module.h>
33 29
34#include <linux/socket.h> 30#include <linux/socket.h>
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 201e5b1ce473..8ffb57f2303a 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -24,10 +24,6 @@
24 SOFTWARE IS DISCLAIMED. 24 SOFTWARE IS DISCLAIMED.
25*/ 25*/
26 26
27/*
28 * $Id: sock.c,v 1.4 2002/08/04 21:23:58 maxk Exp $
29 */
30
31#include <linux/module.h> 27#include <linux/module.h>
32 28
33#include <linux/types.h> 29#include <linux/types.h>
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 0c2c93735e93..b4fb84e398e5 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -23,8 +23,6 @@
23 23
24/* 24/*
25 * Bluetooth RFCOMM core. 25 * Bluetooth RFCOMM core.
26 *
27 * $Id: core.c,v 1.42 2002/10/01 23:26:25 maxk Exp $
28 */ 26 */
29 27
30#include <linux/module.h> 28#include <linux/module.h>
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 5083adcbfae5..c9054487670a 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -23,8 +23,6 @@
23 23
24/* 24/*
25 * RFCOMM sockets. 25 * RFCOMM sockets.
26 *
27 * $Id: sock.c,v 1.24 2002/10/03 01:00:34 maxk Exp $
28 */ 26 */
29 27
30#include <linux/module.h> 28#include <linux/module.h>
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index c9191871c1e0..be84f4fc1477 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -23,8 +23,6 @@
23 23
24/* 24/*
25 * RFCOMM TTY. 25 * RFCOMM TTY.
26 *
27 * $Id: tty.c,v 1.24 2002/10/03 01:54:38 holtmann Exp $
28 */ 26 */
29 27
30#include <linux/module.h> 28#include <linux/module.h>
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 8f3c58e5f7a5..cede010f4ddd 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br.c,v 1.47 2001/12/24 00:56:41 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index bf7787395fe0..a6ffc6c2a69f 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_device.c,v 1.6 2001/12/24 00:59:55 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -21,12 +19,6 @@
21#include <asm/uaccess.h> 19#include <asm/uaccess.h>
22#include "br_private.h" 20#include "br_private.h"
23 21
24static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
25{
26 struct net_bridge *br = netdev_priv(dev);
27 return &br->statistics;
28}
29
30/* net device transmit always called with no BH (preempt_disabled) */ 22/* net device transmit always called with no BH (preempt_disabled) */
31int br_dev_xmit(struct sk_buff *skb, struct net_device *dev) 23int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
32{ 24{
@@ -34,8 +26,8 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
34 const unsigned char *dest = skb->data; 26 const unsigned char *dest = skb->data;
35 struct net_bridge_fdb_entry *dst; 27 struct net_bridge_fdb_entry *dst;
36 28
37 br->statistics.tx_packets++; 29 dev->stats.tx_packets++;
38 br->statistics.tx_bytes += skb->len; 30 dev->stats.tx_bytes += skb->len;
39 31
40 skb_reset_mac_header(skb); 32 skb_reset_mac_header(skb);
41 skb_pull(skb, ETH_HLEN); 33 skb_pull(skb, ETH_HLEN);
@@ -161,7 +153,6 @@ void br_dev_setup(struct net_device *dev)
161 ether_setup(dev); 153 ether_setup(dev);
162 154
163 dev->do_ioctl = br_dev_ioctl; 155 dev->do_ioctl = br_dev_ioctl;
164 dev->get_stats = br_dev_get_stats;
165 dev->hard_start_xmit = br_dev_xmit; 156 dev->hard_start_xmit = br_dev_xmit;
166 dev->open = br_dev_open; 157 dev->open = br_dev_open;
167 dev->set_multicast_list = br_dev_set_multicast_list; 158 dev->set_multicast_list = br_dev_set_multicast_list;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 72c5976a5ce3..4de74cdd091d 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_fdb.c,v 1.6 2002/01/17 00:57:07 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index bdd7c35c3c7b..512645727f51 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_forward.c,v 1.4 2001/08/14 22:05:57 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -115,7 +113,7 @@ static void br_flood(struct net_bridge *br, struct sk_buff *skb,
115 struct sk_buff *skb2; 113 struct sk_buff *skb2;
116 114
117 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) { 115 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) {
118 br->statistics.tx_dropped++; 116 br->dev->stats.tx_dropped++;
119 kfree_skb(skb); 117 kfree_skb(skb);
120 return; 118 return;
121 } 119 }
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index c2397f503b0f..143c954681b8 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_if.c,v 1.7 2001/12/24 00:59:55 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 255c00f60ce7..0145e9416714 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_input.c,v 1.10 2001/12/24 04:50:20 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -24,13 +22,13 @@ const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
24 22
25static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb) 23static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
26{ 24{
27 struct net_device *indev; 25 struct net_device *indev, *brdev = br->dev;
28 26
29 br->statistics.rx_packets++; 27 brdev->stats.rx_packets++;
30 br->statistics.rx_bytes += skb->len; 28 brdev->stats.rx_bytes += skb->len;
31 29
32 indev = skb->dev; 30 indev = skb->dev;
33 skb->dev = br->dev; 31 skb->dev = brdev;
34 32
35 NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, 33 NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
36 netif_receive_skb); 34 netif_receive_skb);
@@ -64,7 +62,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
64 dst = NULL; 62 dst = NULL;
65 63
66 if (is_multicast_ether_addr(dest)) { 64 if (is_multicast_ether_addr(dest)) {
67 br->statistics.multicast++; 65 br->dev->stats.multicast++;
68 skb2 = skb; 66 skb2 = skb;
69 } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) { 67 } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) {
70 skb2 = skb; 68 skb2 = skb;
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index 0655a5f07f58..eeee218eed80 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_ioctl.c,v 1.4 2000/11/08 05:16:40 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 00644a544e3c..88d8ec7b3142 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_notify.c,v 1.2 2000/02/21 15:51:34 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index c11b554fd109..83ff5861c2d2 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -4,8 +4,6 @@
4 * Authors: 4 * Authors:
5 * Lennert Buytenhek <buytenh@gnu.org> 5 * Lennert Buytenhek <buytenh@gnu.org>
6 * 6 *
7 * $Id: br_private.h,v 1.7 2001/12/24 00:59:55 davem Exp $
8 *
9 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
@@ -90,7 +88,6 @@ struct net_bridge
90 spinlock_t lock; 88 spinlock_t lock;
91 struct list_head port_list; 89 struct list_head port_list;
92 struct net_device *dev; 90 struct net_device *dev;
93 struct net_device_stats statistics;
94 spinlock_t hash_lock; 91 spinlock_t hash_lock;
95 struct hlist_head hash[BR_HASH_SIZE]; 92 struct hlist_head hash[BR_HASH_SIZE];
96 struct list_head age_list; 93 struct list_head age_list;
diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h
index e29f01ac1adf..8b650f7fbfa0 100644
--- a/net/bridge/br_private_stp.h
+++ b/net/bridge/br_private_stp.h
@@ -4,8 +4,6 @@
4 * Authors: 4 * Authors:
5 * Lennert Buytenhek <buytenh@gnu.org> 5 * Lennert Buytenhek <buytenh@gnu.org>
6 * 6 *
7 * $Id: br_private_stp.h,v 1.3 2001/02/05 06:03:47 davem Exp $
8 *
9 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index e38034aa56f5..284d1b2fa1ff 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_stp.c,v 1.4 2000/06/19 10:13:35 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index ddeb6e5d45d6..9dc2de656965 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_stp_bpdu.c,v 1.3 2001/11/10 02:35:25 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 1a430eccec9b..1a4e5c37a0cf 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_stp_if.c,v 1.4 2001/04/14 21:14:39 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c
index 77f5255e6915..772a140bfdf0 100644
--- a/net/bridge/br_stp_timer.c
+++ b/net/bridge/br_stp_timer.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_stp_timer.c,v 1.3 2000/05/05 02:17:17 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 7beeefa0f9c0..fb684c2ff8b6 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -83,6 +83,15 @@ config BRIDGE_EBT_IP
83 83
84 To compile it as a module, choose M here. If unsure, say N. 84 To compile it as a module, choose M here. If unsure, say N.
85 85
86config BRIDGE_EBT_IP6
87 tristate "ebt: IP6 filter support"
88 depends on BRIDGE_NF_EBTABLES
89 help
90 This option adds the IP6 match, which allows basic IPV6 header field
91 filtering.
92
93 To compile it as a module, choose M here. If unsure, say N.
94
86config BRIDGE_EBT_LIMIT 95config BRIDGE_EBT_LIMIT
87 tristate "ebt: limit match support" 96 tristate "ebt: limit match support"
88 depends on BRIDGE_NF_EBTABLES 97 depends on BRIDGE_NF_EBTABLES
diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
index 83715d73a503..dd960645b413 100644
--- a/net/bridge/netfilter/Makefile
+++ b/net/bridge/netfilter/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_BRIDGE_EBT_802_3) += ebt_802_3.o
14obj-$(CONFIG_BRIDGE_EBT_AMONG) += ebt_among.o 14obj-$(CONFIG_BRIDGE_EBT_AMONG) += ebt_among.o
15obj-$(CONFIG_BRIDGE_EBT_ARP) += ebt_arp.o 15obj-$(CONFIG_BRIDGE_EBT_ARP) += ebt_arp.o
16obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o 16obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o
17obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip6.o
17obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o 18obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o
18obj-$(CONFIG_BRIDGE_EBT_MARK) += ebt_mark_m.o 19obj-$(CONFIG_BRIDGE_EBT_MARK) += ebt_mark_m.o
19obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o 20obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c
new file mode 100644
index 000000000000..36efb3a75249
--- /dev/null
+++ b/net/bridge/netfilter/ebt_ip6.c
@@ -0,0 +1,144 @@
1/*
2 * ebt_ip6
3 *
4 * Authors:
5 * Manohar Castelino <manohar.r.castelino@intel.com>
6 * Kuo-Lang Tseng <kuo-lang.tseng@intel.com>
7 * Jan Engelhardt <jengelh@computergmbh.de>
8 *
9 * Summary:
10 * This is just a modification of the IPv4 code written by
11 * Bart De Schuymer <bdschuym@pandora.be>
12 * with the changes required to support IPv6
13 *
14 * Jan, 2008
15 */
16
17#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_ip6.h>
19#include <linux/ipv6.h>
20#include <net/ipv6.h>
21#include <linux/in.h>
22#include <linux/module.h>
23#include <net/dsfield.h>
24
25struct tcpudphdr {
26 __be16 src;
27 __be16 dst;
28};
29
30static int ebt_filter_ip6(const struct sk_buff *skb,
31 const struct net_device *in,
32 const struct net_device *out, const void *data,
33 unsigned int datalen)
34{
35 const struct ebt_ip6_info *info = (struct ebt_ip6_info *)data;
36 const struct ipv6hdr *ih6;
37 struct ipv6hdr _ip6h;
38 const struct tcpudphdr *pptr;
39 struct tcpudphdr _ports;
40 struct in6_addr tmp_addr;
41 int i;
42
43 ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
44 if (ih6 == NULL)
45 return EBT_NOMATCH;
46 if (info->bitmask & EBT_IP6_TCLASS &&
47 FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
48 return EBT_NOMATCH;
49 for (i = 0; i < 4; i++)
50 tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
51 info->smsk.in6_u.u6_addr32[i];
52 if (info->bitmask & EBT_IP6_SOURCE &&
53 FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
54 EBT_IP6_SOURCE))
55 return EBT_NOMATCH;
56 for (i = 0; i < 4; i++)
57 tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
58 info->dmsk.in6_u.u6_addr32[i];
59 if (info->bitmask & EBT_IP6_DEST &&
60 FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST))
61 return EBT_NOMATCH;
62 if (info->bitmask & EBT_IP6_PROTO) {
63 uint8_t nexthdr = ih6->nexthdr;
64 int offset_ph;
65
66 offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr);
67 if (offset_ph == -1)
68 return EBT_NOMATCH;
69 if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
70 return EBT_NOMATCH;
71 if (!(info->bitmask & EBT_IP6_DPORT) &&
72 !(info->bitmask & EBT_IP6_SPORT))
73 return EBT_MATCH;
74 pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),
75 &_ports);
76 if (pptr == NULL)
77 return EBT_NOMATCH;
78 if (info->bitmask & EBT_IP6_DPORT) {
79 u32 dst = ntohs(pptr->dst);
80 if (FWINV(dst < info->dport[0] ||
81 dst > info->dport[1], EBT_IP6_DPORT))
82 return EBT_NOMATCH;
83 }
84 if (info->bitmask & EBT_IP6_SPORT) {
85 u32 src = ntohs(pptr->src);
86 if (FWINV(src < info->sport[0] ||
87 src > info->sport[1], EBT_IP6_SPORT))
88 return EBT_NOMATCH;
89 }
90 return EBT_MATCH;
91 }
92 return EBT_MATCH;
93}
94
95static int ebt_ip6_check(const char *tablename, unsigned int hookmask,
96 const struct ebt_entry *e, void *data, unsigned int datalen)
97{
98 struct ebt_ip6_info *info = (struct ebt_ip6_info *)data;
99
100 if (datalen != EBT_ALIGN(sizeof(struct ebt_ip6_info)))
101 return -EINVAL;
102 if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
103 return -EINVAL;
104 if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
105 return -EINVAL;
106 if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
107 if (info->invflags & EBT_IP6_PROTO)
108 return -EINVAL;
109 if (info->protocol != IPPROTO_TCP &&
110 info->protocol != IPPROTO_UDP &&
111 info->protocol != IPPROTO_UDPLITE &&
112 info->protocol != IPPROTO_SCTP &&
113 info->protocol != IPPROTO_DCCP)
114 return -EINVAL;
115 }
116 if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
117 return -EINVAL;
118 if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
119 return -EINVAL;
120 return 0;
121}
122
123static struct ebt_match filter_ip6 =
124{
125 .name = EBT_IP6_MATCH,
126 .match = ebt_filter_ip6,
127 .check = ebt_ip6_check,
128 .me = THIS_MODULE,
129};
130
131static int __init ebt_ip6_init(void)
132{
133 return ebt_register_match(&filter_ip6);
134}
135
136static void __exit ebt_ip6_fini(void)
137{
138 ebt_unregister_match(&filter_ip6);
139}
140
141module_init(ebt_ip6_init);
142module_exit(ebt_ip6_fini);
143MODULE_DESCRIPTION("Ebtables: IPv6 protocol packet match");
144MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 0b209e4aad0a..c883ec8a28b4 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -18,6 +18,9 @@
18#include <linux/if_arp.h> 18#include <linux/if_arp.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <net/netfilter/nf_log.h> 20#include <net/netfilter/nf_log.h>
21#include <linux/ipv6.h>
22#include <net/ipv6.h>
23#include <linux/in6.h>
21 24
22static DEFINE_SPINLOCK(ebt_log_lock); 25static DEFINE_SPINLOCK(ebt_log_lock);
23 26
@@ -58,6 +61,27 @@ static void print_MAC(const unsigned char *p)
58 printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':'); 61 printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':');
59} 62}
60 63
64static void
65print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
66{
67 if (protocol == IPPROTO_TCP ||
68 protocol == IPPROTO_UDP ||
69 protocol == IPPROTO_UDPLITE ||
70 protocol == IPPROTO_SCTP ||
71 protocol == IPPROTO_DCCP) {
72 const struct tcpudphdr *pptr;
73 struct tcpudphdr _ports;
74
75 pptr = skb_header_pointer(skb, offset,
76 sizeof(_ports), &_ports);
77 if (pptr == NULL) {
78 printk(" INCOMPLETE TCP/UDP header");
79 return;
80 }
81 printk(" SPT=%u DPT=%u", ntohs(pptr->src), ntohs(pptr->dst));
82 }
83}
84
61#define myNIPQUAD(a) a[0], a[1], a[2], a[3] 85#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
62static void 86static void
63ebt_log_packet(unsigned int pf, unsigned int hooknum, 87ebt_log_packet(unsigned int pf, unsigned int hooknum,
@@ -95,23 +119,31 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
95 printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP " 119 printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
96 "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr), 120 "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
97 NIPQUAD(ih->daddr), ih->tos, ih->protocol); 121 NIPQUAD(ih->daddr), ih->tos, ih->protocol);
98 if (ih->protocol == IPPROTO_TCP || 122 print_ports(skb, ih->protocol, ih->ihl*4);
99 ih->protocol == IPPROTO_UDP || 123 goto out;
100 ih->protocol == IPPROTO_UDPLITE || 124 }
101 ih->protocol == IPPROTO_SCTP || 125
102 ih->protocol == IPPROTO_DCCP) { 126 if ((bitmask & EBT_LOG_IP6) && eth_hdr(skb)->h_proto ==
103 const struct tcpudphdr *pptr; 127 htons(ETH_P_IPV6)) {
104 struct tcpudphdr _ports; 128 const struct ipv6hdr *ih;
105 129 struct ipv6hdr _iph;
106 pptr = skb_header_pointer(skb, ih->ihl*4, 130 uint8_t nexthdr;
107 sizeof(_ports), &_ports); 131 int offset_ph;
108 if (pptr == NULL) { 132
109 printk(" INCOMPLETE TCP/UDP header"); 133 ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
110 goto out; 134 if (ih == NULL) {
111 } 135 printk(" INCOMPLETE IPv6 header");
112 printk(" SPT=%u DPT=%u", ntohs(pptr->src), 136 goto out;
113 ntohs(pptr->dst));
114 } 137 }
138 printk(" IPv6 SRC=%x:%x:%x:%x:%x:%x:%x:%x "
139 "IPv6 DST=%x:%x:%x:%x:%x:%x:%x:%x, IPv6 "
140 "priority=0x%01X, Next Header=%d", NIP6(ih->saddr),
141 NIP6(ih->daddr), ih->priority, ih->nexthdr);
142 nexthdr = ih->nexthdr;
143 offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr);
144 if (offset_ph == -1)
145 goto out;
146 print_ports(skb, nexthdr, offset_ph);
115 goto out; 147 goto out;
116 } 148 }
117 149
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 90e2177af081..dccd737ea2e3 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -242,11 +242,11 @@ static ssize_t netstat_show(const struct device *d,
242 offset % sizeof(unsigned long) != 0); 242 offset % sizeof(unsigned long) != 0);
243 243
244 read_lock(&dev_base_lock); 244 read_lock(&dev_base_lock);
245 if (dev_isalive(dev) && dev->get_stats && 245 if (dev_isalive(dev)) {
246 (stats = (*dev->get_stats)(dev))) 246 stats = dev->get_stats(dev);
247 ret = sprintf(buf, fmt_ulong, 247 ret = sprintf(buf, fmt_ulong,
248 *(unsigned long *)(((u8 *) stats) + offset)); 248 *(unsigned long *)(((u8 *) stats) + offset));
249 249 }
250 read_unlock(&dev_base_lock); 250 read_unlock(&dev_base_lock);
251 return ret; 251 return ret;
252} 252}
@@ -457,8 +457,7 @@ int netdev_register_kobject(struct net_device *net)
457 strlcpy(dev->bus_id, net->name, BUS_ID_SIZE); 457 strlcpy(dev->bus_id, net->name, BUS_ID_SIZE);
458 458
459#ifdef CONFIG_SYSFS 459#ifdef CONFIG_SYSFS
460 if (net->get_stats) 460 *groups++ = &netstat_group;
461 *groups++ = &netstat_group;
462 461
463#ifdef CONFIG_WIRELESS_EXT 462#ifdef CONFIG_WIRELESS_EXT
464 if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats) 463 if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a9a77216310e..6c8d7f0ea01a 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -607,6 +607,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
607{ 607{
608 struct ifinfomsg *ifm; 608 struct ifinfomsg *ifm;
609 struct nlmsghdr *nlh; 609 struct nlmsghdr *nlh;
610 struct net_device_stats *stats;
611 struct nlattr *attr;
610 612
611 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); 613 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
612 if (nlh == NULL) 614 if (nlh == NULL)
@@ -653,19 +655,13 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
653 NLA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast); 655 NLA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast);
654 } 656 }
655 657
656 if (dev->get_stats) { 658 attr = nla_reserve(skb, IFLA_STATS,
657 struct net_device_stats *stats = dev->get_stats(dev); 659 sizeof(struct rtnl_link_stats));
658 if (stats) { 660 if (attr == NULL)
659 struct nlattr *attr; 661 goto nla_put_failure;
660 662
661 attr = nla_reserve(skb, IFLA_STATS, 663 stats = dev->get_stats(dev);
662 sizeof(struct rtnl_link_stats)); 664 copy_rtnl_link_stats(nla_data(attr), stats);
663 if (attr == NULL)
664 goto nla_put_failure;
665
666 copy_rtnl_link_stats(nla_data(attr), stats);
667 }
668 }
669 665
670 if (dev->rtnl_link_ops) { 666 if (dev->rtnl_link_ops) {
671 if (rtnl_link_fill(skb, dev) < 0) 667 if (rtnl_link_fill(skb, dev) < 0)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1e556d312117..3e18f8525e82 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4,8 +4,6 @@
4 * Authors: Alan Cox <iiitac@pyr.swan.ac.uk> 4 * Authors: Alan Cox <iiitac@pyr.swan.ac.uk>
5 * Florian La Roche <rzsfl@rz.uni-sb.de> 5 * Florian La Roche <rzsfl@rz.uni-sb.de>
6 * 6 *
7 * Version: $Id: skbuff.c,v 1.90 2001/11/07 05:56:19 davem Exp $
8 *
9 * Fixes: 7 * Fixes:
10 * Alan Cox : Fixed the worst of the load 8 * Alan Cox : Fixed the worst of the load
11 * balancer bugs. 9 * balancer bugs.
diff --git a/net/core/sock.c b/net/core/sock.c
index 88094cb09c06..3879bf65897e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -7,8 +7,6 @@
7 * handler for protocols to use and generic option handler. 7 * handler for protocols to use and generic option handler.
8 * 8 *
9 * 9 *
10 * Version: $Id: sock.c,v 1.117 2002/02/01 22:01:03 davem Exp $
11 *
12 * Authors: Ross Biro 10 * Authors: Ross Biro
13 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
14 * Florian La Roche, <flla@stud.uni-sb.de> 12 * Florian La Roche, <flla@stud.uni-sb.de>
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 5fc801057244..a570e2af22cb 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -125,14 +125,6 @@ static struct ctl_table net_core_table[] = {
125#endif /* CONFIG_XFRM */ 125#endif /* CONFIG_XFRM */
126#endif /* CONFIG_NET */ 126#endif /* CONFIG_NET */
127 { 127 {
128 .ctl_name = NET_CORE_SOMAXCONN,
129 .procname = "somaxconn",
130 .data = &init_net.core.sysctl_somaxconn,
131 .maxlen = sizeof(int),
132 .mode = 0644,
133 .proc_handler = &proc_dointvec
134 },
135 {
136 .ctl_name = NET_CORE_BUDGET, 128 .ctl_name = NET_CORE_BUDGET,
137 .procname = "netdev_budget", 129 .procname = "netdev_budget",
138 .data = &netdev_budget, 130 .data = &netdev_budget,
@@ -151,6 +143,18 @@ static struct ctl_table net_core_table[] = {
151 { .ctl_name = 0 } 143 { .ctl_name = 0 }
152}; 144};
153 145
146static struct ctl_table netns_core_table[] = {
147 {
148 .ctl_name = NET_CORE_SOMAXCONN,
149 .procname = "somaxconn",
150 .data = &init_net.core.sysctl_somaxconn,
151 .maxlen = sizeof(int),
152 .mode = 0644,
153 .proc_handler = &proc_dointvec
154 },
155 { .ctl_name = 0 }
156};
157
154static __net_initdata struct ctl_path net_core_path[] = { 158static __net_initdata struct ctl_path net_core_path[] = {
155 { .procname = "net", .ctl_name = CTL_NET, }, 159 { .procname = "net", .ctl_name = CTL_NET, },
156 { .procname = "core", .ctl_name = NET_CORE, }, 160 { .procname = "core", .ctl_name = NET_CORE, },
@@ -159,23 +163,17 @@ static __net_initdata struct ctl_path net_core_path[] = {
159 163
160static __net_init int sysctl_core_net_init(struct net *net) 164static __net_init int sysctl_core_net_init(struct net *net)
161{ 165{
162 struct ctl_table *tbl, *tmp; 166 struct ctl_table *tbl;
163 167
164 net->core.sysctl_somaxconn = SOMAXCONN; 168 net->core.sysctl_somaxconn = SOMAXCONN;
165 169
166 tbl = net_core_table; 170 tbl = netns_core_table;
167 if (net != &init_net) { 171 if (net != &init_net) {
168 tbl = kmemdup(tbl, sizeof(net_core_table), GFP_KERNEL); 172 tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL);
169 if (tbl == NULL) 173 if (tbl == NULL)
170 goto err_dup; 174 goto err_dup;
171 175
172 for (tmp = tbl; tmp->procname; tmp++) { 176 tbl[0].data = &net->core.sysctl_somaxconn;
173 if (tmp->data >= (void *)&init_net &&
174 tmp->data < (void *)(&init_net + 1))
175 tmp->data += (char *)net - (char *)&init_net;
176 else
177 tmp->mode &= ~0222;
178 }
179 } 177 }
180 178
181 net->core.sysctl_hdr = register_net_sysctl_table(net, 179 net->core.sysctl_hdr = register_net_sysctl_table(net,
@@ -186,7 +184,7 @@ static __net_init int sysctl_core_net_init(struct net *net)
186 return 0; 184 return 0;
187 185
188err_reg: 186err_reg:
189 if (tbl != net_core_table) 187 if (tbl != netns_core_table)
190 kfree(tbl); 188 kfree(tbl);
191err_dup: 189err_dup:
192 return -ENOMEM; 190 return -ENOMEM;
@@ -198,7 +196,7 @@ static __net_exit void sysctl_core_net_exit(struct net *net)
198 196
199 tbl = net->core.sysctl_hdr->ctl_table_arg; 197 tbl = net->core.sysctl_hdr->ctl_table_arg;
200 unregister_net_sysctl_table(net->core.sysctl_hdr); 198 unregister_net_sysctl_table(net->core.sysctl_hdr);
201 BUG_ON(tbl == net_core_table); 199 BUG_ON(tbl == netns_core_table);
202 kfree(tbl); 200 kfree(tbl);
203} 201}
204 202
@@ -209,6 +207,7 @@ static __net_initdata struct pernet_operations sysctl_core_ops = {
209 207
210static __init int sysctl_core_init(void) 208static __init int sysctl_core_init(void)
211{ 209{
210 register_net_sysctl_rotable(net_core_path, net_core_table);
212 return register_pernet_subsys(&sysctl_core_ops); 211 return register_pernet_subsys(&sysctl_core_ops);
213} 212}
214 213
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 200ee1e63728..69dbc342a464 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -391,7 +391,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
391 391
392 wstats.updated = 0; 392 wstats.updated = 0;
393 if (rx_stats->mask & IEEE80211_STATMASK_RSSI) { 393 if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
394 wstats.level = rx_stats->rssi; 394 wstats.level = rx_stats->signal;
395 wstats.updated |= IW_QUAL_LEVEL_UPDATED; 395 wstats.updated |= IW_QUAL_LEVEL_UPDATED;
396 } else 396 } else
397 wstats.updated |= IW_QUAL_LEVEL_INVALID; 397 wstats.updated |= IW_QUAL_LEVEL_INVALID;
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index d8b02603cbe5..d996547f7a62 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -542,90 +542,4 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
542 return 1; 542 return 1;
543} 543}
544 544
545/* Incoming 802.11 strucure is converted to a TXB
546 * a block of 802.11 fragment packets (stored as skbs) */
547int ieee80211_tx_frame(struct ieee80211_device *ieee,
548 struct ieee80211_hdr *frame, int hdr_len, int total_len,
549 int encrypt_mpdu)
550{
551 struct ieee80211_txb *txb = NULL;
552 unsigned long flags;
553 struct net_device_stats *stats = &ieee->stats;
554 struct sk_buff *skb_frag;
555 int priority = -1;
556 int fraglen = total_len;
557 int headroom = ieee->tx_headroom;
558 struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
559
560 spin_lock_irqsave(&ieee->lock, flags);
561
562 if (encrypt_mpdu && (!ieee->sec.encrypt || !crypt))
563 encrypt_mpdu = 0;
564
565 /* If there is no driver handler to take the TXB, dont' bother
566 * creating it... */
567 if (!ieee->hard_start_xmit) {
568 printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
569 goto success;
570 }
571
572 if (unlikely(total_len < 24)) {
573 printk(KERN_WARNING "%s: skb too small (%d).\n",
574 ieee->dev->name, total_len);
575 goto success;
576 }
577
578 if (encrypt_mpdu) {
579 frame->frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
580 fraglen += crypt->ops->extra_mpdu_prefix_len +
581 crypt->ops->extra_mpdu_postfix_len;
582 headroom += crypt->ops->extra_mpdu_prefix_len;
583 }
584
585 /* When we allocate the TXB we allocate enough space for the reserve
586 * and full fragment bytes (bytes_per_frag doesn't include prefix,
587 * postfix, header, FCS, etc.) */
588 txb = ieee80211_alloc_txb(1, fraglen, headroom, GFP_ATOMIC);
589 if (unlikely(!txb)) {
590 printk(KERN_WARNING "%s: Could not allocate TXB\n",
591 ieee->dev->name);
592 goto failed;
593 }
594 txb->encrypted = 0;
595 txb->payload_size = fraglen;
596
597 skb_frag = txb->fragments[0];
598
599 memcpy(skb_put(skb_frag, total_len), frame, total_len);
600
601 if (ieee->config &
602 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
603 skb_put(skb_frag, 4);
604
605 /* To avoid overcomplicating things, we do the corner-case frame
606 * encryption in software. The only real situation where encryption is
607 * needed here is during software-based shared key authentication. */
608 if (encrypt_mpdu)
609 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
610
611 success:
612 spin_unlock_irqrestore(&ieee->lock, flags);
613
614 if (txb) {
615 if ((*ieee->hard_start_xmit) (txb, ieee->dev, priority) == 0) {
616 stats->tx_packets++;
617 stats->tx_bytes += txb->payload_size;
618 return 0;
619 }
620 ieee80211_txb_free(txb);
621 }
622 return 0;
623
624 failed:
625 spin_unlock_irqrestore(&ieee->lock, flags);
626 stats->tx_errors++;
627 return 1;
628}
629
630EXPORT_SYMBOL(ieee80211_tx_frame);
631EXPORT_SYMBOL(ieee80211_txb_free); 545EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 623489afa62c..822606b615ca 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -744,98 +744,9 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
744 return 0; 744 return 0;
745} 745}
746 746
747int ieee80211_wx_set_auth(struct net_device *dev,
748 struct iw_request_info *info,
749 union iwreq_data *wrqu,
750 char *extra)
751{
752 struct ieee80211_device *ieee = netdev_priv(dev);
753 unsigned long flags;
754 int err = 0;
755
756 spin_lock_irqsave(&ieee->lock, flags);
757
758 switch (wrqu->param.flags & IW_AUTH_INDEX) {
759 case IW_AUTH_WPA_VERSION:
760 case IW_AUTH_CIPHER_PAIRWISE:
761 case IW_AUTH_CIPHER_GROUP:
762 case IW_AUTH_KEY_MGMT:
763 /*
764 * Host AP driver does not use these parameters and allows
765 * wpa_supplicant to control them internally.
766 */
767 break;
768 case IW_AUTH_TKIP_COUNTERMEASURES:
769 break; /* FIXME */
770 case IW_AUTH_DROP_UNENCRYPTED:
771 ieee->drop_unencrypted = !!wrqu->param.value;
772 break;
773 case IW_AUTH_80211_AUTH_ALG:
774 break; /* FIXME */
775 case IW_AUTH_WPA_ENABLED:
776 ieee->privacy_invoked = ieee->wpa_enabled = !!wrqu->param.value;
777 break;
778 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
779 ieee->ieee802_1x = !!wrqu->param.value;
780 break;
781 case IW_AUTH_PRIVACY_INVOKED:
782 ieee->privacy_invoked = !!wrqu->param.value;
783 break;
784 default:
785 err = -EOPNOTSUPP;
786 break;
787 }
788 spin_unlock_irqrestore(&ieee->lock, flags);
789 return err;
790}
791
792int ieee80211_wx_get_auth(struct net_device *dev,
793 struct iw_request_info *info,
794 union iwreq_data *wrqu,
795 char *extra)
796{
797 struct ieee80211_device *ieee = netdev_priv(dev);
798 unsigned long flags;
799 int err = 0;
800
801 spin_lock_irqsave(&ieee->lock, flags);
802
803 switch (wrqu->param.flags & IW_AUTH_INDEX) {
804 case IW_AUTH_WPA_VERSION:
805 case IW_AUTH_CIPHER_PAIRWISE:
806 case IW_AUTH_CIPHER_GROUP:
807 case IW_AUTH_KEY_MGMT:
808 case IW_AUTH_TKIP_COUNTERMEASURES: /* FIXME */
809 case IW_AUTH_80211_AUTH_ALG: /* FIXME */
810 /*
811 * Host AP driver does not use these parameters and allows
812 * wpa_supplicant to control them internally.
813 */
814 err = -EOPNOTSUPP;
815 break;
816 case IW_AUTH_DROP_UNENCRYPTED:
817 wrqu->param.value = ieee->drop_unencrypted;
818 break;
819 case IW_AUTH_WPA_ENABLED:
820 wrqu->param.value = ieee->wpa_enabled;
821 break;
822 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
823 wrqu->param.value = ieee->ieee802_1x;
824 break;
825 default:
826 err = -EOPNOTSUPP;
827 break;
828 }
829 spin_unlock_irqrestore(&ieee->lock, flags);
830 return err;
831}
832
833EXPORT_SYMBOL(ieee80211_wx_set_encodeext); 747EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
834EXPORT_SYMBOL(ieee80211_wx_get_encodeext); 748EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
835 749
836EXPORT_SYMBOL(ieee80211_wx_get_scan); 750EXPORT_SYMBOL(ieee80211_wx_get_scan);
837EXPORT_SYMBOL(ieee80211_wx_set_encode); 751EXPORT_SYMBOL(ieee80211_wx_set_encode);
838EXPORT_SYMBOL(ieee80211_wx_get_encode); 752EXPORT_SYMBOL(ieee80211_wx_get_encode);
839
840EXPORT_SYMBOL_GPL(ieee80211_wx_set_auth);
841EXPORT_SYMBOL_GPL(ieee80211_wx_get_auth);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 24eca23c2db3..42bd24b64b57 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * PF_INET protocol family socket handler. 6 * PF_INET protocol family socket handler.
7 * 7 *
8 * Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Florian La Roche, <flla@stud.uni-sb.de> 10 * Florian La Roche, <flla@stud.uni-sb.de>
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 9b539fa9fe18..20c515a1be28 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1,7 +1,5 @@
1/* linux/net/ipv4/arp.c 1/* linux/net/ipv4/arp.c
2 * 2 *
3 * Version: $Id: arp.c,v 1.99 2001/08/30 22:55:42 davem Exp $
4 *
5 * Copyright (C) 1994 by Florian La Roche 3 * Copyright (C) 1994 by Florian La Roche
6 * 4 *
7 * This module implements the Address Resolution Protocol ARP (RFC 826), 5 * This module implements the Address Resolution Protocol ARP (RFC 826),
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 79a7ef6209ff..f8c0b0aea93a 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * NET3 IP device support routines. 2 * NET3 IP device support routines.
3 * 3 *
4 * Version: $Id: devinet.c,v 1.44 2001/10/31 21:55:54 davem Exp $
5 *
6 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 6 * as published by the Free Software Foundation; either version
@@ -1013,7 +1011,7 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
1013 memcpy(old, ifa->ifa_label, IFNAMSIZ); 1011 memcpy(old, ifa->ifa_label, IFNAMSIZ);
1014 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); 1012 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
1015 if (named++ == 0) 1013 if (named++ == 0)
1016 continue; 1014 goto skip;
1017 dot = strchr(old, ':'); 1015 dot = strchr(old, ':');
1018 if (dot == NULL) { 1016 if (dot == NULL) {
1019 sprintf(old, ":%d", named); 1017 sprintf(old, ":%d", named);
@@ -1024,6 +1022,8 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
1024 } else { 1022 } else {
1025 strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); 1023 strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot);
1026 } 1024 }
1025skip:
1026 rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
1027 } 1027 }
1028} 1028}
1029 1029
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 0b2ac6a3d903..5ad01d63f83b 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * IPv4 Forwarding Information Base: FIB frontend. 6 * IPv4 Forwarding Information Base: FIB frontend.
7 * 7 *
8 * Version: $Id: fib_frontend.c,v 1.26 2001/10/31 21:55:54 davem Exp $
9 *
10 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 2e2fc3376ac9..eeec4bf982b8 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * IPv4 FIB: lookup engine and maintenance routines. 6 * IPv4 FIB: lookup engine and maintenance routines.
7 * 7 *
8 * Version: $Id: fib_hash.c,v 1.13 2001/10/31 21:55:54 davem Exp $
9 *
10 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 0d4d72827e4b..ded2ae34eab1 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * IPv4 Forwarding Information Base: semantics. 6 * IPv4 Forwarding Information Base: semantics.
7 * 7 *
8 * Version: $Id: fib_semantics.c,v 1.19 2002/01/12 07:54:56 davem Exp $
9 *
10 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 4b02d14e7ab9..394db9c941a1 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -22,8 +22,6 @@
22 * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson 22 * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
23 * IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999 23 * IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
24 * 24 *
25 * Version: $Id: fib_trie.c,v 1.3 2005/06/08 14:20:01 robert Exp $
26 *
27 * 25 *
28 * Code from fib_hash has been reused which includes the following header: 26 * Code from fib_hash has been reused which includes the following header:
29 * 27 *
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 87397351ddac..aa7cf46853b7 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -3,8 +3,6 @@
3 * 3 *
4 * Alan Cox, <alan@redhat.com> 4 * Alan Cox, <alan@redhat.com>
5 * 5 *
6 * Version: $Id: icmp.c,v 1.85 2002/02/01 22:01:03 davem Exp $
7 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 2769dc4a4c84..68e84a933e90 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -8,8 +8,6 @@
8 * the older version didn't come out right using gcc 2.5.8, the newer one 8 * the older version didn't come out right using gcc 2.5.8, the newer one
9 * seems to fall out with gcc 2.6.2. 9 * seems to fall out with gcc 2.6.2.
10 * 10 *
11 * Version: $Id: igmp.c,v 1.47 2002/02/01 22:01:03 davem Exp $
12 *
13 * Authors: 11 * Authors:
14 * Alan Cox <Alan.Cox@linux.org> 12 * Alan Cox <Alan.Cox@linux.org>
15 * 13 *
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index da97695e7096..c10036e7a463 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * inet_diag.c Module for monitoring INET transport protocols sockets. 2 * inet_diag.c Module for monitoring INET transport protocols sockets.
3 * 3 *
4 * Version: $Id: inet_diag.c,v 1.3 2002/02/01 22:01:04 davem Exp $
5 *
6 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 4 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index af995198f643..a456ceeac3f2 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -3,8 +3,6 @@
3 * 3 *
4 * This source is covered by the GNU GPL, the same as all kernel sources. 4 * This source is covered by the GNU GPL, the same as all kernel sources.
5 * 5 *
6 * Version: $Id: inetpeer.c,v 1.7 2001/09/20 21:22:50 davem Exp $
7 *
8 * Authors: Andrey V. Savochkin <saw@msu.ru> 6 * Authors: Andrey V. Savochkin <saw@msu.ru>
9 */ 7 */
10 8
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 4813c39b438b..37d36a3f33cd 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * The IP forwarding functionality. 6 * The IP forwarding functionality.
7 * 7 *
8 * Version: $Id: ip_forward.c,v 1.48 2000/12/13 18:31:48 davem Exp $
9 *
10 * Authors: see ip.c 8 * Authors: see ip.c
11 * 9 *
12 * Fixes: 10 * Fixes:
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index cd6ce6ac6358..91e321407313 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * The IP fragmentation functionality. 6 * The IP fragmentation functionality.
7 * 7 *
8 * Version: $Id: ip_fragment.c,v 1.59 2002/01/12 07:54:56 davem Exp $
9 *
10 * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG> 8 * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
11 * Alan Cox <Alan.Cox@linux.org> 9 * Alan Cox <Alan.Cox@linux.org>
12 * 10 *
@@ -598,7 +596,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
598#ifdef CONFIG_SYSCTL 596#ifdef CONFIG_SYSCTL
599static int zero; 597static int zero;
600 598
601static struct ctl_table ip4_frags_ctl_table[] = { 599static struct ctl_table ip4_frags_ns_ctl_table[] = {
602 { 600 {
603 .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH, 601 .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH,
604 .procname = "ipfrag_high_thresh", 602 .procname = "ipfrag_high_thresh",
@@ -624,6 +622,10 @@ static struct ctl_table ip4_frags_ctl_table[] = {
624 .proc_handler = &proc_dointvec_jiffies, 622 .proc_handler = &proc_dointvec_jiffies,
625 .strategy = &sysctl_jiffies 623 .strategy = &sysctl_jiffies
626 }, 624 },
625 { }
626};
627
628static struct ctl_table ip4_frags_ctl_table[] = {
627 { 629 {
628 .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL, 630 .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL,
629 .procname = "ipfrag_secret_interval", 631 .procname = "ipfrag_secret_interval",
@@ -644,22 +646,20 @@ static struct ctl_table ip4_frags_ctl_table[] = {
644 { } 646 { }
645}; 647};
646 648
647static int ip4_frags_ctl_register(struct net *net) 649static int ip4_frags_ns_ctl_register(struct net *net)
648{ 650{
649 struct ctl_table *table; 651 struct ctl_table *table;
650 struct ctl_table_header *hdr; 652 struct ctl_table_header *hdr;
651 653
652 table = ip4_frags_ctl_table; 654 table = ip4_frags_ns_ctl_table;
653 if (net != &init_net) { 655 if (net != &init_net) {
654 table = kmemdup(table, sizeof(ip4_frags_ctl_table), GFP_KERNEL); 656 table = kmemdup(table, sizeof(ip4_frags_ns_ctl_table), GFP_KERNEL);
655 if (table == NULL) 657 if (table == NULL)
656 goto err_alloc; 658 goto err_alloc;
657 659
658 table[0].data = &net->ipv4.frags.high_thresh; 660 table[0].data = &net->ipv4.frags.high_thresh;
659 table[1].data = &net->ipv4.frags.low_thresh; 661 table[1].data = &net->ipv4.frags.low_thresh;
660 table[2].data = &net->ipv4.frags.timeout; 662 table[2].data = &net->ipv4.frags.timeout;
661 table[3].mode &= ~0222;
662 table[4].mode &= ~0222;
663 } 663 }
664 664
665 hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table); 665 hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table);
@@ -676,7 +676,7 @@ err_alloc:
676 return -ENOMEM; 676 return -ENOMEM;
677} 677}
678 678
679static void ip4_frags_ctl_unregister(struct net *net) 679static void ip4_frags_ns_ctl_unregister(struct net *net)
680{ 680{
681 struct ctl_table *table; 681 struct ctl_table *table;
682 682
@@ -684,13 +684,22 @@ static void ip4_frags_ctl_unregister(struct net *net)
684 unregister_net_sysctl_table(net->ipv4.frags_hdr); 684 unregister_net_sysctl_table(net->ipv4.frags_hdr);
685 kfree(table); 685 kfree(table);
686} 686}
687
688static void ip4_frags_ctl_register(void)
689{
690 register_net_sysctl_rotable(net_ipv4_ctl_path, ip4_frags_ctl_table);
691}
687#else 692#else
688static inline int ip4_frags_ctl_register(struct net *net) 693static inline int ip4_frags_ns_ctl_register(struct net *net)
689{ 694{
690 return 0; 695 return 0;
691} 696}
692 697
693static inline void ip4_frags_ctl_unregister(struct net *net) 698static inline void ip4_frags_ns_ctl_unregister(struct net *net)
699{
700}
701
702static inline void ip4_frags_ctl_register(void)
694{ 703{
695} 704}
696#endif 705#endif
@@ -714,12 +723,12 @@ static int ipv4_frags_init_net(struct net *net)
714 723
715 inet_frags_init_net(&net->ipv4.frags); 724 inet_frags_init_net(&net->ipv4.frags);
716 725
717 return ip4_frags_ctl_register(net); 726 return ip4_frags_ns_ctl_register(net);
718} 727}
719 728
720static void ipv4_frags_exit_net(struct net *net) 729static void ipv4_frags_exit_net(struct net *net)
721{ 730{
722 ip4_frags_ctl_unregister(net); 731 ip4_frags_ns_ctl_unregister(net);
723 inet_frags_exit_net(&net->ipv4.frags, &ip4_frags); 732 inet_frags_exit_net(&net->ipv4.frags, &ip4_frags);
724} 733}
725 734
@@ -730,6 +739,7 @@ static struct pernet_operations ip4_frags_ops = {
730 739
731void __init ipfrag_init(void) 740void __init ipfrag_init(void)
732{ 741{
742 ip4_frags_ctl_register();
733 register_pernet_subsys(&ip4_frags_ops); 743 register_pernet_subsys(&ip4_frags_ops);
734 ip4_frags.hashfn = ip4_hashfn; 744 ip4_frags.hashfn = ip4_hashfn;
735 ip4_frags.constructor = ip4_frag_init; 745 ip4_frags.constructor = ip4_frag_init;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 4342cba4ff82..2a61158ea722 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -473,6 +473,8 @@ static int ipgre_rcv(struct sk_buff *skb)
473 read_lock(&ipgre_lock); 473 read_lock(&ipgre_lock);
474 if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev), 474 if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev),
475 iph->saddr, iph->daddr, key)) != NULL) { 475 iph->saddr, iph->daddr, key)) != NULL) {
476 struct net_device_stats *stats = &tunnel->dev->stats;
477
476 secpath_reset(skb); 478 secpath_reset(skb);
477 479
478 skb->protocol = *(__be16*)(h + 2); 480 skb->protocol = *(__be16*)(h + 2);
@@ -497,28 +499,28 @@ static int ipgre_rcv(struct sk_buff *skb)
497 /* Looped back packet, drop it! */ 499 /* Looped back packet, drop it! */
498 if (skb->rtable->fl.iif == 0) 500 if (skb->rtable->fl.iif == 0)
499 goto drop; 501 goto drop;
500 tunnel->stat.multicast++; 502 stats->multicast++;
501 skb->pkt_type = PACKET_BROADCAST; 503 skb->pkt_type = PACKET_BROADCAST;
502 } 504 }
503#endif 505#endif
504 506
505 if (((flags&GRE_CSUM) && csum) || 507 if (((flags&GRE_CSUM) && csum) ||
506 (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) { 508 (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
507 tunnel->stat.rx_crc_errors++; 509 stats->rx_crc_errors++;
508 tunnel->stat.rx_errors++; 510 stats->rx_errors++;
509 goto drop; 511 goto drop;
510 } 512 }
511 if (tunnel->parms.i_flags&GRE_SEQ) { 513 if (tunnel->parms.i_flags&GRE_SEQ) {
512 if (!(flags&GRE_SEQ) || 514 if (!(flags&GRE_SEQ) ||
513 (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) { 515 (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) {
514 tunnel->stat.rx_fifo_errors++; 516 stats->rx_fifo_errors++;
515 tunnel->stat.rx_errors++; 517 stats->rx_errors++;
516 goto drop; 518 goto drop;
517 } 519 }
518 tunnel->i_seqno = seqno + 1; 520 tunnel->i_seqno = seqno + 1;
519 } 521 }
520 tunnel->stat.rx_packets++; 522 stats->rx_packets++;
521 tunnel->stat.rx_bytes += skb->len; 523 stats->rx_bytes += skb->len;
522 skb->dev = tunnel->dev; 524 skb->dev = tunnel->dev;
523 dst_release(skb->dst); 525 dst_release(skb->dst);
524 skb->dst = NULL; 526 skb->dst = NULL;
@@ -540,7 +542,7 @@ drop_nolock:
540static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 542static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
541{ 543{
542 struct ip_tunnel *tunnel = netdev_priv(dev); 544 struct ip_tunnel *tunnel = netdev_priv(dev);
543 struct net_device_stats *stats = &tunnel->stat; 545 struct net_device_stats *stats = &tunnel->dev->stats;
544 struct iphdr *old_iph = ip_hdr(skb); 546 struct iphdr *old_iph = ip_hdr(skb);
545 struct iphdr *tiph; 547 struct iphdr *tiph;
546 u8 tos; 548 u8 tos;
@@ -554,7 +556,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
554 int mtu; 556 int mtu;
555 557
556 if (tunnel->recursion++) { 558 if (tunnel->recursion++) {
557 tunnel->stat.collisions++; 559 stats->collisions++;
558 goto tx_error; 560 goto tx_error;
559 } 561 }
560 562
@@ -570,7 +572,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
570 /* NBMA tunnel */ 572 /* NBMA tunnel */
571 573
572 if (skb->dst == NULL) { 574 if (skb->dst == NULL) {
573 tunnel->stat.tx_fifo_errors++; 575 stats->tx_fifo_errors++;
574 goto tx_error; 576 goto tx_error;
575 } 577 }
576 578
@@ -621,7 +623,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
621 .tos = RT_TOS(tos) } }, 623 .tos = RT_TOS(tos) } },
622 .proto = IPPROTO_GRE }; 624 .proto = IPPROTO_GRE };
623 if (ip_route_output_key(dev_net(dev), &rt, &fl)) { 625 if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
624 tunnel->stat.tx_carrier_errors++; 626 stats->tx_carrier_errors++;
625 goto tx_error; 627 goto tx_error;
626 } 628 }
627 } 629 }
@@ -629,7 +631,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
629 631
630 if (tdev == dev) { 632 if (tdev == dev) {
631 ip_rt_put(rt); 633 ip_rt_put(rt);
632 tunnel->stat.collisions++; 634 stats->collisions++;
633 goto tx_error; 635 goto tx_error;
634 } 636 }
635 637
@@ -954,11 +956,6 @@ done:
954 return err; 956 return err;
955} 957}
956 958
957static struct net_device_stats *ipgre_tunnel_get_stats(struct net_device *dev)
958{
959 return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
960}
961
962static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) 959static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
963{ 960{
964 struct ip_tunnel *tunnel = netdev_priv(dev); 961 struct ip_tunnel *tunnel = netdev_priv(dev);
@@ -1084,7 +1081,6 @@ static void ipgre_tunnel_setup(struct net_device *dev)
1084 dev->uninit = ipgre_tunnel_uninit; 1081 dev->uninit = ipgre_tunnel_uninit;
1085 dev->destructor = free_netdev; 1082 dev->destructor = free_netdev;
1086 dev->hard_start_xmit = ipgre_tunnel_xmit; 1083 dev->hard_start_xmit = ipgre_tunnel_xmit;
1087 dev->get_stats = ipgre_tunnel_get_stats;
1088 dev->do_ioctl = ipgre_tunnel_ioctl; 1084 dev->do_ioctl = ipgre_tunnel_ioctl;
1089 dev->change_mtu = ipgre_tunnel_change_mtu; 1085 dev->change_mtu = ipgre_tunnel_change_mtu;
1090 1086
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index ff77a4a7f9ec..7c26428ea67b 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * The Internet Protocol (IP) module. 6 * The Internet Protocol (IP) module.
7 * 7 *
8 * Version: $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Donald Becker, <becker@super.org> 10 * Donald Becker, <becker@super.org>
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 33126ad2cfdc..be3f18a7a40e 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * The options processing module for ip.c 6 * The options processing module for ip.c
7 * 7 *
8 * Version: $Id: ip_options.c,v 1.21 2001/09/01 00:31:50 davem Exp $
9 *
10 * Authors: A.N.Kuznetsov 8 * Authors: A.N.Kuznetsov
11 * 9 *
12 */ 10 */
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e527628f56cf..f1278eecf56d 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * The Internet Protocol (IP) output module. 6 * The Internet Protocol (IP) output module.
7 * 7 *
8 * Version: $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Donald Becker, <becker@super.org> 10 * Donald Becker, <becker@super.org>
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index e0514e82308e..105d92a039b9 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * The IP to API glue. 6 * The IP to API glue.
7 * 7 *
8 * Version: $Id: ip_sockglue.c,v 1.62 2002/02/01 22:01:04 davem Exp $
9 *
10 * Authors: see ip.c 8 * Authors: see ip.c
11 * 9 *
12 * Fixes: 10 * Fixes:
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index ed45037ce9be..b88aa9afa42e 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * $Id: ipconfig.c,v 1.46 2002/02/01 22:01:04 davem Exp $
3 *
4 * Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or 2 * Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
5 * user-supplied information to configure own IP address and routes. 3 * user-supplied information to configure own IP address and routes.
6 * 4 *
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index af5cb53da5cc..4c6d2caf9203 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * Linux NET3: IP/IP protocol decoder. 2 * Linux NET3: IP/IP protocol decoder.
3 * 3 *
4 * Version: $Id: ipip.c,v 1.50 2001/10/02 02:22:36 davem Exp $
5 *
6 * Authors: 4 * Authors:
7 * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95 5 * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95
8 * 6 *
@@ -368,8 +366,8 @@ static int ipip_rcv(struct sk_buff *skb)
368 skb->protocol = htons(ETH_P_IP); 366 skb->protocol = htons(ETH_P_IP);
369 skb->pkt_type = PACKET_HOST; 367 skb->pkt_type = PACKET_HOST;
370 368
371 tunnel->stat.rx_packets++; 369 tunnel->dev->stats.rx_packets++;
372 tunnel->stat.rx_bytes += skb->len; 370 tunnel->dev->stats.rx_bytes += skb->len;
373 skb->dev = tunnel->dev; 371 skb->dev = tunnel->dev;
374 dst_release(skb->dst); 372 dst_release(skb->dst);
375 skb->dst = NULL; 373 skb->dst = NULL;
@@ -392,7 +390,7 @@ static int ipip_rcv(struct sk_buff *skb)
392static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 390static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
393{ 391{
394 struct ip_tunnel *tunnel = netdev_priv(dev); 392 struct ip_tunnel *tunnel = netdev_priv(dev);
395 struct net_device_stats *stats = &tunnel->stat; 393 struct net_device_stats *stats = &tunnel->dev->stats;
396 struct iphdr *tiph = &tunnel->parms.iph; 394 struct iphdr *tiph = &tunnel->parms.iph;
397 u8 tos = tunnel->parms.iph.tos; 395 u8 tos = tunnel->parms.iph.tos;
398 __be16 df = tiph->frag_off; 396 __be16 df = tiph->frag_off;
@@ -405,7 +403,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
405 int mtu; 403 int mtu;
406 404
407 if (tunnel->recursion++) { 405 if (tunnel->recursion++) {
408 tunnel->stat.collisions++; 406 stats->collisions++;
409 goto tx_error; 407 goto tx_error;
410 } 408 }
411 409
@@ -418,7 +416,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
418 if (!dst) { 416 if (!dst) {
419 /* NBMA tunnel */ 417 /* NBMA tunnel */
420 if ((rt = skb->rtable) == NULL) { 418 if ((rt = skb->rtable) == NULL) {
421 tunnel->stat.tx_fifo_errors++; 419 stats->tx_fifo_errors++;
422 goto tx_error; 420 goto tx_error;
423 } 421 }
424 if ((dst = rt->rt_gateway) == 0) 422 if ((dst = rt->rt_gateway) == 0)
@@ -433,7 +431,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
433 .tos = RT_TOS(tos) } }, 431 .tos = RT_TOS(tos) } },
434 .proto = IPPROTO_IPIP }; 432 .proto = IPPROTO_IPIP };
435 if (ip_route_output_key(dev_net(dev), &rt, &fl)) { 433 if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
436 tunnel->stat.tx_carrier_errors++; 434 stats->tx_carrier_errors++;
437 goto tx_error_icmp; 435 goto tx_error_icmp;
438 } 436 }
439 } 437 }
@@ -441,7 +439,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
441 439
442 if (tdev == dev) { 440 if (tdev == dev) {
443 ip_rt_put(rt); 441 ip_rt_put(rt);
444 tunnel->stat.collisions++; 442 stats->collisions++;
445 goto tx_error; 443 goto tx_error;
446 } 444 }
447 445
@@ -451,7 +449,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
451 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; 449 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
452 450
453 if (mtu < 68) { 451 if (mtu < 68) {
454 tunnel->stat.collisions++; 452 stats->collisions++;
455 ip_rt_put(rt); 453 ip_rt_put(rt);
456 goto tx_error; 454 goto tx_error;
457 } 455 }
@@ -685,11 +683,6 @@ done:
685 return err; 683 return err;
686} 684}
687 685
688static struct net_device_stats *ipip_tunnel_get_stats(struct net_device *dev)
689{
690 return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
691}
692
693static int ipip_tunnel_change_mtu(struct net_device *dev, int new_mtu) 686static int ipip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
694{ 687{
695 if (new_mtu < 68 || new_mtu > 0xFFF8 - sizeof(struct iphdr)) 688 if (new_mtu < 68 || new_mtu > 0xFFF8 - sizeof(struct iphdr))
@@ -702,7 +695,6 @@ static void ipip_tunnel_setup(struct net_device *dev)
702{ 695{
703 dev->uninit = ipip_tunnel_uninit; 696 dev->uninit = ipip_tunnel_uninit;
704 dev->hard_start_xmit = ipip_tunnel_xmit; 697 dev->hard_start_xmit = ipip_tunnel_xmit;
705 dev->get_stats = ipip_tunnel_get_stats;
706 dev->do_ioctl = ipip_tunnel_ioctl; 698 dev->do_ioctl = ipip_tunnel_ioctl;
707 dev->change_mtu = ipip_tunnel_change_mtu; 699 dev->change_mtu = ipip_tunnel_change_mtu;
708 dev->destructor = free_netdev; 700 dev->destructor = free_netdev;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 11700a4dcd95..300ab0c2919e 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -9,8 +9,6 @@
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 * 11 *
12 * Version: $Id: ipmr.c,v 1.65 2001/10/31 21:55:54 davem Exp $
13 *
14 * Fixes: 12 * Fixes:
15 * Michael Chastain : Incorrect size of copying. 13 * Michael Chastain : Incorrect size of copying.
16 * Alan Cox : Added the cache manager code 14 * Alan Cox : Added the cache manager code
@@ -181,26 +179,20 @@ static int reg_vif_num = -1;
181static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) 179static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
182{ 180{
183 read_lock(&mrt_lock); 181 read_lock(&mrt_lock);
184 ((struct net_device_stats*)netdev_priv(dev))->tx_bytes += skb->len; 182 dev->stats.tx_bytes += skb->len;
185 ((struct net_device_stats*)netdev_priv(dev))->tx_packets++; 183 dev->stats.tx_packets++;
186 ipmr_cache_report(skb, reg_vif_num, IGMPMSG_WHOLEPKT); 184 ipmr_cache_report(skb, reg_vif_num, IGMPMSG_WHOLEPKT);
187 read_unlock(&mrt_lock); 185 read_unlock(&mrt_lock);
188 kfree_skb(skb); 186 kfree_skb(skb);
189 return 0; 187 return 0;
190} 188}
191 189
192static struct net_device_stats *reg_vif_get_stats(struct net_device *dev)
193{
194 return (struct net_device_stats*)netdev_priv(dev);
195}
196
197static void reg_vif_setup(struct net_device *dev) 190static void reg_vif_setup(struct net_device *dev)
198{ 191{
199 dev->type = ARPHRD_PIMREG; 192 dev->type = ARPHRD_PIMREG;
200 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8; 193 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8;
201 dev->flags = IFF_NOARP; 194 dev->flags = IFF_NOARP;
202 dev->hard_start_xmit = reg_vif_xmit; 195 dev->hard_start_xmit = reg_vif_xmit;
203 dev->get_stats = reg_vif_get_stats;
204 dev->destructor = free_netdev; 196 dev->destructor = free_netdev;
205} 197}
206 198
@@ -209,8 +201,7 @@ static struct net_device *ipmr_reg_vif(void)
209 struct net_device *dev; 201 struct net_device *dev;
210 struct in_device *in_dev; 202 struct in_device *in_dev;
211 203
212 dev = alloc_netdev(sizeof(struct net_device_stats), "pimreg", 204 dev = alloc_netdev(0, "pimreg", reg_vif_setup);
213 reg_vif_setup);
214 205
215 if (dev == NULL) 206 if (dev == NULL)
216 return NULL; 207 return NULL;
@@ -1170,8 +1161,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
1170 if (vif->flags & VIFF_REGISTER) { 1161 if (vif->flags & VIFF_REGISTER) {
1171 vif->pkt_out++; 1162 vif->pkt_out++;
1172 vif->bytes_out+=skb->len; 1163 vif->bytes_out+=skb->len;
1173 ((struct net_device_stats*)netdev_priv(vif->dev))->tx_bytes += skb->len; 1164 vif->dev->stats.tx_bytes += skb->len;
1174 ((struct net_device_stats*)netdev_priv(vif->dev))->tx_packets++; 1165 vif->dev->stats.tx_packets++;
1175 ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT); 1166 ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT);
1176 kfree_skb(skb); 1167 kfree_skb(skb);
1177 return; 1168 return;
@@ -1230,8 +1221,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
1230 if (vif->flags & VIFF_TUNNEL) { 1221 if (vif->flags & VIFF_TUNNEL) {
1231 ip_encap(skb, vif->local, vif->remote); 1222 ip_encap(skb, vif->local, vif->remote);
1232 /* FIXME: extra output firewall step used to be here. --RR */ 1223 /* FIXME: extra output firewall step used to be here. --RR */
1233 ((struct ip_tunnel *)netdev_priv(vif->dev))->stat.tx_packets++; 1224 vif->dev->stats.tx_packets++;
1234 ((struct ip_tunnel *)netdev_priv(vif->dev))->stat.tx_bytes+=skb->len; 1225 vif->dev->stats.tx_bytes += skb->len;
1235 } 1226 }
1236 1227
1237 IPCB(skb)->flags |= IPSKB_FORWARDED; 1228 IPCB(skb)->flags |= IPSKB_FORWARDED;
@@ -1487,8 +1478,8 @@ int pim_rcv_v1(struct sk_buff * skb)
1487 skb->pkt_type = PACKET_HOST; 1478 skb->pkt_type = PACKET_HOST;
1488 dst_release(skb->dst); 1479 dst_release(skb->dst);
1489 skb->dst = NULL; 1480 skb->dst = NULL;
1490 ((struct net_device_stats*)netdev_priv(reg_dev))->rx_bytes += skb->len; 1481 reg_dev->stats.rx_bytes += skb->len;
1491 ((struct net_device_stats*)netdev_priv(reg_dev))->rx_packets++; 1482 reg_dev->stats.rx_packets++;
1492 nf_reset(skb); 1483 nf_reset(skb);
1493 netif_rx(skb); 1484 netif_rx(skb);
1494 dev_put(reg_dev); 1485 dev_put(reg_dev);
@@ -1542,8 +1533,8 @@ static int pim_rcv(struct sk_buff * skb)
1542 skb->ip_summed = 0; 1533 skb->ip_summed = 0;
1543 skb->pkt_type = PACKET_HOST; 1534 skb->pkt_type = PACKET_HOST;
1544 dst_release(skb->dst); 1535 dst_release(skb->dst);
1545 ((struct net_device_stats*)netdev_priv(reg_dev))->rx_bytes += skb->len; 1536 reg_dev->stats.rx_bytes += skb->len;
1546 ((struct net_device_stats*)netdev_priv(reg_dev))->rx_packets++; 1537 reg_dev->stats.rx_packets++;
1547 skb->dst = NULL; 1538 skb->dst = NULL;
1548 nf_reset(skb); 1539 nf_reset(skb);
1549 netif_rx(skb); 1540 netif_rx(skb);
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index 535abe0c45e7..1f1897a1a702 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_app.c: Application module support for IPVS 2 * ip_vs_app.c: Application module support for IPVS
3 * 3 *
4 * Version: $Id: ip_vs_app.c,v 1.17 2003/03/22 06:31:21 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 65f1ba112752..f8bdae47a77f 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -5,8 +5,6 @@
5 * high-performance and highly available server based on a 5 * high-performance and highly available server based on a
6 * cluster of servers. 6 * cluster of servers.
7 * 7 *
8 * Version: $Id: ip_vs_conn.c,v 1.31 2003/04/18 09:03:16 wensong Exp $
9 *
10 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 8 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
11 * Peter Kese <peter.kese@ijs.si> 9 * Peter Kese <peter.kese@ijs.si>
12 * Julian Anastasov <ja@ssi.bg> 10 * Julian Anastasov <ja@ssi.bg>
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 963981a9d501..bcf6276ba4b2 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -5,8 +5,6 @@
5 * high-performance and highly available server based on a 5 * high-performance and highly available server based on a
6 * cluster of servers. 6 * cluster of servers.
7 * 7 *
8 * Version: $Id: ip_vs_core.c,v 1.34 2003/05/10 03:05:23 wensong Exp $
9 *
10 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 8 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
11 * Peter Kese <peter.kese@ijs.si> 9 * Peter Kese <peter.kese@ijs.si>
12 * Julian Anastasov <ja@ssi.bg> 10 * Julian Anastasov <ja@ssi.bg>
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 94c5767c8e01..9a5ace0b4dd6 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -5,8 +5,6 @@
5 * high-performance and highly available server based on a 5 * high-performance and highly available server based on a
6 * cluster of servers. 6 * cluster of servers.
7 * 7 *
8 * Version: $Id: ip_vs_ctl.c,v 1.36 2003/06/08 09:31:19 wensong Exp $
9 *
10 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 8 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
11 * Peter Kese <peter.kese@ijs.si> 9 * Peter Kese <peter.kese@ijs.si>
12 * Julian Anastasov <ja@ssi.bg> 10 * Julian Anastasov <ja@ssi.bg>
diff --git a/net/ipv4/ipvs/ip_vs_dh.c b/net/ipv4/ipvs/ip_vs_dh.c
index dcf5d46aaa5e..8afc1503ed20 100644
--- a/net/ipv4/ipvs/ip_vs_dh.c
+++ b/net/ipv4/ipvs/ip_vs_dh.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Destination Hashing scheduling module 2 * IPVS: Destination Hashing scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_dh.c,v 1.5 2002/09/15 08:14:08 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@gnuchina.org> 4 * Authors: Wensong Zhang <wensong@gnuchina.org>
7 * 5 *
8 * Inspired by the consistent hashing scheduler patch from 6 * Inspired by the consistent hashing scheduler patch from
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c
index dfa0d713c801..bc04eedd6dbb 100644
--- a/net/ipv4/ipvs/ip_vs_est.c
+++ b/net/ipv4/ipvs/ip_vs_est.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_est.c: simple rate estimator for IPVS 2 * ip_vs_est.c: simple rate estimator for IPVS
3 * 3 *
4 * Version: $Id: ip_vs_est.c,v 1.4 2002/11/30 01:50:35 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c
index 59aa166b7678..c1c758e4f733 100644
--- a/net/ipv4/ipvs/ip_vs_ftp.c
+++ b/net/ipv4/ipvs/ip_vs_ftp.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_ftp.c: IPVS ftp application module 2 * ip_vs_ftp.c: IPVS ftp application module
3 * 3 *
4 * Version: $Id: ip_vs_ftp.c,v 1.13 2002/09/15 08:14:08 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * 5 *
8 * Changes: 6 * Changes:
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c
index 3888642706ad..0efa3db4b180 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/ipv4/ipvs/ip_vs_lblc.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Locality-Based Least-Connection scheduling module 2 * IPVS: Locality-Based Least-Connection scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_lblc.c,v 1.10 2002/09/15 08:14:08 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@gnuchina.org> 4 * Authors: Wensong Zhang <wensong@gnuchina.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c
index daa260eb21cf..8e3bbeb45138 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Locality-Based Least-Connection with Replication scheduler 2 * IPVS: Locality-Based Least-Connection with Replication scheduler
3 * 3 *
4 * Version: $Id: ip_vs_lblcr.c,v 1.11 2002/09/15 08:14:08 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@gnuchina.org> 4 * Authors: Wensong Zhang <wensong@gnuchina.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_lc.c b/net/ipv4/ipvs/ip_vs_lc.c
index d88fef90a641..ac9f08e065d5 100644
--- a/net/ipv4/ipvs/ip_vs_lc.c
+++ b/net/ipv4/ipvs/ip_vs_lc.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Least-Connection Scheduling module 2 * IPVS: Least-Connection Scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_lc.c,v 1.10 2003/04/18 09:03:16 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_nq.c b/net/ipv4/ipvs/ip_vs_nq.c
index bc2a9e5f2a7b..a46bf258d420 100644
--- a/net/ipv4/ipvs/ip_vs_nq.c
+++ b/net/ipv4/ipvs/ip_vs_nq.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Never Queue scheduling module 2 * IPVS: Never Queue scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_nq.c,v 1.2 2003/06/08 09:31:19 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index 4b1c16cbb16b..876714f23d65 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_proto.c: transport protocol load balancing support for IPVS 2 * ip_vs_proto.c: transport protocol load balancing support for IPVS
3 * 3 *
4 * Version: $Id: ip_vs_proto.c,v 1.2 2003/04/18 09:03:16 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * Julian Anastasov <ja@ssi.bg> 5 * Julian Anastasov <ja@ssi.bg>
8 * 6 *
diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c
index 4bf835e1d86d..73e0ea87c1f5 100644
--- a/net/ipv4/ipvs/ip_vs_proto_ah.c
+++ b/net/ipv4/ipvs/ip_vs_proto_ah.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_proto_ah.c: AH IPSec load balancing support for IPVS 2 * ip_vs_proto_ah.c: AH IPSec load balancing support for IPVS
3 * 3 *
4 * Version: $Id: ip_vs_proto_ah.c,v 1.1 2003/07/04 15:04:37 wensong Exp $
5 *
6 * Authors: Julian Anastasov <ja@ssi.bg>, February 2002 4 * Authors: Julian Anastasov <ja@ssi.bg>, February 2002
7 * Wensong Zhang <wensong@linuxvirtualserver.org> 5 * Wensong Zhang <wensong@linuxvirtualserver.org>
8 * 6 *
diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c
index db6a6b7b1a0b..21d70c8ffa54 100644
--- a/net/ipv4/ipvs/ip_vs_proto_esp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_esp.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_proto_esp.c: ESP IPSec load balancing support for IPVS 2 * ip_vs_proto_esp.c: ESP IPSec load balancing support for IPVS
3 * 3 *
4 * Version: $Id: ip_vs_proto_esp.c,v 1.1 2003/07/04 15:04:37 wensong Exp $
5 *
6 * Authors: Julian Anastasov <ja@ssi.bg>, February 2002 4 * Authors: Julian Anastasov <ja@ssi.bg>, February 2002
7 * Wensong Zhang <wensong@linuxvirtualserver.org> 5 * Wensong Zhang <wensong@linuxvirtualserver.org>
8 * 6 *
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index b83dc14b0a4d..d0ea467986a0 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_proto_tcp.c: TCP load balancing support for IPVS 2 * ip_vs_proto_tcp.c: TCP load balancing support for IPVS
3 * 3 *
4 * Version: $Id: ip_vs_proto_tcp.c,v 1.3 2002/11/30 01:50:35 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * Julian Anastasov <ja@ssi.bg> 5 * Julian Anastasov <ja@ssi.bg>
8 * 6 *
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 75771cb3cd6f..c6be5d56823f 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_proto_udp.c: UDP load balancing support for IPVS 2 * ip_vs_proto_udp.c: UDP load balancing support for IPVS
3 * 3 *
4 * Version: $Id: ip_vs_proto_udp.c,v 1.3 2002/11/30 01:50:35 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * Julian Anastasov <ja@ssi.bg> 5 * Julian Anastasov <ja@ssi.bg>
8 * 6 *
diff --git a/net/ipv4/ipvs/ip_vs_rr.c b/net/ipv4/ipvs/ip_vs_rr.c
index 433f8a947924..c8db12d39e61 100644
--- a/net/ipv4/ipvs/ip_vs_rr.c
+++ b/net/ipv4/ipvs/ip_vs_rr.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Round-Robin Scheduling module 2 * IPVS: Round-Robin Scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_rr.c,v 1.9 2002/09/15 08:14:08 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * Peter Kese <peter.kese@ijs.si> 5 * Peter Kese <peter.kese@ijs.si>
8 * 6 *
diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c
index 121a32b1b756..b64767309855 100644
--- a/net/ipv4/ipvs/ip_vs_sched.c
+++ b/net/ipv4/ipvs/ip_vs_sched.c
@@ -5,8 +5,6 @@
5 * high-performance and highly available server based on a 5 * high-performance and highly available server based on a
6 * cluster of servers. 6 * cluster of servers.
7 * 7 *
8 * Version: $Id: ip_vs_sched.c,v 1.13 2003/05/10 03:05:23 wensong Exp $
9 *
10 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 8 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
11 * Peter Kese <peter.kese@ijs.si> 9 * Peter Kese <peter.kese@ijs.si>
12 * 10 *
diff --git a/net/ipv4/ipvs/ip_vs_sed.c b/net/ipv4/ipvs/ip_vs_sed.c
index dd7c128f9db3..2a7d31358181 100644
--- a/net/ipv4/ipvs/ip_vs_sed.c
+++ b/net/ipv4/ipvs/ip_vs_sed.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Shortest Expected Delay scheduling module 2 * IPVS: Shortest Expected Delay scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_sed.c,v 1.1 2003/05/10 03:06:08 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_sh.c b/net/ipv4/ipvs/ip_vs_sh.c
index 1b25b00ef1e1..b8fdfac65001 100644
--- a/net/ipv4/ipvs/ip_vs_sh.c
+++ b/net/ipv4/ipvs/ip_vs_sh.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Source Hashing scheduling module 2 * IPVS: Source Hashing scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_sh.c,v 1.5 2002/09/15 08:14:08 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@gnuchina.org> 4 * Authors: Wensong Zhang <wensong@gnuchina.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index eff54efe0351..2d4a86f73325 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -5,8 +5,6 @@
5 * high-performance and highly available server based on a 5 * high-performance and highly available server based on a
6 * cluster of servers. 6 * cluster of servers.
7 * 7 *
8 * Version: $Id: ip_vs_sync.c,v 1.13 2003/06/08 09:31:19 wensong Exp $
9 *
10 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 8 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
11 * 9 *
12 * ip_vs_sync: sync connection info from master load balancer to backups 10 * ip_vs_sync: sync connection info from master load balancer to backups
diff --git a/net/ipv4/ipvs/ip_vs_wlc.c b/net/ipv4/ipvs/ip_vs_wlc.c
index 8a9d913261d8..772c3cb4eca1 100644
--- a/net/ipv4/ipvs/ip_vs_wlc.c
+++ b/net/ipv4/ipvs/ip_vs_wlc.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Weighted Least-Connection Scheduling module 2 * IPVS: Weighted Least-Connection Scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_wlc.c,v 1.13 2003/04/18 09:03:16 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * Peter Kese <peter.kese@ijs.si> 5 * Peter Kese <peter.kese@ijs.si>
8 * 6 *
diff --git a/net/ipv4/ipvs/ip_vs_wrr.c b/net/ipv4/ipvs/ip_vs_wrr.c
index 85c680add6df..1d6932d7dc97 100644
--- a/net/ipv4/ipvs/ip_vs_wrr.c
+++ b/net/ipv4/ipvs/ip_vs_wrr.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * IPVS: Weighted Round-Robin Scheduling module 2 * IPVS: Weighted Round-Robin Scheduling module
3 * 3 *
4 * Version: $Id: ip_vs_wrr.c,v 1.12 2002/09/15 08:14:08 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index f63006caea03..9892d4aca42e 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * ip_vs_xmit.c: various packet transmitters for IPVS 2 * ip_vs_xmit.c: various packet transmitters for IPVS
3 * 3 *
4 * Version: $Id: ip_vs_xmit.c,v 1.2 2002/11/30 01:50:35 wensong Exp $
5 *
6 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> 4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
7 * Julian Anastasov <ja@ssi.bg> 5 * Julian Anastasov <ja@ssi.bg>
8 * 6 *
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 2767841a8cef..6e251402506e 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -365,6 +365,18 @@ config IP_NF_RAW
365 If you want to compile it as a module, say M here and read 365 If you want to compile it as a module, say M here and read
366 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 366 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
367 367
368# security table for MAC policy
369config IP_NF_SECURITY
370 tristate "Security table"
371 depends on IP_NF_IPTABLES
372 depends on SECURITY
373 default m if NETFILTER_ADVANCED=n
374 help
375 This option adds a `security' table to iptables, for use
376 with Mandatory Access Control (MAC) policy.
377
378 If unsure, say N.
379
368# ARP tables 380# ARP tables
369config IP_NF_ARPTABLES 381config IP_NF_ARPTABLES
370 tristate "ARP tables support" 382 tristate "ARP tables support"
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index d9b92fbf5579..3f31291f37ce 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
42obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o 42obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
43obj-$(CONFIG_NF_NAT) += iptable_nat.o 43obj-$(CONFIG_NF_NAT) += iptable_nat.o
44obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o 44obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
45obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
45 46
46# matches 47# matches
47obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 48obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 26a37cedcf2e..aa33a4a7a715 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -156,7 +156,6 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
156 case IPQ_COPY_META: 156 case IPQ_COPY_META:
157 case IPQ_COPY_NONE: 157 case IPQ_COPY_NONE:
158 size = NLMSG_SPACE(sizeof(*pmsg)); 158 size = NLMSG_SPACE(sizeof(*pmsg));
159 data_len = 0;
160 break; 159 break;
161 160
162 case IPQ_COPY_PACKET: 161 case IPQ_COPY_PACKET:
@@ -224,8 +223,6 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
224 return skb; 223 return skb;
225 224
226nlmsg_failure: 225nlmsg_failure:
227 if (skb)
228 kfree_skb(skb);
229 *errp = -EINVAL; 226 *errp = -EINVAL;
230 printk(KERN_ERR "ip_queue: error creating packet message\n"); 227 printk(KERN_ERR "ip_queue: error creating packet message\n");
231 return NULL; 228 return NULL;
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
new file mode 100644
index 000000000000..2b472ac2263a
--- /dev/null
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -0,0 +1,180 @@
1/*
2 * "security" table
3 *
4 * This is for use by Mandatory Access Control (MAC) security models,
5 * which need to be able to manage security policy in separate context
6 * to DAC.
7 *
8 * Based on iptable_mangle.c
9 *
10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
11 * Copyright (C) 2000-2004 Netfilter Core Team <coreteam <at> netfilter.org>
12 * Copyright (C) 2008 Red Hat, Inc., James Morris <jmorris <at> redhat.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/module.h>
19#include <linux/netfilter_ipv4/ip_tables.h>
20#include <net/ip.h>
21
22MODULE_LICENSE("GPL");
23MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>");
24MODULE_DESCRIPTION("iptables security table, for MAC rules");
25
26#define SECURITY_VALID_HOOKS (1 << NF_INET_LOCAL_IN) | \
27 (1 << NF_INET_FORWARD) | \
28 (1 << NF_INET_LOCAL_OUT)
29
30static struct
31{
32 struct ipt_replace repl;
33 struct ipt_standard entries[3];
34 struct ipt_error term;
35} initial_table __initdata = {
36 .repl = {
37 .name = "security",
38 .valid_hooks = SECURITY_VALID_HOOKS,
39 .num_entries = 4,
40 .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
41 .hook_entry = {
42 [NF_INET_LOCAL_IN] = 0,
43 [NF_INET_FORWARD] = sizeof(struct ipt_standard),
44 [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
45 },
46 .underflow = {
47 [NF_INET_LOCAL_IN] = 0,
48 [NF_INET_FORWARD] = sizeof(struct ipt_standard),
49 [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
50 },
51 },
52 .entries = {
53 IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
54 IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
55 IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
56 },
57 .term = IPT_ERROR_INIT, /* ERROR */
58};
59
60static struct xt_table security_table = {
61 .name = "security",
62 .valid_hooks = SECURITY_VALID_HOOKS,
63 .lock = __RW_LOCK_UNLOCKED(security_table.lock),
64 .me = THIS_MODULE,
65 .af = AF_INET,
66};
67
68static unsigned int
69ipt_local_in_hook(unsigned int hook,
70 struct sk_buff *skb,
71 const struct net_device *in,
72 const struct net_device *out,
73 int (*okfn)(struct sk_buff *))
74{
75 return ipt_do_table(skb, hook, in, out,
76 nf_local_in_net(in, out)->ipv4.iptable_security);
77}
78
79static unsigned int
80ipt_forward_hook(unsigned int hook,
81 struct sk_buff *skb,
82 const struct net_device *in,
83 const struct net_device *out,
84 int (*okfn)(struct sk_buff *))
85{
86 return ipt_do_table(skb, hook, in, out,
87 nf_forward_net(in, out)->ipv4.iptable_security);
88}
89
90static unsigned int
91ipt_local_out_hook(unsigned int hook,
92 struct sk_buff *skb,
93 const struct net_device *in,
94 const struct net_device *out,
95 int (*okfn)(struct sk_buff *))
96{
97 /* Somebody is playing with raw sockets. */
98 if (skb->len < sizeof(struct iphdr)
99 || ip_hdrlen(skb) < sizeof(struct iphdr)) {
100 if (net_ratelimit())
101 printk(KERN_INFO "iptable_security: ignoring short "
102 "SOCK_RAW packet.\n");
103 return NF_ACCEPT;
104 }
105 return ipt_do_table(skb, hook, in, out,
106 nf_local_out_net(in, out)->ipv4.iptable_security);
107}
108
109static struct nf_hook_ops ipt_ops[] __read_mostly = {
110 {
111 .hook = ipt_local_in_hook,
112 .owner = THIS_MODULE,
113 .pf = PF_INET,
114 .hooknum = NF_INET_LOCAL_IN,
115 .priority = NF_IP_PRI_SECURITY,
116 },
117 {
118 .hook = ipt_forward_hook,
119 .owner = THIS_MODULE,
120 .pf = PF_INET,
121 .hooknum = NF_INET_FORWARD,
122 .priority = NF_IP_PRI_SECURITY,
123 },
124 {
125 .hook = ipt_local_out_hook,
126 .owner = THIS_MODULE,
127 .pf = PF_INET,
128 .hooknum = NF_INET_LOCAL_OUT,
129 .priority = NF_IP_PRI_SECURITY,
130 },
131};
132
133static int __net_init iptable_security_net_init(struct net *net)
134{
135 net->ipv4.iptable_security =
136 ipt_register_table(net, &security_table, &initial_table.repl);
137
138 if (IS_ERR(net->ipv4.iptable_security))
139 return PTR_ERR(net->ipv4.iptable_security);
140
141 return 0;
142}
143
144static void __net_exit iptable_security_net_exit(struct net *net)
145{
146 ipt_unregister_table(net->ipv4.iptable_security);
147}
148
149static struct pernet_operations iptable_security_net_ops = {
150 .init = iptable_security_net_init,
151 .exit = iptable_security_net_exit,
152};
153
154static int __init iptable_security_init(void)
155{
156 int ret;
157
158 ret = register_pernet_subsys(&iptable_security_net_ops);
159 if (ret < 0)
160 return ret;
161
162 ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
163 if (ret < 0)
164 goto cleanup_table;
165
166 return ret;
167
168cleanup_table:
169 unregister_pernet_subsys(&iptable_security_net_ops);
170 return ret;
171}
172
173static void __exit iptable_security_fini(void)
174{
175 nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
176 unregister_pernet_subsys(&iptable_security_net_ops);
177}
178
179module_init(iptable_security_init);
180module_exit(iptable_security_fini);
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 78ab19accace..97791048fa9b 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -87,9 +87,8 @@ static int icmp_packet(struct nf_conn *ct,
87 means this will only run once even if count hits zero twice 87 means this will only run once even if count hits zero twice
88 (theoretically possible with SMP) */ 88 (theoretically possible with SMP) */
89 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { 89 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
90 if (atomic_dec_and_test(&ct->proto.icmp.count) 90 if (atomic_dec_and_test(&ct->proto.icmp.count))
91 && del_timer(&ct->timeout)) 91 nf_ct_kill_acct(ct, ctinfo, skb);
92 ct->timeout.function((unsigned long)ct);
93 } else { 92 } else {
94 atomic_inc(&ct->proto.icmp.count); 93 atomic_inc(&ct->proto.icmp.count);
95 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 94 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 552169b41b16..eb5cee279c5f 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -7,8 +7,6 @@
7 * PROC file system. It is mainly used for debugging and 7 * PROC file system. It is mainly used for debugging and
8 * statistics. 8 * statistics.
9 * 9 *
10 * Version: $Id: proc.c,v 1.45 2001/05/16 16:45:35 davem Exp $
11 *
12 * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 10 * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
13 * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de> 11 * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
14 * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de> 12 * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 971ab9356e51..ea50da0649fd 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * INET protocol dispatch tables. 6 * INET protocol dispatch tables.
7 * 7 *
8 * Version: $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * 10 *
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index e7e091d365ff..1d0c97c8712d 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * RAW - implementation of IP "raw" sockets. 6 * RAW - implementation of IP "raw" sockets.
7 * 7 *
8 * Version: $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * 10 *
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 96be336064fb..fe3a02237286 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * ROUTE - implementation of the IP router. 6 * ROUTE - implementation of the IP router.
7 * 7 *
8 * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Alan Cox, <gw4pts@gw4pts.ampr.org> 10 * Alan Cox, <gw4pts@gw4pts.ampr.org>
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index d182a2a26291..fdde2ae07e24 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -8,8 +8,6 @@
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 *
12 * $Id: syncookies.c,v 1.18 2002/02/01 22:01:04 davem Exp $
13 */ 11 */
14 12
15#include <linux/tcp.h> 13#include <linux/tcp.h>
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index c437f804ee38..901607003205 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem. 2 * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem.
3 * 3 *
4 * $Id: sysctl_net_ipv4.c,v 1.50 2001/10/20 00:00:11 davem Exp $
5 *
6 * Begun April 1, 1996, Mike Shaver. 4 * Begun April 1, 1996, Mike Shaver.
7 * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS] 5 * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS]
8 */ 6 */
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index fc54a48fde1e..cf0850c068f5 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * Implementation of the Transmission Control Protocol(TCP). 6 * Implementation of the Transmission Control Protocol(TCP).
7 * 7 *
8 * Version: $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 10 * Mark Evans, <evansmp@uhura.aston.ac.uk>
@@ -2463,6 +2461,76 @@ static unsigned long tcp_md5sig_users;
2463static struct tcp_md5sig_pool **tcp_md5sig_pool; 2461static struct tcp_md5sig_pool **tcp_md5sig_pool;
2464static DEFINE_SPINLOCK(tcp_md5sig_pool_lock); 2462static DEFINE_SPINLOCK(tcp_md5sig_pool_lock);
2465 2463
2464int tcp_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
2465 int bplen,
2466 struct tcphdr *th, unsigned int tcplen,
2467 struct tcp_md5sig_pool *hp)
2468{
2469 struct scatterlist sg[4];
2470 __u16 data_len;
2471 int block = 0;
2472 __sum16 cksum;
2473 struct hash_desc *desc = &hp->md5_desc;
2474 int err;
2475 unsigned int nbytes = 0;
2476
2477 sg_init_table(sg, 4);
2478
2479 /* 1. The TCP pseudo-header */
2480 sg_set_buf(&sg[block++], &hp->md5_blk, bplen);
2481 nbytes += bplen;
2482
2483 /* 2. The TCP header, excluding options, and assuming a
2484 * checksum of zero
2485 */
2486 cksum = th->check;
2487 th->check = 0;
2488 sg_set_buf(&sg[block++], th, sizeof(*th));
2489 nbytes += sizeof(*th);
2490
2491 /* 3. The TCP segment data (if any) */
2492 data_len = tcplen - (th->doff << 2);
2493 if (data_len > 0) {
2494 u8 *data = (u8 *)th + (th->doff << 2);
2495 sg_set_buf(&sg[block++], data, data_len);
2496 nbytes += data_len;
2497 }
2498
2499 /* 4. an independently-specified key or password, known to both
2500 * TCPs and presumably connection-specific
2501 */
2502 sg_set_buf(&sg[block++], key->key, key->keylen);
2503 nbytes += key->keylen;
2504
2505 sg_mark_end(&sg[block - 1]);
2506
2507 /* Now store the hash into the packet */
2508 err = crypto_hash_init(desc);
2509 if (err) {
2510 if (net_ratelimit())
2511 printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
2512 return -1;
2513 }
2514 err = crypto_hash_update(desc, sg, nbytes);
2515 if (err) {
2516 if (net_ratelimit())
2517 printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
2518 return -1;
2519 }
2520 err = crypto_hash_final(desc, md5_hash);
2521 if (err) {
2522 if (net_ratelimit())
2523 printk(KERN_WARNING "%s(): hash_final failed\n", __func__);
2524 return -1;
2525 }
2526
2527 /* Reset header */
2528 th->check = cksum;
2529
2530 return 0;
2531}
2532EXPORT_SYMBOL(tcp_calc_md5_hash);
2533
2466static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool) 2534static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool)
2467{ 2535{
2468 int cpu; 2536 int cpu;
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 2fbcc7d1b1a0..838d491dfda7 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * tcp_diag.c Module for monitoring TCP transport protocols sockets. 2 * tcp_diag.c Module for monitoring TCP transport protocols sockets.
3 * 3 *
4 * Version: $Id: tcp_diag.c,v 1.3 2002/02/01 22:01:04 davem Exp $
5 *
6 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 4 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
7 * 5 *
8 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index cad73b7dfef0..de30e70ff256 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * Implementation of the Transmission Control Protocol(TCP). 6 * Implementation of the Transmission Control Protocol(TCP).
7 * 7 *
8 * Version: $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 10 * Mark Evans, <evansmp@uhura.aston.ac.uk>
@@ -3450,6 +3448,43 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
3450 return 1; 3448 return 1;
3451} 3449}
3452 3450
3451#ifdef CONFIG_TCP_MD5SIG
3452/*
3453 * Parse MD5 Signature option
3454 */
3455u8 *tcp_parse_md5sig_option(struct tcphdr *th)
3456{
3457 int length = (th->doff << 2) - sizeof (*th);
3458 u8 *ptr = (u8*)(th + 1);
3459
3460 /* If the TCP option is too short, we can short cut */
3461 if (length < TCPOLEN_MD5SIG)
3462 return NULL;
3463
3464 while (length > 0) {
3465 int opcode = *ptr++;
3466 int opsize;
3467
3468 switch(opcode) {
3469 case TCPOPT_EOL:
3470 return NULL;
3471 case TCPOPT_NOP:
3472 length--;
3473 continue;
3474 default:
3475 opsize = *ptr++;
3476 if (opsize < 2 || opsize > length)
3477 return NULL;
3478 if (opcode == TCPOPT_MD5SIG)
3479 return ptr;
3480 }
3481 ptr += opsize - 2;
3482 length -= opsize;
3483 }
3484 return NULL;
3485}
3486#endif
3487
3453static inline void tcp_store_ts_recent(struct tcp_sock *tp) 3488static inline void tcp_store_ts_recent(struct tcp_sock *tp)
3454{ 3489{
3455 tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; 3490 tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
@@ -5422,6 +5457,9 @@ EXPORT_SYMBOL(sysctl_tcp_ecn);
5422EXPORT_SYMBOL(sysctl_tcp_reordering); 5457EXPORT_SYMBOL(sysctl_tcp_reordering);
5423EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); 5458EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
5424EXPORT_SYMBOL(tcp_parse_options); 5459EXPORT_SYMBOL(tcp_parse_options);
5460#ifdef CONFIG_TCP_MD5SIG
5461EXPORT_SYMBOL(tcp_parse_md5sig_option);
5462#endif
5425EXPORT_SYMBOL(tcp_rcv_established); 5463EXPORT_SYMBOL(tcp_rcv_established);
5426EXPORT_SYMBOL(tcp_rcv_state_process); 5464EXPORT_SYMBOL(tcp_rcv_state_process);
5427EXPORT_SYMBOL(tcp_initialize_rcv_mss); 5465EXPORT_SYMBOL(tcp_initialize_rcv_mss);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 97a230026e13..b219a7a7cd08 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * Implementation of the Transmission Control Protocol(TCP). 6 * Implementation of the Transmission Control Protocol(TCP).
7 * 7 *
8 * Version: $Id: tcp_ipv4.c,v 1.240 2002/02/01 22:01:04 davem Exp $
9 *
10 * IPv4 specific functions 8 * IPv4 specific functions
11 * 9 *
12 * 10 *
@@ -95,8 +93,13 @@ static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
95 __be32 addr); 93 __be32 addr);
96static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 94static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
97 __be32 saddr, __be32 daddr, 95 __be32 saddr, __be32 daddr,
98 struct tcphdr *th, int protocol, 96 struct tcphdr *th, unsigned int tcplen);
99 unsigned int tcplen); 97#else
98static inline
99struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr)
100{
101 return NULL;
102}
100#endif 103#endif
101 104
102struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { 105struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
@@ -586,8 +589,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
586 key, 589 key,
587 ip_hdr(skb)->daddr, 590 ip_hdr(skb)->daddr,
588 ip_hdr(skb)->saddr, 591 ip_hdr(skb)->saddr,
589 &rep.th, IPPROTO_TCP, 592 &rep.th, arg.iov[0].iov_len);
590 arg.iov[0].iov_len);
591 } 593 }
592#endif 594#endif
593 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, 595 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
@@ -606,9 +608,9 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
606 outside socket context is ugly, certainly. What can I do? 608 outside socket context is ugly, certainly. What can I do?
607 */ 609 */
608 610
609static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, 611static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
610 struct sk_buff *skb, u32 seq, u32 ack, 612 u32 win, u32 ts, int oif,
611 u32 win, u32 ts) 613 struct tcp_md5sig_key *key)
612{ 614{
613 struct tcphdr *th = tcp_hdr(skb); 615 struct tcphdr *th = tcp_hdr(skb);
614 struct { 616 struct {
@@ -620,10 +622,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
620 ]; 622 ];
621 } rep; 623 } rep;
622 struct ip_reply_arg arg; 624 struct ip_reply_arg arg;
623#ifdef CONFIG_TCP_MD5SIG
624 struct tcp_md5sig_key *key;
625 struct tcp_md5sig_key tw_key;
626#endif
627 625
628 memset(&rep.th, 0, sizeof(struct tcphdr)); 626 memset(&rep.th, 0, sizeof(struct tcphdr));
629 memset(&arg, 0, sizeof(arg)); 627 memset(&arg, 0, sizeof(arg));
@@ -649,23 +647,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
649 rep.th.window = htons(win); 647 rep.th.window = htons(win);
650 648
651#ifdef CONFIG_TCP_MD5SIG 649#ifdef CONFIG_TCP_MD5SIG
652 /*
653 * The SKB holds an imcoming packet, but may not have a valid ->sk
654 * pointer. This is especially the case when we're dealing with a
655 * TIME_WAIT ack, because the sk structure is long gone, and only
656 * the tcp_timewait_sock remains. So the md5 key is stashed in that
657 * structure, and we use it in preference. I believe that (twsk ||
658 * skb->sk) holds true, but we program defensively.
659 */
660 if (!twsk && skb->sk) {
661 key = tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr);
662 } else if (twsk && twsk->tw_md5_keylen) {
663 tw_key.key = twsk->tw_md5_key;
664 tw_key.keylen = twsk->tw_md5_keylen;
665 key = &tw_key;
666 } else
667 key = NULL;
668
669 if (key) { 650 if (key) {
670 int offset = (ts) ? 3 : 0; 651 int offset = (ts) ? 3 : 0;
671 652
@@ -680,16 +661,15 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
680 key, 661 key,
681 ip_hdr(skb)->daddr, 662 ip_hdr(skb)->daddr,
682 ip_hdr(skb)->saddr, 663 ip_hdr(skb)->saddr,
683 &rep.th, IPPROTO_TCP, 664 &rep.th, arg.iov[0].iov_len);
684 arg.iov[0].iov_len);
685 } 665 }
686#endif 666#endif
687 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, 667 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
688 ip_hdr(skb)->saddr, /* XXX */ 668 ip_hdr(skb)->saddr, /* XXX */
689 arg.iov[0].iov_len, IPPROTO_TCP, 0); 669 arg.iov[0].iov_len, IPPROTO_TCP, 0);
690 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 670 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
691 if (twsk) 671 if (oif)
692 arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if; 672 arg.bound_dev_if = oif;
693 673
694 ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb, 674 ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb,
695 &arg, arg.iov[0].iov_len); 675 &arg, arg.iov[0].iov_len);
@@ -702,9 +682,12 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
702 struct inet_timewait_sock *tw = inet_twsk(sk); 682 struct inet_timewait_sock *tw = inet_twsk(sk);
703 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 683 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
704 684
705 tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 685 tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
706 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 686 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
707 tcptw->tw_ts_recent); 687 tcptw->tw_ts_recent,
688 tw->tw_bound_dev_if,
689 tcp_twsk_md5_key(tcptw)
690 );
708 691
709 inet_twsk_put(tw); 692 inet_twsk_put(tw);
710} 693}
@@ -712,9 +695,11 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
712static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, 695static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
713 struct request_sock *req) 696 struct request_sock *req)
714{ 697{
715 tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, 698 tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1,
716 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, 699 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
717 req->ts_recent); 700 req->ts_recent,
701 0,
702 tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr));
718} 703}
719 704
720/* 705/*
@@ -1006,18 +991,12 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
1006 991
1007static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 992static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1008 __be32 saddr, __be32 daddr, 993 __be32 saddr, __be32 daddr,
1009 struct tcphdr *th, int protocol, 994 struct tcphdr *th,
1010 unsigned int tcplen) 995 unsigned int tcplen)
1011{ 996{
1012 struct scatterlist sg[4];
1013 __u16 data_len;
1014 int block = 0;
1015 __sum16 old_checksum;
1016 struct tcp_md5sig_pool *hp; 997 struct tcp_md5sig_pool *hp;
1017 struct tcp4_pseudohdr *bp; 998 struct tcp4_pseudohdr *bp;
1018 struct hash_desc *desc;
1019 int err; 999 int err;
1020 unsigned int nbytes = 0;
1021 1000
1022 /* 1001 /*
1023 * Okay, so RFC2385 is turned on for this connection, 1002 * Okay, so RFC2385 is turned on for this connection,
@@ -1029,63 +1008,25 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1029 goto clear_hash_noput; 1008 goto clear_hash_noput;
1030 1009
1031 bp = &hp->md5_blk.ip4; 1010 bp = &hp->md5_blk.ip4;
1032 desc = &hp->md5_desc;
1033 1011
1034 /* 1012 /*
1035 * 1. the TCP pseudo-header (in the order: source IP address, 1013 * The TCP pseudo-header (in the order: source IP address,
1036 * destination IP address, zero-padded protocol number, and 1014 * destination IP address, zero-padded protocol number, and
1037 * segment length) 1015 * segment length)
1038 */ 1016 */
1039 bp->saddr = saddr; 1017 bp->saddr = saddr;
1040 bp->daddr = daddr; 1018 bp->daddr = daddr;
1041 bp->pad = 0; 1019 bp->pad = 0;
1042 bp->protocol = protocol; 1020 bp->protocol = IPPROTO_TCP;
1043 bp->len = htons(tcplen); 1021 bp->len = htons(tcplen);
1044 1022
1045 sg_init_table(sg, 4); 1023 err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp),
1046 1024 th, tcplen, hp);
1047 sg_set_buf(&sg[block++], bp, sizeof(*bp));
1048 nbytes += sizeof(*bp);
1049
1050 /* 2. the TCP header, excluding options, and assuming a
1051 * checksum of zero/
1052 */
1053 old_checksum = th->check;
1054 th->check = 0;
1055 sg_set_buf(&sg[block++], th, sizeof(struct tcphdr));
1056 nbytes += sizeof(struct tcphdr);
1057
1058 /* 3. the TCP segment data (if any) */
1059 data_len = tcplen - (th->doff << 2);
1060 if (data_len > 0) {
1061 unsigned char *data = (unsigned char *)th + (th->doff << 2);
1062 sg_set_buf(&sg[block++], data, data_len);
1063 nbytes += data_len;
1064 }
1065
1066 /* 4. an independently-specified key or password, known to both
1067 * TCPs and presumably connection-specific
1068 */
1069 sg_set_buf(&sg[block++], key->key, key->keylen);
1070 nbytes += key->keylen;
1071
1072 sg_mark_end(&sg[block - 1]);
1073
1074 /* Now store the Hash into the packet */
1075 err = crypto_hash_init(desc);
1076 if (err)
1077 goto clear_hash;
1078 err = crypto_hash_update(desc, sg, nbytes);
1079 if (err)
1080 goto clear_hash;
1081 err = crypto_hash_final(desc, md5_hash);
1082 if (err) 1025 if (err)
1083 goto clear_hash; 1026 goto clear_hash;
1084 1027
1085 /* Reset header, and free up the crypto */ 1028 /* Free up the crypto pool */
1086 tcp_put_md5sig_pool(); 1029 tcp_put_md5sig_pool();
1087 th->check = old_checksum;
1088
1089out: 1030out:
1090 return 0; 1031 return 0;
1091clear_hash: 1032clear_hash:
@@ -1099,7 +1040,7 @@ int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1099 struct sock *sk, 1040 struct sock *sk,
1100 struct dst_entry *dst, 1041 struct dst_entry *dst,
1101 struct request_sock *req, 1042 struct request_sock *req,
1102 struct tcphdr *th, int protocol, 1043 struct tcphdr *th,
1103 unsigned int tcplen) 1044 unsigned int tcplen)
1104{ 1045{
1105 __be32 saddr, daddr; 1046 __be32 saddr, daddr;
@@ -1115,7 +1056,7 @@ int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1115 } 1056 }
1116 return tcp_v4_do_calc_md5_hash(md5_hash, key, 1057 return tcp_v4_do_calc_md5_hash(md5_hash, key,
1117 saddr, daddr, 1058 saddr, daddr,
1118 th, protocol, tcplen); 1059 th, tcplen);
1119} 1060}
1120 1061
1121EXPORT_SYMBOL(tcp_v4_calc_md5_hash); 1062EXPORT_SYMBOL(tcp_v4_calc_md5_hash);
@@ -1134,52 +1075,12 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb)
1134 struct tcp_md5sig_key *hash_expected; 1075 struct tcp_md5sig_key *hash_expected;
1135 const struct iphdr *iph = ip_hdr(skb); 1076 const struct iphdr *iph = ip_hdr(skb);
1136 struct tcphdr *th = tcp_hdr(skb); 1077 struct tcphdr *th = tcp_hdr(skb);
1137 int length = (th->doff << 2) - sizeof(struct tcphdr);
1138 int genhash; 1078 int genhash;
1139 unsigned char *ptr;
1140 unsigned char newhash[16]; 1079 unsigned char newhash[16];
1141 1080
1142 hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr); 1081 hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr);
1082 hash_location = tcp_parse_md5sig_option(th);
1143 1083
1144 /*
1145 * If the TCP option length is less than the TCP_MD5SIG
1146 * option length, then we can shortcut
1147 */
1148 if (length < TCPOLEN_MD5SIG) {
1149 if (hash_expected)
1150 return 1;
1151 else
1152 return 0;
1153 }
1154
1155 /* Okay, we can't shortcut - we have to grub through the options */
1156 ptr = (unsigned char *)(th + 1);
1157 while (length > 0) {
1158 int opcode = *ptr++;
1159 int opsize;
1160
1161 switch (opcode) {
1162 case TCPOPT_EOL:
1163 goto done_opts;
1164 case TCPOPT_NOP:
1165 length--;
1166 continue;
1167 default:
1168 opsize = *ptr++;
1169 if (opsize < 2)
1170 goto done_opts;
1171 if (opsize > length)
1172 goto done_opts;
1173
1174 if (opcode == TCPOPT_MD5SIG) {
1175 hash_location = ptr;
1176 goto done_opts;
1177 }
1178 }
1179 ptr += opsize-2;
1180 length -= opsize;
1181 }
1182done_opts:
1183 /* We've parsed the options - do we have a hash? */ 1084 /* We've parsed the options - do we have a hash? */
1184 if (!hash_expected && !hash_location) 1085 if (!hash_expected && !hash_location)
1185 return 0; 1086 return 0;
@@ -1206,8 +1107,7 @@ done_opts:
1206 genhash = tcp_v4_do_calc_md5_hash(newhash, 1107 genhash = tcp_v4_do_calc_md5_hash(newhash,
1207 hash_expected, 1108 hash_expected,
1208 iph->saddr, iph->daddr, 1109 iph->saddr, iph->daddr,
1209 th, sk->sk_protocol, 1110 th, skb->len);
1210 skb->len);
1211 1111
1212 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 1112 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
1213 if (net_ratelimit()) { 1113 if (net_ratelimit()) {
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 8245247a6ceb..ea68a478fad6 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * Implementation of the Transmission Control Protocol(TCP). 6 * Implementation of the Transmission Control Protocol(TCP).
7 * 7 *
8 * Version: $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 10 * Mark Evans, <evansmp@uhura.aston.ac.uk>
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index ad993ecb4810..8f83ab432705 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * Implementation of the Transmission Control Protocol(TCP). 6 * Implementation of the Transmission Control Protocol(TCP).
7 * 7 *
8 * Version: $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 10 * Mark Evans, <evansmp@uhura.aston.ac.uk>
@@ -607,7 +605,6 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
607 md5, 605 md5,
608 sk, NULL, NULL, 606 sk, NULL, NULL,
609 tcp_hdr(skb), 607 tcp_hdr(skb),
610 sk->sk_protocol,
611 skb->len); 608 skb->len);
612 } 609 }
613#endif 610#endif
@@ -2266,7 +2263,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2266 tp->af_specific->calc_md5_hash(md5_hash_location, 2263 tp->af_specific->calc_md5_hash(md5_hash_location,
2267 md5, 2264 md5,
2268 NULL, dst, req, 2265 NULL, dst, req,
2269 tcp_hdr(skb), sk->sk_protocol, 2266 tcp_hdr(skb),
2270 skb->len); 2267 skb->len);
2271 } 2268 }
2272#endif 2269#endif
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 63ed9d6830e7..3e358cbb1247 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * Implementation of the Transmission Control Protocol(TCP). 6 * Implementation of the Transmission Control Protocol(TCP).
7 * 7 *
8 * Version: $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 10 * Mark Evans, <evansmp@uhura.aston.ac.uk>
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 56fcda3694ba..355e6d62d483 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * The User Datagram Protocol (UDP). 6 * The User Datagram Protocol (UDP).
7 * 7 *
8 * Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Arnt Gulbrandsen, <agulbra@nvg.unit.no> 10 * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index 72ce26b6c4d3..4ad16b6d5138 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * UDPLITE An implementation of the UDP-Lite protocol (RFC 3828). 2 * UDPLITE An implementation of the UDP-Lite protocol (RFC 3828).
3 * 3 *
4 * Version: $Id: udplite.c,v 1.25 2006/10/19 07:22:36 gerrit Exp $
5 *
6 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk> 4 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk>
7 * 5 *
8 * Changes: 6 * Changes:
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 147588f4c7c0..9be6be3a7ff3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6,8 +6,6 @@
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 * 8 *
9 * $Id: addrconf.c,v 1.69 2001/10/31 21:55:54 davem Exp $
10 *
11 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 11 * as published by the Free Software Foundation; either version
@@ -231,6 +229,12 @@ static inline int addrconf_qdisc_ok(struct net_device *dev)
231 return (dev->qdisc != &noop_qdisc); 229 return (dev->qdisc != &noop_qdisc);
232} 230}
233 231
232/* Check if a route is valid prefix route */
233static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
234{
235 return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0);
236}
237
234static void addrconf_del_timer(struct inet6_ifaddr *ifp) 238static void addrconf_del_timer(struct inet6_ifaddr *ifp)
235{ 239{
236 if (del_timer(&ifp->timer)) 240 if (del_timer(&ifp->timer))
@@ -777,7 +781,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
777 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); 781 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
778 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); 782 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
779 783
780 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 784 if (rt && addrconf_is_prefix_route(rt)) {
781 if (onlink == 0) { 785 if (onlink == 0) {
782 ip6_del_rt(rt); 786 ip6_del_rt(rt);
783 rt = NULL; 787 rt = NULL;
@@ -958,7 +962,8 @@ static inline int ipv6_saddr_preferred(int type)
958 return 0; 962 return 0;
959} 963}
960 964
961static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, 965static int ipv6_get_saddr_eval(struct net *net,
966 struct ipv6_saddr_score *score,
962 struct ipv6_saddr_dst *dst, 967 struct ipv6_saddr_dst *dst,
963 int i) 968 int i)
964{ 969{
@@ -1037,7 +1042,8 @@ static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score,
1037 break; 1042 break;
1038 case IPV6_SADDR_RULE_LABEL: 1043 case IPV6_SADDR_RULE_LABEL:
1039 /* Rule 6: Prefer matching label */ 1044 /* Rule 6: Prefer matching label */
1040 ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, 1045 ret = ipv6_addr_label(net,
1046 &score->ifa->addr, score->addr_type,
1041 score->ifa->idev->dev->ifindex) == dst->label; 1047 score->ifa->idev->dev->ifindex) == dst->label;
1042 break; 1048 break;
1043#ifdef CONFIG_IPV6_PRIVACY 1049#ifdef CONFIG_IPV6_PRIVACY
@@ -1091,7 +1097,7 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
1091 dst.addr = daddr; 1097 dst.addr = daddr;
1092 dst.ifindex = dst_dev ? dst_dev->ifindex : 0; 1098 dst.ifindex = dst_dev ? dst_dev->ifindex : 0;
1093 dst.scope = __ipv6_addr_src_scope(dst_type); 1099 dst.scope = __ipv6_addr_src_scope(dst_type);
1094 dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); 1100 dst.label = ipv6_addr_label(net, daddr, dst_type, dst.ifindex);
1095 dst.prefs = prefs; 1101 dst.prefs = prefs;
1096 1102
1097 hiscore->rule = -1; 1103 hiscore->rule = -1;
@@ -1159,8 +1165,8 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
1159 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { 1165 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) {
1160 int minihiscore, miniscore; 1166 int minihiscore, miniscore;
1161 1167
1162 minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); 1168 minihiscore = ipv6_get_saddr_eval(net, hiscore, &dst, i);
1163 miniscore = ipv6_get_saddr_eval(score, &dst, i); 1169 miniscore = ipv6_get_saddr_eval(net, score, &dst, i);
1164 1170
1165 if (minihiscore > miniscore) { 1171 if (minihiscore > miniscore) {
1166 if (i == IPV6_SADDR_RULE_SCOPE && 1172 if (i == IPV6_SADDR_RULE_SCOPE &&
@@ -1788,7 +1794,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1788 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, 1794 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL,
1789 dev->ifindex, 1); 1795 dev->ifindex, 1);
1790 1796
1791 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 1797 if (rt && addrconf_is_prefix_route(rt)) {
1792 /* Autoconf prefix route */ 1798 /* Autoconf prefix route */
1793 if (valid_lft == 0) { 1799 if (valid_lft == 0) {
1794 ip6_del_rt(rt); 1800 ip6_del_rt(rt);
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 9bfa8846f262..08909039d87b 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -29,6 +29,9 @@
29 */ 29 */
30struct ip6addrlbl_entry 30struct ip6addrlbl_entry
31{ 31{
32#ifdef CONFIG_NET_NS
33 struct net *lbl_net;
34#endif
32 struct in6_addr prefix; 35 struct in6_addr prefix;
33 int prefixlen; 36 int prefixlen;
34 int ifindex; 37 int ifindex;
@@ -46,6 +49,16 @@ static struct ip6addrlbl_table
46 u32 seq; 49 u32 seq;
47} ip6addrlbl_table; 50} ip6addrlbl_table;
48 51
52static inline
53struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl)
54{
55#ifdef CONFIG_NET_NS
56 return lbl->lbl_net;
57#else
58 return &init_net;
59#endif
60}
61
49/* 62/*
50 * Default policy table (RFC3484 + extensions) 63 * Default policy table (RFC3484 + extensions)
51 * 64 *
@@ -65,7 +78,7 @@ static struct ip6addrlbl_table
65 78
66#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL 79#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL
67 80
68static const __initdata struct ip6addrlbl_init_table 81static const __net_initdata struct ip6addrlbl_init_table
69{ 82{
70 const struct in6_addr *prefix; 83 const struct in6_addr *prefix;
71 int prefixlen; 84 int prefixlen;
@@ -108,6 +121,9 @@ static const __initdata struct ip6addrlbl_init_table
108/* Object management */ 121/* Object management */
109static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) 122static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
110{ 123{
124#ifdef CONFIG_NET_NS
125 release_net(p->lbl_net);
126#endif
111 kfree(p); 127 kfree(p);
112} 128}
113 129
@@ -128,10 +144,13 @@ static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
128} 144}
129 145
130/* Find label */ 146/* Find label */
131static int __ip6addrlbl_match(struct ip6addrlbl_entry *p, 147static int __ip6addrlbl_match(struct net *net,
148 struct ip6addrlbl_entry *p,
132 const struct in6_addr *addr, 149 const struct in6_addr *addr,
133 int addrtype, int ifindex) 150 int addrtype, int ifindex)
134{ 151{
152 if (!net_eq(ip6addrlbl_net(p), net))
153 return 0;
135 if (p->ifindex && p->ifindex != ifindex) 154 if (p->ifindex && p->ifindex != ifindex)
136 return 0; 155 return 0;
137 if (p->addrtype && p->addrtype != addrtype) 156 if (p->addrtype && p->addrtype != addrtype)
@@ -141,19 +160,21 @@ static int __ip6addrlbl_match(struct ip6addrlbl_entry *p,
141 return 1; 160 return 1;
142} 161}
143 162
144static struct ip6addrlbl_entry *__ipv6_addr_label(const struct in6_addr *addr, 163static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net,
164 const struct in6_addr *addr,
145 int type, int ifindex) 165 int type, int ifindex)
146{ 166{
147 struct hlist_node *pos; 167 struct hlist_node *pos;
148 struct ip6addrlbl_entry *p; 168 struct ip6addrlbl_entry *p;
149 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 169 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
150 if (__ip6addrlbl_match(p, addr, type, ifindex)) 170 if (__ip6addrlbl_match(net, p, addr, type, ifindex))
151 return p; 171 return p;
152 } 172 }
153 return NULL; 173 return NULL;
154} 174}
155 175
156u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex) 176u32 ipv6_addr_label(struct net *net,
177 const struct in6_addr *addr, int type, int ifindex)
157{ 178{
158 u32 label; 179 u32 label;
159 struct ip6addrlbl_entry *p; 180 struct ip6addrlbl_entry *p;
@@ -161,7 +182,7 @@ u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
161 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK; 182 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK;
162 183
163 rcu_read_lock(); 184 rcu_read_lock();
164 p = __ipv6_addr_label(addr, type, ifindex); 185 p = __ipv6_addr_label(net, addr, type, ifindex);
165 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; 186 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT;
166 rcu_read_unlock(); 187 rcu_read_unlock();
167 188
@@ -174,7 +195,8 @@ u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
174} 195}
175 196
176/* allocate one entry */ 197/* allocate one entry */
177static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix, 198static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net,
199 const struct in6_addr *prefix,
178 int prefixlen, int ifindex, 200 int prefixlen, int ifindex,
179 u32 label) 201 u32 label)
180{ 202{
@@ -216,6 +238,9 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix,
216 newp->addrtype = addrtype; 238 newp->addrtype = addrtype;
217 newp->label = label; 239 newp->label = label;
218 INIT_HLIST_NODE(&newp->list); 240 INIT_HLIST_NODE(&newp->list);
241#ifdef CONFIG_NET_NS
242 newp->lbl_net = hold_net(net);
243#endif
219 atomic_set(&newp->refcnt, 1); 244 atomic_set(&newp->refcnt, 1);
220 return newp; 245 return newp;
221} 246}
@@ -237,6 +262,7 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
237 hlist_for_each_entry_safe(p, pos, n, 262 hlist_for_each_entry_safe(p, pos, n,
238 &ip6addrlbl_table.head, list) { 263 &ip6addrlbl_table.head, list) {
239 if (p->prefixlen == newp->prefixlen && 264 if (p->prefixlen == newp->prefixlen &&
265 net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) &&
240 p->ifindex == newp->ifindex && 266 p->ifindex == newp->ifindex &&
241 ipv6_addr_equal(&p->prefix, &newp->prefix)) { 267 ipv6_addr_equal(&p->prefix, &newp->prefix)) {
242 if (!replace) { 268 if (!replace) {
@@ -261,7 +287,8 @@ out:
261} 287}
262 288
263/* add a label */ 289/* add a label */
264static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen, 290static int ip6addrlbl_add(struct net *net,
291 const struct in6_addr *prefix, int prefixlen,
265 int ifindex, u32 label, int replace) 292 int ifindex, u32 label, int replace)
266{ 293{
267 struct ip6addrlbl_entry *newp; 294 struct ip6addrlbl_entry *newp;
@@ -274,7 +301,7 @@ static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
274 (unsigned int)label, 301 (unsigned int)label,
275 replace); 302 replace);
276 303
277 newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label); 304 newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label);
278 if (IS_ERR(newp)) 305 if (IS_ERR(newp))
279 return PTR_ERR(newp); 306 return PTR_ERR(newp);
280 spin_lock(&ip6addrlbl_table.lock); 307 spin_lock(&ip6addrlbl_table.lock);
@@ -286,7 +313,8 @@ static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
286} 313}
287 314
288/* remove a label */ 315/* remove a label */
289static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 316static int __ip6addrlbl_del(struct net *net,
317 const struct in6_addr *prefix, int prefixlen,
290 int ifindex) 318 int ifindex)
291{ 319{
292 struct ip6addrlbl_entry *p = NULL; 320 struct ip6addrlbl_entry *p = NULL;
@@ -300,6 +328,7 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
300 328
301 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { 329 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
302 if (p->prefixlen == prefixlen && 330 if (p->prefixlen == prefixlen &&
331 net_eq(ip6addrlbl_net(p), net) &&
303 p->ifindex == ifindex && 332 p->ifindex == ifindex &&
304 ipv6_addr_equal(&p->prefix, prefix)) { 333 ipv6_addr_equal(&p->prefix, prefix)) {
305 hlist_del_rcu(&p->list); 334 hlist_del_rcu(&p->list);
@@ -311,7 +340,8 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
311 return ret; 340 return ret;
312} 341}
313 342
314static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 343static int ip6addrlbl_del(struct net *net,
344 const struct in6_addr *prefix, int prefixlen,
315 int ifindex) 345 int ifindex)
316{ 346{
317 struct in6_addr prefix_buf; 347 struct in6_addr prefix_buf;
@@ -324,13 +354,13 @@ static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
324 354
325 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); 355 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen);
326 spin_lock(&ip6addrlbl_table.lock); 356 spin_lock(&ip6addrlbl_table.lock);
327 ret = __ip6addrlbl_del(&prefix_buf, prefixlen, ifindex); 357 ret = __ip6addrlbl_del(net, &prefix_buf, prefixlen, ifindex);
328 spin_unlock(&ip6addrlbl_table.lock); 358 spin_unlock(&ip6addrlbl_table.lock);
329 return ret; 359 return ret;
330} 360}
331 361
332/* add default label */ 362/* add default label */
333static __init int ip6addrlbl_init(void) 363static int __net_init ip6addrlbl_net_init(struct net *net)
334{ 364{
335 int err = 0; 365 int err = 0;
336 int i; 366 int i;
@@ -338,7 +368,8 @@ static __init int ip6addrlbl_init(void)
338 ADDRLABEL(KERN_DEBUG "%s()\n", __func__); 368 ADDRLABEL(KERN_DEBUG "%s()\n", __func__);
339 369
340 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { 370 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
341 int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix, 371 int ret = ip6addrlbl_add(net,
372 ip6addrlbl_init_table[i].prefix,
342 ip6addrlbl_init_table[i].prefixlen, 373 ip6addrlbl_init_table[i].prefixlen,
343 0, 374 0,
344 ip6addrlbl_init_table[i].label, 0); 375 ip6addrlbl_init_table[i].label, 0);
@@ -349,11 +380,32 @@ static __init int ip6addrlbl_init(void)
349 return err; 380 return err;
350} 381}
351 382
383static void __net_exit ip6addrlbl_net_exit(struct net *net)
384{
385 struct ip6addrlbl_entry *p = NULL;
386 struct hlist_node *pos, *n;
387
388 /* Remove all labels belonging to the exiting net */
389 spin_lock(&ip6addrlbl_table.lock);
390 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
391 if (net_eq(ip6addrlbl_net(p), net)) {
392 hlist_del_rcu(&p->list);
393 ip6addrlbl_put(p);
394 }
395 }
396 spin_unlock(&ip6addrlbl_table.lock);
397}
398
399static struct pernet_operations ipv6_addr_label_ops = {
400 .init = ip6addrlbl_net_init,
401 .exit = ip6addrlbl_net_exit,
402};
403
352int __init ipv6_addr_label_init(void) 404int __init ipv6_addr_label_init(void)
353{ 405{
354 spin_lock_init(&ip6addrlbl_table.lock); 406 spin_lock_init(&ip6addrlbl_table.lock);
355 407
356 return ip6addrlbl_init(); 408 return register_pernet_subsys(&ipv6_addr_label_ops);
357} 409}
358 410
359static const struct nla_policy ifal_policy[IFAL_MAX+1] = { 411static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
@@ -371,9 +423,6 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
371 u32 label; 423 u32 label;
372 int err = 0; 424 int err = 0;
373 425
374 if (net != &init_net)
375 return 0;
376
377 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 426 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
378 if (err < 0) 427 if (err < 0)
379 return err; 428 return err;
@@ -385,7 +434,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
385 return -EINVAL; 434 return -EINVAL;
386 435
387 if (ifal->ifal_index && 436 if (ifal->ifal_index &&
388 !__dev_get_by_index(&init_net, ifal->ifal_index)) 437 !__dev_get_by_index(net, ifal->ifal_index))
389 return -EINVAL; 438 return -EINVAL;
390 439
391 if (!tb[IFAL_ADDRESS]) 440 if (!tb[IFAL_ADDRESS])
@@ -403,12 +452,12 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
403 452
404 switch(nlh->nlmsg_type) { 453 switch(nlh->nlmsg_type) {
405 case RTM_NEWADDRLABEL: 454 case RTM_NEWADDRLABEL:
406 err = ip6addrlbl_add(pfx, ifal->ifal_prefixlen, 455 err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen,
407 ifal->ifal_index, label, 456 ifal->ifal_index, label,
408 nlh->nlmsg_flags & NLM_F_REPLACE); 457 nlh->nlmsg_flags & NLM_F_REPLACE);
409 break; 458 break;
410 case RTM_DELADDRLABEL: 459 case RTM_DELADDRLABEL:
411 err = ip6addrlbl_del(pfx, ifal->ifal_prefixlen, 460 err = ip6addrlbl_del(net, pfx, ifal->ifal_prefixlen,
412 ifal->ifal_index); 461 ifal->ifal_index);
413 break; 462 break;
414 default: 463 default:
@@ -458,12 +507,10 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
458 int idx = 0, s_idx = cb->args[0]; 507 int idx = 0, s_idx = cb->args[0];
459 int err; 508 int err;
460 509
461 if (net != &init_net)
462 return 0;
463
464 rcu_read_lock(); 510 rcu_read_lock();
465 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 511 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
466 if (idx >= s_idx) { 512 if (idx >= s_idx &&
513 net_eq(ip6addrlbl_net(p), net)) {
467 if ((err = ip6addrlbl_fill(skb, p, 514 if ((err = ip6addrlbl_fill(skb, p,
468 ip6addrlbl_table.seq, 515 ip6addrlbl_table.seq,
469 NETLINK_CB(cb->skb).pid, 516 NETLINK_CB(cb->skb).pid,
@@ -499,9 +546,6 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
499 struct ip6addrlbl_entry *p; 546 struct ip6addrlbl_entry *p;
500 struct sk_buff *skb; 547 struct sk_buff *skb;
501 548
502 if (net != &init_net)
503 return 0;
504
505 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 549 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
506 if (err < 0) 550 if (err < 0)
507 return err; 551 return err;
@@ -513,7 +557,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
513 return -EINVAL; 557 return -EINVAL;
514 558
515 if (ifal->ifal_index && 559 if (ifal->ifal_index &&
516 !__dev_get_by_index(&init_net, ifal->ifal_index)) 560 !__dev_get_by_index(net, ifal->ifal_index))
517 return -EINVAL; 561 return -EINVAL;
518 562
519 if (!tb[IFAL_ADDRESS]) 563 if (!tb[IFAL_ADDRESS])
@@ -524,7 +568,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
524 return -EINVAL; 568 return -EINVAL;
525 569
526 rcu_read_lock(); 570 rcu_read_lock();
527 p = __ipv6_addr_label(addr, ipv6_addr_type(addr), ifal->ifal_index); 571 p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index);
528 if (p && ip6addrlbl_hold(p)) 572 if (p && ip6addrlbl_hold(p))
529 p = NULL; 573 p = NULL;
530 lseq = ip6addrlbl_table.seq; 574 lseq = ip6addrlbl_table.seq;
@@ -552,7 +596,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
552 goto out; 596 goto out;
553 } 597 }
554 598
555 err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); 599 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
556out: 600out:
557 return err; 601 return err;
558} 602}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e84b3fd17fb4..350457c761e6 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -7,8 +7,6 @@
7 * 7 *
8 * Adapted from linux/net/ipv4/af_inet.c 8 * Adapted from linux/net/ipv4/af_inet.c
9 * 9 *
10 * $Id: af_inet6.c,v 1.66 2002/02/01 22:01:04 davem Exp $
11 *
12 * Fixes: 10 * Fixes:
13 * piggy, Karl Knutson : Socket protocol table 11 * piggy, Karl Knutson : Socket protocol table
14 * Hideaki YOSHIFUJI : sin6_scope_id support 12 * Hideaki YOSHIFUJI : sin6_scope_id support
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 0f0f94a40335..f7b535dec860 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: datagram.c,v 1.24 2002/02/01 22:01:04 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 3cd1c993d52b..602ea826f0a5 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -7,8 +7,6 @@
7 * Andi Kleen <ak@muc.de> 7 * Andi Kleen <ak@muc.de>
8 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 8 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
9 * 9 *
10 * $Id: exthdrs.c,v 1.13 2001/06/19 15:58:56 davem Exp $
11 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 12 * as published by the Free Software Foundation; either version
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index d42dd16d3487..399d41f65437 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: icmp.c,v 1.38 2002/02/08 03:57:19 davem Exp $
9 *
10 * Based on net/ipv4/icmp.c 8 * Based on net/ipv4/icmp.c
11 * 9 *
12 * RFC 1885 10 * RFC 1885
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 1ee4fa17c129..4de2b9efcacb 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: ip6_fib.c,v 1.25 2001/10/31 21:55:55 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 4e5c8615832c..f77a6011c302 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -6,8 +6,6 @@
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Ian P. Morris <I.P.Morris@soton.ac.uk> 7 * Ian P. Morris <I.P.Morris@soton.ac.uk>
8 * 8 *
9 * $Id: ip6_input.c,v 1.19 2000/12/13 18:31:50 davem Exp $
10 *
11 * Based in linux/net/ipv4/ip_input.c 9 * Based in linux/net/ipv4/ip_input.c
12 * 10 *
13 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 48cdce9c696c..40a2813a63d1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: ip6_output.c,v 1.34 2002/02/01 22:01:04 davem Exp $
9 *
10 * Based on linux/net/ipv4/ip_output.c 8 * Based on linux/net/ipv4/ip_output.c
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 2bda3ba100b1..17c7b098cdb0 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -6,8 +6,6 @@
6 * Ville Nuorvala <vnuorval@tcs.hut.fi> 6 * Ville Nuorvala <vnuorval@tcs.hut.fi>
7 * Yasuyuki Kozakai <kozakai@linux-ipv6.org> 7 * Yasuyuki Kozakai <kozakai@linux-ipv6.org>
8 * 8 *
9 * $Id$
10 *
11 * Based on: 9 * Based on:
12 * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c 10 * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c
13 * 11 *
@@ -711,7 +709,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
711 } 709 }
712 710
713 if (!ip6_tnl_rcv_ctl(t)) { 711 if (!ip6_tnl_rcv_ctl(t)) {
714 t->stat.rx_dropped++; 712 t->dev->stats.rx_dropped++;
715 read_unlock(&ip6_tnl_lock); 713 read_unlock(&ip6_tnl_lock);
716 goto discard; 714 goto discard;
717 } 715 }
@@ -728,8 +726,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
728 726
729 dscp_ecn_decapsulate(t, ipv6h, skb); 727 dscp_ecn_decapsulate(t, ipv6h, skb);
730 728
731 t->stat.rx_packets++; 729 t->dev->stats.rx_packets++;
732 t->stat.rx_bytes += skb->len; 730 t->dev->stats.rx_bytes += skb->len;
733 netif_rx(skb); 731 netif_rx(skb);
734 read_unlock(&ip6_tnl_lock); 732 read_unlock(&ip6_tnl_lock);
735 return 0; 733 return 0;
@@ -849,7 +847,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
849 __u32 *pmtu) 847 __u32 *pmtu)
850{ 848{
851 struct ip6_tnl *t = netdev_priv(dev); 849 struct ip6_tnl *t = netdev_priv(dev);
852 struct net_device_stats *stats = &t->stat; 850 struct net_device_stats *stats = &t->dev->stats;
853 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 851 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
854 struct ipv6_tel_txoption opt; 852 struct ipv6_tel_txoption opt;
855 struct dst_entry *dst; 853 struct dst_entry *dst;
@@ -1043,11 +1041,11 @@ static int
1043ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) 1041ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1044{ 1042{
1045 struct ip6_tnl *t = netdev_priv(dev); 1043 struct ip6_tnl *t = netdev_priv(dev);
1046 struct net_device_stats *stats = &t->stat; 1044 struct net_device_stats *stats = &t->dev->stats;
1047 int ret; 1045 int ret;
1048 1046
1049 if (t->recursion++) { 1047 if (t->recursion++) {
1050 t->stat.collisions++; 1048 stats->collisions++;
1051 goto tx_err; 1049 goto tx_err;
1052 } 1050 }
1053 1051
@@ -1289,19 +1287,6 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1289} 1287}
1290 1288
1291/** 1289/**
1292 * ip6_tnl_get_stats - return the stats for tunnel device
1293 * @dev: virtual device associated with tunnel
1294 *
1295 * Return: stats for device
1296 **/
1297
1298static struct net_device_stats *
1299ip6_tnl_get_stats(struct net_device *dev)
1300{
1301 return &(((struct ip6_tnl *)netdev_priv(dev))->stat);
1302}
1303
1304/**
1305 * ip6_tnl_change_mtu - change mtu manually for tunnel device 1290 * ip6_tnl_change_mtu - change mtu manually for tunnel device
1306 * @dev: virtual device associated with tunnel 1291 * @dev: virtual device associated with tunnel
1307 * @new_mtu: the new mtu 1292 * @new_mtu: the new mtu
@@ -1334,7 +1319,6 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
1334 dev->uninit = ip6_tnl_dev_uninit; 1319 dev->uninit = ip6_tnl_dev_uninit;
1335 dev->destructor = free_netdev; 1320 dev->destructor = free_netdev;
1336 dev->hard_start_xmit = ip6_tnl_xmit; 1321 dev->hard_start_xmit = ip6_tnl_xmit;
1337 dev->get_stats = ip6_tnl_get_stats;
1338 dev->do_ioctl = ip6_tnl_ioctl; 1322 dev->do_ioctl = ip6_tnl_ioctl;
1339 dev->change_mtu = ip6_tnl_change_mtu; 1323 dev->change_mtu = ip6_tnl_change_mtu;
1340 1324
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 14796181e8b5..90e763073dc5 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -388,8 +388,8 @@ static int pim6_rcv(struct sk_buff *skb)
388 skb->ip_summed = 0; 388 skb->ip_summed = 0;
389 skb->pkt_type = PACKET_HOST; 389 skb->pkt_type = PACKET_HOST;
390 dst_release(skb->dst); 390 dst_release(skb->dst);
391 ((struct net_device_stats *)netdev_priv(reg_dev))->rx_bytes += skb->len; 391 reg_dev->stats.rx_bytes += skb->len;
392 ((struct net_device_stats *)netdev_priv(reg_dev))->rx_packets++; 392 reg_dev->stats.rx_packets++;
393 skb->dst = NULL; 393 skb->dst = NULL;
394 nf_reset(skb); 394 nf_reset(skb);
395 netif_rx(skb); 395 netif_rx(skb);
@@ -409,26 +409,20 @@ static struct inet6_protocol pim6_protocol = {
409static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) 409static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
410{ 410{
411 read_lock(&mrt_lock); 411 read_lock(&mrt_lock);
412 ((struct net_device_stats *)netdev_priv(dev))->tx_bytes += skb->len; 412 dev->stats.tx_bytes += skb->len;
413 ((struct net_device_stats *)netdev_priv(dev))->tx_packets++; 413 dev->stats.tx_packets++;
414 ip6mr_cache_report(skb, reg_vif_num, MRT6MSG_WHOLEPKT); 414 ip6mr_cache_report(skb, reg_vif_num, MRT6MSG_WHOLEPKT);
415 read_unlock(&mrt_lock); 415 read_unlock(&mrt_lock);
416 kfree_skb(skb); 416 kfree_skb(skb);
417 return 0; 417 return 0;
418} 418}
419 419
420static struct net_device_stats *reg_vif_get_stats(struct net_device *dev)
421{
422 return (struct net_device_stats *)netdev_priv(dev);
423}
424
425static void reg_vif_setup(struct net_device *dev) 420static void reg_vif_setup(struct net_device *dev)
426{ 421{
427 dev->type = ARPHRD_PIMREG; 422 dev->type = ARPHRD_PIMREG;
428 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; 423 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8;
429 dev->flags = IFF_NOARP; 424 dev->flags = IFF_NOARP;
430 dev->hard_start_xmit = reg_vif_xmit; 425 dev->hard_start_xmit = reg_vif_xmit;
431 dev->get_stats = reg_vif_get_stats;
432 dev->destructor = free_netdev; 426 dev->destructor = free_netdev;
433} 427}
434 428
@@ -436,9 +430,7 @@ static struct net_device *ip6mr_reg_vif(void)
436{ 430{
437 struct net_device *dev; 431 struct net_device *dev;
438 432
439 dev = alloc_netdev(sizeof(struct net_device_stats), "pim6reg", 433 dev = alloc_netdev(0, "pim6reg", reg_vif_setup);
440 reg_vif_setup);
441
442 if (dev == NULL) 434 if (dev == NULL)
443 return NULL; 435 return NULL;
444 436
@@ -1248,7 +1240,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
1248 1240
1249#endif 1241#endif
1250 /* 1242 /*
1251 * Spurious command, or MRT_VERSION which you cannot 1243 * Spurious command, or MRT6_VERSION which you cannot
1252 * set. 1244 * set.
1253 */ 1245 */
1254 default: 1246 default:
@@ -1377,8 +1369,8 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi)
1377 if (vif->flags & MIFF_REGISTER) { 1369 if (vif->flags & MIFF_REGISTER) {
1378 vif->pkt_out++; 1370 vif->pkt_out++;
1379 vif->bytes_out += skb->len; 1371 vif->bytes_out += skb->len;
1380 ((struct net_device_stats *)netdev_priv(vif->dev))->tx_bytes += skb->len; 1372 vif->dev->stats.tx_bytes += skb->len;
1381 ((struct net_device_stats *)netdev_priv(vif->dev))->tx_packets++; 1373 vif->dev->stats.tx_packets++;
1382 ip6mr_cache_report(skb, vifi, MRT6MSG_WHOLEPKT); 1374 ip6mr_cache_report(skb, vifi, MRT6MSG_WHOLEPKT);
1383 kfree_skb(skb); 1375 kfree_skb(skb);
1384 return 0; 1376 return 0;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index c042ce19bd14..a9988841172a 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -7,8 +7,6 @@
7 * 7 *
8 * Based on linux/net/ipv4/ip_sockglue.c 8 * Based on linux/net/ipv4/ip_sockglue.c
9 * 9 *
10 * $Id: ipv6_sockglue.c,v 1.41 2002/02/01 22:01:04 davem Exp $
11 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 12 * as published by the Free Software Foundation; either version
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index fd632dd7f98d..bd2fe4cfafa7 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: mcast.c,v 1.40 2002/02/08 03:57:19 davem Exp $
9 *
10 * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c 8 * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
@@ -164,7 +162,6 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
164 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ 162 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \
165 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) 163 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp))))
166 164
167#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
168#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) 165#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
169 166
170#define IPV6_MLD_MAX_MSF 64 167#define IPV6_MLD_MAX_MSF 64
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 6cae5475737e..689dec899c57 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -208,5 +208,17 @@ config IP6_NF_RAW
208 If you want to compile it as a module, say M here and read 208 If you want to compile it as a module, say M here and read
209 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 209 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
210 210
211# security table for MAC policy
212config IP6_NF_SECURITY
213 tristate "Security table"
214 depends on IP6_NF_IPTABLES
215 depends on SECURITY
216 default m if NETFILTER_ADVANCED=n
217 help
218 This option adds a `security' table to iptables, for use
219 with Mandatory Access Control (MAC) policy.
220
221 If unsure, say N.
222
211endmenu 223endmenu
212 224
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index fbf2c14ed887..3f17c948eefb 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
8obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o 8obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
9obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o 9obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
10obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o 10obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
11obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
11 12
12# objects for l3 independent conntrack 13# objects for l3 independent conntrack
13nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o 14nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 2eff3ae8977d..1b8815f6153d 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -159,7 +159,6 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
159 case IPQ_COPY_META: 159 case IPQ_COPY_META:
160 case IPQ_COPY_NONE: 160 case IPQ_COPY_NONE:
161 size = NLMSG_SPACE(sizeof(*pmsg)); 161 size = NLMSG_SPACE(sizeof(*pmsg));
162 data_len = 0;
163 break; 162 break;
164 163
165 case IPQ_COPY_PACKET: 164 case IPQ_COPY_PACKET:
@@ -226,8 +225,6 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
226 return skb; 225 return skb;
227 226
228nlmsg_failure: 227nlmsg_failure:
229 if (skb)
230 kfree_skb(skb);
231 *errp = -EINVAL; 228 *errp = -EINVAL;
232 printk(KERN_ERR "ip6_queue: error creating packet message\n"); 229 printk(KERN_ERR "ip6_queue: error creating packet message\n");
233 return NULL; 230 return NULL;
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
new file mode 100644
index 000000000000..063a3d9c3c67
--- /dev/null
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -0,0 +1,172 @@
1/*
2 * "security" table for IPv6
3 *
4 * This is for use by Mandatory Access Control (MAC) security models,
5 * which need to be able to manage security policy in separate context
6 * to DAC.
7 *
8 * Based on iptable_mangle.c
9 *
10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
11 * Copyright (C) 2000-2004 Netfilter Core Team <coreteam <at> netfilter.org>
12 * Copyright (C) 2008 Red Hat, Inc., James Morris <jmorris <at> redhat.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/module.h>
19#include <linux/netfilter_ipv6/ip6_tables.h>
20
21MODULE_LICENSE("GPL");
22MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>");
23MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
24
25#define SECURITY_VALID_HOOKS (1 << NF_INET_LOCAL_IN) | \
26 (1 << NF_INET_FORWARD) | \
27 (1 << NF_INET_LOCAL_OUT)
28
29static struct
30{
31 struct ip6t_replace repl;
32 struct ip6t_standard entries[3];
33 struct ip6t_error term;
34} initial_table __initdata = {
35 .repl = {
36 .name = "security",
37 .valid_hooks = SECURITY_VALID_HOOKS,
38 .num_entries = 4,
39 .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
40 .hook_entry = {
41 [NF_INET_LOCAL_IN] = 0,
42 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
43 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
44 },
45 .underflow = {
46 [NF_INET_LOCAL_IN] = 0,
47 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
48 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
49 },
50 },
51 .entries = {
52 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
53 IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
54 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
55 },
56 .term = IP6T_ERROR_INIT, /* ERROR */
57};
58
59static struct xt_table security_table = {
60 .name = "security",
61 .valid_hooks = SECURITY_VALID_HOOKS,
62 .lock = __RW_LOCK_UNLOCKED(security_table.lock),
63 .me = THIS_MODULE,
64 .af = AF_INET6,
65};
66
67static unsigned int
68ip6t_local_in_hook(unsigned int hook,
69 struct sk_buff *skb,
70 const struct net_device *in,
71 const struct net_device *out,
72 int (*okfn)(struct sk_buff *))
73{
74 return ip6t_do_table(skb, hook, in, out,
75 init_net.ipv6.ip6table_security);
76}
77
78static unsigned int
79ip6t_forward_hook(unsigned int hook,
80 struct sk_buff *skb,
81 const struct net_device *in,
82 const struct net_device *out,
83 int (*okfn)(struct sk_buff *))
84{
85 return ip6t_do_table(skb, hook, in, out,
86 init_net.ipv6.ip6table_security);
87}
88
89static unsigned int
90ip6t_local_out_hook(unsigned int hook,
91 struct sk_buff *skb,
92 const struct net_device *in,
93 const struct net_device *out,
94 int (*okfn)(struct sk_buff *))
95{
96 /* TBD: handle short packets via raw socket */
97 return ip6t_do_table(skb, hook, in, out,
98 init_net.ipv6.ip6table_security);
99}
100
101static struct nf_hook_ops ip6t_ops[] __read_mostly = {
102 {
103 .hook = ip6t_local_in_hook,
104 .owner = THIS_MODULE,
105 .pf = PF_INET6,
106 .hooknum = NF_INET_LOCAL_IN,
107 .priority = NF_IP6_PRI_SECURITY,
108 },
109 {
110 .hook = ip6t_forward_hook,
111 .owner = THIS_MODULE,
112 .pf = PF_INET6,
113 .hooknum = NF_INET_FORWARD,
114 .priority = NF_IP6_PRI_SECURITY,
115 },
116 {
117 .hook = ip6t_local_out_hook,
118 .owner = THIS_MODULE,
119 .pf = PF_INET6,
120 .hooknum = NF_INET_LOCAL_OUT,
121 .priority = NF_IP6_PRI_SECURITY,
122 },
123};
124
125static int __net_init ip6table_security_net_init(struct net *net)
126{
127 net->ipv6.ip6table_security =
128 ip6t_register_table(net, &security_table, &initial_table.repl);
129
130 if (IS_ERR(net->ipv6.ip6table_security))
131 return PTR_ERR(net->ipv6.ip6table_security);
132
133 return 0;
134}
135
136static void __net_exit ip6table_security_net_exit(struct net *net)
137{
138 ip6t_unregister_table(net->ipv6.ip6table_security);
139}
140
141static struct pernet_operations ip6table_security_net_ops = {
142 .init = ip6table_security_net_init,
143 .exit = ip6table_security_net_exit,
144};
145
146static int __init ip6table_security_init(void)
147{
148 int ret;
149
150 ret = register_pernet_subsys(&ip6table_security_net_ops);
151 if (ret < 0)
152 return ret;
153
154 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
155 if (ret < 0)
156 goto cleanup_table;
157
158 return ret;
159
160cleanup_table:
161 unregister_pernet_subsys(&ip6table_security_net_ops);
162 return ret;
163}
164
165static void __exit ip6table_security_fini(void)
166{
167 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
168 unregister_pernet_subsys(&ip6table_security_net_ops);
169}
170
171module_init(ip6table_security_init);
172module_exit(ip6table_security_fini);
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index ee713b03e9ec..14d47d833545 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -89,9 +89,8 @@ static int icmpv6_packet(struct nf_conn *ct,
89 means this will only run once even if count hits zero twice 89 means this will only run once even if count hits zero twice
90 (theoretically possible with SMP) */ 90 (theoretically possible with SMP) */
91 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { 91 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
92 if (atomic_dec_and_test(&ct->proto.icmp.count) 92 if (atomic_dec_and_test(&ct->proto.icmp.count))
93 && del_timer(&ct->timeout)) 93 nf_ct_kill_acct(ct, ctinfo, skb);
94 ct->timeout.function((unsigned long)ct);
95 } else { 94 } else {
96 atomic_inc(&ct->proto.icmp.count); 95 atomic_inc(&ct->proto.icmp.count);
97 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 96 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index df0736a4cafa..cbc7e514d3ec 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -7,8 +7,6 @@
7 * PROC file system. This is very similar to the IPv4 version, 7 * PROC file system. This is very similar to the IPv4 version,
8 * except it reports the sockets in the INET6 address family. 8 * except it reports the sockets in the INET6 address family.
9 * 9 *
10 * Version: $Id: proc.c,v 1.17 2002/02/01 22:01:04 davem Exp $
11 *
12 * Authors: David S. Miller (davem@caip.rutgers.edu) 10 * Authors: David S. Miller (davem@caip.rutgers.edu)
13 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> 11 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
14 * 12 *
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index f929f47b925e..9ab789159913 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * PF_INET6 protocol dispatch tables. 6 * PF_INET6 protocol dispatch tables.
7 * 7 *
8 * Version: $Id: protocol.c,v 1.10 2001/05/18 02:25:49 davem Exp $
9 *
10 * Authors: Pedro Roque <roque@di.fc.ul.pt> 8 * Authors: Pedro Roque <roque@di.fc.ul.pt>
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 3aee12310d94..70a57e45bf0e 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -7,8 +7,6 @@
7 * 7 *
8 * Adapted from linux/net/ipv4/raw.c 8 * Adapted from linux/net/ipv4/raw.c
9 * 9 *
10 * $Id: raw.c,v 1.51 2002/02/01 22:01:04 davem Exp $
11 *
12 * Fixes: 10 * Fixes:
13 * Hideaki YOSHIFUJI : sin6_scope_id support 11 * Hideaki YOSHIFUJI : sin6_scope_id support
14 * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance) 12 * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 798cabc7535b..13509f906d89 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: reassembly.c,v 1.26 2001/03/07 22:00:57 davem Exp $
9 *
10 * Based on: net/ipv4/ip_fragment.c 8 * Based on: net/ipv4/ip_fragment.c
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
@@ -632,7 +630,7 @@ static struct inet6_protocol frag_protocol =
632}; 630};
633 631
634#ifdef CONFIG_SYSCTL 632#ifdef CONFIG_SYSCTL
635static struct ctl_table ip6_frags_ctl_table[] = { 633static struct ctl_table ip6_frags_ns_ctl_table[] = {
636 { 634 {
637 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH, 635 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH,
638 .procname = "ip6frag_high_thresh", 636 .procname = "ip6frag_high_thresh",
@@ -658,6 +656,10 @@ static struct ctl_table ip6_frags_ctl_table[] = {
658 .proc_handler = &proc_dointvec_jiffies, 656 .proc_handler = &proc_dointvec_jiffies,
659 .strategy = &sysctl_jiffies, 657 .strategy = &sysctl_jiffies,
660 }, 658 },
659 { }
660};
661
662static struct ctl_table ip6_frags_ctl_table[] = {
661 { 663 {
662 .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL, 664 .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL,
663 .procname = "ip6frag_secret_interval", 665 .procname = "ip6frag_secret_interval",
@@ -670,21 +672,20 @@ static struct ctl_table ip6_frags_ctl_table[] = {
670 { } 672 { }
671}; 673};
672 674
673static int ip6_frags_sysctl_register(struct net *net) 675static int ip6_frags_ns_sysctl_register(struct net *net)
674{ 676{
675 struct ctl_table *table; 677 struct ctl_table *table;
676 struct ctl_table_header *hdr; 678 struct ctl_table_header *hdr;
677 679
678 table = ip6_frags_ctl_table; 680 table = ip6_frags_ns_ctl_table;
679 if (net != &init_net) { 681 if (net != &init_net) {
680 table = kmemdup(table, sizeof(ip6_frags_ctl_table), GFP_KERNEL); 682 table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL);
681 if (table == NULL) 683 if (table == NULL)
682 goto err_alloc; 684 goto err_alloc;
683 685
684 table[0].data = &net->ipv6.frags.high_thresh; 686 table[0].data = &net->ipv6.frags.high_thresh;
685 table[1].data = &net->ipv6.frags.low_thresh; 687 table[1].data = &net->ipv6.frags.low_thresh;
686 table[2].data = &net->ipv6.frags.timeout; 688 table[2].data = &net->ipv6.frags.timeout;
687 table[3].mode &= ~0222;
688 } 689 }
689 690
690 hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table); 691 hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table);
@@ -701,7 +702,7 @@ err_alloc:
701 return -ENOMEM; 702 return -ENOMEM;
702} 703}
703 704
704static void ip6_frags_sysctl_unregister(struct net *net) 705static void ip6_frags_ns_sysctl_unregister(struct net *net)
705{ 706{
706 struct ctl_table *table; 707 struct ctl_table *table;
707 708
@@ -709,13 +710,36 @@ static void ip6_frags_sysctl_unregister(struct net *net)
709 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr); 710 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr);
710 kfree(table); 711 kfree(table);
711} 712}
713
714static struct ctl_table_header *ip6_ctl_header;
715
716static int ip6_frags_sysctl_register(void)
717{
718 ip6_ctl_header = register_net_sysctl_rotable(net_ipv6_ctl_path,
719 ip6_frags_ctl_table);
720 return ip6_ctl_header == NULL ? -ENOMEM : 0;
721}
722
723static void ip6_frags_sysctl_unregister(void)
724{
725 unregister_net_sysctl_table(ip6_ctl_header);
726}
712#else 727#else
713static inline int ip6_frags_sysctl_register(struct net *net) 728static inline int ip6_frags_ns_sysctl_register(struct net *net)
714{ 729{
715 return 0; 730 return 0;
716} 731}
717 732
718static inline void ip6_frags_sysctl_unregister(struct net *net) 733static inline void ip6_frags_ns_sysctl_unregister(struct net *net)
734{
735}
736
737static inline int ip6_frags_sysctl_register(void)
738{
739 return 0;
740}
741
742static inline void ip6_frags_sysctl_unregister(void)
719{ 743{
720} 744}
721#endif 745#endif
@@ -728,12 +752,12 @@ static int ipv6_frags_init_net(struct net *net)
728 752
729 inet_frags_init_net(&net->ipv6.frags); 753 inet_frags_init_net(&net->ipv6.frags);
730 754
731 return ip6_frags_sysctl_register(net); 755 return ip6_frags_ns_sysctl_register(net);
732} 756}
733 757
734static void ipv6_frags_exit_net(struct net *net) 758static void ipv6_frags_exit_net(struct net *net)
735{ 759{
736 ip6_frags_sysctl_unregister(net); 760 ip6_frags_ns_sysctl_unregister(net);
737 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags); 761 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
738} 762}
739 763
@@ -750,7 +774,13 @@ int __init ipv6_frag_init(void)
750 if (ret) 774 if (ret)
751 goto out; 775 goto out;
752 776
753 register_pernet_subsys(&ip6_frags_ops); 777 ret = ip6_frags_sysctl_register();
778 if (ret)
779 goto err_sysctl;
780
781 ret = register_pernet_subsys(&ip6_frags_ops);
782 if (ret)
783 goto err_pernet;
754 784
755 ip6_frags.hashfn = ip6_hashfn; 785 ip6_frags.hashfn = ip6_hashfn;
756 ip6_frags.constructor = ip6_frag_init; 786 ip6_frags.constructor = ip6_frag_init;
@@ -763,11 +793,18 @@ int __init ipv6_frag_init(void)
763 inet_frags_init(&ip6_frags); 793 inet_frags_init(&ip6_frags);
764out: 794out:
765 return ret; 795 return ret;
796
797err_pernet:
798 ip6_frags_sysctl_unregister();
799err_sysctl:
800 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
801 goto out;
766} 802}
767 803
768void ipv6_frag_exit(void) 804void ipv6_frag_exit(void)
769{ 805{
770 inet_frags_fini(&ip6_frags); 806 inet_frags_fini(&ip6_frags);
807 ip6_frags_sysctl_unregister();
771 unregister_pernet_subsys(&ip6_frags_ops); 808 unregister_pernet_subsys(&ip6_frags_ops);
772 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT); 809 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
773} 810}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d1f3e19b06c7..efe036aa3dd1 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: route.c,v 1.56 2001/10/31 21:55:55 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 3de6ffdaedf2..b0c5080420a8 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -6,8 +6,6 @@
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 * 8 *
9 * $Id: sit.c,v 1.53 2001/09/25 05:09:53 davem Exp $
10 *
11 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 11 * as published by the Free Software Foundation; either version
@@ -491,13 +489,13 @@ static int ipip6_rcv(struct sk_buff *skb)
491 489
492 if ((tunnel->dev->priv_flags & IFF_ISATAP) && 490 if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
493 !isatap_chksrc(skb, iph, tunnel)) { 491 !isatap_chksrc(skb, iph, tunnel)) {
494 tunnel->stat.rx_errors++; 492 tunnel->dev->stats.rx_errors++;
495 read_unlock(&ipip6_lock); 493 read_unlock(&ipip6_lock);
496 kfree_skb(skb); 494 kfree_skb(skb);
497 return 0; 495 return 0;
498 } 496 }
499 tunnel->stat.rx_packets++; 497 tunnel->dev->stats.rx_packets++;
500 tunnel->stat.rx_bytes += skb->len; 498 tunnel->dev->stats.rx_bytes += skb->len;
501 skb->dev = tunnel->dev; 499 skb->dev = tunnel->dev;
502 dst_release(skb->dst); 500 dst_release(skb->dst);
503 skb->dst = NULL; 501 skb->dst = NULL;
@@ -537,7 +535,7 @@ static inline __be32 try_6to4(struct in6_addr *v6dst)
537static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 535static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
538{ 536{
539 struct ip_tunnel *tunnel = netdev_priv(dev); 537 struct ip_tunnel *tunnel = netdev_priv(dev);
540 struct net_device_stats *stats = &tunnel->stat; 538 struct net_device_stats *stats = &tunnel->dev->stats;
541 struct iphdr *tiph = &tunnel->parms.iph; 539 struct iphdr *tiph = &tunnel->parms.iph;
542 struct ipv6hdr *iph6 = ipv6_hdr(skb); 540 struct ipv6hdr *iph6 = ipv6_hdr(skb);
543 u8 tos = tunnel->parms.iph.tos; 541 u8 tos = tunnel->parms.iph.tos;
@@ -551,7 +549,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
551 int addr_type; 549 int addr_type;
552 550
553 if (tunnel->recursion++) { 551 if (tunnel->recursion++) {
554 tunnel->stat.collisions++; 552 stats->collisions++;
555 goto tx_error; 553 goto tx_error;
556 } 554 }
557 555
@@ -618,20 +616,20 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
618 .oif = tunnel->parms.link, 616 .oif = tunnel->parms.link,
619 .proto = IPPROTO_IPV6 }; 617 .proto = IPPROTO_IPV6 };
620 if (ip_route_output_key(dev_net(dev), &rt, &fl)) { 618 if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
621 tunnel->stat.tx_carrier_errors++; 619 stats->tx_carrier_errors++;
622 goto tx_error_icmp; 620 goto tx_error_icmp;
623 } 621 }
624 } 622 }
625 if (rt->rt_type != RTN_UNICAST) { 623 if (rt->rt_type != RTN_UNICAST) {
626 ip_rt_put(rt); 624 ip_rt_put(rt);
627 tunnel->stat.tx_carrier_errors++; 625 stats->tx_carrier_errors++;
628 goto tx_error_icmp; 626 goto tx_error_icmp;
629 } 627 }
630 tdev = rt->u.dst.dev; 628 tdev = rt->u.dst.dev;
631 629
632 if (tdev == dev) { 630 if (tdev == dev) {
633 ip_rt_put(rt); 631 ip_rt_put(rt);
634 tunnel->stat.collisions++; 632 stats->collisions++;
635 goto tx_error; 633 goto tx_error;
636 } 634 }
637 635
@@ -641,7 +639,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
641 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; 639 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
642 640
643 if (mtu < 68) { 641 if (mtu < 68) {
644 tunnel->stat.collisions++; 642 stats->collisions++;
645 ip_rt_put(rt); 643 ip_rt_put(rt);
646 goto tx_error; 644 goto tx_error;
647 } 645 }
@@ -916,11 +914,6 @@ done:
916 return err; 914 return err;
917} 915}
918 916
919static struct net_device_stats *ipip6_tunnel_get_stats(struct net_device *dev)
920{
921 return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
922}
923
924static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) 917static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
925{ 918{
926 if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - sizeof(struct iphdr)) 919 if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - sizeof(struct iphdr))
@@ -934,7 +927,6 @@ static void ipip6_tunnel_setup(struct net_device *dev)
934 dev->uninit = ipip6_tunnel_uninit; 927 dev->uninit = ipip6_tunnel_uninit;
935 dev->destructor = free_netdev; 928 dev->destructor = free_netdev;
936 dev->hard_start_xmit = ipip6_tunnel_xmit; 929 dev->hard_start_xmit = ipip6_tunnel_xmit;
937 dev->get_stats = ipip6_tunnel_get_stats;
938 dev->do_ioctl = ipip6_tunnel_ioctl; 930 dev->do_ioctl = ipip6_tunnel_ioctl;
939 dev->change_mtu = ipip6_tunnel_change_mtu; 931 dev->change_mtu = ipip6_tunnel_change_mtu;
940 932
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 3804dcbbfab0..5c99274558bf 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -37,6 +37,10 @@ static ctl_table ipv6_table_template[] = {
37 .mode = 0644, 37 .mode = 0644,
38 .proc_handler = &proc_dointvec 38 .proc_handler = &proc_dointvec
39 }, 39 },
40 { .ctl_name = 0 }
41};
42
43static ctl_table ipv6_table[] = {
40 { 44 {
41 .ctl_name = NET_IPV6_MLD_MAX_MSF, 45 .ctl_name = NET_IPV6_MLD_MAX_MSF,
42 .procname = "mld_max_msf", 46 .procname = "mld_max_msf",
@@ -80,12 +84,6 @@ static int ipv6_sysctl_net_init(struct net *net)
80 84
81 ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; 85 ipv6_table[2].data = &net->ipv6.sysctl.bindv6only;
82 86
83 /* We don't want this value to be per namespace, it should be global
84 to all namespaces, so make it read-only when we are not in the
85 init network namespace */
86 if (net != &init_net)
87 ipv6_table[3].mode = 0444;
88
89 net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, 87 net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path,
90 ipv6_table); 88 ipv6_table);
91 if (!net->ipv6.sysctl.table) 89 if (!net->ipv6.sysctl.table)
@@ -126,12 +124,29 @@ static struct pernet_operations ipv6_sysctl_net_ops = {
126 .exit = ipv6_sysctl_net_exit, 124 .exit = ipv6_sysctl_net_exit,
127}; 125};
128 126
127static struct ctl_table_header *ip6_header;
128
129int ipv6_sysctl_register(void) 129int ipv6_sysctl_register(void)
130{ 130{
131 return register_pernet_subsys(&ipv6_sysctl_net_ops); 131 int err = -ENOMEM;;
132
133 ip6_header = register_net_sysctl_rotable(net_ipv6_ctl_path, ipv6_table);
134 if (ip6_header == NULL)
135 goto out;
136
137 err = register_pernet_subsys(&ipv6_sysctl_net_ops);
138 if (err)
139 goto err_pernet;
140out:
141 return err;
142
143err_pernet:
144 unregister_net_sysctl_table(ip6_header);
145 goto out;
132} 146}
133 147
134void ipv6_sysctl_unregister(void) 148void ipv6_sysctl_unregister(void)
135{ 149{
150 unregister_net_sysctl_table(ip6_header);
136 unregister_pernet_subsys(&ipv6_sysctl_net_ops); 151 unregister_pernet_subsys(&ipv6_sysctl_net_ops);
137} 152}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index cb46749d4c32..ebed5d3adb82 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: tcp_ipv6.c,v 1.144 2002/02/01 22:01:04 davem Exp $
9 *
10 * Based on: 8 * Based on:
11 * linux/net/ipv4/tcp.c 9 * linux/net/ipv4/tcp.c
12 * linux/net/ipv4/tcp_input.c 10 * linux/net/ipv4/tcp_input.c
@@ -82,6 +80,12 @@ static struct inet_connection_sock_af_ops ipv6_specific;
82#ifdef CONFIG_TCP_MD5SIG 80#ifdef CONFIG_TCP_MD5SIG
83static struct tcp_sock_af_ops tcp_sock_ipv6_specific; 81static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
84static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; 82static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
83#else
84static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
85 struct in6_addr *addr)
86{
87 return NULL;
88}
85#endif 89#endif
86 90
87static void tcp_v6_hash(struct sock *sk) 91static void tcp_v6_hash(struct sock *sk)
@@ -736,78 +740,34 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
736static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 740static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
737 struct in6_addr *saddr, 741 struct in6_addr *saddr,
738 struct in6_addr *daddr, 742 struct in6_addr *daddr,
739 struct tcphdr *th, int protocol, 743 struct tcphdr *th, unsigned int tcplen)
740 unsigned int tcplen)
741{ 744{
742 struct scatterlist sg[4];
743 __u16 data_len;
744 int block = 0;
745 __sum16 cksum;
746 struct tcp_md5sig_pool *hp; 745 struct tcp_md5sig_pool *hp;
747 struct tcp6_pseudohdr *bp; 746 struct tcp6_pseudohdr *bp;
748 struct hash_desc *desc;
749 int err; 747 int err;
750 unsigned int nbytes = 0;
751 748
752 hp = tcp_get_md5sig_pool(); 749 hp = tcp_get_md5sig_pool();
753 if (!hp) { 750 if (!hp) {
754 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__); 751 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__);
755 goto clear_hash_noput; 752 goto clear_hash_noput;
756 } 753 }
754
757 bp = &hp->md5_blk.ip6; 755 bp = &hp->md5_blk.ip6;
758 desc = &hp->md5_desc;
759 756
760 /* 1. TCP pseudo-header (RFC2460) */ 757 /* 1. TCP pseudo-header (RFC2460) */
761 ipv6_addr_copy(&bp->saddr, saddr); 758 ipv6_addr_copy(&bp->saddr, saddr);
762 ipv6_addr_copy(&bp->daddr, daddr); 759 ipv6_addr_copy(&bp->daddr, daddr);
763 bp->len = htonl(tcplen); 760 bp->len = htonl(tcplen);
764 bp->protocol = htonl(protocol); 761 bp->protocol = htonl(IPPROTO_TCP);
765
766 sg_init_table(sg, 4);
767 762
768 sg_set_buf(&sg[block++], bp, sizeof(*bp)); 763 err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp),
769 nbytes += sizeof(*bp); 764 th, tcplen, hp);
770 765
771 /* 2. TCP header, excluding options */ 766 if (err)
772 cksum = th->check;
773 th->check = 0;
774 sg_set_buf(&sg[block++], th, sizeof(*th));
775 nbytes += sizeof(*th);
776
777 /* 3. TCP segment data (if any) */
778 data_len = tcplen - (th->doff << 2);
779 if (data_len > 0) {
780 u8 *data = (u8 *)th + (th->doff << 2);
781 sg_set_buf(&sg[block++], data, data_len);
782 nbytes += data_len;
783 }
784
785 /* 4. shared key */
786 sg_set_buf(&sg[block++], key->key, key->keylen);
787 nbytes += key->keylen;
788
789 sg_mark_end(&sg[block - 1]);
790
791 /* Now store the hash into the packet */
792 err = crypto_hash_init(desc);
793 if (err) {
794 printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
795 goto clear_hash;
796 }
797 err = crypto_hash_update(desc, sg, nbytes);
798 if (err) {
799 printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
800 goto clear_hash;
801 }
802 err = crypto_hash_final(desc, md5_hash);
803 if (err) {
804 printk(KERN_WARNING "%s(): hash_final failed\n", __func__);
805 goto clear_hash; 767 goto clear_hash;
806 }
807 768
808 /* Reset header, and free up the crypto */ 769 /* Free up the crypto pool */
809 tcp_put_md5sig_pool(); 770 tcp_put_md5sig_pool();
810 th->check = cksum;
811out: 771out:
812 return 0; 772 return 0;
813clear_hash: 773clear_hash:
@@ -821,8 +781,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
821 struct sock *sk, 781 struct sock *sk,
822 struct dst_entry *dst, 782 struct dst_entry *dst,
823 struct request_sock *req, 783 struct request_sock *req,
824 struct tcphdr *th, int protocol, 784 struct tcphdr *th, unsigned int tcplen)
825 unsigned int tcplen)
826{ 785{
827 struct in6_addr *saddr, *daddr; 786 struct in6_addr *saddr, *daddr;
828 787
@@ -835,7 +794,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
835 } 794 }
836 return tcp_v6_do_calc_md5_hash(md5_hash, key, 795 return tcp_v6_do_calc_md5_hash(md5_hash, key,
837 saddr, daddr, 796 saddr, daddr,
838 th, protocol, tcplen); 797 th, tcplen);
839} 798}
840 799
841static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) 800static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
@@ -844,43 +803,12 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
844 struct tcp_md5sig_key *hash_expected; 803 struct tcp_md5sig_key *hash_expected;
845 struct ipv6hdr *ip6h = ipv6_hdr(skb); 804 struct ipv6hdr *ip6h = ipv6_hdr(skb);
846 struct tcphdr *th = tcp_hdr(skb); 805 struct tcphdr *th = tcp_hdr(skb);
847 int length = (th->doff << 2) - sizeof (*th);
848 int genhash; 806 int genhash;
849 u8 *ptr;
850 u8 newhash[16]; 807 u8 newhash[16];
851 808
852 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); 809 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
810 hash_location = tcp_parse_md5sig_option(th);
853 811
854 /* If the TCP option is too short, we can short cut */
855 if (length < TCPOLEN_MD5SIG)
856 return hash_expected ? 1 : 0;
857
858 /* parse options */
859 ptr = (u8*)(th + 1);
860 while (length > 0) {
861 int opcode = *ptr++;
862 int opsize;
863
864 switch(opcode) {
865 case TCPOPT_EOL:
866 goto done_opts;
867 case TCPOPT_NOP:
868 length--;
869 continue;
870 default:
871 opsize = *ptr++;
872 if (opsize < 2 || opsize > length)
873 goto done_opts;
874 if (opcode == TCPOPT_MD5SIG) {
875 hash_location = ptr;
876 goto done_opts;
877 }
878 }
879 ptr += opsize - 2;
880 length -= opsize;
881 }
882
883done_opts:
884 /* do we have a hash as expected? */ 812 /* do we have a hash as expected? */
885 if (!hash_expected) { 813 if (!hash_expected) {
886 if (!hash_location) 814 if (!hash_location)
@@ -910,8 +838,7 @@ done_opts:
910 genhash = tcp_v6_do_calc_md5_hash(newhash, 838 genhash = tcp_v6_do_calc_md5_hash(newhash,
911 hash_expected, 839 hash_expected,
912 &ip6h->saddr, &ip6h->daddr, 840 &ip6h->saddr, &ip6h->daddr,
913 th, sk->sk_protocol, 841 th, skb->len);
914 skb->len);
915 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 842 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
916 if (net_ratelimit()) { 843 if (net_ratelimit()) {
917 printk(KERN_INFO "MD5 Hash %s for " 844 printk(KERN_INFO "MD5 Hash %s for "
@@ -1051,7 +978,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1051 tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key, 978 tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key,
1052 &ipv6_hdr(skb)->daddr, 979 &ipv6_hdr(skb)->daddr,
1053 &ipv6_hdr(skb)->saddr, 980 &ipv6_hdr(skb)->saddr,
1054 t1, IPPROTO_TCP, tot_len); 981 t1, tot_len);
1055 } 982 }
1056#endif 983#endif
1057 984
@@ -1088,8 +1015,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1088 kfree_skb(buff); 1015 kfree_skb(buff);
1089} 1016}
1090 1017
1091static void tcp_v6_send_ack(struct tcp_timewait_sock *tw, 1018static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
1092 struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) 1019 struct tcp_md5sig_key *key)
1093{ 1020{
1094 struct tcphdr *th = tcp_hdr(skb), *t1; 1021 struct tcphdr *th = tcp_hdr(skb), *t1;
1095 struct sk_buff *buff; 1022 struct sk_buff *buff;
@@ -1098,22 +1025,6 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1098 struct sock *ctl_sk = net->ipv6.tcp_sk; 1025 struct sock *ctl_sk = net->ipv6.tcp_sk;
1099 unsigned int tot_len = sizeof(struct tcphdr); 1026 unsigned int tot_len = sizeof(struct tcphdr);
1100 __be32 *topt; 1027 __be32 *topt;
1101#ifdef CONFIG_TCP_MD5SIG
1102 struct tcp_md5sig_key *key;
1103 struct tcp_md5sig_key tw_key;
1104#endif
1105
1106#ifdef CONFIG_TCP_MD5SIG
1107 if (!tw && skb->sk) {
1108 key = tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr);
1109 } else if (tw && tw->tw_md5_keylen) {
1110 tw_key.key = tw->tw_md5_key;
1111 tw_key.keylen = tw->tw_md5_keylen;
1112 key = &tw_key;
1113 } else {
1114 key = NULL;
1115 }
1116#endif
1117 1028
1118 if (ts) 1029 if (ts)
1119 tot_len += TCPOLEN_TSTAMP_ALIGNED; 1030 tot_len += TCPOLEN_TSTAMP_ALIGNED;
@@ -1157,7 +1068,7 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1157 tcp_v6_do_calc_md5_hash((__u8 *)topt, key, 1068 tcp_v6_do_calc_md5_hash((__u8 *)topt, key,
1158 &ipv6_hdr(skb)->daddr, 1069 &ipv6_hdr(skb)->daddr,
1159 &ipv6_hdr(skb)->saddr, 1070 &ipv6_hdr(skb)->saddr,
1160 t1, IPPROTO_TCP, tot_len); 1071 t1, tot_len);
1161 } 1072 }
1162#endif 1073#endif
1163 1074
@@ -1193,16 +1104,17 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1193 struct inet_timewait_sock *tw = inet_twsk(sk); 1104 struct inet_timewait_sock *tw = inet_twsk(sk);
1194 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 1105 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
1195 1106
1196 tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 1107 tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
1197 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 1108 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
1198 tcptw->tw_ts_recent); 1109 tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw));
1199 1110
1200 inet_twsk_put(tw); 1111 inet_twsk_put(tw);
1201} 1112}
1202 1113
1203static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1114static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
1204{ 1115{
1205 tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); 1116 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
1117 tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr));
1206} 1118}
1207 1119
1208 1120
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index dd309626ae9a..e0693fffc9bd 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -7,8 +7,6 @@
7 * 7 *
8 * Based on linux/ipv4/udp.c 8 * Based on linux/ipv4/udp.c
9 * 9 *
10 * $Id: udp.c,v 1.65 2002/02/01 22:01:04 davem Exp $
11 *
12 * Fixes: 10 * Fixes:
13 * Hideaki YOSHIFUJI : sin6_scope_id support 11 * Hideaki YOSHIFUJI : sin6_scope_id support
14 * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which 12 * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 491efd00a866..f6cdcb348e05 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -2,8 +2,6 @@
2 * UDPLITEv6 An implementation of the UDP-Lite protocol over IPv6. 2 * UDPLITEv6 An implementation of the UDP-Lite protocol over IPv6.
3 * See also net/ipv4/udplite.c 3 * See also net/ipv4/udplite.c
4 * 4 *
5 * Version: $Id: udplite.c,v 1.9 2006/10/19 08:28:10 gerrit Exp $
6 *
7 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk> 5 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk>
8 * 6 *
9 * Changes: 7 * Changes:
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index e0eab5927c4f..f6e54fa97f47 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -628,8 +628,8 @@ dev_irnet_poll(struct file * file,
628 * This is the way pppd configure us and control us while the PPP 628 * This is the way pppd configure us and control us while the PPP
629 * instance is active. 629 * instance is active.
630 */ 630 */
631static int 631static long
632dev_irnet_ioctl(struct inode * inode, 632dev_irnet_ioctl(
633 struct file * file, 633 struct file * file,
634 unsigned int cmd, 634 unsigned int cmd,
635 unsigned long arg) 635 unsigned long arg)
@@ -660,6 +660,7 @@ dev_irnet_ioctl(struct inode * inode,
660 { 660 {
661 DEBUG(FS_INFO, "Entering PPP discipline.\n"); 661 DEBUG(FS_INFO, "Entering PPP discipline.\n");
662 /* PPP channel setup (ap->chan in configued in dev_irnet_open())*/ 662 /* PPP channel setup (ap->chan in configued in dev_irnet_open())*/
663 lock_kernel();
663 err = ppp_register_channel(&ap->chan); 664 err = ppp_register_channel(&ap->chan);
664 if(err == 0) 665 if(err == 0)
665 { 666 {
@@ -672,12 +673,14 @@ dev_irnet_ioctl(struct inode * inode,
672 } 673 }
673 else 674 else
674 DERROR(FS_ERROR, "Can't setup PPP channel...\n"); 675 DERROR(FS_ERROR, "Can't setup PPP channel...\n");
676 unlock_kernel();
675 } 677 }
676 else 678 else
677 { 679 {
678 /* In theory, should be N_TTY */ 680 /* In theory, should be N_TTY */
679 DEBUG(FS_INFO, "Exiting PPP discipline.\n"); 681 DEBUG(FS_INFO, "Exiting PPP discipline.\n");
680 /* Disconnect from the generic PPP layer */ 682 /* Disconnect from the generic PPP layer */
683 lock_kernel();
681 if(ap->ppp_open) 684 if(ap->ppp_open)
682 { 685 {
683 ap->ppp_open = 0; 686 ap->ppp_open = 0;
@@ -686,24 +689,20 @@ dev_irnet_ioctl(struct inode * inode,
686 else 689 else
687 DERROR(FS_ERROR, "Channel not registered !\n"); 690 DERROR(FS_ERROR, "Channel not registered !\n");
688 err = 0; 691 err = 0;
692 unlock_kernel();
689 } 693 }
690 break; 694 break;
691 695
692 /* Query PPP channel and unit number */ 696 /* Query PPP channel and unit number */
693 case PPPIOCGCHAN: 697 case PPPIOCGCHAN:
694 if(!ap->ppp_open) 698 if(ap->ppp_open && !put_user(ppp_channel_index(&ap->chan),
695 break; 699 (int __user *)argp))
696 if(put_user(ppp_channel_index(&ap->chan), (int __user *)argp)) 700 err = 0;
697 break;
698 DEBUG(FS_INFO, "Query channel.\n");
699 err = 0;
700 break; 701 break;
701 case PPPIOCGUNIT: 702 case PPPIOCGUNIT:
702 if(!ap->ppp_open) 703 lock_kernel();
703 break; 704 if(ap->ppp_open && !put_user(ppp_unit_number(&ap->chan),
704 if(put_user(ppp_unit_number(&ap->chan), (int __user *)argp)) 705 (int __user *)argp))
705 break;
706 DEBUG(FS_INFO, "Query unit number.\n");
707 err = 0; 706 err = 0;
708 break; 707 break;
709 708
@@ -723,34 +722,39 @@ dev_irnet_ioctl(struct inode * inode,
723 DEBUG(FS_INFO, "Standard PPP ioctl.\n"); 722 DEBUG(FS_INFO, "Standard PPP ioctl.\n");
724 if(!capable(CAP_NET_ADMIN)) 723 if(!capable(CAP_NET_ADMIN))
725 err = -EPERM; 724 err = -EPERM;
726 else 725 else {
726 lock_kernel();
727 err = ppp_irnet_ioctl(&ap->chan, cmd, arg); 727 err = ppp_irnet_ioctl(&ap->chan, cmd, arg);
728 unlock_kernel();
729 }
728 break; 730 break;
729 731
730 /* TTY IOCTLs : Pretend that we are a tty, to keep pppd happy */ 732 /* TTY IOCTLs : Pretend that we are a tty, to keep pppd happy */
731 /* Get termios */ 733 /* Get termios */
732 case TCGETS: 734 case TCGETS:
733 DEBUG(FS_INFO, "Get termios.\n"); 735 DEBUG(FS_INFO, "Get termios.\n");
736 lock_kernel();
734#ifndef TCGETS2 737#ifndef TCGETS2
735 if(kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios)) 738 if(!kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios))
736 break; 739 err = 0;
737#else 740#else
738 if(kernel_termios_to_user_termios_1((struct termios __user *)argp, &ap->termios)) 741 if(kernel_termios_to_user_termios_1((struct termios __user *)argp, &ap->termios))
739 break; 742 err = 0;
740#endif 743#endif
741 err = 0; 744 unlock_kernel();
742 break; 745 break;
743 /* Set termios */ 746 /* Set termios */
744 case TCSETSF: 747 case TCSETSF:
745 DEBUG(FS_INFO, "Set termios.\n"); 748 DEBUG(FS_INFO, "Set termios.\n");
749 lock_kernel();
746#ifndef TCGETS2 750#ifndef TCGETS2
747 if(user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp)) 751 if(!user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp))
748 break; 752 err = 0;
749#else 753#else
750 if(user_termios_to_kernel_termios_1(&ap->termios, (struct termios __user *)argp)) 754 if(!user_termios_to_kernel_termios_1(&ap->termios, (struct termios __user *)argp))
751 break; 755 err = 0;
752#endif 756#endif
753 err = 0; 757 unlock_kernel();
754 break; 758 break;
755 759
756 /* Set DTR/RTS */ 760 /* Set DTR/RTS */
@@ -773,7 +777,9 @@ dev_irnet_ioctl(struct inode * inode,
773 * We should also worry that we don't accept junk here and that 777 * We should also worry that we don't accept junk here and that
774 * we get rid of our own buffers */ 778 * we get rid of our own buffers */
775#ifdef FLUSH_TO_PPP 779#ifdef FLUSH_TO_PPP
780 lock_kernel();
776 ppp_output_wakeup(&ap->chan); 781 ppp_output_wakeup(&ap->chan);
782 unlock_kernel();
777#endif /* FLUSH_TO_PPP */ 783#endif /* FLUSH_TO_PPP */
778 err = 0; 784 err = 0;
779 break; 785 break;
@@ -788,7 +794,7 @@ dev_irnet_ioctl(struct inode * inode,
788 794
789 default: 795 default:
790 DERROR(FS_ERROR, "Unsupported ioctl (0x%X)\n", cmd); 796 DERROR(FS_ERROR, "Unsupported ioctl (0x%X)\n", cmd);
791 err = -ENOIOCTLCMD; 797 err = -ENOTTY;
792 } 798 }
793 799
794 DEXIT(FS_TRACE, " - err = 0x%X\n", err); 800 DEXIT(FS_TRACE, " - err = 0x%X\n", err);
diff --git a/net/irda/irnet/irnet_ppp.h b/net/irda/irnet/irnet_ppp.h
index d2beb7df8f7f..d9f8bd4ebd05 100644
--- a/net/irda/irnet/irnet_ppp.h
+++ b/net/irda/irnet/irnet_ppp.h
@@ -76,9 +76,8 @@ static ssize_t
76static unsigned int 76static unsigned int
77 dev_irnet_poll(struct file *, 77 dev_irnet_poll(struct file *,
78 poll_table *); 78 poll_table *);
79static int 79static long
80 dev_irnet_ioctl(struct inode *, 80 dev_irnet_ioctl(struct file *,
81 struct file *,
82 unsigned int, 81 unsigned int,
83 unsigned long); 82 unsigned long);
84/* ------------------------ PPP INTERFACE ------------------------ */ 83/* ------------------------ PPP INTERFACE ------------------------ */
@@ -102,7 +101,7 @@ static struct file_operations irnet_device_fops =
102 .read = dev_irnet_read, 101 .read = dev_irnet_read,
103 .write = dev_irnet_write, 102 .write = dev_irnet_write,
104 .poll = dev_irnet_poll, 103 .poll = dev_irnet_poll,
105 .ioctl = dev_irnet_ioctl, 104 .unlocked_ioctl = dev_irnet_ioctl,
106 .open = dev_irnet_open, 105 .open = dev_irnet_open,
107 .release = dev_irnet_close 106 .release = dev_irnet_close
108 /* Also : llseek, readdir, mmap, flush, fsync, fasync, lock, readv, writev */ 107 /* Also : llseek, readdir, mmap, flush, fsync, fasync, lock, readv, writev */
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 7b0038f45b16..58e4aee3e696 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -644,6 +644,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
644 } 644 }
645 645
646 txmsg.class = 0; 646 txmsg.class = 0;
647 memcpy(&txmsg.class, skb->data, skb->len >= 4 ? 4 : skb->len);
647 txmsg.tag = iucv->send_tag++; 648 txmsg.tag = iucv->send_tag++;
648 memcpy(skb->cb, &txmsg.tag, 4); 649 memcpy(skb->cb, &txmsg.tag, 4);
649 skb_queue_tail(&iucv->send_skb_q, skb); 650 skb_queue_tail(&iucv->send_skb_q, skb);
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 918970762131..531a206ce7a6 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -474,14 +474,14 @@ static void iucv_setmask_mp(void)
474{ 474{
475 int cpu; 475 int cpu;
476 476
477 preempt_disable(); 477 get_online_cpus();
478 for_each_online_cpu(cpu) 478 for_each_online_cpu(cpu)
479 /* Enable all cpus with a declared buffer. */ 479 /* Enable all cpus with a declared buffer. */
480 if (cpu_isset(cpu, iucv_buffer_cpumask) && 480 if (cpu_isset(cpu, iucv_buffer_cpumask) &&
481 !cpu_isset(cpu, iucv_irq_cpumask)) 481 !cpu_isset(cpu, iucv_irq_cpumask))
482 smp_call_function_single(cpu, iucv_allow_cpu, 482 smp_call_function_single(cpu, iucv_allow_cpu,
483 NULL, 0, 1); 483 NULL, 0, 1);
484 preempt_enable(); 484 put_online_cpus();
485} 485}
486 486
487/** 487/**
@@ -521,16 +521,17 @@ static int iucv_enable(void)
521 goto out; 521 goto out;
522 /* Declare per cpu buffers. */ 522 /* Declare per cpu buffers. */
523 rc = -EIO; 523 rc = -EIO;
524 preempt_disable(); 524 get_online_cpus();
525 for_each_online_cpu(cpu) 525 for_each_online_cpu(cpu)
526 smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1); 526 smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1);
527 preempt_enable();
528 if (cpus_empty(iucv_buffer_cpumask)) 527 if (cpus_empty(iucv_buffer_cpumask))
529 /* No cpu could declare an iucv buffer. */ 528 /* No cpu could declare an iucv buffer. */
530 goto out_path; 529 goto out_path;
530 put_online_cpus();
531 return 0; 531 return 0;
532 532
533out_path: 533out_path:
534 put_online_cpus();
534 kfree(iucv_path_table); 535 kfree(iucv_path_table);
535out: 536out:
536 return rc; 537 return rc;
@@ -545,7 +546,9 @@ out:
545 */ 546 */
546static void iucv_disable(void) 547static void iucv_disable(void)
547{ 548{
549 get_online_cpus();
548 on_each_cpu(iucv_retrieve_cpu, NULL, 0, 1); 550 on_each_cpu(iucv_retrieve_cpu, NULL, 0, 1);
551 put_online_cpus();
549 kfree(iucv_path_table); 552 kfree(iucv_path_table);
550} 553}
551 554
@@ -598,7 +601,7 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
598 return NOTIFY_OK; 601 return NOTIFY_OK;
599} 602}
600 603
601static struct notifier_block __cpuinitdata iucv_cpu_notifier = { 604static struct notifier_block __refdata iucv_cpu_notifier = {
602 .notifier_call = iucv_cpu_notify, 605 .notifier_call = iucv_cpu_notify,
603}; 606};
604 607
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 7470e367272b..f0fc46c8038d 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -579,25 +579,43 @@ static uint8_t pfkey_proto_from_xfrm(uint8_t proto)
579 return (proto ? proto : IPSEC_PROTO_ANY); 579 return (proto ? proto : IPSEC_PROTO_ANY);
580} 580}
581 581
582static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, 582static inline int pfkey_sockaddr_len(sa_family_t family)
583 xfrm_address_t *xaddr)
584{ 583{
585 switch (((struct sockaddr*)(addr + 1))->sa_family) { 584 switch (family) {
585 case AF_INET:
586 return sizeof(struct sockaddr_in);
587#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
588 case AF_INET6:
589 return sizeof(struct sockaddr_in6);
590#endif
591 }
592 return 0;
593}
594
595static
596int pfkey_sockaddr_extract(const struct sockaddr *sa, xfrm_address_t *xaddr)
597{
598 switch (sa->sa_family) {
586 case AF_INET: 599 case AF_INET:
587 xaddr->a4 = 600 xaddr->a4 =
588 ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; 601 ((struct sockaddr_in *)sa)->sin_addr.s_addr;
589 return AF_INET; 602 return AF_INET;
590#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 603#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
591 case AF_INET6: 604 case AF_INET6:
592 memcpy(xaddr->a6, 605 memcpy(xaddr->a6,
593 &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, 606 &((struct sockaddr_in6 *)sa)->sin6_addr,
594 sizeof(struct in6_addr)); 607 sizeof(struct in6_addr));
595 return AF_INET6; 608 return AF_INET6;
596#endif 609#endif
597 default:
598 return 0;
599 } 610 }
600 /* NOTREACHED */ 611 return 0;
612}
613
614static
615int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, xfrm_address_t *xaddr)
616{
617 return pfkey_sockaddr_extract((struct sockaddr *)(addr + 1),
618 xaddr);
601} 619}
602 620
603static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) 621static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs)
@@ -642,20 +660,11 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
642} 660}
643 661
644#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) 662#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
663
645static int 664static int
646pfkey_sockaddr_size(sa_family_t family) 665pfkey_sockaddr_size(sa_family_t family)
647{ 666{
648 switch (family) { 667 return PFKEY_ALIGN8(pfkey_sockaddr_len(family));
649 case AF_INET:
650 return PFKEY_ALIGN8(sizeof(struct sockaddr_in));
651#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
652 case AF_INET6:
653 return PFKEY_ALIGN8(sizeof(struct sockaddr_in6));
654#endif
655 default:
656 return 0;
657 }
658 /* NOTREACHED */
659} 668}
660 669
661static inline int pfkey_mode_from_xfrm(int mode) 670static inline int pfkey_mode_from_xfrm(int mode)
@@ -687,6 +696,36 @@ static inline int pfkey_mode_to_xfrm(int mode)
687 } 696 }
688} 697}
689 698
699static unsigned int pfkey_sockaddr_fill(xfrm_address_t *xaddr, __be16 port,
700 struct sockaddr *sa,
701 unsigned short family)
702{
703 switch (family) {
704 case AF_INET:
705 {
706 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
707 sin->sin_family = AF_INET;
708 sin->sin_port = port;
709 sin->sin_addr.s_addr = xaddr->a4;
710 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
711 return 32;
712 }
713#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
714 case AF_INET6:
715 {
716 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
717 sin6->sin6_family = AF_INET6;
718 sin6->sin6_port = port;
719 sin6->sin6_flowinfo = 0;
720 ipv6_addr_copy(&sin6->sin6_addr, (struct in6_addr *)xaddr->a6);
721 sin6->sin6_scope_id = 0;
722 return 128;
723 }
724#endif
725 }
726 return 0;
727}
728
690static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, 729static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
691 int add_keys, int hsc) 730 int add_keys, int hsc)
692{ 731{
@@ -697,13 +736,9 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
697 struct sadb_address *addr; 736 struct sadb_address *addr;
698 struct sadb_key *key; 737 struct sadb_key *key;
699 struct sadb_x_sa2 *sa2; 738 struct sadb_x_sa2 *sa2;
700 struct sockaddr_in *sin;
701 struct sadb_x_sec_ctx *sec_ctx; 739 struct sadb_x_sec_ctx *sec_ctx;
702 struct xfrm_sec_ctx *xfrm_ctx; 740 struct xfrm_sec_ctx *xfrm_ctx;
703 int ctx_size = 0; 741 int ctx_size = 0;
704#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
705 struct sockaddr_in6 *sin6;
706#endif
707 int size; 742 int size;
708 int auth_key_size = 0; 743 int auth_key_size = 0;
709 int encrypt_key_size = 0; 744 int encrypt_key_size = 0;
@@ -732,14 +767,7 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
732 } 767 }
733 768
734 /* identity & sensitivity */ 769 /* identity & sensitivity */
735 770 if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr, x->props.family))
736 if ((x->props.family == AF_INET &&
737 x->sel.saddr.a4 != x->props.saddr.a4)
738#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
739 || (x->props.family == AF_INET6 &&
740 memcmp (x->sel.saddr.a6, x->props.saddr.a6, sizeof (struct in6_addr)))
741#endif
742 )
743 size += sizeof(struct sadb_address) + sockaddr_size; 771 size += sizeof(struct sadb_address) + sockaddr_size;
744 772
745 if (add_keys) { 773 if (add_keys) {
@@ -861,29 +889,12 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
861 protocol's number." - RFC2367 */ 889 protocol's number." - RFC2367 */
862 addr->sadb_address_proto = 0; 890 addr->sadb_address_proto = 0;
863 addr->sadb_address_reserved = 0; 891 addr->sadb_address_reserved = 0;
864 if (x->props.family == AF_INET) {
865 addr->sadb_address_prefixlen = 32;
866 892
867 sin = (struct sockaddr_in *) (addr + 1); 893 addr->sadb_address_prefixlen =
868 sin->sin_family = AF_INET; 894 pfkey_sockaddr_fill(&x->props.saddr, 0,
869 sin->sin_addr.s_addr = x->props.saddr.a4; 895 (struct sockaddr *) (addr + 1),
870 sin->sin_port = 0; 896 x->props.family);
871 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 897 if (!addr->sadb_address_prefixlen)
872 }
873#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
874 else if (x->props.family == AF_INET6) {
875 addr->sadb_address_prefixlen = 128;
876
877 sin6 = (struct sockaddr_in6 *) (addr + 1);
878 sin6->sin6_family = AF_INET6;
879 sin6->sin6_port = 0;
880 sin6->sin6_flowinfo = 0;
881 memcpy(&sin6->sin6_addr, x->props.saddr.a6,
882 sizeof(struct in6_addr));
883 sin6->sin6_scope_id = 0;
884 }
885#endif
886 else
887 BUG(); 898 BUG();
888 899
889 /* dst address */ 900 /* dst address */
@@ -894,70 +905,32 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
894 sizeof(uint64_t); 905 sizeof(uint64_t);
895 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 906 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
896 addr->sadb_address_proto = 0; 907 addr->sadb_address_proto = 0;
897 addr->sadb_address_prefixlen = 32; /* XXX */
898 addr->sadb_address_reserved = 0; 908 addr->sadb_address_reserved = 0;
899 if (x->props.family == AF_INET) {
900 sin = (struct sockaddr_in *) (addr + 1);
901 sin->sin_family = AF_INET;
902 sin->sin_addr.s_addr = x->id.daddr.a4;
903 sin->sin_port = 0;
904 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
905 909
906 if (x->sel.saddr.a4 != x->props.saddr.a4) { 910 addr->sadb_address_prefixlen =
907 addr = (struct sadb_address*) skb_put(skb, 911 pfkey_sockaddr_fill(&x->id.daddr, 0,
908 sizeof(struct sadb_address)+sockaddr_size); 912 (struct sockaddr *) (addr + 1),
909 addr->sadb_address_len = 913 x->props.family);
910 (sizeof(struct sadb_address)+sockaddr_size)/ 914 if (!addr->sadb_address_prefixlen)
911 sizeof(uint64_t); 915 BUG();
912 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
913 addr->sadb_address_proto =
914 pfkey_proto_from_xfrm(x->sel.proto);
915 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
916 addr->sadb_address_reserved = 0;
917
918 sin = (struct sockaddr_in *) (addr + 1);
919 sin->sin_family = AF_INET;
920 sin->sin_addr.s_addr = x->sel.saddr.a4;
921 sin->sin_port = x->sel.sport;
922 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
923 }
924 }
925#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
926 else if (x->props.family == AF_INET6) {
927 addr->sadb_address_prefixlen = 128;
928 916
929 sin6 = (struct sockaddr_in6 *) (addr + 1); 917 if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr,
930 sin6->sin6_family = AF_INET6; 918 x->props.family)) {
931 sin6->sin6_port = 0; 919 addr = (struct sadb_address*) skb_put(skb,
932 sin6->sin6_flowinfo = 0; 920 sizeof(struct sadb_address)+sockaddr_size);
933 memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr)); 921 addr->sadb_address_len =
934 sin6->sin6_scope_id = 0; 922 (sizeof(struct sadb_address)+sockaddr_size)/
923 sizeof(uint64_t);
924 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
925 addr->sadb_address_proto =
926 pfkey_proto_from_xfrm(x->sel.proto);
927 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
928 addr->sadb_address_reserved = 0;
935 929
936 if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, 930 pfkey_sockaddr_fill(&x->sel.saddr, x->sel.sport,
937 sizeof(struct in6_addr))) { 931 (struct sockaddr *) (addr + 1),
938 addr = (struct sadb_address *) skb_put(skb, 932 x->props.family);
939 sizeof(struct sadb_address)+sockaddr_size);
940 addr->sadb_address_len =
941 (sizeof(struct sadb_address)+sockaddr_size)/
942 sizeof(uint64_t);
943 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
944 addr->sadb_address_proto =
945 pfkey_proto_from_xfrm(x->sel.proto);
946 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
947 addr->sadb_address_reserved = 0;
948
949 sin6 = (struct sockaddr_in6 *) (addr + 1);
950 sin6->sin6_family = AF_INET6;
951 sin6->sin6_port = x->sel.sport;
952 sin6->sin6_flowinfo = 0;
953 memcpy(&sin6->sin6_addr, x->sel.saddr.a6,
954 sizeof(struct in6_addr));
955 sin6->sin6_scope_id = 0;
956 }
957 } 933 }
958#endif
959 else
960 BUG();
961 934
962 /* auth key */ 935 /* auth key */
963 if (add_keys && auth_key_size) { 936 if (add_keys && auth_key_size) {
@@ -1853,10 +1826,6 @@ static int
1853parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) 1826parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1854{ 1827{
1855 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; 1828 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
1856 struct sockaddr_in *sin;
1857#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1858 struct sockaddr_in6 *sin6;
1859#endif
1860 int mode; 1829 int mode;
1861 1830
1862 if (xp->xfrm_nr >= XFRM_MAX_DEPTH) 1831 if (xp->xfrm_nr >= XFRM_MAX_DEPTH)
@@ -1881,31 +1850,19 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1881 1850
1882 /* addresses present only in tunnel mode */ 1851 /* addresses present only in tunnel mode */
1883 if (t->mode == XFRM_MODE_TUNNEL) { 1852 if (t->mode == XFRM_MODE_TUNNEL) {
1884 struct sockaddr *sa; 1853 u8 *sa = (u8 *) (rq + 1);
1885 sa = (struct sockaddr *)(rq+1); 1854 int family, socklen;
1886 switch(sa->sa_family) { 1855
1887 case AF_INET: 1856 family = pfkey_sockaddr_extract((struct sockaddr *)sa,
1888 sin = (struct sockaddr_in*)sa; 1857 &t->saddr);
1889 t->saddr.a4 = sin->sin_addr.s_addr; 1858 if (!family)
1890 sin++;
1891 if (sin->sin_family != AF_INET)
1892 return -EINVAL;
1893 t->id.daddr.a4 = sin->sin_addr.s_addr;
1894 break;
1895#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1896 case AF_INET6:
1897 sin6 = (struct sockaddr_in6*)sa;
1898 memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1899 sin6++;
1900 if (sin6->sin6_family != AF_INET6)
1901 return -EINVAL;
1902 memcpy(t->id.daddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1903 break;
1904#endif
1905 default:
1906 return -EINVAL; 1859 return -EINVAL;
1907 } 1860
1908 t->encap_family = sa->sa_family; 1861 socklen = pfkey_sockaddr_len(family);
1862 if (pfkey_sockaddr_extract((struct sockaddr *)(sa + socklen),
1863 &t->id.daddr) != family)
1864 return -EINVAL;
1865 t->encap_family = family;
1909 } else 1866 } else
1910 t->encap_family = xp->family; 1867 t->encap_family = xp->family;
1911 1868
@@ -1952,9 +1909,7 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1952 1909
1953 for (i=0; i<xp->xfrm_nr; i++) { 1910 for (i=0; i<xp->xfrm_nr; i++) {
1954 t = xp->xfrm_vec + i; 1911 t = xp->xfrm_vec + i;
1955 socklen += (t->encap_family == AF_INET ? 1912 socklen += pfkey_sockaddr_len(t->encap_family);
1956 sizeof(struct sockaddr_in) :
1957 sizeof(struct sockaddr_in6));
1958 } 1913 }
1959 1914
1960 return sizeof(struct sadb_msg) + 1915 return sizeof(struct sadb_msg) +
@@ -1987,18 +1942,12 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
1987 struct sadb_address *addr; 1942 struct sadb_address *addr;
1988 struct sadb_lifetime *lifetime; 1943 struct sadb_lifetime *lifetime;
1989 struct sadb_x_policy *pol; 1944 struct sadb_x_policy *pol;
1990 struct sockaddr_in *sin;
1991 struct sadb_x_sec_ctx *sec_ctx; 1945 struct sadb_x_sec_ctx *sec_ctx;
1992 struct xfrm_sec_ctx *xfrm_ctx; 1946 struct xfrm_sec_ctx *xfrm_ctx;
1993#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1994 struct sockaddr_in6 *sin6;
1995#endif
1996 int i; 1947 int i;
1997 int size; 1948 int size;
1998 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1949 int sockaddr_size = pfkey_sockaddr_size(xp->family);
1999 int socklen = (xp->family == AF_INET ? 1950 int socklen = pfkey_sockaddr_len(xp->family);
2000 sizeof(struct sockaddr_in) :
2001 sizeof(struct sockaddr_in6));
2002 1951
2003 size = pfkey_xfrm_policy2msg_size(xp); 1952 size = pfkey_xfrm_policy2msg_size(xp);
2004 1953
@@ -2016,26 +1965,10 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2016 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); 1965 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
2017 addr->sadb_address_prefixlen = xp->selector.prefixlen_s; 1966 addr->sadb_address_prefixlen = xp->selector.prefixlen_s;
2018 addr->sadb_address_reserved = 0; 1967 addr->sadb_address_reserved = 0;
2019 /* src address */ 1968 if (!pfkey_sockaddr_fill(&xp->selector.saddr,
2020 if (xp->family == AF_INET) { 1969 xp->selector.sport,
2021 sin = (struct sockaddr_in *) (addr + 1); 1970 (struct sockaddr *) (addr + 1),
2022 sin->sin_family = AF_INET; 1971 xp->family))
2023 sin->sin_addr.s_addr = xp->selector.saddr.a4;
2024 sin->sin_port = xp->selector.sport;
2025 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2026 }
2027#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2028 else if (xp->family == AF_INET6) {
2029 sin6 = (struct sockaddr_in6 *) (addr + 1);
2030 sin6->sin6_family = AF_INET6;
2031 sin6->sin6_port = xp->selector.sport;
2032 sin6->sin6_flowinfo = 0;
2033 memcpy(&sin6->sin6_addr, xp->selector.saddr.a6,
2034 sizeof(struct in6_addr));
2035 sin6->sin6_scope_id = 0;
2036 }
2037#endif
2038 else
2039 BUG(); 1972 BUG();
2040 1973
2041 /* dst address */ 1974 /* dst address */
@@ -2048,26 +1981,10 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2048 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); 1981 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
2049 addr->sadb_address_prefixlen = xp->selector.prefixlen_d; 1982 addr->sadb_address_prefixlen = xp->selector.prefixlen_d;
2050 addr->sadb_address_reserved = 0; 1983 addr->sadb_address_reserved = 0;
2051 if (xp->family == AF_INET) { 1984
2052 sin = (struct sockaddr_in *) (addr + 1); 1985 pfkey_sockaddr_fill(&xp->selector.daddr, xp->selector.dport,
2053 sin->sin_family = AF_INET; 1986 (struct sockaddr *) (addr + 1),
2054 sin->sin_addr.s_addr = xp->selector.daddr.a4; 1987 xp->family);
2055 sin->sin_port = xp->selector.dport;
2056 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2057 }
2058#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2059 else if (xp->family == AF_INET6) {
2060 sin6 = (struct sockaddr_in6 *) (addr + 1);
2061 sin6->sin6_family = AF_INET6;
2062 sin6->sin6_port = xp->selector.dport;
2063 sin6->sin6_flowinfo = 0;
2064 memcpy(&sin6->sin6_addr, xp->selector.daddr.a6,
2065 sizeof(struct in6_addr));
2066 sin6->sin6_scope_id = 0;
2067 }
2068#endif
2069 else
2070 BUG();
2071 1988
2072 /* hard time */ 1989 /* hard time */
2073 lifetime = (struct sadb_lifetime *) skb_put(skb, 1990 lifetime = (struct sadb_lifetime *) skb_put(skb,
@@ -2121,12 +2038,13 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2121 int mode; 2038 int mode;
2122 2039
2123 req_size = sizeof(struct sadb_x_ipsecrequest); 2040 req_size = sizeof(struct sadb_x_ipsecrequest);
2124 if (t->mode == XFRM_MODE_TUNNEL) 2041 if (t->mode == XFRM_MODE_TUNNEL) {
2125 req_size += ((t->encap_family == AF_INET ? 2042 socklen = pfkey_sockaddr_len(t->encap_family);
2126 sizeof(struct sockaddr_in) : 2043 req_size += socklen * 2;
2127 sizeof(struct sockaddr_in6)) * 2); 2044 } else {
2128 else
2129 size -= 2*socklen; 2045 size -= 2*socklen;
2046 socklen = 0;
2047 }
2130 rq = (void*)skb_put(skb, req_size); 2048 rq = (void*)skb_put(skb, req_size);
2131 pol->sadb_x_policy_len += req_size/8; 2049 pol->sadb_x_policy_len += req_size/8;
2132 memset(rq, 0, sizeof(*rq)); 2050 memset(rq, 0, sizeof(*rq));
@@ -2141,42 +2059,15 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2141 if (t->optional) 2059 if (t->optional)
2142 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; 2060 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
2143 rq->sadb_x_ipsecrequest_reqid = t->reqid; 2061 rq->sadb_x_ipsecrequest_reqid = t->reqid;
2062
2144 if (t->mode == XFRM_MODE_TUNNEL) { 2063 if (t->mode == XFRM_MODE_TUNNEL) {
2145 switch (t->encap_family) { 2064 u8 *sa = (void *)(rq + 1);
2146 case AF_INET: 2065 pfkey_sockaddr_fill(&t->saddr, 0,
2147 sin = (void*)(rq+1); 2066 (struct sockaddr *)sa,
2148 sin->sin_family = AF_INET; 2067 t->encap_family);
2149 sin->sin_addr.s_addr = t->saddr.a4; 2068 pfkey_sockaddr_fill(&t->id.daddr, 0,
2150 sin->sin_port = 0; 2069 (struct sockaddr *) (sa + socklen),
2151 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 2070 t->encap_family);
2152 sin++;
2153 sin->sin_family = AF_INET;
2154 sin->sin_addr.s_addr = t->id.daddr.a4;
2155 sin->sin_port = 0;
2156 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2157 break;
2158#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2159 case AF_INET6:
2160 sin6 = (void*)(rq+1);
2161 sin6->sin6_family = AF_INET6;
2162 sin6->sin6_port = 0;
2163 sin6->sin6_flowinfo = 0;
2164 memcpy(&sin6->sin6_addr, t->saddr.a6,
2165 sizeof(struct in6_addr));
2166 sin6->sin6_scope_id = 0;
2167
2168 sin6++;
2169 sin6->sin6_family = AF_INET6;
2170 sin6->sin6_port = 0;
2171 sin6->sin6_flowinfo = 0;
2172 memcpy(&sin6->sin6_addr, t->id.daddr.a6,
2173 sizeof(struct in6_addr));
2174 sin6->sin6_scope_id = 0;
2175 break;
2176#endif
2177 default:
2178 break;
2179 }
2180 } 2071 }
2181 } 2072 }
2182 2073
@@ -2459,61 +2350,31 @@ out:
2459#ifdef CONFIG_NET_KEY_MIGRATE 2350#ifdef CONFIG_NET_KEY_MIGRATE
2460static int pfkey_sockaddr_pair_size(sa_family_t family) 2351static int pfkey_sockaddr_pair_size(sa_family_t family)
2461{ 2352{
2462 switch (family) { 2353 return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2);
2463 case AF_INET:
2464 return PFKEY_ALIGN8(sizeof(struct sockaddr_in) * 2);
2465#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2466 case AF_INET6:
2467 return PFKEY_ALIGN8(sizeof(struct sockaddr_in6) * 2);
2468#endif
2469 default:
2470 return 0;
2471 }
2472 /* NOTREACHED */
2473} 2354}
2474 2355
2475static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, 2356static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq,
2476 xfrm_address_t *saddr, xfrm_address_t *daddr, 2357 xfrm_address_t *saddr, xfrm_address_t *daddr,
2477 u16 *family) 2358 u16 *family)
2478{ 2359{
2479 struct sockaddr *sa = (struct sockaddr *)(rq + 1); 2360 u8 *sa = (u8 *) (rq + 1);
2361 int af, socklen;
2362
2480 if (rq->sadb_x_ipsecrequest_len < 2363 if (rq->sadb_x_ipsecrequest_len <
2481 pfkey_sockaddr_pair_size(sa->sa_family)) 2364 pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family))
2482 return -EINVAL; 2365 return -EINVAL;
2483 2366
2484 switch (sa->sa_family) { 2367 af = pfkey_sockaddr_extract((struct sockaddr *) sa,
2485 case AF_INET: 2368 saddr);
2486 { 2369 if (!af)
2487 struct sockaddr_in *sin;
2488 sin = (struct sockaddr_in *)sa;
2489 if ((sin+1)->sin_family != AF_INET)
2490 return -EINVAL;
2491 memcpy(&saddr->a4, &sin->sin_addr, sizeof(saddr->a4));
2492 sin++;
2493 memcpy(&daddr->a4, &sin->sin_addr, sizeof(daddr->a4));
2494 *family = AF_INET;
2495 break;
2496 }
2497#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2498 case AF_INET6:
2499 {
2500 struct sockaddr_in6 *sin6;
2501 sin6 = (struct sockaddr_in6 *)sa;
2502 if ((sin6+1)->sin6_family != AF_INET6)
2503 return -EINVAL;
2504 memcpy(&saddr->a6, &sin6->sin6_addr,
2505 sizeof(saddr->a6));
2506 sin6++;
2507 memcpy(&daddr->a6, &sin6->sin6_addr,
2508 sizeof(daddr->a6));
2509 *family = AF_INET6;
2510 break;
2511 }
2512#endif
2513 default:
2514 return -EINVAL; 2370 return -EINVAL;
2515 }
2516 2371
2372 socklen = pfkey_sockaddr_len(af);
2373 if (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen),
2374 daddr) != af)
2375 return -EINVAL;
2376
2377 *family = af;
2517 return 0; 2378 return 0;
2518} 2379}
2519 2380
@@ -3094,10 +2955,6 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3094 struct sadb_msg *hdr; 2955 struct sadb_msg *hdr;
3095 struct sadb_address *addr; 2956 struct sadb_address *addr;
3096 struct sadb_x_policy *pol; 2957 struct sadb_x_policy *pol;
3097 struct sockaddr_in *sin;
3098#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3099 struct sockaddr_in6 *sin6;
3100#endif
3101 int sockaddr_size; 2958 int sockaddr_size;
3102 int size; 2959 int size;
3103 struct sadb_x_sec_ctx *sec_ctx; 2960 struct sadb_x_sec_ctx *sec_ctx;
@@ -3146,29 +3003,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3146 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3003 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
3147 addr->sadb_address_proto = 0; 3004 addr->sadb_address_proto = 0;
3148 addr->sadb_address_reserved = 0; 3005 addr->sadb_address_reserved = 0;
3149 if (x->props.family == AF_INET) { 3006 addr->sadb_address_prefixlen =
3150 addr->sadb_address_prefixlen = 32; 3007 pfkey_sockaddr_fill(&x->props.saddr, 0,
3151 3008 (struct sockaddr *) (addr + 1),
3152 sin = (struct sockaddr_in *) (addr + 1); 3009 x->props.family);
3153 sin->sin_family = AF_INET; 3010 if (!addr->sadb_address_prefixlen)
3154 sin->sin_addr.s_addr = x->props.saddr.a4;
3155 sin->sin_port = 0;
3156 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3157 }
3158#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3159 else if (x->props.family == AF_INET6) {
3160 addr->sadb_address_prefixlen = 128;
3161
3162 sin6 = (struct sockaddr_in6 *) (addr + 1);
3163 sin6->sin6_family = AF_INET6;
3164 sin6->sin6_port = 0;
3165 sin6->sin6_flowinfo = 0;
3166 memcpy(&sin6->sin6_addr,
3167 x->props.saddr.a6, sizeof(struct in6_addr));
3168 sin6->sin6_scope_id = 0;
3169 }
3170#endif
3171 else
3172 BUG(); 3011 BUG();
3173 3012
3174 /* dst address */ 3013 /* dst address */
@@ -3180,29 +3019,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3180 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3019 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
3181 addr->sadb_address_proto = 0; 3020 addr->sadb_address_proto = 0;
3182 addr->sadb_address_reserved = 0; 3021 addr->sadb_address_reserved = 0;
3183 if (x->props.family == AF_INET) { 3022 addr->sadb_address_prefixlen =
3184 addr->sadb_address_prefixlen = 32; 3023 pfkey_sockaddr_fill(&x->id.daddr, 0,
3185 3024 (struct sockaddr *) (addr + 1),
3186 sin = (struct sockaddr_in *) (addr + 1); 3025 x->props.family);
3187 sin->sin_family = AF_INET; 3026 if (!addr->sadb_address_prefixlen)
3188 sin->sin_addr.s_addr = x->id.daddr.a4;
3189 sin->sin_port = 0;
3190 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3191 }
3192#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3193 else if (x->props.family == AF_INET6) {
3194 addr->sadb_address_prefixlen = 128;
3195
3196 sin6 = (struct sockaddr_in6 *) (addr + 1);
3197 sin6->sin6_family = AF_INET6;
3198 sin6->sin6_port = 0;
3199 sin6->sin6_flowinfo = 0;
3200 memcpy(&sin6->sin6_addr,
3201 x->id.daddr.a6, sizeof(struct in6_addr));
3202 sin6->sin6_scope_id = 0;
3203 }
3204#endif
3205 else
3206 BUG(); 3027 BUG();
3207 3028
3208 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy)); 3029 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy));
@@ -3328,10 +3149,6 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3328 struct sadb_sa *sa; 3149 struct sadb_sa *sa;
3329 struct sadb_address *addr; 3150 struct sadb_address *addr;
3330 struct sadb_x_nat_t_port *n_port; 3151 struct sadb_x_nat_t_port *n_port;
3331 struct sockaddr_in *sin;
3332#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3333 struct sockaddr_in6 *sin6;
3334#endif
3335 int sockaddr_size; 3152 int sockaddr_size;
3336 int size; 3153 int size;
3337 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0); 3154 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0);
@@ -3395,29 +3212,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3395 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3212 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
3396 addr->sadb_address_proto = 0; 3213 addr->sadb_address_proto = 0;
3397 addr->sadb_address_reserved = 0; 3214 addr->sadb_address_reserved = 0;
3398 if (x->props.family == AF_INET) { 3215 addr->sadb_address_prefixlen =
3399 addr->sadb_address_prefixlen = 32; 3216 pfkey_sockaddr_fill(&x->props.saddr, 0,
3400 3217 (struct sockaddr *) (addr + 1),
3401 sin = (struct sockaddr_in *) (addr + 1); 3218 x->props.family);
3402 sin->sin_family = AF_INET; 3219 if (!addr->sadb_address_prefixlen)
3403 sin->sin_addr.s_addr = x->props.saddr.a4;
3404 sin->sin_port = 0;
3405 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3406 }
3407#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3408 else if (x->props.family == AF_INET6) {
3409 addr->sadb_address_prefixlen = 128;
3410
3411 sin6 = (struct sockaddr_in6 *) (addr + 1);
3412 sin6->sin6_family = AF_INET6;
3413 sin6->sin6_port = 0;
3414 sin6->sin6_flowinfo = 0;
3415 memcpy(&sin6->sin6_addr,
3416 x->props.saddr.a6, sizeof(struct in6_addr));
3417 sin6->sin6_scope_id = 0;
3418 }
3419#endif
3420 else
3421 BUG(); 3220 BUG();
3422 3221
3423 /* NAT_T_SPORT (old port) */ 3222 /* NAT_T_SPORT (old port) */
@@ -3436,28 +3235,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3436 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3235 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
3437 addr->sadb_address_proto = 0; 3236 addr->sadb_address_proto = 0;
3438 addr->sadb_address_reserved = 0; 3237 addr->sadb_address_reserved = 0;
3439 if (x->props.family == AF_INET) { 3238 addr->sadb_address_prefixlen =
3440 addr->sadb_address_prefixlen = 32; 3239 pfkey_sockaddr_fill(ipaddr, 0,
3441 3240 (struct sockaddr *) (addr + 1),
3442 sin = (struct sockaddr_in *) (addr + 1); 3241 x->props.family);
3443 sin->sin_family = AF_INET; 3242 if (!addr->sadb_address_prefixlen)
3444 sin->sin_addr.s_addr = ipaddr->a4;
3445 sin->sin_port = 0;
3446 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3447 }
3448#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3449 else if (x->props.family == AF_INET6) {
3450 addr->sadb_address_prefixlen = 128;
3451
3452 sin6 = (struct sockaddr_in6 *) (addr + 1);
3453 sin6->sin6_family = AF_INET6;
3454 sin6->sin6_port = 0;
3455 sin6->sin6_flowinfo = 0;
3456 memcpy(&sin6->sin6_addr, &ipaddr->a6, sizeof(struct in6_addr));
3457 sin6->sin6_scope_id = 0;
3458 }
3459#endif
3460 else
3461 BUG(); 3243 BUG();
3462 3244
3463 /* NAT_T_DPORT (new port) */ 3245 /* NAT_T_DPORT (new port) */
@@ -3475,10 +3257,6 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3475 struct xfrm_selector *sel) 3257 struct xfrm_selector *sel)
3476{ 3258{
3477 struct sadb_address *addr; 3259 struct sadb_address *addr;
3478 struct sockaddr_in *sin;
3479#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3480 struct sockaddr_in6 *sin6;
3481#endif
3482 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize); 3260 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize);
3483 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8; 3261 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8;
3484 addr->sadb_address_exttype = type; 3262 addr->sadb_address_exttype = type;
@@ -3487,50 +3265,16 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3487 3265
3488 switch (type) { 3266 switch (type) {
3489 case SADB_EXT_ADDRESS_SRC: 3267 case SADB_EXT_ADDRESS_SRC:
3490 if (sel->family == AF_INET) { 3268 addr->sadb_address_prefixlen = sel->prefixlen_s;
3491 addr->sadb_address_prefixlen = sel->prefixlen_s; 3269 pfkey_sockaddr_fill(&sel->saddr, 0,
3492 sin = (struct sockaddr_in *)(addr + 1); 3270 (struct sockaddr *)(addr + 1),
3493 sin->sin_family = AF_INET; 3271 sel->family);
3494 memcpy(&sin->sin_addr.s_addr, &sel->saddr,
3495 sizeof(sin->sin_addr.s_addr));
3496 sin->sin_port = 0;
3497 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3498 }
3499#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3500 else if (sel->family == AF_INET6) {
3501 addr->sadb_address_prefixlen = sel->prefixlen_s;
3502 sin6 = (struct sockaddr_in6 *)(addr + 1);
3503 sin6->sin6_family = AF_INET6;
3504 sin6->sin6_port = 0;
3505 sin6->sin6_flowinfo = 0;
3506 sin6->sin6_scope_id = 0;
3507 memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr,
3508 sizeof(sin6->sin6_addr.s6_addr));
3509 }
3510#endif
3511 break; 3272 break;
3512 case SADB_EXT_ADDRESS_DST: 3273 case SADB_EXT_ADDRESS_DST:
3513 if (sel->family == AF_INET) { 3274 addr->sadb_address_prefixlen = sel->prefixlen_d;
3514 addr->sadb_address_prefixlen = sel->prefixlen_d; 3275 pfkey_sockaddr_fill(&sel->daddr, 0,
3515 sin = (struct sockaddr_in *)(addr + 1); 3276 (struct sockaddr *)(addr + 1),
3516 sin->sin_family = AF_INET; 3277 sel->family);
3517 memcpy(&sin->sin_addr.s_addr, &sel->daddr,
3518 sizeof(sin->sin_addr.s_addr));
3519 sin->sin_port = 0;
3520 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3521 }
3522#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3523 else if (sel->family == AF_INET6) {
3524 addr->sadb_address_prefixlen = sel->prefixlen_d;
3525 sin6 = (struct sockaddr_in6 *)(addr + 1);
3526 sin6->sin6_family = AF_INET6;
3527 sin6->sin6_port = 0;
3528 sin6->sin6_flowinfo = 0;
3529 sin6->sin6_scope_id = 0;
3530 memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr,
3531 sizeof(sin6->sin6_addr.s6_addr));
3532 }
3533#endif
3534 break; 3278 break;
3535 default: 3279 default:
3536 return -EINVAL; 3280 return -EINVAL;
@@ -3545,10 +3289,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
3545 xfrm_address_t *src, xfrm_address_t *dst) 3289 xfrm_address_t *src, xfrm_address_t *dst)
3546{ 3290{
3547 struct sadb_x_ipsecrequest *rq; 3291 struct sadb_x_ipsecrequest *rq;
3548 struct sockaddr_in *sin; 3292 u8 *sa;
3549#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3293 int socklen = pfkey_sockaddr_len(family);
3550 struct sockaddr_in6 *sin6;
3551#endif
3552 int size_req; 3294 int size_req;
3553 3295
3554 size_req = sizeof(struct sadb_x_ipsecrequest) + 3296 size_req = sizeof(struct sadb_x_ipsecrequest) +
@@ -3562,38 +3304,10 @@ static int set_ipsecrequest(struct sk_buff *skb,
3562 rq->sadb_x_ipsecrequest_level = level; 3304 rq->sadb_x_ipsecrequest_level = level;
3563 rq->sadb_x_ipsecrequest_reqid = reqid; 3305 rq->sadb_x_ipsecrequest_reqid = reqid;
3564 3306
3565 switch (family) { 3307 sa = (u8 *) (rq + 1);
3566 case AF_INET: 3308 if (!pfkey_sockaddr_fill(src, 0, (struct sockaddr *)sa, family) ||
3567 sin = (struct sockaddr_in *)(rq + 1); 3309 !pfkey_sockaddr_fill(dst, 0, (struct sockaddr *)(sa + socklen), family))
3568 sin->sin_family = AF_INET;
3569 memcpy(&sin->sin_addr.s_addr, src,
3570 sizeof(sin->sin_addr.s_addr));
3571 sin++;
3572 sin->sin_family = AF_INET;
3573 memcpy(&sin->sin_addr.s_addr, dst,
3574 sizeof(sin->sin_addr.s_addr));
3575 break;
3576#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3577 case AF_INET6:
3578 sin6 = (struct sockaddr_in6 *)(rq + 1);
3579 sin6->sin6_family = AF_INET6;
3580 sin6->sin6_port = 0;
3581 sin6->sin6_flowinfo = 0;
3582 sin6->sin6_scope_id = 0;
3583 memcpy(&sin6->sin6_addr.s6_addr, src,
3584 sizeof(sin6->sin6_addr.s6_addr));
3585 sin6++;
3586 sin6->sin6_family = AF_INET6;
3587 sin6->sin6_port = 0;
3588 sin6->sin6_flowinfo = 0;
3589 sin6->sin6_scope_id = 0;
3590 memcpy(&sin6->sin6_addr.s6_addr, dst,
3591 sizeof(sin6->sin6_addr.s6_addr));
3592 break;
3593#endif
3594 default:
3595 return -EINVAL; 3310 return -EINVAL;
3596 }
3597 3311
3598 return 0; 3312 return 0;
3599} 3313}
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index a24b459dd45a..590e00b2766c 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -7,11 +7,23 @@ config MAC80211
7 select CRC32 7 select CRC32
8 select WIRELESS_EXT 8 select WIRELESS_EXT
9 select CFG80211 9 select CFG80211
10 select NET_SCH_FIFO
11 ---help--- 10 ---help---
12 This option enables the hardware independent IEEE 802.11 11 This option enables the hardware independent IEEE 802.11
13 networking stack. 12 networking stack.
14 13
14config MAC80211_QOS
15 def_bool y
16 depends on MAC80211
17 depends on NET_SCHED
18 depends on NETDEVICES_MULTIQUEUE
19
20comment "QoS/HT support disabled"
21 depends on MAC80211 && !MAC80211_QOS
22comment "QoS/HT support needs CONFIG_NET_SCHED"
23 depends on MAC80211 && !NET_SCHED
24comment "QoS/HT support needs CONFIG_NETDEVICES_MULTIQUEUE"
25 depends on MAC80211 && !NETDEVICES_MULTIQUEUE
26
15menu "Rate control algorithm selection" 27menu "Rate control algorithm selection"
16 depends on MAC80211 != n 28 depends on MAC80211 != n
17 29
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 4e5847fd316c..1d2a4e010e5c 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -29,7 +29,7 @@ mac80211-y := \
29 event.o 29 event.o
30 30
31mac80211-$(CONFIG_MAC80211_LEDS) += led.o 31mac80211-$(CONFIG_MAC80211_LEDS) += led.o
32mac80211-$(CONFIG_NET_SCHED) += wme.o 32mac80211-$(CONFIG_MAC80211_QOS) += wme.o
33mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ 33mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
34 debugfs.o \ 34 debugfs.o \
35 debugfs_sta.o \ 35 debugfs_sta.o \
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index 59f1691f62c8..4d4c2dfcf9a0 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -134,7 +134,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
134} 134}
135 135
136 136
137struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[]) 137struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
138{ 138{
139 struct crypto_cipher *tfm; 139 struct crypto_cipher *tfm;
140 140
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h
index 885f19030b29..8cd0f14aab4d 100644
--- a/net/mac80211/aes_ccm.h
+++ b/net/mac80211/aes_ccm.h
@@ -14,7 +14,7 @@
14 14
15#define AES_BLOCK_LEN 16 15#define AES_BLOCK_LEN 16
16 16
17struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[]); 17struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
18void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, 18void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
19 u8 *b_0, u8 *aad, u8 *data, size_t data_len, 19 u8 *b_0, u8 *aad, u8 *data, size_t data_len,
20 u8 *cdata, u8 *mic); 20 u8 *cdata, u8 *mic);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a9fce4afdf21..81087281b031 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -256,8 +256,8 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
256 case ALG_TKIP: 256 case ALG_TKIP:
257 params.cipher = WLAN_CIPHER_SUITE_TKIP; 257 params.cipher = WLAN_CIPHER_SUITE_TKIP;
258 258
259 iv32 = key->u.tkip.iv32; 259 iv32 = key->u.tkip.tx.iv32;
260 iv16 = key->u.tkip.iv16; 260 iv16 = key->u.tkip.tx.iv16;
261 261
262 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && 262 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
263 sdata->local->ops->get_tkip_seq) 263 sdata->local->ops->get_tkip_seq)
@@ -602,6 +602,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
602 */ 602 */
603 603
604 if (params->station_flags & STATION_FLAG_CHANGED) { 604 if (params->station_flags & STATION_FLAG_CHANGED) {
605 spin_lock_bh(&sta->lock);
605 sta->flags &= ~WLAN_STA_AUTHORIZED; 606 sta->flags &= ~WLAN_STA_AUTHORIZED;
606 if (params->station_flags & STATION_FLAG_AUTHORIZED) 607 if (params->station_flags & STATION_FLAG_AUTHORIZED)
607 sta->flags |= WLAN_STA_AUTHORIZED; 608 sta->flags |= WLAN_STA_AUTHORIZED;
@@ -613,6 +614,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
613 sta->flags &= ~WLAN_STA_WME; 614 sta->flags &= ~WLAN_STA_WME;
614 if (params->station_flags & STATION_FLAG_WME) 615 if (params->station_flags & STATION_FLAG_WME)
615 sta->flags |= WLAN_STA_WME; 616 sta->flags |= WLAN_STA_WME;
617 spin_unlock_bh(&sta->lock);
616 } 618 }
617 619
618 /* 620 /*
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 1cccbfd781f6..d20d90eead1f 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -197,45 +197,6 @@ DEBUGFS_STATS_FILE(rx_handlers_fragments, 20, "%u",
197DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u", 197DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u",
198 local->tx_status_drop); 198 local->tx_status_drop);
199 199
200static ssize_t stats_wme_rx_queue_read(struct file *file,
201 char __user *userbuf,
202 size_t count, loff_t *ppos)
203{
204 struct ieee80211_local *local = file->private_data;
205 char buf[NUM_RX_DATA_QUEUES*15], *p = buf;
206 int i;
207
208 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
209 p += scnprintf(p, sizeof(buf)+buf-p,
210 "%u\n", local->wme_rx_queue[i]);
211
212 return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
213}
214
215static const struct file_operations stats_wme_rx_queue_ops = {
216 .read = stats_wme_rx_queue_read,
217 .open = mac80211_open_file_generic,
218};
219
220static ssize_t stats_wme_tx_queue_read(struct file *file,
221 char __user *userbuf,
222 size_t count, loff_t *ppos)
223{
224 struct ieee80211_local *local = file->private_data;
225 char buf[NUM_TX_DATA_QUEUES*15], *p = buf;
226 int i;
227
228 for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
229 p += scnprintf(p, sizeof(buf)+buf-p,
230 "%u\n", local->wme_tx_queue[i]);
231
232 return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
233}
234
235static const struct file_operations stats_wme_tx_queue_ops = {
236 .read = stats_wme_tx_queue_read,
237 .open = mac80211_open_file_generic,
238};
239#endif 200#endif
240 201
241DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount); 202DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
@@ -303,8 +264,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
303 DEBUGFS_STATS_ADD(rx_expand_skb_head2); 264 DEBUGFS_STATS_ADD(rx_expand_skb_head2);
304 DEBUGFS_STATS_ADD(rx_handlers_fragments); 265 DEBUGFS_STATS_ADD(rx_handlers_fragments);
305 DEBUGFS_STATS_ADD(tx_status_drop); 266 DEBUGFS_STATS_ADD(tx_status_drop);
306 DEBUGFS_STATS_ADD(wme_tx_queue);
307 DEBUGFS_STATS_ADD(wme_rx_queue);
308#endif 267#endif
309 DEBUGFS_STATS_ADD(dot11ACKFailureCount); 268 DEBUGFS_STATS_ADD(dot11ACKFailureCount);
310 DEBUGFS_STATS_ADD(dot11RTSFailureCount); 269 DEBUGFS_STATS_ADD(dot11RTSFailureCount);
@@ -356,8 +315,6 @@ void debugfs_hw_del(struct ieee80211_local *local)
356 DEBUGFS_STATS_DEL(rx_expand_skb_head2); 315 DEBUGFS_STATS_DEL(rx_expand_skb_head2);
357 DEBUGFS_STATS_DEL(rx_handlers_fragments); 316 DEBUGFS_STATS_DEL(rx_handlers_fragments);
358 DEBUGFS_STATS_DEL(tx_status_drop); 317 DEBUGFS_STATS_DEL(tx_status_drop);
359 DEBUGFS_STATS_DEL(wme_tx_queue);
360 DEBUGFS_STATS_DEL(wme_rx_queue);
361#endif 318#endif
362 DEBUGFS_STATS_DEL(dot11ACKFailureCount); 319 DEBUGFS_STATS_DEL(dot11ACKFailureCount);
363 DEBUGFS_STATS_DEL(dot11RTSFailureCount); 320 DEBUGFS_STATS_DEL(dot11RTSFailureCount);
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 19efc3a6a932..7439b63df5d0 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -97,8 +97,8 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
97 break; 97 break;
98 case ALG_TKIP: 98 case ALG_TKIP:
99 len = scnprintf(buf, sizeof(buf), "%08x %04x\n", 99 len = scnprintf(buf, sizeof(buf), "%08x %04x\n",
100 key->u.tkip.iv32, 100 key->u.tkip.tx.iv32,
101 key->u.tkip.iv16); 101 key->u.tkip.tx.iv16);
102 break; 102 break;
103 case ALG_CCMP: 103 case ALG_CCMP:
104 tpn = key->u.ccmp.tx_pn; 104 tpn = key->u.ccmp.tx_pn;
@@ -128,8 +128,8 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
128 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) 128 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
129 p += scnprintf(p, sizeof(buf)+buf-p, 129 p += scnprintf(p, sizeof(buf)+buf-p,
130 "%08x %04x\n", 130 "%08x %04x\n",
131 key->u.tkip.iv32_rx[i], 131 key->u.tkip.rx[i].iv32,
132 key->u.tkip.iv16_rx[i]); 132 key->u.tkip.rx[i].iv16);
133 len = p - buf; 133 len = p - buf;
134 break; 134 break;
135 case ALG_CCMP: 135 case ALG_CCMP:
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index e3326d046944..b2089b2da48a 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -155,7 +155,6 @@ static const struct file_operations name##_ops = { \
155 __IEEE80211_IF_WFILE(name) 155 __IEEE80211_IF_WFILE(name)
156 156
157/* common attributes */ 157/* common attributes */
158IEEE80211_IF_FILE(channel_use, channel_use, DEC);
159IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); 158IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
160 159
161/* STA/IBSS attributes */ 160/* STA/IBSS attributes */
@@ -248,7 +247,6 @@ IEEE80211_IF_WFILE(min_discovery_timeout,
248 247
249static void add_sta_files(struct ieee80211_sub_if_data *sdata) 248static void add_sta_files(struct ieee80211_sub_if_data *sdata)
250{ 249{
251 DEBUGFS_ADD(channel_use, sta);
252 DEBUGFS_ADD(drop_unencrypted, sta); 250 DEBUGFS_ADD(drop_unencrypted, sta);
253 DEBUGFS_ADD(state, sta); 251 DEBUGFS_ADD(state, sta);
254 DEBUGFS_ADD(bssid, sta); 252 DEBUGFS_ADD(bssid, sta);
@@ -269,7 +267,6 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
269 267
270static void add_ap_files(struct ieee80211_sub_if_data *sdata) 268static void add_ap_files(struct ieee80211_sub_if_data *sdata)
271{ 269{
272 DEBUGFS_ADD(channel_use, ap);
273 DEBUGFS_ADD(drop_unencrypted, ap); 270 DEBUGFS_ADD(drop_unencrypted, ap);
274 DEBUGFS_ADD(num_sta_ps, ap); 271 DEBUGFS_ADD(num_sta_ps, ap);
275 DEBUGFS_ADD(dtim_count, ap); 272 DEBUGFS_ADD(dtim_count, ap);
@@ -281,14 +278,12 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
281 278
282static void add_wds_files(struct ieee80211_sub_if_data *sdata) 279static void add_wds_files(struct ieee80211_sub_if_data *sdata)
283{ 280{
284 DEBUGFS_ADD(channel_use, wds);
285 DEBUGFS_ADD(drop_unencrypted, wds); 281 DEBUGFS_ADD(drop_unencrypted, wds);
286 DEBUGFS_ADD(peer, wds); 282 DEBUGFS_ADD(peer, wds);
287} 283}
288 284
289static void add_vlan_files(struct ieee80211_sub_if_data *sdata) 285static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
290{ 286{
291 DEBUGFS_ADD(channel_use, vlan);
292 DEBUGFS_ADD(drop_unencrypted, vlan); 287 DEBUGFS_ADD(drop_unencrypted, vlan);
293} 288}
294 289
@@ -376,7 +371,6 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
376 371
377static void del_sta_files(struct ieee80211_sub_if_data *sdata) 372static void del_sta_files(struct ieee80211_sub_if_data *sdata)
378{ 373{
379 DEBUGFS_DEL(channel_use, sta);
380 DEBUGFS_DEL(drop_unencrypted, sta); 374 DEBUGFS_DEL(drop_unencrypted, sta);
381 DEBUGFS_DEL(state, sta); 375 DEBUGFS_DEL(state, sta);
382 DEBUGFS_DEL(bssid, sta); 376 DEBUGFS_DEL(bssid, sta);
@@ -397,7 +391,6 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata)
397 391
398static void del_ap_files(struct ieee80211_sub_if_data *sdata) 392static void del_ap_files(struct ieee80211_sub_if_data *sdata)
399{ 393{
400 DEBUGFS_DEL(channel_use, ap);
401 DEBUGFS_DEL(drop_unencrypted, ap); 394 DEBUGFS_DEL(drop_unencrypted, ap);
402 DEBUGFS_DEL(num_sta_ps, ap); 395 DEBUGFS_DEL(num_sta_ps, ap);
403 DEBUGFS_DEL(dtim_count, ap); 396 DEBUGFS_DEL(dtim_count, ap);
@@ -409,14 +402,12 @@ static void del_ap_files(struct ieee80211_sub_if_data *sdata)
409 402
410static void del_wds_files(struct ieee80211_sub_if_data *sdata) 403static void del_wds_files(struct ieee80211_sub_if_data *sdata)
411{ 404{
412 DEBUGFS_DEL(channel_use, wds);
413 DEBUGFS_DEL(drop_unencrypted, wds); 405 DEBUGFS_DEL(drop_unencrypted, wds);
414 DEBUGFS_DEL(peer, wds); 406 DEBUGFS_DEL(peer, wds);
415} 407}
416 408
417static void del_vlan_files(struct ieee80211_sub_if_data *sdata) 409static void del_vlan_files(struct ieee80211_sub_if_data *sdata)
418{ 410{
419 DEBUGFS_DEL(channel_use, vlan);
420 DEBUGFS_DEL(drop_unencrypted, vlan); 411 DEBUGFS_DEL(drop_unencrypted, vlan);
421} 412}
422 413
@@ -528,7 +519,7 @@ void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata,
528 add_files(sdata); 519 add_files(sdata);
529} 520}
530 521
531static int netdev_notify(struct notifier_block * nb, 522static int netdev_notify(struct notifier_block *nb,
532 unsigned long state, 523 unsigned long state,
533 void *ndev) 524 void *ndev)
534{ 525{
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 6d47a1d31b37..79a062782d52 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -63,10 +63,9 @@ STA_FILE(tx_fragments, tx_fragments, LU);
63STA_FILE(tx_filtered, tx_filtered_count, LU); 63STA_FILE(tx_filtered, tx_filtered_count, LU);
64STA_FILE(tx_retry_failed, tx_retry_failed, LU); 64STA_FILE(tx_retry_failed, tx_retry_failed, LU);
65STA_FILE(tx_retry_count, tx_retry_count, LU); 65STA_FILE(tx_retry_count, tx_retry_count, LU);
66STA_FILE(last_rssi, last_rssi, D);
67STA_FILE(last_signal, last_signal, D); 66STA_FILE(last_signal, last_signal, D);
67STA_FILE(last_qual, last_qual, D);
68STA_FILE(last_noise, last_noise, D); 68STA_FILE(last_noise, last_noise, D);
69STA_FILE(channel_use, channel_use, D);
70STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); 69STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU);
71 70
72static ssize_t sta_flags_read(struct file *file, char __user *userbuf, 71static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
@@ -74,14 +73,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
74{ 73{
75 char buf[100]; 74 char buf[100];
76 struct sta_info *sta = file->private_data; 75 struct sta_info *sta = file->private_data;
76 u32 staflags = get_sta_flags(sta);
77 int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", 77 int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s",
78 sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", 78 staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
79 sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", 79 staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
80 sta->flags & WLAN_STA_PS ? "PS\n" : "", 80 staflags & WLAN_STA_PS ? "PS\n" : "",
81 sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", 81 staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
82 sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", 82 staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
83 sta->flags & WLAN_STA_WME ? "WME\n" : "", 83 staflags & WLAN_STA_WME ? "WME\n" : "",
84 sta->flags & WLAN_STA_WDS ? "WDS\n" : ""); 84 staflags & WLAN_STA_WDS ? "WDS\n" : "");
85 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 85 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
86} 86}
87STA_OPS(flags); 87STA_OPS(flags);
@@ -123,36 +123,6 @@ static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
123} 123}
124STA_OPS(last_seq_ctrl); 124STA_OPS(last_seq_ctrl);
125 125
126#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
127static ssize_t sta_wme_rx_queue_read(struct file *file, char __user *userbuf,
128 size_t count, loff_t *ppos)
129{
130 char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
131 int i;
132 struct sta_info *sta = file->private_data;
133 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
134 p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
135 sta->wme_rx_queue[i]);
136 p += scnprintf(p, sizeof(buf)+buf-p, "\n");
137 return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
138}
139STA_OPS(wme_rx_queue);
140
141static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf,
142 size_t count, loff_t *ppos)
143{
144 char buf[15*NUM_TX_DATA_QUEUES], *p = buf;
145 int i;
146 struct sta_info *sta = file->private_data;
147 for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
148 p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
149 sta->wme_tx_queue[i]);
150 p += scnprintf(p, sizeof(buf)+buf-p, "\n");
151 return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
152}
153STA_OPS(wme_tx_queue);
154#endif
155
156static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, 126static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
157 size_t count, loff_t *ppos) 127 size_t count, loff_t *ppos)
158{ 128{
@@ -293,10 +263,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
293 DEBUGFS_ADD(num_ps_buf_frames); 263 DEBUGFS_ADD(num_ps_buf_frames);
294 DEBUGFS_ADD(inactive_ms); 264 DEBUGFS_ADD(inactive_ms);
295 DEBUGFS_ADD(last_seq_ctrl); 265 DEBUGFS_ADD(last_seq_ctrl);
296#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
297 DEBUGFS_ADD(wme_rx_queue);
298 DEBUGFS_ADD(wme_tx_queue);
299#endif
300 DEBUGFS_ADD(agg_status); 266 DEBUGFS_ADD(agg_status);
301} 267}
302 268
@@ -306,10 +272,6 @@ void ieee80211_sta_debugfs_remove(struct sta_info *sta)
306 DEBUGFS_DEL(num_ps_buf_frames); 272 DEBUGFS_DEL(num_ps_buf_frames);
307 DEBUGFS_DEL(inactive_ms); 273 DEBUGFS_DEL(inactive_ms);
308 DEBUGFS_DEL(last_seq_ctrl); 274 DEBUGFS_DEL(last_seq_ctrl);
309#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
310 DEBUGFS_DEL(wme_rx_queue);
311 DEBUGFS_DEL(wme_tx_queue);
312#endif
313 DEBUGFS_DEL(agg_status); 275 DEBUGFS_DEL(agg_status);
314 276
315 debugfs_remove(sta->debugfs.dir); 277 debugfs_remove(sta->debugfs.dir);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 006486b26726..b19bd16703b2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2,6 +2,7 @@
2 * Copyright 2002-2005, Instant802 Networks, Inc. 2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005, Devicescape Software, Inc. 3 * Copyright 2005, Devicescape Software, Inc.
4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
5 * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -82,7 +83,7 @@ struct ieee80211_sta_bss {
82 u16 capability; /* host byte order */ 83 u16 capability; /* host byte order */
83 enum ieee80211_band band; 84 enum ieee80211_band band;
84 int freq; 85 int freq;
85 int rssi, signal, noise; 86 int signal, noise, qual;
86 u8 *wpa_ie; 87 u8 *wpa_ie;
87 size_t wpa_ie_len; 88 size_t wpa_ie_len;
88 u8 *rsn_ie; 89 u8 *rsn_ie;
@@ -91,6 +92,8 @@ struct ieee80211_sta_bss {
91 size_t wmm_ie_len; 92 size_t wmm_ie_len;
92 u8 *ht_ie; 93 u8 *ht_ie;
93 size_t ht_ie_len; 94 size_t ht_ie_len;
95 u8 *ht_add_ie;
96 size_t ht_add_ie_len;
94#ifdef CONFIG_MAC80211_MESH 97#ifdef CONFIG_MAC80211_MESH
95 u8 *mesh_id; 98 u8 *mesh_id;
96 size_t mesh_id_len; 99 size_t mesh_id_len;
@@ -147,7 +150,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result;
147#define IEEE80211_TX_UNICAST BIT(1) 150#define IEEE80211_TX_UNICAST BIT(1)
148#define IEEE80211_TX_PS_BUFFERED BIT(2) 151#define IEEE80211_TX_PS_BUFFERED BIT(2)
149#define IEEE80211_TX_PROBE_LAST_FRAG BIT(3) 152#define IEEE80211_TX_PROBE_LAST_FRAG BIT(3)
150#define IEEE80211_TX_INJECTED BIT(4)
151 153
152struct ieee80211_tx_data { 154struct ieee80211_tx_data {
153 struct sk_buff *skb; 155 struct sk_buff *skb;
@@ -157,13 +159,12 @@ struct ieee80211_tx_data {
157 struct sta_info *sta; 159 struct sta_info *sta;
158 struct ieee80211_key *key; 160 struct ieee80211_key *key;
159 161
160 struct ieee80211_tx_control *control;
161 struct ieee80211_channel *channel; 162 struct ieee80211_channel *channel;
162 struct ieee80211_rate *rate; 163 s8 rate_idx;
163 /* use this rate (if set) for last fragment; rate can 164 /* use this rate (if set) for last fragment; rate can
164 * be set to lower rate for the first fragments, e.g., 165 * be set to lower rate for the first fragments, e.g.,
165 * when using CTS protection with IEEE 802.11g. */ 166 * when using CTS protection with IEEE 802.11g. */
166 struct ieee80211_rate *last_frag_rate; 167 s8 last_frag_rate_idx;
167 168
168 /* Extra fragments (in addition to the first fragment 169 /* Extra fragments (in addition to the first fragment
169 * in skb) */ 170 * in skb) */
@@ -202,32 +203,16 @@ struct ieee80211_rx_data {
202 unsigned int flags; 203 unsigned int flags;
203 int sent_ps_buffered; 204 int sent_ps_buffered;
204 int queue; 205 int queue;
205 int load;
206 u32 tkip_iv32; 206 u32 tkip_iv32;
207 u16 tkip_iv16; 207 u16 tkip_iv16;
208}; 208};
209 209
210/* flags used in struct ieee80211_tx_packet_data.flags */
211#define IEEE80211_TXPD_REQ_TX_STATUS BIT(0)
212#define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1)
213#define IEEE80211_TXPD_REQUEUE BIT(2)
214#define IEEE80211_TXPD_EAPOL_FRAME BIT(3)
215#define IEEE80211_TXPD_AMPDU BIT(4)
216/* Stored in sk_buff->cb */
217struct ieee80211_tx_packet_data {
218 int ifindex;
219 unsigned long jiffies;
220 unsigned int flags;
221 u8 queue;
222};
223
224struct ieee80211_tx_stored_packet { 210struct ieee80211_tx_stored_packet {
225 struct ieee80211_tx_control control;
226 struct sk_buff *skb; 211 struct sk_buff *skb;
227 struct sk_buff **extra_frag; 212 struct sk_buff **extra_frag;
228 struct ieee80211_rate *last_frag_rate; 213 s8 last_frag_rate_idx;
229 int num_extra_frag; 214 int num_extra_frag;
230 unsigned int last_frag_rate_ctrl_probe; 215 bool last_frag_rate_ctrl_probe;
231}; 216};
232 217
233struct beacon_data { 218struct beacon_data {
@@ -464,14 +449,11 @@ struct ieee80211_sub_if_data {
464 struct ieee80211_if_sta sta; 449 struct ieee80211_if_sta sta;
465 u32 mntr_flags; 450 u32 mntr_flags;
466 } u; 451 } u;
467 int channel_use;
468 int channel_use_raw;
469 452
470#ifdef CONFIG_MAC80211_DEBUGFS 453#ifdef CONFIG_MAC80211_DEBUGFS
471 struct dentry *debugfsdir; 454 struct dentry *debugfsdir;
472 union { 455 union {
473 struct { 456 struct {
474 struct dentry *channel_use;
475 struct dentry *drop_unencrypted; 457 struct dentry *drop_unencrypted;
476 struct dentry *state; 458 struct dentry *state;
477 struct dentry *bssid; 459 struct dentry *bssid;
@@ -490,7 +472,6 @@ struct ieee80211_sub_if_data {
490 struct dentry *num_beacons_sta; 472 struct dentry *num_beacons_sta;
491 } sta; 473 } sta;
492 struct { 474 struct {
493 struct dentry *channel_use;
494 struct dentry *drop_unencrypted; 475 struct dentry *drop_unencrypted;
495 struct dentry *num_sta_ps; 476 struct dentry *num_sta_ps;
496 struct dentry *dtim_count; 477 struct dentry *dtim_count;
@@ -500,12 +481,10 @@ struct ieee80211_sub_if_data {
500 struct dentry *num_buffered_multicast; 481 struct dentry *num_buffered_multicast;
501 } ap; 482 } ap;
502 struct { 483 struct {
503 struct dentry *channel_use;
504 struct dentry *drop_unencrypted; 484 struct dentry *drop_unencrypted;
505 struct dentry *peer; 485 struct dentry *peer;
506 } wds; 486 } wds;
507 struct { 487 struct {
508 struct dentry *channel_use;
509 struct dentry *drop_unencrypted; 488 struct dentry *drop_unencrypted;
510 } vlan; 489 } vlan;
511 struct { 490 struct {
@@ -610,8 +589,8 @@ struct ieee80211_local {
610 struct sta_info *sta_hash[STA_HASH_SIZE]; 589 struct sta_info *sta_hash[STA_HASH_SIZE];
611 struct timer_list sta_cleanup; 590 struct timer_list sta_cleanup;
612 591
613 unsigned long state[NUM_TX_DATA_QUEUES_AMPDU]; 592 unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
614 struct ieee80211_tx_stored_packet pending_packet[NUM_TX_DATA_QUEUES_AMPDU]; 593 struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES];
615 struct tasklet_struct tx_pending_tasklet; 594 struct tasklet_struct tx_pending_tasklet;
616 595
617 /* number of interfaces with corresponding IFF_ flags */ 596 /* number of interfaces with corresponding IFF_ flags */
@@ -677,9 +656,6 @@ struct ieee80211_local {
677 assoc_led_name[32], radio_led_name[32]; 656 assoc_led_name[32], radio_led_name[32];
678#endif 657#endif
679 658
680 u32 channel_use;
681 u32 channel_use_raw;
682
683#ifdef CONFIG_MAC80211_DEBUGFS 659#ifdef CONFIG_MAC80211_DEBUGFS
684 struct work_struct sta_debugfs_add; 660 struct work_struct sta_debugfs_add;
685#endif 661#endif
@@ -705,8 +681,6 @@ struct ieee80211_local {
705 unsigned int rx_expand_skb_head2; 681 unsigned int rx_expand_skb_head2;
706 unsigned int rx_handlers_fragments; 682 unsigned int rx_handlers_fragments;
707 unsigned int tx_status_drop; 683 unsigned int tx_status_drop;
708 unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES];
709 unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES];
710#define I802_DEBUG_INC(c) (c)++ 684#define I802_DEBUG_INC(c) (c)++
711#else /* CONFIG_MAC80211_DEBUG_COUNTERS */ 685#else /* CONFIG_MAC80211_DEBUG_COUNTERS */
712#define I802_DEBUG_INC(c) do { } while (0) 686#define I802_DEBUG_INC(c) do { } while (0)
@@ -764,8 +738,6 @@ struct ieee80211_local {
764 struct dentry *rx_expand_skb_head2; 738 struct dentry *rx_expand_skb_head2;
765 struct dentry *rx_handlers_fragments; 739 struct dentry *rx_handlers_fragments;
766 struct dentry *tx_status_drop; 740 struct dentry *tx_status_drop;
767 struct dentry *wme_tx_queue;
768 struct dentry *wme_rx_queue;
769#endif 741#endif
770 struct dentry *dot11ACKFailureCount; 742 struct dentry *dot11ACKFailureCount;
771 struct dentry *dot11RTSFailureCount; 743 struct dentry *dot11RTSFailureCount;
@@ -778,6 +750,15 @@ struct ieee80211_local {
778#endif 750#endif
779}; 751};
780 752
753static inline int ieee80211_is_multiqueue(struct ieee80211_local *local)
754{
755#ifdef CONFIG_MAC80211_QOS
756 return netif_is_multiqueue(local->mdev);
757#else
758 return 0;
759#endif
760}
761
781/* this struct represents 802.11n's RA/TID combination */ 762/* this struct represents 802.11n's RA/TID combination */
782struct ieee80211_ra_tid { 763struct ieee80211_ra_tid {
783 u8 ra[ETH_ALEN]; 764 u8 ra[ETH_ALEN];
@@ -847,11 +828,6 @@ static inline struct ieee80211_hw *local_to_hw(
847 return &local->hw; 828 return &local->hw;
848} 829}
849 830
850enum ieee80211_link_state_t {
851 IEEE80211_LINK_STATE_XOFF = 0,
852 IEEE80211_LINK_STATE_PENDING,
853};
854
855struct sta_attribute { 831struct sta_attribute {
856 struct attribute attr; 832 struct attribute attr;
857 ssize_t (*show)(const struct sta_info *, char *buf); 833 ssize_t (*show)(const struct sta_info *, char *buf);
@@ -877,29 +853,8 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
877 853
878/* ieee80211_ioctl.c */ 854/* ieee80211_ioctl.c */
879extern const struct iw_handler_def ieee80211_iw_handler_def; 855extern const struct iw_handler_def ieee80211_iw_handler_def;
880
881
882/* Least common multiple of the used rates (in 100 kbps). This is used to
883 * calculate rate_inv values for each rate so that only integers are needed. */
884#define CHAN_UTIL_RATE_LCM 95040
885/* 1 usec is 1/8 * (95040/10) = 1188 */
886#define CHAN_UTIL_PER_USEC 1188
887/* Amount of bits to shift the result right to scale the total utilization
888 * to values that will not wrap around 32-bit integers. */
889#define CHAN_UTIL_SHIFT 9
890/* Theoretical maximum of channel utilization counter in 10 ms (stat_time=1):
891 * (CHAN_UTIL_PER_USEC * 10000) >> CHAN_UTIL_SHIFT = 23203. So dividing the
892 * raw value with about 23 should give utilization in 10th of a percentage
893 * (1/1000). However, utilization is only estimated and not all intervals
894 * between frames etc. are calculated. 18 seems to give numbers that are closer
895 * to the real maximum. */
896#define CHAN_UTIL_PER_10MS 18
897#define CHAN_UTIL_HDR_LONG (202 * CHAN_UTIL_PER_USEC)
898#define CHAN_UTIL_HDR_SHORT (40 * CHAN_UTIL_PER_USEC)
899
900
901/* ieee80211_ioctl.c */
902int ieee80211_set_freq(struct net_device *dev, int freq); 856int ieee80211_set_freq(struct net_device *dev, int freq);
857
903/* ieee80211_sta.c */ 858/* ieee80211_sta.c */
904void ieee80211_sta_timer(unsigned long data); 859void ieee80211_sta_timer(unsigned long data);
905void ieee80211_sta_work(struct work_struct *work); 860void ieee80211_sta_work(struct work_struct *work);
@@ -919,9 +874,9 @@ ieee80211_rx_result ieee80211_sta_rx_scan(
919void ieee80211_rx_bss_list_init(struct net_device *dev); 874void ieee80211_rx_bss_list_init(struct net_device *dev);
920void ieee80211_rx_bss_list_deinit(struct net_device *dev); 875void ieee80211_rx_bss_list_deinit(struct net_device *dev);
921int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); 876int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len);
922struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, 877struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev,
923 struct sk_buff *skb, u8 *bssid, 878 struct sk_buff *skb, u8 *bssid,
924 u8 *addr); 879 u8 *addr);
925int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); 880int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason);
926int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); 881int ieee80211_sta_disassociate(struct net_device *dev, u16 reason);
927void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 882void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
@@ -940,7 +895,6 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
940 895
941void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da, 896void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da,
942 u16 tid, u16 initiator, u16 reason); 897 u16 tid, u16 initiator, u16 reason);
943void sta_rx_agg_session_timer_expired(unsigned long data);
944void sta_addba_resp_timer_expired(unsigned long data); 898void sta_addba_resp_timer_expired(unsigned long data);
945void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr); 899void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr);
946u64 ieee80211_sta_get_rates(struct ieee80211_local *local, 900u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 06e88a5a036d..984472702381 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -33,9 +33,8 @@ static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata)
33{ 33{
34 int i; 34 int i;
35 35
36 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { 36 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
37 __skb_queue_purge(&sdata->fragments[i].skb_list); 37 __skb_queue_purge(&sdata->fragments[i].skb_list);
38 }
39} 38}
40 39
41/* Must be called with rtnl lock held. */ 40/* Must be called with rtnl lock held. */
@@ -167,9 +166,10 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
167 ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | 166 ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
168 IEEE80211_AUTH_ALG_SHARED_KEY; 167 IEEE80211_AUTH_ALG_SHARED_KEY;
169 ifsta->flags |= IEEE80211_STA_CREATE_IBSS | 168 ifsta->flags |= IEEE80211_STA_CREATE_IBSS |
170 IEEE80211_STA_WMM_ENABLED |
171 IEEE80211_STA_AUTO_BSSID_SEL | 169 IEEE80211_STA_AUTO_BSSID_SEL |
172 IEEE80211_STA_AUTO_CHANNEL_SEL; 170 IEEE80211_STA_AUTO_CHANNEL_SEL;
171 if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4)
172 ifsta->flags |= IEEE80211_STA_WMM_ENABLED;
173 173
174 msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); 174 msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev);
175 sdata->bss = &msdata->u.ap; 175 sdata->bss = &msdata->u.ap;
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 150d66dbda9d..d4893bd17754 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -321,8 +321,15 @@ void ieee80211_key_link(struct ieee80211_key *key,
321 * some hardware cannot handle TKIP with QoS, so 321 * some hardware cannot handle TKIP with QoS, so
322 * we indicate whether QoS could be in use. 322 * we indicate whether QoS could be in use.
323 */ 323 */
324 if (sta->flags & WLAN_STA_WME) 324 if (test_sta_flags(sta, WLAN_STA_WME))
325 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; 325 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
326
327 /*
328 * This key is for a specific sta interface,
329 * inform the driver that it should try to store
330 * this key as pairwise key.
331 */
332 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
326 } else { 333 } else {
327 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { 334 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) {
328 struct sta_info *ap; 335 struct sta_info *ap;
@@ -335,7 +342,7 @@ void ieee80211_key_link(struct ieee80211_key *key,
335 /* same here, the AP could be using QoS */ 342 /* same here, the AP could be using QoS */
336 ap = sta_info_get(key->local, key->sdata->u.sta.bssid); 343 ap = sta_info_get(key->local, key->sdata->u.sta.bssid);
337 if (ap) { 344 if (ap) {
338 if (ap->flags & WLAN_STA_WME) 345 if (test_sta_flags(ap, WLAN_STA_WME))
339 key->conf.flags |= 346 key->conf.flags |=
340 IEEE80211_KEY_FLAG_WMM_STA; 347 IEEE80211_KEY_FLAG_WMM_STA;
341 } 348 }
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index f52c3df1fe9a..a0f774aafa45 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -69,6 +69,13 @@ enum ieee80211_internal_key_flags {
69 KEY_FLAG_TODO_ADD_DEBUGFS = BIT(5), 69 KEY_FLAG_TODO_ADD_DEBUGFS = BIT(5),
70}; 70};
71 71
72struct tkip_ctx {
73 u32 iv32;
74 u16 iv16;
75 u16 p1k[5];
76 int initialized;
77};
78
72struct ieee80211_key { 79struct ieee80211_key {
73 struct ieee80211_local *local; 80 struct ieee80211_local *local;
74 struct ieee80211_sub_if_data *sdata; 81 struct ieee80211_sub_if_data *sdata;
@@ -85,16 +92,10 @@ struct ieee80211_key {
85 union { 92 union {
86 struct { 93 struct {
87 /* last used TSC */ 94 /* last used TSC */
88 u32 iv32; 95 struct tkip_ctx tx;
89 u16 iv16;
90 u16 p1k[5];
91 int tx_initialized;
92 96
93 /* last received RSC */ 97 /* last received RSC */
94 u32 iv32_rx[NUM_RX_DATA_QUEUES]; 98 struct tkip_ctx rx[NUM_RX_DATA_QUEUES];
95 u16 iv16_rx[NUM_RX_DATA_QUEUES];
96 u16 p1k_rx[NUM_RX_DATA_QUEUES][5];
97 int rx_initialized[NUM_RX_DATA_QUEUES];
98 } tkip; 99 } tkip;
99 struct { 100 struct {
100 u8 tx_pn[6]; 101 u8 tx_pn[6];
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 98c0b5e56ecc..b182f018a187 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -35,8 +35,6 @@
35#include "debugfs.h" 35#include "debugfs.h"
36#include "debugfs_netdev.h" 36#include "debugfs_netdev.h"
37 37
38#define SUPP_MCS_SET_LEN 16
39
40/* 38/*
41 * For seeing transmitted packets on monitor interfaces 39 * For seeing transmitted packets on monitor interfaces
42 * we have a radiotap header too. 40 * we have a radiotap header too.
@@ -112,7 +110,13 @@ static int ieee80211_master_open(struct net_device *dev)
112 break; 110 break;
113 } 111 }
114 } 112 }
115 return res; 113
114 if (res)
115 return res;
116
117 netif_start_queue(local->mdev);
118
119 return 0;
116} 120}
117 121
118static int ieee80211_master_stop(struct net_device *dev) 122static int ieee80211_master_stop(struct net_device *dev)
@@ -346,6 +350,7 @@ static int ieee80211_open(struct net_device *dev)
346 goto err_del_interface; 350 goto err_del_interface;
347 } 351 }
348 352
353 /* no locking required since STA is not live yet */
349 sta->flags |= WLAN_STA_AUTHORIZED; 354 sta->flags |= WLAN_STA_AUTHORIZED;
350 355
351 res = sta_info_insert(sta); 356 res = sta_info_insert(sta);
@@ -385,8 +390,8 @@ static int ieee80211_open(struct net_device *dev)
385 * yet be effective. Trigger execution of ieee80211_sta_work 390 * yet be effective. Trigger execution of ieee80211_sta_work
386 * to fix this. 391 * to fix this.
387 */ 392 */
388 if(sdata->vif.type == IEEE80211_IF_TYPE_STA || 393 if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
389 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 394 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
390 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 395 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
391 queue_work(local->hw.workqueue, &ifsta->work); 396 queue_work(local->hw.workqueue, &ifsta->work);
392 } 397 }
@@ -585,16 +590,16 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
585 sta = sta_info_get(local, ra); 590 sta = sta_info_get(local, ra);
586 if (!sta) { 591 if (!sta) {
587 printk(KERN_DEBUG "Could not find the station\n"); 592 printk(KERN_DEBUG "Could not find the station\n");
588 rcu_read_unlock(); 593 ret = -ENOENT;
589 return -ENOENT; 594 goto exit;
590 } 595 }
591 596
592 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 597 spin_lock_bh(&sta->lock);
593 598
594 /* we have tried too many times, receiver does not want A-MPDU */ 599 /* we have tried too many times, receiver does not want A-MPDU */
595 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { 600 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
596 ret = -EBUSY; 601 ret = -EBUSY;
597 goto start_ba_exit; 602 goto err_unlock_sta;
598 } 603 }
599 604
600 state = &sta->ampdu_mlme.tid_state_tx[tid]; 605 state = &sta->ampdu_mlme.tid_state_tx[tid];
@@ -605,7 +610,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
605 "idle on tid %u\n", tid); 610 "idle on tid %u\n", tid);
606#endif /* CONFIG_MAC80211_HT_DEBUG */ 611#endif /* CONFIG_MAC80211_HT_DEBUG */
607 ret = -EAGAIN; 612 ret = -EAGAIN;
608 goto start_ba_exit; 613 goto err_unlock_sta;
609 } 614 }
610 615
611 /* prepare A-MPDU MLME for Tx aggregation */ 616 /* prepare A-MPDU MLME for Tx aggregation */
@@ -616,7 +621,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
616 printk(KERN_ERR "allocate tx mlme to tid %d failed\n", 621 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
617 tid); 622 tid);
618 ret = -ENOMEM; 623 ret = -ENOMEM;
619 goto start_ba_exit; 624 goto err_unlock_sta;
620 } 625 }
621 /* Tx timer */ 626 /* Tx timer */
622 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = 627 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
@@ -639,7 +644,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
639 printk(KERN_DEBUG "BA request denied - queue unavailable for" 644 printk(KERN_DEBUG "BA request denied - queue unavailable for"
640 " tid %d\n", tid); 645 " tid %d\n", tid);
641#endif /* CONFIG_MAC80211_HT_DEBUG */ 646#endif /* CONFIG_MAC80211_HT_DEBUG */
642 goto start_ba_err; 647 goto err_unlock_queue;
643 } 648 }
644 sdata = sta->sdata; 649 sdata = sta->sdata;
645 650
@@ -661,12 +666,13 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
661 " tid %d\n", tid); 666 " tid %d\n", tid);
662#endif /* CONFIG_MAC80211_HT_DEBUG */ 667#endif /* CONFIG_MAC80211_HT_DEBUG */
663 *state = HT_AGG_STATE_IDLE; 668 *state = HT_AGG_STATE_IDLE;
664 goto start_ba_err; 669 goto err_unlock_queue;
665 } 670 }
666 671
667 /* Will put all the packets in the new SW queue */ 672 /* Will put all the packets in the new SW queue */
668 ieee80211_requeue(local, ieee802_1d_to_ac[tid]); 673 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
669 spin_unlock_bh(&local->mdev->queue_lock); 674 spin_unlock_bh(&local->mdev->queue_lock);
675 spin_unlock_bh(&sta->lock);
670 676
671 /* send an addBA request */ 677 /* send an addBA request */
672 sta->ampdu_mlme.dialog_token_allocator++; 678 sta->ampdu_mlme.dialog_token_allocator++;
@@ -674,25 +680,26 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
674 sta->ampdu_mlme.dialog_token_allocator; 680 sta->ampdu_mlme.dialog_token_allocator;
675 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; 681 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
676 682
683
677 ieee80211_send_addba_request(sta->sdata->dev, ra, tid, 684 ieee80211_send_addba_request(sta->sdata->dev, ra, tid,
678 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 685 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
679 sta->ampdu_mlme.tid_tx[tid]->ssn, 686 sta->ampdu_mlme.tid_tx[tid]->ssn,
680 0x40, 5000); 687 0x40, 5000);
681
682 /* activate the timer for the recipient's addBA response */ 688 /* activate the timer for the recipient's addBA response */
683 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = 689 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
684 jiffies + ADDBA_RESP_INTERVAL; 690 jiffies + ADDBA_RESP_INTERVAL;
685 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 691 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
686 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); 692 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
687 goto start_ba_exit; 693 goto exit;
688 694
689start_ba_err: 695err_unlock_queue:
690 kfree(sta->ampdu_mlme.tid_tx[tid]); 696 kfree(sta->ampdu_mlme.tid_tx[tid]);
691 sta->ampdu_mlme.tid_tx[tid] = NULL; 697 sta->ampdu_mlme.tid_tx[tid] = NULL;
692 spin_unlock_bh(&local->mdev->queue_lock); 698 spin_unlock_bh(&local->mdev->queue_lock);
693 ret = -EBUSY; 699 ret = -EBUSY;
694start_ba_exit: 700err_unlock_sta:
695 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 701 spin_unlock_bh(&sta->lock);
702exit:
696 rcu_read_unlock(); 703 rcu_read_unlock();
697 return ret; 704 return ret;
698} 705}
@@ -720,7 +727,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
720 727
721 /* check if the TID is in aggregation */ 728 /* check if the TID is in aggregation */
722 state = &sta->ampdu_mlme.tid_state_tx[tid]; 729 state = &sta->ampdu_mlme.tid_state_tx[tid];
723 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 730 spin_lock_bh(&sta->lock);
724 731
725 if (*state != HT_AGG_STATE_OPERATIONAL) { 732 if (*state != HT_AGG_STATE_OPERATIONAL) {
726 ret = -ENOENT; 733 ret = -ENOENT;
@@ -750,7 +757,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
750 } 757 }
751 758
752stop_BA_exit: 759stop_BA_exit:
753 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 760 spin_unlock_bh(&sta->lock);
754 rcu_read_unlock(); 761 rcu_read_unlock();
755 return ret; 762 return ret;
756} 763}
@@ -779,12 +786,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
779 } 786 }
780 787
781 state = &sta->ampdu_mlme.tid_state_tx[tid]; 788 state = &sta->ampdu_mlme.tid_state_tx[tid];
782 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 789 spin_lock_bh(&sta->lock);
783 790
784 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 791 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
785 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", 792 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
786 *state); 793 *state);
787 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 794 spin_unlock_bh(&sta->lock);
788 rcu_read_unlock(); 795 rcu_read_unlock();
789 return; 796 return;
790 } 797 }
@@ -797,7 +804,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
797 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); 804 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
798 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 805 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
799 } 806 }
800 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 807 spin_unlock_bh(&sta->lock);
801 rcu_read_unlock(); 808 rcu_read_unlock();
802} 809}
803EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); 810EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
@@ -831,10 +838,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
831 } 838 }
832 state = &sta->ampdu_mlme.tid_state_tx[tid]; 839 state = &sta->ampdu_mlme.tid_state_tx[tid];
833 840
834 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 841 /* NOTE: no need to use sta->lock in this state check, as
842 * ieee80211_stop_tx_ba_session will let only
843 * one stop call to pass through per sta/tid */
835 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { 844 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
836 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); 845 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
837 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
838 rcu_read_unlock(); 846 rcu_read_unlock();
839 return; 847 return;
840 } 848 }
@@ -857,11 +865,12 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
857 * ieee80211_wake_queue is not used here as this queue is not 865 * ieee80211_wake_queue is not used here as this queue is not
858 * necessarily stopped */ 866 * necessarily stopped */
859 netif_schedule(local->mdev); 867 netif_schedule(local->mdev);
868 spin_lock_bh(&sta->lock);
860 *state = HT_AGG_STATE_IDLE; 869 *state = HT_AGG_STATE_IDLE;
861 sta->ampdu_mlme.addba_req_num[tid] = 0; 870 sta->ampdu_mlme.addba_req_num[tid] = 0;
862 kfree(sta->ampdu_mlme.tid_tx[tid]); 871 kfree(sta->ampdu_mlme.tid_tx[tid]);
863 sta->ampdu_mlme.tid_tx[tid] = NULL; 872 sta->ampdu_mlme.tid_tx[tid] = NULL;
864 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 873 spin_unlock_bh(&sta->lock);
865 874
866 rcu_read_unlock(); 875 rcu_read_unlock();
867} 876}
@@ -967,8 +976,7 @@ void ieee80211_if_setup(struct net_device *dev)
967/* everything else */ 976/* everything else */
968 977
969static int __ieee80211_if_config(struct net_device *dev, 978static int __ieee80211_if_config(struct net_device *dev,
970 struct sk_buff *beacon, 979 struct sk_buff *beacon)
971 struct ieee80211_tx_control *control)
972{ 980{
973 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 981 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
974 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 982 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
@@ -986,13 +994,11 @@ static int __ieee80211_if_config(struct net_device *dev,
986 conf.ssid_len = sdata->u.sta.ssid_len; 994 conf.ssid_len = sdata->u.sta.ssid_len;
987 } else if (ieee80211_vif_is_mesh(&sdata->vif)) { 995 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
988 conf.beacon = beacon; 996 conf.beacon = beacon;
989 conf.beacon_control = control;
990 ieee80211_start_mesh(dev); 997 ieee80211_start_mesh(dev);
991 } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { 998 } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
992 conf.ssid = sdata->u.ap.ssid; 999 conf.ssid = sdata->u.ap.ssid;
993 conf.ssid_len = sdata->u.ap.ssid_len; 1000 conf.ssid_len = sdata->u.ap.ssid_len;
994 conf.beacon = beacon; 1001 conf.beacon = beacon;
995 conf.beacon_control = control;
996 } 1002 }
997 return local->ops->config_interface(local_to_hw(local), 1003 return local->ops->config_interface(local_to_hw(local),
998 &sdata->vif, &conf); 1004 &sdata->vif, &conf);
@@ -1005,23 +1011,21 @@ int ieee80211_if_config(struct net_device *dev)
1005 if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && 1011 if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT &&
1006 (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) 1012 (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
1007 return ieee80211_if_config_beacon(dev); 1013 return ieee80211_if_config_beacon(dev);
1008 return __ieee80211_if_config(dev, NULL, NULL); 1014 return __ieee80211_if_config(dev, NULL);
1009} 1015}
1010 1016
1011int ieee80211_if_config_beacon(struct net_device *dev) 1017int ieee80211_if_config_beacon(struct net_device *dev)
1012{ 1018{
1013 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1019 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1014 struct ieee80211_tx_control control;
1015 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1020 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1016 struct sk_buff *skb; 1021 struct sk_buff *skb;
1017 1022
1018 if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) 1023 if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
1019 return 0; 1024 return 0;
1020 skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif, 1025 skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif);
1021 &control);
1022 if (!skb) 1026 if (!skb)
1023 return -ENOMEM; 1027 return -ENOMEM;
1024 return __ieee80211_if_config(dev, skb, &control); 1028 return __ieee80211_if_config(dev, skb);
1025} 1029}
1026 1030
1027int ieee80211_hw_config(struct ieee80211_local *local) 1031int ieee80211_hw_config(struct ieee80211_local *local)
@@ -1068,56 +1072,84 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
1068 struct ieee80211_supported_band *sband; 1072 struct ieee80211_supported_band *sband;
1069 struct ieee80211_ht_info ht_conf; 1073 struct ieee80211_ht_info ht_conf;
1070 struct ieee80211_ht_bss_info ht_bss_conf; 1074 struct ieee80211_ht_bss_info ht_bss_conf;
1071 int i;
1072 u32 changed = 0; 1075 u32 changed = 0;
1076 int i;
1077 u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS;
1078 u8 tx_mcs_set_cap;
1073 1079
1074 sband = local->hw.wiphy->bands[conf->channel->band]; 1080 sband = local->hw.wiphy->bands[conf->channel->band];
1075 1081
1082 memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info));
1083 memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info));
1084
1076 /* HT is not supported */ 1085 /* HT is not supported */
1077 if (!sband->ht_info.ht_supported) { 1086 if (!sband->ht_info.ht_supported) {
1078 conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; 1087 conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
1079 return 0; 1088 goto out;
1080 } 1089 }
1081 1090
1082 memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); 1091 /* disable HT */
1083 memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); 1092 if (!enable_ht) {
1084 1093 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)
1085 if (enable_ht) {
1086 if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE))
1087 changed |= BSS_CHANGED_HT; 1094 changed |= BSS_CHANGED_HT;
1095 conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
1096 conf->ht_conf.ht_supported = 0;
1097 goto out;
1098 }
1088 1099
1089 conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE;
1090 ht_conf.ht_supported = 1;
1091 1100
1092 ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; 1101 if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE))
1093 ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); 1102 changed |= BSS_CHANGED_HT;
1094 ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS;
1095 1103
1096 for (i = 0; i < SUPP_MCS_SET_LEN; i++) 1104 conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE;
1097 ht_conf.supp_mcs_set[i] = 1105 ht_conf.ht_supported = 1;
1098 sband->ht_info.supp_mcs_set[i] &
1099 req_ht_cap->supp_mcs_set[i];
1100 1106
1101 ht_bss_conf.primary_channel = req_bss_cap->primary_channel; 1107 ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap;
1102 ht_bss_conf.bss_cap = req_bss_cap->bss_cap; 1108 ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS);
1103 ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; 1109 ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS;
1110 ht_bss_conf.primary_channel = req_bss_cap->primary_channel;
1111 ht_bss_conf.bss_cap = req_bss_cap->bss_cap;
1112 ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode;
1104 1113
1105 ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; 1114 ht_conf.ampdu_factor = req_ht_cap->ampdu_factor;
1106 ht_conf.ampdu_density = req_ht_cap->ampdu_density; 1115 ht_conf.ampdu_density = req_ht_cap->ampdu_density;
1107 1116
1108 /* if bss configuration changed store the new one */ 1117 /* Bits 96-100 */
1109 if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || 1118 tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12];
1110 memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { 1119
1111 changed |= BSS_CHANGED_HT; 1120 /* configure suppoerted Tx MCS according to requested MCS
1112 memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); 1121 * (based in most cases on Rx capabilities of peer) and self
1113 memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); 1122 * Tx MCS capabilities (as defined by low level driver HW
1114 } 1123 * Tx capabilities) */
1115 } else { 1124 if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED))
1116 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) 1125 goto check_changed;
1117 changed |= BSS_CHANGED_HT;
1118 conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
1119 }
1120 1126
1127 /* Counting from 0 therfore + 1 */
1128 if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF)
1129 max_tx_streams = ((tx_mcs_set_cap &
1130 IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1;
1131
1132 for (i = 0; i < max_tx_streams; i++)
1133 ht_conf.supp_mcs_set[i] =
1134 sband->ht_info.supp_mcs_set[i] &
1135 req_ht_cap->supp_mcs_set[i];
1136
1137 if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM)
1138 for (i = IEEE80211_SUPP_MCS_SET_UEQM;
1139 i < IEEE80211_SUPP_MCS_SET_LEN; i++)
1140 ht_conf.supp_mcs_set[i] =
1141 sband->ht_info.supp_mcs_set[i] &
1142 req_ht_cap->supp_mcs_set[i];
1143
1144check_changed:
1145 /* if bss configuration changed store the new one */
1146 if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) ||
1147 memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) {
1148 changed |= BSS_CHANGED_HT;
1149 memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf));
1150 memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf));
1151 }
1152out:
1121 return changed; 1153 return changed;
1122} 1154}
1123 1155
@@ -1148,38 +1180,20 @@ void ieee80211_reset_erp_info(struct net_device *dev)
1148} 1180}
1149 1181
1150void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, 1182void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
1151 struct sk_buff *skb, 1183 struct sk_buff *skb)
1152 struct ieee80211_tx_status *status)
1153{ 1184{
1154 struct ieee80211_local *local = hw_to_local(hw); 1185 struct ieee80211_local *local = hw_to_local(hw);
1155 struct ieee80211_tx_status *saved; 1186 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1156 int tmp; 1187 int tmp;
1157 1188
1158 skb->dev = local->mdev; 1189 skb->dev = local->mdev;
1159 saved = kmalloc(sizeof(struct ieee80211_tx_status), GFP_ATOMIC);
1160 if (unlikely(!saved)) {
1161 if (net_ratelimit())
1162 printk(KERN_WARNING "%s: Not enough memory, "
1163 "dropping tx status", skb->dev->name);
1164 /* should be dev_kfree_skb_irq, but due to this function being
1165 * named _irqsafe instead of just _irq we can't be sure that
1166 * people won't call it from non-irq contexts */
1167 dev_kfree_skb_any(skb);
1168 return;
1169 }
1170 memcpy(saved, status, sizeof(struct ieee80211_tx_status));
1171 /* copy pointer to saved status into skb->cb for use by tasklet */
1172 memcpy(skb->cb, &saved, sizeof(saved));
1173
1174 skb->pkt_type = IEEE80211_TX_STATUS_MSG; 1190 skb->pkt_type = IEEE80211_TX_STATUS_MSG;
1175 skb_queue_tail(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS ? 1191 skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ?
1176 &local->skb_queue : &local->skb_queue_unreliable, skb); 1192 &local->skb_queue : &local->skb_queue_unreliable, skb);
1177 tmp = skb_queue_len(&local->skb_queue) + 1193 tmp = skb_queue_len(&local->skb_queue) +
1178 skb_queue_len(&local->skb_queue_unreliable); 1194 skb_queue_len(&local->skb_queue_unreliable);
1179 while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && 1195 while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT &&
1180 (skb = skb_dequeue(&local->skb_queue_unreliable))) { 1196 (skb = skb_dequeue(&local->skb_queue_unreliable))) {
1181 memcpy(&saved, skb->cb, sizeof(saved));
1182 kfree(saved);
1183 dev_kfree_skb_irq(skb); 1197 dev_kfree_skb_irq(skb);
1184 tmp--; 1198 tmp--;
1185 I802_DEBUG_INC(local->tx_status_drop); 1199 I802_DEBUG_INC(local->tx_status_drop);
@@ -1193,7 +1207,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
1193 struct ieee80211_local *local = (struct ieee80211_local *) data; 1207 struct ieee80211_local *local = (struct ieee80211_local *) data;
1194 struct sk_buff *skb; 1208 struct sk_buff *skb;
1195 struct ieee80211_rx_status rx_status; 1209 struct ieee80211_rx_status rx_status;
1196 struct ieee80211_tx_status *tx_status;
1197 struct ieee80211_ra_tid *ra_tid; 1210 struct ieee80211_ra_tid *ra_tid;
1198 1211
1199 while ((skb = skb_dequeue(&local->skb_queue)) || 1212 while ((skb = skb_dequeue(&local->skb_queue)) ||
@@ -1208,12 +1221,8 @@ static void ieee80211_tasklet_handler(unsigned long data)
1208 __ieee80211_rx(local_to_hw(local), skb, &rx_status); 1221 __ieee80211_rx(local_to_hw(local), skb, &rx_status);
1209 break; 1222 break;
1210 case IEEE80211_TX_STATUS_MSG: 1223 case IEEE80211_TX_STATUS_MSG:
1211 /* get pointer to saved status out of skb->cb */
1212 memcpy(&tx_status, skb->cb, sizeof(tx_status));
1213 skb->pkt_type = 0; 1224 skb->pkt_type = 0;
1214 ieee80211_tx_status(local_to_hw(local), 1225 ieee80211_tx_status(local_to_hw(local), skb);
1215 skb, tx_status);
1216 kfree(tx_status);
1217 break; 1226 break;
1218 case IEEE80211_DELBA_MSG: 1227 case IEEE80211_DELBA_MSG:
1219 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 1228 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
@@ -1242,24 +1251,15 @@ static void ieee80211_tasklet_handler(unsigned long data)
1242 * Also, tx_packet_data in cb is restored from tx_control. */ 1251 * Also, tx_packet_data in cb is restored from tx_control. */
1243static void ieee80211_remove_tx_extra(struct ieee80211_local *local, 1252static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
1244 struct ieee80211_key *key, 1253 struct ieee80211_key *key,
1245 struct sk_buff *skb, 1254 struct sk_buff *skb)
1246 struct ieee80211_tx_control *control)
1247{ 1255{
1248 int hdrlen, iv_len, mic_len; 1256 int hdrlen, iv_len, mic_len;
1249 struct ieee80211_tx_packet_data *pkt_data; 1257 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1250 1258
1251 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; 1259 info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS |
1252 pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex; 1260 IEEE80211_TX_CTL_DO_NOT_ENCRYPT |
1253 pkt_data->flags = 0; 1261 IEEE80211_TX_CTL_REQUEUE |
1254 if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS) 1262 IEEE80211_TX_CTL_EAPOL_FRAME;
1255 pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
1256 if (control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)
1257 pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
1258 if (control->flags & IEEE80211_TXCTL_REQUEUE)
1259 pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
1260 if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME)
1261 pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
1262 pkt_data->queue = control->queue;
1263 1263
1264 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1264 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1265 1265
@@ -1306,9 +1306,10 @@ no_key:
1306 1306
1307static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, 1307static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
1308 struct sta_info *sta, 1308 struct sta_info *sta,
1309 struct sk_buff *skb, 1309 struct sk_buff *skb)
1310 struct ieee80211_tx_status *status)
1311{ 1310{
1311 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1312
1312 sta->tx_filtered_count++; 1313 sta->tx_filtered_count++;
1313 1314
1314 /* 1315 /*
@@ -1316,7 +1317,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
1316 * packet. If the STA went to power save mode, this will happen 1317 * packet. If the STA went to power save mode, this will happen
1317 * when it wakes up for the next time. 1318 * when it wakes up for the next time.
1318 */ 1319 */
1319 sta->flags |= WLAN_STA_CLEAR_PS_FILT; 1320 set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT);
1320 1321
1321 /* 1322 /*
1322 * This code races in the following way: 1323 * This code races in the following way:
@@ -1348,20 +1349,18 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
1348 * can be unknown, for example with different interrupt status 1349 * can be unknown, for example with different interrupt status
1349 * bits. 1350 * bits.
1350 */ 1351 */
1351 if (sta->flags & WLAN_STA_PS && 1352 if (test_sta_flags(sta, WLAN_STA_PS) &&
1352 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { 1353 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
1353 ieee80211_remove_tx_extra(local, sta->key, skb, 1354 ieee80211_remove_tx_extra(local, sta->key, skb);
1354 &status->control);
1355 skb_queue_tail(&sta->tx_filtered, skb); 1355 skb_queue_tail(&sta->tx_filtered, skb);
1356 return; 1356 return;
1357 } 1357 }
1358 1358
1359 if (!(sta->flags & WLAN_STA_PS) && 1359 if (!test_sta_flags(sta, WLAN_STA_PS) &&
1360 !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { 1360 !(info->flags & IEEE80211_TX_CTL_REQUEUE)) {
1361 /* Software retry the packet once */ 1361 /* Software retry the packet once */
1362 status->control.flags |= IEEE80211_TXCTL_REQUEUE; 1362 info->flags |= IEEE80211_TX_CTL_REQUEUE;
1363 ieee80211_remove_tx_extra(local, sta->key, skb, 1363 ieee80211_remove_tx_extra(local, sta->key, skb);
1364 &status->control);
1365 dev_queue_xmit(skb); 1364 dev_queue_xmit(skb);
1366 return; 1365 return;
1367 } 1366 }
@@ -1371,61 +1370,49 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
1371 "queue_len=%d PS=%d @%lu\n", 1370 "queue_len=%d PS=%d @%lu\n",
1372 wiphy_name(local->hw.wiphy), 1371 wiphy_name(local->hw.wiphy),
1373 skb_queue_len(&sta->tx_filtered), 1372 skb_queue_len(&sta->tx_filtered),
1374 !!(sta->flags & WLAN_STA_PS), jiffies); 1373 !!test_sta_flags(sta, WLAN_STA_PS), jiffies);
1375 dev_kfree_skb(skb); 1374 dev_kfree_skb(skb);
1376} 1375}
1377 1376
1378void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, 1377void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
1379 struct ieee80211_tx_status *status)
1380{ 1378{
1381 struct sk_buff *skb2; 1379 struct sk_buff *skb2;
1382 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1380 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1383 struct ieee80211_local *local = hw_to_local(hw); 1381 struct ieee80211_local *local = hw_to_local(hw);
1382 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1384 u16 frag, type; 1383 u16 frag, type;
1385 struct ieee80211_tx_status_rtap_hdr *rthdr; 1384 struct ieee80211_tx_status_rtap_hdr *rthdr;
1386 struct ieee80211_sub_if_data *sdata; 1385 struct ieee80211_sub_if_data *sdata;
1387 struct net_device *prev_dev = NULL; 1386 struct net_device *prev_dev = NULL;
1388 1387
1389 if (!status) {
1390 printk(KERN_ERR
1391 "%s: ieee80211_tx_status called with NULL status\n",
1392 wiphy_name(local->hw.wiphy));
1393 dev_kfree_skb(skb);
1394 return;
1395 }
1396
1397 rcu_read_lock(); 1388 rcu_read_lock();
1398 1389
1399 if (status->excessive_retries) { 1390 if (info->status.excessive_retries) {
1400 struct sta_info *sta; 1391 struct sta_info *sta;
1401 sta = sta_info_get(local, hdr->addr1); 1392 sta = sta_info_get(local, hdr->addr1);
1402 if (sta) { 1393 if (sta) {
1403 if (sta->flags & WLAN_STA_PS) { 1394 if (test_sta_flags(sta, WLAN_STA_PS)) {
1404 /* 1395 /*
1405 * The STA is in power save mode, so assume 1396 * The STA is in power save mode, so assume
1406 * that this TX packet failed because of that. 1397 * that this TX packet failed because of that.
1407 */ 1398 */
1408 status->excessive_retries = 0; 1399 ieee80211_handle_filtered_frame(local, sta, skb);
1409 status->flags |= IEEE80211_TX_STATUS_TX_FILTERED;
1410 ieee80211_handle_filtered_frame(local, sta,
1411 skb, status);
1412 rcu_read_unlock(); 1400 rcu_read_unlock();
1413 return; 1401 return;
1414 } 1402 }
1415 } 1403 }
1416 } 1404 }
1417 1405
1418 if (status->flags & IEEE80211_TX_STATUS_TX_FILTERED) { 1406 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
1419 struct sta_info *sta; 1407 struct sta_info *sta;
1420 sta = sta_info_get(local, hdr->addr1); 1408 sta = sta_info_get(local, hdr->addr1);
1421 if (sta) { 1409 if (sta) {
1422 ieee80211_handle_filtered_frame(local, sta, skb, 1410 ieee80211_handle_filtered_frame(local, sta, skb);
1423 status);
1424 rcu_read_unlock(); 1411 rcu_read_unlock();
1425 return; 1412 return;
1426 } 1413 }
1427 } else 1414 } else
1428 rate_control_tx_status(local->mdev, skb, status); 1415 rate_control_tx_status(local->mdev, skb);
1429 1416
1430 rcu_read_unlock(); 1417 rcu_read_unlock();
1431 1418
@@ -1439,14 +1426,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
1439 frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; 1426 frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
1440 type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; 1427 type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE;
1441 1428
1442 if (status->flags & IEEE80211_TX_STATUS_ACK) { 1429 if (info->flags & IEEE80211_TX_STAT_ACK) {
1443 if (frag == 0) { 1430 if (frag == 0) {
1444 local->dot11TransmittedFrameCount++; 1431 local->dot11TransmittedFrameCount++;
1445 if (is_multicast_ether_addr(hdr->addr1)) 1432 if (is_multicast_ether_addr(hdr->addr1))
1446 local->dot11MulticastTransmittedFrameCount++; 1433 local->dot11MulticastTransmittedFrameCount++;
1447 if (status->retry_count > 0) 1434 if (info->status.retry_count > 0)
1448 local->dot11RetryCount++; 1435 local->dot11RetryCount++;
1449 if (status->retry_count > 1) 1436 if (info->status.retry_count > 1)
1450 local->dot11MultipleRetryCount++; 1437 local->dot11MultipleRetryCount++;
1451 } 1438 }
1452 1439
@@ -1483,7 +1470,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
1483 return; 1470 return;
1484 } 1471 }
1485 1472
1486 rthdr = (struct ieee80211_tx_status_rtap_hdr*) 1473 rthdr = (struct ieee80211_tx_status_rtap_hdr *)
1487 skb_push(skb, sizeof(*rthdr)); 1474 skb_push(skb, sizeof(*rthdr));
1488 1475
1489 memset(rthdr, 0, sizeof(*rthdr)); 1476 memset(rthdr, 0, sizeof(*rthdr));
@@ -1492,17 +1479,17 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
1492 cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | 1479 cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
1493 (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); 1480 (1 << IEEE80211_RADIOTAP_DATA_RETRIES));
1494 1481
1495 if (!(status->flags & IEEE80211_TX_STATUS_ACK) && 1482 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
1496 !is_multicast_ether_addr(hdr->addr1)) 1483 !is_multicast_ether_addr(hdr->addr1))
1497 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); 1484 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
1498 1485
1499 if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) && 1486 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) &&
1500 (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) 1487 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
1501 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); 1488 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
1502 else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) 1489 else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
1503 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); 1490 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
1504 1491
1505 rthdr->data_retries = status->retry_count; 1492 rthdr->data_retries = info->status.retry_count;
1506 1493
1507 /* XXX: is this sufficient for BPF? */ 1494 /* XXX: is this sufficient for BPF? */
1508 skb_set_mac_header(skb, 0); 1495 skb_set_mac_header(skb, 0);
@@ -1652,12 +1639,32 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1652 if (result < 0) 1639 if (result < 0)
1653 return result; 1640 return result;
1654 1641
1642 /*
1643 * We use the number of queues for feature tests (QoS, HT) internally
1644 * so restrict them appropriately.
1645 */
1646#ifdef CONFIG_MAC80211_QOS
1647 if (hw->queues > IEEE80211_MAX_QUEUES)
1648 hw->queues = IEEE80211_MAX_QUEUES;
1649 if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
1650 hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
1651 if (hw->queues < 4)
1652 hw->ampdu_queues = 0;
1653#else
1654 hw->queues = 1;
1655 hw->ampdu_queues = 0;
1656#endif
1657
1655 /* for now, mdev needs sub_if_data :/ */ 1658 /* for now, mdev needs sub_if_data :/ */
1656 mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), 1659 mdev = alloc_netdev_mq(sizeof(struct ieee80211_sub_if_data),
1657 "wmaster%d", ether_setup); 1660 "wmaster%d", ether_setup,
1661 ieee80211_num_queues(hw));
1658 if (!mdev) 1662 if (!mdev)
1659 goto fail_mdev_alloc; 1663 goto fail_mdev_alloc;
1660 1664
1665 if (ieee80211_num_queues(hw) > 1)
1666 mdev->features |= NETIF_F_MULTI_QUEUE;
1667
1661 sdata = IEEE80211_DEV_TO_SUB_IF(mdev); 1668 sdata = IEEE80211_DEV_TO_SUB_IF(mdev);
1662 mdev->ieee80211_ptr = &sdata->wdev; 1669 mdev->ieee80211_ptr = &sdata->wdev;
1663 sdata->wdev.wiphy = local->hw.wiphy; 1670 sdata->wdev.wiphy = local->hw.wiphy;
@@ -1702,13 +1709,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1702 1709
1703 local->hw.conf.beacon_int = 1000; 1710 local->hw.conf.beacon_int = 1000;
1704 1711
1705 local->wstats_flags |= local->hw.max_rssi ? 1712 local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
1706 IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID; 1713 IEEE80211_HW_SIGNAL_DB |
1707 local->wstats_flags |= local->hw.max_signal ? 1714 IEEE80211_HW_SIGNAL_DBM) ?
1708 IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; 1715 IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID;
1709 local->wstats_flags |= local->hw.max_noise ? 1716 local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ?
1710 IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; 1717 IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID;
1711 if (local->hw.max_rssi < 0 || local->hw.max_noise < 0) 1718 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
1712 local->wstats_flags |= IW_QUAL_DBM; 1719 local->wstats_flags |= IW_QUAL_DBM;
1713 1720
1714 result = sta_info_start(local); 1721 result = sta_info_start(local);
@@ -1858,7 +1865,9 @@ static int __init ieee80211_init(void)
1858 struct sk_buff *skb; 1865 struct sk_buff *skb;
1859 int ret; 1866 int ret;
1860 1867
1861 BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); 1868 BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb));
1869 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) +
1870 IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
1862 1871
1863 ret = rc80211_pid_init(); 1872 ret = rc80211_pid_init();
1864 if (ret) 1873 if (ret)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 697ef67f96b6..b5933b271491 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -315,6 +315,13 @@ struct mesh_table *mesh_table_alloc(int size_order)
315 return newtbl; 315 return newtbl;
316} 316}
317 317
318static void __mesh_table_free(struct mesh_table *tbl)
319{
320 kfree(tbl->hash_buckets);
321 kfree(tbl->hashwlock);
322 kfree(tbl);
323}
324
318void mesh_table_free(struct mesh_table *tbl, bool free_leafs) 325void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
319{ 326{
320 struct hlist_head *mesh_hash; 327 struct hlist_head *mesh_hash;
@@ -330,9 +337,7 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
330 } 337 }
331 spin_unlock(&tbl->hashwlock[i]); 338 spin_unlock(&tbl->hashwlock[i]);
332 } 339 }
333 kfree(tbl->hash_buckets); 340 __mesh_table_free(tbl);
334 kfree(tbl->hashwlock);
335 kfree(tbl);
336} 341}
337 342
338static void ieee80211_mesh_path_timer(unsigned long data) 343static void ieee80211_mesh_path_timer(unsigned long data)
@@ -349,21 +354,16 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
349{ 354{
350 struct mesh_table *newtbl; 355 struct mesh_table *newtbl;
351 struct hlist_head *oldhash; 356 struct hlist_head *oldhash;
352 struct hlist_node *p; 357 struct hlist_node *p, *q;
353 int err = 0;
354 int i; 358 int i;
355 359
356 if (atomic_read(&tbl->entries) 360 if (atomic_read(&tbl->entries)
357 < tbl->mean_chain_len * (tbl->hash_mask + 1)) { 361 < tbl->mean_chain_len * (tbl->hash_mask + 1))
358 err = -EPERM;
359 goto endgrow; 362 goto endgrow;
360 }
361 363
362 newtbl = mesh_table_alloc(tbl->size_order + 1); 364 newtbl = mesh_table_alloc(tbl->size_order + 1);
363 if (!newtbl) { 365 if (!newtbl)
364 err = -ENOMEM;
365 goto endgrow; 366 goto endgrow;
366 }
367 367
368 newtbl->free_node = tbl->free_node; 368 newtbl->free_node = tbl->free_node;
369 newtbl->mean_chain_len = tbl->mean_chain_len; 369 newtbl->mean_chain_len = tbl->mean_chain_len;
@@ -373,13 +373,19 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
373 oldhash = tbl->hash_buckets; 373 oldhash = tbl->hash_buckets;
374 for (i = 0; i <= tbl->hash_mask; i++) 374 for (i = 0; i <= tbl->hash_mask; i++)
375 hlist_for_each(p, &oldhash[i]) 375 hlist_for_each(p, &oldhash[i])
376 tbl->copy_node(p, newtbl); 376 if (tbl->copy_node(p, newtbl) < 0)
377 goto errcopy;
377 378
379 return newtbl;
380
381errcopy:
382 for (i = 0; i <= newtbl->hash_mask; i++) {
383 hlist_for_each_safe(p, q, &newtbl->hash_buckets[i])
384 tbl->free_node(p, 0);
385 }
386 __mesh_table_free(tbl);
378endgrow: 387endgrow:
379 if (err) 388 return NULL;
380 return NULL;
381 else
382 return newtbl;
383} 389}
384 390
385/** 391/**
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 2e161f6d8288..669eafafe497 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -109,7 +109,7 @@ struct mesh_table {
109 __u32 hash_rnd; /* Used for hash generation */ 109 __u32 hash_rnd; /* Used for hash generation */
110 atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ 110 atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */
111 void (*free_node) (struct hlist_node *p, bool free_leafs); 111 void (*free_node) (struct hlist_node *p, bool free_leafs);
112 void (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); 112 int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
113 int size_order; 113 int size_order;
114 int mean_chain_len; 114 int mean_chain_len;
115}; 115};
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index af0cd1e3e213..7fa149e230e6 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -26,7 +26,7 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
26{ 26{
27 if (ae) 27 if (ae)
28 offset += 6; 28 offset += 6;
29 return le32_to_cpu(get_unaligned((__le32 *) (preq_elem + offset))); 29 return get_unaligned_le32(preq_elem + offset);
30} 30}
31 31
32/* HWMP IE processing macros */ 32/* HWMP IE processing macros */
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 99c2d360888e..947b13b40726 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -158,19 +158,14 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
158 if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0) 158 if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0)
159 return -ENOSPC; 159 return -ENOSPC;
160 160
161 err = -ENOMEM;
161 new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL); 162 new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
162 if (!new_mpath) { 163 if (!new_mpath)
163 atomic_dec(&sdata->u.sta.mpaths); 164 goto err_path_alloc;
164 err = -ENOMEM; 165
165 goto endadd2;
166 }
167 new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); 166 new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
168 if (!new_node) { 167 if (!new_node)
169 kfree(new_mpath); 168 goto err_node_alloc;
170 atomic_dec(&sdata->u.sta.mpaths);
171 err = -ENOMEM;
172 goto endadd2;
173 }
174 169
175 read_lock(&pathtbl_resize_lock); 170 read_lock(&pathtbl_resize_lock);
176 memcpy(new_mpath->dst, dst, ETH_ALEN); 171 memcpy(new_mpath->dst, dst, ETH_ALEN);
@@ -189,16 +184,11 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
189 184
190 spin_lock(&mesh_paths->hashwlock[hash_idx]); 185 spin_lock(&mesh_paths->hashwlock[hash_idx]);
191 186
187 err = -EEXIST;
192 hlist_for_each_entry(node, n, bucket, list) { 188 hlist_for_each_entry(node, n, bucket, list) {
193 mpath = node->mpath; 189 mpath = node->mpath;
194 if (mpath->dev == dev && memcmp(dst, mpath->dst, ETH_ALEN) 190 if (mpath->dev == dev && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
195 == 0) { 191 goto err_exists;
196 err = -EEXIST;
197 atomic_dec(&sdata->u.sta.mpaths);
198 kfree(new_node);
199 kfree(new_mpath);
200 goto endadd;
201 }
202 } 192 }
203 193
204 hlist_add_head_rcu(&new_node->list, bucket); 194 hlist_add_head_rcu(&new_node->list, bucket);
@@ -206,10 +196,9 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
206 mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) 196 mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1))
207 grow = 1; 197 grow = 1;
208 198
209endadd:
210 spin_unlock(&mesh_paths->hashwlock[hash_idx]); 199 spin_unlock(&mesh_paths->hashwlock[hash_idx]);
211 read_unlock(&pathtbl_resize_lock); 200 read_unlock(&pathtbl_resize_lock);
212 if (!err && grow) { 201 if (grow) {
213 struct mesh_table *oldtbl, *newtbl; 202 struct mesh_table *oldtbl, *newtbl;
214 203
215 write_lock(&pathtbl_resize_lock); 204 write_lock(&pathtbl_resize_lock);
@@ -217,7 +206,7 @@ endadd:
217 newtbl = mesh_table_grow(mesh_paths); 206 newtbl = mesh_table_grow(mesh_paths);
218 if (!newtbl) { 207 if (!newtbl) {
219 write_unlock(&pathtbl_resize_lock); 208 write_unlock(&pathtbl_resize_lock);
220 return -ENOMEM; 209 return 0;
221 } 210 }
222 rcu_assign_pointer(mesh_paths, newtbl); 211 rcu_assign_pointer(mesh_paths, newtbl);
223 write_unlock(&pathtbl_resize_lock); 212 write_unlock(&pathtbl_resize_lock);
@@ -225,7 +214,16 @@ endadd:
225 synchronize_rcu(); 214 synchronize_rcu();
226 mesh_table_free(oldtbl, false); 215 mesh_table_free(oldtbl, false);
227 } 216 }
228endadd2: 217 return 0;
218
219err_exists:
220 spin_unlock(&mesh_paths->hashwlock[hash_idx]);
221 read_unlock(&pathtbl_resize_lock);
222 kfree(new_node);
223err_node_alloc:
224 kfree(new_mpath);
225err_path_alloc:
226 atomic_dec(&sdata->u.sta.mpaths);
229 return err; 227 return err;
230} 228}
231 229
@@ -460,25 +458,28 @@ static void mesh_path_node_free(struct hlist_node *p, bool free_leafs)
460 struct mpath_node *node = hlist_entry(p, struct mpath_node, list); 458 struct mpath_node *node = hlist_entry(p, struct mpath_node, list);
461 mpath = node->mpath; 459 mpath = node->mpath;
462 hlist_del_rcu(p); 460 hlist_del_rcu(p);
463 synchronize_rcu();
464 if (free_leafs) 461 if (free_leafs)
465 kfree(mpath); 462 kfree(mpath);
466 kfree(node); 463 kfree(node);
467} 464}
468 465
469static void mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) 466static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl)
470{ 467{
471 struct mesh_path *mpath; 468 struct mesh_path *mpath;
472 struct mpath_node *node, *new_node; 469 struct mpath_node *node, *new_node;
473 u32 hash_idx; 470 u32 hash_idx;
474 471
472 new_node = kmalloc(sizeof(struct mpath_node), GFP_ATOMIC);
473 if (new_node == NULL)
474 return -ENOMEM;
475
475 node = hlist_entry(p, struct mpath_node, list); 476 node = hlist_entry(p, struct mpath_node, list);
476 mpath = node->mpath; 477 mpath = node->mpath;
477 new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
478 new_node->mpath = mpath; 478 new_node->mpath = mpath;
479 hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl); 479 hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl);
480 hlist_add_head(&new_node->list, 480 hlist_add_head(&new_node->list,
481 &newtbl->hash_buckets[hash_idx]); 481 &newtbl->hash_buckets[hash_idx]);
482 return 0;
482} 483}
483 484
484int mesh_pathtbl_init(void) 485int mesh_pathtbl_init(void)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 37f0c2b94ae7..9efeb1f07025 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -79,7 +79,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
79 * 79 *
80 * @sta: mes peer link to restart 80 * @sta: mes peer link to restart
81 * 81 *
82 * Locking: this function must be called holding sta->plink_lock 82 * Locking: this function must be called holding sta->lock
83 */ 83 */
84static inline void mesh_plink_fsm_restart(struct sta_info *sta) 84static inline void mesh_plink_fsm_restart(struct sta_info *sta)
85{ 85{
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
105 if (!sta) 105 if (!sta)
106 return NULL; 106 return NULL;
107 107
108 sta->flags |= WLAN_STA_AUTHORIZED; 108 sta->flags = WLAN_STA_AUTHORIZED;
109 sta->supp_rates[local->hw.conf.channel->band] = rates; 109 sta->supp_rates[local->hw.conf.channel->band] = rates;
110 110
111 return sta; 111 return sta;
@@ -118,7 +118,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
118 * 118 *
119 * All mesh paths with this peer as next hop will be flushed 119 * All mesh paths with this peer as next hop will be flushed
120 * 120 *
121 * Locking: the caller must hold sta->plink_lock 121 * Locking: the caller must hold sta->lock
122 */ 122 */
123static void __mesh_plink_deactivate(struct sta_info *sta) 123static void __mesh_plink_deactivate(struct sta_info *sta)
124{ 124{
@@ -139,9 +139,9 @@ static void __mesh_plink_deactivate(struct sta_info *sta)
139 */ 139 */
140void mesh_plink_deactivate(struct sta_info *sta) 140void mesh_plink_deactivate(struct sta_info *sta)
141{ 141{
142 spin_lock_bh(&sta->plink_lock); 142 spin_lock_bh(&sta->lock);
143 __mesh_plink_deactivate(sta); 143 __mesh_plink_deactivate(sta);
144 spin_unlock_bh(&sta->plink_lock); 144 spin_unlock_bh(&sta->lock);
145} 145}
146 146
147static int mesh_plink_frame_tx(struct net_device *dev, 147static int mesh_plink_frame_tx(struct net_device *dev,
@@ -270,10 +270,10 @@ static void mesh_plink_timer(unsigned long data)
270 */ 270 */
271 sta = (struct sta_info *) data; 271 sta = (struct sta_info *) data;
272 272
273 spin_lock_bh(&sta->plink_lock); 273 spin_lock_bh(&sta->lock);
274 if (sta->ignore_plink_timer) { 274 if (sta->ignore_plink_timer) {
275 sta->ignore_plink_timer = false; 275 sta->ignore_plink_timer = false;
276 spin_unlock_bh(&sta->plink_lock); 276 spin_unlock_bh(&sta->lock);
277 return; 277 return;
278 } 278 }
279 mpl_dbg("Mesh plink timer for %s fired on state %d\n", 279 mpl_dbg("Mesh plink timer for %s fired on state %d\n",
@@ -298,7 +298,7 @@ static void mesh_plink_timer(unsigned long data)
298 rand % sta->plink_timeout; 298 rand % sta->plink_timeout;
299 ++sta->plink_retries; 299 ++sta->plink_retries;
300 mod_plink_timer(sta, sta->plink_timeout); 300 mod_plink_timer(sta, sta->plink_timeout);
301 spin_unlock_bh(&sta->plink_lock); 301 spin_unlock_bh(&sta->lock);
302 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, 302 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
303 0, 0); 303 0, 0);
304 break; 304 break;
@@ -311,7 +311,7 @@ static void mesh_plink_timer(unsigned long data)
311 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); 311 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
312 sta->plink_state = PLINK_HOLDING; 312 sta->plink_state = PLINK_HOLDING;
313 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 313 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
314 spin_unlock_bh(&sta->plink_lock); 314 spin_unlock_bh(&sta->lock);
315 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, 315 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid,
316 reason); 316 reason);
317 break; 317 break;
@@ -319,10 +319,10 @@ static void mesh_plink_timer(unsigned long data)
319 /* holding timer */ 319 /* holding timer */
320 del_timer(&sta->plink_timer); 320 del_timer(&sta->plink_timer);
321 mesh_plink_fsm_restart(sta); 321 mesh_plink_fsm_restart(sta);
322 spin_unlock_bh(&sta->plink_lock); 322 spin_unlock_bh(&sta->lock);
323 break; 323 break;
324 default: 324 default:
325 spin_unlock_bh(&sta->plink_lock); 325 spin_unlock_bh(&sta->lock);
326 break; 326 break;
327 } 327 }
328} 328}
@@ -344,16 +344,16 @@ int mesh_plink_open(struct sta_info *sta)
344 DECLARE_MAC_BUF(mac); 344 DECLARE_MAC_BUF(mac);
345#endif 345#endif
346 346
347 spin_lock_bh(&sta->plink_lock); 347 spin_lock_bh(&sta->lock);
348 get_random_bytes(&llid, 2); 348 get_random_bytes(&llid, 2);
349 sta->llid = llid; 349 sta->llid = llid;
350 if (sta->plink_state != PLINK_LISTEN) { 350 if (sta->plink_state != PLINK_LISTEN) {
351 spin_unlock_bh(&sta->plink_lock); 351 spin_unlock_bh(&sta->lock);
352 return -EBUSY; 352 return -EBUSY;
353 } 353 }
354 sta->plink_state = PLINK_OPN_SNT; 354 sta->plink_state = PLINK_OPN_SNT;
355 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 355 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
356 spin_unlock_bh(&sta->plink_lock); 356 spin_unlock_bh(&sta->lock);
357 mpl_dbg("Mesh plink: starting establishment with %s\n", 357 mpl_dbg("Mesh plink: starting establishment with %s\n",
358 print_mac(mac, sta->addr)); 358 print_mac(mac, sta->addr));
359 359
@@ -367,10 +367,10 @@ void mesh_plink_block(struct sta_info *sta)
367 DECLARE_MAC_BUF(mac); 367 DECLARE_MAC_BUF(mac);
368#endif 368#endif
369 369
370 spin_lock_bh(&sta->plink_lock); 370 spin_lock_bh(&sta->lock);
371 __mesh_plink_deactivate(sta); 371 __mesh_plink_deactivate(sta);
372 sta->plink_state = PLINK_BLOCKED; 372 sta->plink_state = PLINK_BLOCKED;
373 spin_unlock_bh(&sta->plink_lock); 373 spin_unlock_bh(&sta->lock);
374} 374}
375 375
376int mesh_plink_close(struct sta_info *sta) 376int mesh_plink_close(struct sta_info *sta)
@@ -383,14 +383,14 @@ int mesh_plink_close(struct sta_info *sta)
383 383
384 mpl_dbg("Mesh plink: closing link with %s\n", 384 mpl_dbg("Mesh plink: closing link with %s\n",
385 print_mac(mac, sta->addr)); 385 print_mac(mac, sta->addr));
386 spin_lock_bh(&sta->plink_lock); 386 spin_lock_bh(&sta->lock);
387 sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); 387 sta->reason = cpu_to_le16(MESH_LINK_CANCELLED);
388 reason = sta->reason; 388 reason = sta->reason;
389 389
390 if (sta->plink_state == PLINK_LISTEN || 390 if (sta->plink_state == PLINK_LISTEN ||
391 sta->plink_state == PLINK_BLOCKED) { 391 sta->plink_state == PLINK_BLOCKED) {
392 mesh_plink_fsm_restart(sta); 392 mesh_plink_fsm_restart(sta);
393 spin_unlock_bh(&sta->plink_lock); 393 spin_unlock_bh(&sta->lock);
394 return 0; 394 return 0;
395 } else if (sta->plink_state == PLINK_ESTAB) { 395 } else if (sta->plink_state == PLINK_ESTAB) {
396 __mesh_plink_deactivate(sta); 396 __mesh_plink_deactivate(sta);
@@ -402,7 +402,7 @@ int mesh_plink_close(struct sta_info *sta)
402 sta->plink_state = PLINK_HOLDING; 402 sta->plink_state = PLINK_HOLDING;
403 llid = sta->llid; 403 llid = sta->llid;
404 plid = sta->plid; 404 plid = sta->plid;
405 spin_unlock_bh(&sta->plink_lock); 405 spin_unlock_bh(&sta->lock);
406 mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, 406 mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid,
407 plid, reason); 407 plid, reason);
408 return 0; 408 return 0;
@@ -490,7 +490,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
490 /* avoid warning */ 490 /* avoid warning */
491 break; 491 break;
492 } 492 }
493 spin_lock_bh(&sta->plink_lock); 493 spin_lock_bh(&sta->lock);
494 } else if (!sta) { 494 } else if (!sta) {
495 /* ftype == PLINK_OPEN */ 495 /* ftype == PLINK_OPEN */
496 u64 rates; 496 u64 rates;
@@ -512,9 +512,9 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
512 return; 512 return;
513 } 513 }
514 event = OPN_ACPT; 514 event = OPN_ACPT;
515 spin_lock_bh(&sta->plink_lock); 515 spin_lock_bh(&sta->lock);
516 } else { 516 } else {
517 spin_lock_bh(&sta->plink_lock); 517 spin_lock_bh(&sta->lock);
518 switch (ftype) { 518 switch (ftype) {
519 case PLINK_OPEN: 519 case PLINK_OPEN:
520 if (!mesh_plink_free_count(sdata) || 520 if (!mesh_plink_free_count(sdata) ||
@@ -551,7 +551,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
551 break; 551 break;
552 default: 552 default:
553 mpl_dbg("Mesh plink: unknown frame subtype\n"); 553 mpl_dbg("Mesh plink: unknown frame subtype\n");
554 spin_unlock_bh(&sta->plink_lock); 554 spin_unlock_bh(&sta->lock);
555 rcu_read_unlock(); 555 rcu_read_unlock();
556 return; 556 return;
557 } 557 }
@@ -568,7 +568,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
568 switch (event) { 568 switch (event) {
569 case CLS_ACPT: 569 case CLS_ACPT:
570 mesh_plink_fsm_restart(sta); 570 mesh_plink_fsm_restart(sta);
571 spin_unlock_bh(&sta->plink_lock); 571 spin_unlock_bh(&sta->lock);
572 break; 572 break;
573 case OPN_ACPT: 573 case OPN_ACPT:
574 sta->plink_state = PLINK_OPN_RCVD; 574 sta->plink_state = PLINK_OPN_RCVD;
@@ -576,14 +576,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
576 get_random_bytes(&llid, 2); 576 get_random_bytes(&llid, 2);
577 sta->llid = llid; 577 sta->llid = llid;
578 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 578 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
579 spin_unlock_bh(&sta->plink_lock); 579 spin_unlock_bh(&sta->lock);
580 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, 580 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
581 0, 0); 581 0, 0);
582 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, 582 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr,
583 llid, plid, 0); 583 llid, plid, 0);
584 break; 584 break;
585 default: 585 default:
586 spin_unlock_bh(&sta->plink_lock); 586 spin_unlock_bh(&sta->lock);
587 break; 587 break;
588 } 588 }
589 break; 589 break;
@@ -603,7 +603,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
603 sta->ignore_plink_timer = true; 603 sta->ignore_plink_timer = true;
604 604
605 llid = sta->llid; 605 llid = sta->llid;
606 spin_unlock_bh(&sta->plink_lock); 606 spin_unlock_bh(&sta->lock);
607 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 607 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
608 plid, reason); 608 plid, reason);
609 break; 609 break;
@@ -612,7 +612,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
612 sta->plink_state = PLINK_OPN_RCVD; 612 sta->plink_state = PLINK_OPN_RCVD;
613 sta->plid = plid; 613 sta->plid = plid;
614 llid = sta->llid; 614 llid = sta->llid;
615 spin_unlock_bh(&sta->plink_lock); 615 spin_unlock_bh(&sta->lock);
616 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 616 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
617 plid, 0); 617 plid, 0);
618 break; 618 break;
@@ -622,10 +622,10 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
622 dot11MeshConfirmTimeout(sdata))) 622 dot11MeshConfirmTimeout(sdata)))
623 sta->ignore_plink_timer = true; 623 sta->ignore_plink_timer = true;
624 624
625 spin_unlock_bh(&sta->plink_lock); 625 spin_unlock_bh(&sta->lock);
626 break; 626 break;
627 default: 627 default:
628 spin_unlock_bh(&sta->plink_lock); 628 spin_unlock_bh(&sta->lock);
629 break; 629 break;
630 } 630 }
631 break; 631 break;
@@ -645,13 +645,13 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
645 sta->ignore_plink_timer = true; 645 sta->ignore_plink_timer = true;
646 646
647 llid = sta->llid; 647 llid = sta->llid;
648 spin_unlock_bh(&sta->plink_lock); 648 spin_unlock_bh(&sta->lock);
649 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 649 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
650 plid, reason); 650 plid, reason);
651 break; 651 break;
652 case OPN_ACPT: 652 case OPN_ACPT:
653 llid = sta->llid; 653 llid = sta->llid;
654 spin_unlock_bh(&sta->plink_lock); 654 spin_unlock_bh(&sta->lock);
655 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 655 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
656 plid, 0); 656 plid, 0);
657 break; 657 break;
@@ -659,12 +659,12 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
659 del_timer(&sta->plink_timer); 659 del_timer(&sta->plink_timer);
660 sta->plink_state = PLINK_ESTAB; 660 sta->plink_state = PLINK_ESTAB;
661 mesh_plink_inc_estab_count(sdata); 661 mesh_plink_inc_estab_count(sdata);
662 spin_unlock_bh(&sta->plink_lock); 662 spin_unlock_bh(&sta->lock);
663 mpl_dbg("Mesh plink with %s ESTABLISHED\n", 663 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
664 print_mac(mac, sta->addr)); 664 print_mac(mac, sta->addr));
665 break; 665 break;
666 default: 666 default:
667 spin_unlock_bh(&sta->plink_lock); 667 spin_unlock_bh(&sta->lock);
668 break; 668 break;
669 } 669 }
670 break; 670 break;
@@ -684,7 +684,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
684 sta->ignore_plink_timer = true; 684 sta->ignore_plink_timer = true;
685 685
686 llid = sta->llid; 686 llid = sta->llid;
687 spin_unlock_bh(&sta->plink_lock); 687 spin_unlock_bh(&sta->lock);
688 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 688 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
689 plid, reason); 689 plid, reason);
690 break; 690 break;
@@ -692,14 +692,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
692 del_timer(&sta->plink_timer); 692 del_timer(&sta->plink_timer);
693 sta->plink_state = PLINK_ESTAB; 693 sta->plink_state = PLINK_ESTAB;
694 mesh_plink_inc_estab_count(sdata); 694 mesh_plink_inc_estab_count(sdata);
695 spin_unlock_bh(&sta->plink_lock); 695 spin_unlock_bh(&sta->lock);
696 mpl_dbg("Mesh plink with %s ESTABLISHED\n", 696 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
697 print_mac(mac, sta->addr)); 697 print_mac(mac, sta->addr));
698 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 698 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
699 plid, 0); 699 plid, 0);
700 break; 700 break;
701 default: 701 default:
702 spin_unlock_bh(&sta->plink_lock); 702 spin_unlock_bh(&sta->lock);
703 break; 703 break;
704 } 704 }
705 break; 705 break;
@@ -713,18 +713,18 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
713 sta->plink_state = PLINK_HOLDING; 713 sta->plink_state = PLINK_HOLDING;
714 llid = sta->llid; 714 llid = sta->llid;
715 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 715 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
716 spin_unlock_bh(&sta->plink_lock); 716 spin_unlock_bh(&sta->lock);
717 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 717 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
718 plid, reason); 718 plid, reason);
719 break; 719 break;
720 case OPN_ACPT: 720 case OPN_ACPT:
721 llid = sta->llid; 721 llid = sta->llid;
722 spin_unlock_bh(&sta->plink_lock); 722 spin_unlock_bh(&sta->lock);
723 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 723 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
724 plid, 0); 724 plid, 0);
725 break; 725 break;
726 default: 726 default:
727 spin_unlock_bh(&sta->plink_lock); 727 spin_unlock_bh(&sta->lock);
728 break; 728 break;
729 } 729 }
730 break; 730 break;
@@ -734,7 +734,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
734 if (del_timer(&sta->plink_timer)) 734 if (del_timer(&sta->plink_timer))
735 sta->ignore_plink_timer = 1; 735 sta->ignore_plink_timer = 1;
736 mesh_plink_fsm_restart(sta); 736 mesh_plink_fsm_restart(sta);
737 spin_unlock_bh(&sta->plink_lock); 737 spin_unlock_bh(&sta->lock);
738 break; 738 break;
739 case OPN_ACPT: 739 case OPN_ACPT:
740 case CNF_ACPT: 740 case CNF_ACPT:
@@ -742,19 +742,19 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
742 case CNF_RJCT: 742 case CNF_RJCT:
743 llid = sta->llid; 743 llid = sta->llid;
744 reason = sta->reason; 744 reason = sta->reason;
745 spin_unlock_bh(&sta->plink_lock); 745 spin_unlock_bh(&sta->lock);
746 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 746 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
747 plid, reason); 747 plid, reason);
748 break; 748 break;
749 default: 749 default:
750 spin_unlock_bh(&sta->plink_lock); 750 spin_unlock_bh(&sta->lock);
751 } 751 }
752 break; 752 break;
753 default: 753 default:
754 /* should not get here, PLINK_BLOCKED is dealt with at the 754 /* should not get here, PLINK_BLOCKED is dealt with at the
755 * beggining of the function 755 * beggining of the function
756 */ 756 */
757 spin_unlock_bh(&sta->plink_lock); 757 spin_unlock_bh(&sta->lock);
758 break; 758 break;
759 } 759 }
760 760
diff --git a/net/mac80211/michael.c b/net/mac80211/michael.c
index 0f844f7895f1..1fcdf38cf60c 100644
--- a/net/mac80211/michael.c
+++ b/net/mac80211/michael.c
@@ -6,85 +6,58 @@
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9
10#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/bitops.h>
11#include <asm/unaligned.h>
11 12
12#include "michael.h" 13#include "michael.h"
13 14
14static inline u32 rotr(u32 val, int bits) 15static void michael_block(struct michael_mic_ctx *mctx, u32 val)
15{
16 return (val >> bits) | (val << (32 - bits));
17}
18
19
20static inline u32 rotl(u32 val, int bits)
21{
22 return (val << bits) | (val >> (32 - bits));
23}
24
25
26static inline u32 xswap(u32 val)
27{
28 return ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8);
29}
30
31
32#define michael_block(l, r) \
33do { \
34 r ^= rotl(l, 17); \
35 l += r; \
36 r ^= xswap(l); \
37 l += r; \
38 r ^= rotl(l, 3); \
39 l += r; \
40 r ^= rotr(l, 2); \
41 l += r; \
42} while (0)
43
44
45static inline u32 michael_get32(u8 *data)
46{ 16{
47 return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); 17 mctx->l ^= val;
18 mctx->r ^= rol32(mctx->l, 17);
19 mctx->l += mctx->r;
20 mctx->r ^= ((mctx->l & 0xff00ff00) >> 8) |
21 ((mctx->l & 0x00ff00ff) << 8);
22 mctx->l += mctx->r;
23 mctx->r ^= rol32(mctx->l, 3);
24 mctx->l += mctx->r;
25 mctx->r ^= ror32(mctx->l, 2);
26 mctx->l += mctx->r;
48} 27}
49 28
50 29static void michael_mic_hdr(struct michael_mic_ctx *mctx,
51static inline void michael_put32(u32 val, u8 *data) 30 const u8 *key, const u8 *da, const u8 *sa, u8 priority)
52{ 31{
53 data[0] = val & 0xff; 32 mctx->l = get_unaligned_le32(key);
54 data[1] = (val >> 8) & 0xff; 33 mctx->r = get_unaligned_le32(key + 4);
55 data[2] = (val >> 16) & 0xff; 34
56 data[3] = (val >> 24) & 0xff; 35 /*
36 * A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC
37 * calculation, but it is _not_ transmitted
38 */
39 michael_block(mctx, get_unaligned_le32(da));
40 michael_block(mctx, get_unaligned_le16(&da[4]) |
41 (get_unaligned_le16(sa) << 16));
42 michael_block(mctx, get_unaligned_le32(&sa[2]));
43 michael_block(mctx, priority);
57} 44}
58 45
59 46void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority,
60void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, 47 const u8 *data, size_t data_len, u8 *mic)
61 u8 *data, size_t data_len, u8 *mic)
62{ 48{
63 u32 l, r, val; 49 u32 val;
64 size_t block, blocks, left; 50 size_t block, blocks, left;
51 struct michael_mic_ctx mctx;
65 52
66 l = michael_get32(key); 53 michael_mic_hdr(&mctx, key, da, sa, priority);
67 r = michael_get32(key + 4);
68
69 /* A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC
70 * calculation, but it is _not_ transmitted */
71 l ^= michael_get32(da);
72 michael_block(l, r);
73 l ^= da[4] | (da[5] << 8) | (sa[0] << 16) | (sa[1] << 24);
74 michael_block(l, r);
75 l ^= michael_get32(&sa[2]);
76 michael_block(l, r);
77 l ^= priority;
78 michael_block(l, r);
79 54
80 /* Real data */ 55 /* Real data */
81 blocks = data_len / 4; 56 blocks = data_len / 4;
82 left = data_len % 4; 57 left = data_len % 4;
83 58
84 for (block = 0; block < blocks; block++) { 59 for (block = 0; block < blocks; block++)
85 l ^= michael_get32(&data[block * 4]); 60 michael_block(&mctx, get_unaligned_le32(&data[block * 4]));
86 michael_block(l, r);
87 }
88 61
89 /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make 62 /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make
90 * total length a multiple of 4. */ 63 * total length a multiple of 4. */
@@ -94,11 +67,10 @@ void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority,
94 left--; 67 left--;
95 val |= data[blocks * 4 + left]; 68 val |= data[blocks * 4 + left];
96 } 69 }
97 l ^= val;
98 michael_block(l, r);
99 /* last block is zero, so l ^ 0 = l */
100 michael_block(l, r);
101 70
102 michael_put32(l, mic); 71 michael_block(&mctx, val);
103 michael_put32(r, mic + 4); 72 michael_block(&mctx, 0);
73
74 put_unaligned_le32(mctx.l, mic);
75 put_unaligned_le32(mctx.r, mic + 4);
104} 76}
diff --git a/net/mac80211/michael.h b/net/mac80211/michael.h
index 2e6aebabeea1..69b4501f13ba 100644
--- a/net/mac80211/michael.h
+++ b/net/mac80211/michael.h
@@ -14,7 +14,11 @@
14 14
15#define MICHAEL_MIC_LEN 8 15#define MICHAEL_MIC_LEN 8
16 16
17void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, 17struct michael_mic_ctx {
18 u8 *data, size_t data_len, u8 *mic); 18 u32 l, r;
19};
20
21void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority,
22 const u8 *data, size_t data_len, u8 *mic);
19 23
20#endif /* MICHAEL_H */ 24#endif /* MICHAEL_H */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4d2b582dd055..7f05820dc629 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -87,6 +87,7 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
87 u8 *ssid, size_t ssid_len); 87 u8 *ssid, size_t ssid_len);
88static int ieee80211_sta_config_auth(struct net_device *dev, 88static int ieee80211_sta_config_auth(struct net_device *dev,
89 struct ieee80211_if_sta *ifsta); 89 struct ieee80211_if_sta *ifsta);
90static void sta_rx_agg_session_timer_expired(unsigned long data);
90 91
91 92
92void ieee802_11_parse_elems(u8 *start, size_t len, 93void ieee802_11_parse_elems(u8 *start, size_t len,
@@ -256,19 +257,8 @@ static void ieee80211_sta_def_wmm_params(struct net_device *dev,
256 qparam.cw_max = 1023; 257 qparam.cw_max = 1023;
257 qparam.txop = 0; 258 qparam.txop = 0;
258 259
259 for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) 260 for (i = 0; i < local_to_hw(local)->queues; i++)
260 local->ops->conf_tx(local_to_hw(local), 261 local->ops->conf_tx(local_to_hw(local), i, &qparam);
261 i + IEEE80211_TX_QUEUE_DATA0,
262 &qparam);
263
264 if (ibss) {
265 /* IBSS uses different parameters for Beacon sending */
266 qparam.cw_min++;
267 qparam.cw_min *= 2;
268 qparam.cw_min--;
269 local->ops->conf_tx(local_to_hw(local),
270 IEEE80211_TX_QUEUE_BEACON, &qparam);
271 }
272 } 262 }
273} 263}
274 264
@@ -282,6 +272,12 @@ static void ieee80211_sta_wmm_params(struct net_device *dev,
282 int count; 272 int count;
283 u8 *pos; 273 u8 *pos;
284 274
275 if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED))
276 return;
277
278 if (!wmm_param)
279 return;
280
285 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) 281 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
286 return; 282 return;
287 count = wmm_param[6] & 0x0f; 283 count = wmm_param[6] & 0x0f;
@@ -305,29 +301,25 @@ static void ieee80211_sta_wmm_params(struct net_device *dev,
305 301
306 switch (aci) { 302 switch (aci) {
307 case 1: 303 case 1:
308 queue = IEEE80211_TX_QUEUE_DATA3; 304 queue = 3;
309 if (acm) { 305 if (acm)
310 local->wmm_acm |= BIT(0) | BIT(3); 306 local->wmm_acm |= BIT(0) | BIT(3);
311 }
312 break; 307 break;
313 case 2: 308 case 2:
314 queue = IEEE80211_TX_QUEUE_DATA1; 309 queue = 1;
315 if (acm) { 310 if (acm)
316 local->wmm_acm |= BIT(4) | BIT(5); 311 local->wmm_acm |= BIT(4) | BIT(5);
317 }
318 break; 312 break;
319 case 3: 313 case 3:
320 queue = IEEE80211_TX_QUEUE_DATA0; 314 queue = 0;
321 if (acm) { 315 if (acm)
322 local->wmm_acm |= BIT(6) | BIT(7); 316 local->wmm_acm |= BIT(6) | BIT(7);
323 }
324 break; 317 break;
325 case 0: 318 case 0:
326 default: 319 default:
327 queue = IEEE80211_TX_QUEUE_DATA2; 320 queue = 2;
328 if (acm) { 321 if (acm)
329 local->wmm_acm |= BIT(1) | BIT(2); 322 local->wmm_acm |= BIT(1) | BIT(2);
330 }
331 break; 323 break;
332 } 324 }
333 325
@@ -586,7 +578,7 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
586 int encrypt) 578 int encrypt)
587{ 579{
588 struct ieee80211_sub_if_data *sdata; 580 struct ieee80211_sub_if_data *sdata;
589 struct ieee80211_tx_packet_data *pkt_data; 581 struct ieee80211_tx_info *info;
590 582
591 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 583 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
592 skb->dev = sdata->local->mdev; 584 skb->dev = sdata->local->mdev;
@@ -594,11 +586,11 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
594 skb_set_network_header(skb, 0); 586 skb_set_network_header(skb, 0);
595 skb_set_transport_header(skb, 0); 587 skb_set_transport_header(skb, 0);
596 588
597 pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 589 info = IEEE80211_SKB_CB(skb);
598 memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); 590 memset(info, 0, sizeof(struct ieee80211_tx_info));
599 pkt_data->ifindex = sdata->dev->ifindex; 591 info->control.ifindex = sdata->dev->ifindex;
600 if (!encrypt) 592 if (!encrypt)
601 pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; 593 info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
602 594
603 dev_queue_xmit(skb); 595 dev_queue_xmit(skb);
604} 596}
@@ -727,9 +719,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
727 if (bss) { 719 if (bss) {
728 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 720 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
729 capab |= WLAN_CAPABILITY_PRIVACY; 721 capab |= WLAN_CAPABILITY_PRIVACY;
730 if (bss->wmm_ie) { 722 if (bss->wmm_ie)
731 wmm = 1; 723 wmm = 1;
732 }
733 724
734 /* get all rates supported by the device and the AP as 725 /* get all rates supported by the device and the AP as
735 * some APs don't like getting a superset of their rates 726 * some APs don't like getting a superset of their rates
@@ -821,9 +812,32 @@ static void ieee80211_send_assoc(struct net_device *dev,
821 *pos++ = 1; /* WME ver */ 812 *pos++ = 1; /* WME ver */
822 *pos++ = 0; 813 *pos++ = 0;
823 } 814 }
815
824 /* wmm support is a must to HT */ 816 /* wmm support is a must to HT */
825 if (wmm && sband->ht_info.ht_supported) { 817 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
826 __le16 tmp = cpu_to_le16(sband->ht_info.cap); 818 sband->ht_info.ht_supported && bss->ht_add_ie) {
819 struct ieee80211_ht_addt_info *ht_add_info =
820 (struct ieee80211_ht_addt_info *)bss->ht_add_ie;
821 u16 cap = sband->ht_info.cap;
822 __le16 tmp;
823 u32 flags = local->hw.conf.channel->flags;
824
825 switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) {
826 case IEEE80211_HT_IE_CHA_SEC_ABOVE:
827 if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
828 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
829 cap &= ~IEEE80211_HT_CAP_SGI_40;
830 }
831 break;
832 case IEEE80211_HT_IE_CHA_SEC_BELOW:
833 if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
834 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
835 cap &= ~IEEE80211_HT_CAP_SGI_40;
836 }
837 break;
838 }
839
840 tmp = cpu_to_le16(cap);
827 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); 841 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2);
828 *pos++ = WLAN_EID_HT_CAPABILITY; 842 *pos++ = WLAN_EID_HT_CAPABILITY;
829 *pos++ = sizeof(struct ieee80211_ht_cap); 843 *pos++ = sizeof(struct ieee80211_ht_cap);
@@ -1141,8 +1155,8 @@ static void ieee80211_send_addba_resp(struct net_device *dev, u8 *da, u16 tid,
1141 struct ieee80211_mgmt *mgmt; 1155 struct ieee80211_mgmt *mgmt;
1142 u16 capab; 1156 u16 capab;
1143 1157
1144 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + 1158 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1145 sizeof(mgmt->u.action.u.addba_resp)); 1159
1146 if (!skb) { 1160 if (!skb) {
1147 printk(KERN_DEBUG "%s: failed to allocate buffer " 1161 printk(KERN_DEBUG "%s: failed to allocate buffer "
1148 "for addba resp frame\n", dev->name); 1162 "for addba resp frame\n", dev->name);
@@ -1190,9 +1204,7 @@ void ieee80211_send_addba_request(struct net_device *dev, const u8 *da,
1190 struct ieee80211_mgmt *mgmt; 1204 struct ieee80211_mgmt *mgmt;
1191 u16 capab; 1205 u16 capab;
1192 1206
1193 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + 1207 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1194 sizeof(mgmt->u.action.u.addba_req));
1195
1196 1208
1197 if (!skb) { 1209 if (!skb) {
1198 printk(KERN_ERR "%s: failed to allocate buffer " 1210 printk(KERN_ERR "%s: failed to allocate buffer "
@@ -1293,7 +1305,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1293 1305
1294 1306
1295 /* examine state machine */ 1307 /* examine state machine */
1296 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1308 spin_lock_bh(&sta->lock);
1297 1309
1298 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { 1310 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1299#ifdef CONFIG_MAC80211_HT_DEBUG 1311#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -1360,7 +1372,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1360 tid_agg_rx->stored_mpdu_num = 0; 1372 tid_agg_rx->stored_mpdu_num = 0;
1361 status = WLAN_STATUS_SUCCESS; 1373 status = WLAN_STATUS_SUCCESS;
1362end: 1374end:
1363 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1375 spin_unlock_bh(&sta->lock);
1364 1376
1365end_no_lock: 1377end_no_lock:
1366 ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, 1378 ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid,
@@ -1392,10 +1404,10 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1392 1404
1393 state = &sta->ampdu_mlme.tid_state_tx[tid]; 1405 state = &sta->ampdu_mlme.tid_state_tx[tid];
1394 1406
1395 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1407 spin_lock_bh(&sta->lock);
1396 1408
1397 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 1409 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1398 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1410 spin_unlock_bh(&sta->lock);
1399 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" 1411 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
1400 "%d\n", *state); 1412 "%d\n", *state);
1401 goto addba_resp_exit; 1413 goto addba_resp_exit;
@@ -1403,7 +1415,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1403 1415
1404 if (mgmt->u.action.u.addba_resp.dialog_token != 1416 if (mgmt->u.action.u.addba_resp.dialog_token !=
1405 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 1417 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1406 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1418 spin_unlock_bh(&sta->lock);
1407#ifdef CONFIG_MAC80211_HT_DEBUG 1419#ifdef CONFIG_MAC80211_HT_DEBUG
1408 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 1420 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1409#endif /* CONFIG_MAC80211_HT_DEBUG */ 1421#endif /* CONFIG_MAC80211_HT_DEBUG */
@@ -1427,7 +1439,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1427 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 1439 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
1428 } 1440 }
1429 1441
1430 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1442 spin_unlock_bh(&sta->lock);
1431 printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); 1443 printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid);
1432 } else { 1444 } else {
1433 printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); 1445 printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid);
@@ -1435,7 +1447,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1435 sta->ampdu_mlme.addba_req_num[tid]++; 1447 sta->ampdu_mlme.addba_req_num[tid]++;
1436 /* this will allow the state check in stop_BA_session */ 1448 /* this will allow the state check in stop_BA_session */
1437 *state = HT_AGG_STATE_OPERATIONAL; 1449 *state = HT_AGG_STATE_OPERATIONAL;
1438 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1450 spin_unlock_bh(&sta->lock);
1439 ieee80211_stop_tx_ba_session(hw, sta->addr, tid, 1451 ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
1440 WLAN_BACK_INITIATOR); 1452 WLAN_BACK_INITIATOR);
1441 } 1453 }
@@ -1454,8 +1466,7 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
1454 struct ieee80211_mgmt *mgmt; 1466 struct ieee80211_mgmt *mgmt;
1455 u16 params; 1467 u16 params;
1456 1468
1457 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + 1469 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1458 sizeof(mgmt->u.action.u.delba));
1459 1470
1460 if (!skb) { 1471 if (!skb) {
1461 printk(KERN_ERR "%s: failed to allocate buffer " 1472 printk(KERN_ERR "%s: failed to allocate buffer "
@@ -1506,17 +1517,17 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1506 } 1517 }
1507 1518
1508 /* check if TID is in operational state */ 1519 /* check if TID is in operational state */
1509 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1520 spin_lock_bh(&sta->lock);
1510 if (sta->ampdu_mlme.tid_state_rx[tid] 1521 if (sta->ampdu_mlme.tid_state_rx[tid]
1511 != HT_AGG_STATE_OPERATIONAL) { 1522 != HT_AGG_STATE_OPERATIONAL) {
1512 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1523 spin_unlock_bh(&sta->lock);
1513 rcu_read_unlock(); 1524 rcu_read_unlock();
1514 return; 1525 return;
1515 } 1526 }
1516 sta->ampdu_mlme.tid_state_rx[tid] = 1527 sta->ampdu_mlme.tid_state_rx[tid] =
1517 HT_AGG_STATE_REQ_STOP_BA_MSK | 1528 HT_AGG_STATE_REQ_STOP_BA_MSK |
1518 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 1529 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1519 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1530 spin_unlock_bh(&sta->lock);
1520 1531
1521 /* stop HW Rx aggregation. ampdu_action existence 1532 /* stop HW Rx aggregation. ampdu_action existence
1522 * already verified in session init so we add the BUG_ON */ 1533 * already verified in session init so we add the BUG_ON */
@@ -1593,10 +1604,10 @@ static void ieee80211_sta_process_delba(struct net_device *dev,
1593 ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, 1604 ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid,
1594 WLAN_BACK_INITIATOR, 0); 1605 WLAN_BACK_INITIATOR, 0);
1595 else { /* WLAN_BACK_RECIPIENT */ 1606 else { /* WLAN_BACK_RECIPIENT */
1596 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1607 spin_lock_bh(&sta->lock);
1597 sta->ampdu_mlme.tid_state_tx[tid] = 1608 sta->ampdu_mlme.tid_state_tx[tid] =
1598 HT_AGG_STATE_OPERATIONAL; 1609 HT_AGG_STATE_OPERATIONAL;
1599 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1610 spin_unlock_bh(&sta->lock);
1600 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, 1611 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
1601 WLAN_BACK_RECIPIENT); 1612 WLAN_BACK_RECIPIENT);
1602 } 1613 }
@@ -1633,9 +1644,9 @@ void sta_addba_resp_timer_expired(unsigned long data)
1633 1644
1634 state = &sta->ampdu_mlme.tid_state_tx[tid]; 1645 state = &sta->ampdu_mlme.tid_state_tx[tid];
1635 /* check if the TID waits for addBA response */ 1646 /* check if the TID waits for addBA response */
1636 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1647 spin_lock_bh(&sta->lock);
1637 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 1648 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1638 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1649 spin_unlock_bh(&sta->lock);
1639 *state = HT_AGG_STATE_IDLE; 1650 *state = HT_AGG_STATE_IDLE;
1640 printk(KERN_DEBUG "timer expired on tid %d but we are not " 1651 printk(KERN_DEBUG "timer expired on tid %d but we are not "
1641 "expecting addBA response there", tid); 1652 "expecting addBA response there", tid);
@@ -1646,7 +1657,7 @@ void sta_addba_resp_timer_expired(unsigned long data)
1646 1657
1647 /* go through the state check in stop_BA_session */ 1658 /* go through the state check in stop_BA_session */
1648 *state = HT_AGG_STATE_OPERATIONAL; 1659 *state = HT_AGG_STATE_OPERATIONAL;
1649 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1660 spin_unlock_bh(&sta->lock);
1650 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, 1661 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
1651 WLAN_BACK_INITIATOR); 1662 WLAN_BACK_INITIATOR);
1652 1663
@@ -1659,7 +1670,7 @@ timer_expired_exit:
1659 * resetting it after each frame that arrives from the originator. 1670 * resetting it after each frame that arrives from the originator.
1660 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed. 1671 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
1661 */ 1672 */
1662void sta_rx_agg_session_timer_expired(unsigned long data) 1673static void sta_rx_agg_session_timer_expired(unsigned long data)
1663{ 1674{
1664 /* not an elegant detour, but there is no choice as the timer passes 1675 /* not an elegant detour, but there is no choice as the timer passes
1665 * only one argument, and various sta_info are needed here, so init 1676 * only one argument, and various sta_info are needed here, so init
@@ -1848,9 +1859,8 @@ static void ieee80211_rx_mgmt_deauth(struct net_device *dev,
1848 " (reason=%d)\n", 1859 " (reason=%d)\n",
1849 dev->name, print_mac(mac, mgmt->sa), reason_code); 1860 dev->name, print_mac(mac, mgmt->sa), reason_code);
1850 1861
1851 if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) { 1862 if (ifsta->flags & IEEE80211_STA_AUTHENTICATED)
1852 printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); 1863 printk(KERN_DEBUG "%s: deauthenticated\n", dev->name);
1853 }
1854 1864
1855 if (ifsta->state == IEEE80211_AUTHENTICATE || 1865 if (ifsta->state == IEEE80211_AUTHENTICATE ||
1856 ifsta->state == IEEE80211_ASSOCIATE || 1866 ifsta->state == IEEE80211_ASSOCIATE ||
@@ -2013,8 +2023,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2013 local->hw.conf.channel->center_freq, 2023 local->hw.conf.channel->center_freq,
2014 ifsta->ssid, ifsta->ssid_len); 2024 ifsta->ssid, ifsta->ssid_len);
2015 if (bss) { 2025 if (bss) {
2016 sta->last_rssi = bss->rssi;
2017 sta->last_signal = bss->signal; 2026 sta->last_signal = bss->signal;
2027 sta->last_qual = bss->qual;
2018 sta->last_noise = bss->noise; 2028 sta->last_noise = bss->noise;
2019 ieee80211_rx_bss_put(dev, bss); 2029 ieee80211_rx_bss_put(dev, bss);
2020 } 2030 }
@@ -2038,8 +2048,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2038 * to between the sta_info_alloc() and sta_info_insert() above. 2048 * to between the sta_info_alloc() and sta_info_insert() above.
2039 */ 2049 */
2040 2050
2041 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | 2051 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
2042 WLAN_STA_AUTHORIZED; 2052 WLAN_STA_AUTHORIZED);
2043 2053
2044 rates = 0; 2054 rates = 0;
2045 basic_rates = 0; 2055 basic_rates = 0;
@@ -2083,7 +2093,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2083 else 2093 else
2084 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; 2094 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
2085 2095
2086 if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { 2096 if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
2097 (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
2087 struct ieee80211_ht_bss_info bss_info; 2098 struct ieee80211_ht_bss_info bss_info;
2088 ieee80211_ht_cap_ie_to_ht_info( 2099 ieee80211_ht_cap_ie_to_ht_info(
2089 (struct ieee80211_ht_cap *) 2100 (struct ieee80211_ht_cap *)
@@ -2096,8 +2107,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2096 2107
2097 rate_control_rate_init(sta, local); 2108 rate_control_rate_init(sta, local);
2098 2109
2099 if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { 2110 if (elems.wmm_param) {
2100 sta->flags |= WLAN_STA_WME; 2111 set_sta_flags(sta, WLAN_STA_WME);
2101 rcu_read_unlock(); 2112 rcu_read_unlock();
2102 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, 2113 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param,
2103 elems.wmm_param_len); 2114 elems.wmm_param_len);
@@ -2281,6 +2292,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
2281 kfree(bss->rsn_ie); 2292 kfree(bss->rsn_ie);
2282 kfree(bss->wmm_ie); 2293 kfree(bss->wmm_ie);
2283 kfree(bss->ht_ie); 2294 kfree(bss->ht_ie);
2295 kfree(bss->ht_add_ie);
2284 kfree(bss_mesh_id(bss)); 2296 kfree(bss_mesh_id(bss));
2285 kfree(bss_mesh_cfg(bss)); 2297 kfree(bss_mesh_cfg(bss));
2286 kfree(bss); 2298 kfree(bss);
@@ -2331,7 +2343,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2331 int res, rates, i, j; 2343 int res, rates, i, j;
2332 struct sk_buff *skb; 2344 struct sk_buff *skb;
2333 struct ieee80211_mgmt *mgmt; 2345 struct ieee80211_mgmt *mgmt;
2334 struct ieee80211_tx_control control; 2346 struct ieee80211_tx_info *control;
2335 struct rate_selection ratesel; 2347 struct rate_selection ratesel;
2336 u8 *pos; 2348 u8 *pos;
2337 struct ieee80211_sub_if_data *sdata; 2349 struct ieee80211_sub_if_data *sdata;
@@ -2419,21 +2431,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2419 memcpy(pos, &bss->supp_rates[8], rates); 2431 memcpy(pos, &bss->supp_rates[8], rates);
2420 } 2432 }
2421 2433
2422 memset(&control, 0, sizeof(control)); 2434 control = IEEE80211_SKB_CB(skb);
2435
2423 rate_control_get_rate(dev, sband, skb, &ratesel); 2436 rate_control_get_rate(dev, sband, skb, &ratesel);
2424 if (!ratesel.rate) { 2437 if (ratesel.rate_idx < 0) {
2425 printk(KERN_DEBUG "%s: Failed to determine TX rate " 2438 printk(KERN_DEBUG "%s: Failed to determine TX rate "
2426 "for IBSS beacon\n", dev->name); 2439 "for IBSS beacon\n", dev->name);
2427 break; 2440 break;
2428 } 2441 }
2429 control.vif = &sdata->vif; 2442 control->control.vif = &sdata->vif;
2430 control.tx_rate = ratesel.rate; 2443 control->tx_rate_idx = ratesel.rate_idx;
2431 if (sdata->bss_conf.use_short_preamble && 2444 if (sdata->bss_conf.use_short_preamble &&
2432 ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) 2445 sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
2433 control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; 2446 control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
2434 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; 2447 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
2435 control.flags |= IEEE80211_TXCTL_NO_ACK; 2448 control->flags |= IEEE80211_TX_CTL_NO_ACK;
2436 control.retry_limit = 1; 2449 control->control.retry_limit = 1;
2437 2450
2438 ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); 2451 ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
2439 if (ifsta->probe_resp) { 2452 if (ifsta->probe_resp) {
@@ -2448,8 +2461,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2448 } 2461 }
2449 2462
2450 if (local->ops->beacon_update && 2463 if (local->ops->beacon_update &&
2451 local->ops->beacon_update(local_to_hw(local), 2464 local->ops->beacon_update(local_to_hw(local), skb) == 0) {
2452 skb, &control) == 0) {
2453 printk(KERN_DEBUG "%s: Configured IBSS beacon " 2465 printk(KERN_DEBUG "%s: Configured IBSS beacon "
2454 "template\n", dev->name); 2466 "template\n", dev->name);
2455 skb = NULL; 2467 skb = NULL;
@@ -2657,6 +2669,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2657 bss->ht_ie_len = 0; 2669 bss->ht_ie_len = 0;
2658 } 2670 }
2659 2671
2672 if (elems.ht_info_elem &&
2673 (!bss->ht_add_ie ||
2674 bss->ht_add_ie_len != elems.ht_info_elem_len ||
2675 memcmp(bss->ht_add_ie, elems.ht_info_elem,
2676 elems.ht_info_elem_len))) {
2677 kfree(bss->ht_add_ie);
2678 bss->ht_add_ie =
2679 kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC);
2680 if (bss->ht_add_ie) {
2681 memcpy(bss->ht_add_ie, elems.ht_info_elem - 2,
2682 elems.ht_info_elem_len + 2);
2683 bss->ht_add_ie_len = elems.ht_info_elem_len + 2;
2684 } else
2685 bss->ht_add_ie_len = 0;
2686 } else if (!elems.ht_info_elem && bss->ht_add_ie) {
2687 kfree(bss->ht_add_ie);
2688 bss->ht_add_ie = NULL;
2689 bss->ht_add_ie_len = 0;
2690 }
2691
2660 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); 2692 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
2661 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); 2693 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
2662 2694
@@ -2682,9 +2714,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2682 2714
2683 bss->timestamp = beacon_timestamp; 2715 bss->timestamp = beacon_timestamp;
2684 bss->last_update = jiffies; 2716 bss->last_update = jiffies;
2685 bss->rssi = rx_status->ssi;
2686 bss->signal = rx_status->signal; 2717 bss->signal = rx_status->signal;
2687 bss->noise = rx_status->noise; 2718 bss->noise = rx_status->noise;
2719 bss->qual = rx_status->qual;
2688 if (!beacon && !bss->probe_resp) 2720 if (!beacon && !bss->probe_resp)
2689 bss->probe_resp = true; 2721 bss->probe_resp = true;
2690 2722
@@ -2879,10 +2911,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
2879 2911
2880 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); 2912 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
2881 2913
2882 if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { 2914 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param,
2883 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, 2915 elems.wmm_param_len);
2884 elems.wmm_param_len);
2885 }
2886 2916
2887 /* Do not send changes to driver if we are scanning. This removes 2917 /* Do not send changes to driver if we are scanning. This removes
2888 * requirement that driver's bss_info_changed function needs to be 2918 * requirement that driver's bss_info_changed function needs to be
@@ -3478,9 +3508,9 @@ static int ieee80211_sta_config_auth(struct net_device *dev,
3478 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) 3508 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
3479 continue; 3509 continue;
3480 3510
3481 if (!selected || top_rssi < bss->rssi) { 3511 if (!selected || top_rssi < bss->signal) {
3482 selected = bss; 3512 selected = bss;
3483 top_rssi = bss->rssi; 3513 top_rssi = bss->signal;
3484 } 3514 }
3485 } 3515 }
3486 if (selected) 3516 if (selected)
@@ -3557,10 +3587,12 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
3557 bss->beacon_int = local->hw.conf.beacon_int; 3587 bss->beacon_int = local->hw.conf.beacon_int;
3558 bss->last_update = jiffies; 3588 bss->last_update = jiffies;
3559 bss->capability = WLAN_CAPABILITY_IBSS; 3589 bss->capability = WLAN_CAPABILITY_IBSS;
3560 if (sdata->default_key) { 3590
3591 if (sdata->default_key)
3561 bss->capability |= WLAN_CAPABILITY_PRIVACY; 3592 bss->capability |= WLAN_CAPABILITY_PRIVACY;
3562 } else 3593 else
3563 sdata->drop_unencrypted = 0; 3594 sdata->drop_unencrypted = 0;
3595
3564 bss->supp_rates_len = sband->n_bitrates; 3596 bss->supp_rates_len = sband->n_bitrates;
3565 pos = bss->supp_rates; 3597 pos = bss->supp_rates;
3566 for (i = 0; i < sband->n_bitrates; i++) { 3598 for (i = 0; i < sband->n_bitrates; i++) {
@@ -4114,8 +4146,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
4114 IW_EV_FREQ_LEN); 4146 IW_EV_FREQ_LEN);
4115 memset(&iwe, 0, sizeof(iwe)); 4147 memset(&iwe, 0, sizeof(iwe));
4116 iwe.cmd = IWEVQUAL; 4148 iwe.cmd = IWEVQUAL;
4117 iwe.u.qual.qual = bss->signal; 4149 iwe.u.qual.qual = bss->qual;
4118 iwe.u.qual.level = bss->rssi; 4150 iwe.u.qual.level = bss->signal;
4119 iwe.u.qual.noise = bss->noise; 4151 iwe.u.qual.noise = bss->noise;
4120 iwe.u.qual.updated = local->wstats_flags; 4152 iwe.u.qual.updated = local->wstats_flags;
4121 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4153 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
@@ -4146,6 +4178,14 @@ ieee80211_sta_scan_result(struct net_device *dev,
4146 bss->rsn_ie); 4178 bss->rsn_ie);
4147 } 4179 }
4148 4180
4181 if (bss && bss->ht_ie) {
4182 memset(&iwe, 0, sizeof(iwe));
4183 iwe.cmd = IWEVGENIE;
4184 iwe.u.data.length = bss->ht_ie_len;
4185 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
4186 bss->ht_ie);
4187 }
4188
4149 if (bss && bss->supp_rates_len > 0) { 4189 if (bss && bss->supp_rates_len > 0) {
4150 /* display all supported rates in readable format */ 4190 /* display all supported rates in readable format */
4151 char *p = current_ev + IW_EV_LCP_LEN; 4191 char *p = current_ev + IW_EV_LCP_LEN;
@@ -4247,6 +4287,7 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
4247{ 4287{
4248 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 4288 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4249 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 4289 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4290
4250 kfree(ifsta->extra_ie); 4291 kfree(ifsta->extra_ie);
4251 if (len == 0) { 4292 if (len == 0) {
4252 ifsta->extra_ie = NULL; 4293 ifsta->extra_ie = NULL;
@@ -4264,9 +4305,9 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
4264} 4305}
4265 4306
4266 4307
4267struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, 4308struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev,
4268 struct sk_buff *skb, u8 *bssid, 4309 struct sk_buff *skb, u8 *bssid,
4269 u8 *addr) 4310 u8 *addr)
4270{ 4311{
4271 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 4312 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
4272 struct sta_info *sta; 4313 struct sta_info *sta;
@@ -4290,7 +4331,7 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
4290 if (!sta) 4331 if (!sta)
4291 return NULL; 4332 return NULL;
4292 4333
4293 sta->flags |= WLAN_STA_AUTHORIZED; 4334 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
4294 4335
4295 sta->supp_rates[local->hw.conf.channel->band] = 4336 sta->supp_rates[local->hw.conf.channel->band] =
4296 sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; 4337 sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band];
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 841df93807fc..0388c090dfe9 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -176,20 +176,24 @@ void rate_control_get_rate(struct net_device *dev,
176 rcu_read_lock(); 176 rcu_read_lock();
177 sta = sta_info_get(local, hdr->addr1); 177 sta = sta_info_get(local, hdr->addr1);
178 178
179 memset(sel, 0, sizeof(struct rate_selection)); 179 sel->rate_idx = -1;
180 sel->nonerp_idx = -1;
181 sel->probe_idx = -1;
180 182
181 ref->ops->get_rate(ref->priv, dev, sband, skb, sel); 183 ref->ops->get_rate(ref->priv, dev, sband, skb, sel);
182 184
185 BUG_ON(sel->rate_idx < 0);
186
183 /* Select a non-ERP backup rate. */ 187 /* Select a non-ERP backup rate. */
184 if (!sel->nonerp) { 188 if (sel->nonerp_idx < 0) {
185 for (i = 0; i < sband->n_bitrates; i++) { 189 for (i = 0; i < sband->n_bitrates; i++) {
186 struct ieee80211_rate *rate = &sband->bitrates[i]; 190 struct ieee80211_rate *rate = &sband->bitrates[i];
187 if (sel->rate->bitrate < rate->bitrate) 191 if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate)
188 break; 192 break;
189 193
190 if (rate_supported(sta, sband->band, i) && 194 if (rate_supported(sta, sband->band, i) &&
191 !(rate->flags & IEEE80211_RATE_ERP_G)) 195 !(rate->flags & IEEE80211_RATE_ERP_G))
192 sel->nonerp = rate; 196 sel->nonerp_idx = i;
193 } 197 }
194 } 198 }
195 199
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 5b45f33cb766..0ed9c8a2f56f 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -19,22 +19,22 @@
19#include "ieee80211_i.h" 19#include "ieee80211_i.h"
20#include "sta_info.h" 20#include "sta_info.h"
21 21
22/* TODO: kdoc */ 22/**
23 * struct rate_selection - rate selection for rate control algos
24 * @rate: selected transmission rate index
25 * @nonerp: Non-ERP rate to use instead if ERP cannot be used
26 * @probe: rate for probing (or -1)
27 *
28 */
23struct rate_selection { 29struct rate_selection {
24 /* Selected transmission rate */ 30 s8 rate_idx, nonerp_idx, probe_idx;
25 struct ieee80211_rate *rate;
26 /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */
27 struct ieee80211_rate *nonerp;
28 /* probe with this rate, or NULL for no probing */
29 struct ieee80211_rate *probe;
30}; 31};
31 32
32struct rate_control_ops { 33struct rate_control_ops {
33 struct module *module; 34 struct module *module;
34 const char *name; 35 const char *name;
35 void (*tx_status)(void *priv, struct net_device *dev, 36 void (*tx_status)(void *priv, struct net_device *dev,
36 struct sk_buff *skb, 37 struct sk_buff *skb);
37 struct ieee80211_tx_status *status);
38 void (*get_rate)(void *priv, struct net_device *dev, 38 void (*get_rate)(void *priv, struct net_device *dev,
39 struct ieee80211_supported_band *band, 39 struct ieee80211_supported_band *band,
40 struct sk_buff *skb, 40 struct sk_buff *skb,
@@ -76,13 +76,12 @@ struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
76void rate_control_put(struct rate_control_ref *ref); 76void rate_control_put(struct rate_control_ref *ref);
77 77
78static inline void rate_control_tx_status(struct net_device *dev, 78static inline void rate_control_tx_status(struct net_device *dev,
79 struct sk_buff *skb, 79 struct sk_buff *skb)
80 struct ieee80211_tx_status *status)
81{ 80{
82 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 81 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
83 struct rate_control_ref *ref = local->rate_ctrl; 82 struct rate_control_ref *ref = local->rate_ctrl;
84 83
85 ref->ops->tx_status(ref->priv, dev, skb, status); 84 ref->ops->tx_status(ref->priv, dev, skb);
86} 85}
87 86
88 87
@@ -138,7 +137,7 @@ static inline int rate_supported(struct sta_info *sta,
138 return (sta == NULL || sta->supp_rates[band] & BIT(index)); 137 return (sta == NULL || sta->supp_rates[band] & BIT(index));
139} 138}
140 139
141static inline int 140static inline s8
142rate_lowest_index(struct ieee80211_local *local, 141rate_lowest_index(struct ieee80211_local *local,
143 struct ieee80211_supported_band *sband, 142 struct ieee80211_supported_band *sband,
144 struct sta_info *sta) 143 struct sta_info *sta)
@@ -155,14 +154,6 @@ rate_lowest_index(struct ieee80211_local *local,
155 return 0; 154 return 0;
156} 155}
157 156
158static inline struct ieee80211_rate *
159rate_lowest(struct ieee80211_local *local,
160 struct ieee80211_supported_band *sband,
161 struct sta_info *sta)
162{
163 return &sband->bitrates[rate_lowest_index(local, sband, sta)];
164}
165
166 157
167/* functions for rate control related to a device */ 158/* functions for rate control related to a device */
168int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 159int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h
index 04afc13ed825..2078803d3581 100644
--- a/net/mac80211/rc80211_pid.h
+++ b/net/mac80211/rc80211_pid.h
@@ -61,7 +61,7 @@ enum rc_pid_event_type {
61union rc_pid_event_data { 61union rc_pid_event_data {
62 /* RC_PID_EVENT_TX_STATUS */ 62 /* RC_PID_EVENT_TX_STATUS */
63 struct { 63 struct {
64 struct ieee80211_tx_status tx_status; 64 struct ieee80211_tx_info tx_status;
65 }; 65 };
66 /* RC_PID_EVENT_TYPE_RATE_CHANGE */ 66 /* RC_PID_EVENT_TYPE_RATE_CHANGE */
67 /* RC_PID_EVENT_TYPE_TX_RATE */ 67 /* RC_PID_EVENT_TYPE_TX_RATE */
@@ -158,7 +158,7 @@ struct rc_pid_debugfs_entries {
158}; 158};
159 159
160void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, 160void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
161 struct ieee80211_tx_status *stat); 161 struct ieee80211_tx_info *stat);
162 162
163void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf, 163void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
164 int index, int rate); 164 int index, int rate);
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index a849b745bdb5..e8945413e4a2 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -237,8 +237,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
237} 237}
238 238
239static void rate_control_pid_tx_status(void *priv, struct net_device *dev, 239static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
240 struct sk_buff *skb, 240 struct sk_buff *skb)
241 struct ieee80211_tx_status *status)
242{ 241{
243 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 242 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
244 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 243 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -248,6 +247,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
248 struct rc_pid_sta_info *spinfo; 247 struct rc_pid_sta_info *spinfo;
249 unsigned long period; 248 unsigned long period;
250 struct ieee80211_supported_band *sband; 249 struct ieee80211_supported_band *sband;
250 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
251 251
252 rcu_read_lock(); 252 rcu_read_lock();
253 253
@@ -266,28 +266,28 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
266 266
267 /* Ignore all frames that were sent with a different rate than the rate 267 /* Ignore all frames that were sent with a different rate than the rate
268 * we currently advise mac80211 to use. */ 268 * we currently advise mac80211 to use. */
269 if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx]) 269 if (info->tx_rate_idx != sta->txrate_idx)
270 goto unlock; 270 goto unlock;
271 271
272 spinfo = sta->rate_ctrl_priv; 272 spinfo = sta->rate_ctrl_priv;
273 spinfo->tx_num_xmit++; 273 spinfo->tx_num_xmit++;
274 274
275#ifdef CONFIG_MAC80211_DEBUGFS 275#ifdef CONFIG_MAC80211_DEBUGFS
276 rate_control_pid_event_tx_status(&spinfo->events, status); 276 rate_control_pid_event_tx_status(&spinfo->events, info);
277#endif 277#endif
278 278
279 /* We count frames that totally failed to be transmitted as two bad 279 /* We count frames that totally failed to be transmitted as two bad
280 * frames, those that made it out but had some retries as one good and 280 * frames, those that made it out but had some retries as one good and
281 * one bad frame. */ 281 * one bad frame. */
282 if (status->excessive_retries) { 282 if (info->status.excessive_retries) {
283 spinfo->tx_num_failed += 2; 283 spinfo->tx_num_failed += 2;
284 spinfo->tx_num_xmit++; 284 spinfo->tx_num_xmit++;
285 } else if (status->retry_count) { 285 } else if (info->status.retry_count) {
286 spinfo->tx_num_failed++; 286 spinfo->tx_num_failed++;
287 spinfo->tx_num_xmit++; 287 spinfo->tx_num_xmit++;
288 } 288 }
289 289
290 if (status->excessive_retries) { 290 if (info->status.excessive_retries) {
291 sta->tx_retry_failed++; 291 sta->tx_retry_failed++;
292 sta->tx_num_consecutive_failures++; 292 sta->tx_num_consecutive_failures++;
293 sta->tx_num_mpdu_fail++; 293 sta->tx_num_mpdu_fail++;
@@ -295,8 +295,8 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
295 sta->tx_num_consecutive_failures = 0; 295 sta->tx_num_consecutive_failures = 0;
296 sta->tx_num_mpdu_ok++; 296 sta->tx_num_mpdu_ok++;
297 } 297 }
298 sta->tx_retry_count += status->retry_count; 298 sta->tx_retry_count += info->status.retry_count;
299 sta->tx_num_mpdu_fail += status->retry_count; 299 sta->tx_num_mpdu_fail += info->status.retry_count;
300 300
301 /* Update PID controller state. */ 301 /* Update PID controller state. */
302 period = (HZ * pinfo->sampling_period + 500) / 1000; 302 period = (HZ * pinfo->sampling_period + 500) / 1000;
@@ -330,7 +330,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
330 fc = le16_to_cpu(hdr->frame_control); 330 fc = le16_to_cpu(hdr->frame_control);
331 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || 331 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
332 is_multicast_ether_addr(hdr->addr1) || !sta) { 332 is_multicast_ether_addr(hdr->addr1) || !sta) {
333 sel->rate = rate_lowest(local, sband, sta); 333 sel->rate_idx = rate_lowest_index(local, sband, sta);
334 rcu_read_unlock(); 334 rcu_read_unlock();
335 return; 335 return;
336 } 336 }
@@ -349,7 +349,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
349 349
350 rcu_read_unlock(); 350 rcu_read_unlock();
351 351
352 sel->rate = &sband->bitrates[rateidx]; 352 sel->rate_idx = rateidx;
353 353
354#ifdef CONFIG_MAC80211_DEBUGFS 354#ifdef CONFIG_MAC80211_DEBUGFS
355 rate_control_pid_event_tx_rate( 355 rate_control_pid_event_tx_rate(
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index ff5c380f3c13..8121d3bc6835 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -39,11 +39,11 @@ static void rate_control_pid_event(struct rc_pid_event_buffer *buf,
39} 39}
40 40
41void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, 41void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
42 struct ieee80211_tx_status *stat) 42 struct ieee80211_tx_info *stat)
43{ 43{
44 union rc_pid_event_data evd; 44 union rc_pid_event_data evd;
45 45
46 memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_status)); 46 memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info));
47 rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); 47 rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd);
48} 48}
49 49
@@ -167,8 +167,8 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
167 switch (ev->type) { 167 switch (ev->type) {
168 case RC_PID_EVENT_TYPE_TX_STATUS: 168 case RC_PID_EVENT_TYPE_TX_STATUS:
169 p += snprintf(pb + p, length - p, "tx_status %u %u", 169 p += snprintf(pb + p, length - p, "tx_status %u %u",
170 ev->data.tx_status.excessive_retries, 170 ev->data.tx_status.status.excessive_retries,
171 ev->data.tx_status.retry_count); 171 ev->data.tx_status.status.retry_count);
172 break; 172 break;
173 case RC_PID_EVENT_TYPE_RATE_CHANGE: 173 case RC_PID_EVENT_TYPE_RATE_CHANGE:
174 p += snprintf(pb + p, length - p, "rate_change %d %d", 174 p += snprintf(pb + p, length - p, "rate_change %d %d",
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 0941e5d6a522..a3643fd86af9 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -77,6 +77,134 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status,
77 return 0; 77 return 0;
78} 78}
79 79
80static int
81ieee80211_rx_radiotap_len(struct ieee80211_local *local,
82 struct ieee80211_rx_status *status)
83{
84 int len;
85
86 /* always present fields */
87 len = sizeof(struct ieee80211_radiotap_header) + 9;
88
89 if (status->flag & RX_FLAG_TSFT)
90 len += 8;
91 if (local->hw.flags & IEEE80211_HW_SIGNAL_DB ||
92 local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
93 len += 1;
94 if (local->hw.flags & IEEE80211_HW_NOISE_DBM)
95 len += 1;
96
97 if (len & 1) /* padding for RX_FLAGS if necessary */
98 len++;
99
100 /* make sure radiotap starts at a naturally aligned address */
101 if (len % 8)
102 len = roundup(len, 8);
103
104 return len;
105}
106
107/**
108 * ieee80211_add_rx_radiotap_header - add radiotap header
109 *
110 * add a radiotap header containing all the fields which the hardware provided.
111 */
112static void
113ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
114 struct sk_buff *skb,
115 struct ieee80211_rx_status *status,
116 struct ieee80211_rate *rate,
117 int rtap_len)
118{
119 struct ieee80211_radiotap_header *rthdr;
120 unsigned char *pos;
121
122 rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
123 memset(rthdr, 0, rtap_len);
124
125 /* radiotap header, set always present flags */
126 rthdr->it_present =
127 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
128 (1 << IEEE80211_RADIOTAP_RATE) |
129 (1 << IEEE80211_RADIOTAP_CHANNEL) |
130 (1 << IEEE80211_RADIOTAP_ANTENNA) |
131 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
132 rthdr->it_len = cpu_to_le16(rtap_len);
133
134 pos = (unsigned char *)(rthdr+1);
135
136 /* the order of the following fields is important */
137
138 /* IEEE80211_RADIOTAP_TSFT */
139 if (status->flag & RX_FLAG_TSFT) {
140 *(__le64 *)pos = cpu_to_le64(status->mactime);
141 rthdr->it_present |=
142 cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
143 pos += 8;
144 }
145
146 /* IEEE80211_RADIOTAP_FLAGS */
147 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
148 *pos |= IEEE80211_RADIOTAP_F_FCS;
149 pos++;
150
151 /* IEEE80211_RADIOTAP_RATE */
152 *pos = rate->bitrate / 5;
153 pos++;
154
155 /* IEEE80211_RADIOTAP_CHANNEL */
156 *(__le16 *)pos = cpu_to_le16(status->freq);
157 pos += 2;
158 if (status->band == IEEE80211_BAND_5GHZ)
159 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM |
160 IEEE80211_CHAN_5GHZ);
161 else
162 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_DYN |
163 IEEE80211_CHAN_2GHZ);
164 pos += 2;
165
166 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
167 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
168 *pos = status->signal;
169 rthdr->it_present |=
170 cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
171 pos++;
172 }
173
174 /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
175 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
176 *pos = status->noise;
177 rthdr->it_present |=
178 cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
179 pos++;
180 }
181
182 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */
183
184 /* IEEE80211_RADIOTAP_ANTENNA */
185 *pos = status->antenna;
186 pos++;
187
188 /* IEEE80211_RADIOTAP_DB_ANTSIGNAL */
189 if (local->hw.flags & IEEE80211_HW_SIGNAL_DB) {
190 *pos = status->signal;
191 rthdr->it_present |=
192 cpu_to_le32(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL);
193 pos++;
194 }
195
196 /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */
197
198 /* IEEE80211_RADIOTAP_RX_FLAGS */
199 /* ensure 2 byte alignment for the 2 byte field as required */
200 if ((pos - (unsigned char *)rthdr) & 1)
201 pos++;
202 /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */
203 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
204 *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS);
205 pos += 2;
206}
207
80/* 208/*
81 * This function copies a received frame to all monitor interfaces and 209 * This function copies a received frame to all monitor interfaces and
82 * returns a cleaned-up SKB that no longer includes the FCS nor the 210 * returns a cleaned-up SKB that no longer includes the FCS nor the
@@ -89,17 +217,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
89{ 217{
90 struct ieee80211_sub_if_data *sdata; 218 struct ieee80211_sub_if_data *sdata;
91 int needed_headroom = 0; 219 int needed_headroom = 0;
92 struct ieee80211_radiotap_header *rthdr;
93 __le64 *rttsft = NULL;
94 struct ieee80211_rtap_fixed_data {
95 u8 flags;
96 u8 rate;
97 __le16 chan_freq;
98 __le16 chan_flags;
99 u8 antsignal;
100 u8 padding_for_rxflags;
101 __le16 rx_flags;
102 } __attribute__ ((packed)) *rtfixed;
103 struct sk_buff *skb, *skb2; 220 struct sk_buff *skb, *skb2;
104 struct net_device *prev_dev = NULL; 221 struct net_device *prev_dev = NULL;
105 int present_fcs_len = 0; 222 int present_fcs_len = 0;
@@ -116,8 +233,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
116 if (status->flag & RX_FLAG_RADIOTAP) 233 if (status->flag & RX_FLAG_RADIOTAP)
117 rtap_len = ieee80211_get_radiotap_len(origskb->data); 234 rtap_len = ieee80211_get_radiotap_len(origskb->data);
118 else 235 else
119 /* room for radiotap header, always present fields and TSFT */ 236 /* room for the radiotap header based on driver features */
120 needed_headroom = sizeof(*rthdr) + sizeof(*rtfixed) + 8; 237 needed_headroom = ieee80211_rx_radiotap_len(local, status);
121 238
122 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 239 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
123 present_fcs_len = FCS_LEN; 240 present_fcs_len = FCS_LEN;
@@ -163,55 +280,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
163 } 280 }
164 281
165 /* if necessary, prepend radiotap information */ 282 /* if necessary, prepend radiotap information */
166 if (!(status->flag & RX_FLAG_RADIOTAP)) { 283 if (!(status->flag & RX_FLAG_RADIOTAP))
167 rtfixed = (void *) skb_push(skb, sizeof(*rtfixed)); 284 ieee80211_add_rx_radiotap_header(local, skb, status, rate,
168 rtap_len = sizeof(*rthdr) + sizeof(*rtfixed); 285 needed_headroom);
169 if (status->flag & RX_FLAG_TSFT) {
170 rttsft = (void *) skb_push(skb, sizeof(*rttsft));
171 rtap_len += 8;
172 }
173 rthdr = (void *) skb_push(skb, sizeof(*rthdr));
174 memset(rthdr, 0, sizeof(*rthdr));
175 memset(rtfixed, 0, sizeof(*rtfixed));
176 rthdr->it_present =
177 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
178 (1 << IEEE80211_RADIOTAP_RATE) |
179 (1 << IEEE80211_RADIOTAP_CHANNEL) |
180 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |
181 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
182 rtfixed->flags = 0;
183 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
184 rtfixed->flags |= IEEE80211_RADIOTAP_F_FCS;
185
186 if (rttsft) {
187 *rttsft = cpu_to_le64(status->mactime);
188 rthdr->it_present |=
189 cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
190 }
191
192 /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */
193 rtfixed->rx_flags = 0;
194 if (status->flag &
195 (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
196 rtfixed->rx_flags |=
197 cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS);
198
199 rtfixed->rate = rate->bitrate / 5;
200
201 rtfixed->chan_freq = cpu_to_le16(status->freq);
202
203 if (status->band == IEEE80211_BAND_5GHZ)
204 rtfixed->chan_flags =
205 cpu_to_le16(IEEE80211_CHAN_OFDM |
206 IEEE80211_CHAN_5GHZ);
207 else
208 rtfixed->chan_flags =
209 cpu_to_le16(IEEE80211_CHAN_DYN |
210 IEEE80211_CHAN_2GHZ);
211
212 rtfixed->antsignal = status->ssi;
213 rthdr->it_len = cpu_to_le16(rtap_len);
214 }
215 286
216 skb_reset_mac_header(skb); 287 skb_reset_mac_header(skb);
217 skb->ip_summed = CHECKSUM_UNNECESSARY; 288 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -275,11 +346,6 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
275 } 346 }
276 } 347 }
277 348
278 I802_DEBUG_INC(rx->local->wme_rx_queue[tid]);
279 /* only a debug counter, sta might not be assigned properly yet */
280 if (rx->sta)
281 I802_DEBUG_INC(rx->sta->wme_rx_queue[tid]);
282
283 rx->queue = tid; 349 rx->queue = tid;
284 /* Set skb->priority to 1d tag if highest order bit of TID is not set. 350 /* Set skb->priority to 1d tag if highest order bit of TID is not set.
285 * For now, set skb->priority to 0 for other cases. */ 351 * For now, set skb->priority to 0 for other cases. */
@@ -321,51 +387,9 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx)
321} 387}
322 388
323 389
324static u32 ieee80211_rx_load_stats(struct ieee80211_local *local,
325 struct sk_buff *skb,
326 struct ieee80211_rx_status *status,
327 struct ieee80211_rate *rate)
328{
329 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
330 u32 load = 0, hdrtime;
331
332 /* Estimate total channel use caused by this frame */
333
334 /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values,
335 * 1 usec = 1/8 * (1080 / 10) = 13.5 */
336
337 if (status->band == IEEE80211_BAND_5GHZ ||
338 (status->band == IEEE80211_BAND_5GHZ &&
339 rate->flags & IEEE80211_RATE_ERP_G))
340 hdrtime = CHAN_UTIL_HDR_SHORT;
341 else
342 hdrtime = CHAN_UTIL_HDR_LONG;
343
344 load = hdrtime;
345 if (!is_multicast_ether_addr(hdr->addr1))
346 load += hdrtime;
347
348 /* TODO: optimise again */
349 load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate;
350
351 /* Divide channel_use by 8 to avoid wrapping around the counter */
352 load >>= CHAN_UTIL_SHIFT;
353
354 return load;
355}
356
357/* rx handlers */ 390/* rx handlers */
358 391
359static ieee80211_rx_result 392static ieee80211_rx_result
360ieee80211_rx_h_if_stats(struct ieee80211_rx_data *rx)
361{
362 if (rx->sta)
363 rx->sta->channel_use_raw += rx->load;
364 rx->sdata->channel_use_raw += rx->load;
365 return RX_CONTINUE;
366}
367
368static ieee80211_rx_result
369ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) 393ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
370{ 394{
371 struct ieee80211_local *local = rx->local; 395 struct ieee80211_local *local = rx->local;
@@ -484,7 +508,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
484 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && 508 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL &&
485 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && 509 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
486 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 510 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
487 (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { 511 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
488 if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && 512 if ((!(rx->fc & IEEE80211_FCTL_FROMDS) &&
489 !(rx->fc & IEEE80211_FCTL_TODS) && 513 !(rx->fc & IEEE80211_FCTL_TODS) &&
490 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) 514 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
@@ -635,8 +659,7 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta)
635 659
636 if (sdata->bss) 660 if (sdata->bss)
637 atomic_inc(&sdata->bss->num_sta_ps); 661 atomic_inc(&sdata->bss->num_sta_ps);
638 sta->flags |= WLAN_STA_PS; 662 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
639 sta->flags &= ~WLAN_STA_PSPOLL;
640#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 663#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
641 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", 664 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n",
642 dev->name, print_mac(mac, sta->addr), sta->aid); 665 dev->name, print_mac(mac, sta->addr), sta->aid);
@@ -649,7 +672,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
649 struct sk_buff *skb; 672 struct sk_buff *skb;
650 int sent = 0; 673 int sent = 0;
651 struct ieee80211_sub_if_data *sdata; 674 struct ieee80211_sub_if_data *sdata;
652 struct ieee80211_tx_packet_data *pkt_data; 675 struct ieee80211_tx_info *info;
653 DECLARE_MAC_BUF(mac); 676 DECLARE_MAC_BUF(mac);
654 677
655 sdata = sta->sdata; 678 sdata = sta->sdata;
@@ -657,7 +680,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
657 if (sdata->bss) 680 if (sdata->bss)
658 atomic_dec(&sdata->bss->num_sta_ps); 681 atomic_dec(&sdata->bss->num_sta_ps);
659 682
660 sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL); 683 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
661 684
662 if (!skb_queue_empty(&sta->ps_tx_buf)) 685 if (!skb_queue_empty(&sta->ps_tx_buf))
663 sta_info_clear_tim_bit(sta); 686 sta_info_clear_tim_bit(sta);
@@ -669,13 +692,13 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
669 692
670 /* Send all buffered frames to the station */ 693 /* Send all buffered frames to the station */
671 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { 694 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) {
672 pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 695 info = IEEE80211_SKB_CB(skb);
673 sent++; 696 sent++;
674 pkt_data->flags |= IEEE80211_TXPD_REQUEUE; 697 info->flags |= IEEE80211_TX_CTL_REQUEUE;
675 dev_queue_xmit(skb); 698 dev_queue_xmit(skb);
676 } 699 }
677 while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { 700 while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
678 pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 701 info = IEEE80211_SKB_CB(skb);
679 local->total_ps_buffered--; 702 local->total_ps_buffered--;
680 sent++; 703 sent++;
681#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 704#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
@@ -683,7 +706,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
683 "since STA not sleeping anymore\n", dev->name, 706 "since STA not sleeping anymore\n", dev->name,
684 print_mac(mac, sta->addr), sta->aid); 707 print_mac(mac, sta->addr), sta->aid);
685#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 708#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
686 pkt_data->flags |= IEEE80211_TXPD_REQUEUE; 709 info->flags |= IEEE80211_TX_CTL_REQUEUE;
687 dev_queue_xmit(skb); 710 dev_queue_xmit(skb);
688 } 711 }
689 712
@@ -725,16 +748,17 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
725 748
726 sta->rx_fragments++; 749 sta->rx_fragments++;
727 sta->rx_bytes += rx->skb->len; 750 sta->rx_bytes += rx->skb->len;
728 sta->last_rssi = rx->status->ssi;
729 sta->last_signal = rx->status->signal; 751 sta->last_signal = rx->status->signal;
752 sta->last_qual = rx->status->qual;
730 sta->last_noise = rx->status->noise; 753 sta->last_noise = rx->status->noise;
731 754
732 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { 755 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) {
733 /* Change STA power saving mode only in the end of a frame 756 /* Change STA power saving mode only in the end of a frame
734 * exchange sequence */ 757 * exchange sequence */
735 if ((sta->flags & WLAN_STA_PS) && !(rx->fc & IEEE80211_FCTL_PM)) 758 if (test_sta_flags(sta, WLAN_STA_PS) &&
759 !(rx->fc & IEEE80211_FCTL_PM))
736 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); 760 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta);
737 else if (!(sta->flags & WLAN_STA_PS) && 761 else if (!test_sta_flags(sta, WLAN_STA_PS) &&
738 (rx->fc & IEEE80211_FCTL_PM)) 762 (rx->fc & IEEE80211_FCTL_PM))
739 ap_sta_ps_start(dev, sta); 763 ap_sta_ps_start(dev, sta);
740 } 764 }
@@ -988,7 +1012,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
988 * Tell TX path to send one frame even though the STA may 1012 * Tell TX path to send one frame even though the STA may
989 * still remain is PS mode after this frame exchange. 1013 * still remain is PS mode after this frame exchange.
990 */ 1014 */
991 rx->sta->flags |= WLAN_STA_PSPOLL; 1015 set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
992 1016
993#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1017#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
994 printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", 1018 printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n",
@@ -1051,7 +1075,8 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
1051static int 1075static int
1052ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) 1076ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
1053{ 1077{
1054 if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) { 1078 if (unlikely(!rx->sta ||
1079 !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) {
1055#ifdef CONFIG_MAC80211_DEBUG 1080#ifdef CONFIG_MAC80211_DEBUG
1056 if (net_ratelimit()) 1081 if (net_ratelimit())
1057 printk(KERN_DEBUG "%s: dropped frame " 1082 printk(KERN_DEBUG "%s: dropped frame "
@@ -1713,7 +1738,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx)
1713typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_rx_data *); 1738typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_rx_data *);
1714static ieee80211_rx_handler ieee80211_rx_handlers[] = 1739static ieee80211_rx_handler ieee80211_rx_handlers[] =
1715{ 1740{
1716 ieee80211_rx_h_if_stats,
1717 ieee80211_rx_h_passive_scan, 1741 ieee80211_rx_h_passive_scan,
1718 ieee80211_rx_h_check, 1742 ieee80211_rx_h_check,
1719 ieee80211_rx_h_decrypt, 1743 ieee80211_rx_h_decrypt,
@@ -1872,7 +1896,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1872static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, 1896static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1873 struct sk_buff *skb, 1897 struct sk_buff *skb,
1874 struct ieee80211_rx_status *status, 1898 struct ieee80211_rx_status *status,
1875 u32 load,
1876 struct ieee80211_rate *rate) 1899 struct ieee80211_rate *rate)
1877{ 1900{
1878 struct ieee80211_local *local = hw_to_local(hw); 1901 struct ieee80211_local *local = hw_to_local(hw);
@@ -1891,7 +1914,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1891 rx.local = local; 1914 rx.local = local;
1892 1915
1893 rx.status = status; 1916 rx.status = status;
1894 rx.load = load;
1895 rx.rate = rate; 1917 rx.rate = rate;
1896 rx.fc = le16_to_cpu(hdr->frame_control); 1918 rx.fc = le16_to_cpu(hdr->frame_control);
1897 type = rx.fc & IEEE80211_FCTL_FTYPE; 1919 type = rx.fc & IEEE80211_FCTL_FTYPE;
@@ -2000,7 +2022,6 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2000 struct ieee80211_rx_status status; 2022 struct ieee80211_rx_status status;
2001 u16 head_seq_num, buf_size; 2023 u16 head_seq_num, buf_size;
2002 int index; 2024 int index;
2003 u32 pkt_load;
2004 struct ieee80211_supported_band *sband; 2025 struct ieee80211_supported_band *sband;
2005 struct ieee80211_rate *rate; 2026 struct ieee80211_rate *rate;
2006 2027
@@ -2035,12 +2056,9 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2035 sizeof(status)); 2056 sizeof(status));
2036 sband = local->hw.wiphy->bands[status.band]; 2057 sband = local->hw.wiphy->bands[status.band];
2037 rate = &sband->bitrates[status.rate_idx]; 2058 rate = &sband->bitrates[status.rate_idx];
2038 pkt_load = ieee80211_rx_load_stats(local,
2039 tid_agg_rx->reorder_buf[index],
2040 &status, rate);
2041 __ieee80211_rx_handle_packet(hw, 2059 __ieee80211_rx_handle_packet(hw,
2042 tid_agg_rx->reorder_buf[index], 2060 tid_agg_rx->reorder_buf[index],
2043 &status, pkt_load, rate); 2061 &status, rate);
2044 tid_agg_rx->stored_mpdu_num--; 2062 tid_agg_rx->stored_mpdu_num--;
2045 tid_agg_rx->reorder_buf[index] = NULL; 2063 tid_agg_rx->reorder_buf[index] = NULL;
2046 } 2064 }
@@ -2082,11 +2100,8 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2082 sizeof(status)); 2100 sizeof(status));
2083 sband = local->hw.wiphy->bands[status.band]; 2101 sband = local->hw.wiphy->bands[status.band];
2084 rate = &sband->bitrates[status.rate_idx]; 2102 rate = &sband->bitrates[status.rate_idx];
2085 pkt_load = ieee80211_rx_load_stats(local,
2086 tid_agg_rx->reorder_buf[index],
2087 &status, rate);
2088 __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], 2103 __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
2089 &status, pkt_load, rate); 2104 &status, rate);
2090 tid_agg_rx->stored_mpdu_num--; 2105 tid_agg_rx->stored_mpdu_num--;
2091 tid_agg_rx->reorder_buf[index] = NULL; 2106 tid_agg_rx->reorder_buf[index] = NULL;
2092 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); 2107 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
@@ -2165,7 +2180,6 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
2165 struct ieee80211_rx_status *status) 2180 struct ieee80211_rx_status *status)
2166{ 2181{
2167 struct ieee80211_local *local = hw_to_local(hw); 2182 struct ieee80211_local *local = hw_to_local(hw);
2168 u32 pkt_load;
2169 struct ieee80211_rate *rate = NULL; 2183 struct ieee80211_rate *rate = NULL;
2170 struct ieee80211_supported_band *sband; 2184 struct ieee80211_supported_band *sband;
2171 2185
@@ -2205,11 +2219,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
2205 return; 2219 return;
2206 } 2220 }
2207 2221
2208 pkt_load = ieee80211_rx_load_stats(local, skb, status, rate);
2209 local->channel_use_raw += pkt_load;
2210
2211 if (!ieee80211_rx_reorder_ampdu(local, skb)) 2222 if (!ieee80211_rx_reorder_ampdu(local, skb))
2212 __ieee80211_rx_handle_packet(hw, skb, status, pkt_load, rate); 2223 __ieee80211_rx_handle_packet(hw, skb, status, rate);
2213 2224
2214 rcu_read_unlock(); 2225 rcu_read_unlock();
2215} 2226}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 7d4fe4a52929..c24770cb02c5 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -202,14 +202,12 @@ void sta_info_destroy(struct sta_info *sta)
202 dev_kfree_skb_any(skb); 202 dev_kfree_skb_any(skb);
203 203
204 for (i = 0; i < STA_TID_NUM; i++) { 204 for (i = 0; i < STA_TID_NUM; i++) {
205 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 205 spin_lock_bh(&sta->lock);
206 if (sta->ampdu_mlme.tid_rx[i]) 206 if (sta->ampdu_mlme.tid_rx[i])
207 del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); 207 del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer);
208 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
209 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
210 if (sta->ampdu_mlme.tid_tx[i]) 208 if (sta->ampdu_mlme.tid_tx[i])
211 del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); 209 del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer);
212 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 210 spin_unlock_bh(&sta->lock);
213 } 211 }
214 212
215 __sta_info_free(local, sta); 213 __sta_info_free(local, sta);
@@ -236,6 +234,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
236 if (!sta) 234 if (!sta)
237 return NULL; 235 return NULL;
238 236
237 spin_lock_init(&sta->lock);
238
239 memcpy(sta->addr, addr, ETH_ALEN); 239 memcpy(sta->addr, addr, ETH_ALEN);
240 sta->local = local; 240 sta->local = local;
241 sta->sdata = sdata; 241 sta->sdata = sdata;
@@ -249,15 +249,13 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
249 return NULL; 249 return NULL;
250 } 250 }
251 251
252 spin_lock_init(&sta->ampdu_mlme.ampdu_rx);
253 spin_lock_init(&sta->ampdu_mlme.ampdu_tx);
254 for (i = 0; i < STA_TID_NUM; i++) { 252 for (i = 0; i < STA_TID_NUM; i++) {
255 /* timer_to_tid must be initialized with identity mapping to 253 /* timer_to_tid must be initialized with identity mapping to
256 * enable session_timer's data differentiation. refer to 254 * enable session_timer's data differentiation. refer to
257 * sta_rx_agg_session_timer_expired for useage */ 255 * sta_rx_agg_session_timer_expired for useage */
258 sta->timer_to_tid[i] = i; 256 sta->timer_to_tid[i] = i;
259 /* tid to tx queue: initialize according to HW (0 is valid) */ 257 /* tid to tx queue: initialize according to HW (0 is valid) */
260 sta->tid_to_tx_q[i] = local->hw.queues; 258 sta->tid_to_tx_q[i] = ieee80211_num_queues(&local->hw);
261 /* rx */ 259 /* rx */
262 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; 260 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
263 sta->ampdu_mlme.tid_rx[i] = NULL; 261 sta->ampdu_mlme.tid_rx[i] = NULL;
@@ -276,7 +274,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
276 274
277#ifdef CONFIG_MAC80211_MESH 275#ifdef CONFIG_MAC80211_MESH
278 sta->plink_state = PLINK_LISTEN; 276 sta->plink_state = PLINK_LISTEN;
279 spin_lock_init(&sta->plink_lock);
280 init_timer(&sta->plink_timer); 277 init_timer(&sta->plink_timer);
281#endif 278#endif
282 279
@@ -437,8 +434,7 @@ void __sta_info_unlink(struct sta_info **sta)
437 434
438 list_del(&(*sta)->list); 435 list_del(&(*sta)->list);
439 436
440 if ((*sta)->flags & WLAN_STA_PS) { 437 if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) {
441 (*sta)->flags &= ~WLAN_STA_PS;
442 if (sdata->bss) 438 if (sdata->bss)
443 atomic_dec(&sdata->bss->num_sta_ps); 439 atomic_dec(&sdata->bss->num_sta_ps);
444 __sta_info_clear_tim_bit(sdata->bss, *sta); 440 __sta_info_clear_tim_bit(sdata->bss, *sta);
@@ -515,20 +511,20 @@ static inline int sta_info_buffer_expired(struct ieee80211_local *local,
515 struct sta_info *sta, 511 struct sta_info *sta,
516 struct sk_buff *skb) 512 struct sk_buff *skb)
517{ 513{
518 struct ieee80211_tx_packet_data *pkt_data; 514 struct ieee80211_tx_info *info;
519 int timeout; 515 int timeout;
520 516
521 if (!skb) 517 if (!skb)
522 return 0; 518 return 0;
523 519
524 pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; 520 info = IEEE80211_SKB_CB(skb);
525 521
526 /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ 522 /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */
527 timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / 523 timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 /
528 15625) * HZ; 524 15625) * HZ;
529 if (timeout < STA_TX_BUFFER_EXPIRE) 525 if (timeout < STA_TX_BUFFER_EXPIRE)
530 timeout = STA_TX_BUFFER_EXPIRE; 526 timeout = STA_TX_BUFFER_EXPIRE;
531 return time_after(jiffies, pkt_data->jiffies + timeout); 527 return time_after(jiffies, info->control.jiffies + timeout);
532} 528}
533 529
534 530
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index f8c95bc9659c..95753f860acf 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -32,7 +32,7 @@
32 * @WLAN_STA_WDS: Station is one of our WDS peers. 32 * @WLAN_STA_WDS: Station is one of our WDS peers.
33 * @WLAN_STA_PSPOLL: Station has just PS-polled us. 33 * @WLAN_STA_PSPOLL: Station has just PS-polled us.
34 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the 34 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
35 * IEEE80211_TXCTL_CLEAR_PS_FILT control flag) when the next 35 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
36 * frame to this station is transmitted. 36 * frame to this station is transmitted.
37 */ 37 */
38enum ieee80211_sta_info_flags { 38enum ieee80211_sta_info_flags {
@@ -129,23 +129,19 @@ enum plink_state {
129 * 129 *
130 * @tid_state_rx: TID's state in Rx session state machine. 130 * @tid_state_rx: TID's state in Rx session state machine.
131 * @tid_rx: aggregation info for Rx per TID 131 * @tid_rx: aggregation info for Rx per TID
132 * @ampdu_rx: for locking sections in aggregation Rx flow
133 * @tid_state_tx: TID's state in Tx session state machine. 132 * @tid_state_tx: TID's state in Tx session state machine.
134 * @tid_tx: aggregation info for Tx per TID 133 * @tid_tx: aggregation info for Tx per TID
135 * @addba_req_num: number of times addBA request has been sent. 134 * @addba_req_num: number of times addBA request has been sent.
136 * @ampdu_tx: for locking sectionsi in aggregation Tx flow
137 * @dialog_token_allocator: dialog token enumerator for each new session; 135 * @dialog_token_allocator: dialog token enumerator for each new session;
138 */ 136 */
139struct sta_ampdu_mlme { 137struct sta_ampdu_mlme {
140 /* rx */ 138 /* rx */
141 u8 tid_state_rx[STA_TID_NUM]; 139 u8 tid_state_rx[STA_TID_NUM];
142 struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; 140 struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
143 spinlock_t ampdu_rx;
144 /* tx */ 141 /* tx */
145 u8 tid_state_tx[STA_TID_NUM]; 142 u8 tid_state_tx[STA_TID_NUM];
146 struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; 143 struct tid_ampdu_tx *tid_tx[STA_TID_NUM];
147 u8 addba_req_num[STA_TID_NUM]; 144 u8 addba_req_num[STA_TID_NUM];
148 spinlock_t ampdu_tx;
149 u8 dialog_token_allocator; 145 u8 dialog_token_allocator;
150}; 146};
151 147
@@ -177,6 +173,8 @@ struct sta_ampdu_mlme {
177 * @rx_bytes: Number of bytes received from this STA 173 * @rx_bytes: Number of bytes received from this STA
178 * @supp_rates: Bitmap of supported rates (per band) 174 * @supp_rates: Bitmap of supported rates (per band)
179 * @ht_info: HT capabilities of this STA 175 * @ht_info: HT capabilities of this STA
176 * @lock: used for locking all fields that require locking, see comments
177 * in the header file.
180 */ 178 */
181struct sta_info { 179struct sta_info {
182 /* General information, mostly static */ 180 /* General information, mostly static */
@@ -187,6 +185,7 @@ struct sta_info {
187 struct ieee80211_key *key; 185 struct ieee80211_key *key;
188 struct rate_control_ref *rate_ctrl; 186 struct rate_control_ref *rate_ctrl;
189 void *rate_ctrl_priv; 187 void *rate_ctrl_priv;
188 spinlock_t lock;
190 struct ieee80211_ht_info ht_info; 189 struct ieee80211_ht_info ht_info;
191 u64 supp_rates[IEEE80211_NUM_BANDS]; 190 u64 supp_rates[IEEE80211_NUM_BANDS];
192 u8 addr[ETH_ALEN]; 191 u8 addr[ETH_ALEN];
@@ -199,7 +198,7 @@ struct sta_info {
199 */ 198 */
200 u8 pin_status; 199 u8 pin_status;
201 200
202 /* frequently updated information, needs locking? */ 201 /* frequently updated information, locked with lock spinlock */
203 u32 flags; 202 u32 flags;
204 203
205 /* 204 /*
@@ -217,8 +216,8 @@ struct sta_info {
217 * from this STA */ 216 * from this STA */
218 unsigned long rx_fragments; /* number of received MPDUs */ 217 unsigned long rx_fragments; /* number of received MPDUs */
219 unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ 218 unsigned long rx_dropped; /* number of dropped MPDUs from this STA */
220 int last_rssi; /* RSSI of last received frame from this STA */
221 int last_signal; /* signal of last received frame from this STA */ 219 int last_signal; /* signal of last received frame from this STA */
220 int last_qual; /* qual of last received frame from this STA */
222 int last_noise; /* noise of last received frame from this STA */ 221 int last_noise; /* noise of last received frame from this STA */
223 /* last received seq/frag number from this STA (per RX queue) */ 222 /* last received seq/frag number from this STA (per RX queue) */
224 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; 223 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
@@ -246,12 +245,8 @@ struct sta_info {
246 unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; 245 unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES];
247#endif 246#endif
248 247
249 /* Debug counters, no locking doesn't matter */
250 int channel_use;
251 int channel_use_raw;
252
253 /* 248 /*
254 * Aggregation information, comes with own locking. 249 * Aggregation information, locked with lock.
255 */ 250 */
256 struct sta_ampdu_mlme ampdu_mlme; 251 struct sta_ampdu_mlme ampdu_mlme;
257 u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ 252 u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */
@@ -270,9 +265,6 @@ struct sta_info {
270 enum plink_state plink_state; 265 enum plink_state plink_state;
271 u32 plink_timeout; 266 u32 plink_timeout;
272 struct timer_list plink_timer; 267 struct timer_list plink_timer;
273 spinlock_t plink_lock; /* For peer_state reads / updates and other
274 updates in the structure. Ensures robust
275 transitions for the peerlink FSM */
276#endif 268#endif
277 269
278#ifdef CONFIG_MAC80211_DEBUGFS 270#ifdef CONFIG_MAC80211_DEBUGFS
@@ -299,6 +291,64 @@ static inline enum plink_state sta_plink_state(struct sta_info *sta)
299 return PLINK_LISTEN; 291 return PLINK_LISTEN;
300} 292}
301 293
294static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
295{
296 spin_lock_bh(&sta->lock);
297 sta->flags |= flags;
298 spin_unlock_bh(&sta->lock);
299}
300
301static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
302{
303 spin_lock_bh(&sta->lock);
304 sta->flags &= ~flags;
305 spin_unlock_bh(&sta->lock);
306}
307
308static inline void set_and_clear_sta_flags(struct sta_info *sta,
309 const u32 set, const u32 clear)
310{
311 spin_lock_bh(&sta->lock);
312 sta->flags |= set;
313 sta->flags &= ~clear;
314 spin_unlock_bh(&sta->lock);
315}
316
317static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
318{
319 u32 ret;
320
321 spin_lock_bh(&sta->lock);
322 ret = sta->flags & flags;
323 spin_unlock_bh(&sta->lock);
324
325 return ret;
326}
327
328static inline u32 test_and_clear_sta_flags(struct sta_info *sta,
329 const u32 flags)
330{
331 u32 ret;
332
333 spin_lock_bh(&sta->lock);
334 ret = sta->flags & flags;
335 sta->flags &= ~flags;
336 spin_unlock_bh(&sta->lock);
337
338 return ret;
339}
340
341static inline u32 get_sta_flags(struct sta_info *sta)
342{
343 u32 ret;
344
345 spin_lock_bh(&sta->lock);
346 ret = sta->flags;
347 spin_unlock_bh(&sta->lock);
348
349 return ret;
350}
351
302 352
303/* Maximum number of concurrently registered stations */ 353/* Maximum number of concurrently registered stations */
304#define MAX_STA_COUNT 2007 354#define MAX_STA_COUNT 2007
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 09093da24af6..a00cf1ea7719 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -6,25 +6,23 @@
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9
10#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/bitops.h>
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <asm/unaligned.h>
13 14
14#include <net/mac80211.h> 15#include <net/mac80211.h>
15#include "key.h" 16#include "key.h"
16#include "tkip.h" 17#include "tkip.h"
17#include "wep.h" 18#include "wep.h"
18 19
19
20/* TKIP key mixing functions */
21
22
23#define PHASE1_LOOP_COUNT 8 20#define PHASE1_LOOP_COUNT 8
24 21
25 22/*
26/* 2-byte by 2-byte subset of the full AES S-box table; second part of this 23 * 2-byte by 2-byte subset of the full AES S-box table; second part of this
27 * table is identical to first part but byte-swapped */ 24 * table is identical to first part but byte-swapped
25 */
28static const u16 tkip_sbox[256] = 26static const u16 tkip_sbox[256] =
29{ 27{
30 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, 28 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
@@ -61,84 +59,48 @@ static const u16 tkip_sbox[256] =
61 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, 59 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
62}; 60};
63 61
64 62static u16 tkipS(u16 val)
65static inline u16 Mk16(u8 x, u8 y)
66{
67 return ((u16) x << 8) | (u16) y;
68}
69
70
71static inline u8 Hi8(u16 v)
72{
73 return v >> 8;
74}
75
76
77static inline u8 Lo8(u16 v)
78{
79 return v & 0xff;
80}
81
82
83static inline u16 Hi16(u32 v)
84{ 63{
85 return v >> 16; 64 return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]);
86} 65}
87 66
88 67/*
89static inline u16 Lo16(u32 v) 68 * P1K := Phase1(TA, TK, TSC)
90{
91 return v & 0xffff;
92}
93
94
95static inline u16 RotR1(u16 v)
96{
97 return (v >> 1) | ((v & 0x0001) << 15);
98}
99
100
101static inline u16 tkip_S(u16 val)
102{
103 u16 a = tkip_sbox[Hi8(val)];
104
105 return tkip_sbox[Lo8(val)] ^ Hi8(a) ^ (Lo8(a) << 8);
106}
107
108
109
110/* P1K := Phase1(TA, TK, TSC)
111 * TA = transmitter address (48 bits) 69 * TA = transmitter address (48 bits)
112 * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) 70 * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits)
113 * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) 71 * TSC = TKIP sequence counter (48 bits, only 32 msb bits used)
114 * P1K: 80 bits 72 * P1K: 80 bits
115 */ 73 */
116static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, 74static void tkip_mixing_phase1(struct ieee80211_key *key, const u8 *ta,
117 u16 *p1k) 75 struct tkip_ctx *ctx, u32 tsc_IV32)
118{ 76{
119 int i, j; 77 int i, j;
78 const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY];
79 u16 *p1k = ctx->p1k;
120 80
121 p1k[0] = Lo16(tsc_IV32); 81 p1k[0] = tsc_IV32 & 0xFFFF;
122 p1k[1] = Hi16(tsc_IV32); 82 p1k[1] = tsc_IV32 >> 16;
123 p1k[2] = Mk16(ta[1], ta[0]); 83 p1k[2] = get_unaligned_le16(ta + 0);
124 p1k[3] = Mk16(ta[3], ta[2]); 84 p1k[3] = get_unaligned_le16(ta + 2);
125 p1k[4] = Mk16(ta[5], ta[4]); 85 p1k[4] = get_unaligned_le16(ta + 4);
126 86
127 for (i = 0; i < PHASE1_LOOP_COUNT; i++) { 87 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
128 j = 2 * (i & 1); 88 j = 2 * (i & 1);
129 p1k[0] += tkip_S(p1k[4] ^ Mk16(tk[ 1 + j], tk[ 0 + j])); 89 p1k[0] += tkipS(p1k[4] ^ get_unaligned_le16(tk + 0 + j));
130 p1k[1] += tkip_S(p1k[0] ^ Mk16(tk[ 5 + j], tk[ 4 + j])); 90 p1k[1] += tkipS(p1k[0] ^ get_unaligned_le16(tk + 4 + j));
131 p1k[2] += tkip_S(p1k[1] ^ Mk16(tk[ 9 + j], tk[ 8 + j])); 91 p1k[2] += tkipS(p1k[1] ^ get_unaligned_le16(tk + 8 + j));
132 p1k[3] += tkip_S(p1k[2] ^ Mk16(tk[13 + j], tk[12 + j])); 92 p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j));
133 p1k[4] += tkip_S(p1k[3] ^ Mk16(tk[ 1 + j], tk[ 0 + j])) + i; 93 p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i;
134 } 94 }
95 ctx->initialized = 1;
135} 96}
136 97
137 98static void tkip_mixing_phase2(struct ieee80211_key *key, struct tkip_ctx *ctx,
138static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, 99 u16 tsc_IV16, u8 *rc4key)
139 u8 *rc4key)
140{ 100{
141 u16 ppk[6]; 101 u16 ppk[6];
102 const u16 *p1k = ctx->p1k;
103 const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY];
142 int i; 104 int i;
143 105
144 ppk[0] = p1k[0]; 106 ppk[0] = p1k[0];
@@ -148,70 +110,51 @@ static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16,
148 ppk[4] = p1k[4]; 110 ppk[4] = p1k[4];
149 ppk[5] = p1k[4] + tsc_IV16; 111 ppk[5] = p1k[4] + tsc_IV16;
150 112
151 ppk[0] += tkip_S(ppk[5] ^ Mk16(tk[ 1], tk[ 0])); 113 ppk[0] += tkipS(ppk[5] ^ get_unaligned_le16(tk + 0));
152 ppk[1] += tkip_S(ppk[0] ^ Mk16(tk[ 3], tk[ 2])); 114 ppk[1] += tkipS(ppk[0] ^ get_unaligned_le16(tk + 2));
153 ppk[2] += tkip_S(ppk[1] ^ Mk16(tk[ 5], tk[ 4])); 115 ppk[2] += tkipS(ppk[1] ^ get_unaligned_le16(tk + 4));
154 ppk[3] += tkip_S(ppk[2] ^ Mk16(tk[ 7], tk[ 6])); 116 ppk[3] += tkipS(ppk[2] ^ get_unaligned_le16(tk + 6));
155 ppk[4] += tkip_S(ppk[3] ^ Mk16(tk[ 9], tk[ 8])); 117 ppk[4] += tkipS(ppk[3] ^ get_unaligned_le16(tk + 8));
156 ppk[5] += tkip_S(ppk[4] ^ Mk16(tk[11], tk[10])); 118 ppk[5] += tkipS(ppk[4] ^ get_unaligned_le16(tk + 10));
157 ppk[0] += RotR1(ppk[5] ^ Mk16(tk[13], tk[12])); 119 ppk[0] += ror16(ppk[5] ^ get_unaligned_le16(tk + 12), 1);
158 ppk[1] += RotR1(ppk[0] ^ Mk16(tk[15], tk[14])); 120 ppk[1] += ror16(ppk[0] ^ get_unaligned_le16(tk + 14), 1);
159 ppk[2] += RotR1(ppk[1]); 121 ppk[2] += ror16(ppk[1], 1);
160 ppk[3] += RotR1(ppk[2]); 122 ppk[3] += ror16(ppk[2], 1);
161 ppk[4] += RotR1(ppk[3]); 123 ppk[4] += ror16(ppk[3], 1);
162 ppk[5] += RotR1(ppk[4]); 124 ppk[5] += ror16(ppk[4], 1);
163 125
164 rc4key[0] = Hi8(tsc_IV16); 126 rc4key[0] = tsc_IV16 >> 8;
165 rc4key[1] = (Hi8(tsc_IV16) | 0x20) & 0x7f; 127 rc4key[1] = ((tsc_IV16 >> 8) | 0x20) & 0x7f;
166 rc4key[2] = Lo8(tsc_IV16); 128 rc4key[2] = tsc_IV16 & 0xFF;
167 rc4key[3] = Lo8((ppk[5] ^ Mk16(tk[1], tk[0])) >> 1); 129 rc4key[3] = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF;
168 130
169 for (i = 0; i < 6; i++) { 131 rc4key += 4;
170 rc4key[4 + 2 * i] = Lo8(ppk[i]); 132 for (i = 0; i < 6; i++)
171 rc4key[5 + 2 * i] = Hi8(ppk[i]); 133 put_unaligned_le16(ppk[i], rc4key + 2 * i);
172 }
173} 134}
174 135
175
176/* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets 136/* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets
177 * of the IV. Returns pointer to the octet following IVs (i.e., beginning of 137 * of the IV. Returns pointer to the octet following IVs (i.e., beginning of
178 * the packet payload). */ 138 * the packet payload). */
179u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, 139u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key,
180 u8 iv0, u8 iv1, u8 iv2) 140 u8 iv0, u8 iv1, u8 iv2)
181{ 141{
182 *pos++ = iv0; 142 *pos++ = iv0;
183 *pos++ = iv1; 143 *pos++ = iv1;
184 *pos++ = iv2; 144 *pos++ = iv2;
185 *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; 145 *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */;
186 *pos++ = key->u.tkip.iv32 & 0xff; 146 put_unaligned_le32(key->u.tkip.tx.iv32, pos);
187 *pos++ = (key->u.tkip.iv32 >> 8) & 0xff; 147 return pos + 4;
188 *pos++ = (key->u.tkip.iv32 >> 16) & 0xff;
189 *pos++ = (key->u.tkip.iv32 >> 24) & 0xff;
190 return pos;
191}
192
193
194void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta,
195 u16 *phase1key)
196{
197 tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
198 key->u.tkip.iv32, phase1key);
199} 148}
200 149
201void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, 150static void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta,
202 u8 *rc4key) 151 u8 *rc4key)
203{ 152{
204 /* Calculate per-packet key */ 153 /* Calculate per-packet key */
205 if (key->u.tkip.iv16 == 0 || !key->u.tkip.tx_initialized) { 154 if (key->u.tkip.tx.iv16 == 0 || !key->u.tkip.tx.initialized)
206 /* IV16 wrapped around - perform TKIP phase 1 */ 155 tkip_mixing_phase1(key, ta, &key->u.tkip.tx, key->u.tkip.tx.iv32);
207 tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
208 key->u.tkip.iv32, key->u.tkip.p1k);
209 key->u.tkip.tx_initialized = 1;
210 }
211 156
212 tkip_mixing_phase2(key->u.tkip.p1k, 157 tkip_mixing_phase2(key, &key->u.tkip.tx, key->u.tkip.tx.iv16, rc4key);
213 &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
214 key->u.tkip.iv16, rc4key);
215} 158}
216 159
217void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, 160void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
@@ -228,18 +171,16 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
228 u16 iv16; 171 u16 iv16;
229 u32 iv32; 172 u32 iv32;
230 173
231 iv16 = data[hdr_len] << 8; 174 iv16 = data[hdr_len + 2] | (data[hdr_len] << 8);
232 iv16 += data[hdr_len + 2]; 175 iv32 = get_unaligned_le32(data + hdr_len + 4);
233 iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) |
234 (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24);
235 176
236#ifdef CONFIG_TKIP_DEBUG 177#ifdef CONFIG_TKIP_DEBUG
237 printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", 178 printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n",
238 iv16, iv32); 179 iv16, iv32);
239 180
240 if (iv32 != key->u.tkip.iv32) { 181 if (iv32 != key->u.tkip.tx.iv32) {
241 printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", 182 printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n",
242 iv32, key->u.tkip.iv32); 183 iv32, key->u.tkip.tx.iv32);
243 printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " 184 printk(KERN_DEBUG "Wrap around of iv16 in the middle of a "
244 "fragmented packet\n"); 185 "fragmented packet\n");
245 } 186 }
@@ -248,20 +189,15 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
248 /* Update the p1k only when the iv16 in the packet wraps around, this 189 /* Update the p1k only when the iv16 in the packet wraps around, this
249 * might occur after the wrap around of iv16 in the key in case of 190 * might occur after the wrap around of iv16 in the key in case of
250 * fragmented packets. */ 191 * fragmented packets. */
251 if (iv16 == 0 || !key->u.tkip.tx_initialized) { 192 if (iv16 == 0 || !key->u.tkip.tx.initialized)
252 /* IV16 wrapped around - perform TKIP phase 1 */ 193 tkip_mixing_phase1(key, ta, &key->u.tkip.tx, iv32);
253 tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
254 iv32, key->u.tkip.p1k);
255 key->u.tkip.tx_initialized = 1;
256 }
257 194
258 if (type == IEEE80211_TKIP_P1_KEY) { 195 if (type == IEEE80211_TKIP_P1_KEY) {
259 memcpy(outkey, key->u.tkip.p1k, sizeof(u16) * 5); 196 memcpy(outkey, key->u.tkip.tx.p1k, sizeof(u16) * 5);
260 return; 197 return;
261 } 198 }
262 199
263 tkip_mixing_phase2(key->u.tkip.p1k, 200 tkip_mixing_phase2(key, &key->u.tkip.tx, iv16, outkey);
264 &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], iv16, outkey);
265} 201}
266EXPORT_SYMBOL(ieee80211_get_tkip_key); 202EXPORT_SYMBOL(ieee80211_get_tkip_key);
267 203
@@ -281,7 +217,6 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
281 ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); 217 ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
282} 218}
283 219
284
285/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the 220/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
286 * beginning of the buffer containing IEEE 802.11 header payload, i.e., 221 * beginning of the buffer containing IEEE 802.11 header payload, i.e.,
287 * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the 222 * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the
@@ -302,7 +237,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
302 237
303 iv16 = (pos[0] << 8) | pos[2]; 238 iv16 = (pos[0] << 8) | pos[2];
304 keyid = pos[3]; 239 keyid = pos[3];
305 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); 240 iv32 = get_unaligned_le32(pos + 4);
306 pos += 8; 241 pos += 8;
307#ifdef CONFIG_TKIP_DEBUG 242#ifdef CONFIG_TKIP_DEBUG
308 { 243 {
@@ -322,33 +257,31 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
322 if ((keyid >> 6) != key->conf.keyidx) 257 if ((keyid >> 6) != key->conf.keyidx)
323 return TKIP_DECRYPT_INVALID_KEYIDX; 258 return TKIP_DECRYPT_INVALID_KEYIDX;
324 259
325 if (key->u.tkip.rx_initialized[queue] && 260 if (key->u.tkip.rx[queue].initialized &&
326 (iv32 < key->u.tkip.iv32_rx[queue] || 261 (iv32 < key->u.tkip.rx[queue].iv32 ||
327 (iv32 == key->u.tkip.iv32_rx[queue] && 262 (iv32 == key->u.tkip.rx[queue].iv32 &&
328 iv16 <= key->u.tkip.iv16_rx[queue]))) { 263 iv16 <= key->u.tkip.rx[queue].iv16))) {
329#ifdef CONFIG_TKIP_DEBUG 264#ifdef CONFIG_TKIP_DEBUG
330 DECLARE_MAC_BUF(mac); 265 DECLARE_MAC_BUF(mac);
331 printk(KERN_DEBUG "TKIP replay detected for RX frame from " 266 printk(KERN_DEBUG "TKIP replay detected for RX frame from "
332 "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", 267 "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n",
333 print_mac(mac, ta), 268 print_mac(mac, ta),
334 iv32, iv16, key->u.tkip.iv32_rx[queue], 269 iv32, iv16, key->u.tkip.rx[queue].iv32,
335 key->u.tkip.iv16_rx[queue]); 270 key->u.tkip.rx[queue].iv16);
336#endif /* CONFIG_TKIP_DEBUG */ 271#endif /* CONFIG_TKIP_DEBUG */
337 return TKIP_DECRYPT_REPLAY; 272 return TKIP_DECRYPT_REPLAY;
338 } 273 }
339 274
340 if (only_iv) { 275 if (only_iv) {
341 res = TKIP_DECRYPT_OK; 276 res = TKIP_DECRYPT_OK;
342 key->u.tkip.rx_initialized[queue] = 1; 277 key->u.tkip.rx[queue].initialized = 1;
343 goto done; 278 goto done;
344 } 279 }
345 280
346 if (!key->u.tkip.rx_initialized[queue] || 281 if (!key->u.tkip.rx[queue].initialized ||
347 key->u.tkip.iv32_rx[queue] != iv32) { 282 key->u.tkip.rx[queue].iv32 != iv32) {
348 key->u.tkip.rx_initialized[queue] = 1;
349 /* IV16 wrapped around - perform TKIP phase 1 */ 283 /* IV16 wrapped around - perform TKIP phase 1 */
350 tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], 284 tkip_mixing_phase1(key, ta, &key->u.tkip.rx[queue], iv32);
351 iv32, key->u.tkip.p1k_rx[queue]);
352#ifdef CONFIG_TKIP_DEBUG 285#ifdef CONFIG_TKIP_DEBUG
353 { 286 {
354 int i; 287 int i;
@@ -362,7 +295,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
362 printk("\n"); 295 printk("\n");
363 printk(KERN_DEBUG "TKIP decrypt: P1K="); 296 printk(KERN_DEBUG "TKIP decrypt: P1K=");
364 for (i = 0; i < 5; i++) 297 for (i = 0; i < 5; i++)
365 printk("%04x ", key->u.tkip.p1k_rx[queue][i]); 298 printk("%04x ", key->u.tkip.rx[queue].p1k[i]);
366 printk("\n"); 299 printk("\n");
367 } 300 }
368#endif /* CONFIG_TKIP_DEBUG */ 301#endif /* CONFIG_TKIP_DEBUG */
@@ -377,13 +310,11 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
377 310
378 key->local->ops->update_tkip_key( 311 key->local->ops->update_tkip_key(
379 local_to_hw(key->local), &key->conf, 312 local_to_hw(key->local), &key->conf,
380 sta_addr, iv32, key->u.tkip.p1k_rx[queue]); 313 sta_addr, iv32, key->u.tkip.rx[queue].p1k);
381 } 314 }
382 } 315 }
383 316
384 tkip_mixing_phase2(key->u.tkip.p1k_rx[queue], 317 tkip_mixing_phase2(key, &key->u.tkip.rx[queue], iv16, rc4key);
385 &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
386 iv16, rc4key);
387#ifdef CONFIG_TKIP_DEBUG 318#ifdef CONFIG_TKIP_DEBUG
388 { 319 {
389 int i; 320 int i;
@@ -409,5 +340,3 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
409 340
410 return res; 341 return res;
411} 342}
412
413
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h
index b7c2ee763d9d..b890427fc959 100644
--- a/net/mac80211/tkip.h
+++ b/net/mac80211/tkip.h
@@ -13,12 +13,8 @@
13#include <linux/crypto.h> 13#include <linux/crypto.h>
14#include "key.h" 14#include "key.h"
15 15
16u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, 16u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key,
17 u8 iv0, u8 iv1, u8 iv2); 17 u8 iv0, u8 iv1, u8 iv2);
18void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta,
19 u16 *phase1key);
20void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta,
21 u8 *rc4key);
22void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, 18void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
23 struct ieee80211_key *key, 19 struct ieee80211_key *key,
24 u8 *pos, size_t payload_len, u8 *ta); 20 u8 *pos, size_t payload_len, u8 *ta);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1d7dd54aacef..1ad9e664f287 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -91,11 +91,12 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
91 int next_frag_len) 91 int next_frag_len)
92{ 92{
93 int rate, mrate, erp, dur, i; 93 int rate, mrate, erp, dur, i;
94 struct ieee80211_rate *txrate = tx->rate; 94 struct ieee80211_rate *txrate;
95 struct ieee80211_local *local = tx->local; 95 struct ieee80211_local *local = tx->local;
96 struct ieee80211_supported_band *sband; 96 struct ieee80211_supported_band *sband;
97 97
98 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 98 sband = local->hw.wiphy->bands[tx->channel->band];
99 txrate = &sband->bitrates[tx->rate_idx];
99 100
100 erp = 0; 101 erp = 0;
101 if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 102 if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
@@ -212,18 +213,6 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
212 return dur; 213 return dur;
213} 214}
214 215
215static inline int __ieee80211_queue_stopped(const struct ieee80211_local *local,
216 int queue)
217{
218 return test_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]);
219}
220
221static inline int __ieee80211_queue_pending(const struct ieee80211_local *local,
222 int queue)
223{
224 return test_bit(IEEE80211_LINK_STATE_PENDING, &local->state[queue]);
225}
226
227static int inline is_ieee80211_device(struct net_device *dev, 216static int inline is_ieee80211_device(struct net_device *dev,
228 struct net_device *master) 217 struct net_device *master)
229{ 218{
@@ -237,12 +226,12 @@ static ieee80211_tx_result
237ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) 226ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
238{ 227{
239#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 228#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
240 struct sk_buff *skb = tx->skb; 229 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
241 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
242#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 230#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
231 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
243 u32 sta_flags; 232 u32 sta_flags;
244 233
245 if (unlikely(tx->flags & IEEE80211_TX_INJECTED)) 234 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
246 return TX_CONTINUE; 235 return TX_CONTINUE;
247 236
248 if (unlikely(tx->local->sta_sw_scanning) && 237 if (unlikely(tx->local->sta_sw_scanning) &&
@@ -256,7 +245,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
256 if (tx->flags & IEEE80211_TX_PS_BUFFERED) 245 if (tx->flags & IEEE80211_TX_PS_BUFFERED)
257 return TX_CONTINUE; 246 return TX_CONTINUE;
258 247
259 sta_flags = tx->sta ? tx->sta->flags : 0; 248 sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
260 249
261 if (likely(tx->flags & IEEE80211_TX_UNICAST)) { 250 if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
262 if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && 251 if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
@@ -347,6 +336,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
347static ieee80211_tx_result 336static ieee80211_tx_result
348ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) 337ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
349{ 338{
339 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
340
350 /* 341 /*
351 * broadcast/multicast frame 342 * broadcast/multicast frame
352 * 343 *
@@ -382,7 +373,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
382 } 373 }
383 374
384 /* buffered in hardware */ 375 /* buffered in hardware */
385 tx->control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM; 376 info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
386 377
387 return TX_CONTINUE; 378 return TX_CONTINUE;
388} 379}
@@ -391,6 +382,8 @@ static ieee80211_tx_result
391ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) 382ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
392{ 383{
393 struct sta_info *sta = tx->sta; 384 struct sta_info *sta = tx->sta;
385 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
386 u32 staflags;
394 DECLARE_MAC_BUF(mac); 387 DECLARE_MAC_BUF(mac);
395 388
396 if (unlikely(!sta || 389 if (unlikely(!sta ||
@@ -398,9 +391,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
398 (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) 391 (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)))
399 return TX_CONTINUE; 392 return TX_CONTINUE;
400 393
401 if (unlikely((sta->flags & WLAN_STA_PS) && 394 staflags = get_sta_flags(sta);
402 !(sta->flags & WLAN_STA_PSPOLL))) { 395
403 struct ieee80211_tx_packet_data *pkt_data; 396 if (unlikely((staflags & WLAN_STA_PS) &&
397 !(staflags & WLAN_STA_PSPOLL))) {
404#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 398#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
405 printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " 399 printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries "
406 "before %d)\n", 400 "before %d)\n",
@@ -424,19 +418,18 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
424 if (skb_queue_empty(&sta->ps_tx_buf)) 418 if (skb_queue_empty(&sta->ps_tx_buf))
425 sta_info_set_tim_bit(sta); 419 sta_info_set_tim_bit(sta);
426 420
427 pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb; 421 info->control.jiffies = jiffies;
428 pkt_data->jiffies = jiffies;
429 skb_queue_tail(&sta->ps_tx_buf, tx->skb); 422 skb_queue_tail(&sta->ps_tx_buf, tx->skb);
430 return TX_QUEUED; 423 return TX_QUEUED;
431 } 424 }
432#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 425#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
433 else if (unlikely(sta->flags & WLAN_STA_PS)) { 426 else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) {
434 printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " 427 printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll "
435 "set -> send frame\n", tx->dev->name, 428 "set -> send frame\n", tx->dev->name,
436 print_mac(mac, sta->addr)); 429 print_mac(mac, sta->addr));
437 } 430 }
438#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 431#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
439 sta->flags &= ~WLAN_STA_PSPOLL; 432 clear_sta_flags(sta, WLAN_STA_PSPOLL);
440 433
441 return TX_CONTINUE; 434 return TX_CONTINUE;
442} 435}
@@ -457,17 +450,18 @@ static ieee80211_tx_result
457ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) 450ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
458{ 451{
459 struct ieee80211_key *key; 452 struct ieee80211_key *key;
453 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
460 u16 fc = tx->fc; 454 u16 fc = tx->fc;
461 455
462 if (unlikely(tx->control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) 456 if (unlikely(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))
463 tx->key = NULL; 457 tx->key = NULL;
464 else if (tx->sta && (key = rcu_dereference(tx->sta->key))) 458 else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
465 tx->key = key; 459 tx->key = key;
466 else if ((key = rcu_dereference(tx->sdata->default_key))) 460 else if ((key = rcu_dereference(tx->sdata->default_key)))
467 tx->key = key; 461 tx->key = key;
468 else if (tx->sdata->drop_unencrypted && 462 else if (tx->sdata->drop_unencrypted &&
469 !(tx->control->flags & IEEE80211_TXCTL_EAPOL_FRAME) && 463 !(info->flags & IEEE80211_TX_CTL_EAPOL_FRAME) &&
470 !(tx->flags & IEEE80211_TX_INJECTED)) { 464 !(info->flags & IEEE80211_TX_CTL_INJECTED)) {
471 I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); 465 I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
472 return TX_DROP; 466 return TX_DROP;
473 } else 467 } else
@@ -496,7 +490,156 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
496 } 490 }
497 491
498 if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) 492 if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
499 tx->control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; 493 info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
494
495 return TX_CONTINUE;
496}
497
498static ieee80211_tx_result
499ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
500{
501 struct rate_selection rsel;
502 struct ieee80211_supported_band *sband;
503 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
504
505 sband = tx->local->hw.wiphy->bands[tx->channel->band];
506
507 if (likely(tx->rate_idx < 0)) {
508 rate_control_get_rate(tx->dev, sband, tx->skb, &rsel);
509 tx->rate_idx = rsel.rate_idx;
510 if (unlikely(rsel.probe_idx >= 0)) {
511 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
512 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
513 info->control.alt_retry_rate_idx = tx->rate_idx;
514 tx->rate_idx = rsel.probe_idx;
515 } else
516 info->control.alt_retry_rate_idx = -1;
517
518 if (unlikely(tx->rate_idx < 0))
519 return TX_DROP;
520 } else
521 info->control.alt_retry_rate_idx = -1;
522
523 if (tx->sdata->bss_conf.use_cts_prot &&
524 (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
525 tx->last_frag_rate_idx = tx->rate_idx;
526 if (rsel.probe_idx >= 0)
527 tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG;
528 else
529 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
530 tx->rate_idx = rsel.nonerp_idx;
531 info->tx_rate_idx = rsel.nonerp_idx;
532 info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
533 } else {
534 tx->last_frag_rate_idx = tx->rate_idx;
535 info->tx_rate_idx = tx->rate_idx;
536 }
537 info->tx_rate_idx = tx->rate_idx;
538
539 return TX_CONTINUE;
540}
541
542static ieee80211_tx_result
543ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
544{
545 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
546 u16 fc = le16_to_cpu(hdr->frame_control);
547 u16 dur;
548 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
549 struct ieee80211_supported_band *sband;
550
551 sband = tx->local->hw.wiphy->bands[tx->channel->band];
552
553 if (tx->sta)
554 info->control.aid = tx->sta->aid;
555
556 if (!info->control.retry_limit) {
557 if (!is_multicast_ether_addr(hdr->addr1)) {
558 int len = min_t(int, tx->skb->len + FCS_LEN,
559 tx->local->fragmentation_threshold);
560 if (len > tx->local->rts_threshold
561 && tx->local->rts_threshold <
562 IEEE80211_MAX_RTS_THRESHOLD) {
563 info->flags |= IEEE80211_TX_CTL_USE_RTS_CTS;
564 info->flags |=
565 IEEE80211_TX_CTL_LONG_RETRY_LIMIT;
566 info->control.retry_limit =
567 tx->local->long_retry_limit;
568 } else {
569 info->control.retry_limit =
570 tx->local->short_retry_limit;
571 }
572 } else {
573 info->control.retry_limit = 1;
574 }
575 }
576
577 if (tx->flags & IEEE80211_TX_FRAGMENTED) {
578 /* Do not use multiple retry rates when sending fragmented
579 * frames.
580 * TODO: The last fragment could still use multiple retry
581 * rates. */
582 info->control.alt_retry_rate_idx = -1;
583 }
584
585 /* Use CTS protection for unicast frames sent using extended rates if
586 * there are associated non-ERP stations and RTS/CTS is not configured
587 * for the frame. */
588 if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) &&
589 (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) &&
590 (tx->flags & IEEE80211_TX_UNICAST) &&
591 tx->sdata->bss_conf.use_cts_prot &&
592 !(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS))
593 info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT;
594
595 /* Transmit data frames using short preambles if the driver supports
596 * short preambles at the selected rate and short preambles are
597 * available on the network at the current point in time. */
598 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
599 (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
600 tx->sdata->bss_conf.use_short_preamble &&
601 (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) {
602 info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
603 }
604
605 /* Setup duration field for the first fragment of the frame. Duration
606 * for remaining fragments will be updated when they are being sent
607 * to low-level driver in ieee80211_tx(). */
608 dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1),
609 (tx->flags & IEEE80211_TX_FRAGMENTED) ?
610 tx->extra_frag[0]->len : 0);
611 hdr->duration_id = cpu_to_le16(dur);
612
613 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
614 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
615 struct ieee80211_rate *rate;
616 s8 baserate = -1;
617 int idx;
618
619 /* Do not use multiple retry rates when using RTS/CTS */
620 info->control.alt_retry_rate_idx = -1;
621
622 /* Use min(data rate, max base rate) as CTS/RTS rate */
623 rate = &sband->bitrates[tx->rate_idx];
624
625 for (idx = 0; idx < sband->n_bitrates; idx++) {
626 if (sband->bitrates[idx].bitrate > rate->bitrate)
627 continue;
628 if (tx->sdata->basic_rates & BIT(idx) &&
629 (baserate < 0 ||
630 (sband->bitrates[baserate].bitrate
631 < sband->bitrates[idx].bitrate)))
632 baserate = idx;
633 }
634
635 if (baserate >= 0)
636 info->control.rts_cts_rate_idx = baserate;
637 else
638 info->control.rts_cts_rate_idx = 0;
639 }
640
641 if (tx->sta)
642 info->control.aid = tx->sta->aid;
500 643
501 return TX_CONTINUE; 644 return TX_CONTINUE;
502} 645}
@@ -515,6 +658,17 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
515 if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) 658 if (!(tx->flags & IEEE80211_TX_FRAGMENTED))
516 return TX_CONTINUE; 659 return TX_CONTINUE;
517 660
661 /*
662 * Warn when submitting a fragmented A-MPDU frame and drop it.
663 * This is an error and needs to be fixed elsewhere, but when
664 * done needs to take care of monitor interfaces (injection)
665 * etc.
666 */
667 if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU ||
668 skb_get_queue_mapping(tx->skb) >=
669 ieee80211_num_regular_queues(&tx->local->hw)))
670 return TX_DROP;
671
518 first = tx->skb; 672 first = tx->skb;
519 673
520 hdrlen = ieee80211_get_hdrlen(tx->fc); 674 hdrlen = ieee80211_get_hdrlen(tx->fc);
@@ -602,215 +756,22 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx)
602} 756}
603 757
604static ieee80211_tx_result 758static ieee80211_tx_result
605ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) 759ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
606{ 760{
607 struct rate_selection rsel; 761 int i;
608 struct ieee80211_supported_band *sband;
609
610 sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band];
611
612 if (likely(!tx->rate)) {
613 rate_control_get_rate(tx->dev, sband, tx->skb, &rsel);
614 tx->rate = rsel.rate;
615 if (unlikely(rsel.probe)) {
616 tx->control->flags |=
617 IEEE80211_TXCTL_RATE_CTRL_PROBE;
618 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
619 tx->control->alt_retry_rate = tx->rate;
620 tx->rate = rsel.probe;
621 } else
622 tx->control->alt_retry_rate = NULL;
623
624 if (!tx->rate)
625 return TX_DROP;
626 } else
627 tx->control->alt_retry_rate = NULL;
628
629 if (tx->sdata->bss_conf.use_cts_prot &&
630 (tx->flags & IEEE80211_TX_FRAGMENTED) && rsel.nonerp) {
631 tx->last_frag_rate = tx->rate;
632 if (rsel.probe)
633 tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG;
634 else
635 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
636 tx->rate = rsel.nonerp;
637 tx->control->tx_rate = rsel.nonerp;
638 tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
639 } else {
640 tx->last_frag_rate = tx->rate;
641 tx->control->tx_rate = tx->rate;
642 }
643 tx->control->tx_rate = tx->rate;
644
645 return TX_CONTINUE;
646}
647
648static ieee80211_tx_result
649ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
650{
651 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
652 u16 fc = le16_to_cpu(hdr->frame_control);
653 u16 dur;
654 struct ieee80211_tx_control *control = tx->control;
655
656 if (!control->retry_limit) {
657 if (!is_multicast_ether_addr(hdr->addr1)) {
658 if (tx->skb->len + FCS_LEN > tx->local->rts_threshold
659 && tx->local->rts_threshold <
660 IEEE80211_MAX_RTS_THRESHOLD) {
661 control->flags |=
662 IEEE80211_TXCTL_USE_RTS_CTS;
663 control->flags |=
664 IEEE80211_TXCTL_LONG_RETRY_LIMIT;
665 control->retry_limit =
666 tx->local->long_retry_limit;
667 } else {
668 control->retry_limit =
669 tx->local->short_retry_limit;
670 }
671 } else {
672 control->retry_limit = 1;
673 }
674 }
675
676 if (tx->flags & IEEE80211_TX_FRAGMENTED) {
677 /* Do not use multiple retry rates when sending fragmented
678 * frames.
679 * TODO: The last fragment could still use multiple retry
680 * rates. */
681 control->alt_retry_rate = NULL;
682 }
683
684 /* Use CTS protection for unicast frames sent using extended rates if
685 * there are associated non-ERP stations and RTS/CTS is not configured
686 * for the frame. */
687 if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) &&
688 (tx->rate->flags & IEEE80211_RATE_ERP_G) &&
689 (tx->flags & IEEE80211_TX_UNICAST) &&
690 tx->sdata->bss_conf.use_cts_prot &&
691 !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS))
692 control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT;
693
694 /* Transmit data frames using short preambles if the driver supports
695 * short preambles at the selected rate and short preambles are
696 * available on the network at the current point in time. */
697 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
698 (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
699 tx->sdata->bss_conf.use_short_preamble &&
700 (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) {
701 tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
702 }
703
704 /* Setup duration field for the first fragment of the frame. Duration
705 * for remaining fragments will be updated when they are being sent
706 * to low-level driver in ieee80211_tx(). */
707 dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1),
708 (tx->flags & IEEE80211_TX_FRAGMENTED) ?
709 tx->extra_frag[0]->len : 0);
710 hdr->duration_id = cpu_to_le16(dur);
711
712 if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
713 (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
714 struct ieee80211_supported_band *sband;
715 struct ieee80211_rate *rate, *baserate;
716 int idx;
717
718 sband = tx->local->hw.wiphy->bands[
719 tx->local->hw.conf.channel->band];
720
721 /* Do not use multiple retry rates when using RTS/CTS */
722 control->alt_retry_rate = NULL;
723
724 /* Use min(data rate, max base rate) as CTS/RTS rate */
725 rate = tx->rate;
726 baserate = NULL;
727
728 for (idx = 0; idx < sband->n_bitrates; idx++) {
729 if (sband->bitrates[idx].bitrate > rate->bitrate)
730 continue;
731 if (tx->sdata->basic_rates & BIT(idx) &&
732 (!baserate ||
733 (baserate->bitrate < sband->bitrates[idx].bitrate)))
734 baserate = &sband->bitrates[idx];
735 }
736
737 if (baserate)
738 control->rts_cts_rate = baserate;
739 else
740 control->rts_cts_rate = &sband->bitrates[0];
741 }
742
743 if (tx->sta) {
744 control->aid = tx->sta->aid;
745 tx->sta->tx_packets++;
746 tx->sta->tx_fragments++;
747 tx->sta->tx_bytes += tx->skb->len;
748 if (tx->extra_frag) {
749 int i;
750 tx->sta->tx_fragments += tx->num_extra_frag;
751 for (i = 0; i < tx->num_extra_frag; i++) {
752 tx->sta->tx_bytes +=
753 tx->extra_frag[i]->len;
754 }
755 }
756 }
757
758 return TX_CONTINUE;
759}
760
761static ieee80211_tx_result
762ieee80211_tx_h_load_stats(struct ieee80211_tx_data *tx)
763{
764 struct ieee80211_local *local = tx->local;
765 struct sk_buff *skb = tx->skb;
766 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
767 u32 load = 0, hdrtime;
768 struct ieee80211_rate *rate = tx->rate;
769
770 /* TODO: this could be part of tx_status handling, so that the number
771 * of retries would be known; TX rate should in that case be stored
772 * somewhere with the packet */
773
774 /* Estimate total channel use caused by this frame */
775
776 /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values,
777 * 1 usec = 1/8 * (1080 / 10) = 13.5 */
778
779 if (tx->channel->band == IEEE80211_BAND_5GHZ ||
780 (tx->channel->band == IEEE80211_BAND_2GHZ &&
781 rate->flags & IEEE80211_RATE_ERP_G))
782 hdrtime = CHAN_UTIL_HDR_SHORT;
783 else
784 hdrtime = CHAN_UTIL_HDR_LONG;
785
786 load = hdrtime;
787 if (!is_multicast_ether_addr(hdr->addr1))
788 load += hdrtime;
789
790 if (tx->control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
791 load += 2 * hdrtime;
792 else if (tx->control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
793 load += hdrtime;
794 762
795 /* TODO: optimise again */ 763 if (!tx->sta)
796 load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; 764 return TX_CONTINUE;
797 765
766 tx->sta->tx_packets++;
767 tx->sta->tx_fragments++;
768 tx->sta->tx_bytes += tx->skb->len;
798 if (tx->extra_frag) { 769 if (tx->extra_frag) {
799 int i; 770 tx->sta->tx_fragments += tx->num_extra_frag;
800 for (i = 0; i < tx->num_extra_frag; i++) { 771 for (i = 0; i < tx->num_extra_frag; i++)
801 load += 2 * hdrtime; 772 tx->sta->tx_bytes += tx->extra_frag[i]->len;
802 load += tx->extra_frag[i]->len *
803 tx->rate->bitrate;
804 }
805 } 773 }
806 774
807 /* Divide channel_use by 8 to avoid wrapping around the counter */
808 load >>= CHAN_UTIL_SHIFT;
809 local->channel_use_raw += load;
810 if (tx->sta)
811 tx->sta->channel_use_raw += load;
812 tx->sdata->channel_use_raw += load;
813
814 return TX_CONTINUE; 775 return TX_CONTINUE;
815} 776}
816 777
@@ -823,11 +784,12 @@ static ieee80211_tx_handler ieee80211_tx_handlers[] =
823 ieee80211_tx_h_ps_buf, 784 ieee80211_tx_h_ps_buf,
824 ieee80211_tx_h_select_key, 785 ieee80211_tx_h_select_key,
825 ieee80211_tx_h_michael_mic_add, 786 ieee80211_tx_h_michael_mic_add,
826 ieee80211_tx_h_fragment,
827 ieee80211_tx_h_encrypt,
828 ieee80211_tx_h_rate_ctrl, 787 ieee80211_tx_h_rate_ctrl,
829 ieee80211_tx_h_misc, 788 ieee80211_tx_h_misc,
830 ieee80211_tx_h_load_stats, 789 ieee80211_tx_h_fragment,
790 /* handlers after fragment must be aware of tx info fragmentation! */
791 ieee80211_tx_h_encrypt,
792 ieee80211_tx_h_stats,
831 NULL 793 NULL
832}; 794};
833 795
@@ -854,12 +816,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
854 (struct ieee80211_radiotap_header *) skb->data; 816 (struct ieee80211_radiotap_header *) skb->data;
855 struct ieee80211_supported_band *sband; 817 struct ieee80211_supported_band *sband;
856 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); 818 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
857 struct ieee80211_tx_control *control = tx->control; 819 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
858 820
859 sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; 821 sband = tx->local->hw.wiphy->bands[tx->channel->band];
860 822
861 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; 823 info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
862 tx->flags |= IEEE80211_TX_INJECTED; 824 info->flags |= IEEE80211_TX_CTL_INJECTED;
863 tx->flags &= ~IEEE80211_TX_FRAGMENTED; 825 tx->flags &= ~IEEE80211_TX_FRAGMENTED;
864 826
865 /* 827 /*
@@ -896,7 +858,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
896 r = &sband->bitrates[i]; 858 r = &sband->bitrates[i];
897 859
898 if (r->bitrate == target_rate) { 860 if (r->bitrate == target_rate) {
899 tx->rate = r; 861 tx->rate_idx = i;
900 break; 862 break;
901 } 863 }
902 } 864 }
@@ -907,7 +869,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
907 * radiotap uses 0 for 1st ant, mac80211 is 1 for 869 * radiotap uses 0 for 1st ant, mac80211 is 1 for
908 * 1st ant 870 * 1st ant
909 */ 871 */
910 control->antenna_sel_tx = (*iterator.this_arg) + 1; 872 info->antenna_sel_tx = (*iterator.this_arg) + 1;
911 break; 873 break;
912 874
913#if 0 875#if 0
@@ -931,8 +893,8 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
931 skb_trim(skb, skb->len - FCS_LEN); 893 skb_trim(skb, skb->len - FCS_LEN);
932 } 894 }
933 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) 895 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
934 control->flags &= 896 info->flags &=
935 ~IEEE80211_TXCTL_DO_NOT_ENCRYPT; 897 ~IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
936 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) 898 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
937 tx->flags |= IEEE80211_TX_FRAGMENTED; 899 tx->flags |= IEEE80211_TX_FRAGMENTED;
938 break; 900 break;
@@ -967,12 +929,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
967static ieee80211_tx_result 929static ieee80211_tx_result
968__ieee80211_tx_prepare(struct ieee80211_tx_data *tx, 930__ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
969 struct sk_buff *skb, 931 struct sk_buff *skb,
970 struct net_device *dev, 932 struct net_device *dev)
971 struct ieee80211_tx_control *control)
972{ 933{
973 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 934 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
974 struct ieee80211_hdr *hdr; 935 struct ieee80211_hdr *hdr;
975 struct ieee80211_sub_if_data *sdata; 936 struct ieee80211_sub_if_data *sdata;
937 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
976 938
977 int hdrlen; 939 int hdrlen;
978 940
@@ -981,7 +943,9 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
981 tx->dev = dev; /* use original interface */ 943 tx->dev = dev; /* use original interface */
982 tx->local = local; 944 tx->local = local;
983 tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); 945 tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
984 tx->control = control; 946 tx->channel = local->hw.conf.channel;
947 tx->rate_idx = -1;
948 tx->last_frag_rate_idx = -1;
985 /* 949 /*
986 * Set this flag (used below to indicate "automatic fragmentation"), 950 * Set this flag (used below to indicate "automatic fragmentation"),
987 * it will be cleared/left by radiotap as desired. 951 * it will be cleared/left by radiotap as desired.
@@ -1008,10 +972,10 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1008 972
1009 if (is_multicast_ether_addr(hdr->addr1)) { 973 if (is_multicast_ether_addr(hdr->addr1)) {
1010 tx->flags &= ~IEEE80211_TX_UNICAST; 974 tx->flags &= ~IEEE80211_TX_UNICAST;
1011 control->flags |= IEEE80211_TXCTL_NO_ACK; 975 info->flags |= IEEE80211_TX_CTL_NO_ACK;
1012 } else { 976 } else {
1013 tx->flags |= IEEE80211_TX_UNICAST; 977 tx->flags |= IEEE80211_TX_UNICAST;
1014 control->flags &= ~IEEE80211_TXCTL_NO_ACK; 978 info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
1015 } 979 }
1016 980
1017 if (tx->flags & IEEE80211_TX_FRAGMENTED) { 981 if (tx->flags & IEEE80211_TX_FRAGMENTED) {
@@ -1024,18 +988,16 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1024 } 988 }
1025 989
1026 if (!tx->sta) 990 if (!tx->sta)
1027 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; 991 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1028 else if (tx->sta->flags & WLAN_STA_CLEAR_PS_FILT) { 992 else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT))
1029 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; 993 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1030 tx->sta->flags &= ~WLAN_STA_CLEAR_PS_FILT;
1031 }
1032 994
1033 hdrlen = ieee80211_get_hdrlen(tx->fc); 995 hdrlen = ieee80211_get_hdrlen(tx->fc);
1034 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { 996 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
1035 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; 997 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];
1036 tx->ethertype = (pos[0] << 8) | pos[1]; 998 tx->ethertype = (pos[0] << 8) | pos[1];
1037 } 999 }
1038 control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT; 1000 info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
1039 1001
1040 return TX_CONTINUE; 1002 return TX_CONTINUE;
1041} 1003}
@@ -1045,14 +1007,12 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1045 */ 1007 */
1046static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, 1008static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1047 struct sk_buff *skb, 1009 struct sk_buff *skb,
1048 struct net_device *mdev, 1010 struct net_device *mdev)
1049 struct ieee80211_tx_control *control)
1050{ 1011{
1051 struct ieee80211_tx_packet_data *pkt_data; 1012 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1052 struct net_device *dev; 1013 struct net_device *dev;
1053 1014
1054 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; 1015 dev = dev_get_by_index(&init_net, info->control.ifindex);
1055 dev = dev_get_by_index(&init_net, pkt_data->ifindex);
1056 if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { 1016 if (unlikely(dev && !is_ieee80211_device(dev, mdev))) {
1057 dev_put(dev); 1017 dev_put(dev);
1058 dev = NULL; 1018 dev = NULL;
@@ -1060,7 +1020,7 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1060 if (unlikely(!dev)) 1020 if (unlikely(!dev))
1061 return -ENODEV; 1021 return -ENODEV;
1062 /* initialises tx with control */ 1022 /* initialises tx with control */
1063 __ieee80211_tx_prepare(tx, skb, dev, control); 1023 __ieee80211_tx_prepare(tx, skb, dev);
1064 dev_put(dev); 1024 dev_put(dev);
1065 return 0; 1025 return 0;
1066} 1026}
@@ -1068,50 +1028,49 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1068static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, 1028static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1069 struct ieee80211_tx_data *tx) 1029 struct ieee80211_tx_data *tx)
1070{ 1030{
1071 struct ieee80211_tx_control *control = tx->control; 1031 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1072 int ret, i; 1032 int ret, i;
1073 1033
1074 if (!ieee80211_qdisc_installed(local->mdev) && 1034 if (netif_subqueue_stopped(local->mdev, skb))
1075 __ieee80211_queue_stopped(local, 0)) {
1076 netif_stop_queue(local->mdev);
1077 return IEEE80211_TX_AGAIN; 1035 return IEEE80211_TX_AGAIN;
1078 } 1036
1079 if (skb) { 1037 if (skb) {
1080 ieee80211_dump_frame(wiphy_name(local->hw.wiphy), 1038 ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
1081 "TX to low-level driver", skb); 1039 "TX to low-level driver", skb);
1082 ret = local->ops->tx(local_to_hw(local), skb, control); 1040 ret = local->ops->tx(local_to_hw(local), skb);
1083 if (ret) 1041 if (ret)
1084 return IEEE80211_TX_AGAIN; 1042 return IEEE80211_TX_AGAIN;
1085 local->mdev->trans_start = jiffies; 1043 local->mdev->trans_start = jiffies;
1086 ieee80211_led_tx(local, 1); 1044 ieee80211_led_tx(local, 1);
1087 } 1045 }
1088 if (tx->extra_frag) { 1046 if (tx->extra_frag) {
1089 control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
1090 IEEE80211_TXCTL_USE_CTS_PROTECT |
1091 IEEE80211_TXCTL_CLEAR_PS_FILT |
1092 IEEE80211_TXCTL_FIRST_FRAGMENT);
1093 for (i = 0; i < tx->num_extra_frag; i++) { 1047 for (i = 0; i < tx->num_extra_frag; i++) {
1094 if (!tx->extra_frag[i]) 1048 if (!tx->extra_frag[i])
1095 continue; 1049 continue;
1096 if (__ieee80211_queue_stopped(local, control->queue)) 1050 info = IEEE80211_SKB_CB(tx->extra_frag[i]);
1051 info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS |
1052 IEEE80211_TX_CTL_USE_CTS_PROTECT |
1053 IEEE80211_TX_CTL_CLEAR_PS_FILT |
1054 IEEE80211_TX_CTL_FIRST_FRAGMENT);
1055 if (netif_subqueue_stopped(local->mdev,
1056 tx->extra_frag[i]))
1097 return IEEE80211_TX_FRAG_AGAIN; 1057 return IEEE80211_TX_FRAG_AGAIN;
1098 if (i == tx->num_extra_frag) { 1058 if (i == tx->num_extra_frag) {
1099 control->tx_rate = tx->last_frag_rate; 1059 info->tx_rate_idx = tx->last_frag_rate_idx;
1100 1060
1101 if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) 1061 if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG)
1102 control->flags |= 1062 info->flags |=
1103 IEEE80211_TXCTL_RATE_CTRL_PROBE; 1063 IEEE80211_TX_CTL_RATE_CTRL_PROBE;
1104 else 1064 else
1105 control->flags &= 1065 info->flags &=
1106 ~IEEE80211_TXCTL_RATE_CTRL_PROBE; 1066 ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
1107 } 1067 }
1108 1068
1109 ieee80211_dump_frame(wiphy_name(local->hw.wiphy), 1069 ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
1110 "TX to low-level driver", 1070 "TX to low-level driver",
1111 tx->extra_frag[i]); 1071 tx->extra_frag[i]);
1112 ret = local->ops->tx(local_to_hw(local), 1072 ret = local->ops->tx(local_to_hw(local),
1113 tx->extra_frag[i], 1073 tx->extra_frag[i]);
1114 control);
1115 if (ret) 1074 if (ret)
1116 return IEEE80211_TX_FRAG_AGAIN; 1075 return IEEE80211_TX_FRAG_AGAIN;
1117 local->mdev->trans_start = jiffies; 1076 local->mdev->trans_start = jiffies;
@@ -1124,17 +1083,20 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1124 return IEEE80211_TX_OK; 1083 return IEEE80211_TX_OK;
1125} 1084}
1126 1085
1127static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, 1086static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)
1128 struct ieee80211_tx_control *control)
1129{ 1087{
1130 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1088 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1131 struct sta_info *sta; 1089 struct sta_info *sta;
1132 ieee80211_tx_handler *handler; 1090 ieee80211_tx_handler *handler;
1133 struct ieee80211_tx_data tx; 1091 struct ieee80211_tx_data tx;
1134 ieee80211_tx_result res = TX_DROP, res_prepare; 1092 ieee80211_tx_result res = TX_DROP, res_prepare;
1093 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1135 int ret, i; 1094 int ret, i;
1095 u16 queue;
1096
1097 queue = skb_get_queue_mapping(skb);
1136 1098
1137 WARN_ON(__ieee80211_queue_pending(local, control->queue)); 1099 WARN_ON(test_bit(queue, local->queues_pending));
1138 1100
1139 if (unlikely(skb->len < 10)) { 1101 if (unlikely(skb->len < 10)) {
1140 dev_kfree_skb(skb); 1102 dev_kfree_skb(skb);
@@ -1144,7 +1106,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1144 rcu_read_lock(); 1106 rcu_read_lock();
1145 1107
1146 /* initialises tx */ 1108 /* initialises tx */
1147 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control); 1109 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev);
1148 1110
1149 if (res_prepare == TX_DROP) { 1111 if (res_prepare == TX_DROP) {
1150 dev_kfree_skb(skb); 1112 dev_kfree_skb(skb);
@@ -1154,6 +1116,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1154 1116
1155 sta = tx.sta; 1117 sta = tx.sta;
1156 tx.channel = local->hw.conf.channel; 1118 tx.channel = local->hw.conf.channel;
1119 info->band = tx.channel->band;
1157 1120
1158 for (handler = ieee80211_tx_handlers; *handler != NULL; 1121 for (handler = ieee80211_tx_handlers; *handler != NULL;
1159 handler++) { 1122 handler++) {
@@ -1162,7 +1125,8 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1162 break; 1125 break;
1163 } 1126 }
1164 1127
1165 skb = tx.skb; /* handlers are allowed to change skb */ 1128 if (WARN_ON(tx.skb != skb))
1129 goto drop;
1166 1130
1167 if (unlikely(res == TX_DROP)) { 1131 if (unlikely(res == TX_DROP)) {
1168 I802_DEBUG_INC(local->tx_handlers_drop); 1132 I802_DEBUG_INC(local->tx_handlers_drop);
@@ -1186,7 +1150,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1186 next_len = tx.extra_frag[i + 1]->len; 1150 next_len = tx.extra_frag[i + 1]->len;
1187 } else { 1151 } else {
1188 next_len = 0; 1152 next_len = 0;
1189 tx.rate = tx.last_frag_rate; 1153 tx.rate_idx = tx.last_frag_rate_idx;
1190 } 1154 }
1191 dur = ieee80211_duration(&tx, 0, next_len); 1155 dur = ieee80211_duration(&tx, 0, next_len);
1192 hdr->duration_id = cpu_to_le16(dur); 1156 hdr->duration_id = cpu_to_le16(dur);
@@ -1196,34 +1160,41 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1196retry: 1160retry:
1197 ret = __ieee80211_tx(local, skb, &tx); 1161 ret = __ieee80211_tx(local, skb, &tx);
1198 if (ret) { 1162 if (ret) {
1199 struct ieee80211_tx_stored_packet *store = 1163 struct ieee80211_tx_stored_packet *store;
1200 &local->pending_packet[control->queue]; 1164
1165 /*
1166 * Since there are no fragmented frames on A-MPDU
1167 * queues, there's no reason for a driver to reject
1168 * a frame there, warn and drop it.
1169 */
1170 if (WARN_ON(queue >= ieee80211_num_regular_queues(&local->hw)))
1171 goto drop;
1172
1173 store = &local->pending_packet[queue];
1201 1174
1202 if (ret == IEEE80211_TX_FRAG_AGAIN) 1175 if (ret == IEEE80211_TX_FRAG_AGAIN)
1203 skb = NULL; 1176 skb = NULL;
1204 set_bit(IEEE80211_LINK_STATE_PENDING, 1177 set_bit(queue, local->queues_pending);
1205 &local->state[control->queue]);
1206 smp_mb(); 1178 smp_mb();
1207 /* When the driver gets out of buffers during sending of 1179 /*
1208 * fragments and calls ieee80211_stop_queue, there is 1180 * When the driver gets out of buffers during sending of
1209 * a small window between IEEE80211_LINK_STATE_XOFF and 1181 * fragments and calls ieee80211_stop_queue, the netif
1210 * IEEE80211_LINK_STATE_PENDING flags are set. If a buffer 1182 * subqueue is stopped. There is, however, a small window
1183 * in which the PENDING bit is not yet set. If a buffer
1211 * gets available in that window (i.e. driver calls 1184 * gets available in that window (i.e. driver calls
1212 * ieee80211_wake_queue), we would end up with ieee80211_tx 1185 * ieee80211_wake_queue), we would end up with ieee80211_tx
1213 * called with IEEE80211_LINK_STATE_PENDING. Prevent this by 1186 * called with the PENDING bit still set. Prevent this by
1214 * continuing transmitting here when that situation is 1187 * continuing transmitting here when that situation is
1215 * possible to have happened. */ 1188 * possible to have happened.
1216 if (!__ieee80211_queue_stopped(local, control->queue)) { 1189 */
1217 clear_bit(IEEE80211_LINK_STATE_PENDING, 1190 if (!__netif_subqueue_stopped(local->mdev, queue)) {
1218 &local->state[control->queue]); 1191 clear_bit(queue, local->queues_pending);
1219 goto retry; 1192 goto retry;
1220 } 1193 }
1221 memcpy(&store->control, control,
1222 sizeof(struct ieee80211_tx_control));
1223 store->skb = skb; 1194 store->skb = skb;
1224 store->extra_frag = tx.extra_frag; 1195 store->extra_frag = tx.extra_frag;
1225 store->num_extra_frag = tx.num_extra_frag; 1196 store->num_extra_frag = tx.num_extra_frag;
1226 store->last_frag_rate = tx.last_frag_rate; 1197 store->last_frag_rate_idx = tx.last_frag_rate_idx;
1227 store->last_frag_rate_ctrl_probe = 1198 store->last_frag_rate_ctrl_probe =
1228 !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); 1199 !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG);
1229 } 1200 }
@@ -1243,24 +1214,57 @@ retry:
1243 1214
1244/* device xmit handlers */ 1215/* device xmit handlers */
1245 1216
1217static int ieee80211_skb_resize(struct ieee80211_local *local,
1218 struct sk_buff *skb,
1219 int head_need, bool may_encrypt)
1220{
1221 int tail_need = 0;
1222
1223 /*
1224 * This could be optimised, devices that do full hardware
1225 * crypto (including TKIP MMIC) need no tailroom... But we
1226 * have no drivers for such devices currently.
1227 */
1228 if (may_encrypt) {
1229 tail_need = IEEE80211_ENCRYPT_TAILROOM;
1230 tail_need -= skb_tailroom(skb);
1231 tail_need = max_t(int, tail_need, 0);
1232 }
1233
1234 if (head_need || tail_need) {
1235 /* Sorry. Can't account for this any more */
1236 skb_orphan(skb);
1237 }
1238
1239 if (skb_header_cloned(skb))
1240 I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
1241 else
1242 I802_DEBUG_INC(local->tx_expand_skb_head);
1243
1244 if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
1245 printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n",
1246 wiphy_name(local->hw.wiphy));
1247 return -ENOMEM;
1248 }
1249
1250 /* update truesize too */
1251 skb->truesize += head_need + tail_need;
1252
1253 return 0;
1254}
1255
1246int ieee80211_master_start_xmit(struct sk_buff *skb, 1256int ieee80211_master_start_xmit(struct sk_buff *skb,
1247 struct net_device *dev) 1257 struct net_device *dev)
1248{ 1258{
1249 struct ieee80211_tx_control control; 1259 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1250 struct ieee80211_tx_packet_data *pkt_data;
1251 struct net_device *odev = NULL; 1260 struct net_device *odev = NULL;
1252 struct ieee80211_sub_if_data *osdata; 1261 struct ieee80211_sub_if_data *osdata;
1253 int headroom; 1262 int headroom;
1263 bool may_encrypt;
1254 int ret; 1264 int ret;
1255 1265
1256 /* 1266 if (info->control.ifindex)
1257 * copy control out of the skb so other people can use skb->cb 1267 odev = dev_get_by_index(&init_net, info->control.ifindex);
1258 */
1259 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
1260 memset(&control, 0, sizeof(struct ieee80211_tx_control));
1261
1262 if (pkt_data->ifindex)
1263 odev = dev_get_by_index(&init_net, pkt_data->ifindex);
1264 if (unlikely(odev && !is_ieee80211_device(odev, dev))) { 1268 if (unlikely(odev && !is_ieee80211_device(odev, dev))) {
1265 dev_put(odev); 1269 dev_put(odev);
1266 odev = NULL; 1270 odev = NULL;
@@ -1273,32 +1277,25 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1273 dev_kfree_skb(skb); 1277 dev_kfree_skb(skb);
1274 return 0; 1278 return 0;
1275 } 1279 }
1280
1276 osdata = IEEE80211_DEV_TO_SUB_IF(odev); 1281 osdata = IEEE80211_DEV_TO_SUB_IF(odev);
1277 1282
1278 headroom = osdata->local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM; 1283 may_encrypt = !(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT);
1279 if (skb_headroom(skb) < headroom) { 1284
1280 if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) { 1285 headroom = osdata->local->tx_headroom;
1281 dev_kfree_skb(skb); 1286 if (may_encrypt)
1282 dev_put(odev); 1287 headroom += IEEE80211_ENCRYPT_HEADROOM;
1283 return 0; 1288 headroom -= skb_headroom(skb);
1284 } 1289 headroom = max_t(int, 0, headroom);
1290
1291 if (ieee80211_skb_resize(osdata->local, skb, headroom, may_encrypt)) {
1292 dev_kfree_skb(skb);
1293 dev_put(odev);
1294 return 0;
1285 } 1295 }
1286 1296
1287 control.vif = &osdata->vif; 1297 info->control.vif = &osdata->vif;
1288 control.type = osdata->vif.type; 1298 ret = ieee80211_tx(odev, skb);
1289 if (pkt_data->flags & IEEE80211_TXPD_REQ_TX_STATUS)
1290 control.flags |= IEEE80211_TXCTL_REQ_TX_STATUS;
1291 if (pkt_data->flags & IEEE80211_TXPD_DO_NOT_ENCRYPT)
1292 control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
1293 if (pkt_data->flags & IEEE80211_TXPD_REQUEUE)
1294 control.flags |= IEEE80211_TXCTL_REQUEUE;
1295 if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME)
1296 control.flags |= IEEE80211_TXCTL_EAPOL_FRAME;
1297 if (pkt_data->flags & IEEE80211_TXPD_AMPDU)
1298 control.flags |= IEEE80211_TXCTL_AMPDU;
1299 control.queue = pkt_data->queue;
1300
1301 ret = ieee80211_tx(odev, skb, &control);
1302 dev_put(odev); 1299 dev_put(odev);
1303 1300
1304 return ret; 1301 return ret;
@@ -1308,7 +1305,7 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1308 struct net_device *dev) 1305 struct net_device *dev)
1309{ 1306{
1310 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1307 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1311 struct ieee80211_tx_packet_data *pkt_data; 1308 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1312 struct ieee80211_radiotap_header *prthdr = 1309 struct ieee80211_radiotap_header *prthdr =
1313 (struct ieee80211_radiotap_header *)skb->data; 1310 (struct ieee80211_radiotap_header *)skb->data;
1314 u16 len_rthdr; 1311 u16 len_rthdr;
@@ -1330,12 +1327,12 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1330 1327
1331 skb->dev = local->mdev; 1328 skb->dev = local->mdev;
1332 1329
1333 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
1334 memset(pkt_data, 0, sizeof(*pkt_data));
1335 /* needed because we set skb device to master */ 1330 /* needed because we set skb device to master */
1336 pkt_data->ifindex = dev->ifindex; 1331 info->control.ifindex = dev->ifindex;
1337 1332
1338 pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; 1333 info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
1334 /* Interfaces should always request a status report */
1335 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
1339 1336
1340 /* 1337 /*
1341 * fix up the pointers accounting for the radiotap 1338 * fix up the pointers accounting for the radiotap
@@ -1379,7 +1376,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1379 struct net_device *dev) 1376 struct net_device *dev)
1380{ 1377{
1381 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1378 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1382 struct ieee80211_tx_packet_data *pkt_data; 1379 struct ieee80211_tx_info *info;
1383 struct ieee80211_sub_if_data *sdata; 1380 struct ieee80211_sub_if_data *sdata;
1384 int ret = 1, head_need; 1381 int ret = 1, head_need;
1385 u16 ethertype, hdrlen, meshhdrlen = 0, fc; 1382 u16 ethertype, hdrlen, meshhdrlen = 0, fc;
@@ -1486,12 +1483,13 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1486 rcu_read_lock(); 1483 rcu_read_lock();
1487 sta = sta_info_get(local, hdr.addr1); 1484 sta = sta_info_get(local, hdr.addr1);
1488 if (sta) 1485 if (sta)
1489 sta_flags = sta->flags; 1486 sta_flags = get_sta_flags(sta);
1490 rcu_read_unlock(); 1487 rcu_read_unlock();
1491 } 1488 }
1492 1489
1493 /* receiver is QoS enabled, use a QoS type frame */ 1490 /* receiver and we are QoS enabled, use a QoS type frame */
1494 if (sta_flags & WLAN_STA_WME) { 1491 if (sta_flags & WLAN_STA_WME &&
1492 ieee80211_num_regular_queues(&local->hw) >= 4) {
1495 fc |= IEEE80211_STYPE_QOS_DATA; 1493 fc |= IEEE80211_STYPE_QOS_DATA;
1496 hdrlen += 2; 1494 hdrlen += 2;
1497 } 1495 }
@@ -1555,32 +1553,26 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1555 * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and 1553 * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and
1556 * alloc_skb() (net/core/skbuff.c) 1554 * alloc_skb() (net/core/skbuff.c)
1557 */ 1555 */
1558 head_need = hdrlen + encaps_len + meshhdrlen + local->tx_headroom; 1556 head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
1559 head_need -= skb_headroom(skb);
1560 1557
1561 /* We are going to modify skb data, so make a copy of it if happens to 1558 /*
1562 * be cloned. This could happen, e.g., with Linux bridge code passing 1559 * So we need to modify the skb header and hence need a copy of
1563 * us broadcast frames. */ 1560 * that. The head_need variable above doesn't, so far, include
1561 * the needed header space that we don't need right away. If we
1562 * can, then we don't reallocate right now but only after the
1563 * frame arrives at the master device (if it does...)
1564 *
1565 * If we cannot, however, then we will reallocate to include all
1566 * the ever needed space. Also, if we need to reallocate it anyway,
1567 * make it big enough for everything we may ever need.
1568 */
1564 1569
1565 if (head_need > 0 || skb_header_cloned(skb)) { 1570 if (head_need > 0 || skb_header_cloned(skb)) {
1566#if 0 1571 head_need += IEEE80211_ENCRYPT_HEADROOM;
1567 printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes " 1572 head_need += local->tx_headroom;
1568 "of headroom\n", dev->name, head_need); 1573 head_need = max_t(int, 0, head_need);
1569#endif 1574 if (ieee80211_skb_resize(local, skb, head_need, true))
1570
1571 if (skb_header_cloned(skb))
1572 I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
1573 else
1574 I802_DEBUG_INC(local->tx_expand_skb_head);
1575 /* Since we have to reallocate the buffer, make sure that there
1576 * is enough room for possible WEP IV/ICV and TKIP (8 bytes
1577 * before payload and 12 after). */
1578 if (pskb_expand_head(skb, (head_need > 0 ? head_need + 8 : 8),
1579 12, GFP_ATOMIC)) {
1580 printk(KERN_DEBUG "%s: failed to reallocate TX buffer"
1581 "\n", dev->name);
1582 goto fail; 1575 goto fail;
1583 }
1584 } 1576 }
1585 1577
1586 if (encaps_data) { 1578 if (encaps_data) {
@@ -1611,11 +1603,14 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1611 nh_pos += hdrlen; 1603 nh_pos += hdrlen;
1612 h_pos += hdrlen; 1604 h_pos += hdrlen;
1613 1605
1614 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; 1606 info = IEEE80211_SKB_CB(skb);
1615 memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); 1607 memset(info, 0, sizeof(*info));
1616 pkt_data->ifindex = dev->ifindex; 1608 info->control.ifindex = dev->ifindex;
1617 if (ethertype == ETH_P_PAE) 1609 if (ethertype == ETH_P_PAE)
1618 pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; 1610 info->flags |= IEEE80211_TX_CTL_EAPOL_FRAME;
1611
1612 /* Interfaces should always request a status report */
1613 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
1619 1614
1620 skb->dev = local->mdev; 1615 skb->dev = local->mdev;
1621 dev->stats.tx_packets++; 1616 dev->stats.tx_packets++;
@@ -1640,46 +1635,55 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1640 return ret; 1635 return ret;
1641} 1636}
1642 1637
1643/* helper functions for pending packets for when queues are stopped */
1644 1638
1639/*
1640 * ieee80211_clear_tx_pending may not be called in a context where
1641 * it is possible that it packets could come in again.
1642 */
1645void ieee80211_clear_tx_pending(struct ieee80211_local *local) 1643void ieee80211_clear_tx_pending(struct ieee80211_local *local)
1646{ 1644{
1647 int i, j; 1645 int i, j;
1648 struct ieee80211_tx_stored_packet *store; 1646 struct ieee80211_tx_stored_packet *store;
1649 1647
1650 for (i = 0; i < local->hw.queues; i++) { 1648 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
1651 if (!__ieee80211_queue_pending(local, i)) 1649 if (!test_bit(i, local->queues_pending))
1652 continue; 1650 continue;
1653 store = &local->pending_packet[i]; 1651 store = &local->pending_packet[i];
1654 kfree_skb(store->skb); 1652 kfree_skb(store->skb);
1655 for (j = 0; j < store->num_extra_frag; j++) 1653 for (j = 0; j < store->num_extra_frag; j++)
1656 kfree_skb(store->extra_frag[j]); 1654 kfree_skb(store->extra_frag[j]);
1657 kfree(store->extra_frag); 1655 kfree(store->extra_frag);
1658 clear_bit(IEEE80211_LINK_STATE_PENDING, &local->state[i]); 1656 clear_bit(i, local->queues_pending);
1659 } 1657 }
1660} 1658}
1661 1659
1660/*
1661 * Transmit all pending packets. Called from tasklet, locks master device
1662 * TX lock so that no new packets can come in.
1663 */
1662void ieee80211_tx_pending(unsigned long data) 1664void ieee80211_tx_pending(unsigned long data)
1663{ 1665{
1664 struct ieee80211_local *local = (struct ieee80211_local *)data; 1666 struct ieee80211_local *local = (struct ieee80211_local *)data;
1665 struct net_device *dev = local->mdev; 1667 struct net_device *dev = local->mdev;
1666 struct ieee80211_tx_stored_packet *store; 1668 struct ieee80211_tx_stored_packet *store;
1667 struct ieee80211_tx_data tx; 1669 struct ieee80211_tx_data tx;
1668 int i, ret, reschedule = 0; 1670 int i, ret;
1669 1671
1670 netif_tx_lock_bh(dev); 1672 netif_tx_lock_bh(dev);
1671 for (i = 0; i < local->hw.queues; i++) { 1673 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
1672 if (__ieee80211_queue_stopped(local, i)) 1674 /* Check that this queue is ok */
1675 if (__netif_subqueue_stopped(local->mdev, i))
1673 continue; 1676 continue;
1674 if (!__ieee80211_queue_pending(local, i)) { 1677
1675 reschedule = 1; 1678 if (!test_bit(i, local->queues_pending)) {
1679 ieee80211_wake_queue(&local->hw, i);
1676 continue; 1680 continue;
1677 } 1681 }
1682
1678 store = &local->pending_packet[i]; 1683 store = &local->pending_packet[i];
1679 tx.control = &store->control;
1680 tx.extra_frag = store->extra_frag; 1684 tx.extra_frag = store->extra_frag;
1681 tx.num_extra_frag = store->num_extra_frag; 1685 tx.num_extra_frag = store->num_extra_frag;
1682 tx.last_frag_rate = store->last_frag_rate; 1686 tx.last_frag_rate_idx = store->last_frag_rate_idx;
1683 tx.flags = 0; 1687 tx.flags = 0;
1684 if (store->last_frag_rate_ctrl_probe) 1688 if (store->last_frag_rate_ctrl_probe)
1685 tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; 1689 tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG;
@@ -1688,19 +1692,11 @@ void ieee80211_tx_pending(unsigned long data)
1688 if (ret == IEEE80211_TX_FRAG_AGAIN) 1692 if (ret == IEEE80211_TX_FRAG_AGAIN)
1689 store->skb = NULL; 1693 store->skb = NULL;
1690 } else { 1694 } else {
1691 clear_bit(IEEE80211_LINK_STATE_PENDING, 1695 clear_bit(i, local->queues_pending);
1692 &local->state[i]); 1696 ieee80211_wake_queue(&local->hw, i);
1693 reschedule = 1;
1694 } 1697 }
1695 } 1698 }
1696 netif_tx_unlock_bh(dev); 1699 netif_tx_unlock_bh(dev);
1697 if (reschedule) {
1698 if (!ieee80211_qdisc_installed(dev)) {
1699 if (!__ieee80211_queue_stopped(local, 0))
1700 netif_wake_queue(dev);
1701 } else
1702 netif_schedule(dev);
1703 }
1704} 1700}
1705 1701
1706/* functions for drivers to get certain frames */ 1702/* functions for drivers to get certain frames */
@@ -1769,11 +1765,11 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
1769} 1765}
1770 1766
1771struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, 1767struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1772 struct ieee80211_vif *vif, 1768 struct ieee80211_vif *vif)
1773 struct ieee80211_tx_control *control)
1774{ 1769{
1775 struct ieee80211_local *local = hw_to_local(hw); 1770 struct ieee80211_local *local = hw_to_local(hw);
1776 struct sk_buff *skb; 1771 struct sk_buff *skb;
1772 struct ieee80211_tx_info *info;
1777 struct net_device *bdev; 1773 struct net_device *bdev;
1778 struct ieee80211_sub_if_data *sdata = NULL; 1774 struct ieee80211_sub_if_data *sdata = NULL;
1779 struct ieee80211_if_ap *ap = NULL; 1775 struct ieee80211_if_ap *ap = NULL;
@@ -1783,9 +1779,10 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1783 struct ieee80211_mgmt *mgmt; 1779 struct ieee80211_mgmt *mgmt;
1784 int *num_beacons; 1780 int *num_beacons;
1785 bool err = true; 1781 bool err = true;
1782 enum ieee80211_band band = local->hw.conf.channel->band;
1786 u8 *pos; 1783 u8 *pos;
1787 1784
1788 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1785 sband = local->hw.wiphy->bands[band];
1789 1786
1790 rcu_read_lock(); 1787 rcu_read_lock();
1791 1788
@@ -1878,30 +1875,32 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1878 goto out; 1875 goto out;
1879 } 1876 }
1880 1877
1881 if (control) { 1878 info = IEEE80211_SKB_CB(skb);
1882 rate_control_get_rate(local->mdev, sband, skb, &rsel);
1883 if (!rsel.rate) {
1884 if (net_ratelimit()) {
1885 printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
1886 "no rate found\n",
1887 wiphy_name(local->hw.wiphy));
1888 }
1889 dev_kfree_skb(skb);
1890 skb = NULL;
1891 goto out;
1892 }
1893 1879
1894 control->vif = vif; 1880 info->band = band;
1895 control->tx_rate = rsel.rate; 1881 rate_control_get_rate(local->mdev, sband, skb, &rsel);
1896 if (sdata->bss_conf.use_short_preamble && 1882
1897 rsel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) 1883 if (unlikely(rsel.rate_idx < 0)) {
1898 control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; 1884 if (net_ratelimit()) {
1899 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; 1885 printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
1900 control->flags |= IEEE80211_TXCTL_NO_ACK; 1886 "no rate found\n",
1901 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; 1887 wiphy_name(local->hw.wiphy));
1902 control->retry_limit = 1; 1888 }
1903 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; 1889 dev_kfree_skb(skb);
1890 skb = NULL;
1891 goto out;
1904 } 1892 }
1893
1894 info->control.vif = vif;
1895 info->tx_rate_idx = rsel.rate_idx;
1896 if (sdata->bss_conf.use_short_preamble &&
1897 sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
1898 info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
1899 info->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
1900 info->flags |= IEEE80211_TX_CTL_NO_ACK;
1901 info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
1902 info->control.retry_limit = 1;
1903 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1905 (*num_beacons)++; 1904 (*num_beacons)++;
1906out: 1905out:
1907 rcu_read_unlock(); 1906 rcu_read_unlock();
@@ -1911,7 +1910,7 @@ EXPORT_SYMBOL(ieee80211_beacon_get);
1911 1910
1912void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1911void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1913 const void *frame, size_t frame_len, 1912 const void *frame, size_t frame_len,
1914 const struct ieee80211_tx_control *frame_txctl, 1913 const struct ieee80211_tx_info *frame_txctl,
1915 struct ieee80211_rts *rts) 1914 struct ieee80211_rts *rts)
1916{ 1915{
1917 const struct ieee80211_hdr *hdr = frame; 1916 const struct ieee80211_hdr *hdr = frame;
@@ -1928,7 +1927,7 @@ EXPORT_SYMBOL(ieee80211_rts_get);
1928 1927
1929void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1928void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1930 const void *frame, size_t frame_len, 1929 const void *frame, size_t frame_len,
1931 const struct ieee80211_tx_control *frame_txctl, 1930 const struct ieee80211_tx_info *frame_txctl,
1932 struct ieee80211_cts *cts) 1931 struct ieee80211_cts *cts)
1933{ 1932{
1934 const struct ieee80211_hdr *hdr = frame; 1933 const struct ieee80211_hdr *hdr = frame;
@@ -1944,11 +1943,10 @@ EXPORT_SYMBOL(ieee80211_ctstoself_get);
1944 1943
1945struct sk_buff * 1944struct sk_buff *
1946ieee80211_get_buffered_bc(struct ieee80211_hw *hw, 1945ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
1947 struct ieee80211_vif *vif, 1946 struct ieee80211_vif *vif)
1948 struct ieee80211_tx_control *control)
1949{ 1947{
1950 struct ieee80211_local *local = hw_to_local(hw); 1948 struct ieee80211_local *local = hw_to_local(hw);
1951 struct sk_buff *skb; 1949 struct sk_buff *skb = NULL;
1952 struct sta_info *sta; 1950 struct sta_info *sta;
1953 ieee80211_tx_handler *handler; 1951 ieee80211_tx_handler *handler;
1954 struct ieee80211_tx_data tx; 1952 struct ieee80211_tx_data tx;
@@ -1957,10 +1955,11 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
1957 struct ieee80211_sub_if_data *sdata; 1955 struct ieee80211_sub_if_data *sdata;
1958 struct ieee80211_if_ap *bss = NULL; 1956 struct ieee80211_if_ap *bss = NULL;
1959 struct beacon_data *beacon; 1957 struct beacon_data *beacon;
1958 struct ieee80211_tx_info *info;
1960 1959
1961 sdata = vif_to_sdata(vif); 1960 sdata = vif_to_sdata(vif);
1962 bdev = sdata->dev; 1961 bdev = sdata->dev;
1963 1962 bss = &sdata->u.ap;
1964 1963
1965 if (!bss) 1964 if (!bss)
1966 return NULL; 1965 return NULL;
@@ -1968,19 +1967,16 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
1968 rcu_read_lock(); 1967 rcu_read_lock();
1969 beacon = rcu_dereference(bss->beacon); 1968 beacon = rcu_dereference(bss->beacon);
1970 1969
1971 if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || 1970 if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || !beacon->head)
1972 !beacon->head) { 1971 goto out;
1973 rcu_read_unlock();
1974 return NULL;
1975 }
1976 1972
1977 if (bss->dtim_count != 0) 1973 if (bss->dtim_count != 0)
1978 return NULL; /* send buffered bc/mc only after DTIM beacon */ 1974 goto out; /* send buffered bc/mc only after DTIM beacon */
1979 memset(control, 0, sizeof(*control)); 1975
1980 while (1) { 1976 while (1) {
1981 skb = skb_dequeue(&bss->ps_bc_buf); 1977 skb = skb_dequeue(&bss->ps_bc_buf);
1982 if (!skb) 1978 if (!skb)
1983 return NULL; 1979 goto out;
1984 local->total_ps_buffered--; 1980 local->total_ps_buffered--;
1985 1981
1986 if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { 1982 if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) {
@@ -1993,20 +1989,26 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
1993 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1989 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1994 } 1990 }
1995 1991
1996 if (!ieee80211_tx_prepare(&tx, skb, local->mdev, control)) 1992 if (!ieee80211_tx_prepare(&tx, skb, local->mdev))
1997 break; 1993 break;
1998 dev_kfree_skb_any(skb); 1994 dev_kfree_skb_any(skb);
1999 } 1995 }
1996
1997 info = IEEE80211_SKB_CB(skb);
1998
2000 sta = tx.sta; 1999 sta = tx.sta;
2001 tx.flags |= IEEE80211_TX_PS_BUFFERED; 2000 tx.flags |= IEEE80211_TX_PS_BUFFERED;
2002 tx.channel = local->hw.conf.channel; 2001 tx.channel = local->hw.conf.channel;
2002 info->band = tx.channel->band;
2003 2003
2004 for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { 2004 for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) {
2005 res = (*handler)(&tx); 2005 res = (*handler)(&tx);
2006 if (res == TX_DROP || res == TX_QUEUED) 2006 if (res == TX_DROP || res == TX_QUEUED)
2007 break; 2007 break;
2008 } 2008 }
2009 skb = tx.skb; /* handlers are allowed to change skb */ 2009
2010 if (WARN_ON(tx.skb != skb))
2011 res = TX_DROP;
2010 2012
2011 if (res == TX_DROP) { 2013 if (res == TX_DROP) {
2012 I802_DEBUG_INC(local->tx_handlers_drop); 2014 I802_DEBUG_INC(local->tx_handlers_drop);
@@ -2017,6 +2019,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2017 skb = NULL; 2019 skb = NULL;
2018 } 2020 }
2019 2021
2022out:
2020 rcu_read_unlock(); 2023 rcu_read_unlock();
2021 2024
2022 return skb; 2025 return skb;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 4e97b266f907..6513bc2d2707 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -258,7 +258,7 @@ EXPORT_SYMBOL(ieee80211_generic_frame_duration);
258 258
259__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, 259__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
260 struct ieee80211_vif *vif, size_t frame_len, 260 struct ieee80211_vif *vif, size_t frame_len,
261 const struct ieee80211_tx_control *frame_txctl) 261 const struct ieee80211_tx_info *frame_txctl)
262{ 262{
263 struct ieee80211_local *local = hw_to_local(hw); 263 struct ieee80211_local *local = hw_to_local(hw);
264 struct ieee80211_rate *rate; 264 struct ieee80211_rate *rate;
@@ -266,10 +266,13 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
266 bool short_preamble; 266 bool short_preamble;
267 int erp; 267 int erp;
268 u16 dur; 268 u16 dur;
269 struct ieee80211_supported_band *sband;
270
271 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
269 272
270 short_preamble = sdata->bss_conf.use_short_preamble; 273 short_preamble = sdata->bss_conf.use_short_preamble;
271 274
272 rate = frame_txctl->rts_cts_rate; 275 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
273 276
274 erp = 0; 277 erp = 0;
275 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 278 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
@@ -292,7 +295,7 @@ EXPORT_SYMBOL(ieee80211_rts_duration);
292__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, 295__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
293 struct ieee80211_vif *vif, 296 struct ieee80211_vif *vif,
294 size_t frame_len, 297 size_t frame_len,
295 const struct ieee80211_tx_control *frame_txctl) 298 const struct ieee80211_tx_info *frame_txctl)
296{ 299{
297 struct ieee80211_local *local = hw_to_local(hw); 300 struct ieee80211_local *local = hw_to_local(hw);
298 struct ieee80211_rate *rate; 301 struct ieee80211_rate *rate;
@@ -300,10 +303,13 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
300 bool short_preamble; 303 bool short_preamble;
301 int erp; 304 int erp;
302 u16 dur; 305 u16 dur;
306 struct ieee80211_supported_band *sband;
307
308 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
303 309
304 short_preamble = sdata->bss_conf.use_short_preamble; 310 short_preamble = sdata->bss_conf.use_short_preamble;
305 311
306 rate = frame_txctl->rts_cts_rate; 312 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
307 erp = 0; 313 erp = 0;
308 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 314 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
309 erp = rate->flags & IEEE80211_RATE_ERP_G; 315 erp = rate->flags & IEEE80211_RATE_ERP_G;
@@ -311,7 +317,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
311 /* Data frame duration */ 317 /* Data frame duration */
312 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, 318 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate,
313 erp, short_preamble); 319 erp, short_preamble);
314 if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { 320 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
315 /* ACK duration */ 321 /* ACK duration */
316 dur += ieee80211_frame_duration(local, 10, rate->bitrate, 322 dur += ieee80211_frame_duration(local, 10, rate->bitrate,
317 erp, short_preamble); 323 erp, short_preamble);
@@ -325,17 +331,15 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
325{ 331{
326 struct ieee80211_local *local = hw_to_local(hw); 332 struct ieee80211_local *local = hw_to_local(hw);
327 333
328 if (test_and_clear_bit(IEEE80211_LINK_STATE_XOFF, 334 if (test_bit(queue, local->queues_pending)) {
329 &local->state[queue])) { 335 tasklet_schedule(&local->tx_pending_tasklet);
330 if (test_bit(IEEE80211_LINK_STATE_PENDING, 336 } else {
331 &local->state[queue])) 337 if (ieee80211_is_multiqueue(local)) {
332 tasklet_schedule(&local->tx_pending_tasklet); 338 netif_wake_subqueue(local->mdev, queue);
333 else 339 } else {
334 if (!ieee80211_qdisc_installed(local->mdev)) { 340 WARN_ON(queue != 0);
335 if (queue == 0) 341 netif_wake_queue(local->mdev);
336 netif_wake_queue(local->mdev); 342 }
337 } else
338 __netif_schedule(local->mdev);
339 } 343 }
340} 344}
341EXPORT_SYMBOL(ieee80211_wake_queue); 345EXPORT_SYMBOL(ieee80211_wake_queue);
@@ -344,29 +348,20 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
344{ 348{
345 struct ieee80211_local *local = hw_to_local(hw); 349 struct ieee80211_local *local = hw_to_local(hw);
346 350
347 if (!ieee80211_qdisc_installed(local->mdev) && queue == 0) 351 if (ieee80211_is_multiqueue(local)) {
352 netif_stop_subqueue(local->mdev, queue);
353 } else {
354 WARN_ON(queue != 0);
348 netif_stop_queue(local->mdev); 355 netif_stop_queue(local->mdev);
349 set_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]); 356 }
350} 357}
351EXPORT_SYMBOL(ieee80211_stop_queue); 358EXPORT_SYMBOL(ieee80211_stop_queue);
352 359
353void ieee80211_start_queues(struct ieee80211_hw *hw)
354{
355 struct ieee80211_local *local = hw_to_local(hw);
356 int i;
357
358 for (i = 0; i < local->hw.queues; i++)
359 clear_bit(IEEE80211_LINK_STATE_XOFF, &local->state[i]);
360 if (!ieee80211_qdisc_installed(local->mdev))
361 netif_start_queue(local->mdev);
362}
363EXPORT_SYMBOL(ieee80211_start_queues);
364
365void ieee80211_stop_queues(struct ieee80211_hw *hw) 360void ieee80211_stop_queues(struct ieee80211_hw *hw)
366{ 361{
367 int i; 362 int i;
368 363
369 for (i = 0; i < hw->queues; i++) 364 for (i = 0; i < ieee80211_num_queues(hw); i++)
370 ieee80211_stop_queue(hw, i); 365 ieee80211_stop_queue(hw, i);
371} 366}
372EXPORT_SYMBOL(ieee80211_stop_queues); 367EXPORT_SYMBOL(ieee80211_stop_queues);
@@ -375,7 +370,7 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw)
375{ 370{
376 int i; 371 int i;
377 372
378 for (i = 0; i < hw->queues; i++) 373 for (i = 0; i < hw->queues + hw->ampdu_queues; i++)
379 ieee80211_wake_queue(hw, i); 374 ieee80211_wake_queue(hw, i);
380} 375}
381EXPORT_SYMBOL(ieee80211_wake_queues); 376EXPORT_SYMBOL(ieee80211_wake_queues);
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index affcecd78c10..e7b6344c900a 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -93,13 +93,9 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
93 fc |= IEEE80211_FCTL_PROTECTED; 93 fc |= IEEE80211_FCTL_PROTECTED;
94 hdr->frame_control = cpu_to_le16(fc); 94 hdr->frame_control = cpu_to_le16(fc);
95 95
96 if ((skb_headroom(skb) < WEP_IV_LEN || 96 if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN ||
97 skb_tailroom(skb) < WEP_ICV_LEN)) { 97 skb_headroom(skb) < WEP_IV_LEN))
98 I802_DEBUG_INC(local->tx_expand_skb_head); 98 return NULL;
99 if (unlikely(pskb_expand_head(skb, WEP_IV_LEN, WEP_ICV_LEN,
100 GFP_ATOMIC)))
101 return NULL;
102 }
103 99
104 hdrlen = ieee80211_get_hdrlen(fc); 100 hdrlen = ieee80211_get_hdrlen(fc);
105 newhdr = skb_push(skb, WEP_IV_LEN); 101 newhdr = skb_push(skb, WEP_IV_LEN);
@@ -333,11 +329,16 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
333 329
334static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) 330static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
335{ 331{
332 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
333
334 info->control.iv_len = WEP_IV_LEN;
335 info->control.icv_len = WEP_ICV_LEN;
336
336 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { 337 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
337 if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) 338 if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
338 return -1; 339 return -1;
339 } else { 340 } else {
340 tx->control->key_idx = tx->key->conf.hw_key_idx; 341 info->control.hw_key = &tx->key->conf;
341 if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { 342 if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
342 if (!ieee80211_wep_add_iv(tx->local, skb, tx->key)) 343 if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
343 return -1; 344 return -1;
@@ -349,8 +350,6 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
349ieee80211_tx_result 350ieee80211_tx_result
350ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) 351ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
351{ 352{
352 tx->control->iv_len = WEP_IV_LEN;
353 tx->control->icv_len = WEP_ICV_LEN;
354 ieee80211_tx_set_protected(tx); 353 ieee80211_tx_set_protected(tx);
355 354
356 if (wep_encrypt_skb(tx, tx->skb) < 0) { 355 if (wep_encrypt_skb(tx, tx->skb) < 0) {
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index 363779c50658..e587172115b8 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -26,7 +26,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
26 struct ieee80211_key *key); 26 struct ieee80211_key *key);
27int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, 27int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
28 struct ieee80211_key *key); 28 struct ieee80211_key *key);
29u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); 29u8 *ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
30 30
31ieee80211_rx_result 31ieee80211_rx_result
32ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); 32ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx);
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index a8bb8e31b1ec..4806d96b9877 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -169,14 +169,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
169 range->num_encoding_sizes = 2; 169 range->num_encoding_sizes = 2;
170 range->max_encoding_tokens = NUM_DEFAULT_KEYS; 170 range->max_encoding_tokens = NUM_DEFAULT_KEYS;
171 171
172 range->max_qual.qual = local->hw.max_signal; 172 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC ||
173 range->max_qual.level = local->hw.max_rssi; 173 local->hw.flags & IEEE80211_HW_SIGNAL_DB)
174 range->max_qual.noise = local->hw.max_noise; 174 range->max_qual.level = local->hw.max_signal;
175 else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
176 range->max_qual.level = -110;
177 else
178 range->max_qual.level = 0;
179
180 if (local->hw.flags & IEEE80211_HW_NOISE_DBM)
181 range->max_qual.noise = -110;
182 else
183 range->max_qual.noise = 0;
184
185 range->max_qual.qual = 100;
175 range->max_qual.updated = local->wstats_flags; 186 range->max_qual.updated = local->wstats_flags;
176 187
177 range->avg_qual.qual = local->hw.max_signal/2; 188 range->avg_qual.qual = 50;
178 range->avg_qual.level = 0; 189 /* not always true but better than nothing */
179 range->avg_qual.noise = 0; 190 range->avg_qual.level = range->max_qual.level / 2;
191 range->avg_qual.noise = range->max_qual.noise / 2;
180 range->avg_qual.updated = local->wstats_flags; 192 range->avg_qual.updated = local->wstats_flags;
181 193
182 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 194 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
@@ -1007,8 +1019,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
1007 wstats->qual.noise = 0; 1019 wstats->qual.noise = 0;
1008 wstats->qual.updated = IW_QUAL_ALL_INVALID; 1020 wstats->qual.updated = IW_QUAL_ALL_INVALID;
1009 } else { 1021 } else {
1010 wstats->qual.level = sta->last_rssi; 1022 wstats->qual.level = sta->last_signal;
1011 wstats->qual.qual = sta->last_signal; 1023 wstats->qual.qual = sta->last_qual;
1012 wstats->qual.noise = sta->last_noise; 1024 wstats->qual.noise = sta->last_noise;
1013 wstats->qual.updated = local->wstats_flags; 1025 wstats->qual.updated = local->wstats_flags;
1014 } 1026 }
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index dc1598b86004..14a9ff10a1e9 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -19,16 +19,22 @@
19#include "wme.h" 19#include "wme.h"
20 20
21/* maximum number of hardware queues we support. */ 21/* maximum number of hardware queues we support. */
22#define TC_80211_MAX_QUEUES 16 22#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
23/* current number of hardware queues we support. */
24#define QD_NUM(hw) ((hw)->queues + (hw)->ampdu_queues)
23 25
26/*
27 * Default mapping in classifier to work with default
28 * queue setup.
29 */
24const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; 30const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 };
25 31
26struct ieee80211_sched_data 32struct ieee80211_sched_data
27{ 33{
28 unsigned long qdisc_pool[BITS_TO_LONGS(TC_80211_MAX_QUEUES)]; 34 unsigned long qdisc_pool[BITS_TO_LONGS(QD_MAX_QUEUES)];
29 struct tcf_proto *filter_list; 35 struct tcf_proto *filter_list;
30 struct Qdisc *queues[TC_80211_MAX_QUEUES]; 36 struct Qdisc *queues[QD_MAX_QUEUES];
31 struct sk_buff_head requeued[TC_80211_MAX_QUEUES]; 37 struct sk_buff_head requeued[QD_MAX_QUEUES];
32}; 38};
33 39
34static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0}; 40static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0};
@@ -95,7 +101,7 @@ static inline int wme_downgrade_ac(struct sk_buff *skb)
95 101
96/* positive return value indicates which queue to use 102/* positive return value indicates which queue to use
97 * negative return value indicates to drop the frame */ 103 * negative return value indicates to drop the frame */
98static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) 104static int classify80211(struct sk_buff *skb, struct Qdisc *qd)
99{ 105{
100 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); 106 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
101 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 107 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -106,7 +112,7 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
106 if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) { 112 if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) {
107 /* management frames go on AC_VO queue, but are sent 113 /* management frames go on AC_VO queue, but are sent
108 * without QoS control fields */ 114 * without QoS control fields */
109 return IEEE80211_TX_QUEUE_DATA0; 115 return 0;
110 } 116 }
111 117
112 if (0 /* injected */) { 118 if (0 /* injected */) {
@@ -141,29 +147,29 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
141static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) 147static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
142{ 148{
143 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); 149 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
150 struct ieee80211_hw *hw = &local->hw;
144 struct ieee80211_sched_data *q = qdisc_priv(qd); 151 struct ieee80211_sched_data *q = qdisc_priv(qd);
145 struct ieee80211_tx_packet_data *pkt_data = 152 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
146 (struct ieee80211_tx_packet_data *) skb->cb;
147 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 153 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
148 unsigned short fc = le16_to_cpu(hdr->frame_control); 154 unsigned short fc = le16_to_cpu(hdr->frame_control);
149 struct Qdisc *qdisc; 155 struct Qdisc *qdisc;
150 int err, queue;
151 struct sta_info *sta; 156 struct sta_info *sta;
157 int err, queue;
152 u8 tid; 158 u8 tid;
153 159
154 if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) { 160 if (info->flags & IEEE80211_TX_CTL_REQUEUE) {
155 queue = pkt_data->queue; 161 queue = skb_get_queue_mapping(skb);
156 rcu_read_lock(); 162 rcu_read_lock();
157 sta = sta_info_get(local, hdr->addr1); 163 sta = sta_info_get(local, hdr->addr1);
158 tid = skb->priority & QOS_CONTROL_TAG1D_MASK; 164 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
159 if (sta) { 165 if (sta) {
160 int ampdu_queue = sta->tid_to_tx_q[tid]; 166 int ampdu_queue = sta->tid_to_tx_q[tid];
161 if ((ampdu_queue < local->hw.queues) && 167 if ((ampdu_queue < QD_NUM(hw)) &&
162 test_bit(ampdu_queue, q->qdisc_pool)) { 168 test_bit(ampdu_queue, q->qdisc_pool)) {
163 queue = ampdu_queue; 169 queue = ampdu_queue;
164 pkt_data->flags |= IEEE80211_TXPD_AMPDU; 170 info->flags |= IEEE80211_TX_CTL_AMPDU;
165 } else { 171 } else {
166 pkt_data->flags &= ~IEEE80211_TXPD_AMPDU; 172 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
167 } 173 }
168 } 174 }
169 rcu_read_unlock(); 175 rcu_read_unlock();
@@ -174,6 +180,9 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
174 180
175 queue = classify80211(skb, qd); 181 queue = classify80211(skb, qd);
176 182
183 if (unlikely(queue >= local->hw.queues))
184 queue = local->hw.queues - 1;
185
177 /* now we know the 1d priority, fill in the QoS header if there is one 186 /* now we know the 1d priority, fill in the QoS header if there is one
178 */ 187 */
179 if (WLAN_FC_IS_QOS_DATA(fc)) { 188 if (WLAN_FC_IS_QOS_DATA(fc)) {
@@ -193,35 +202,24 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
193 sta = sta_info_get(local, hdr->addr1); 202 sta = sta_info_get(local, hdr->addr1);
194 if (sta) { 203 if (sta) {
195 int ampdu_queue = sta->tid_to_tx_q[tid]; 204 int ampdu_queue = sta->tid_to_tx_q[tid];
196 if ((ampdu_queue < local->hw.queues) && 205 if ((ampdu_queue < QD_NUM(hw)) &&
197 test_bit(ampdu_queue, q->qdisc_pool)) { 206 test_bit(ampdu_queue, q->qdisc_pool)) {
198 queue = ampdu_queue; 207 queue = ampdu_queue;
199 pkt_data->flags |= IEEE80211_TXPD_AMPDU; 208 info->flags |= IEEE80211_TX_CTL_AMPDU;
200 } else { 209 } else {
201 pkt_data->flags &= ~IEEE80211_TXPD_AMPDU; 210 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
202 } 211 }
203 } 212 }
204 213
205 rcu_read_unlock(); 214 rcu_read_unlock();
206 } 215 }
207 216
208 if (unlikely(queue >= local->hw.queues)) {
209#if 0
210 if (net_ratelimit()) {
211 printk(KERN_DEBUG "%s - queue=%d (hw does not "
212 "support) -> %d\n",
213 __func__, queue, local->hw.queues - 1);
214 }
215#endif
216 queue = local->hw.queues - 1;
217 }
218
219 if (unlikely(queue < 0)) { 217 if (unlikely(queue < 0)) {
220 kfree_skb(skb); 218 kfree_skb(skb);
221 err = NET_XMIT_DROP; 219 err = NET_XMIT_DROP;
222 } else { 220 } else {
223 tid = skb->priority & QOS_CONTROL_TAG1D_MASK; 221 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
224 pkt_data->queue = (unsigned int) queue; 222 skb_set_queue_mapping(skb, queue);
225 qdisc = q->queues[queue]; 223 qdisc = q->queues[queue];
226 err = qdisc->enqueue(skb, qdisc); 224 err = qdisc->enqueue(skb, qdisc);
227 if (err == NET_XMIT_SUCCESS) { 225 if (err == NET_XMIT_SUCCESS) {
@@ -242,13 +240,11 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
242static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) 240static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd)
243{ 241{
244 struct ieee80211_sched_data *q = qdisc_priv(qd); 242 struct ieee80211_sched_data *q = qdisc_priv(qd);
245 struct ieee80211_tx_packet_data *pkt_data =
246 (struct ieee80211_tx_packet_data *) skb->cb;
247 struct Qdisc *qdisc; 243 struct Qdisc *qdisc;
248 int err; 244 int err;
249 245
250 /* we recorded which queue to use earlier! */ 246 /* we recorded which queue to use earlier! */
251 qdisc = q->queues[pkt_data->queue]; 247 qdisc = q->queues[skb_get_queue_mapping(skb)];
252 248
253 if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) { 249 if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) {
254 qd->q.qlen++; 250 qd->q.qlen++;
@@ -270,13 +266,10 @@ static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd)
270 int queue; 266 int queue;
271 267
272 /* check all the h/w queues in numeric/priority order */ 268 /* check all the h/w queues in numeric/priority order */
273 for (queue = 0; queue < hw->queues; queue++) { 269 for (queue = 0; queue < QD_NUM(hw); queue++) {
274 /* see if there is room in this hardware queue */ 270 /* see if there is room in this hardware queue */
275 if ((test_bit(IEEE80211_LINK_STATE_XOFF, 271 if (__netif_subqueue_stopped(local->mdev, queue) ||
276 &local->state[queue])) || 272 !test_bit(queue, q->qdisc_pool))
277 (test_bit(IEEE80211_LINK_STATE_PENDING,
278 &local->state[queue])) ||
279 (!test_bit(queue, q->qdisc_pool)))
280 continue; 273 continue;
281 274
282 /* there is space - try and get a frame */ 275 /* there is space - try and get a frame */
@@ -308,7 +301,7 @@ static void wme_qdiscop_reset(struct Qdisc* qd)
308 301
309 /* QUESTION: should we have some hardware flush functionality here? */ 302 /* QUESTION: should we have some hardware flush functionality here? */
310 303
311 for (queue = 0; queue < hw->queues; queue++) { 304 for (queue = 0; queue < QD_NUM(hw); queue++) {
312 skb_queue_purge(&q->requeued[queue]); 305 skb_queue_purge(&q->requeued[queue]);
313 qdisc_reset(q->queues[queue]); 306 qdisc_reset(q->queues[queue]);
314 } 307 }
@@ -326,7 +319,7 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
326 tcf_destroy_chain(q->filter_list); 319 tcf_destroy_chain(q->filter_list);
327 q->filter_list = NULL; 320 q->filter_list = NULL;
328 321
329 for (queue=0; queue < hw->queues; queue++) { 322 for (queue = 0; queue < QD_NUM(hw); queue++) {
330 skb_queue_purge(&q->requeued[queue]); 323 skb_queue_purge(&q->requeued[queue]);
331 qdisc_destroy(q->queues[queue]); 324 qdisc_destroy(q->queues[queue]);
332 q->queues[queue] = &noop_qdisc; 325 q->queues[queue] = &noop_qdisc;
@@ -337,17 +330,6 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
337/* called whenever parameters are updated on existing qdisc */ 330/* called whenever parameters are updated on existing qdisc */
338static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt) 331static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt)
339{ 332{
340/* struct ieee80211_sched_data *q = qdisc_priv(qd);
341*/
342 /* check our options block is the right size */
343 /* copy any options to our local structure */
344/* Ignore options block for now - always use static mapping
345 struct tc_ieee80211_qopt *qopt = nla_data(opt);
346
347 if (opt->nla_len < nla_attr_size(sizeof(*qopt)))
348 return -EINVAL;
349 memcpy(q->tag2queue, qopt->tag2queue, sizeof(qopt->tag2queue));
350*/
351 return 0; 333 return 0;
352} 334}
353 335
@@ -358,7 +340,7 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
358 struct ieee80211_sched_data *q = qdisc_priv(qd); 340 struct ieee80211_sched_data *q = qdisc_priv(qd);
359 struct net_device *dev = qd->dev; 341 struct net_device *dev = qd->dev;
360 struct ieee80211_local *local; 342 struct ieee80211_local *local;
361 int queues; 343 struct ieee80211_hw *hw;
362 int err = 0, i; 344 int err = 0, i;
363 345
364 /* check that device is a mac80211 device */ 346 /* check that device is a mac80211 device */
@@ -366,29 +348,26 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
366 dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) 348 dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
367 return -EINVAL; 349 return -EINVAL;
368 350
369 /* check this device is an ieee80211 master type device */ 351 local = wdev_priv(dev->ieee80211_ptr);
370 if (dev->type != ARPHRD_IEEE80211) 352 hw = &local->hw;
353
354 /* only allow on master dev */
355 if (dev != local->mdev)
371 return -EINVAL; 356 return -EINVAL;
372 357
373 /* check that there is no qdisc currently attached to device 358 /* ensure that we are root qdisc */
374 * this ensures that we will be the root qdisc. (I can't find a better 359 if (qd->parent != TC_H_ROOT)
375 * way to test this explicitly) */
376 if (dev->qdisc_sleeping != &noop_qdisc)
377 return -EINVAL; 360 return -EINVAL;
378 361
379 if (qd->flags & TCQ_F_INGRESS) 362 if (qd->flags & TCQ_F_INGRESS)
380 return -EINVAL; 363 return -EINVAL;
381 364
382 local = wdev_priv(dev->ieee80211_ptr);
383 queues = local->hw.queues;
384
385 /* if options were passed in, set them */ 365 /* if options were passed in, set them */
386 if (opt) { 366 if (opt)
387 err = wme_qdiscop_tune(qd, opt); 367 err = wme_qdiscop_tune(qd, opt);
388 }
389 368
390 /* create child queues */ 369 /* create child queues */
391 for (i = 0; i < queues; i++) { 370 for (i = 0; i < QD_NUM(hw); i++) {
392 skb_queue_head_init(&q->requeued[i]); 371 skb_queue_head_init(&q->requeued[i]);
393 q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops, 372 q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops,
394 qd->handle); 373 qd->handle);
@@ -399,8 +378,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
399 } 378 }
400 } 379 }
401 380
402 /* reserve all legacy QoS queues */ 381 /* non-aggregation queues: reserve/mark as used */
403 for (i = 0; i < min(IEEE80211_TX_QUEUE_DATA4, queues); i++) 382 for (i = 0; i < local->hw.queues; i++)
404 set_bit(i, q->qdisc_pool); 383 set_bit(i, q->qdisc_pool);
405 384
406 return err; 385 return err;
@@ -408,16 +387,6 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
408 387
409static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb) 388static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb)
410{ 389{
411/* struct ieee80211_sched_data *q = qdisc_priv(qd);
412 unsigned char *p = skb->tail;
413 struct tc_ieee80211_qopt opt;
414
415 memcpy(&opt.tag2queue, q->tag2queue, TC_80211_MAX_TAG + 1);
416 NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
417*/ return skb->len;
418/*
419nla_put_failure:
420 skb_trim(skb, p - skb->data);*/
421 return -1; 390 return -1;
422} 391}
423 392
@@ -430,7 +399,7 @@ static int wme_classop_graft(struct Qdisc *qd, unsigned long arg,
430 struct ieee80211_hw *hw = &local->hw; 399 struct ieee80211_hw *hw = &local->hw;
431 unsigned long queue = arg - 1; 400 unsigned long queue = arg - 1;
432 401
433 if (queue >= hw->queues) 402 if (queue >= QD_NUM(hw))
434 return -EINVAL; 403 return -EINVAL;
435 404
436 if (!new) 405 if (!new)
@@ -454,7 +423,7 @@ wme_classop_leaf(struct Qdisc *qd, unsigned long arg)
454 struct ieee80211_hw *hw = &local->hw; 423 struct ieee80211_hw *hw = &local->hw;
455 unsigned long queue = arg - 1; 424 unsigned long queue = arg - 1;
456 425
457 if (queue >= hw->queues) 426 if (queue >= QD_NUM(hw))
458 return NULL; 427 return NULL;
459 428
460 return q->queues[queue]; 429 return q->queues[queue];
@@ -467,7 +436,7 @@ static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid)
467 struct ieee80211_hw *hw = &local->hw; 436 struct ieee80211_hw *hw = &local->hw;
468 unsigned long queue = TC_H_MIN(classid); 437 unsigned long queue = TC_H_MIN(classid);
469 438
470 if (queue - 1 >= hw->queues) 439 if (queue - 1 >= QD_NUM(hw))
471 return 0; 440 return 0;
472 441
473 return queue; 442 return queue;
@@ -493,7 +462,7 @@ static int wme_classop_change(struct Qdisc *qd, u32 handle, u32 parent,
493 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); 462 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
494 struct ieee80211_hw *hw = &local->hw; 463 struct ieee80211_hw *hw = &local->hw;
495 464
496 if (cl - 1 > hw->queues) 465 if (cl - 1 > QD_NUM(hw))
497 return -ENOENT; 466 return -ENOENT;
498 467
499 /* TODO: put code to program hardware queue parameters here, 468 /* TODO: put code to program hardware queue parameters here,
@@ -510,7 +479,7 @@ static int wme_classop_delete(struct Qdisc *qd, unsigned long cl)
510 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); 479 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
511 struct ieee80211_hw *hw = &local->hw; 480 struct ieee80211_hw *hw = &local->hw;
512 481
513 if (cl - 1 > hw->queues) 482 if (cl - 1 > QD_NUM(hw))
514 return -ENOENT; 483 return -ENOENT;
515 return 0; 484 return 0;
516} 485}
@@ -523,7 +492,7 @@ static int wme_classop_dump_class(struct Qdisc *qd, unsigned long cl,
523 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); 492 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
524 struct ieee80211_hw *hw = &local->hw; 493 struct ieee80211_hw *hw = &local->hw;
525 494
526 if (cl - 1 > hw->queues) 495 if (cl - 1 > QD_NUM(hw))
527 return -ENOENT; 496 return -ENOENT;
528 tcm->tcm_handle = TC_H_MIN(cl); 497 tcm->tcm_handle = TC_H_MIN(cl);
529 tcm->tcm_parent = qd->handle; 498 tcm->tcm_parent = qd->handle;
@@ -541,7 +510,7 @@ static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg)
541 if (arg->stop) 510 if (arg->stop)
542 return; 511 return;
543 512
544 for (queue = 0; queue < hw->queues; queue++) { 513 for (queue = 0; queue < QD_NUM(hw); queue++) {
545 if (arg->count < arg->skip) { 514 if (arg->count < arg->skip) {
546 arg->count++; 515 arg->count++;
547 continue; 516 continue;
@@ -658,10 +627,13 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,
658 DECLARE_MAC_BUF(mac); 627 DECLARE_MAC_BUF(mac);
659 628
660 /* prepare the filter and save it for the SW queue 629 /* prepare the filter and save it for the SW queue
661 * matching the recieved HW queue */ 630 * matching the received HW queue */
631
632 if (!local->hw.ampdu_queues)
633 return -EPERM;
662 634
663 /* try to get a Qdisc from the pool */ 635 /* try to get a Qdisc from the pool */
664 for (i = IEEE80211_TX_QUEUE_BEACON; i < local->hw.queues; i++) 636 for (i = local->hw.queues; i < QD_NUM(&local->hw); i++)
665 if (!test_and_set_bit(i, q->qdisc_pool)) { 637 if (!test_and_set_bit(i, q->qdisc_pool)) {
666 ieee80211_stop_queue(local_to_hw(local), i); 638 ieee80211_stop_queue(local_to_hw(local), i);
667 sta->tid_to_tx_q[tid] = i; 639 sta->tid_to_tx_q[tid] = i;
@@ -690,13 +662,14 @@ void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local,
690 struct sta_info *sta, u16 tid, 662 struct sta_info *sta, u16 tid,
691 u8 requeue) 663 u8 requeue)
692{ 664{
665 struct ieee80211_hw *hw = &local->hw;
693 struct ieee80211_sched_data *q = 666 struct ieee80211_sched_data *q =
694 qdisc_priv(local->mdev->qdisc_sleeping); 667 qdisc_priv(local->mdev->qdisc_sleeping);
695 int agg_queue = sta->tid_to_tx_q[tid]; 668 int agg_queue = sta->tid_to_tx_q[tid];
696 669
697 /* return the qdisc to the pool */ 670 /* return the qdisc to the pool */
698 clear_bit(agg_queue, q->qdisc_pool); 671 clear_bit(agg_queue, q->qdisc_pool);
699 sta->tid_to_tx_q[tid] = local->hw.queues; 672 sta->tid_to_tx_q[tid] = QD_NUM(hw);
700 673
701 if (requeue) 674 if (requeue)
702 ieee80211_requeue(local, agg_queue); 675 ieee80211_requeue(local, agg_queue);
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index fcc6b05508cc..bbdb53344817 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -31,7 +31,7 @@ static inline int WLAN_FC_IS_QOS_DATA(u16 fc)
31 return (fc & 0x8C) == 0x88; 31 return (fc & 0x8C) == 0x88;
32} 32}
33 33
34#ifdef CONFIG_NET_SCHED 34#ifdef CONFIG_MAC80211_QOS
35void ieee80211_install_qdisc(struct net_device *dev); 35void ieee80211_install_qdisc(struct net_device *dev);
36int ieee80211_qdisc_installed(struct net_device *dev); 36int ieee80211_qdisc_installed(struct net_device *dev);
37int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, 37int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 45709ada8fee..9f6fd20374e1 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -79,6 +79,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
79 struct sk_buff *skb = tx->skb; 79 struct sk_buff *skb = tx->skb;
80 int authenticator; 80 int authenticator;
81 int wpa_test = 0; 81 int wpa_test = 0;
82 int tail;
82 83
83 fc = tx->fc; 84 fc = tx->fc;
84 85
@@ -98,16 +99,13 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
98 return TX_CONTINUE; 99 return TX_CONTINUE;
99 } 100 }
100 101
101 if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { 102 tail = MICHAEL_MIC_LEN;
102 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 103 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
103 if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, 104 tail += TKIP_ICV_LEN;
104 MICHAEL_MIC_LEN + TKIP_ICV_LEN, 105
105 GFP_ATOMIC))) { 106 if (WARN_ON(skb_tailroom(skb) < tail ||
106 printk(KERN_DEBUG "%s: failed to allocate more memory " 107 skb_headroom(skb) < TKIP_IV_LEN))
107 "for Michael MIC\n", tx->dev->name); 108 return TX_DROP;
108 return TX_DROP;
109 }
110 }
111 109
112#if 0 110#if 0
113 authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ 111 authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */
@@ -176,59 +174,65 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
176 skb_trim(skb, skb->len - MICHAEL_MIC_LEN); 174 skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
177 175
178 /* update IV in key information to be able to detect replays */ 176 /* update IV in key information to be able to detect replays */
179 rx->key->u.tkip.iv32_rx[rx->queue] = rx->tkip_iv32; 177 rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
180 rx->key->u.tkip.iv16_rx[rx->queue] = rx->tkip_iv16; 178 rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
181 179
182 return RX_CONTINUE; 180 return RX_CONTINUE;
183} 181}
184 182
185 183
186static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, 184static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
187 struct sk_buff *skb, int test)
188{ 185{
189 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 186 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
190 struct ieee80211_key *key = tx->key; 187 struct ieee80211_key *key = tx->key;
191 int hdrlen, len, tailneed; 188 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
189 int hdrlen, len, tail;
192 u16 fc; 190 u16 fc;
193 u8 *pos; 191 u8 *pos;
194 192
193 info->control.icv_len = TKIP_ICV_LEN;
194 info->control.iv_len = TKIP_IV_LEN;
195
196 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
197 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
198 /* hwaccel - with no need for preallocated room for IV/ICV */
199 info->control.hw_key = &tx->key->conf;
200 return 0;
201 }
202
195 fc = le16_to_cpu(hdr->frame_control); 203 fc = le16_to_cpu(hdr->frame_control);
196 hdrlen = ieee80211_get_hdrlen(fc); 204 hdrlen = ieee80211_get_hdrlen(fc);
197 len = skb->len - hdrlen; 205 len = skb->len - hdrlen;
198 206
199 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 207 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
200 tailneed = 0; 208 tail = 0;
201 else 209 else
202 tailneed = TKIP_ICV_LEN; 210 tail = TKIP_ICV_LEN;
203 211
204 if ((skb_headroom(skb) < TKIP_IV_LEN || 212 if (WARN_ON(skb_tailroom(skb) < tail ||
205 skb_tailroom(skb) < tailneed)) { 213 skb_headroom(skb) < TKIP_IV_LEN))
206 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 214 return -1;
207 if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, tailneed,
208 GFP_ATOMIC)))
209 return -1;
210 }
211 215
212 pos = skb_push(skb, TKIP_IV_LEN); 216 pos = skb_push(skb, TKIP_IV_LEN);
213 memmove(pos, pos + TKIP_IV_LEN, hdrlen); 217 memmove(pos, pos + TKIP_IV_LEN, hdrlen);
214 pos += hdrlen; 218 pos += hdrlen;
215 219
216 /* Increase IV for the frame */ 220 /* Increase IV for the frame */
217 key->u.tkip.iv16++; 221 key->u.tkip.tx.iv16++;
218 if (key->u.tkip.iv16 == 0) 222 if (key->u.tkip.tx.iv16 == 0)
219 key->u.tkip.iv32++; 223 key->u.tkip.tx.iv32++;
220 224
221 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 225 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
222 hdr = (struct ieee80211_hdr *)skb->data; 226 hdr = (struct ieee80211_hdr *)skb->data;
223 227
224 /* hwaccel - with preallocated room for IV */ 228 /* hwaccel - with preallocated room for IV */
225 ieee80211_tkip_add_iv(pos, key, 229 ieee80211_tkip_add_iv(pos, key,
226 (u8) (key->u.tkip.iv16 >> 8), 230 (u8) (key->u.tkip.tx.iv16 >> 8),
227 (u8) (((key->u.tkip.iv16 >> 8) | 0x20) & 231 (u8) (((key->u.tkip.tx.iv16 >> 8) | 0x20) &
228 0x7f), 232 0x7f),
229 (u8) key->u.tkip.iv16); 233 (u8) key->u.tkip.tx.iv16);
230 234
231 tx->control->key_idx = tx->key->conf.hw_key_idx; 235 info->control.hw_key = &tx->key->conf;
232 return 0; 236 return 0;
233 } 237 }
234 238
@@ -246,28 +250,16 @@ ieee80211_tx_result
246ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) 250ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
247{ 251{
248 struct sk_buff *skb = tx->skb; 252 struct sk_buff *skb = tx->skb;
249 int wpa_test = 0, test = 0;
250 253
251 tx->control->icv_len = TKIP_ICV_LEN;
252 tx->control->iv_len = TKIP_IV_LEN;
253 ieee80211_tx_set_protected(tx); 254 ieee80211_tx_set_protected(tx);
254 255
255 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 256 if (tkip_encrypt_skb(tx, skb) < 0)
256 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
257 !wpa_test) {
258 /* hwaccel - with no need for preallocated room for IV/ICV */
259 tx->control->key_idx = tx->key->conf.hw_key_idx;
260 return TX_CONTINUE;
261 }
262
263 if (tkip_encrypt_skb(tx, skb, test) < 0)
264 return TX_DROP; 257 return TX_DROP;
265 258
266 if (tx->extra_frag) { 259 if (tx->extra_frag) {
267 int i; 260 int i;
268 for (i = 0; i < tx->num_extra_frag; i++) { 261 for (i = 0; i < tx->num_extra_frag; i++) {
269 if (tkip_encrypt_skb(tx, tx->extra_frag[i], test) 262 if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0)
270 < 0)
271 return TX_DROP; 263 return TX_DROP;
272 } 264 }
273 } 265 }
@@ -429,16 +421,27 @@ static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr)
429} 421}
430 422
431 423
432static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, 424static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
433 struct sk_buff *skb, int test)
434{ 425{
435 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 426 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
436 struct ieee80211_key *key = tx->key; 427 struct ieee80211_key *key = tx->key;
437 int hdrlen, len, tailneed; 428 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
429 int hdrlen, len, tail;
438 u16 fc; 430 u16 fc;
439 u8 *pos, *pn, *b_0, *aad, *scratch; 431 u8 *pos, *pn, *b_0, *aad, *scratch;
440 int i; 432 int i;
441 433
434 info->control.icv_len = CCMP_MIC_LEN;
435 info->control.iv_len = CCMP_HDR_LEN;
436
437 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
438 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
439 /* hwaccel - with no need for preallocated room for CCMP "
440 * header or MIC fields */
441 info->control.hw_key = &tx->key->conf;
442 return 0;
443 }
444
442 scratch = key->u.ccmp.tx_crypto_buf; 445 scratch = key->u.ccmp.tx_crypto_buf;
443 b_0 = scratch + 3 * AES_BLOCK_LEN; 446 b_0 = scratch + 3 * AES_BLOCK_LEN;
444 aad = scratch + 4 * AES_BLOCK_LEN; 447 aad = scratch + 4 * AES_BLOCK_LEN;
@@ -448,17 +451,13 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx,
448 len = skb->len - hdrlen; 451 len = skb->len - hdrlen;
449 452
450 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 453 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
451 tailneed = 0; 454 tail = 0;
452 else 455 else
453 tailneed = CCMP_MIC_LEN; 456 tail = CCMP_MIC_LEN;
454 457
455 if ((skb_headroom(skb) < CCMP_HDR_LEN || 458 if (WARN_ON(skb_tailroom(skb) < tail ||
456 skb_tailroom(skb) < tailneed)) { 459 skb_headroom(skb) < CCMP_HDR_LEN))
457 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 460 return -1;
458 if (unlikely(pskb_expand_head(skb, CCMP_HDR_LEN, tailneed,
459 GFP_ATOMIC)))
460 return -1;
461 }
462 461
463 pos = skb_push(skb, CCMP_HDR_LEN); 462 pos = skb_push(skb, CCMP_HDR_LEN);
464 memmove(pos, pos + CCMP_HDR_LEN, hdrlen); 463 memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
@@ -478,7 +477,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx,
478 477
479 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 478 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
480 /* hwaccel - with preallocated room for CCMP header */ 479 /* hwaccel - with preallocated room for CCMP header */
481 tx->control->key_idx = key->conf.hw_key_idx; 480 info->control.hw_key = &tx->key->conf;
482 return 0; 481 return 0;
483 } 482 }
484 483
@@ -495,28 +494,16 @@ ieee80211_tx_result
495ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) 494ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
496{ 495{
497 struct sk_buff *skb = tx->skb; 496 struct sk_buff *skb = tx->skb;
498 int test = 0;
499 497
500 tx->control->icv_len = CCMP_MIC_LEN;
501 tx->control->iv_len = CCMP_HDR_LEN;
502 ieee80211_tx_set_protected(tx); 498 ieee80211_tx_set_protected(tx);
503 499
504 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 500 if (ccmp_encrypt_skb(tx, skb) < 0)
505 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
506 /* hwaccel - with no need for preallocated room for CCMP "
507 * header or MIC fields */
508 tx->control->key_idx = tx->key->conf.hw_key_idx;
509 return TX_CONTINUE;
510 }
511
512 if (ccmp_encrypt_skb(tx, skb, test) < 0)
513 return TX_DROP; 501 return TX_DROP;
514 502
515 if (tx->extra_frag) { 503 if (tx->extra_frag) {
516 int i; 504 int i;
517 for (i = 0; i < tx->num_extra_frag; i++) { 505 for (i = 0; i < tx->num_extra_frag; i++) {
518 if (ccmp_encrypt_skb(tx, tx->extra_frag[i], test) 506 if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0)
519 < 0)
520 return TX_DROP; 507 return TX_DROP;
521 } 508 }
522 } 509 }
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 662c1ccfee26..f27c99246a4c 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -847,6 +847,25 @@ acct:
847} 847}
848EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); 848EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
849 849
850void __nf_ct_kill_acct(struct nf_conn *ct,
851 enum ip_conntrack_info ctinfo,
852 const struct sk_buff *skb,
853 int do_acct)
854{
855#ifdef CONFIG_NF_CT_ACCT
856 if (do_acct) {
857 spin_lock_bh(&nf_conntrack_lock);
858 ct->counters[CTINFO2DIR(ctinfo)].packets++;
859 ct->counters[CTINFO2DIR(ctinfo)].bytes +=
860 skb->len - skb_network_offset(skb);
861 spin_unlock_bh(&nf_conntrack_lock);
862 }
863#endif
864 if (del_timer(&ct->timeout))
865 ct->timeout.function((unsigned long)ct);
866}
867EXPORT_SYMBOL_GPL(__nf_ct_kill_acct);
868
850#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 869#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
851 870
852#include <linux/netfilter/nfnetlink.h> 871#include <linux/netfilter/nfnetlink.h>
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
index bcc19fa4ed1e..ba1c4915e9eb 100644
--- a/net/netfilter/nf_conntrack_extend.c
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -88,13 +88,11 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
88 newlen = newoff + t->len; 88 newlen = newoff + t->len;
89 rcu_read_unlock(); 89 rcu_read_unlock();
90 90
91 if (newlen >= ksize(ct->ext)) { 91 new = krealloc(ct->ext, newlen, gfp);
92 new = kmalloc(newlen, gfp); 92 if (!new)
93 if (!new) 93 return NULL;
94 return NULL;
95
96 memcpy(new, ct->ext, ct->ext->len);
97 94
95 if (new != ct->ext) {
98 for (i = 0; i < NF_CT_EXT_NUM; i++) { 96 for (i = 0; i < NF_CT_EXT_NUM; i++) {
99 if (!nf_ct_ext_exist(ct, i)) 97 if (!nf_ct_ext_exist(ct, i))
100 continue; 98 continue;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 0edefcfc5949..63c4e1f299b8 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -4,7 +4,7 @@
4 * (C) 2001 by Jay Schulist <jschlst@samba.org> 4 * (C) 2001 by Jay Schulist <jschlst@samba.org>
5 * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org> 5 * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
6 * (C) 2003 by Patrick Mchardy <kaber@trash.net> 6 * (C) 2003 by Patrick Mchardy <kaber@trash.net>
7 * (C) 2005-2007 by Pablo Neira Ayuso <pablo@netfilter.org> 7 * (C) 2005-2008 by Pablo Neira Ayuso <pablo@netfilter.org>
8 * 8 *
9 * Initial connection tracking via netlink development funded and 9 * Initial connection tracking via netlink development funded and
10 * generally made possible by Network Robots, Inc. (www.networkrobots.com) 10 * generally made possible by Network Robots, Inc. (www.networkrobots.com)
@@ -475,14 +475,14 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
475 if (ctnetlink_dump_id(skb, ct) < 0) 475 if (ctnetlink_dump_id(skb, ct) < 0)
476 goto nla_put_failure; 476 goto nla_put_failure;
477 477
478 if (ctnetlink_dump_status(skb, ct) < 0)
479 goto nla_put_failure;
480
478 if (events & IPCT_DESTROY) { 481 if (events & IPCT_DESTROY) {
479 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || 482 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
480 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0) 483 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
481 goto nla_put_failure; 484 goto nla_put_failure;
482 } else { 485 } else {
483 if (ctnetlink_dump_status(skb, ct) < 0)
484 goto nla_put_failure;
485
486 if (ctnetlink_dump_timeout(skb, ct) < 0) 486 if (ctnetlink_dump_timeout(skb, ct) < 0)
487 goto nla_put_failure; 487 goto nla_put_failure;
488 488
@@ -812,9 +812,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
812 return -ENOENT; 812 return -ENOENT;
813 } 813 }
814 } 814 }
815 if (del_timer(&ct->timeout))
816 ct->timeout.function((unsigned long)ct);
817 815
816 nf_ct_kill(ct);
818 nf_ct_put(ct); 817 nf_ct_put(ct);
819 818
820 return 0; 819 return 0;
@@ -891,20 +890,19 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
891 890
892 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING)) 891 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
893 /* unchangeable */ 892 /* unchangeable */
894 return -EINVAL; 893 return -EBUSY;
895 894
896 if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY)) 895 if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
897 /* SEEN_REPLY bit can only be set */ 896 /* SEEN_REPLY bit can only be set */
898 return -EINVAL; 897 return -EBUSY;
899
900 898
901 if (d & IPS_ASSURED && !(status & IPS_ASSURED)) 899 if (d & IPS_ASSURED && !(status & IPS_ASSURED))
902 /* ASSURED bit can only be set */ 900 /* ASSURED bit can only be set */
903 return -EINVAL; 901 return -EBUSY;
904 902
905 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { 903 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
906#ifndef CONFIG_NF_NAT_NEEDED 904#ifndef CONFIG_NF_NAT_NEEDED
907 return -EINVAL; 905 return -EOPNOTSUPP;
908#else 906#else
909 struct nf_nat_range range; 907 struct nf_nat_range range;
910 908
@@ -945,7 +943,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
945 943
946 /* don't change helper of sibling connections */ 944 /* don't change helper of sibling connections */
947 if (ct->master) 945 if (ct->master)
948 return -EINVAL; 946 return -EBUSY;
949 947
950 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); 948 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
951 if (err < 0) 949 if (err < 0)
@@ -963,7 +961,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
963 961
964 helper = __nf_conntrack_helper_find_byname(helpname); 962 helper = __nf_conntrack_helper_find_byname(helpname);
965 if (helper == NULL) 963 if (helper == NULL)
966 return -EINVAL; 964 return -EOPNOTSUPP;
967 965
968 if (help) { 966 if (help) {
969 if (help->helper == helper) 967 if (help->helper == helper)
@@ -1258,12 +1256,12 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1258 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) { 1256 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
1259 /* we only allow nat config for new conntracks */ 1257 /* we only allow nat config for new conntracks */
1260 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { 1258 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
1261 err = -EINVAL; 1259 err = -EOPNOTSUPP;
1262 goto out_unlock; 1260 goto out_unlock;
1263 } 1261 }
1264 /* can't link an existing conntrack to a master */ 1262 /* can't link an existing conntrack to a master */
1265 if (cda[CTA_TUPLE_MASTER]) { 1263 if (cda[CTA_TUPLE_MASTER]) {
1266 err = -EINVAL; 1264 err = -EOPNOTSUPP;
1267 goto out_unlock; 1265 goto out_unlock;
1268 } 1266 }
1269 err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), 1267 err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h),
@@ -1608,7 +1606,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1608 h = __nf_conntrack_helper_find_byname(name); 1606 h = __nf_conntrack_helper_find_byname(name);
1609 if (!h) { 1607 if (!h) {
1610 spin_unlock_bh(&nf_conntrack_lock); 1608 spin_unlock_bh(&nf_conntrack_lock);
1611 return -EINVAL; 1609 return -EOPNOTSUPP;
1612 } 1610 }
1613 for (i = 0; i < nf_ct_expect_hsize; i++) { 1611 for (i = 0; i < nf_ct_expect_hsize; i++) {
1614 hlist_for_each_entry_safe(exp, n, next, 1612 hlist_for_each_entry_safe(exp, n, next,
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index afb4a1861d2c..e7866dd3cde6 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -475,8 +475,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
475 if (type == DCCP_PKT_RESET && 475 if (type == DCCP_PKT_RESET &&
476 !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 476 !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
477 /* Tear down connection immediately if only reply is a RESET */ 477 /* Tear down connection immediately if only reply is a RESET */
478 if (del_timer(&ct->timeout)) 478 nf_ct_kill_acct(ct, ctinfo, skb);
479 ct->timeout.function((unsigned long)ct);
480 return NF_ACCEPT; 479 return NF_ACCEPT;
481 } 480 }
482 481
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index cbf2e27a22b2..41183a4d2d62 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -463,6 +463,82 @@ static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
463 return true; 463 return true;
464} 464}
465 465
466#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
467
468#include <linux/netfilter/nfnetlink.h>
469#include <linux/netfilter/nfnetlink_conntrack.h>
470
471static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
472 const struct nf_conn *ct)
473{
474 struct nlattr *nest_parms;
475
476 read_lock_bh(&sctp_lock);
477 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP | NLA_F_NESTED);
478 if (!nest_parms)
479 goto nla_put_failure;
480
481 NLA_PUT_U8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state);
482
483 NLA_PUT_BE32(skb,
484 CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
485 htonl(ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]));
486
487 NLA_PUT_BE32(skb,
488 CTA_PROTOINFO_SCTP_VTAG_REPLY,
489 htonl(ct->proto.sctp.vtag[IP_CT_DIR_REPLY]));
490
491 read_unlock_bh(&sctp_lock);
492
493 nla_nest_end(skb, nest_parms);
494
495 return 0;
496
497nla_put_failure:
498 read_unlock_bh(&sctp_lock);
499 return -1;
500}
501
502static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = {
503 [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 },
504 [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 },
505 [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 },
506};
507
508static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
509{
510 struct nlattr *attr = cda[CTA_PROTOINFO_SCTP];
511 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1];
512 int err;
513
514 /* updates may not contain the internal protocol info, skip parsing */
515 if (!attr)
516 return 0;
517
518 err = nla_parse_nested(tb,
519 CTA_PROTOINFO_SCTP_MAX,
520 attr,
521 sctp_nla_policy);
522 if (err < 0)
523 return err;
524
525 if (!tb[CTA_PROTOINFO_SCTP_STATE] ||
526 !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] ||
527 !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
528 return -EINVAL;
529
530 write_lock_bh(&sctp_lock);
531 ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
532 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
533 ntohl(nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]));
534 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
535 ntohl(nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]));
536 write_unlock_bh(&sctp_lock);
537
538 return 0;
539}
540#endif
541
466#ifdef CONFIG_SYSCTL 542#ifdef CONFIG_SYSCTL
467static unsigned int sctp_sysctl_table_users; 543static unsigned int sctp_sysctl_table_users;
468static struct ctl_table_header *sctp_sysctl_header; 544static struct ctl_table_header *sctp_sysctl_header;
@@ -591,6 +667,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
591 .new = sctp_new, 667 .new = sctp_new,
592 .me = THIS_MODULE, 668 .me = THIS_MODULE,
593#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 669#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
670 .to_nlattr = sctp_to_nlattr,
671 .from_nlattr = nlattr_to_sctp,
594 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 672 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
595 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 673 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
596 .nla_policy = nf_ct_port_nla_policy, 674 .nla_policy = nf_ct_port_nla_policy,
@@ -617,6 +695,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
617 .new = sctp_new, 695 .new = sctp_new,
618 .me = THIS_MODULE, 696 .me = THIS_MODULE,
619#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 697#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
698 .to_nlattr = sctp_to_nlattr,
699 .from_nlattr = nlattr_to_sctp,
620 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 700 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
621 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 701 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
622 .nla_policy = nf_ct_port_nla_policy, 702 .nla_policy = nf_ct_port_nla_policy,
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index ba94004fe323..8db13fba10bc 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -843,8 +843,7 @@ static int tcp_packet(struct nf_conn *ct,
843 /* Attempt to reopen a closed/aborted connection. 843 /* Attempt to reopen a closed/aborted connection.
844 * Delete this connection and look up again. */ 844 * Delete this connection and look up again. */
845 write_unlock_bh(&tcp_lock); 845 write_unlock_bh(&tcp_lock);
846 if (del_timer(&ct->timeout)) 846 nf_ct_kill(ct);
847 ct->timeout.function((unsigned long)ct);
848 return -NF_REPEAT; 847 return -NF_REPEAT;
849 } 848 }
850 /* Fall through */ 849 /* Fall through */
@@ -877,8 +876,7 @@ static int tcp_packet(struct nf_conn *ct,
877 if (LOG_INVALID(IPPROTO_TCP)) 876 if (LOG_INVALID(IPPROTO_TCP))
878 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 877 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
879 "nf_ct_tcp: killing out of sync session "); 878 "nf_ct_tcp: killing out of sync session ");
880 if (del_timer(&ct->timeout)) 879 nf_ct_kill(ct);
881 ct->timeout.function((unsigned long)ct);
882 return -NF_DROP; 880 return -NF_DROP;
883 } 881 }
884 ct->proto.tcp.last_index = index; 882 ct->proto.tcp.last_index = index;
@@ -961,8 +959,7 @@ static int tcp_packet(struct nf_conn *ct,
961 problem case, so we can delete the conntrack 959 problem case, so we can delete the conntrack
962 immediately. --RR */ 960 immediately. --RR */
963 if (th->rst) { 961 if (th->rst) {
964 if (del_timer(&ct->timeout)) 962 nf_ct_kill_acct(ct, ctinfo, skb);
965 ct->timeout.function((unsigned long)ct);
966 return NF_ACCEPT; 963 return NF_ACCEPT;
967 } 964 }
968 } else if (!test_bit(IPS_ASSURED_BIT, &ct->status) 965 } else if (!test_bit(IPS_ASSURED_BIT, &ct->status)
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 3447025ce068..04e9c965f8ca 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -243,7 +243,6 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
243 switch ((enum nfqnl_config_mode)queue->copy_mode) { 243 switch ((enum nfqnl_config_mode)queue->copy_mode) {
244 case NFQNL_COPY_META: 244 case NFQNL_COPY_META:
245 case NFQNL_COPY_NONE: 245 case NFQNL_COPY_NONE:
246 data_len = 0;
247 break; 246 break;
248 247
249 case NFQNL_COPY_PACKET: 248 case NFQNL_COPY_PACKET:
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 211189eb2b67..76ca1f2421eb 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -8,7 +8,7 @@
8 * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 8 * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
9 * by Henrik Nordstrom <hno@marasystems.com> 9 * by Henrik Nordstrom <hno@marasystems.com>
10 * 10 *
11 * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com> 11 * (C) 2006,2008 Red Hat, Inc., James Morris <jmorris@redhat.com>
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
@@ -94,6 +94,12 @@ connsecmark_tg_check(const char *tablename, const void *entry,
94{ 94{
95 const struct xt_connsecmark_target_info *info = targinfo; 95 const struct xt_connsecmark_target_info *info = targinfo;
96 96
97 if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) {
98 printk(KERN_INFO PFX "target only valid in the \'mangle\' "
99 "or \'security\' tables, not \'%s\'.\n", tablename);
100 return false;
101 }
102
97 switch (info->mode) { 103 switch (info->mode) {
98 case CONNSECMARK_SAVE: 104 case CONNSECMARK_SAVE:
99 case CONNSECMARK_RESTORE: 105 case CONNSECMARK_RESTORE:
@@ -126,7 +132,6 @@ static struct xt_target connsecmark_tg_reg[] __read_mostly = {
126 .destroy = connsecmark_tg_destroy, 132 .destroy = connsecmark_tg_destroy,
127 .target = connsecmark_tg, 133 .target = connsecmark_tg,
128 .targetsize = sizeof(struct xt_connsecmark_target_info), 134 .targetsize = sizeof(struct xt_connsecmark_target_info),
129 .table = "mangle",
130 .me = THIS_MODULE, 135 .me = THIS_MODULE,
131 }, 136 },
132 { 137 {
@@ -136,7 +141,6 @@ static struct xt_target connsecmark_tg_reg[] __read_mostly = {
136 .destroy = connsecmark_tg_destroy, 141 .destroy = connsecmark_tg_destroy,
137 .target = connsecmark_tg, 142 .target = connsecmark_tg,
138 .targetsize = sizeof(struct xt_connsecmark_target_info), 143 .targetsize = sizeof(struct xt_connsecmark_target_info),
139 .table = "mangle",
140 .me = THIS_MODULE, 144 .me = THIS_MODULE,
141 }, 145 },
142}; 146};
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index c0284856ccd4..94f87ee7552b 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -5,7 +5,7 @@
5 * Based on the nfmark match by: 5 * Based on the nfmark match by:
6 * (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 6 * (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
7 * 7 *
8 * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com> 8 * (C) 2006,2008 Red Hat, Inc., James Morris <jmorris@redhat.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -89,6 +89,12 @@ secmark_tg_check(const char *tablename, const void *entry,
89{ 89{
90 struct xt_secmark_target_info *info = targinfo; 90 struct xt_secmark_target_info *info = targinfo;
91 91
92 if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) {
93 printk(KERN_INFO PFX "target only valid in the \'mangle\' "
94 "or \'security\' tables, not \'%s\'.\n", tablename);
95 return false;
96 }
97
92 if (mode && mode != info->mode) { 98 if (mode && mode != info->mode) {
93 printk(KERN_INFO PFX "mode already set to %hu cannot mix with " 99 printk(KERN_INFO PFX "mode already set to %hu cannot mix with "
94 "rules for mode %hu\n", mode, info->mode); 100 "rules for mode %hu\n", mode, info->mode);
@@ -127,7 +133,6 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
127 .destroy = secmark_tg_destroy, 133 .destroy = secmark_tg_destroy,
128 .target = secmark_tg, 134 .target = secmark_tg,
129 .targetsize = sizeof(struct xt_secmark_target_info), 135 .targetsize = sizeof(struct xt_secmark_target_info),
130 .table = "mangle",
131 .me = THIS_MODULE, 136 .me = THIS_MODULE,
132 }, 137 },
133 { 138 {
@@ -137,7 +142,6 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
137 .destroy = secmark_tg_destroy, 142 .destroy = secmark_tg_destroy,
138 .target = secmark_tg, 143 .target = secmark_tg,
139 .targetsize = sizeof(struct xt_secmark_target_info), 144 .targetsize = sizeof(struct xt_secmark_target_info),
140 .table = "mangle",
141 .me = THIS_MODULE, 145 .me = THIS_MODULE,
142 }, 146 },
143}; 147};
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 9b97f8006c9c..6507c02dbe0d 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -759,7 +759,7 @@ struct sock *netlink_getsockbyfilp(struct file *filp)
759 * 0: continue 759 * 0: continue
760 * 1: repeat lookup - reference dropped while waiting for socket memory. 760 * 1: repeat lookup - reference dropped while waiting for socket memory.
761 */ 761 */
762int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, 762int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
763 long *timeo, struct sock *ssk) 763 long *timeo, struct sock *ssk)
764{ 764{
765 struct netlink_sock *nlk; 765 struct netlink_sock *nlk;
@@ -892,7 +892,7 @@ retry:
892 return err; 892 return err;
893 } 893 }
894 894
895 err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk); 895 err = netlink_attachskb(sk, skb, &timeo, ssk);
896 if (err == 1) 896 if (err == 1)
897 goto retry; 897 goto retry;
898 if (err) 898 if (err)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2cee87da4441..beca6402f1cf 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * PACKET - implements raw packet sockets. 6 * PACKET - implements raw packet sockets.
7 * 7 *
8 * Version: $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Alan Cox, <gw4pts@gw4pts.ampr.org> 10 * Alan Cox, <gw4pts@gw4pts.ampr.org>
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 5bc1ed490180..213071859030 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -24,8 +24,6 @@
24 * Jiri Fojtasek 24 * Jiri Fojtasek
25 * fixed requeue routine 25 * fixed requeue routine
26 * and many others. thanks. 26 * and many others. thanks.
27 *
28 * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $
29 */ 27 */
30#include <linux/module.h> 28#include <linux/module.h>
31#include <linux/types.h> 29#include <linux/types.h>
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 532634861db1..d5cc731b6798 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -136,6 +136,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
136 136
137 /* Set association default SACK delay */ 137 /* Set association default SACK delay */
138 asoc->sackdelay = msecs_to_jiffies(sp->sackdelay); 138 asoc->sackdelay = msecs_to_jiffies(sp->sackdelay);
139 asoc->sackfreq = sp->sackfreq;
139 140
140 /* Set the association default flags controlling 141 /* Set the association default flags controlling
141 * Heartbeat, SACK delay, and Path MTU Discovery. 142 * Heartbeat, SACK delay, and Path MTU Discovery.
@@ -261,6 +262,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
261 * already received one packet.] 262 * already received one packet.]
262 */ 263 */
263 asoc->peer.sack_needed = 1; 264 asoc->peer.sack_needed = 1;
265 asoc->peer.sack_cnt = 0;
264 266
265 /* Assume that the peer will tell us if he recognizes ASCONF 267 /* Assume that the peer will tell us if he recognizes ASCONF
266 * as part of INIT exchange. 268 * as part of INIT exchange.
@@ -615,6 +617,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
615 * association configured value. 617 * association configured value.
616 */ 618 */
617 peer->sackdelay = asoc->sackdelay; 619 peer->sackdelay = asoc->sackdelay;
620 peer->sackfreq = asoc->sackfreq;
618 621
619 /* Enable/disable heartbeat, SACK delay, and path MTU discovery 622 /* Enable/disable heartbeat, SACK delay, and path MTU discovery
620 * based on association setting. 623 * based on association setting.
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 0aba759cb9b7..5dd89831eceb 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -383,3 +383,144 @@ void sctp_assocs_proc_exit(void)
383{ 383{
384 remove_proc_entry("assocs", proc_net_sctp); 384 remove_proc_entry("assocs", proc_net_sctp);
385} 385}
386
387static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos)
388{
389 if (*pos >= sctp_assoc_hashsize)
390 return NULL;
391
392 if (*pos < 0)
393 *pos = 0;
394
395 if (*pos == 0)
396 seq_printf(seq, "ADDR ASSOC_ID HB_ACT RTO MAX_PATH_RTX "
397 "REM_ADDR_RTX START\n");
398
399 return (void *)pos;
400}
401
402static void *sctp_remaddr_seq_next(struct seq_file *seq, void *v, loff_t *pos)
403{
404 if (++*pos >= sctp_assoc_hashsize)
405 return NULL;
406
407 return pos;
408}
409
410static void sctp_remaddr_seq_stop(struct seq_file *seq, void *v)
411{
412 return;
413}
414
415static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
416{
417 struct sctp_hashbucket *head;
418 struct sctp_ep_common *epb;
419 struct sctp_association *assoc;
420 struct hlist_node *node;
421 struct sctp_transport *tsp;
422 int hash = *(loff_t *)v;
423
424 if (hash >= sctp_assoc_hashsize)
425 return -ENOMEM;
426
427 head = &sctp_assoc_hashtable[hash];
428 sctp_local_bh_disable();
429 read_lock(&head->lock);
430 sctp_for_each_hentry(epb, node, &head->chain) {
431 assoc = sctp_assoc(epb);
432 list_for_each_entry(tsp, &assoc->peer.transport_addr_list,
433 transports) {
434 /*
435 * The remote address (ADDR)
436 */
437 tsp->af_specific->seq_dump_addr(seq, &tsp->ipaddr);
438 seq_printf(seq, " ");
439
440 /*
441 * The association ID (ASSOC_ID)
442 */
443 seq_printf(seq, "%d ", tsp->asoc->assoc_id);
444
445 /*
446 * If the Heartbeat is active (HB_ACT)
447 * Note: 1 = Active, 0 = Inactive
448 */
449 seq_printf(seq, "%d ", timer_pending(&tsp->hb_timer));
450
451 /*
452 * Retransmit time out (RTO)
453 */
454 seq_printf(seq, "%lu ", tsp->rto);
455
456 /*
457 * Maximum path retransmit count (PATH_MAX_RTX)
458 */
459 seq_printf(seq, "%d ", tsp->pathmaxrxt);
460
461 /*
462 * remote address retransmit count (REM_ADDR_RTX)
463 * Note: We don't have a way to tally this at the moment
464 * so lets just leave it as zero for the moment
465 */
466 seq_printf(seq, "0 ");
467
468 /*
469 * remote address start time (START). This is also not
470 * currently implemented, but we can record it with a
471 * jiffies marker in a subsequent patch
472 */
473 seq_printf(seq, "0");
474
475 seq_printf(seq, "\n");
476 }
477 }
478
479 read_unlock(&head->lock);
480 sctp_local_bh_enable();
481
482 return 0;
483
484}
485
486static const struct seq_operations sctp_remaddr_ops = {
487 .start = sctp_remaddr_seq_start,
488 .next = sctp_remaddr_seq_next,
489 .stop = sctp_remaddr_seq_stop,
490 .show = sctp_remaddr_seq_show,
491};
492
493/* Cleanup the proc fs entry for 'remaddr' object. */
494void sctp_remaddr_proc_exit(void)
495{
496 remove_proc_entry("remaddr", proc_net_sctp);
497}
498
499static int sctp_remaddr_seq_open(struct inode *inode, struct file *file)
500{
501 return seq_open(file, &sctp_remaddr_ops);
502}
503
504static const struct file_operations sctp_remaddr_seq_fops = {
505 .open = sctp_remaddr_seq_open,
506 .read = seq_read,
507 .llseek = seq_lseek,
508 .release = seq_release,
509};
510
511int __init sctp_remaddr_proc_init(void)
512{
513 struct proc_dir_entry *p;
514
515 p = create_proc_entry("remaddr", S_IRUGO, proc_net_sctp);
516 if (!p)
517 return -ENOMEM;
518 p->proc_fops = &sctp_remaddr_seq_fops;
519
520 return 0;
521}
522
523void sctp_assoc_proc_exit(void)
524{
525 remove_proc_entry("remaddr", proc_net_sctp);
526}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index b435a193c5df..d6af466091d2 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -113,6 +113,8 @@ static __init int sctp_proc_init(void)
113 goto out_nomem; 113 goto out_nomem;
114 if (sctp_assocs_proc_init()) 114 if (sctp_assocs_proc_init())
115 goto out_nomem; 115 goto out_nomem;
116 if (sctp_remaddr_proc_init())
117 goto out_nomem;
116 118
117 return 0; 119 return 0;
118 120
@@ -129,6 +131,7 @@ static void sctp_proc_exit(void)
129 sctp_snmp_proc_exit(); 131 sctp_snmp_proc_exit();
130 sctp_eps_proc_exit(); 132 sctp_eps_proc_exit();
131 sctp_assocs_proc_exit(); 133 sctp_assocs_proc_exit();
134 sctp_remaddr_proc_exit();
132 135
133 if (proc_net_sctp) { 136 if (proc_net_sctp) {
134 proc_net_sctp = NULL; 137 proc_net_sctp = NULL;
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 23a9f1a95b7d..b083312c725a 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -190,20 +190,28 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
190 * unacknowledged DATA chunk. ... 190 * unacknowledged DATA chunk. ...
191 */ 191 */
192 if (!asoc->peer.sack_needed) { 192 if (!asoc->peer.sack_needed) {
193 /* We will need a SACK for the next packet. */ 193 asoc->peer.sack_cnt++;
194 asoc->peer.sack_needed = 1;
195 194
196 /* Set the SACK delay timeout based on the 195 /* Set the SACK delay timeout based on the
197 * SACK delay for the last transport 196 * SACK delay for the last transport
198 * data was received from, or the default 197 * data was received from, or the default
199 * for the association. 198 * for the association.
200 */ 199 */
201 if (trans) 200 if (trans) {
201 /* We will need a SACK for the next packet. */
202 if (asoc->peer.sack_cnt >= trans->sackfreq - 1)
203 asoc->peer.sack_needed = 1;
204
202 asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 205 asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
203 trans->sackdelay; 206 trans->sackdelay;
204 else 207 } else {
208 /* We will need a SACK for the next packet. */
209 if (asoc->peer.sack_cnt >= asoc->sackfreq - 1)
210 asoc->peer.sack_needed = 1;
211
205 asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 212 asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
206 asoc->sackdelay; 213 asoc->sackdelay;
214 }
207 215
208 /* Restart the SACK timer. */ 216 /* Restart the SACK timer. */
209 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, 217 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
@@ -216,6 +224,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
216 goto nomem; 224 goto nomem;
217 225
218 asoc->peer.sack_needed = 0; 226 asoc->peer.sack_needed = 0;
227 asoc->peer.sack_cnt = 0;
219 228
220 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(sack)); 229 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(sack));
221 230
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e7e3baf7009e..253e5ea7e1e8 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -956,7 +956,8 @@ out:
956 */ 956 */
957static int __sctp_connect(struct sock* sk, 957static int __sctp_connect(struct sock* sk,
958 struct sockaddr *kaddrs, 958 struct sockaddr *kaddrs,
959 int addrs_size) 959 int addrs_size,
960 sctp_assoc_t *assoc_id)
960{ 961{
961 struct sctp_sock *sp; 962 struct sctp_sock *sp;
962 struct sctp_endpoint *ep; 963 struct sctp_endpoint *ep;
@@ -1111,6 +1112,8 @@ static int __sctp_connect(struct sock* sk,
1111 timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK); 1112 timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK);
1112 1113
1113 err = sctp_wait_for_connect(asoc, &timeo); 1114 err = sctp_wait_for_connect(asoc, &timeo);
1115 if (!err && assoc_id)
1116 *assoc_id = asoc->assoc_id;
1114 1117
1115 /* Don't free association on exit. */ 1118 /* Don't free association on exit. */
1116 asoc = NULL; 1119 asoc = NULL;
@@ -1128,7 +1131,8 @@ out_free:
1128/* Helper for tunneling sctp_connectx() requests through sctp_setsockopt() 1131/* Helper for tunneling sctp_connectx() requests through sctp_setsockopt()
1129 * 1132 *
1130 * API 8.9 1133 * API 8.9
1131 * int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt); 1134 * int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt,
1135 * sctp_assoc_t *asoc);
1132 * 1136 *
1133 * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses. 1137 * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
1134 * If the sd is an IPv6 socket, the addresses passed can either be IPv4 1138 * If the sd is an IPv6 socket, the addresses passed can either be IPv4
@@ -1144,8 +1148,10 @@ out_free:
1144 * representation is termed a "packed array" of addresses). The caller 1148 * representation is termed a "packed array" of addresses). The caller
1145 * specifies the number of addresses in the array with addrcnt. 1149 * specifies the number of addresses in the array with addrcnt.
1146 * 1150 *
1147 * On success, sctp_connectx() returns 0. On failure, sctp_connectx() returns 1151 * On success, sctp_connectx() returns 0. It also sets the assoc_id to
1148 * -1, and sets errno to the appropriate error code. 1152 * the association id of the new association. On failure, sctp_connectx()
1153 * returns -1, and sets errno to the appropriate error code. The assoc_id
1154 * is not touched by the kernel.
1149 * 1155 *
1150 * For SCTP, the port given in each socket address must be the same, or 1156 * For SCTP, the port given in each socket address must be the same, or
1151 * sctp_connectx() will fail, setting errno to EINVAL. 1157 * sctp_connectx() will fail, setting errno to EINVAL.
@@ -1182,11 +1188,12 @@ out_free:
1182 * addrs The pointer to the addresses in user land 1188 * addrs The pointer to the addresses in user land
1183 * addrssize Size of the addrs buffer 1189 * addrssize Size of the addrs buffer
1184 * 1190 *
1185 * Returns 0 if ok, <0 errno code on error. 1191 * Returns >=0 if ok, <0 errno code on error.
1186 */ 1192 */
1187SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, 1193SCTP_STATIC int __sctp_setsockopt_connectx(struct sock* sk,
1188 struct sockaddr __user *addrs, 1194 struct sockaddr __user *addrs,
1189 int addrs_size) 1195 int addrs_size,
1196 sctp_assoc_t *assoc_id)
1190{ 1197{
1191 int err = 0; 1198 int err = 0;
1192 struct sockaddr *kaddrs; 1199 struct sockaddr *kaddrs;
@@ -1209,13 +1216,46 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
1209 if (__copy_from_user(kaddrs, addrs, addrs_size)) { 1216 if (__copy_from_user(kaddrs, addrs, addrs_size)) {
1210 err = -EFAULT; 1217 err = -EFAULT;
1211 } else { 1218 } else {
1212 err = __sctp_connect(sk, kaddrs, addrs_size); 1219 err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id);
1213 } 1220 }
1214 1221
1215 kfree(kaddrs); 1222 kfree(kaddrs);
1223
1216 return err; 1224 return err;
1217} 1225}
1218 1226
1227/*
1228 * This is an older interface. It's kept for backward compatibility
1229 * to the option that doesn't provide association id.
1230 */
1231SCTP_STATIC int sctp_setsockopt_connectx_old(struct sock* sk,
1232 struct sockaddr __user *addrs,
1233 int addrs_size)
1234{
1235 return __sctp_setsockopt_connectx(sk, addrs, addrs_size, NULL);
1236}
1237
1238/*
1239 * New interface for the API. The since the API is done with a socket
1240 * option, to make it simple we feed back the association id is as a return
1241 * indication to the call. Error is always negative and association id is
1242 * always positive.
1243 */
1244SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
1245 struct sockaddr __user *addrs,
1246 int addrs_size)
1247{
1248 sctp_assoc_t assoc_id = 0;
1249 int err = 0;
1250
1251 err = __sctp_setsockopt_connectx(sk, addrs, addrs_size, &assoc_id);
1252
1253 if (err)
1254 return err;
1255 else
1256 return assoc_id;
1257}
1258
1219/* API 3.1.4 close() - UDP Style Syntax 1259/* API 3.1.4 close() - UDP Style Syntax
1220 * Applications use close() to perform graceful shutdown (as described in 1260 * Applications use close() to perform graceful shutdown (as described in
1221 * Section 10.1 of [SCTP]) on ALL the associations currently represented 1261 * Section 10.1 of [SCTP]) on ALL the associations currently represented
@@ -2305,74 +2345,98 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
2305 return 0; 2345 return 0;
2306} 2346}
2307 2347
2308/* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) 2348/*
2309 * 2349 * 7.1.23. Get or set delayed ack timer (SCTP_DELAYED_SACK)
2310 * This options will get or set the delayed ack timer. The time is set 2350 *
2311 * in milliseconds. If the assoc_id is 0, then this sets or gets the 2351 * This option will effect the way delayed acks are performed. This
2312 * endpoints default delayed ack timer value. If the assoc_id field is 2352 * option allows you to get or set the delayed ack time, in
2313 * non-zero, then the set or get effects the specified association. 2353 * milliseconds. It also allows changing the delayed ack frequency.
2314 * 2354 * Changing the frequency to 1 disables the delayed sack algorithm. If
2315 * struct sctp_assoc_value { 2355 * the assoc_id is 0, then this sets or gets the endpoints default
2316 * sctp_assoc_t assoc_id; 2356 * values. If the assoc_id field is non-zero, then the set or get
2317 * uint32_t assoc_value; 2357 * effects the specified association for the one to many model (the
2318 * }; 2358 * assoc_id field is ignored by the one to one model). Note that if
2359 * sack_delay or sack_freq are 0 when setting this option, then the
2360 * current values will remain unchanged.
2361 *
2362 * struct sctp_sack_info {
2363 * sctp_assoc_t sack_assoc_id;
2364 * uint32_t sack_delay;
2365 * uint32_t sack_freq;
2366 * };
2319 * 2367 *
2320 * assoc_id - This parameter, indicates which association the 2368 * sack_assoc_id - This parameter, indicates which association the user
2321 * user is preforming an action upon. Note that if 2369 * is performing an action upon. Note that if this field's value is
2322 * this field's value is zero then the endpoints 2370 * zero then the endpoints default value is changed (effecting future
2323 * default value is changed (effecting future 2371 * associations only).
2324 * associations only).
2325 * 2372 *
2326 * assoc_value - This parameter contains the number of milliseconds 2373 * sack_delay - This parameter contains the number of milliseconds that
2327 * that the user is requesting the delayed ACK timer 2374 * the user is requesting the delayed ACK timer be set to. Note that
2328 * be set to. Note that this value is defined in 2375 * this value is defined in the standard to be between 200 and 500
2329 * the standard to be between 200 and 500 milliseconds. 2376 * milliseconds.
2330 * 2377 *
2331 * Note: a value of zero will leave the value alone, 2378 * sack_freq - This parameter contains the number of packets that must
2332 * but disable SACK delay. A non-zero value will also 2379 * be received before a sack is sent without waiting for the delay
2333 * enable SACK delay. 2380 * timer to expire. The default value for this is 2, setting this
2381 * value to 1 will disable the delayed sack algorithm.
2334 */ 2382 */
2335 2383
2336static int sctp_setsockopt_delayed_ack_time(struct sock *sk, 2384static int sctp_setsockopt_delayed_ack(struct sock *sk,
2337 char __user *optval, int optlen) 2385 char __user *optval, int optlen)
2338{ 2386{
2339 struct sctp_assoc_value params; 2387 struct sctp_sack_info params;
2340 struct sctp_transport *trans = NULL; 2388 struct sctp_transport *trans = NULL;
2341 struct sctp_association *asoc = NULL; 2389 struct sctp_association *asoc = NULL;
2342 struct sctp_sock *sp = sctp_sk(sk); 2390 struct sctp_sock *sp = sctp_sk(sk);
2343 2391
2344 if (optlen != sizeof(struct sctp_assoc_value)) 2392 if (optlen == sizeof(struct sctp_sack_info)) {
2345 return - EINVAL; 2393 if (copy_from_user(&params, optval, optlen))
2394 return -EFAULT;
2346 2395
2347 if (copy_from_user(&params, optval, optlen)) 2396 if (params.sack_delay == 0 && params.sack_freq == 0)
2348 return -EFAULT; 2397 return 0;
2398 } else if (optlen == sizeof(struct sctp_assoc_value)) {
2399 printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info "
2400 "in delayed_ack socket option deprecated\n");
2401 printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n");
2402 if (copy_from_user(&params, optval, optlen))
2403 return -EFAULT;
2404
2405 if (params.sack_delay == 0)
2406 params.sack_freq = 1;
2407 else
2408 params.sack_freq = 0;
2409 } else
2410 return - EINVAL;
2349 2411
2350 /* Validate value parameter. */ 2412 /* Validate value parameter. */
2351 if (params.assoc_value > 500) 2413 if (params.sack_delay > 500)
2352 return -EINVAL; 2414 return -EINVAL;
2353 2415
2354 /* Get association, if assoc_id != 0 and the socket is a one 2416 /* Get association, if sack_assoc_id != 0 and the socket is a one
2355 * to many style socket, and an association was not found, then 2417 * to many style socket, and an association was not found, then
2356 * the id was invalid. 2418 * the id was invalid.
2357 */ 2419 */
2358 asoc = sctp_id2assoc(sk, params.assoc_id); 2420 asoc = sctp_id2assoc(sk, params.sack_assoc_id);
2359 if (!asoc && params.assoc_id && sctp_style(sk, UDP)) 2421 if (!asoc && params.sack_assoc_id && sctp_style(sk, UDP))
2360 return -EINVAL; 2422 return -EINVAL;
2361 2423
2362 if (params.assoc_value) { 2424 if (params.sack_delay) {
2363 if (asoc) { 2425 if (asoc) {
2364 asoc->sackdelay = 2426 asoc->sackdelay =
2365 msecs_to_jiffies(params.assoc_value); 2427 msecs_to_jiffies(params.sack_delay);
2366 asoc->param_flags = 2428 asoc->param_flags =
2367 (asoc->param_flags & ~SPP_SACKDELAY) | 2429 (asoc->param_flags & ~SPP_SACKDELAY) |
2368 SPP_SACKDELAY_ENABLE; 2430 SPP_SACKDELAY_ENABLE;
2369 } else { 2431 } else {
2370 sp->sackdelay = params.assoc_value; 2432 sp->sackdelay = params.sack_delay;
2371 sp->param_flags = 2433 sp->param_flags =
2372 (sp->param_flags & ~SPP_SACKDELAY) | 2434 (sp->param_flags & ~SPP_SACKDELAY) |
2373 SPP_SACKDELAY_ENABLE; 2435 SPP_SACKDELAY_ENABLE;
2374 } 2436 }
2375 } else { 2437 }
2438
2439 if (params.sack_freq == 1) {
2376 if (asoc) { 2440 if (asoc) {
2377 asoc->param_flags = 2441 asoc->param_flags =
2378 (asoc->param_flags & ~SPP_SACKDELAY) | 2442 (asoc->param_flags & ~SPP_SACKDELAY) |
@@ -2382,22 +2446,40 @@ static int sctp_setsockopt_delayed_ack_time(struct sock *sk,
2382 (sp->param_flags & ~SPP_SACKDELAY) | 2446 (sp->param_flags & ~SPP_SACKDELAY) |
2383 SPP_SACKDELAY_DISABLE; 2447 SPP_SACKDELAY_DISABLE;
2384 } 2448 }
2449 } else if (params.sack_freq > 1) {
2450 if (asoc) {
2451 asoc->sackfreq = params.sack_freq;
2452 asoc->param_flags =
2453 (asoc->param_flags & ~SPP_SACKDELAY) |
2454 SPP_SACKDELAY_ENABLE;
2455 } else {
2456 sp->sackfreq = params.sack_freq;
2457 sp->param_flags =
2458 (sp->param_flags & ~SPP_SACKDELAY) |
2459 SPP_SACKDELAY_ENABLE;
2460 }
2385 } 2461 }
2386 2462
2387 /* If change is for association, also apply to each transport. */ 2463 /* If change is for association, also apply to each transport. */
2388 if (asoc) { 2464 if (asoc) {
2389 list_for_each_entry(trans, &asoc->peer.transport_addr_list, 2465 list_for_each_entry(trans, &asoc->peer.transport_addr_list,
2390 transports) { 2466 transports) {
2391 if (params.assoc_value) { 2467 if (params.sack_delay) {
2392 trans->sackdelay = 2468 trans->sackdelay =
2393 msecs_to_jiffies(params.assoc_value); 2469 msecs_to_jiffies(params.sack_delay);
2394 trans->param_flags = 2470 trans->param_flags =
2395 (trans->param_flags & ~SPP_SACKDELAY) | 2471 (trans->param_flags & ~SPP_SACKDELAY) |
2396 SPP_SACKDELAY_ENABLE; 2472 SPP_SACKDELAY_ENABLE;
2397 } else { 2473 }
2474 if (params.sack_freq == 1) {
2398 trans->param_flags = 2475 trans->param_flags =
2399 (trans->param_flags & ~SPP_SACKDELAY) | 2476 (trans->param_flags & ~SPP_SACKDELAY) |
2400 SPP_SACKDELAY_DISABLE; 2477 SPP_SACKDELAY_DISABLE;
2478 } else if (params.sack_freq > 1) {
2479 trans->sackfreq = params.sack_freq;
2480 trans->param_flags =
2481 (trans->param_flags & ~SPP_SACKDELAY) |
2482 SPP_SACKDELAY_ENABLE;
2401 } 2483 }
2402 } 2484 }
2403 } 2485 }
@@ -3164,10 +3246,18 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
3164 optlen, SCTP_BINDX_REM_ADDR); 3246 optlen, SCTP_BINDX_REM_ADDR);
3165 break; 3247 break;
3166 3248
3249 case SCTP_SOCKOPT_CONNECTX_OLD:
3250 /* 'optlen' is the size of the addresses buffer. */
3251 retval = sctp_setsockopt_connectx_old(sk,
3252 (struct sockaddr __user *)optval,
3253 optlen);
3254 break;
3255
3167 case SCTP_SOCKOPT_CONNECTX: 3256 case SCTP_SOCKOPT_CONNECTX:
3168 /* 'optlen' is the size of the addresses buffer. */ 3257 /* 'optlen' is the size of the addresses buffer. */
3169 retval = sctp_setsockopt_connectx(sk, (struct sockaddr __user *)optval, 3258 retval = sctp_setsockopt_connectx(sk,
3170 optlen); 3259 (struct sockaddr __user *)optval,
3260 optlen);
3171 break; 3261 break;
3172 3262
3173 case SCTP_DISABLE_FRAGMENTS: 3263 case SCTP_DISABLE_FRAGMENTS:
@@ -3186,8 +3276,8 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
3186 retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); 3276 retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
3187 break; 3277 break;
3188 3278
3189 case SCTP_DELAYED_ACK_TIME: 3279 case SCTP_DELAYED_ACK:
3190 retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); 3280 retval = sctp_setsockopt_delayed_ack(sk, optval, optlen);
3191 break; 3281 break;
3192 case SCTP_PARTIAL_DELIVERY_POINT: 3282 case SCTP_PARTIAL_DELIVERY_POINT:
3193 retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen); 3283 retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen);
@@ -3294,7 +3384,7 @@ SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *addr,
3294 /* Pass correct addr len to common routine (so it knows there 3384 /* Pass correct addr len to common routine (so it knows there
3295 * is only one address being passed. 3385 * is only one address being passed.
3296 */ 3386 */
3297 err = __sctp_connect(sk, addr, af->sockaddr_len); 3387 err = __sctp_connect(sk, addr, af->sockaddr_len, NULL);
3298 } 3388 }
3299 3389
3300 sctp_release_sock(sk); 3390 sctp_release_sock(sk);
@@ -3446,6 +3536,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3446 sp->pathmaxrxt = sctp_max_retrans_path; 3536 sp->pathmaxrxt = sctp_max_retrans_path;
3447 sp->pathmtu = 0; // allow default discovery 3537 sp->pathmtu = 0; // allow default discovery
3448 sp->sackdelay = sctp_sack_timeout; 3538 sp->sackdelay = sctp_sack_timeout;
3539 sp->sackfreq = 2;
3449 sp->param_flags = SPP_HB_ENABLE | 3540 sp->param_flags = SPP_HB_ENABLE |
3450 SPP_PMTUD_ENABLE | 3541 SPP_PMTUD_ENABLE |
3451 SPP_SACKDELAY_ENABLE; 3542 SPP_SACKDELAY_ENABLE;
@@ -3999,70 +4090,91 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
3999 return 0; 4090 return 0;
4000} 4091}
4001 4092
4002/* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) 4093/*
4003 * 4094 * 7.1.23. Get or set delayed ack timer (SCTP_DELAYED_SACK)
4004 * This options will get or set the delayed ack timer. The time is set 4095 *
4005 * in milliseconds. If the assoc_id is 0, then this sets or gets the 4096 * This option will effect the way delayed acks are performed. This
4006 * endpoints default delayed ack timer value. If the assoc_id field is 4097 * option allows you to get or set the delayed ack time, in
4007 * non-zero, then the set or get effects the specified association. 4098 * milliseconds. It also allows changing the delayed ack frequency.
4008 * 4099 * Changing the frequency to 1 disables the delayed sack algorithm. If
4009 * struct sctp_assoc_value { 4100 * the assoc_id is 0, then this sets or gets the endpoints default
4010 * sctp_assoc_t assoc_id; 4101 * values. If the assoc_id field is non-zero, then the set or get
4011 * uint32_t assoc_value; 4102 * effects the specified association for the one to many model (the
4012 * }; 4103 * assoc_id field is ignored by the one to one model). Note that if
4104 * sack_delay or sack_freq are 0 when setting this option, then the
4105 * current values will remain unchanged.
4106 *
4107 * struct sctp_sack_info {
4108 * sctp_assoc_t sack_assoc_id;
4109 * uint32_t sack_delay;
4110 * uint32_t sack_freq;
4111 * };
4013 * 4112 *
4014 * assoc_id - This parameter, indicates which association the 4113 * sack_assoc_id - This parameter, indicates which association the user
4015 * user is preforming an action upon. Note that if 4114 * is performing an action upon. Note that if this field's value is
4016 * this field's value is zero then the endpoints 4115 * zero then the endpoints default value is changed (effecting future
4017 * default value is changed (effecting future 4116 * associations only).
4018 * associations only).
4019 * 4117 *
4020 * assoc_value - This parameter contains the number of milliseconds 4118 * sack_delay - This parameter contains the number of milliseconds that
4021 * that the user is requesting the delayed ACK timer 4119 * the user is requesting the delayed ACK timer be set to. Note that
4022 * be set to. Note that this value is defined in 4120 * this value is defined in the standard to be between 200 and 500
4023 * the standard to be between 200 and 500 milliseconds. 4121 * milliseconds.
4024 * 4122 *
4025 * Note: a value of zero will leave the value alone, 4123 * sack_freq - This parameter contains the number of packets that must
4026 * but disable SACK delay. A non-zero value will also 4124 * be received before a sack is sent without waiting for the delay
4027 * enable SACK delay. 4125 * timer to expire. The default value for this is 2, setting this
4126 * value to 1 will disable the delayed sack algorithm.
4028 */ 4127 */
4029static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, 4128static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
4030 char __user *optval, 4129 char __user *optval,
4031 int __user *optlen) 4130 int __user *optlen)
4032{ 4131{
4033 struct sctp_assoc_value params; 4132 struct sctp_sack_info params;
4034 struct sctp_association *asoc = NULL; 4133 struct sctp_association *asoc = NULL;
4035 struct sctp_sock *sp = sctp_sk(sk); 4134 struct sctp_sock *sp = sctp_sk(sk);
4036 4135
4037 if (len < sizeof(struct sctp_assoc_value)) 4136 if (len >= sizeof(struct sctp_sack_info)) {
4038 return - EINVAL; 4137 len = sizeof(struct sctp_sack_info);
4039
4040 len = sizeof(struct sctp_assoc_value);
4041 4138
4042 if (copy_from_user(&params, optval, len)) 4139 if (copy_from_user(&params, optval, len))
4043 return -EFAULT; 4140 return -EFAULT;
4141 } else if (len == sizeof(struct sctp_assoc_value)) {
4142 printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info "
4143 "in delayed_ack socket option deprecated\n");
4144 printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n");
4145 if (copy_from_user(&params, optval, len))
4146 return -EFAULT;
4147 } else
4148 return - EINVAL;
4044 4149
4045 /* Get association, if assoc_id != 0 and the socket is a one 4150 /* Get association, if sack_assoc_id != 0 and the socket is a one
4046 * to many style socket, and an association was not found, then 4151 * to many style socket, and an association was not found, then
4047 * the id was invalid. 4152 * the id was invalid.
4048 */ 4153 */
4049 asoc = sctp_id2assoc(sk, params.assoc_id); 4154 asoc = sctp_id2assoc(sk, params.sack_assoc_id);
4050 if (!asoc && params.assoc_id && sctp_style(sk, UDP)) 4155 if (!asoc && params.sack_assoc_id && sctp_style(sk, UDP))
4051 return -EINVAL; 4156 return -EINVAL;
4052 4157
4053 if (asoc) { 4158 if (asoc) {
4054 /* Fetch association values. */ 4159 /* Fetch association values. */
4055 if (asoc->param_flags & SPP_SACKDELAY_ENABLE) 4160 if (asoc->param_flags & SPP_SACKDELAY_ENABLE) {
4056 params.assoc_value = jiffies_to_msecs( 4161 params.sack_delay = jiffies_to_msecs(
4057 asoc->sackdelay); 4162 asoc->sackdelay);
4058 else 4163 params.sack_freq = asoc->sackfreq;
4059 params.assoc_value = 0; 4164
4165 } else {
4166 params.sack_delay = 0;
4167 params.sack_freq = 1;
4168 }
4060 } else { 4169 } else {
4061 /* Fetch socket values. */ 4170 /* Fetch socket values. */
4062 if (sp->param_flags & SPP_SACKDELAY_ENABLE) 4171 if (sp->param_flags & SPP_SACKDELAY_ENABLE) {
4063 params.assoc_value = sp->sackdelay; 4172 params.sack_delay = sp->sackdelay;
4064 else 4173 params.sack_freq = sp->sackfreq;
4065 params.assoc_value = 0; 4174 } else {
4175 params.sack_delay = 0;
4176 params.sack_freq = 1;
4177 }
4066 } 4178 }
4067 4179
4068 if (copy_to_user(optval, &params, len)) 4180 if (copy_to_user(optval, &params, len))
@@ -5218,8 +5330,8 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5218 retval = sctp_getsockopt_peer_addr_params(sk, len, optval, 5330 retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
5219 optlen); 5331 optlen);
5220 break; 5332 break;
5221 case SCTP_DELAYED_ACK_TIME: 5333 case SCTP_DELAYED_ACK:
5222 retval = sctp_getsockopt_delayed_ack_time(sk, len, optval, 5334 retval = sctp_getsockopt_delayed_ack(sk, len, optval,
5223 optlen); 5335 optlen);
5224 break; 5336 break;
5225 case SCTP_INITMSG: 5337 case SCTP_INITMSG:
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index cc12d5f5d5da..019d4b4478c9 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -33,8 +33,6 @@
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 */ 36 */
39 37
40 38
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index b4f0525f91af..007c1a6708ee 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -4,7 +4,6 @@
4 * Begun April 1, 1996, Mike Shaver. 4 * Begun April 1, 1996, Mike Shaver.
5 * Added /proc/sys/net directories for each protocol family. [MS] 5 * Added /proc/sys/net directories for each protocol family. [MS]
6 * 6 *
7 * $Log: sysctl_net.c,v $
8 * Revision 1.2 1996/05/08 20:24:40 shaver 7 * Revision 1.2 1996/05/08 20:24:40 shaver
9 * Added bits for NET_BRIDGE and the NET_IPV4_ARP stuff and 8 * Added bits for NET_BRIDGE and the NET_IPV4_ARP stuff and
10 * NET_IPV4_IP_FORWARD. 9 * NET_IPV4_IP_FORWARD.
@@ -40,6 +39,27 @@ static struct ctl_table_root net_sysctl_root = {
40 .lookup = net_ctl_header_lookup, 39 .lookup = net_ctl_header_lookup,
41}; 40};
42 41
42static LIST_HEAD(net_sysctl_ro_tables);
43static struct list_head *net_ctl_ro_header_lookup(struct ctl_table_root *root,
44 struct nsproxy *namespaces)
45{
46 return &net_sysctl_ro_tables;
47}
48
49static int net_ctl_ro_header_perms(struct ctl_table_root *root,
50 struct nsproxy *namespaces, struct ctl_table *table)
51{
52 if (namespaces->net_ns == &init_net)
53 return table->mode;
54 else
55 return table->mode & ~0222;
56}
57
58static struct ctl_table_root net_sysctl_ro_root = {
59 .lookup = net_ctl_ro_header_lookup,
60 .permissions = net_ctl_ro_header_perms,
61};
62
43static int sysctl_net_init(struct net *net) 63static int sysctl_net_init(struct net *net)
44{ 64{
45 INIT_LIST_HEAD(&net->sysctl_table_headers); 65 INIT_LIST_HEAD(&net->sysctl_table_headers);
@@ -64,6 +84,7 @@ static __init int sysctl_init(void)
64 if (ret) 84 if (ret)
65 goto out; 85 goto out;
66 register_sysctl_root(&net_sysctl_root); 86 register_sysctl_root(&net_sysctl_root);
87 register_sysctl_root(&net_sysctl_ro_root);
67out: 88out:
68 return ret; 89 return ret;
69} 90}
@@ -80,6 +101,14 @@ struct ctl_table_header *register_net_sysctl_table(struct net *net,
80} 101}
81EXPORT_SYMBOL_GPL(register_net_sysctl_table); 102EXPORT_SYMBOL_GPL(register_net_sysctl_table);
82 103
104struct ctl_table_header *register_net_sysctl_rotable(const
105 struct ctl_path *path, struct ctl_table *table)
106{
107 return __register_sysctl_paths(&net_sysctl_ro_root,
108 &init_nsproxy, path, table);
109}
110EXPORT_SYMBOL_GPL(register_net_sysctl_rotable);
111
83void unregister_net_sysctl_table(struct ctl_table_header *header) 112void unregister_net_sysctl_table(struct ctl_table_header *header)
84{ 113{
85 unregister_sysctl_table(header); 114 unregister_sysctl_table(header);
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index e7880172ef19..a5883b1452ff 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -276,7 +276,7 @@ static void bclink_send_nack(struct node *n_ptr)
276 if (buf) { 276 if (buf) {
277 msg = buf_msg(buf); 277 msg = buf_msg(buf);
278 msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 278 msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
279 TIPC_OK, INT_H_SIZE, n_ptr->addr); 279 INT_H_SIZE, n_ptr->addr);
280 msg_set_mc_netid(msg, tipc_net_id); 280 msg_set_mc_netid(msg, tipc_net_id);
281 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 281 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
282 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); 282 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after);
@@ -571,7 +571,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
571 assert(tipc_cltr_bcast_nodes.count != 0); 571 assert(tipc_cltr_bcast_nodes.count != 0);
572 bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); 572 bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count);
573 msg = buf_msg(buf); 573 msg = buf_msg(buf);
574 msg_set_non_seq(msg); 574 msg_set_non_seq(msg, 1);
575 msg_set_mc_netid(msg, tipc_net_id); 575 msg_set_mc_netid(msg, tipc_net_id);
576 } 576 }
577 577
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
index 4bb3404f610b..bc1db474fe01 100644
--- a/net/tipc/cluster.c
+++ b/net/tipc/cluster.c
@@ -238,7 +238,7 @@ static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
238 if (buf) { 238 if (buf) {
239 msg = buf_msg(buf); 239 msg = buf_msg(buf);
240 memset((char *)msg, 0, size); 240 memset((char *)msg, 0, size);
241 msg_init(msg, ROUTE_DISTRIBUTOR, 0, TIPC_OK, INT_H_SIZE, dest); 241 msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest);
242 } 242 }
243 return buf; 243 return buf;
244} 244}
diff --git a/net/tipc/config.c b/net/tipc/config.c
index c71337a22d33..ca3544d030c7 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -2,7 +2,7 @@
2 * net/tipc/config.c: TIPC configuration management code 2 * net/tipc/config.c: TIPC configuration management code
3 * 3 *
4 * Copyright (c) 2002-2006, Ericsson AB 4 * Copyright (c) 2002-2006, Ericsson AB
5 * Copyright (c) 2004-2006, Wind River Systems 5 * Copyright (c) 2004-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -293,7 +293,6 @@ static struct sk_buff *cfg_set_own_addr(void)
293 if (tipc_mode == TIPC_NET_MODE) 293 if (tipc_mode == TIPC_NET_MODE)
294 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 294 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
295 " (cannot change node address once assigned)"); 295 " (cannot change node address once assigned)");
296 tipc_own_addr = addr;
297 296
298 /* 297 /*
299 * Must release all spinlocks before calling start_net() because 298 * Must release all spinlocks before calling start_net() because
@@ -306,7 +305,7 @@ static struct sk_buff *cfg_set_own_addr(void)
306 */ 305 */
307 306
308 spin_unlock_bh(&config_lock); 307 spin_unlock_bh(&config_lock);
309 tipc_core_start_net(); 308 tipc_core_start_net(addr);
310 spin_lock_bh(&config_lock); 309 spin_lock_bh(&config_lock);
311 return tipc_cfg_reply_none(); 310 return tipc_cfg_reply_none();
312} 311}
@@ -529,7 +528,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
529 break; 528 break;
530#endif 529#endif
531 case TIPC_CMD_SET_LOG_SIZE: 530 case TIPC_CMD_SET_LOG_SIZE:
532 rep_tlv_buf = tipc_log_resize(req_tlv_area, req_tlv_space); 531 rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space);
533 break; 532 break;
534 case TIPC_CMD_DUMP_LOG: 533 case TIPC_CMD_DUMP_LOG:
535 rep_tlv_buf = tipc_log_dump(); 534 rep_tlv_buf = tipc_log_dump();
@@ -602,6 +601,10 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
602 case TIPC_CMD_GET_NETID: 601 case TIPC_CMD_GET_NETID:
603 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 602 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
604 break; 603 break;
604 case TIPC_CMD_NOT_NET_ADMIN:
605 rep_tlv_buf =
606 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
607 break;
605 default: 608 default:
606 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 609 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
607 " (unknown command)"); 610 " (unknown command)");
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 740aac5cdfb6..3256bd7d398f 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -49,7 +49,7 @@
49#include "config.h" 49#include "config.h"
50 50
51 51
52#define TIPC_MOD_VER "1.6.3" 52#define TIPC_MOD_VER "1.6.4"
53 53
54#ifndef CONFIG_TIPC_ZONES 54#ifndef CONFIG_TIPC_ZONES
55#define CONFIG_TIPC_ZONES 3 55#define CONFIG_TIPC_ZONES 3
@@ -117,11 +117,11 @@ void tipc_core_stop_net(void)
117 * start_net - start TIPC networking sub-systems 117 * start_net - start TIPC networking sub-systems
118 */ 118 */
119 119
120int tipc_core_start_net(void) 120int tipc_core_start_net(unsigned long addr)
121{ 121{
122 int res; 122 int res;
123 123
124 if ((res = tipc_net_start()) || 124 if ((res = tipc_net_start(addr)) ||
125 (res = tipc_eth_media_start())) { 125 (res = tipc_eth_media_start())) {
126 tipc_core_stop_net(); 126 tipc_core_stop_net();
127 } 127 }
@@ -164,8 +164,7 @@ int tipc_core_start(void)
164 tipc_mode = TIPC_NODE_MODE; 164 tipc_mode = TIPC_NODE_MODE;
165 165
166 if ((res = tipc_handler_start()) || 166 if ((res = tipc_handler_start()) ||
167 (res = tipc_ref_table_init(tipc_max_ports + tipc_max_subscriptions, 167 (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) ||
168 tipc_random)) ||
169 (res = tipc_reg_start()) || 168 (res = tipc_reg_start()) ||
170 (res = tipc_nametbl_init()) || 169 (res = tipc_nametbl_init()) ||
171 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || 170 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) ||
@@ -182,7 +181,7 @@ static int __init tipc_init(void)
182{ 181{
183 int res; 182 int res;
184 183
185 tipc_log_reinit(CONFIG_TIPC_LOG); 184 tipc_log_resize(CONFIG_TIPC_LOG);
186 info("Activated (version " TIPC_MOD_VER 185 info("Activated (version " TIPC_MOD_VER
187 " compiled " __DATE__ " " __TIME__ ")\n"); 186 " compiled " __DATE__ " " __TIME__ ")\n");
188 187
@@ -209,7 +208,7 @@ static void __exit tipc_exit(void)
209 tipc_core_stop_net(); 208 tipc_core_stop_net();
210 tipc_core_stop(); 209 tipc_core_stop();
211 info("Deactivated\n"); 210 info("Deactivated\n");
212 tipc_log_stop(); 211 tipc_log_resize(0);
213} 212}
214 213
215module_init(tipc_init); 214module_init(tipc_init);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 5a0e4878d3b7..a881f92a8537 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -2,7 +2,7 @@
2 * net/tipc/core.h: Include file for TIPC global declarations 2 * net/tipc/core.h: Include file for TIPC global declarations
3 * 3 *
4 * Copyright (c) 2005-2006, Ericsson AB 4 * Copyright (c) 2005-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -59,84 +59,108 @@
59#include <linux/vmalloc.h> 59#include <linux/vmalloc.h>
60 60
61/* 61/*
62 * TIPC debugging code 62 * TIPC sanity test macros
63 */ 63 */
64 64
65#define assert(i) BUG_ON(!(i)) 65#define assert(i) BUG_ON(!(i))
66 66
67struct tipc_msg;
68extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG;
69extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *);
70void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*);
71void tipc_printf(struct print_buf *, const char *fmt, ...);
72void tipc_dump(struct print_buf*,const char *fmt, ...);
73
74#ifdef CONFIG_TIPC_DEBUG
75
76/* 67/*
77 * TIPC debug support included: 68 * TIPC system monitoring code
78 * - system messages are printed to TIPC_OUTPUT print buffer
79 * - debug messages are printed to DBG_OUTPUT print buffer
80 */ 69 */
81 70
82#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_ERR "TIPC: " fmt, ## arg) 71/*
83#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) 72 * TIPC's print buffer subsystem supports the following print buffers:
84#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) 73 *
74 * TIPC_NULL : null buffer (i.e. print nowhere)
75 * TIPC_CONS : system console
76 * TIPC_LOG : TIPC log buffer
77 * &buf : user-defined buffer (struct print_buf *)
78 *
79 * Note: TIPC_LOG is configured to echo its output to the system console;
80 * user-defined buffers can be configured to do the same thing.
81 */
85 82
86#define dbg(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) 83extern struct print_buf *const TIPC_NULL;
87#define msg_dbg(msg, txt) do {if (DBG_OUTPUT != TIPC_NULL) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) 84extern struct print_buf *const TIPC_CONS;
88#define dump(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) 85extern struct print_buf *const TIPC_LOG;
89 86
87void tipc_printf(struct print_buf *, const char *fmt, ...);
90 88
91/* 89/*
92 * By default, TIPC_OUTPUT is defined to be system console and TIPC log buffer, 90 * TIPC_OUTPUT is the destination print buffer for system messages.
93 * while DBG_OUTPUT is the null print buffer. These defaults can be changed
94 * here, or on a per .c file basis, by redefining these symbols. The following
95 * print buffer options are available:
96 *
97 * TIPC_NULL : null buffer (i.e. print nowhere)
98 * TIPC_CONS : system console
99 * TIPC_LOG : TIPC log buffer
100 * &buf : user-defined buffer (struct print_buf *)
101 * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG))
102 */ 91 */
103 92
104#ifndef TIPC_OUTPUT 93#ifndef TIPC_OUTPUT
105#define TIPC_OUTPUT TIPC_TEE(TIPC_CONS,TIPC_LOG) 94#define TIPC_OUTPUT TIPC_LOG
106#endif
107
108#ifndef DBG_OUTPUT
109#define DBG_OUTPUT TIPC_NULL
110#endif 95#endif
111 96
112#else
113
114/* 97/*
115 * TIPC debug support not included: 98 * TIPC can be configured to send system messages to TIPC_OUTPUT
116 * - system messages are printed to system console 99 * or to the system console only.
117 * - debug messages are not printed
118 */ 100 */
119 101
102#ifdef CONFIG_TIPC_DEBUG
103
104#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
105 KERN_ERR "TIPC: " fmt, ## arg)
106#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
107 KERN_WARNING "TIPC: " fmt, ## arg)
108#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
109 KERN_NOTICE "TIPC: " fmt, ## arg)
110
111#else
112
120#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) 113#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg)
121#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg) 114#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg)
122#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg) 115#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg)
123 116
124#define dbg(fmt, arg...) do {} while (0) 117#endif
125#define msg_dbg(msg,txt) do {} while (0)
126#define dump(fmt,arg...) do {} while (0)
127 118
119/*
120 * DBG_OUTPUT is the destination print buffer for debug messages.
121 * It defaults to the the null print buffer, but can be redefined
122 * (typically in the individual .c files being debugged) to allow
123 * selected debug messages to be generated where needed.
124 */
125
126#ifndef DBG_OUTPUT
127#define DBG_OUTPUT TIPC_NULL
128#endif
128 129
129/* 130/*
130 * TIPC_OUTPUT is defined to be the system console, while DBG_OUTPUT is 131 * TIPC can be configured to send debug messages to the specified print buffer
131 * the null print buffer. Thes ensures that any system or debug messages 132 * (typically DBG_OUTPUT) or to suppress them entirely.
132 * that are generated without using the above macros are handled correctly.
133 */ 133 */
134 134
135#undef TIPC_OUTPUT 135#ifdef CONFIG_TIPC_DEBUG
136#define TIPC_OUTPUT TIPC_CONS
137 136
138#undef DBG_OUTPUT 137#define dbg(fmt, arg...) \
139#define DBG_OUTPUT TIPC_NULL 138 do { \
139 if (DBG_OUTPUT != TIPC_NULL) \
140 tipc_printf(DBG_OUTPUT, fmt, ## arg); \
141 } while (0)
142#define msg_dbg(msg, txt) \
143 do { \
144 if (DBG_OUTPUT != TIPC_NULL) \
145 tipc_msg_dbg(DBG_OUTPUT, msg, txt); \
146 } while (0)
147#define dump(fmt, arg...) \
148 do { \
149 if (DBG_OUTPUT != TIPC_NULL) \
150 tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \
151 } while (0)
152
153void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
154void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
155
156#else
157
158#define dbg(fmt, arg...) do {} while (0)
159#define msg_dbg(msg, txt) do {} while (0)
160#define dump(fmt, arg...) do {} while (0)
161
162#define tipc_msg_dbg(...) do {} while (0)
163#define tipc_dump_dbg(...) do {} while (0)
140 164
141#endif 165#endif
142 166
@@ -178,7 +202,7 @@ extern atomic_t tipc_user_count;
178 202
179extern int tipc_core_start(void); 203extern int tipc_core_start(void);
180extern void tipc_core_stop(void); 204extern void tipc_core_stop(void);
181extern int tipc_core_start_net(void); 205extern int tipc_core_start_net(unsigned long addr);
182extern void tipc_core_stop_net(void); 206extern void tipc_core_stop_net(void);
183extern int tipc_handler_start(void); 207extern int tipc_handler_start(void);
184extern void tipc_handler_stop(void); 208extern void tipc_handler_stop(void);
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c
index e809d2a2ce06..29ecae851668 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/dbg.c
@@ -2,7 +2,7 @@
2 * net/tipc/dbg.c: TIPC print buffer routines for debugging 2 * net/tipc/dbg.c: TIPC print buffer routines for debugging
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -38,17 +38,43 @@
38#include "config.h" 38#include "config.h"
39#include "dbg.h" 39#include "dbg.h"
40 40
41static char print_string[TIPC_PB_MAX_STR]; 41/*
42static DEFINE_SPINLOCK(print_lock); 42 * TIPC pre-defines the following print buffers:
43 *
44 * TIPC_NULL : null buffer (i.e. print nowhere)
45 * TIPC_CONS : system console
46 * TIPC_LOG : TIPC log buffer
47 *
48 * Additional user-defined print buffers are also permitted.
49 */
43 50
44static struct print_buf null_buf = { NULL, 0, NULL, NULL }; 51static struct print_buf null_buf = { NULL, 0, NULL, 0 };
45struct print_buf *TIPC_NULL = &null_buf; 52struct print_buf *const TIPC_NULL = &null_buf;
46 53
47static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; 54static struct print_buf cons_buf = { NULL, 0, NULL, 1 };
48struct print_buf *TIPC_CONS = &cons_buf; 55struct print_buf *const TIPC_CONS = &cons_buf;
49 56
50static struct print_buf log_buf = { NULL, 0, NULL, NULL }; 57static struct print_buf log_buf = { NULL, 0, NULL, 1 };
51struct print_buf *TIPC_LOG = &log_buf; 58struct print_buf *const TIPC_LOG = &log_buf;
59
60/*
61 * Locking policy when using print buffers.
62 *
63 * 1) tipc_printf() uses 'print_lock' to protect against concurrent access to
64 * 'print_string' when writing to a print buffer. This also protects against
65 * concurrent writes to the print buffer being written to.
66 *
67 * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned
68 * use of 'print_lock' to protect against all types of concurrent operations
69 * on their associated print buffer (not just write operations).
70 *
71 * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely
72 * on the caller to prevent simultaneous use of the print buffer(s) being
73 * manipulated.
74 */
75
76static char print_string[TIPC_PB_MAX_STR];
77static DEFINE_SPINLOCK(print_lock);
52 78
53 79
54#define FORMAT(PTR,LEN,FMT) \ 80#define FORMAT(PTR,LEN,FMT) \
@@ -60,27 +86,14 @@ struct print_buf *TIPC_LOG = &log_buf;
60 *(PTR + LEN) = '\0';\ 86 *(PTR + LEN) = '\0';\
61} 87}
62 88
63/*
64 * Locking policy when using print buffers.
65 *
66 * The following routines use 'print_lock' for protection:
67 * 1) tipc_printf() - to protect its print buffer(s) and 'print_string'
68 * 2) TIPC_TEE() - to protect its print buffer(s)
69 * 3) tipc_dump() - to protect its print buffer(s) and 'print_string'
70 * 4) tipc_log_XXX() - to protect TIPC_LOG
71 *
72 * All routines of the form tipc_printbuf_XXX() rely on the caller to prevent
73 * simultaneous use of the print buffer(s) being manipulated.
74 */
75
76/** 89/**
77 * tipc_printbuf_init - initialize print buffer to empty 90 * tipc_printbuf_init - initialize print buffer to empty
78 * @pb: pointer to print buffer structure 91 * @pb: pointer to print buffer structure
79 * @raw: pointer to character array used by print buffer 92 * @raw: pointer to character array used by print buffer
80 * @size: size of character array 93 * @size: size of character array
81 * 94 *
82 * Makes the print buffer a null device that discards anything written to it 95 * Note: If the character array is too small (or absent), the print buffer
83 * if the character array is too small (or absent). 96 * becomes a null device that discards anything written to it.
84 */ 97 */
85 98
86void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) 99void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
@@ -88,13 +101,13 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
88 pb->buf = raw; 101 pb->buf = raw;
89 pb->crs = raw; 102 pb->crs = raw;
90 pb->size = size; 103 pb->size = size;
91 pb->next = NULL; 104 pb->echo = 0;
92 105
93 if (size < TIPC_PB_MIN_SIZE) { 106 if (size < TIPC_PB_MIN_SIZE) {
94 pb->buf = NULL; 107 pb->buf = NULL;
95 } else if (raw) { 108 } else if (raw) {
96 pb->buf[0] = 0; 109 pb->buf[0] = 0;
97 pb->buf[size-1] = ~0; 110 pb->buf[size - 1] = ~0;
98 } 111 }
99} 112}
100 113
@@ -105,7 +118,11 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
105 118
106void tipc_printbuf_reset(struct print_buf *pb) 119void tipc_printbuf_reset(struct print_buf *pb)
107{ 120{
108 tipc_printbuf_init(pb, pb->buf, pb->size); 121 if (pb->buf) {
122 pb->crs = pb->buf;
123 pb->buf[0] = 0;
124 pb->buf[pb->size - 1] = ~0;
125 }
109} 126}
110 127
111/** 128/**
@@ -141,7 +158,7 @@ int tipc_printbuf_validate(struct print_buf *pb)
141 158
142 if (pb->buf[pb->size - 1] == 0) { 159 if (pb->buf[pb->size - 1] == 0) {
143 cp_buf = kmalloc(pb->size, GFP_ATOMIC); 160 cp_buf = kmalloc(pb->size, GFP_ATOMIC);
144 if (cp_buf != NULL){ 161 if (cp_buf) {
145 tipc_printbuf_init(&cb, cp_buf, pb->size); 162 tipc_printbuf_init(&cb, cp_buf, pb->size);
146 tipc_printbuf_move(&cb, pb); 163 tipc_printbuf_move(&cb, pb);
147 tipc_printbuf_move(pb, &cb); 164 tipc_printbuf_move(pb, &cb);
@@ -179,15 +196,16 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
179 } 196 }
180 197
181 if (pb_to->size < pb_from->size) { 198 if (pb_to->size < pb_from->size) {
182 tipc_printbuf_reset(pb_to); 199 strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***");
183 tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***"); 200 pb_to->buf[pb_to->size - 1] = ~0;
201 pb_to->crs = strchr(pb_to->buf, 0);
184 return; 202 return;
185 } 203 }
186 204
187 /* Copy data from char after cursor to end (if used) */ 205 /* Copy data from char after cursor to end (if used) */
188 206
189 len = pb_from->buf + pb_from->size - pb_from->crs - 2; 207 len = pb_from->buf + pb_from->size - pb_from->crs - 2;
190 if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { 208 if ((pb_from->buf[pb_from->size - 1] == 0) && (len > 0)) {
191 strcpy(pb_to->buf, pb_from->crs + 1); 209 strcpy(pb_to->buf, pb_from->crs + 1);
192 pb_to->crs = pb_to->buf + len; 210 pb_to->crs = pb_to->buf + len;
193 } else 211 } else
@@ -203,8 +221,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
203} 221}
204 222
205/** 223/**
206 * tipc_printf - append formatted output to print buffer chain 224 * tipc_printf - append formatted output to print buffer
207 * @pb: pointer to chain of print buffers (may be NULL) 225 * @pb: pointer to print buffer
208 * @fmt: formatted info to be printed 226 * @fmt: formatted info to be printed
209 */ 227 */
210 228
@@ -213,68 +231,40 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
213 int chars_to_add; 231 int chars_to_add;
214 int chars_left; 232 int chars_left;
215 char save_char; 233 char save_char;
216 struct print_buf *pb_next;
217 234
218 spin_lock_bh(&print_lock); 235 spin_lock_bh(&print_lock);
236
219 FORMAT(print_string, chars_to_add, fmt); 237 FORMAT(print_string, chars_to_add, fmt);
220 if (chars_to_add >= TIPC_PB_MAX_STR) 238 if (chars_to_add >= TIPC_PB_MAX_STR)
221 strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); 239 strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***");
222 240
223 while (pb) { 241 if (pb->buf) {
224 if (pb == TIPC_CONS) 242 chars_left = pb->buf + pb->size - pb->crs - 1;
225 printk(print_string); 243 if (chars_to_add <= chars_left) {
226 else if (pb->buf) { 244 strcpy(pb->crs, print_string);
227 chars_left = pb->buf + pb->size - pb->crs - 1; 245 pb->crs += chars_to_add;
228 if (chars_to_add <= chars_left) { 246 } else if (chars_to_add >= (pb->size - 1)) {
229 strcpy(pb->crs, print_string); 247 strcpy(pb->buf, print_string + chars_to_add + 1
230 pb->crs += chars_to_add; 248 - pb->size);
231 } else if (chars_to_add >= (pb->size - 1)) { 249 pb->crs = pb->buf + pb->size - 1;
232 strcpy(pb->buf, print_string + chars_to_add + 1 250 } else {
233 - pb->size); 251 strcpy(pb->buf, print_string + chars_left);
234 pb->crs = pb->buf + pb->size - 1; 252 save_char = print_string[chars_left];
235 } else { 253 print_string[chars_left] = 0;
236 strcpy(pb->buf, print_string + chars_left); 254 strcpy(pb->crs, print_string);
237 save_char = print_string[chars_left]; 255 print_string[chars_left] = save_char;
238 print_string[chars_left] = 0; 256 pb->crs = pb->buf + chars_to_add - chars_left;
239 strcpy(pb->crs, print_string);
240 print_string[chars_left] = save_char;
241 pb->crs = pb->buf + chars_to_add - chars_left;
242 }
243 } 257 }
244 pb_next = pb->next;
245 pb->next = NULL;
246 pb = pb_next;
247 } 258 }
248 spin_unlock_bh(&print_lock);
249}
250 259
251/** 260 if (pb->echo)
252 * TIPC_TEE - perform next output operation on both print buffers 261 printk(print_string);
253 * @b0: pointer to chain of print buffers (may be NULL)
254 * @b1: pointer to print buffer to add to chain
255 *
256 * Returns pointer to print buffer chain.
257 */
258 262
259struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
260{
261 struct print_buf *pb = b0;
262
263 if (!b0 || (b0 == b1))
264 return b1;
265
266 spin_lock_bh(&print_lock);
267 while (pb->next) {
268 if ((pb->next == b1) || (pb->next == b0))
269 pb->next = pb->next->next;
270 else
271 pb = pb->next;
272 }
273 pb->next = b1;
274 spin_unlock_bh(&print_lock); 263 spin_unlock_bh(&print_lock);
275 return b0;
276} 264}
277 265
266#ifdef CONFIG_TIPC_DEBUG
267
278/** 268/**
279 * print_to_console - write string of bytes to console in multiple chunks 269 * print_to_console - write string of bytes to console in multiple chunks
280 */ 270 */
@@ -321,72 +311,66 @@ static void printbuf_dump(struct print_buf *pb)
321} 311}
322 312
323/** 313/**
324 * tipc_dump - dump non-console print buffer(s) to console 314 * tipc_dump_dbg - dump (non-console) print buffer to console
325 * @pb: pointer to chain of print buffers 315 * @pb: pointer to print buffer
326 */ 316 */
327 317
328void tipc_dump(struct print_buf *pb, const char *fmt, ...) 318void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...)
329{ 319{
330 struct print_buf *pb_next;
331 int len; 320 int len;
332 321
322 if (pb == TIPC_CONS)
323 return;
324
333 spin_lock_bh(&print_lock); 325 spin_lock_bh(&print_lock);
326
334 FORMAT(print_string, len, fmt); 327 FORMAT(print_string, len, fmt);
335 printk(print_string); 328 printk(print_string);
336 329
337 for (; pb; pb = pb->next) { 330 printk("\n---- Start of %s log dump ----\n\n",
338 if (pb != TIPC_CONS) { 331 (pb == TIPC_LOG) ? "global" : "local");
339 printk("\n---- Start of %s log dump ----\n\n", 332 printbuf_dump(pb);
340 (pb == TIPC_LOG) ? "global" : "local"); 333 tipc_printbuf_reset(pb);
341 printbuf_dump(pb); 334 printk("\n---- End of dump ----\n");
342 tipc_printbuf_reset(pb); 335
343 printk("\n---- End of dump ----\n");
344 }
345 pb_next = pb->next;
346 pb->next = NULL;
347 pb = pb_next;
348 }
349 spin_unlock_bh(&print_lock); 336 spin_unlock_bh(&print_lock);
350} 337}
351 338
339#endif
340
352/** 341/**
353 * tipc_log_stop - free up TIPC log print buffer 342 * tipc_log_resize - change the size of the TIPC log buffer
343 * @log_size: print buffer size to use
354 */ 344 */
355 345
356void tipc_log_stop(void) 346int tipc_log_resize(int log_size)
357{ 347{
348 int res = 0;
349
358 spin_lock_bh(&print_lock); 350 spin_lock_bh(&print_lock);
359 if (TIPC_LOG->buf) { 351 if (TIPC_LOG->buf) {
360 kfree(TIPC_LOG->buf); 352 kfree(TIPC_LOG->buf);
361 TIPC_LOG->buf = NULL; 353 TIPC_LOG->buf = NULL;
362 } 354 }
363 spin_unlock_bh(&print_lock);
364}
365
366/**
367 * tipc_log_reinit - (re)initialize TIPC log print buffer
368 * @log_size: print buffer size to use
369 */
370
371void tipc_log_reinit(int log_size)
372{
373 tipc_log_stop();
374
375 if (log_size) { 355 if (log_size) {
376 if (log_size < TIPC_PB_MIN_SIZE) 356 if (log_size < TIPC_PB_MIN_SIZE)
377 log_size = TIPC_PB_MIN_SIZE; 357 log_size = TIPC_PB_MIN_SIZE;
378 spin_lock_bh(&print_lock); 358 res = TIPC_LOG->echo;
379 tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), 359 tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC),
380 log_size); 360 log_size);
381 spin_unlock_bh(&print_lock); 361 TIPC_LOG->echo = res;
362 res = !TIPC_LOG->buf;
382 } 363 }
364 spin_unlock_bh(&print_lock);
365
366 return res;
383} 367}
384 368
385/** 369/**
386 * tipc_log_resize - reconfigure size of TIPC log buffer 370 * tipc_log_resize_cmd - reconfigure size of TIPC log buffer
387 */ 371 */
388 372
389struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space) 373struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space)
390{ 374{
391 u32 value; 375 u32 value;
392 376
@@ -397,7 +381,9 @@ struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space)
397 if (value != delimit(value, 0, 32768)) 381 if (value != delimit(value, 0, 32768))
398 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 382 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
399 " (log size must be 0-32768)"); 383 " (log size must be 0-32768)");
400 tipc_log_reinit(value); 384 if (tipc_log_resize(value))
385 return tipc_cfg_reply_error_string(
386 "unable to create specified log (log size is now 0)");
401 return tipc_cfg_reply_none(); 387 return tipc_cfg_reply_none();
402} 388}
403 389
@@ -410,27 +396,32 @@ struct sk_buff *tipc_log_dump(void)
410 struct sk_buff *reply; 396 struct sk_buff *reply;
411 397
412 spin_lock_bh(&print_lock); 398 spin_lock_bh(&print_lock);
413 if (!TIPC_LOG->buf) 399 if (!TIPC_LOG->buf) {
400 spin_unlock_bh(&print_lock);
414 reply = tipc_cfg_reply_ultra_string("log not activated\n"); 401 reply = tipc_cfg_reply_ultra_string("log not activated\n");
415 else if (tipc_printbuf_empty(TIPC_LOG)) 402 } else if (tipc_printbuf_empty(TIPC_LOG)) {
403 spin_unlock_bh(&print_lock);
416 reply = tipc_cfg_reply_ultra_string("log is empty\n"); 404 reply = tipc_cfg_reply_ultra_string("log is empty\n");
405 }
417 else { 406 else {
418 struct tlv_desc *rep_tlv; 407 struct tlv_desc *rep_tlv;
419 struct print_buf pb; 408 struct print_buf pb;
420 int str_len; 409 int str_len;
421 410
422 str_len = min(TIPC_LOG->size, 32768u); 411 str_len = min(TIPC_LOG->size, 32768u);
412 spin_unlock_bh(&print_lock);
423 reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); 413 reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len));
424 if (reply) { 414 if (reply) {
425 rep_tlv = (struct tlv_desc *)reply->data; 415 rep_tlv = (struct tlv_desc *)reply->data;
426 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); 416 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len);
417 spin_lock_bh(&print_lock);
427 tipc_printbuf_move(&pb, TIPC_LOG); 418 tipc_printbuf_move(&pb, TIPC_LOG);
419 spin_unlock_bh(&print_lock);
428 str_len = strlen(TLV_DATA(rep_tlv)) + 1; 420 str_len = strlen(TLV_DATA(rep_tlv)) + 1;
429 skb_put(reply, TLV_SPACE(str_len)); 421 skb_put(reply, TLV_SPACE(str_len));
430 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 422 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
431 } 423 }
432 } 424 }
433 spin_unlock_bh(&print_lock);
434 return reply; 425 return reply;
435} 426}
436 427
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h
index c01b085000e0..5ef1bc8f64ef 100644
--- a/net/tipc/dbg.h
+++ b/net/tipc/dbg.h
@@ -2,7 +2,7 @@
2 * net/tipc/dbg.h: Include file for TIPC print buffer routines 2 * net/tipc/dbg.h: Include file for TIPC print buffer routines
3 * 3 *
4 * Copyright (c) 1997-2006, Ericsson AB 4 * Copyright (c) 1997-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -42,14 +42,14 @@
42 * @buf: pointer to character array containing print buffer contents 42 * @buf: pointer to character array containing print buffer contents
43 * @size: size of character array 43 * @size: size of character array
44 * @crs: pointer to first unused space in character array (i.e. final NUL) 44 * @crs: pointer to first unused space in character array (i.e. final NUL)
45 * @next: used to link print buffers when printing to more than one at a time 45 * @echo: echo output to system console if non-zero
46 */ 46 */
47 47
48struct print_buf { 48struct print_buf {
49 char *buf; 49 char *buf;
50 u32 size; 50 u32 size;
51 char *crs; 51 char *crs;
52 struct print_buf *next; 52 int echo;
53}; 53};
54 54
55#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ 55#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */
@@ -61,10 +61,10 @@ int tipc_printbuf_empty(struct print_buf *pb);
61int tipc_printbuf_validate(struct print_buf *pb); 61int tipc_printbuf_validate(struct print_buf *pb);
62void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); 62void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from);
63 63
64void tipc_log_reinit(int log_size); 64int tipc_log_resize(int log_size);
65void tipc_log_stop(void);
66 65
67struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space); 66struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area,
67 int req_tlv_space);
68struct sk_buff *tipc_log_dump(void); 68struct sk_buff *tipc_log_dump(void);
69 69
70#endif 70#endif
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 5d643e5721eb..1657f0e795ff 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -120,9 +120,8 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
120 120
121 if (buf) { 121 if (buf) {
122 msg = buf_msg(buf); 122 msg = buf_msg(buf);
123 msg_init(msg, LINK_CONFIG, type, TIPC_OK, DSC_H_SIZE, 123 msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain);
124 dest_domain); 124 msg_set_non_seq(msg, 1);
125 msg_set_non_seq(msg);
126 msg_set_req_links(msg, req_links); 125 msg_set_req_links(msg, req_links);
127 msg_set_dest_domain(msg, dest_domain); 126 msg_set_dest_domain(msg, dest_domain);
128 msg_set_bc_netid(msg, tipc_net_id); 127 msg_set_bc_netid(msg, tipc_net_id);
@@ -156,11 +155,11 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
156/** 155/**
157 * tipc_disc_recv_msg - handle incoming link setup message (request or response) 156 * tipc_disc_recv_msg - handle incoming link setup message (request or response)
158 * @buf: buffer containing message 157 * @buf: buffer containing message
158 * @b_ptr: bearer that message arrived on
159 */ 159 */
160 160
161void tipc_disc_recv_msg(struct sk_buff *buf) 161void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
162{ 162{
163 struct bearer *b_ptr = (struct bearer *)TIPC_SKB_CB(buf)->handle;
164 struct link *link; 163 struct link *link;
165 struct tipc_media_addr media_addr; 164 struct tipc_media_addr media_addr;
166 struct tipc_msg *msg = buf_msg(buf); 165 struct tipc_msg *msg = buf_msg(buf);
@@ -200,9 +199,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
200 dbg(" in own cluster\n"); 199 dbg(" in own cluster\n");
201 if (n_ptr == NULL) { 200 if (n_ptr == NULL) {
202 n_ptr = tipc_node_create(orig); 201 n_ptr = tipc_node_create(orig);
203 } 202 if (!n_ptr)
204 if (n_ptr == NULL) { 203 return;
205 return;
206 } 204 }
207 spin_lock_bh(&n_ptr->lock); 205 spin_lock_bh(&n_ptr->lock);
208 link = n_ptr->links[b_ptr->identity]; 206 link = n_ptr->links[b_ptr->identity];
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index 9fd7587b143a..c36eaeb7d5d0 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -48,7 +48,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr,
48void tipc_disc_update_link_req(struct link_req *req); 48void tipc_disc_update_link_req(struct link_req *req);
49void tipc_disc_stop_link_req(struct link_req *req); 49void tipc_disc_stop_link_req(struct link_req *req);
50 50
51void tipc_disc_recv_msg(struct sk_buff *buf); 51void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr);
52 52
53void tipc_disc_link_event(u32 addr, char *name, int up); 53void tipc_disc_link_event(u32 addr, char *name, int up);
54#if 0 54#if 0
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2a26a16e269f..9784a8e963b4 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -51,6 +51,12 @@
51 51
52 52
53/* 53/*
54 * Out-of-range value for link session numbers
55 */
56
57#define INVALID_SESSION 0x10000
58
59/*
54 * Limit for deferred reception queue: 60 * Limit for deferred reception queue:
55 */ 61 */
56 62
@@ -147,9 +153,21 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
147 153
148#define LINK_LOG_BUF_SIZE 0 154#define LINK_LOG_BUF_SIZE 0
149 155
150#define dbg_link(fmt, arg...) do {if (LINK_LOG_BUF_SIZE) tipc_printf(&l_ptr->print_buf, fmt, ## arg); } while(0) 156#define dbg_link(fmt, arg...) \
151#define dbg_link_msg(msg, txt) do {if (LINK_LOG_BUF_SIZE) tipc_msg_print(&l_ptr->print_buf, msg, txt); } while(0) 157 do { \
152#define dbg_link_state(txt) do {if (LINK_LOG_BUF_SIZE) link_print(l_ptr, &l_ptr->print_buf, txt); } while(0) 158 if (LINK_LOG_BUF_SIZE) \
159 tipc_printf(&l_ptr->print_buf, fmt, ## arg); \
160 } while (0)
161#define dbg_link_msg(msg, txt) \
162 do { \
163 if (LINK_LOG_BUF_SIZE) \
164 tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \
165 } while (0)
166#define dbg_link_state(txt) \
167 do { \
168 if (LINK_LOG_BUF_SIZE) \
169 link_print(l_ptr, &l_ptr->print_buf, txt); \
170 } while (0)
153#define dbg_link_dump() do { \ 171#define dbg_link_dump() do { \
154 if (LINK_LOG_BUF_SIZE) { \ 172 if (LINK_LOG_BUF_SIZE) { \
155 tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ 173 tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \
@@ -450,9 +468,9 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
450 468
451 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; 469 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg;
452 msg = l_ptr->pmsg; 470 msg = l_ptr->pmsg;
453 msg_init(msg, LINK_PROTOCOL, RESET_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); 471 msg_init(msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, l_ptr->addr);
454 msg_set_size(msg, sizeof(l_ptr->proto_msg)); 472 msg_set_size(msg, sizeof(l_ptr->proto_msg));
455 msg_set_session(msg, tipc_random); 473 msg_set_session(msg, (tipc_random & 0xffff));
456 msg_set_bearer_id(msg, b_ptr->identity); 474 msg_set_bearer_id(msg, b_ptr->identity);
457 strcpy((char *)msg_data(msg), if_name); 475 strcpy((char *)msg_data(msg), if_name);
458 476
@@ -693,10 +711,10 @@ void tipc_link_reset(struct link *l_ptr)
693 u32 checkpoint = l_ptr->next_in_no; 711 u32 checkpoint = l_ptr->next_in_no;
694 int was_active_link = tipc_link_is_active(l_ptr); 712 int was_active_link = tipc_link_is_active(l_ptr);
695 713
696 msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1); 714 msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
697 715
698 /* Link is down, accept any session: */ 716 /* Link is down, accept any session */
699 l_ptr->peer_session = 0; 717 l_ptr->peer_session = INVALID_SESSION;
700 718
701 /* Prepare for max packet size negotiation */ 719 /* Prepare for max packet size negotiation */
702 link_init_max_pkt(l_ptr); 720 link_init_max_pkt(l_ptr);
@@ -1110,7 +1128,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1110 1128
1111 if (bundler) { 1129 if (bundler) {
1112 msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG, 1130 msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG,
1113 TIPC_OK, INT_H_SIZE, l_ptr->addr); 1131 INT_H_SIZE, l_ptr->addr);
1114 skb_copy_to_linear_data(bundler, &bundler_hdr, 1132 skb_copy_to_linear_data(bundler, &bundler_hdr,
1115 INT_H_SIZE); 1133 INT_H_SIZE);
1116 skb_trim(bundler, INT_H_SIZE); 1134 skb_trim(bundler, INT_H_SIZE);
@@ -1374,7 +1392,7 @@ again:
1374 1392
1375 msg_dbg(hdr, ">FRAGMENTING>"); 1393 msg_dbg(hdr, ">FRAGMENTING>");
1376 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 1394 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1377 TIPC_OK, INT_H_SIZE, msg_destnode(hdr)); 1395 INT_H_SIZE, msg_destnode(hdr));
1378 msg_set_link_selector(&fragm_hdr, sender->publ.ref); 1396 msg_set_link_selector(&fragm_hdr, sender->publ.ref);
1379 msg_set_size(&fragm_hdr, max_pkt); 1397 msg_set_size(&fragm_hdr, max_pkt);
1380 msg_set_fragm_no(&fragm_hdr, 1); 1398 msg_set_fragm_no(&fragm_hdr, 1);
@@ -1651,7 +1669,7 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1651 struct tipc_msg *msg = buf_msg(buf); 1669 struct tipc_msg *msg = buf_msg(buf);
1652 1670
1653 warn("Retransmission failure on link <%s>\n", l_ptr->name); 1671 warn("Retransmission failure on link <%s>\n", l_ptr->name);
1654 tipc_msg_print(TIPC_OUTPUT, msg, ">RETR-FAIL>"); 1672 tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>");
1655 1673
1656 if (l_ptr->addr) { 1674 if (l_ptr->addr) {
1657 1675
@@ -1748,21 +1766,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1748 l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; 1766 l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0;
1749} 1767}
1750 1768
1751/*
1752 * link_recv_non_seq: Receive packets which are outside
1753 * the link sequence flow
1754 */
1755
1756static void link_recv_non_seq(struct sk_buff *buf)
1757{
1758 struct tipc_msg *msg = buf_msg(buf);
1759
1760 if (msg_user(msg) == LINK_CONFIG)
1761 tipc_disc_recv_msg(buf);
1762 else
1763 tipc_bclink_recv_pkt(buf);
1764}
1765
1766/** 1769/**
1767 * link_insert_deferred_queue - insert deferred messages back into receive chain 1770 * link_insert_deferred_queue - insert deferred messages back into receive chain
1768 */ 1771 */
@@ -1839,7 +1842,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1839{ 1842{
1840 read_lock_bh(&tipc_net_lock); 1843 read_lock_bh(&tipc_net_lock);
1841 while (head) { 1844 while (head) {
1842 struct bearer *b_ptr; 1845 struct bearer *b_ptr = (struct bearer *)tb_ptr;
1843 struct node *n_ptr; 1846 struct node *n_ptr;
1844 struct link *l_ptr; 1847 struct link *l_ptr;
1845 struct sk_buff *crs; 1848 struct sk_buff *crs;
@@ -1850,9 +1853,6 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1850 u32 released = 0; 1853 u32 released = 0;
1851 int type; 1854 int type;
1852 1855
1853 b_ptr = (struct bearer *)tb_ptr;
1854 TIPC_SKB_CB(buf)->handle = b_ptr;
1855
1856 head = head->next; 1856 head = head->next;
1857 1857
1858 /* Ensure message is well-formed */ 1858 /* Ensure message is well-formed */
@@ -1871,7 +1871,10 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1871 msg = buf_msg(buf); 1871 msg = buf_msg(buf);
1872 1872
1873 if (unlikely(msg_non_seq(msg))) { 1873 if (unlikely(msg_non_seq(msg))) {
1874 link_recv_non_seq(buf); 1874 if (msg_user(msg) == LINK_CONFIG)
1875 tipc_disc_recv_msg(buf, b_ptr);
1876 else
1877 tipc_bclink_recv_pkt(buf);
1875 continue; 1878 continue;
1876 } 1879 }
1877 1880
@@ -1978,8 +1981,6 @@ deliver:
1978 if (link_recv_changeover_msg(&l_ptr, &buf)) { 1981 if (link_recv_changeover_msg(&l_ptr, &buf)) {
1979 msg = buf_msg(buf); 1982 msg = buf_msg(buf);
1980 seq_no = msg_seqno(msg); 1983 seq_no = msg_seqno(msg);
1981 TIPC_SKB_CB(buf)->handle
1982 = b_ptr;
1983 if (type == ORIGINAL_MSG) 1984 if (type == ORIGINAL_MSG)
1984 goto deliver; 1985 goto deliver;
1985 goto protocol_check; 1986 goto protocol_check;
@@ -2263,7 +2264,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2263 switch (msg_type(msg)) { 2264 switch (msg_type(msg)) {
2264 2265
2265 case RESET_MSG: 2266 case RESET_MSG:
2266 if (!link_working_unknown(l_ptr) && l_ptr->peer_session) { 2267 if (!link_working_unknown(l_ptr) &&
2268 (l_ptr->peer_session != INVALID_SESSION)) {
2267 if (msg_session(msg) == l_ptr->peer_session) { 2269 if (msg_session(msg) == l_ptr->peer_session) {
2268 dbg("Duplicate RESET: %u<->%u\n", 2270 dbg("Duplicate RESET: %u<->%u\n",
2269 msg_session(msg), l_ptr->peer_session); 2271 msg_session(msg), l_ptr->peer_session);
@@ -2424,7 +2426,7 @@ void tipc_link_changeover(struct link *l_ptr)
2424 } 2426 }
2425 2427
2426 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, 2428 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
2427 ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); 2429 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
2428 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2430 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2429 msg_set_msgcnt(&tunnel_hdr, msgcount); 2431 msg_set_msgcnt(&tunnel_hdr, msgcount);
2430 dbg("Link changeover requires %u tunnel messages\n", msgcount); 2432 dbg("Link changeover requires %u tunnel messages\n", msgcount);
@@ -2479,7 +2481,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2479 struct tipc_msg tunnel_hdr; 2481 struct tipc_msg tunnel_hdr;
2480 2482
2481 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, 2483 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
2482 DUPLICATE_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); 2484 DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr);
2483 msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); 2485 msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size);
2484 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2486 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2485 iter = l_ptr->first_out; 2487 iter = l_ptr->first_out;
@@ -2672,10 +2674,12 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2672 u32 pack_sz = link_max_pkt(l_ptr); 2674 u32 pack_sz = link_max_pkt(l_ptr);
2673 u32 fragm_sz = pack_sz - INT_H_SIZE; 2675 u32 fragm_sz = pack_sz - INT_H_SIZE;
2674 u32 fragm_no = 1; 2676 u32 fragm_no = 1;
2675 u32 destaddr = msg_destnode(inmsg); 2677 u32 destaddr;
2676 2678
2677 if (msg_short(inmsg)) 2679 if (msg_short(inmsg))
2678 destaddr = l_ptr->addr; 2680 destaddr = l_ptr->addr;
2681 else
2682 destaddr = msg_destnode(inmsg);
2679 2683
2680 if (msg_routed(inmsg)) 2684 if (msg_routed(inmsg))
2681 msg_set_prevnode(inmsg, tipc_own_addr); 2685 msg_set_prevnode(inmsg, tipc_own_addr);
@@ -2683,7 +2687,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2683 /* Prepare reusable fragment header: */ 2687 /* Prepare reusable fragment header: */
2684 2688
2685 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 2689 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
2686 TIPC_OK, INT_H_SIZE, destaddr); 2690 INT_H_SIZE, destaddr);
2687 msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); 2691 msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg));
2688 msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); 2692 msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++));
2689 msg_set_fragm_no(&fragm_hdr, fragm_no); 2693 msg_set_fragm_no(&fragm_hdr, fragm_no);
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 696a8633df75..73dcd00d674e 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -41,7 +41,9 @@
41#include "bearer.h" 41#include "bearer.h"
42 42
43 43
44void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str) 44#ifdef CONFIG_TIPC_DEBUG
45
46void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
45{ 47{
46 u32 usr = msg_user(msg); 48 u32 usr = msg_user(msg);
47 tipc_printf(buf, str); 49 tipc_printf(buf, str);
@@ -228,13 +230,10 @@ void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str
228 230
229 switch (usr) { 231 switch (usr) {
230 case CONN_MANAGER: 232 case CONN_MANAGER:
231 case NAME_DISTRIBUTOR:
232 case TIPC_LOW_IMPORTANCE: 233 case TIPC_LOW_IMPORTANCE:
233 case TIPC_MEDIUM_IMPORTANCE: 234 case TIPC_MEDIUM_IMPORTANCE:
234 case TIPC_HIGH_IMPORTANCE: 235 case TIPC_HIGH_IMPORTANCE:
235 case TIPC_CRITICAL_IMPORTANCE: 236 case TIPC_CRITICAL_IMPORTANCE:
236 if (msg_short(msg))
237 break; /* No error */
238 switch (msg_errcode(msg)) { 237 switch (msg_errcode(msg)) {
239 case TIPC_OK: 238 case TIPC_OK:
240 break; 239 break;
@@ -315,9 +314,11 @@ void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str
315 } 314 }
316 tipc_printf(buf, "\n"); 315 tipc_printf(buf, "\n");
317 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { 316 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) {
318 tipc_msg_print(buf,msg_get_wrapped(msg)," /"); 317 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
319 } 318 }
320 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { 319 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) {
321 tipc_msg_print(buf,msg_get_wrapped(msg)," /"); 320 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
322 } 321 }
323} 322}
323
324#endif
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index ad487e8abcc2..7ee6ae238147 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -2,7 +2,7 @@
2 * net/tipc/msg.h: Include file for TIPC message header routines 2 * net/tipc/msg.h: Include file for TIPC message header routines
3 * 3 *
4 * Copyright (c) 2000-2007, Ericsson AB 4 * Copyright (c) 2000-2007, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2008, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -75,6 +75,14 @@ static inline void msg_set_bits(struct tipc_msg *m, u32 w,
75 m->hdr[w] |= htonl(val); 75 m->hdr[w] |= htonl(val);
76} 76}
77 77
78static inline void msg_swap_words(struct tipc_msg *msg, u32 a, u32 b)
79{
80 u32 temp = msg->hdr[a];
81
82 msg->hdr[a] = msg->hdr[b];
83 msg->hdr[b] = temp;
84}
85
78/* 86/*
79 * Word 0 87 * Word 0
80 */ 88 */
@@ -119,9 +127,9 @@ static inline int msg_non_seq(struct tipc_msg *m)
119 return msg_bits(m, 0, 20, 1); 127 return msg_bits(m, 0, 20, 1);
120} 128}
121 129
122static inline void msg_set_non_seq(struct tipc_msg *m) 130static inline void msg_set_non_seq(struct tipc_msg *m, u32 n)
123{ 131{
124 msg_set_bits(m, 0, 20, 1, 1); 132 msg_set_bits(m, 0, 20, 1, n);
125} 133}
126 134
127static inline int msg_dest_droppable(struct tipc_msg *m) 135static inline int msg_dest_droppable(struct tipc_msg *m)
@@ -224,6 +232,25 @@ static inline void msg_set_seqno(struct tipc_msg *m, u32 n)
224 msg_set_bits(m, 2, 0, 0xffff, n); 232 msg_set_bits(m, 2, 0, 0xffff, n);
225} 233}
226 234
235/*
236 * TIPC may utilize the "link ack #" and "link seq #" fields of a short
237 * message header to hold the destination node for the message, since the
238 * normal "dest node" field isn't present. This cache is only referenced
239 * when required, so populating the cache of a longer message header is
240 * harmless (as long as the header has the two link sequence fields present).
241 *
242 * Note: Host byte order is OK here, since the info never goes off-card.
243 */
244
245static inline u32 msg_destnode_cache(struct tipc_msg *m)
246{
247 return m->hdr[2];
248}
249
250static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode)
251{
252 m->hdr[2] = dnode;
253}
227 254
228/* 255/*
229 * Words 3-10 256 * Words 3-10
@@ -325,7 +352,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
325 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
326 w0:|vers |msg usr|hdr sz |n|resrv| packet size | 353 w0:|vers |msg usr|hdr sz |n|resrv| packet size |
327 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 354 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
328 w1:|m typ|rsv=0| sequence gap | broadcast ack no | 355 w1:|m typ| sequence gap | broadcast ack no |
329 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 356 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
330 w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | 357 w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to |
331 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 358 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -388,12 +415,12 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
388 415
389static inline u32 msg_seq_gap(struct tipc_msg *m) 416static inline u32 msg_seq_gap(struct tipc_msg *m)
390{ 417{
391 return msg_bits(m, 1, 16, 0xff); 418 return msg_bits(m, 1, 16, 0x1fff);
392} 419}
393 420
394static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) 421static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
395{ 422{
396 msg_set_bits(m, 1, 16, 0xff, n); 423 msg_set_bits(m, 1, 16, 0x1fff, n);
397} 424}
398 425
399static inline u32 msg_req_links(struct tipc_msg *m) 426static inline u32 msg_req_links(struct tipc_msg *m)
@@ -696,7 +723,7 @@ static inline u32 msg_tot_importance(struct tipc_msg *m)
696 723
697 724
698static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, 725static inline void msg_init(struct tipc_msg *m, u32 user, u32 type,
699 u32 err, u32 hsize, u32 destnode) 726 u32 hsize, u32 destnode)
700{ 727{
701 memset(m, 0, hsize); 728 memset(m, 0, hsize);
702 msg_set_version(m); 729 msg_set_version(m);
@@ -705,7 +732,6 @@ static inline void msg_init(struct tipc_msg *m, u32 user, u32 type,
705 msg_set_size(m, hsize); 732 msg_set_size(m, hsize);
706 msg_set_prevnode(m, tipc_own_addr); 733 msg_set_prevnode(m, tipc_own_addr);
707 msg_set_type(m, type); 734 msg_set_type(m, type);
708 msg_set_errcode(m, err);
709 if (!msg_short(m)) { 735 if (!msg_short(m)) {
710 msg_set_orignode(m, tipc_own_addr); 736 msg_set_orignode(m, tipc_own_addr);
711 msg_set_destnode(m, destnode); 737 msg_set_destnode(m, destnode);
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 39fd1619febf..10a69894e2fd 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -41,9 +41,6 @@
41#include "msg.h" 41#include "msg.h"
42#include "name_distr.h" 42#include "name_distr.h"
43 43
44#undef DBG_OUTPUT
45#define DBG_OUTPUT NULL
46
47#define ITEM_SIZE sizeof(struct distr_item) 44#define ITEM_SIZE sizeof(struct distr_item)
48 45
49/** 46/**
@@ -106,8 +103,7 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
106 103
107 if (buf != NULL) { 104 if (buf != NULL) {
108 msg = buf_msg(buf); 105 msg = buf_msg(buf);
109 msg_init(msg, NAME_DISTRIBUTOR, type, TIPC_OK, 106 msg_init(msg, NAME_DISTRIBUTOR, type, LONG_H_SIZE, dest);
110 LONG_H_SIZE, dest);
111 msg_set_size(msg, LONG_H_SIZE + size); 107 msg_set_size(msg, LONG_H_SIZE + size);
112 } 108 }
113 return buf; 109 return buf;
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index ac7dfdda7973..096f7bd240a0 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -74,7 +74,7 @@ struct sub_seq {
74 * @first_free: array index of first unused sub-sequence entry 74 * @first_free: array index of first unused sub-sequence entry
75 * @ns_list: links to adjacent name sequences in hash chain 75 * @ns_list: links to adjacent name sequences in hash chain
76 * @subscriptions: list of subscriptions for this 'type' 76 * @subscriptions: list of subscriptions for this 'type'
77 * @lock: spinlock controlling access to name sequence structure 77 * @lock: spinlock controlling access to publication lists of all sub-sequences
78 */ 78 */
79 79
80struct name_seq { 80struct name_seq {
@@ -905,6 +905,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
905 struct sub_seq *sseq; 905 struct sub_seq *sseq;
906 char typearea[11]; 906 char typearea[11];
907 907
908 if (seq->first_free == 0)
909 return;
910
908 sprintf(typearea, "%-10u", seq->type); 911 sprintf(typearea, "%-10u", seq->type);
909 912
910 if (depth == 1) { 913 if (depth == 1) {
@@ -915,7 +918,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
915 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { 918 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) {
916 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { 919 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) {
917 tipc_printf(buf, "%s ", typearea); 920 tipc_printf(buf, "%s ", typearea);
921 spin_lock_bh(&seq->lock);
918 subseq_list(sseq, buf, depth, index); 922 subseq_list(sseq, buf, depth, index);
923 spin_unlock_bh(&seq->lock);
919 sprintf(typearea, "%10s", " "); 924 sprintf(typearea, "%10s", " ");
920 } 925 }
921 } 926 }
@@ -1050,15 +1055,12 @@ void tipc_nametbl_dump(void)
1050 1055
1051int tipc_nametbl_init(void) 1056int tipc_nametbl_init(void)
1052{ 1057{
1053 int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; 1058 table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head),
1054 1059 GFP_ATOMIC);
1055 table.types = kzalloc(array_size, GFP_ATOMIC);
1056 if (!table.types) 1060 if (!table.types)
1057 return -ENOMEM; 1061 return -ENOMEM;
1058 1062
1059 write_lock_bh(&tipc_nametbl_lock);
1060 table.local_publ_count = 0; 1063 table.local_publ_count = 0;
1061 write_unlock_bh(&tipc_nametbl_lock);
1062 return 0; 1064 return 0;
1063} 1065}
1064 1066
diff --git a/net/tipc/net.c b/net/tipc/net.c
index c39c76201e8e..cc51fa483672 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -266,7 +266,7 @@ void tipc_net_route_msg(struct sk_buff *buf)
266 tipc_link_send(buf, dnode, msg_link_selector(msg)); 266 tipc_link_send(buf, dnode, msg_link_selector(msg));
267} 267}
268 268
269int tipc_net_start(void) 269int tipc_net_start(u32 addr)
270{ 270{
271 char addr_string[16]; 271 char addr_string[16];
272 int res; 272 int res;
@@ -274,6 +274,10 @@ int tipc_net_start(void)
274 if (tipc_mode != TIPC_NODE_MODE) 274 if (tipc_mode != TIPC_NODE_MODE)
275 return -ENOPROTOOPT; 275 return -ENOPROTOOPT;
276 276
277 tipc_subscr_stop();
278 tipc_cfg_stop();
279
280 tipc_own_addr = addr;
277 tipc_mode = TIPC_NET_MODE; 281 tipc_mode = TIPC_NET_MODE;
278 tipc_named_reinit(); 282 tipc_named_reinit();
279 tipc_port_reinit(); 283 tipc_port_reinit();
@@ -284,10 +288,10 @@ int tipc_net_start(void)
284 (res = tipc_bclink_init())) { 288 (res = tipc_bclink_init())) {
285 return res; 289 return res;
286 } 290 }
287 tipc_subscr_stop(); 291
288 tipc_cfg_stop();
289 tipc_k_signal((Handler)tipc_subscr_start, 0); 292 tipc_k_signal((Handler)tipc_subscr_start, 0);
290 tipc_k_signal((Handler)tipc_cfg_init, 0); 293 tipc_k_signal((Handler)tipc_cfg_init, 0);
294
291 info("Started in network mode\n"); 295 info("Started in network mode\n");
292 info("Own node address %s, network identity %u\n", 296 info("Own node address %s, network identity %u\n",
293 addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); 297 addr_string_fill(addr_string, tipc_own_addr), tipc_net_id);
diff --git a/net/tipc/net.h b/net/tipc/net.h
index a6a0e9976ac9..d154ac2bda9a 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -58,7 +58,7 @@ void tipc_net_route_msg(struct sk_buff *buf);
58struct node *tipc_net_select_remote_node(u32 addr, u32 ref); 58struct node *tipc_net_select_remote_node(u32 addr, u32 ref);
59u32 tipc_net_select_router(u32 addr, u32 ref); 59u32 tipc_net_select_router(u32 addr, u32 ref);
60 60
61int tipc_net_start(void); 61int tipc_net_start(u32 addr);
62void tipc_net_stop(void); 62void tipc_net_stop(void);
63 63
64#endif 64#endif
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 6a7f7b4c2595..c387217bb230 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -2,7 +2,7 @@
2 * net/tipc/netlink.c: TIPC configuration handling 2 * net/tipc/netlink.c: TIPC configuration handling
3 * 3 *
4 * Copyright (c) 2005-2006, Ericsson AB 4 * Copyright (c) 2005-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -45,15 +45,17 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
45 struct nlmsghdr *req_nlh = info->nlhdr; 45 struct nlmsghdr *req_nlh = info->nlhdr;
46 struct tipc_genlmsghdr *req_userhdr = info->userhdr; 46 struct tipc_genlmsghdr *req_userhdr = info->userhdr;
47 int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN); 47 int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
48 u16 cmd;
48 49
49 if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) 50 if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
50 rep_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); 51 cmd = TIPC_CMD_NOT_NET_ADMIN;
51 else 52 else
52 rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, 53 cmd = req_userhdr->cmd;
53 req_userhdr->cmd, 54
54 NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, 55 rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd,
55 NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), 56 NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
56 hdr_space); 57 NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
58 hdr_space);
57 59
58 if (rep_buf) { 60 if (rep_buf) {
59 skb_push(rep_buf, hdr_space); 61 skb_push(rep_buf, hdr_space);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 598f4d3a0098..34e9a2bb7c19 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -52,16 +52,40 @@ static void node_established_contact(struct node *n_ptr);
52 52
53struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ 53struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */
54 54
55static DEFINE_SPINLOCK(node_create_lock);
56
55u32 tipc_own_tag = 0; 57u32 tipc_own_tag = 0;
56 58
59/**
60 * tipc_node_create - create neighboring node
61 *
62 * Currently, this routine is called by neighbor discovery code, which holds
63 * net_lock for reading only. We must take node_create_lock to ensure a node
64 * isn't created twice if two different bearers discover the node at the same
65 * time. (It would be preferable to switch to holding net_lock in write mode,
66 * but this is a non-trivial change.)
67 */
68
57struct node *tipc_node_create(u32 addr) 69struct node *tipc_node_create(u32 addr)
58{ 70{
59 struct cluster *c_ptr; 71 struct cluster *c_ptr;
60 struct node *n_ptr; 72 struct node *n_ptr;
61 struct node **curr_node; 73 struct node **curr_node;
62 74
75 spin_lock_bh(&node_create_lock);
76
77 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
78 if (addr < n_ptr->addr)
79 break;
80 if (addr == n_ptr->addr) {
81 spin_unlock_bh(&node_create_lock);
82 return n_ptr;
83 }
84 }
85
63 n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); 86 n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC);
64 if (!n_ptr) { 87 if (!n_ptr) {
88 spin_unlock_bh(&node_create_lock);
65 warn("Node creation failed, no memory\n"); 89 warn("Node creation failed, no memory\n");
66 return NULL; 90 return NULL;
67 } 91 }
@@ -71,6 +95,7 @@ struct node *tipc_node_create(u32 addr)
71 c_ptr = tipc_cltr_create(addr); 95 c_ptr = tipc_cltr_create(addr);
72 } 96 }
73 if (!c_ptr) { 97 if (!c_ptr) {
98 spin_unlock_bh(&node_create_lock);
74 kfree(n_ptr); 99 kfree(n_ptr);
75 return NULL; 100 return NULL;
76 } 101 }
@@ -91,6 +116,7 @@ struct node *tipc_node_create(u32 addr)
91 } 116 }
92 } 117 }
93 (*curr_node) = n_ptr; 118 (*curr_node) = n_ptr;
119 spin_unlock_bh(&node_create_lock);
94 return n_ptr; 120 return n_ptr;
95} 121}
96 122
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 2f5806410c64..2e0cff408ff9 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -211,15 +211,18 @@ exit:
211} 211}
212 212
213/** 213/**
214 * tipc_createport_raw - create a native TIPC port 214 * tipc_createport_raw - create a generic TIPC port
215 * 215 *
216 * Returns local port reference 216 * Returns port reference, or 0 if unable to create it
217 *
218 * Note: The newly created port is returned in the locked state.
217 */ 219 */
218 220
219u32 tipc_createport_raw(void *usr_handle, 221u32 tipc_createport_raw(void *usr_handle,
220 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), 222 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
221 void (*wakeup)(struct tipc_port *), 223 void (*wakeup)(struct tipc_port *),
222 const u32 importance) 224 const u32 importance,
225 struct tipc_port **tp_ptr)
223{ 226{
224 struct port *p_ptr; 227 struct port *p_ptr;
225 struct tipc_msg *msg; 228 struct tipc_msg *msg;
@@ -237,17 +240,12 @@ u32 tipc_createport_raw(void *usr_handle,
237 return 0; 240 return 0;
238 } 241 }
239 242
240 tipc_port_lock(ref);
241 p_ptr->publ.usr_handle = usr_handle; 243 p_ptr->publ.usr_handle = usr_handle;
242 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 244 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT;
243 p_ptr->publ.ref = ref; 245 p_ptr->publ.ref = ref;
244 msg = &p_ptr->publ.phdr; 246 msg = &p_ptr->publ.phdr;
245 msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 247 msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
246 0);
247 msg_set_orignode(msg, tipc_own_addr);
248 msg_set_prevnode(msg, tipc_own_addr);
249 msg_set_origport(msg, ref); 248 msg_set_origport(msg, ref);
250 msg_set_importance(msg,importance);
251 p_ptr->last_in_seqno = 41; 249 p_ptr->last_in_seqno = 41;
252 p_ptr->sent = 1; 250 p_ptr->sent = 1;
253 INIT_LIST_HEAD(&p_ptr->wait_list); 251 INIT_LIST_HEAD(&p_ptr->wait_list);
@@ -262,7 +260,7 @@ u32 tipc_createport_raw(void *usr_handle,
262 INIT_LIST_HEAD(&p_ptr->port_list); 260 INIT_LIST_HEAD(&p_ptr->port_list);
263 list_add_tail(&p_ptr->port_list, &ports); 261 list_add_tail(&p_ptr->port_list, &ports);
264 spin_unlock_bh(&tipc_port_list_lock); 262 spin_unlock_bh(&tipc_port_list_lock);
265 tipc_port_unlock(p_ptr); 263 *tp_ptr = &p_ptr->publ;
266 return ref; 264 return ref;
267} 265}
268 266
@@ -402,10 +400,10 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
402 buf = buf_acquire(LONG_H_SIZE); 400 buf = buf_acquire(LONG_H_SIZE);
403 if (buf) { 401 if (buf) {
404 msg = buf_msg(buf); 402 msg = buf_msg(buf);
405 msg_init(msg, usr, type, err, LONG_H_SIZE, destnode); 403 msg_init(msg, usr, type, LONG_H_SIZE, destnode);
404 msg_set_errcode(msg, err);
406 msg_set_destport(msg, destport); 405 msg_set_destport(msg, destport);
407 msg_set_origport(msg, origport); 406 msg_set_origport(msg, origport);
408 msg_set_destnode(msg, destnode);
409 msg_set_orignode(msg, orignode); 407 msg_set_orignode(msg, orignode);
410 msg_set_transp_seqno(msg, seqno); 408 msg_set_transp_seqno(msg, seqno);
411 msg_set_msgcnt(msg, ack); 409 msg_set_msgcnt(msg, ack);
@@ -446,17 +444,19 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
446 return data_sz; 444 return data_sz;
447 } 445 }
448 rmsg = buf_msg(rbuf); 446 rmsg = buf_msg(rbuf);
449 msg_init(rmsg, imp, msg_type(msg), err, hdr_sz, msg_orignode(msg)); 447 msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg));
448 msg_set_errcode(rmsg, err);
450 msg_set_destport(rmsg, msg_origport(msg)); 449 msg_set_destport(rmsg, msg_origport(msg));
451 msg_set_prevnode(rmsg, tipc_own_addr);
452 msg_set_origport(rmsg, msg_destport(msg)); 450 msg_set_origport(rmsg, msg_destport(msg));
453 if (msg_short(msg)) 451 if (msg_short(msg)) {
454 msg_set_orignode(rmsg, tipc_own_addr); 452 msg_set_orignode(rmsg, tipc_own_addr);
455 else 453 /* leave name type & instance as zeroes */
454 } else {
456 msg_set_orignode(rmsg, msg_destnode(msg)); 455 msg_set_orignode(rmsg, msg_destnode(msg));
456 msg_set_nametype(rmsg, msg_nametype(msg));
457 msg_set_nameinst(rmsg, msg_nameinst(msg));
458 }
457 msg_set_size(rmsg, data_sz + hdr_sz); 459 msg_set_size(rmsg, data_sz + hdr_sz);
458 msg_set_nametype(rmsg, msg_nametype(msg));
459 msg_set_nameinst(rmsg, msg_nameinst(msg));
460 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); 460 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz);
461 461
462 /* send self-abort message when rejecting on a connected port */ 462 /* send self-abort message when rejecting on a connected port */
@@ -778,6 +778,7 @@ void tipc_port_reinit(void)
778 msg = &p_ptr->publ.phdr; 778 msg = &p_ptr->publ.phdr;
779 if (msg_orignode(msg) == tipc_own_addr) 779 if (msg_orignode(msg) == tipc_own_addr)
780 break; 780 break;
781 msg_set_prevnode(msg, tipc_own_addr);
781 msg_set_orignode(msg, tipc_own_addr); 782 msg_set_orignode(msg, tipc_own_addr);
782 } 783 }
783 spin_unlock_bh(&tipc_port_list_lock); 784 spin_unlock_bh(&tipc_port_list_lock);
@@ -838,16 +839,13 @@ static void port_dispatcher_sigh(void *dummy)
838 u32 peer_node = port_peernode(p_ptr); 839 u32 peer_node = port_peernode(p_ptr);
839 840
840 tipc_port_unlock(p_ptr); 841 tipc_port_unlock(p_ptr);
842 if (unlikely(!cb))
843 goto reject;
841 if (unlikely(!connected)) { 844 if (unlikely(!connected)) {
842 if (unlikely(published)) 845 if (tipc_connect2port(dref, &orig))
843 goto reject; 846 goto reject;
844 tipc_connect2port(dref,&orig); 847 } else if ((msg_origport(msg) != peer_port) ||
845 } 848 (msg_orignode(msg) != peer_node))
846 if (unlikely(msg_origport(msg) != peer_port))
847 goto reject;
848 if (unlikely(msg_orignode(msg) != peer_node))
849 goto reject;
850 if (unlikely(!cb))
851 goto reject; 849 goto reject;
852 if (unlikely(++p_ptr->publ.conn_unacked >= 850 if (unlikely(++p_ptr->publ.conn_unacked >=
853 TIPC_FLOW_CONTROL_WIN)) 851 TIPC_FLOW_CONTROL_WIN))
@@ -862,9 +860,7 @@ static void port_dispatcher_sigh(void *dummy)
862 tipc_msg_event cb = up_ptr->msg_cb; 860 tipc_msg_event cb = up_ptr->msg_cb;
863 861
864 tipc_port_unlock(p_ptr); 862 tipc_port_unlock(p_ptr);
865 if (unlikely(connected)) 863 if (unlikely(!cb || connected))
866 goto reject;
867 if (unlikely(!cb))
868 goto reject; 864 goto reject;
869 skb_pull(buf, msg_hdr_sz(msg)); 865 skb_pull(buf, msg_hdr_sz(msg));
870 cb(usr_handle, dref, &buf, msg_data(msg), 866 cb(usr_handle, dref, &buf, msg_data(msg),
@@ -877,11 +873,7 @@ static void port_dispatcher_sigh(void *dummy)
877 tipc_named_msg_event cb = up_ptr->named_msg_cb; 873 tipc_named_msg_event cb = up_ptr->named_msg_cb;
878 874
879 tipc_port_unlock(p_ptr); 875 tipc_port_unlock(p_ptr);
880 if (unlikely(connected)) 876 if (unlikely(!cb || connected || !published))
881 goto reject;
882 if (unlikely(!cb))
883 goto reject;
884 if (unlikely(!published))
885 goto reject; 877 goto reject;
886 dseq.type = msg_nametype(msg); 878 dseq.type = msg_nametype(msg);
887 dseq.lower = msg_nameinst(msg); 879 dseq.lower = msg_nameinst(msg);
@@ -908,11 +900,10 @@ err:
908 u32 peer_node = port_peernode(p_ptr); 900 u32 peer_node = port_peernode(p_ptr);
909 901
910 tipc_port_unlock(p_ptr); 902 tipc_port_unlock(p_ptr);
911 if (!connected || !cb) 903 if (!cb || !connected)
912 break;
913 if (msg_origport(msg) != peer_port)
914 break; 904 break;
915 if (msg_orignode(msg) != peer_node) 905 if ((msg_origport(msg) != peer_port) ||
906 (msg_orignode(msg) != peer_node))
916 break; 907 break;
917 tipc_disconnect(dref); 908 tipc_disconnect(dref);
918 skb_pull(buf, msg_hdr_sz(msg)); 909 skb_pull(buf, msg_hdr_sz(msg));
@@ -924,7 +915,7 @@ err:
924 tipc_msg_err_event cb = up_ptr->err_cb; 915 tipc_msg_err_event cb = up_ptr->err_cb;
925 916
926 tipc_port_unlock(p_ptr); 917 tipc_port_unlock(p_ptr);
927 if (connected || !cb) 918 if (!cb || connected)
928 break; 919 break;
929 skb_pull(buf, msg_hdr_sz(msg)); 920 skb_pull(buf, msg_hdr_sz(msg));
930 cb(usr_handle, dref, &buf, msg_data(msg), 921 cb(usr_handle, dref, &buf, msg_data(msg),
@@ -937,7 +928,7 @@ err:
937 up_ptr->named_err_cb; 928 up_ptr->named_err_cb;
938 929
939 tipc_port_unlock(p_ptr); 930 tipc_port_unlock(p_ptr);
940 if (connected || !cb) 931 if (!cb || connected)
941 break; 932 break;
942 dseq.type = msg_nametype(msg); 933 dseq.type = msg_nametype(msg);
943 dseq.lower = msg_nameinst(msg); 934 dseq.lower = msg_nameinst(msg);
@@ -1053,6 +1044,7 @@ int tipc_createport(u32 user_ref,
1053{ 1044{
1054 struct user_port *up_ptr; 1045 struct user_port *up_ptr;
1055 struct port *p_ptr; 1046 struct port *p_ptr;
1047 struct tipc_port *tp_ptr;
1056 u32 ref; 1048 u32 ref;
1057 1049
1058 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); 1050 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
@@ -1060,12 +1052,13 @@ int tipc_createport(u32 user_ref,
1060 warn("Port creation failed, no memory\n"); 1052 warn("Port creation failed, no memory\n");
1061 return -ENOMEM; 1053 return -ENOMEM;
1062 } 1054 }
1063 ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, importance); 1055 ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup,
1064 p_ptr = tipc_port_lock(ref); 1056 importance, &tp_ptr);
1065 if (!p_ptr) { 1057 if (ref == 0) {
1066 kfree(up_ptr); 1058 kfree(up_ptr);
1067 return -ENOMEM; 1059 return -ENOMEM;
1068 } 1060 }
1061 p_ptr = (struct port *)tp_ptr;
1069 1062
1070 p_ptr->user_port = up_ptr; 1063 p_ptr->user_port = up_ptr;
1071 up_ptr->user_ref = user_ref; 1064 up_ptr->user_ref = user_ref;
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 89cbab24d08f..a101de86824d 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -142,9 +142,13 @@ void tipc_ref_table_stop(void)
142/** 142/**
143 * tipc_ref_acquire - create reference to an object 143 * tipc_ref_acquire - create reference to an object
144 * 144 *
145 * Return a unique reference value which can be translated back to the pointer 145 * Register an object pointer in reference table and lock the object.
146 * 'object' at a later time. Also, pass back a pointer to the lock protecting 146 * Returns a unique reference value that is used from then on to retrieve the
147 * the object, but without locking it. 147 * object pointer, or to determine that the object has been deregistered.
148 *
149 * Note: The object is returned in the locked state so that the caller can
150 * register a partially initialized object, without running the risk that
151 * the object will be accessed before initialization is complete.
148 */ 152 */
149 153
150u32 tipc_ref_acquire(void *object, spinlock_t **lock) 154u32 tipc_ref_acquire(void *object, spinlock_t **lock)
@@ -178,13 +182,13 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
178 ref = (next_plus_upper & ~index_mask) + index; 182 ref = (next_plus_upper & ~index_mask) + index;
179 entry->ref = ref; 183 entry->ref = ref;
180 entry->object = object; 184 entry->object = object;
181 spin_unlock_bh(&entry->lock);
182 *lock = &entry->lock; 185 *lock = &entry->lock;
183 } 186 }
184 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { 187 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
185 index = tipc_ref_table.init_point++; 188 index = tipc_ref_table.init_point++;
186 entry = &(tipc_ref_table.entries[index]); 189 entry = &(tipc_ref_table.entries[index]);
187 spin_lock_init(&entry->lock); 190 spin_lock_init(&entry->lock);
191 spin_lock_bh(&entry->lock);
188 ref = tipc_ref_table.start_mask + index; 192 ref = tipc_ref_table.start_mask + index;
189 entry->ref = ref; 193 entry->ref = ref;
190 entry->object = object; 194 entry->object = object;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 230f9ca2ad6b..38f48795b40e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -188,6 +188,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
188 const struct proto_ops *ops; 188 const struct proto_ops *ops;
189 socket_state state; 189 socket_state state;
190 struct sock *sk; 190 struct sock *sk;
191 struct tipc_port *tp_ptr;
191 u32 portref; 192 u32 portref;
192 193
193 /* Validate arguments */ 194 /* Validate arguments */
@@ -225,7 +226,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
225 /* Allocate TIPC port for socket to use */ 226 /* Allocate TIPC port for socket to use */
226 227
227 portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, 228 portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch,
228 TIPC_LOW_IMPORTANCE); 229 TIPC_LOW_IMPORTANCE, &tp_ptr);
229 if (unlikely(portref == 0)) { 230 if (unlikely(portref == 0)) {
230 sk_free(sk); 231 sk_free(sk);
231 return -ENOMEM; 232 return -ENOMEM;
@@ -241,6 +242,8 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
241 sk->sk_backlog_rcv = backlog_rcv; 242 sk->sk_backlog_rcv = backlog_rcv;
242 tipc_sk(sk)->p = tipc_get_port(portref); 243 tipc_sk(sk)->p = tipc_get_port(portref);
243 244
245 spin_unlock_bh(tp_ptr->lock);
246
244 if (sock->state == SS_READY) { 247 if (sock->state == SS_READY) {
245 tipc_set_portunreturnable(portref, 1); 248 tipc_set_portunreturnable(portref, 1);
246 if (sock->type == SOCK_DGRAM) 249 if (sock->type == SOCK_DGRAM)
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 8c01ccd3626c..0326d3060bc7 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/subscr.c: TIPC subscription service 2 * net/tipc/subscr.c: TIPC network topology service
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -36,27 +36,24 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h" 38#include "dbg.h"
39#include "subscr.h"
40#include "name_table.h" 39#include "name_table.h"
40#include "port.h"
41#include "ref.h" 41#include "ref.h"
42#include "subscr.h"
42 43
43/** 44/**
44 * struct subscriber - TIPC network topology subscriber 45 * struct subscriber - TIPC network topology subscriber
45 * @ref: object reference to subscriber object itself 46 * @port_ref: object reference to server port connecting to subscriber
46 * @lock: pointer to spinlock controlling access to subscriber object 47 * @lock: pointer to spinlock controlling access to subscriber's server port
47 * @subscriber_list: adjacent subscribers in top. server's list of subscribers 48 * @subscriber_list: adjacent subscribers in top. server's list of subscribers
48 * @subscription_list: list of subscription objects for this subscriber 49 * @subscription_list: list of subscription objects for this subscriber
49 * @port_ref: object reference to port used to communicate with subscriber
50 * @swap: indicates if subscriber uses opposite endianness in its messages
51 */ 50 */
52 51
53struct subscriber { 52struct subscriber {
54 u32 ref; 53 u32 port_ref;
55 spinlock_t *lock; 54 spinlock_t *lock;
56 struct list_head subscriber_list; 55 struct list_head subscriber_list;
57 struct list_head subscription_list; 56 struct list_head subscription_list;
58 u32 port_ref;
59 int swap;
60}; 57};
61 58
62/** 59/**
@@ -88,13 +85,14 @@ static struct top_srv topsrv = { 0 };
88 85
89static u32 htohl(u32 in, int swap) 86static u32 htohl(u32 in, int swap)
90{ 87{
91 char *c = (char *)&in; 88 return swap ? (u32)___constant_swab32(in) : in;
92
93 return swap ? ((c[3] << 3) + (c[2] << 2) + (c[1] << 1) + c[0]) : in;
94} 89}
95 90
96/** 91/**
97 * subscr_send_event - send a message containing a tipc_event to the subscriber 92 * subscr_send_event - send a message containing a tipc_event to the subscriber
93 *
94 * Note: Must not hold subscriber's server port lock, since tipc_send() will
95 * try to take the lock if the message is rejected and returned!
98 */ 96 */
99 97
100static void subscr_send_event(struct subscription *sub, 98static void subscr_send_event(struct subscription *sub,
@@ -109,12 +107,12 @@ static void subscr_send_event(struct subscription *sub,
109 msg_sect.iov_base = (void *)&sub->evt; 107 msg_sect.iov_base = (void *)&sub->evt;
110 msg_sect.iov_len = sizeof(struct tipc_event); 108 msg_sect.iov_len = sizeof(struct tipc_event);
111 109
112 sub->evt.event = htohl(event, sub->owner->swap); 110 sub->evt.event = htohl(event, sub->swap);
113 sub->evt.found_lower = htohl(found_lower, sub->owner->swap); 111 sub->evt.found_lower = htohl(found_lower, sub->swap);
114 sub->evt.found_upper = htohl(found_upper, sub->owner->swap); 112 sub->evt.found_upper = htohl(found_upper, sub->swap);
115 sub->evt.port.ref = htohl(port_ref, sub->owner->swap); 113 sub->evt.port.ref = htohl(port_ref, sub->swap);
116 sub->evt.port.node = htohl(node, sub->owner->swap); 114 sub->evt.port.node = htohl(node, sub->swap);
117 tipc_send(sub->owner->port_ref, 1, &msg_sect); 115 tipc_send(sub->server_ref, 1, &msg_sect);
118} 116}
119 117
120/** 118/**
@@ -151,13 +149,12 @@ void tipc_subscr_report_overlap(struct subscription *sub,
151 u32 node, 149 u32 node,
152 int must) 150 int must)
153{ 151{
154 dbg("Rep overlap %u:%u,%u<->%u,%u\n", sub->seq.type, sub->seq.lower,
155 sub->seq.upper, found_lower, found_upper);
156 if (!tipc_subscr_overlap(sub, found_lower, found_upper)) 152 if (!tipc_subscr_overlap(sub, found_lower, found_upper))
157 return; 153 return;
158 if (!must && !(sub->filter & TIPC_SUB_PORTS)) 154 if (!must && !(sub->filter & TIPC_SUB_PORTS))
159 return; 155 return;
160 subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); 156
157 sub->event_cb(sub, found_lower, found_upper, event, port_ref, node);
161} 158}
162 159
163/** 160/**
@@ -166,20 +163,18 @@ void tipc_subscr_report_overlap(struct subscription *sub,
166 163
167static void subscr_timeout(struct subscription *sub) 164static void subscr_timeout(struct subscription *sub)
168{ 165{
169 struct subscriber *subscriber; 166 struct port *server_port;
170 u32 subscriber_ref;
171 167
172 /* Validate subscriber reference (in case subscriber is terminating) */ 168 /* Validate server port reference (in case subscriber is terminating) */
173 169
174 subscriber_ref = sub->owner->ref; 170 server_port = tipc_port_lock(sub->server_ref);
175 subscriber = (struct subscriber *)tipc_ref_lock(subscriber_ref); 171 if (server_port == NULL)
176 if (subscriber == NULL)
177 return; 172 return;
178 173
179 /* Validate timeout (in case subscription is being cancelled) */ 174 /* Validate timeout (in case subscription is being cancelled) */
180 175
181 if (sub->timeout == TIPC_WAIT_FOREVER) { 176 if (sub->timeout == TIPC_WAIT_FOREVER) {
182 tipc_ref_unlock(subscriber_ref); 177 tipc_port_unlock(server_port);
183 return; 178 return;
184 } 179 }
185 180
@@ -187,19 +182,21 @@ static void subscr_timeout(struct subscription *sub)
187 182
188 tipc_nametbl_unsubscribe(sub); 183 tipc_nametbl_unsubscribe(sub);
189 184
190 /* Notify subscriber of timeout, then unlink subscription */ 185 /* Unlink subscription from subscriber */
191 186
192 subscr_send_event(sub,
193 sub->evt.s.seq.lower,
194 sub->evt.s.seq.upper,
195 TIPC_SUBSCR_TIMEOUT,
196 0,
197 0);
198 list_del(&sub->subscription_list); 187 list_del(&sub->subscription_list);
199 188
189 /* Release subscriber's server port */
190
191 tipc_port_unlock(server_port);
192
193 /* Notify subscriber of timeout */
194
195 subscr_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
196 TIPC_SUBSCR_TIMEOUT, 0, 0);
197
200 /* Now destroy subscription */ 198 /* Now destroy subscription */
201 199
202 tipc_ref_unlock(subscriber_ref);
203 k_term_timer(&sub->timer); 200 k_term_timer(&sub->timer);
204 kfree(sub); 201 kfree(sub);
205 atomic_dec(&topsrv.subscription_count); 202 atomic_dec(&topsrv.subscription_count);
@@ -208,7 +205,7 @@ static void subscr_timeout(struct subscription *sub)
208/** 205/**
209 * subscr_del - delete a subscription within a subscription list 206 * subscr_del - delete a subscription within a subscription list
210 * 207 *
211 * Called with subscriber locked. 208 * Called with subscriber port locked.
212 */ 209 */
213 210
214static void subscr_del(struct subscription *sub) 211static void subscr_del(struct subscription *sub)
@@ -222,7 +219,7 @@ static void subscr_del(struct subscription *sub)
222/** 219/**
223 * subscr_terminate - terminate communication with a subscriber 220 * subscr_terminate - terminate communication with a subscriber
224 * 221 *
225 * Called with subscriber locked. Routine must temporarily release this lock 222 * Called with subscriber port locked. Routine must temporarily release lock
226 * to enable subscription timeout routine(s) to finish without deadlocking; 223 * to enable subscription timeout routine(s) to finish without deadlocking;
227 * the lock is then reclaimed to allow caller to release it upon return. 224 * the lock is then reclaimed to allow caller to release it upon return.
228 * (This should work even in the unlikely event some other thread creates 225 * (This should work even in the unlikely event some other thread creates
@@ -232,14 +229,21 @@ static void subscr_del(struct subscription *sub)
232 229
233static void subscr_terminate(struct subscriber *subscriber) 230static void subscr_terminate(struct subscriber *subscriber)
234{ 231{
232 u32 port_ref;
235 struct subscription *sub; 233 struct subscription *sub;
236 struct subscription *sub_temp; 234 struct subscription *sub_temp;
237 235
238 /* Invalidate subscriber reference */ 236 /* Invalidate subscriber reference */
239 237
240 tipc_ref_discard(subscriber->ref); 238 port_ref = subscriber->port_ref;
239 subscriber->port_ref = 0;
241 spin_unlock_bh(subscriber->lock); 240 spin_unlock_bh(subscriber->lock);
242 241
242 /* Sever connection to subscriber */
243
244 tipc_shutdown(port_ref);
245 tipc_deleteport(port_ref);
246
243 /* Destroy any existing subscriptions for subscriber */ 247 /* Destroy any existing subscriptions for subscriber */
244 248
245 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, 249 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
@@ -253,27 +257,25 @@ static void subscr_terminate(struct subscriber *subscriber)
253 subscr_del(sub); 257 subscr_del(sub);
254 } 258 }
255 259
256 /* Sever connection to subscriber */
257
258 tipc_shutdown(subscriber->port_ref);
259 tipc_deleteport(subscriber->port_ref);
260
261 /* Remove subscriber from topology server's subscriber list */ 260 /* Remove subscriber from topology server's subscriber list */
262 261
263 spin_lock_bh(&topsrv.lock); 262 spin_lock_bh(&topsrv.lock);
264 list_del(&subscriber->subscriber_list); 263 list_del(&subscriber->subscriber_list);
265 spin_unlock_bh(&topsrv.lock); 264 spin_unlock_bh(&topsrv.lock);
266 265
267 /* Now destroy subscriber */ 266 /* Reclaim subscriber lock */
268 267
269 spin_lock_bh(subscriber->lock); 268 spin_lock_bh(subscriber->lock);
269
270 /* Now destroy subscriber */
271
270 kfree(subscriber); 272 kfree(subscriber);
271} 273}
272 274
273/** 275/**
274 * subscr_cancel - handle subscription cancellation request 276 * subscr_cancel - handle subscription cancellation request
275 * 277 *
276 * Called with subscriber locked. Routine must temporarily release this lock 278 * Called with subscriber port locked. Routine must temporarily release lock
277 * to enable the subscription timeout routine to finish without deadlocking; 279 * to enable the subscription timeout routine to finish without deadlocking;
278 * the lock is then reclaimed to allow caller to release it upon return. 280 * the lock is then reclaimed to allow caller to release it upon return.
279 * 281 *
@@ -316,27 +318,25 @@ static void subscr_cancel(struct tipc_subscr *s,
316/** 318/**
317 * subscr_subscribe - create subscription for subscriber 319 * subscr_subscribe - create subscription for subscriber
318 * 320 *
319 * Called with subscriber locked 321 * Called with subscriber port locked.
320 */ 322 */
321 323
322static void subscr_subscribe(struct tipc_subscr *s, 324static struct subscription *subscr_subscribe(struct tipc_subscr *s,
323 struct subscriber *subscriber) 325 struct subscriber *subscriber)
324{ 326{
325 struct subscription *sub; 327 struct subscription *sub;
328 int swap;
326 329
327 /* Determine/update subscriber's endianness */ 330 /* Determine subscriber's endianness */
328 331
329 if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)) 332 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
330 subscriber->swap = 0;
331 else
332 subscriber->swap = 1;
333 333
334 /* Detect & process a subscription cancellation request */ 334 /* Detect & process a subscription cancellation request */
335 335
336 if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) { 336 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
337 s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap); 337 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
338 subscr_cancel(s, subscriber); 338 subscr_cancel(s, subscriber);
339 return; 339 return NULL;
340 } 340 }
341 341
342 /* Refuse subscription if global limit exceeded */ 342 /* Refuse subscription if global limit exceeded */
@@ -345,63 +345,66 @@ static void subscr_subscribe(struct tipc_subscr *s,
345 warn("Subscription rejected, subscription limit reached (%u)\n", 345 warn("Subscription rejected, subscription limit reached (%u)\n",
346 tipc_max_subscriptions); 346 tipc_max_subscriptions);
347 subscr_terminate(subscriber); 347 subscr_terminate(subscriber);
348 return; 348 return NULL;
349 } 349 }
350 350
351 /* Allocate subscription object */ 351 /* Allocate subscription object */
352 352
353 sub = kzalloc(sizeof(*sub), GFP_ATOMIC); 353 sub = kmalloc(sizeof(*sub), GFP_ATOMIC);
354 if (!sub) { 354 if (!sub) {
355 warn("Subscription rejected, no memory\n"); 355 warn("Subscription rejected, no memory\n");
356 subscr_terminate(subscriber); 356 subscr_terminate(subscriber);
357 return; 357 return NULL;
358 } 358 }
359 359
360 /* Initialize subscription object */ 360 /* Initialize subscription object */
361 361
362 sub->seq.type = htohl(s->seq.type, subscriber->swap); 362 sub->seq.type = htohl(s->seq.type, swap);
363 sub->seq.lower = htohl(s->seq.lower, subscriber->swap); 363 sub->seq.lower = htohl(s->seq.lower, swap);
364 sub->seq.upper = htohl(s->seq.upper, subscriber->swap); 364 sub->seq.upper = htohl(s->seq.upper, swap);
365 sub->timeout = htohl(s->timeout, subscriber->swap); 365 sub->timeout = htohl(s->timeout, swap);
366 sub->filter = htohl(s->filter, subscriber->swap); 366 sub->filter = htohl(s->filter, swap);
367 if ((!(sub->filter & TIPC_SUB_PORTS) 367 if ((!(sub->filter & TIPC_SUB_PORTS)
368 == !(sub->filter & TIPC_SUB_SERVICE)) 368 == !(sub->filter & TIPC_SUB_SERVICE))
369 || (sub->seq.lower > sub->seq.upper)) { 369 || (sub->seq.lower > sub->seq.upper)) {
370 warn("Subscription rejected, illegal request\n"); 370 warn("Subscription rejected, illegal request\n");
371 kfree(sub); 371 kfree(sub);
372 subscr_terminate(subscriber); 372 subscr_terminate(subscriber);
373 return; 373 return NULL;
374 } 374 }
375 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); 375 sub->event_cb = subscr_send_event;
376 INIT_LIST_HEAD(&sub->subscription_list);
377 INIT_LIST_HEAD(&sub->nameseq_list); 376 INIT_LIST_HEAD(&sub->nameseq_list);
378 list_add(&sub->subscription_list, &subscriber->subscription_list); 377 list_add(&sub->subscription_list, &subscriber->subscription_list);
378 sub->server_ref = subscriber->port_ref;
379 sub->swap = swap;
380 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
379 atomic_inc(&topsrv.subscription_count); 381 atomic_inc(&topsrv.subscription_count);
380 if (sub->timeout != TIPC_WAIT_FOREVER) { 382 if (sub->timeout != TIPC_WAIT_FOREVER) {
381 k_init_timer(&sub->timer, 383 k_init_timer(&sub->timer,
382 (Handler)subscr_timeout, (unsigned long)sub); 384 (Handler)subscr_timeout, (unsigned long)sub);
383 k_start_timer(&sub->timer, sub->timeout); 385 k_start_timer(&sub->timer, sub->timeout);
384 } 386 }
385 sub->owner = subscriber; 387
386 tipc_nametbl_subscribe(sub); 388 return sub;
387} 389}
388 390
389/** 391/**
390 * subscr_conn_shutdown_event - handle termination request from subscriber 392 * subscr_conn_shutdown_event - handle termination request from subscriber
393 *
394 * Called with subscriber's server port unlocked.
391 */ 395 */
392 396
393static void subscr_conn_shutdown_event(void *usr_handle, 397static void subscr_conn_shutdown_event(void *usr_handle,
394 u32 portref, 398 u32 port_ref,
395 struct sk_buff **buf, 399 struct sk_buff **buf,
396 unsigned char const *data, 400 unsigned char const *data,
397 unsigned int size, 401 unsigned int size,
398 int reason) 402 int reason)
399{ 403{
400 struct subscriber *subscriber; 404 struct subscriber *subscriber = usr_handle;
401 spinlock_t *subscriber_lock; 405 spinlock_t *subscriber_lock;
402 406
403 subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle); 407 if (tipc_port_lock(port_ref) == NULL)
404 if (subscriber == NULL)
405 return; 408 return;
406 409
407 subscriber_lock = subscriber->lock; 410 subscriber_lock = subscriber->lock;
@@ -411,6 +414,8 @@ static void subscr_conn_shutdown_event(void *usr_handle,
411 414
412/** 415/**
413 * subscr_conn_msg_event - handle new subscription request from subscriber 416 * subscr_conn_msg_event - handle new subscription request from subscriber
417 *
418 * Called with subscriber's server port unlocked.
414 */ 419 */
415 420
416static void subscr_conn_msg_event(void *usr_handle, 421static void subscr_conn_msg_event(void *usr_handle,
@@ -419,20 +424,46 @@ static void subscr_conn_msg_event(void *usr_handle,
419 const unchar *data, 424 const unchar *data,
420 u32 size) 425 u32 size)
421{ 426{
422 struct subscriber *subscriber; 427 struct subscriber *subscriber = usr_handle;
423 spinlock_t *subscriber_lock; 428 spinlock_t *subscriber_lock;
429 struct subscription *sub;
430
431 /*
432 * Lock subscriber's server port (& make a local copy of lock pointer,
433 * in case subscriber is deleted while processing subscription request)
434 */
424 435
425 subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle); 436 if (tipc_port_lock(port_ref) == NULL)
426 if (subscriber == NULL)
427 return; 437 return;
428 438
429 subscriber_lock = subscriber->lock; 439 subscriber_lock = subscriber->lock;
430 if (size != sizeof(struct tipc_subscr))
431 subscr_terminate(subscriber);
432 else
433 subscr_subscribe((struct tipc_subscr *)data, subscriber);
434 440
435 spin_unlock_bh(subscriber_lock); 441 if (size != sizeof(struct tipc_subscr)) {
442 subscr_terminate(subscriber);
443 spin_unlock_bh(subscriber_lock);
444 } else {
445 sub = subscr_subscribe((struct tipc_subscr *)data, subscriber);
446 spin_unlock_bh(subscriber_lock);
447 if (sub != NULL) {
448
449 /*
450 * We must release the server port lock before adding a
451 * subscription to the name table since TIPC needs to be
452 * able to (re)acquire the port lock if an event message
453 * issued by the subscription process is rejected and
454 * returned. The subscription cannot be deleted while
455 * it is being added to the name table because:
456 * a) the single-threading of the native API port code
457 * ensures the subscription cannot be cancelled and
458 * the subscriber connection cannot be broken, and
459 * b) the name table lock ensures the subscription
460 * timeout code cannot delete the subscription,
461 * so the subscription object is still protected.
462 */
463
464 tipc_nametbl_subscribe(sub);
465 }
466 }
436} 467}
437 468
438/** 469/**
@@ -448,16 +479,10 @@ static void subscr_named_msg_event(void *usr_handle,
448 struct tipc_portid const *orig, 479 struct tipc_portid const *orig,
449 struct tipc_name_seq const *dest) 480 struct tipc_name_seq const *dest)
450{ 481{
451 struct subscriber *subscriber; 482 static struct iovec msg_sect = {NULL, 0};
452 struct iovec msg_sect = {NULL, 0};
453 spinlock_t *subscriber_lock;
454 483
455 dbg("subscr_named_msg_event: orig = %x own = %x,\n", 484 struct subscriber *subscriber;
456 orig->node, tipc_own_addr); 485 u32 server_port_ref;
457 if (size && (size != sizeof(struct tipc_subscr))) {
458 warn("Subscriber rejected, invalid subscription size\n");
459 return;
460 }
461 486
462 /* Create subscriber object */ 487 /* Create subscriber object */
463 488
@@ -468,17 +493,11 @@ static void subscr_named_msg_event(void *usr_handle,
468 } 493 }
469 INIT_LIST_HEAD(&subscriber->subscription_list); 494 INIT_LIST_HEAD(&subscriber->subscription_list);
470 INIT_LIST_HEAD(&subscriber->subscriber_list); 495 INIT_LIST_HEAD(&subscriber->subscriber_list);
471 subscriber->ref = tipc_ref_acquire(subscriber, &subscriber->lock);
472 if (subscriber->ref == 0) {
473 warn("Subscriber rejected, reference table exhausted\n");
474 kfree(subscriber);
475 return;
476 }
477 496
478 /* Establish a connection to subscriber */ 497 /* Create server port & establish connection to subscriber */
479 498
480 tipc_createport(topsrv.user_ref, 499 tipc_createport(topsrv.user_ref,
481 (void *)(unsigned long)subscriber->ref, 500 subscriber,
482 importance, 501 importance,
483 NULL, 502 NULL,
484 NULL, 503 NULL,
@@ -490,32 +509,36 @@ static void subscr_named_msg_event(void *usr_handle,
490 &subscriber->port_ref); 509 &subscriber->port_ref);
491 if (subscriber->port_ref == 0) { 510 if (subscriber->port_ref == 0) {
492 warn("Subscriber rejected, unable to create port\n"); 511 warn("Subscriber rejected, unable to create port\n");
493 tipc_ref_discard(subscriber->ref);
494 kfree(subscriber); 512 kfree(subscriber);
495 return; 513 return;
496 } 514 }
497 tipc_connect2port(subscriber->port_ref, orig); 515 tipc_connect2port(subscriber->port_ref, orig);
498 516
517 /* Lock server port (& save lock address for future use) */
518
519 subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock;
499 520
500 /* Add subscriber to topology server's subscriber list */ 521 /* Add subscriber to topology server's subscriber list */
501 522
502 tipc_ref_lock(subscriber->ref);
503 spin_lock_bh(&topsrv.lock); 523 spin_lock_bh(&topsrv.lock);
504 list_add(&subscriber->subscriber_list, &topsrv.subscriber_list); 524 list_add(&subscriber->subscriber_list, &topsrv.subscriber_list);
505 spin_unlock_bh(&topsrv.lock); 525 spin_unlock_bh(&topsrv.lock);
506 526
507 /* 527 /* Unlock server port */
508 * Subscribe now if message contains a subscription,
509 * otherwise send an empty response to complete connection handshaking
510 */
511 528
512 subscriber_lock = subscriber->lock; 529 server_port_ref = subscriber->port_ref;
513 if (size) 530 spin_unlock_bh(subscriber->lock);
514 subscr_subscribe((struct tipc_subscr *)data, subscriber);
515 else
516 tipc_send(subscriber->port_ref, 1, &msg_sect);
517 531
518 spin_unlock_bh(subscriber_lock); 532 /* Send an ACK- to complete connection handshaking */
533
534 tipc_send(server_port_ref, 1, &msg_sect);
535
536 /* Handle optional subscription request */
537
538 if (size != 0) {
539 subscr_conn_msg_event(subscriber, server_port_ref,
540 buf, data, size);
541 }
519} 542}
520 543
521int tipc_subscr_start(void) 544int tipc_subscr_start(void)
@@ -574,8 +597,8 @@ void tipc_subscr_stop(void)
574 list_for_each_entry_safe(subscriber, subscriber_temp, 597 list_for_each_entry_safe(subscriber, subscriber_temp,
575 &topsrv.subscriber_list, 598 &topsrv.subscriber_list,
576 subscriber_list) { 599 subscriber_list) {
577 tipc_ref_lock(subscriber->ref);
578 subscriber_lock = subscriber->lock; 600 subscriber_lock = subscriber->lock;
601 spin_lock_bh(subscriber_lock);
579 subscr_terminate(subscriber); 602 subscr_terminate(subscriber);
580 spin_unlock_bh(subscriber_lock); 603 spin_unlock_bh(subscriber_lock);
581 } 604 }
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 93a8e674fac1..45d89bf4d202 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/subscr.h: Include file for TIPC subscription service 2 * net/tipc/subscr.h: Include file for TIPC network topology service
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,34 +37,44 @@
37#ifndef _TIPC_SUBSCR_H 37#ifndef _TIPC_SUBSCR_H
38#define _TIPC_SUBSCR_H 38#define _TIPC_SUBSCR_H
39 39
40struct subscription;
41
42typedef void (*tipc_subscr_event) (struct subscription *sub,
43 u32 found_lower, u32 found_upper,
44 u32 event, u32 port_ref, u32 node);
45
40/** 46/**
41 * struct subscription - TIPC network topology subscription object 47 * struct subscription - TIPC network topology subscription object
42 * @seq: name sequence associated with subscription 48 * @seq: name sequence associated with subscription
43 * @timeout: duration of subscription (in ms) 49 * @timeout: duration of subscription (in ms)
44 * @filter: event filtering to be done for subscription 50 * @filter: event filtering to be done for subscription
45 * @evt: template for events generated by subscription 51 * @event_cb: routine invoked when a subscription event is detected
46 * @subscription_list: adjacent subscriptions in subscriber's subscription list 52 * @timer: timer governing subscription duration (optional)
47 * @nameseq_list: adjacent subscriptions in name sequence's subscription list 53 * @nameseq_list: adjacent subscriptions in name sequence's subscription list
48 * @timer_ref: reference to timer governing subscription duration (may be NULL) 54 * @subscription_list: adjacent subscriptions in subscriber's subscription list
49 * @owner: pointer to subscriber object associated with this subscription 55 * @server_ref: object reference of server port associated with subscription
56 * @swap: indicates if subscriber uses opposite endianness in its messages
57 * @evt: template for events generated by subscription
50 */ 58 */
51 59
52struct subscription { 60struct subscription {
53 struct tipc_name_seq seq; 61 struct tipc_name_seq seq;
54 u32 timeout; 62 u32 timeout;
55 u32 filter; 63 u32 filter;
56 struct tipc_event evt; 64 tipc_subscr_event event_cb;
57 struct list_head subscription_list;
58 struct list_head nameseq_list;
59 struct timer_list timer; 65 struct timer_list timer;
60 struct subscriber *owner; 66 struct list_head nameseq_list;
67 struct list_head subscription_list;
68 u32 server_ref;
69 int swap;
70 struct tipc_event evt;
61}; 71};
62 72
63int tipc_subscr_overlap(struct subscription * sub, 73int tipc_subscr_overlap(struct subscription *sub,
64 u32 found_lower, 74 u32 found_lower,
65 u32 found_upper); 75 u32 found_upper);
66 76
67void tipc_subscr_report_overlap(struct subscription * sub, 77void tipc_subscr_report_overlap(struct subscription *sub,
68 u32 found_lower, 78 u32 found_lower,
69 u32 found_upper, 79 u32 found_upper,
70 u32 event, 80 u32 event,
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e18cd3628db4..392e80e3268d 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -8,8 +8,6 @@
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 * 10 *
11 * Version: $Id: af_unix.c,v 1.133 2002/02/08 03:57:19 davem Exp $
12 *
13 * Fixes: 11 * Fixes:
14 * Linus Torvalds : Assorted bug cures. 12 * Linus Torvalds : Assorted bug cures.
15 * Niibe Yutaka : async I/O support. 13 * Niibe Yutaka : async I/O support.
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index 9ab31a3ce3ad..b210a88d0960 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -350,9 +350,9 @@ __be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
350 * o execute requested action or pass command to the device driver 350 * o execute requested action or pass command to the device driver
351 */ 351 */
352 352
353int wanrouter_ioctl(struct inode *inode, struct file *file, 353long wanrouter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
354 unsigned int cmd, unsigned long arg)
355{ 354{
355 struct inode *inode = file->f_path.dentry->d_inode;
356 int err = 0; 356 int err = 0;
357 struct proc_dir_entry *dent; 357 struct proc_dir_entry *dent;
358 struct wan_device *wandev; 358 struct wan_device *wandev;
@@ -372,6 +372,7 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
372 if (wandev->magic != ROUTER_MAGIC) 372 if (wandev->magic != ROUTER_MAGIC)
373 return -EINVAL; 373 return -EINVAL;
374 374
375 lock_kernel();
375 switch (cmd) { 376 switch (cmd) {
376 case ROUTER_SETUP: 377 case ROUTER_SETUP:
377 err = wanrouter_device_setup(wandev, data); 378 err = wanrouter_device_setup(wandev, data);
@@ -403,6 +404,7 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
403 err = wandev->ioctl(wandev, cmd, arg); 404 err = wandev->ioctl(wandev, cmd, arg);
404 else err = -EINVAL; 405 else err = -EINVAL;
405 } 406 }
407 unlock_kernel();
406 return err; 408 return err;
407} 409}
408 410
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
index 5bebe40bf4e6..267f7ff49827 100644
--- a/net/wanrouter/wanproc.c
+++ b/net/wanrouter/wanproc.c
@@ -278,7 +278,7 @@ static const struct file_operations wandev_fops = {
278 .read = seq_read, 278 .read = seq_read,
279 .llseek = seq_lseek, 279 .llseek = seq_lseek,
280 .release = single_release, 280 .release = single_release,
281 .ioctl = wanrouter_ioctl, 281 .unlocked_ioctl = wanrouter_ioctl,
282}; 282};
283 283
284/* 284/*
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 80afacdae46c..f1da0b93bc56 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -143,8 +143,11 @@ void cfg80211_put_dev(struct cfg80211_registered_device *drv)
143int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 143int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
144 char *newname) 144 char *newname)
145{ 145{
146 struct cfg80211_registered_device *drv;
146 int idx, taken = -1, result, digits; 147 int idx, taken = -1, result, digits;
147 148
149 mutex_lock(&cfg80211_drv_mutex);
150
148 /* prohibit calling the thing phy%d when %d is not its number */ 151 /* prohibit calling the thing phy%d when %d is not its number */
149 sscanf(newname, PHY_NAME "%d%n", &idx, &taken); 152 sscanf(newname, PHY_NAME "%d%n", &idx, &taken);
150 if (taken == strlen(newname) && idx != rdev->idx) { 153 if (taken == strlen(newname) && idx != rdev->idx) {
@@ -156,14 +159,30 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
156 * deny the name if it is phy<idx> where <idx> is printed 159 * deny the name if it is phy<idx> where <idx> is printed
157 * without leading zeroes. taken == strlen(newname) here 160 * without leading zeroes. taken == strlen(newname) here
158 */ 161 */
162 result = -EINVAL;
159 if (taken == strlen(PHY_NAME) + digits) 163 if (taken == strlen(PHY_NAME) + digits)
160 return -EINVAL; 164 goto out_unlock;
165 }
166
167
168 /* Ignore nop renames */
169 result = 0;
170 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
171 goto out_unlock;
172
173 /* Ensure another device does not already have this name. */
174 list_for_each_entry(drv, &cfg80211_drv_list, list) {
175 result = -EINVAL;
176 if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0)
177 goto out_unlock;
161 } 178 }
162 179
163 /* this will check for collisions */ 180 /* this will only check for collisions in sysfs
181 * which is not even always compiled in.
182 */
164 result = device_rename(&rdev->wiphy.dev, newname); 183 result = device_rename(&rdev->wiphy.dev, newname);
165 if (result) 184 if (result)
166 return result; 185 goto out_unlock;
167 186
168 if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, 187 if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
169 rdev->wiphy.debugfsdir, 188 rdev->wiphy.debugfsdir,
@@ -172,9 +191,13 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
172 printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", 191 printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n",
173 newname); 192 newname);
174 193
175 nl80211_notify_dev_rename(rdev); 194 result = 0;
195out_unlock:
196 mutex_unlock(&cfg80211_drv_mutex);
197 if (result == 0)
198 nl80211_notify_dev_rename(rdev);
176 199
177 return 0; 200 return result;
178} 201}
179 202
180/* exported functions */ 203/* exported functions */
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index 28fbd0b0b568..f591871a7b4f 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -59,23 +59,21 @@ int ieee80211_radiotap_iterator_init(
59 return -EINVAL; 59 return -EINVAL;
60 60
61 /* sanity check for allowed length and radiotap length field */ 61 /* sanity check for allowed length and radiotap length field */
62 if (max_length < le16_to_cpu(get_unaligned(&radiotap_header->it_len))) 62 if (max_length < get_unaligned_le16(&radiotap_header->it_len))
63 return -EINVAL; 63 return -EINVAL;
64 64
65 iterator->rtheader = radiotap_header; 65 iterator->rtheader = radiotap_header;
66 iterator->max_length = le16_to_cpu(get_unaligned( 66 iterator->max_length = get_unaligned_le16(&radiotap_header->it_len);
67 &radiotap_header->it_len));
68 iterator->arg_index = 0; 67 iterator->arg_index = 0;
69 iterator->bitmap_shifter = le32_to_cpu(get_unaligned( 68 iterator->bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present);
70 &radiotap_header->it_present));
71 iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header); 69 iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);
72 iterator->this_arg = NULL; 70 iterator->this_arg = NULL;
73 71
74 /* find payload start allowing for extended bitmap(s) */ 72 /* find payload start allowing for extended bitmap(s) */
75 73
76 if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) { 74 if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {
77 while (le32_to_cpu(get_unaligned((__le32 *)iterator->arg)) & 75 while (get_unaligned_le32(iterator->arg) &
78 (1<<IEEE80211_RADIOTAP_EXT)) { 76 (1 << IEEE80211_RADIOTAP_EXT)) {
79 iterator->arg += sizeof(u32); 77 iterator->arg += sizeof(u32);
80 78
81 /* 79 /*
@@ -241,8 +239,8 @@ int ieee80211_radiotap_iterator_next(
241 if (iterator->bitmap_shifter & 1) { 239 if (iterator->bitmap_shifter & 1) {
242 /* b31 was set, there is more */ 240 /* b31 was set, there is more */
243 /* move to next u32 bitmap */ 241 /* move to next u32 bitmap */
244 iterator->bitmap_shifter = le32_to_cpu( 242 iterator->bitmap_shifter =
245 get_unaligned(iterator->next_bitmap)); 243 get_unaligned_le32(iterator->next_bitmap);
246 iterator->next_bitmap++; 244 iterator->next_bitmap++;
247 } else 245 } else
248 /* no more bitmaps: end */ 246 /* no more bitmaps: end */