summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/8021q/vlanproc.c7
-rw-r--r--net/9p/Kconfig10
-rw-r--r--net/9p/Makefile3
-rw-r--r--net/9p/client.c32
-rw-r--r--net/9p/conv.c128
-rw-r--r--net/9p/error.c15
-rw-r--r--net/9p/fcprint.c8
-rw-r--r--net/9p/mod.c8
-rw-r--r--net/9p/trans_fd.c204
-rw-r--r--net/9p/trans_virtio.c175
-rw-r--r--net/9p/util.c36
-rw-r--r--net/atm/br2684.c4
-rw-r--r--net/atm/proc.c6
-rw-r--r--net/bluetooth/bnep/core.c8
-rw-r--r--net/bluetooth/hci_event.c9
-rw-r--r--net/bluetooth/hci_sock.c2
-rw-r--r--net/bluetooth/l2cap.c2
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/bridge/br_fdb.c4
-rw-r--r--net/bridge/br_if.c17
-rw-r--r--net/bridge/br_stp_bpdu.c4
-rw-r--r--net/can/af_can.c16
-rw-r--r--net/can/bcm.c6
-rw-r--r--net/compat.c90
-rw-r--r--net/core/dev.c33
-rw-r--r--net/core/filter.c4
-rw-r--r--net/core/neighbour.c5
-rw-r--r--net/core/net-sysfs.c7
-rw-r--r--net/core/net-sysfs.h2
-rw-r--r--net/core/netpoll.c2
-rw-r--r--net/core/pktgen.c12
-rw-r--r--net/core/skbuff.c4
-rw-r--r--net/core/sock.c5
-rw-r--r--net/dccp/ccids/ccid2.c2
-rw-r--r--net/dccp/ccids/ccid3.c4
-rw-r--r--net/dccp/feat.c2
-rw-r--r--net/decnet/dn_route.c12
-rw-r--r--net/econet/af_econet.c2
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/arp.c2
-rw-r--r--net/ipv4/cipso_ipv4.c22
-rw-r--r--net/ipv4/icmp.c3
-rw-r--r--net/ipv4/igmp.c4
-rw-r--r--net/ipv4/ip_input.c2
-rw-r--r--net/ipv4/ip_output.c22
-rw-r--r--net/ipv4/ip_sockglue.c9
-rw-r--r--net/ipv4/ipconfig.c14
-rw-r--r--net/ipv4/ipvs/ip_vs_proto.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_ah.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_esp.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_tcp.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c80
-rw-r--r--net/ipv4/netfilter/ip_queue.c5
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c2
-rw-r--r--net/ipv4/raw.c10
-rw-r--r--net/ipv4/route.c56
-rw-r--r--net/ipv4/tcp_cong.c12
-rw-r--r--net/ipv4/tcp_cubic.c4
-rw-r--r--net/ipv4/tcp_hybla.c6
-rw-r--r--net/ipv4/tcp_input.c63
-rw-r--r--net/ipv4/tcp_ipv4.c10
-rw-r--r--net/ipv4/tcp_vegas.c16
-rw-r--r--net/ipv4/tcp_veno.c14
-rw-r--r--net/ipv4/udp.c7
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ipv6_sockglue.c4
-rw-r--r--net/ipv6/mcast.c4
-rw-r--r--net/ipv6/ndisc.c4
-rw-r--r--net/ipv6/netfilter/ip6_queue.c5
-rw-r--r--net/ipv6/proc.c6
-rw-r--r--net/ipv6/raw.c10
-rw-r--r--net/ipv6/reassembly.c4
-rw-r--r--net/ipv6/route.c6
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/irda/discovery.c8
-rw-r--r--net/irda/ircomm/ircomm_tty.c6
-rw-r--r--net/irda/iriap.c8
-rw-r--r--net/irda/irlmp.c5
-rw-r--r--net/irda/irnet/irnet_irda.c70
-rw-r--r--net/irda/irnet/irnet_irda.h8
-rw-r--r--net/key/af_key.c17
-rw-r--r--net/mac80211/debugfs_key.c15
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/iface.c9
-rw-r--r--net/mac80211/main.c54
-rw-r--r--net/mac80211/mesh.c19
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_hwmp.c2
-rw-r--r--net/mac80211/mesh_pathtbl.c17
-rw-r--r--net/mac80211/mlme.c64
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c4
-rw-r--r--net/mac80211/rx.c12
-rw-r--r--net/mac80211/tkip.c6
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/util.c10
-rw-r--r--net/mac80211/wme.c3
-rw-r--r--net/netfilter/Kconfig4
-rw-r--r--net/netfilter/nf_conntrack_core.c4
-rw-r--r--net/netfilter/nf_conntrack_netlink.c3
-rw-r--r--net/netfilter/nf_conntrack_sip.c22
-rw-r--r--net/netfilter/nf_conntrack_standalone.c6
-rw-r--r--net/netfilter/nf_queue.c2
-rw-r--r--net/netfilter/nfnetlink_queue.c5
-rw-r--r--net/netfilter/x_tables.c15
-rw-r--r--net/netfilter/xt_TCPOPTSTRIP.c2
-rw-r--r--net/netfilter/xt_connbytes.c5
-rw-r--r--net/netfilter/xt_hashlimit.c12
-rw-r--r--net/netfilter/xt_iprange.c2
-rw-r--r--net/netlabel/netlabel_unlabeled.c1
-rw-r--r--net/netlabel/netlabel_user.c4
-rw-r--r--net/netlabel/netlabel_user.h1
-rw-r--r--net/netlink/af_netlink.c1
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/rose/rose_route.c8
-rw-r--r--net/rxrpc/ar-transport.c3
-rw-r--r--net/sched/act_simple.c45
-rw-r--r--net/sched/sch_generic.c1
-rw-r--r--net/sched/sch_htb.c8
-rw-r--r--net/sched/sch_sfq.c3
-rw-r--r--net/sctp/sm_make_chunk.c16
-rw-r--r--net/sunrpc/cache.c15
-rw-r--r--net/sunrpc/stats.c8
-rw-r--r--net/sunrpc/svc.c1
-rw-r--r--net/sysctl_net.c2
-rw-r--r--net/tipc/core.h11
-rw-r--r--net/xfrm/xfrm_output.c8
-rw-r--r--net/xfrm/xfrm_policy.c12
-rw-r--r--net/xfrm/xfrm_state.c13
-rw-r--r--net/xfrm/xfrm_user.c41
131 files changed, 1331 insertions, 617 deletions
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index daad0064e2c2..08b54b593d56 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -176,12 +176,11 @@ int vlan_proc_add_dev(struct net_device *vlandev)
struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id);
- dev_info->dent = proc_create(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR,
- vn->proc_vlan_dir, &vlandev_fops);
+ dev_info->dent =
+ proc_create_data(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR,
+ vn->proc_vlan_dir, &vlandev_fops, vlandev);
if (!dev_info->dent)
return -ENOBUFS;
-
- dev_info->dent->data = vlandev;
return 0;
}
diff --git a/net/9p/Kconfig b/net/9p/Kconfig
index bafc50c9e6ff..ff34c5acc130 100644
--- a/net/9p/Kconfig
+++ b/net/9p/Kconfig
@@ -13,16 +13,6 @@ menuconfig NET_9P
If unsure, say N.
-config NET_9P_FD
- depends on NET_9P
- default y if NET_9P
- tristate "9P File Descriptor Transports (Experimental)"
- help
- This builds support for file descriptor transports for 9p
- which includes support for TCP/IP, named pipes, or passed
- file descriptors. TCP/IP is the default transport for 9p,
- so if you are going to use 9p, you'll likely want this.
-
config NET_9P_VIRTIO
depends on NET_9P && EXPERIMENTAL && VIRTIO
tristate "9P Virtio Transport (Experimental)"
diff --git a/net/9p/Makefile b/net/9p/Makefile
index 8a1051101898..519219480db1 100644
--- a/net/9p/Makefile
+++ b/net/9p/Makefile
@@ -1,5 +1,4 @@
obj-$(CONFIG_NET_9P) := 9pnet.o
-obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
9pnet-objs := \
@@ -9,8 +8,6 @@ obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
error.o \
fcprint.o \
util.o \
-
-9pnet_fd-objs := \
trans_fd.o \
9pnet_virtio-objs := \
diff --git a/net/9p/client.c b/net/9p/client.c
index 84e087e24146..2ffe40cf2f01 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -64,21 +64,30 @@ static match_table_t tokens = {
* @options: options string passed from mount
* @v9ses: existing v9fs session information
*
+ * Return 0 upon success, -ERRNO upon failure
*/
-static void parse_opts(char *options, struct p9_client *clnt)
+static int parse_opts(char *opts, struct p9_client *clnt)
{
+ char *options;
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
- int ret;
+ int ret = 0;
clnt->trans_mod = v9fs_default_trans();
clnt->dotu = 1;
clnt->msize = 8192;
- if (!options)
- return;
+ if (!opts)
+ return 0;
+
+ options = kstrdup(opts, GFP_KERNEL);
+ if (!options) {
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "failed to allocate copy of option string\n");
+ return -ENOMEM;
+ }
while ((p = strsep(&options, ",")) != NULL) {
int token;
@@ -86,10 +95,11 @@ static void parse_opts(char *options, struct p9_client *clnt)
continue;
token = match_token(p, tokens, args);
if (token < Opt_trans) {
- ret = match_int(&args[0], &option);
- if (ret < 0) {
+ int r = match_int(&args[0], &option);
+ if (r < 0) {
P9_DPRINTK(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
+ ret = r;
continue;
}
}
@@ -107,6 +117,8 @@ static void parse_opts(char *options, struct p9_client *clnt)
continue;
}
}
+ kfree(options);
+ return ret;
}
@@ -138,16 +150,20 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
if (!clnt)
return ERR_PTR(-ENOMEM);
+ clnt->trans = NULL;
spin_lock_init(&clnt->lock);
INIT_LIST_HEAD(&clnt->fidlist);
clnt->fidpool = p9_idpool_create();
- if (!clnt->fidpool) {
+ if (IS_ERR(clnt->fidpool)) {
err = PTR_ERR(clnt->fidpool);
clnt->fidpool = NULL;
goto error;
}
- parse_opts(options, clnt);
+ err = parse_opts(options, clnt);
+ if (err < 0)
+ goto error;
+
if (clnt->trans_mod == NULL) {
err = -EPROTONOSUPPORT;
P9_DPRINTK(P9_DEBUG_ERROR,
diff --git a/net/9p/conv.c b/net/9p/conv.c
index 3fe35d532c87..44547201f5bc 100644
--- a/net/9p/conv.c
+++ b/net/9p/conv.c
@@ -197,7 +197,7 @@ static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid)
/**
* p9_size_wstat - calculate the size of a variable length stat struct
- * @stat: metadata (stat) structure
+ * @wstat: metadata (stat) structure
* @dotu: non-zero if 9P2000.u
*
*/
@@ -511,6 +511,12 @@ p9_create_common(struct cbuf *bufp, u32 size, u8 id)
return fc;
}
+/**
+ * p9_set_tag - set the tag field of an &p9_fcall structure
+ * @fc: fcall structure to set tag within
+ * @tag: tag id to set
+ */
+
void p9_set_tag(struct p9_fcall *fc, u16 tag)
{
fc->tag = tag;
@@ -518,6 +524,12 @@ void p9_set_tag(struct p9_fcall *fc, u16 tag)
}
EXPORT_SYMBOL(p9_set_tag);
+/**
+ * p9_create_tversion - allocates and creates a T_VERSION request
+ * @msize: requested maximum data size
+ * @version: version string to negotiate
+ *
+ */
struct p9_fcall *p9_create_tversion(u32 msize, char *version)
{
int size;
@@ -542,6 +554,16 @@ error:
}
EXPORT_SYMBOL(p9_create_tversion);
+/**
+ * p9_create_tauth - allocates and creates a T_AUTH request
+ * @afid: handle to use for authentication protocol
+ * @uname: user name attempting to authenticate
+ * @aname: mount specifier for remote server
+ * @n_uname: numeric id for user attempting to authneticate
+ * @dotu: 9P2000.u extension flag
+ *
+ */
+
struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
u32 n_uname, int dotu)
{
@@ -580,6 +602,18 @@ error:
}
EXPORT_SYMBOL(p9_create_tauth);
+/**
+ * p9_create_tattach - allocates and creates a T_ATTACH request
+ * @fid: handle to use for the new mount point
+ * @afid: handle to use for authentication protocol
+ * @uname: user name attempting to attach
+ * @aname: mount specifier for remote server
+ * @n_uname: numeric id for user attempting to attach
+ * @n_uname: numeric id for user attempting to attach
+ * @dotu: 9P2000.u extension flag
+ *
+ */
+
struct p9_fcall *
p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname,
u32 n_uname, int dotu)
@@ -616,6 +650,12 @@ error:
}
EXPORT_SYMBOL(p9_create_tattach);
+/**
+ * p9_create_tflush - allocates and creates a T_FLUSH request
+ * @oldtag: tag id for the transaction we are attempting to cancel
+ *
+ */
+
struct p9_fcall *p9_create_tflush(u16 oldtag)
{
int size;
@@ -639,6 +679,15 @@ error:
}
EXPORT_SYMBOL(p9_create_tflush);
+/**
+ * p9_create_twalk - allocates and creates a T_FLUSH request
+ * @fid: handle we are traversing from
+ * @newfid: a new handle for this transaction
+ * @nwname: number of path elements to traverse
+ * @wnames: array of path elements
+ *
+ */
+
struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
char **wnames)
{
@@ -677,6 +726,13 @@ error:
}
EXPORT_SYMBOL(p9_create_twalk);
+/**
+ * p9_create_topen - allocates and creates a T_OPEN request
+ * @fid: handle we are trying to open
+ * @mode: what mode we are trying to open the file in
+ *
+ */
+
struct p9_fcall *p9_create_topen(u32 fid, u8 mode)
{
int size;
@@ -701,6 +757,19 @@ error:
}
EXPORT_SYMBOL(p9_create_topen);
+/**
+ * p9_create_tcreate - allocates and creates a T_CREATE request
+ * @fid: handle of directory we are trying to create in
+ * @name: name of the file we are trying to create
+ * @perm: permissions for the file we are trying to create
+ * @mode: what mode we are trying to open the file in
+ * @extension: 9p2000.u extension string (for special files)
+ * @dotu: 9p2000.u enabled flag
+ *
+ * Note: Plan 9 create semantics include opening the resulting file
+ * which is why mode is included.
+ */
+
struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
char *extension, int dotu)
{
@@ -736,6 +805,13 @@ error:
}
EXPORT_SYMBOL(p9_create_tcreate);
+/**
+ * p9_create_tread - allocates and creates a T_READ request
+ * @fid: handle of the file we are trying to read
+ * @offset: offset to start reading from
+ * @count: how many bytes to read
+ */
+
struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count)
{
int size;
@@ -761,6 +837,17 @@ error:
}
EXPORT_SYMBOL(p9_create_tread);
+/**
+ * p9_create_twrite - allocates and creates a T_WRITE request from the kernel
+ * @fid: handle of the file we are trying to write
+ * @offset: offset to start writing at
+ * @count: how many bytes to write
+ * @data: data to write
+ *
+ * This function will create a requst with data buffers from the kernel
+ * such as the page cache.
+ */
+
struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count,
const char *data)
{
@@ -794,6 +881,16 @@ error:
}
EXPORT_SYMBOL(p9_create_twrite);
+/**
+ * p9_create_twrite_u - allocates and creates a T_WRITE request from userspace
+ * @fid: handle of the file we are trying to write
+ * @offset: offset to start writing at
+ * @count: how many bytes to write
+ * @data: data to write
+ *
+ * This function will create a request with data buffers from userspace
+ */
+
struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count,
const char __user *data)
{
@@ -827,6 +924,14 @@ error:
}
EXPORT_SYMBOL(p9_create_twrite_u);
+/**
+ * p9_create_tclunk - allocate a request to forget about a file handle
+ * @fid: handle of the file we closing or forgetting about
+ *
+ * clunk is used both to close open files and to discard transient handles
+ * which may be created during meta-data operations and hierarchy traversal.
+ */
+
struct p9_fcall *p9_create_tclunk(u32 fid)
{
int size;
@@ -850,6 +955,12 @@ error:
}
EXPORT_SYMBOL(p9_create_tclunk);
+/**
+ * p9_create_tremove - allocate and create a request to remove a file
+ * @fid: handle of the file or directory we are removing
+ *
+ */
+
struct p9_fcall *p9_create_tremove(u32 fid)
{
int size;
@@ -873,6 +984,12 @@ error:
}
EXPORT_SYMBOL(p9_create_tremove);
+/**
+ * p9_create_tstat - allocate and populate a request for attributes
+ * @fid: handle of the file or directory we are trying to get the attributes of
+ *
+ */
+
struct p9_fcall *p9_create_tstat(u32 fid)
{
int size;
@@ -896,6 +1013,14 @@ error:
}
EXPORT_SYMBOL(p9_create_tstat);
+/**
+ * p9_create_tstat - allocate and populate a request to change attributes
+ * @fid: handle of the file or directory we are trying to change
+ * @wstat: &p9_stat structure with attributes we wish to set
+ * @dotu: 9p2000.u enabled flag
+ *
+ */
+
struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat,
int dotu)
{
@@ -922,3 +1047,4 @@ error:
return fc;
}
EXPORT_SYMBOL(p9_create_twstat);
+
diff --git a/net/9p/error.c b/net/9p/error.c
index 64104b9cb422..fdebe4314062 100644
--- a/net/9p/error.c
+++ b/net/9p/error.c
@@ -33,6 +33,13 @@
#include <linux/errno.h>
#include <net/9p/9p.h>
+/**
+ * struct errormap - map string errors from Plan 9 to Linux numeric ids
+ * @name: string sent over 9P
+ * @val: numeric id most closely representing @name
+ * @namelen: length of string
+ * @list: hash-table list for string lookup
+ */
struct errormap {
char *name;
int val;
@@ -177,8 +184,7 @@ static struct errormap errmap[] = {
};
/**
- * p9_error_init - preload
- * @errstr: error string
+ * p9_error_init - preload mappings into hash list
*
*/
@@ -206,6 +212,7 @@ EXPORT_SYMBOL(p9_error_init);
/**
* errstr2errno - convert error string to error number
* @errstr: error string
+ * @len: length of error string
*
*/
@@ -230,8 +237,8 @@ int p9_errstr2errno(char *errstr, int len)
if (errno == 0) {
/* TODO: if error isn't found, add it dynamically */
errstr[len] = 0;
- printk(KERN_ERR "%s: errstr :%s: not found\n", __func__,
- errstr);
+ printk(KERN_ERR "%s: server reported unknown error %s\n",
+ __func__, errstr);
errno = 1;
}
diff --git a/net/9p/fcprint.c b/net/9p/fcprint.c
index 40244fbd9b0d..53dd8e28dd8a 100644
--- a/net/9p/fcprint.c
+++ b/net/9p/fcprint.c
@@ -142,6 +142,14 @@ p9_printdata(char *buf, int buflen, u8 *data, int datalen)
return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16);
}
+/**
+ * p9_printfcall - decode and print a protocol structure into a buffer
+ * @buf: buffer to deposit decoded structure into
+ * @buflen: available space in buffer
+ * @fc: protocol rpc structure of type &p9_fcall
+ * @extended: whether or not session is operating with extended protocol
+ */
+
int
p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended)
{
diff --git a/net/9p/mod.c b/net/9p/mod.c
index c285aab2af04..bdee1fb7cc62 100644
--- a/net/9p/mod.c
+++ b/net/9p/mod.c
@@ -39,9 +39,6 @@ module_param_named(debug, p9_debug_level, uint, 0);
MODULE_PARM_DESC(debug, "9P debugging level");
#endif
-extern int p9_mux_global_init(void);
-extern void p9_mux_global_exit(void);
-
/*
* Dynamic Transport Registration Routines
*
@@ -52,7 +49,7 @@ static struct p9_trans_module *v9fs_default_transport;
/**
* v9fs_register_trans - register a new transport with 9p
- * @m - structure describing the transport module and entry points
+ * @m: structure describing the transport module and entry points
*
*/
void v9fs_register_trans(struct p9_trans_module *m)
@@ -65,7 +62,7 @@ EXPORT_SYMBOL(v9fs_register_trans);
/**
* v9fs_match_trans - match transport versus registered transports
- * @arg: string identifying transport
+ * @name: string identifying transport
*
*/
struct p9_trans_module *v9fs_match_trans(const substring_t *name)
@@ -110,6 +107,7 @@ static int __init init_p9(void)
p9_error_init();
printk(KERN_INFO "Installing 9P2000 support\n");
+ p9_trans_fd_init();
return ret;
}
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index f624dff76852..4507f744f44e 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -47,12 +47,29 @@
#define SCHED_TIMEOUT 10
#define MAXPOLLWADDR 2
+/**
+ * struct p9_fd_opts - per-transport options
+ * @rfd: file descriptor for reading (trans=fd)
+ * @wfd: file descriptor for writing (trans=fd)
+ * @port: port to connect to (trans=tcp)
+ *
+ */
+
struct p9_fd_opts {
int rfd;
int wfd;
u16 port;
};
+
+/**
+ * struct p9_trans_fd - transport state
+ * @rd: reference to file to read from
+ * @wr: reference of file to write to
+ * @conn: connection state reference
+ *
+ */
+
struct p9_trans_fd {
struct file *rd;
struct file *wr;
@@ -90,10 +107,24 @@ enum {
};
struct p9_req;
-
typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
+
+/**
+ * struct p9_req - fd mux encoding of an rpc transaction
+ * @lock: protects req_list
+ * @tag: numeric tag for rpc transaction
+ * @tcall: request &p9_fcall structure
+ * @rcall: response &p9_fcall structure
+ * @err: error state
+ * @cb: callback for when response is received
+ * @cba: argument to pass to callback
+ * @flush: flag to indicate RPC has been flushed
+ * @req_list: list link for higher level objects to chain requests
+ *
+ */
+
struct p9_req {
- spinlock_t lock; /* protect request structure */
+ spinlock_t lock;
int tag;
struct p9_fcall *tcall;
struct p9_fcall *rcall;
@@ -104,7 +135,39 @@ struct p9_req {
struct list_head req_list;
};
-struct p9_mux_poll_task;
+struct p9_mux_poll_task {
+ struct task_struct *task;
+ struct list_head mux_list;
+ int muxnum;
+};
+
+/**
+ * struct p9_conn - fd mux connection state information
+ * @lock: protects mux_list (?)
+ * @mux_list: list link for mux to manage multiple connections (?)
+ * @poll_task: task polling on this connection
+ * @msize: maximum size for connection (dup)
+ * @extended: 9p2000.u flag (dup)
+ * @trans: reference to transport instance for this connection
+ * @tagpool: id accounting for transactions
+ * @err: error state
+ * @equeue: event wait_q (?)
+ * @req_list: accounting for requests which have been sent
+ * @unsent_req_list: accounting for requests that haven't been sent
+ * @rcall: current response &p9_fcall structure
+ * @rpos: read position in current frame
+ * @rbuf: current read buffer
+ * @wpos: write position for current frame
+ * @wsize: amount of data to write for current frame
+ * @wbuf: current write buffer
+ * @poll_wait: array of wait_q's for various worker threads
+ * @poll_waddr: ????
+ * @pt: poll state
+ * @rq: current read work
+ * @wq: current write work
+ * @wsched: ????
+ *
+ */
struct p9_conn {
spinlock_t lock; /* protect lock structure */
@@ -132,11 +195,16 @@ struct p9_conn {
unsigned long wsched;
};
-struct p9_mux_poll_task {
- struct task_struct *task;
- struct list_head mux_list;
- int muxnum;
-};
+/**
+ * struct p9_mux_rpc - fd mux rpc accounting structure
+ * @m: connection this request was issued on
+ * @err: error state
+ * @tcall: request &p9_fcall
+ * @rcall: response &p9_fcall
+ * @wqueue: wait queue that client is blocked on for this rpc
+ *
+ * Bug: isn't this information duplicated elsewhere like &p9_req
+ */
struct p9_mux_rpc {
struct p9_conn *m;
@@ -207,10 +275,12 @@ static void p9_mux_put_tag(struct p9_conn *m, u16 tag)
/**
* p9_mux_calc_poll_procs - calculates the number of polling procs
- * based on the number of mounted v9fs filesystems.
+ * @muxnum: number of mounts
*
+ * Calculation is based on the number of mounted v9fs filesystems.
* The current implementation returns sqrt of the number of mounts.
*/
+
static int p9_mux_calc_poll_procs(int muxnum)
{
int n;
@@ -331,12 +401,11 @@ static void p9_mux_poll_stop(struct p9_conn *m)
/**
* p9_conn_create - allocate and initialize the per-session mux data
- * Creates the polling task if this is the first session.
+ * @trans: transport structure
*
- * @trans - transport structure
- * @msize - maximum message size
- * @extended - extended flag
+ * Note: Creates the polling task if this is the first session.
*/
+
static struct p9_conn *p9_conn_create(struct p9_trans *trans)
{
int i, n;
@@ -406,7 +475,10 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
/**
* p9_mux_destroy - cancels all pending requests and frees mux resources
+ * @m: mux to destroy
+ *
*/
+
static void p9_conn_destroy(struct p9_conn *m)
{
P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
@@ -429,9 +501,14 @@ static void p9_conn_destroy(struct p9_conn *m)
}
/**
- * p9_pollwait - called by files poll operation to add v9fs-poll task
- * to files wait queue
+ * p9_pollwait - add poll task to the wait queue
+ * @filp: file pointer being polled
+ * @wait_address: wait_q to block on
+ * @p: poll state
+ *
+ * called by files poll operation to add v9fs-poll task to files wait queue
*/
+
static void
p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
{
@@ -462,7 +539,10 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
/**
* p9_poll_mux - polls a mux and schedules read or write works if necessary
+ * @m: connection to poll
+ *
*/
+
static void p9_poll_mux(struct p9_conn *m)
{
int n;
@@ -499,9 +579,14 @@ static void p9_poll_mux(struct p9_conn *m)
}
/**
- * p9_poll_proc - polls all v9fs transports for new events and queues
- * the appropriate work to the work queue
+ * p9_poll_proc - poll worker thread
+ * @a: thread state and arguments
+ *
+ * polls all v9fs transports for new events and queues the appropriate
+ * work to the work queue
+ *
*/
+
static int p9_poll_proc(void *a)
{
struct p9_conn *m, *mtmp;
@@ -527,7 +612,10 @@ static int p9_poll_proc(void *a)
/**
* p9_write_work - called when a transport can send some data
+ * @work: container for work to be done
+ *
*/
+
static void p9_write_work(struct work_struct *work)
{
int n, err;
@@ -638,7 +726,10 @@ static void process_request(struct p9_conn *m, struct p9_req *req)
/**
* p9_read_work - called when there is some data to be read from a transport
+ * @work: container of work to be done
+ *
*/
+
static void p9_read_work(struct work_struct *work)
{
int n, err;
@@ -793,7 +884,9 @@ error:
* @tc: request to be sent
* @cb: callback function to call when response is received
* @cba: parameter to pass to the callback function
+ *
*/
+
static struct p9_req *p9_send_request(struct p9_conn *m,
struct p9_fcall *tc,
p9_conn_req_callback cb, void *cba)
@@ -961,10 +1054,12 @@ p9_conn_rpc_cb(struct p9_req *req, void *a)
/**
* p9_fd_rpc- sends 9P request and waits until a response is available.
* The function can be interrupted.
- * @m: mux data
+ * @t: transport data
* @tc: request to be sent
* @rc: pointer where a pointer to the response is stored
+ *
*/
+
int
p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
{
@@ -1041,8 +1136,10 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
* @m: mux data
* @tc: request to be sent
* @cb: callback function to be called when response arrives
- * @cba: value to pass to the callback function
+ * @a: value to pass to the callback function
+ *
*/
+
int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
p9_conn_req_callback cb, void *a)
{
@@ -1065,7 +1162,9 @@ int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
* p9_conn_cancel - cancel all pending requests with error
* @m: mux data
* @err: error code
+ *
*/
+
void p9_conn_cancel(struct p9_conn *m, int err)
{
struct p9_req *req, *rtmp;
@@ -1097,35 +1196,46 @@ void p9_conn_cancel(struct p9_conn *m, int err)
}
/**
- * v9fs_parse_options - parse mount options into session structure
+ * parse_options - parse mount options into session structure
* @options: options string passed from mount
- * @v9ses: existing v9fs session information
+ * @opts: transport-specific structure to parse options into
*
+ * Returns 0 upon success, -ERRNO upon failure
*/
-static void parse_opts(char *options, struct p9_fd_opts *opts)
+static int parse_opts(char *params, struct p9_fd_opts *opts)
{
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
+ char *options;
int ret;
opts->port = P9_PORT;
opts->rfd = ~0;
opts->wfd = ~0;
- if (!options)
- return;
+ if (!params)
+ return 0;
+
+ options = kstrdup(params, GFP_KERNEL);
+ if (!options) {
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "failed to allocate copy of option string\n");
+ return -ENOMEM;
+ }
while ((p = strsep(&options, ",")) != NULL) {
int token;
+ int r;
if (!*p)
continue;
token = match_token(p, tokens, args);
- ret = match_int(&args[0], &option);
- if (ret < 0) {
+ r = match_int(&args[0], &option);
+ if (r < 0) {
P9_DPRINTK(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
+ ret = r;
continue;
}
switch (token) {
@@ -1142,6 +1252,8 @@ static void parse_opts(char *options, struct p9_fd_opts *opts)
continue;
}
}
+ kfree(options);
+ return 0;
}
static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
@@ -1193,11 +1305,12 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
/**
* p9_fd_read- read from a fd
- * @v9ses: session information
+ * @trans: transport instance state
* @v: buffer to receive data into
* @len: size of receive buffer
*
*/
+
static int p9_fd_read(struct p9_trans *trans, void *v, int len)
{
int ret;
@@ -1220,11 +1333,12 @@ static int p9_fd_read(struct p9_trans *trans, void *v, int len)
/**
* p9_fd_write - write to a socket
- * @v9ses: session information
+ * @trans: transport instance state
* @v: buffer to send data from
* @len: size of send buffer
*
*/
+
static int p9_fd_write(struct p9_trans *trans, void *v, int len)
{
int ret;
@@ -1296,6 +1410,7 @@ end:
* @trans: private socket structure
*
*/
+
static void p9_fd_close(struct p9_trans *trans)
{
struct p9_trans_fd *ts;
@@ -1318,6 +1433,23 @@ static void p9_fd_close(struct p9_trans *trans)
kfree(ts);
}
+/*
+ * stolen from NFS - maybe should be made a generic function?
+ */
+static inline int valid_ipaddr4(const char *buf)
+{
+ int rc, count, in[4];
+
+ rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
+ if (rc != 4)
+ return -EINVAL;
+ for (count = 0; count < 4; count++) {
+ if (in[count] > 255)
+ return -EINVAL;
+ }
+ return 0;
+}
+
static struct p9_trans *
p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
{
@@ -1328,7 +1460,12 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
struct p9_fd_opts opts;
struct p9_trans_fd *p;
- parse_opts(args, &opts);
+ err = parse_opts(args, &opts);
+ if (err < 0)
+ return ERR_PTR(err);
+
+ if (valid_ipaddr4(addr) < 0)
+ return ERR_PTR(-EINVAL);
csocket = NULL;
trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
@@ -1508,7 +1645,7 @@ static struct p9_trans_module p9_fd_trans = {
.create = p9_trans_create_fd,
};
-static int __init p9_trans_fd_init(void)
+int p9_trans_fd_init(void)
{
int ret = p9_mux_global_init();
if (ret) {
@@ -1522,9 +1659,4 @@ static int __init p9_trans_fd_init(void)
return 0;
}
-
-module_init(p9_trans_fd_init);
-
-MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
-MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
-MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(p9_trans_fd_init);
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index de7a9f532edc..42adc052b149 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -49,29 +49,75 @@
#define VIRTQUEUE_NUM 128
/* a single mutex to manage channel initialization and attachment */
-static DECLARE_MUTEX(virtio_9p_lock);
+static DEFINE_MUTEX(virtio_9p_lock);
/* global which tracks highest initialized channel */
static int chan_index;
#define P9_INIT_MAXTAG 16
-#define REQ_STATUS_IDLE 0
-#define REQ_STATUS_SENT 1
-#define REQ_STATUS_RCVD 2
-#define REQ_STATUS_FLSH 3
+
+/**
+ * enum p9_req_status_t - virtio request status
+ * @REQ_STATUS_IDLE: request slot unused
+ * @REQ_STATUS_SENT: request sent to server
+ * @REQ_STATUS_RCVD: response received from server
+ * @REQ_STATUS_FLSH: request has been flushed
+ *
+ * The @REQ_STATUS_IDLE state is used to mark a request slot as unused
+ * but use is actually tracked by the idpool structure which handles tag
+ * id allocation.
+ *
+ */
+
+enum p9_req_status_t {
+ REQ_STATUS_IDLE,
+ REQ_STATUS_SENT,
+ REQ_STATUS_RCVD,
+ REQ_STATUS_FLSH,
+};
+
+/**
+ * struct p9_req_t - virtio request slots
+ * @status: status of this request slot
+ * @wq: wait_queue for the client to block on for this request
+ *
+ * The virtio transport uses an array to track outstanding requests
+ * instead of a list. While this may incurr overhead during initial
+ * allocation or expansion, it makes request lookup much easier as the
+ * tag id is a index into an array. (We use tag+1 so that we can accomodate
+ * the -1 tag for the T_VERSION request).
+ * This also has the nice effect of only having to allocate wait_queues
+ * once, instead of constantly allocating and freeing them. Its possible
+ * other resources could benefit from this scheme as well.
+ *
+ */
struct p9_req_t {
int status;
wait_queue_head_t *wq;
};
-/* We keep all per-channel information in a structure.
+/**
+ * struct virtio_chan - per-instance transport information
+ * @initialized: whether the channel is initialized
+ * @inuse: whether the channel is in use
+ * @lock: protects multiple elements within this structure
+ * @vdev: virtio dev associated with this channel
+ * @vq: virtio queue associated with this channel
+ * @tagpool: accounting for tag ids (and request slots)
+ * @reqs: array of request slots
+ * @max_tag: current number of request_slots allocated
+ * @sg: scatter gather list which is used to pack a request (protected?)
+ *
+ * We keep all per-channel information in a structure.
* This structure is allocated within the devices dev->mem space.
* A pointer to the structure will get put in the transport private.
+ *
*/
+
static struct virtio_chan {
- bool initialized; /* channel is initialized */
- bool inuse; /* channel is in use */
+ bool initialized;
+ bool inuse;
spinlock_t lock;
@@ -86,7 +132,19 @@ static struct virtio_chan {
struct scatterlist sg[VIRTQUEUE_NUM];
} channels[MAX_9P_CHAN];
-/* Lookup requests by tag */
+/**
+ * p9_lookup_tag - Lookup requests by tag
+ * @c: virtio channel to lookup tag within
+ * @tag: numeric id for transaction
+ *
+ * this is a simple array lookup, but will grow the
+ * request_slots as necessary to accomodate transaction
+ * ids which did not previously have a slot.
+ *
+ * Bugs: there is currently no upper limit on request slots set
+ * here, but that should be constrained by the id accounting.
+ */
+
static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag)
{
/* This looks up the original request by tag so we know which
@@ -130,11 +188,20 @@ static unsigned int rest_of_page(void *data)
return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
}
+/**
+ * p9_virtio_close - reclaim resources of a channel
+ * @trans: transport state
+ *
+ * This reclaims a channel by freeing its resources and
+ * reseting its inuse flag.
+ *
+ */
+
static void p9_virtio_close(struct p9_trans *trans)
{
struct virtio_chan *chan = trans->priv;
int count;
- unsigned int flags;
+ unsigned long flags;
spin_lock_irqsave(&chan->lock, flags);
p9_idpool_destroy(chan->tagpool);
@@ -144,13 +211,26 @@ static void p9_virtio_close(struct p9_trans *trans)
chan->max_tag = 0;
spin_unlock_irqrestore(&chan->lock, flags);
- down(&virtio_9p_lock);
+ mutex_lock(&virtio_9p_lock);
chan->inuse = false;
- up(&virtio_9p_lock);
+ mutex_unlock(&virtio_9p_lock);
kfree(trans);
}
+/**
+ * req_done - callback which signals activity from the server
+ * @vq: virtio queue activity was received on
+ *
+ * This notifies us that the server has triggered some activity
+ * on the virtio channel - most likely a response to request we
+ * sent. Figure out which requests now have responses and wake up
+ * those threads.
+ *
+ * Bugs: could do with some additional sanity checking, but appears to work.
+ *
+ */
+
static void req_done(struct virtqueue *vq)
{
struct virtio_chan *chan = vq->vdev->priv;
@@ -169,6 +249,20 @@ static void req_done(struct virtqueue *vq)
spin_unlock_irqrestore(&chan->lock, flags);
}
+/**
+ * pack_sg_list - pack a scatter gather list from a linear buffer
+ * @sg: scatter/gather list to pack into
+ * @start: which segment of the sg_list to start at
+ * @limit: maximum segment to pack data to
+ * @data: data to pack into scatter/gather list
+ * @count: amount of data to pack into the scatter/gather list
+ *
+ * sg_lists have multiple segments of various sizes. This will pack
+ * arbitrary data into an existing scatter gather list, segmenting the
+ * data as necessary within constraints.
+ *
+ */
+
static int
pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
int count)
@@ -189,6 +283,14 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
return index-start;
}
+/**
+ * p9_virtio_rpc - issue a request and wait for a response
+ * @t: transport state
+ * @tc: &p9_fcall request to transmit
+ * @rc: &p9_fcall to put reponse into
+ *
+ */
+
static int
p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
{
@@ -263,16 +365,26 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
return 0;
}
+/**
+ * p9_virtio_probe - probe for existence of 9P virtio channels
+ * @vdev: virtio device to probe
+ *
+ * This probes for existing virtio channels. At present only
+ * a single channel is in use, so in the future more work may need
+ * to be done here.
+ *
+ */
+
static int p9_virtio_probe(struct virtio_device *vdev)
{
int err;
struct virtio_chan *chan;
int index;
- down(&virtio_9p_lock);
+ mutex_lock(&virtio_9p_lock);
index = chan_index++;
chan = &channels[index];
- up(&virtio_9p_lock);
+ mutex_unlock(&virtio_9p_lock);
if (chan_index > MAX_9P_CHAN) {
printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n");
@@ -301,17 +413,34 @@ static int p9_virtio_probe(struct virtio_device *vdev)
out_free_vq:
vdev->config->del_vq(chan->vq);
fail:
- down(&virtio_9p_lock);
+ mutex_lock(&virtio_9p_lock);
chan_index--;
- up(&virtio_9p_lock);
+ mutex_unlock(&virtio_9p_lock);
return err;
}
-/* This sets up a transport channel for 9p communication. Right now
+
+/**
+ * p9_virtio_create - allocate a new virtio channel
+ * @devname: string identifying the channel to connect to (unused)
+ * @args: args passed from sys_mount() for per-transport options (unused)
+ * @msize: requested maximum packet size
+ * @extended: 9p2000.u enabled flag
+ *
+ * This sets up a transport channel for 9p communication. Right now
* we only match the first available channel, but eventually we couldlook up
* alternate channels by matching devname versus a virtio_config entry.
* We use a simple reference count mechanism to ensure that only a single
- * mount has a channel open at a time. */
+ * mount has a channel open at a time.
+ *
+ * Bugs: doesn't allow identification of a specific channel
+ * to allocate, channels are allocated sequentially. This was
+ * a pragmatic decision to get things rolling, but ideally some
+ * way of identifying the channel to attach to would be nice
+ * if we are going to support multiple channels.
+ *
+ */
+
static struct p9_trans *
p9_virtio_create(const char *devname, char *args, int msize,
unsigned char extended)
@@ -320,7 +449,7 @@ p9_virtio_create(const char *devname, char *args, int msize,
struct virtio_chan *chan = channels;
int index = 0;
- down(&virtio_9p_lock);
+ mutex_lock(&virtio_9p_lock);
while (index < MAX_9P_CHAN) {
if (chan->initialized && !chan->inuse) {
chan->inuse = true;
@@ -330,7 +459,7 @@ p9_virtio_create(const char *devname, char *args, int msize,
chan = &channels[index];
}
}
- up(&virtio_9p_lock);
+ mutex_unlock(&virtio_9p_lock);
if (index >= MAX_9P_CHAN) {
printk(KERN_ERR "9p: no channels available\n");
@@ -360,6 +489,12 @@ p9_virtio_create(const char *devname, char *args, int msize,
return trans;
}
+/**
+ * p9_virtio_remove - clean up resources associated with a virtio device
+ * @vdev: virtio device to remove
+ *
+ */
+
static void p9_virtio_remove(struct virtio_device *vdev)
{
struct virtio_chan *chan = vdev->priv;
diff --git a/net/9p/util.c b/net/9p/util.c
index ef7215565d88..958fc58cd1ff 100644
--- a/net/9p/util.c
+++ b/net/9p/util.c
@@ -32,11 +32,23 @@
#include <linux/idr.h>
#include <net/9p/9p.h>
+/**
+ * struct p9_idpool - per-connection accounting for tag idpool
+ * @lock: protects the pool
+ * @pool: idr to allocate tag id from
+ *
+ */
+
struct p9_idpool {
spinlock_t lock;
struct idr pool;
};
+/**
+ * p9_idpool_create - create a new per-connection id pool
+ *
+ */
+
struct p9_idpool *p9_idpool_create(void)
{
struct p9_idpool *p;
@@ -52,6 +64,11 @@ struct p9_idpool *p9_idpool_create(void)
}
EXPORT_SYMBOL(p9_idpool_create);
+/**
+ * p9_idpool_destroy - create a new per-connection id pool
+ * @p: idpool to destory
+ */
+
void p9_idpool_destroy(struct p9_idpool *p)
{
idr_destroy(&p->pool);
@@ -61,9 +78,9 @@ EXPORT_SYMBOL(p9_idpool_destroy);
/**
* p9_idpool_get - allocate numeric id from pool
- * @p - pool to allocate from
+ * @p: pool to allocate from
*
- * XXX - This seems to be an awful generic function, should it be in idr.c with
+ * Bugs: This seems to be an awful generic function, should it be in idr.c with
* the lock included in struct idr?
*/
@@ -71,7 +88,7 @@ int p9_idpool_get(struct p9_idpool *p)
{
int i = 0;
int error;
- unsigned int flags;
+ unsigned long flags;
retry:
if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
@@ -94,15 +111,16 @@ EXPORT_SYMBOL(p9_idpool_get);
/**
* p9_idpool_put - release numeric id from pool
- * @p - pool to allocate from
+ * @id: numeric id which is being released
+ * @p: pool to release id into
*
- * XXX - This seems to be an awful generic function, should it be in idr.c with
+ * Bugs: This seems to be an awful generic function, should it be in idr.c with
* the lock included in struct idr?
*/
void p9_idpool_put(int id, struct p9_idpool *p)
{
- unsigned int flags;
+ unsigned long flags;
spin_lock_irqsave(&p->lock, flags);
idr_remove(&p->pool, id);
spin_unlock_irqrestore(&p->lock, flags);
@@ -111,11 +129,13 @@ EXPORT_SYMBOL(p9_idpool_put);
/**
* p9_idpool_check - check if the specified id is available
- * @id - id to check
- * @p - pool
+ * @id: id to check
+ * @p: pool to check
*/
+
int p9_idpool_check(int id, struct p9_idpool *p)
{
return idr_find(&p->pool, id) != NULL;
}
EXPORT_SYMBOL(p9_idpool_check);
+
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 1b228065e745..9d52ebfc1962 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -346,9 +346,9 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
/* skb==NULL means VCC is being destroyed */
br2684_close_vcc(brvcc);
if (list_empty(&brdev->brvccs)) {
- read_lock(&devs_lock);
+ write_lock_irq(&devs_lock);
list_del(&brdev->br2684_devs);
- read_unlock(&devs_lock);
+ write_unlock_irq(&devs_lock);
unregister_netdev(net_dev);
free_netdev(net_dev);
}
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 5c9f3d148135..49487b313f22 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -417,12 +417,10 @@ int atm_proc_dev_register(struct atm_dev *dev)
goto err_out;
sprintf(dev->proc_name,"%s:%d",dev->type, dev->number);
- dev->proc_entry = proc_create(dev->proc_name, 0, atm_proc_root,
- &proc_atm_dev_ops);
+ dev->proc_entry = proc_create_data(dev->proc_name, 0, atm_proc_root,
+ &proc_atm_dev_ops, dev);
if (!dev->proc_entry)
goto err_free_name;
- dev->proc_entry->data = dev;
- dev->proc_entry->owner = THIS_MODULE;
return 0;
err_free_name:
kfree(dev->proc_name);
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 347e935faaf0..f85d94643aaf 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -135,7 +135,7 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len
if (len < 2)
return -EILSEQ;
- n = ntohs(get_unaligned(data));
+ n = get_unaligned_be16(data);
data++; len -= 2;
if (len < n)
@@ -150,8 +150,8 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len
int i;
for (i = 0; i < n; i++) {
- f[i].start = ntohs(get_unaligned(data++));
- f[i].end = ntohs(get_unaligned(data++));
+ f[i].start = get_unaligned_be16(data++);
+ f[i].end = get_unaligned_be16(data++);
BT_DBG("proto filter start %d end %d",
f[i].start, f[i].end);
@@ -180,7 +180,7 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
if (len < 2)
return -EILSEQ;
- n = ntohs(get_unaligned((__be16 *) data));
+ n = get_unaligned_be16(data);
data += 2; len -= 2;
if (len < n)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 46df2e403df8..6aef8f24e581 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -129,8 +129,7 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
if (conn) {
- __le16 policy = get_unaligned((__le16 *) (sent + 2));
- conn->link_policy = __le16_to_cpu(policy);
+ conn->link_policy = get_unaligned_le16(sent + 2);
}
hci_dev_unlock(hdev);
@@ -313,7 +312,7 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb
return;
if (!status) {
- __u16 setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
+ __u16 setting = get_unaligned_le16(sent);
if (hdev->voice_setting != setting) {
hdev->voice_setting = setting;
@@ -1152,8 +1151,8 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
struct hci_conn *conn;
__u16 handle, count;
- handle = __le16_to_cpu(get_unaligned(ptr++));
- count = __le16_to_cpu(get_unaligned(ptr++));
+ handle = get_unaligned_le16(ptr++);
+ count = get_unaligned_le16(ptr++);
conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn) {
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 1d36c093523b..747fabd735d2 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -440,7 +440,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
skb->dev = (void *) hdev;
if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
- u16 opcode = __le16_to_cpu(get_unaligned((__le16 *) skb->data));
+ u16 opcode = get_unaligned_le16(skb->data);
u16 ogf = hci_opcode_ogf(opcode);
u16 ocf = hci_opcode_ocf(opcode);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index a4849f2c1d81..6e180d255505 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1827,7 +1827,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
del_timer(&conn->info_timer);
if (type == L2CAP_IT_FEAT_MASK)
- conn->feat_mask = __le32_to_cpu(get_unaligned((__le32 *) rsp->data));
+ conn->feat_mask = get_unaligned_le32(rsp->data);
l2cap_conn_start(conn);
diff --git a/net/bridge/br.c b/net/bridge/br.c
index a90182873120..8f3c58e5f7a5 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -76,7 +76,6 @@ static void __exit br_deinit(void)
rcu_assign_pointer(br_stp_sap->rcv_func, NULL);
br_netlink_fini();
- br_netfilter_fini();
unregister_netdevice_notifier(&br_device_notifier);
brioctl_set(NULL);
@@ -84,6 +83,7 @@ static void __exit br_deinit(void)
synchronize_net();
+ br_netfilter_fini();
llc_sap_put(br_stp_sap);
br_fdb_get_hook = NULL;
br_fdb_put_hook = NULL;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 9326c377822e..72c5976a5ce3 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -285,7 +285,11 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
/* convert from internal format to API */
memcpy(fe->mac_addr, f->addr.addr, ETH_ALEN);
+
+ /* due to ABI compat need to split into hi/lo */
fe->port_no = f->dst->port_no;
+ fe->port_hi = f->dst->port_no >> 8;
+
fe->is_local = f->is_local;
if (!f->is_static)
fe->ageing_timer_value = jiffies_to_clock_t(jiffies - f->ageing_timer);
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 298e0f463c56..c2397f503b0f 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -273,15 +273,13 @@ int br_add_bridge(const char *name)
rtnl_lock();
if (strchr(dev->name, '%')) {
ret = dev_alloc_name(dev, dev->name);
- if (ret < 0) {
- free_netdev(dev);
- goto out;
- }
+ if (ret < 0)
+ goto out_free;
}
ret = register_netdevice(dev);
if (ret)
- goto out;
+ goto out_free;
ret = br_sysfs_addbr(dev);
if (ret)
@@ -289,6 +287,10 @@ int br_add_bridge(const char *name)
out:
rtnl_unlock();
return ret;
+
+out_free:
+ free_netdev(dev);
+ goto out;
}
int br_del_bridge(const char *name)
@@ -411,9 +413,12 @@ err2:
br_fdb_delete_by_port(br, p, 1);
err1:
kobject_del(&p->kobj);
- return err;
+ goto put_back;
err0:
kobject_put(&p->kobj);
+
+put_back:
+ dev_put(dev);
return err;
}
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 8deab645ef75..ddeb6e5d45d6 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -58,12 +58,12 @@ static inline void br_set_ticks(unsigned char *dest, int j)
{
unsigned long ticks = (STP_HZ * j)/ HZ;
- put_unaligned(htons(ticks), (__be16 *)dest);
+ put_unaligned_be16(ticks, dest);
}
static inline int br_get_ticks(const unsigned char *src)
{
- unsigned long ticks = ntohs(get_unaligned((__be16 *)src));
+ unsigned long ticks = get_unaligned_be16(src);
return DIV_ROUND_UP(ticks * HZ, STP_HZ);
}
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 2759b76f731c..7e8ca2836452 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -208,6 +208,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
*/
int can_send(struct sk_buff *skb, int loop)
{
+ struct sk_buff *newskb = NULL;
int err;
if (skb->dev->type != ARPHRD_CAN) {
@@ -244,8 +245,7 @@ int can_send(struct sk_buff *skb, int loop)
* If the interface is not capable to do loopback
* itself, we do it here.
*/
- struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
-
+ newskb = skb_clone(skb, GFP_ATOMIC);
if (!newskb) {
kfree_skb(skb);
return -ENOMEM;
@@ -254,7 +254,6 @@ int can_send(struct sk_buff *skb, int loop)
newskb->sk = skb->sk;
newskb->ip_summed = CHECKSUM_UNNECESSARY;
newskb->pkt_type = PACKET_BROADCAST;
- netif_rx(newskb);
}
} else {
/* indication for the CAN driver: no loopback required */
@@ -266,11 +265,20 @@ int can_send(struct sk_buff *skb, int loop)
if (err > 0)
err = net_xmit_errno(err);
+ if (err) {
+ if (newskb)
+ kfree_skb(newskb);
+ return err;
+ }
+
+ if (newskb)
+ netif_rx(newskb);
+
/* update statistics */
can_stats.tx_frames++;
can_stats.tx_frames_delta++;
- return err;
+ return 0;
}
EXPORT_SYMBOL(can_send);
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 74fd2d33aff4..d9a3a9d13bed 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -412,12 +412,6 @@ static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data)
bcm_send_to_user(op, &head, data, 1);
}
-/* TODO: move to linux/hrtimer.h */
-static inline int hrtimer_callback_running(struct hrtimer *timer)
-{
- return timer->state & HRTIMER_STATE_CALLBACK;
-}
-
/*
* bcm_rx_update_and_send - process a detected relevant receive content change
* 1. update the last received data
diff --git a/net/compat.c b/net/compat.c
index 01bf95d0832e..c823f6f290cb 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -548,6 +548,9 @@ struct compat_group_filter {
__attribute__ ((aligned(4)));
} __attribute__ ((packed));
+#define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \
+ sizeof(struct __kernel_sockaddr_storage))
+
int compat_mc_setsockopt(struct sock *sock, int level, int optname,
char __user *optval, int optlen,
@@ -582,7 +585,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
case MCAST_UNBLOCK_SOURCE:
{
struct compat_group_source_req __user *gsr32 = (void *)optval;
- struct group_source_req *kgsr = compat_alloc_user_space(
+ struct group_source_req __user *kgsr = compat_alloc_user_space(
sizeof(struct group_source_req));
u32 interface;
@@ -603,10 +606,10 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
case MCAST_MSFILTER:
{
struct compat_group_filter __user *gf32 = (void *)optval;
- struct group_filter *kgf;
+ struct group_filter __user *kgf;
u32 interface, fmode, numsrc;
- if (!access_ok(VERIFY_READ, gf32, sizeof(*gf32)) ||
+ if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) ||
__get_user(interface, &gf32->gf_interface) ||
__get_user(fmode, &gf32->gf_fmode) ||
__get_user(numsrc, &gf32->gf_numsrc))
@@ -622,7 +625,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
__put_user(numsrc, &kgf->gf_numsrc) ||
copy_in_user(&kgf->gf_group, &gf32->gf_group,
sizeof(kgf->gf_group)) ||
- (numsrc && copy_in_user(&kgf->gf_slist, &gf32->gf_slist,
+ (numsrc && copy_in_user(kgf->gf_slist, gf32->gf_slist,
numsrc * sizeof(kgf->gf_slist[0]))))
return -EFAULT;
koptval = (char __user *)kgf;
@@ -637,6 +640,85 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
EXPORT_SYMBOL(compat_mc_setsockopt);
+int compat_mc_getsockopt(struct sock *sock, int level, int optname,
+ char __user *optval, int __user *optlen,
+ int (*getsockopt)(struct sock *,int,int,char __user *,int __user *))
+{
+ struct compat_group_filter __user *gf32 = (void *)optval;
+ struct group_filter __user *kgf;
+ int __user *koptlen;
+ u32 interface, fmode, numsrc;
+ int klen, ulen, err;
+
+ if (optname != MCAST_MSFILTER)
+ return getsockopt(sock, level, optname, optval, optlen);
+
+ koptlen = compat_alloc_user_space(sizeof(*koptlen));
+ if (!access_ok(VERIFY_READ, optlen, sizeof(*optlen)) ||
+ __get_user(ulen, optlen))
+ return -EFAULT;
+
+ /* adjust len for pad */
+ klen = ulen + sizeof(*kgf) - sizeof(*gf32);
+
+ if (klen < GROUP_FILTER_SIZE(0))
+ return -EINVAL;
+
+ if (!access_ok(VERIFY_WRITE, koptlen, sizeof(*koptlen)) ||
+ __put_user(klen, koptlen))
+ return -EFAULT;
+
+ /* have to allow space for previous compat_alloc_user_space, too */
+ kgf = compat_alloc_user_space(klen+sizeof(*optlen));
+
+ if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) ||
+ __get_user(interface, &gf32->gf_interface) ||
+ __get_user(fmode, &gf32->gf_fmode) ||
+ __get_user(numsrc, &gf32->gf_numsrc) ||
+ __put_user(interface, &kgf->gf_interface) ||
+ __put_user(fmode, &kgf->gf_fmode) ||
+ __put_user(numsrc, &kgf->gf_numsrc) ||
+ copy_in_user(&kgf->gf_group,&gf32->gf_group,sizeof(kgf->gf_group)))
+ return -EFAULT;
+
+ err = getsockopt(sock, level, optname, (char __user *)kgf, koptlen);
+ if (err)
+ return err;
+
+ if (!access_ok(VERIFY_READ, koptlen, sizeof(*koptlen)) ||
+ __get_user(klen, koptlen))
+ return -EFAULT;
+
+ ulen = klen - (sizeof(*kgf)-sizeof(*gf32));
+
+ if (!access_ok(VERIFY_WRITE, optlen, sizeof(*optlen)) ||
+ __put_user(ulen, optlen))
+ return -EFAULT;
+
+ if (!access_ok(VERIFY_READ, kgf, klen) ||
+ !access_ok(VERIFY_WRITE, gf32, ulen) ||
+ __get_user(interface, &kgf->gf_interface) ||
+ __get_user(fmode, &kgf->gf_fmode) ||
+ __get_user(numsrc, &kgf->gf_numsrc) ||
+ __put_user(interface, &gf32->gf_interface) ||
+ __put_user(fmode, &gf32->gf_fmode) ||
+ __put_user(numsrc, &gf32->gf_numsrc))
+ return -EFAULT;
+ if (numsrc) {
+ int copylen;
+
+ klen -= GROUP_FILTER_SIZE(0);
+ copylen = numsrc * sizeof(gf32->gf_slist[0]);
+ if (copylen > klen)
+ copylen = klen;
+ if (copy_in_user(gf32->gf_slist, kgf->gf_slist, copylen))
+ return -EFAULT;
+ }
+ return err;
+}
+
+EXPORT_SYMBOL(compat_mc_getsockopt);
+
/* Argument list sizes for compat_sys_socketcall */
#define AL(x) ((x) * sizeof(u32))
diff --git a/net/core/dev.c b/net/core/dev.c
index e1df1ab3e04a..a1607bc0cd4c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -162,7 +162,7 @@ struct net_dma {
struct dma_client client;
spinlock_t lock;
cpumask_t channel_mask;
- struct dma_chan *channels[NR_CPUS];
+ struct dma_chan **channels;
};
static enum dma_state_client
@@ -994,6 +994,8 @@ int dev_open(struct net_device *dev)
{
int ret = 0;
+ ASSERT_RTNL();
+
/*
* Is it already up?
*/
@@ -1060,6 +1062,8 @@ int dev_open(struct net_device *dev)
*/
int dev_close(struct net_device *dev)
{
+ ASSERT_RTNL();
+
might_sleep();
if (!(dev->flags & IFF_UP))
@@ -1524,7 +1528,7 @@ static int dev_gso_segment(struct sk_buff *skb)
if (!segs)
return 0;
- if (unlikely(IS_ERR(segs)))
+ if (IS_ERR(segs))
return PTR_ERR(segs);
skb->next = segs;
@@ -2444,7 +2448,7 @@ static struct netif_rx_stats *softnet_get_online(loff_t *pos)
{
struct netif_rx_stats *rc = NULL;
- while (*pos < NR_CPUS)
+ while (*pos < nr_cpu_ids)
if (cpu_online(*pos)) {
rc = &per_cpu(netdev_rx_stat, *pos);
break;
@@ -3776,6 +3780,7 @@ int register_netdevice(struct net_device *dev)
}
}
+ netdev_initialize_kobject(dev);
ret = netdev_register_kobject(dev);
if (ret)
goto err_uninit;
@@ -4208,7 +4213,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
}
/* Fixup kobjects */
- err = device_rename(&dev->dev, dev->name);
+ netdev_unregister_kobject(dev);
+ err = netdev_register_kobject(dev);
WARN_ON(err);
/* Add the device back in the hashes */
@@ -4324,7 +4330,7 @@ netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
spin_lock(&net_dma->lock);
switch (state) {
case DMA_RESOURCE_AVAILABLE:
- for (i = 0; i < NR_CPUS; i++)
+ for (i = 0; i < nr_cpu_ids; i++)
if (net_dma->channels[i] == chan) {
found = 1;
break;
@@ -4339,7 +4345,7 @@ netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
}
break;
case DMA_RESOURCE_REMOVED:
- for (i = 0; i < NR_CPUS; i++)
+ for (i = 0; i < nr_cpu_ids; i++)
if (net_dma->channels[i] == chan) {
found = 1;
pos = i;
@@ -4366,6 +4372,13 @@ netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
*/
static int __init netdev_dma_register(void)
{
+ net_dma.channels = kzalloc(nr_cpu_ids * sizeof(struct net_dma),
+ GFP_KERNEL);
+ if (unlikely(!net_dma.channels)) {
+ printk(KERN_NOTICE
+ "netdev_dma: no memory for net_dma.channels\n");
+ return -ENOMEM;
+ }
spin_lock_init(&net_dma.lock);
dma_cap_set(DMA_MEMCPY, net_dma.client.cap_mask);
dma_async_client_register(&net_dma.client);
@@ -4471,17 +4484,19 @@ static void __net_exit default_device_exit(struct net *net)
rtnl_lock();
for_each_netdev_safe(net, dev, next) {
int err;
+ char fb_name[IFNAMSIZ];
/* Ignore unmoveable devices (i.e. loopback) */
if (dev->features & NETIF_F_NETNS_LOCAL)
continue;
/* Push remaing network devices to init_net */
- err = dev_change_net_namespace(dev, &init_net, "dev%d");
+ snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
+ err = dev_change_net_namespace(dev, &init_net, fb_name);
if (err) {
- printk(KERN_WARNING "%s: failed to move %s to init_net: %d\n",
+ printk(KERN_EMERG "%s: failed to move %s to init_net: %d\n",
__func__, dev->name, err);
- unregister_netdevice(dev);
+ BUG();
}
}
rtnl_unlock();
diff --git a/net/core/filter.c b/net/core/filter.c
index f5f3cf603064..4f8369729a4e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -213,7 +213,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
load_w:
ptr = load_pointer(skb, k, 4, &tmp);
if (ptr != NULL) {
- A = ntohl(get_unaligned((__be32 *)ptr));
+ A = get_unaligned_be32(ptr);
continue;
}
break;
@@ -222,7 +222,7 @@ load_w:
load_h:
ptr = load_pointer(skb, k, 2, &tmp);
if (ptr != NULL) {
- A = ntohs(get_unaligned((__be16 *)ptr));
+ A = get_unaligned_be16(ptr);
continue;
}
break;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 75075c303c44..5d9d7130bd6e 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1430,11 +1430,10 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
panic("cannot create neighbour cache statistics");
#ifdef CONFIG_PROC_FS
- tbl->pde = proc_create(tbl->id, 0, init_net.proc_net_stat,
- &neigh_stat_seq_fops);
+ tbl->pde = proc_create_data(tbl->id, 0, init_net.proc_net_stat,
+ &neigh_stat_seq_fops, tbl);
if (!tbl->pde)
panic("cannot create neighbour proc dir entry");
- tbl->pde->data = tbl;
#endif
tbl->hash_mask = 1;
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 4e7b847347f7..90e2177af081 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -449,7 +449,6 @@ int netdev_register_kobject(struct net_device *net)
struct device *dev = &(net->dev);
struct attribute_group **groups = net->sysfs_groups;
- device_initialize(dev);
dev->class = &net_class;
dev->platform_data = net;
dev->groups = groups;
@@ -470,6 +469,12 @@ int netdev_register_kobject(struct net_device *net)
return device_add(dev);
}
+void netdev_initialize_kobject(struct net_device *net)
+{
+ struct device *device = &(net->dev);
+ device_initialize(device);
+}
+
int netdev_kobject_init(void)
{
return class_register(&net_class);
diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h
index f5f108db3924..14e7524260b3 100644
--- a/net/core/net-sysfs.h
+++ b/net/core/net-sysfs.h
@@ -4,5 +4,5 @@
int netdev_kobject_init(void);
int netdev_register_kobject(struct net_device *);
void netdev_unregister_kobject(struct net_device *);
-
+void netdev_initialize_kobject(struct net_device *);
#endif
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b04d643fc3c7..8fb134da0346 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -419,7 +419,7 @@ static void arp_reply(struct sk_buff *skb)
return;
size = arp_hdr_len(skb->dev);
- send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
+ send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev),
LL_RESERVED_SPACE(np->dev));
if (!send_skb)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index a803b442234c..8dca21110493 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -3570,15 +3570,14 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
if (err)
goto out1;
- pkt_dev->entry = proc_create(ifname, 0600,
- pg_proc_dir, &pktgen_if_fops);
+ pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir,
+ &pktgen_if_fops, pkt_dev);
if (!pkt_dev->entry) {
printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n",
PG_PROC_DIR, ifname);
err = -EINVAL;
goto out2;
}
- pkt_dev->entry->data = pkt_dev;
#ifdef CONFIG_XFRM
pkt_dev->ipsmode = XFRM_MODE_TRANSPORT;
pkt_dev->ipsproto = IPPROTO_ESP;
@@ -3628,7 +3627,8 @@ static int __init pktgen_create_thread(int cpu)
kthread_bind(p, cpu);
t->tsk = p;
- pe = proc_create(t->tsk->comm, 0600, pg_proc_dir, &pktgen_thread_fops);
+ pe = proc_create_data(t->tsk->comm, 0600, pg_proc_dir,
+ &pktgen_thread_fops, t);
if (!pe) {
printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n",
PG_PROC_DIR, t->tsk->comm);
@@ -3638,8 +3638,6 @@ static int __init pktgen_create_thread(int cpu)
return -EINVAL;
}
- pe->data = t;
-
wake_up_process(p);
return 0;
@@ -3716,8 +3714,6 @@ static int __init pg_init(void)
return -EINVAL;
}
- pe->data = NULL;
-
/* Register us to receive netdevice events */
register_netdevice_notifier(&pktgen_notifier_block);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4fe605fa6f8a..5c459f2b7985 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -200,7 +200,9 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
goto nodata;
/*
- * See comment in sk_buff definition, just before the 'tail' member
+ * Only clear those fields we need to clear, not those that we will
+ * actually initialise below. Hence, don't put any more fields after
+ * the tail pointer in struct sk_buff!
*/
memset(skb, 0, offsetof(struct sk_buff, tail));
skb->truesize = size + sizeof(struct sk_buff);
diff --git a/net/core/sock.c b/net/core/sock.c
index 5dbb81bc9673..88094cb09c06 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -228,11 +228,12 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
static int warned __read_mostly;
*timeo_p = 0;
- if (warned < 10 && net_ratelimit())
+ if (warned < 10 && net_ratelimit()) {
warned++;
printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
"tries to set negative timeout\n",
current->comm, task_pid_nr(current));
+ }
return 0;
}
*timeo_p = MAX_SCHEDULE_TIMEOUT;
@@ -269,7 +270,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
int err = 0;
int skb_len;
- /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
+ /* Cast sk->rcvbuf to unsigned... It's pointless, but reduces
number of warnings when compiling with -W --ANK
*/
if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index b5b52ebb2693..8e9580874216 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -716,7 +716,7 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
* packets for new connections, following the rules from [RFC3390]".
* We need to convert the bytes of RFC3390 into the packets of RFC 4341.
*/
- hctx->ccid2hctx_cwnd = min(4U, max(2U, 4380U / dp->dccps_mss_cache));
+ hctx->ccid2hctx_cwnd = clamp(4380U / dp->dccps_mss_cache, 2U, 4U);
/* Make sure that Ack Ratio is enabled and within bounds. */
max_ratio = DIV_ROUND_UP(hctx->ccid2hctx_cwnd, 2);
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index e76f460af0ea..cd61dea2eea1 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -88,8 +88,8 @@ static void ccid3_hc_tx_set_state(struct sock *sk,
static inline u64 rfc3390_initial_rate(struct sock *sk)
{
const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
- const __u32 w_init = min_t(__u32, 4 * hctx->ccid3hctx_s,
- max_t(__u32, 2 * hctx->ccid3hctx_s, 4380));
+ const __u32 w_init = clamp_t(__u32, 4380U,
+ 2 * hctx->ccid3hctx_s, 4 * hctx->ccid3hctx_s);
return scaled_div(w_init << 6, hctx->ccid3hctx_rtt);
}
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 4a4f6ce4498d..933a0ecf8d46 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -32,7 +32,7 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
if (len > 3) {
DCCP_WARN("invalid length %d\n", len);
- return 1;
+ return -EINVAL;
}
/* XXX add further sanity checks */
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 2f665a516476..f50e88bf2661 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -235,14 +235,14 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
else
min_mtu -= 21;
- if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= min_mtu) {
+ if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) {
if (!(dst_metric_locked(dst, RTAX_MTU))) {
dst->metrics[RTAX_MTU-1] = mtu;
dst_set_expires(dst, dn_rt_mtu_expires);
}
if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
- if (dst->metrics[RTAX_ADVMSS-1] > mss)
+ if (dst_metric(dst, RTAX_ADVMSS) > mss)
dst->metrics[RTAX_ADVMSS-1] = mss;
}
}
@@ -805,12 +805,12 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
rt->u.dst.neighbour = n;
}
- if (rt->u.dst.metrics[RTAX_MTU-1] == 0 ||
- rt->u.dst.metrics[RTAX_MTU-1] > rt->u.dst.dev->mtu)
+ if (dst_metric(&rt->u.dst, RTAX_MTU) == 0 ||
+ dst_metric(&rt->u.dst, RTAX_MTU) > rt->u.dst.dev->mtu)
rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu;
mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->u.dst));
- if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0 ||
- rt->u.dst.metrics[RTAX_ADVMSS-1] > mss)
+ if (dst_metric(&rt->u.dst, RTAX_ADVMSS) == 0 ||
+ dst_metric(&rt->u.dst, RTAX_ADVMSS) > mss)
rt->u.dst.metrics[RTAX_ADVMSS-1] = mss;
return 0;
}
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 68d154480043..7c9bb13b1539 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -340,7 +340,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
dev_hold(dev);
- skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev),
+ skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
msg->msg_flags & MSG_DONTWAIT, &err);
if (skb==NULL)
goto out_unlock;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index f2b5270efdaa..24eca23c2db3 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1234,7 +1234,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
segs = ops->gso_segment(skb, features);
rcu_read_unlock();
- if (!segs || unlikely(IS_ERR(segs)))
+ if (!segs || IS_ERR(segs))
goto out;
skb = segs;
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 68b72a7a1806..418862f1bf22 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -570,7 +570,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
* Allocate a buffer
*/
- skb = alloc_skb(arp_hdr_len(dev) + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
+ skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
if (skb == NULL)
return NULL;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 4637ded3dba8..2c0e4572cc90 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -338,7 +338,7 @@ static int cipso_v4_cache_check(const unsigned char *key,
return -ENOENT;
hash = cipso_v4_map_cache_hash(key, key_len);
- bkt = hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
+ bkt = hash & (CIPSO_V4_CACHE_BUCKETS - 1);
spin_lock_bh(&cipso_v4_cache[bkt].lock);
list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) {
if (entry->hash == hash &&
@@ -417,7 +417,7 @@ int cipso_v4_cache_add(const struct sk_buff *skb,
atomic_inc(&secattr->cache->refcount);
entry->lsm_data = secattr->cache;
- bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
+ bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETS - 1);
spin_lock_bh(&cipso_v4_cache[bkt].lock);
if (cipso_v4_cache[bkt].size < cipso_v4_cache_bucketsize) {
list_add(&entry->list, &cipso_v4_cache[bkt].list);
@@ -983,7 +983,7 @@ static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def,
return -EFAULT;
for (iter = 0; iter < enumcat_len; iter += 2) {
- cat = ntohs(get_unaligned((__be16 *)&enumcat[iter]));
+ cat = get_unaligned_be16(&enumcat[iter]);
if (cat <= cat_prev)
return -EFAULT;
cat_prev = cat;
@@ -1052,7 +1052,7 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
for (iter = 0; iter < net_cat_len; iter += 2) {
ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat,
- ntohs(get_unaligned((__be16 *)&net_cat[iter])),
+ get_unaligned_be16(&net_cat[iter]),
GFP_ATOMIC);
if (ret_val != 0)
return ret_val;
@@ -1086,10 +1086,9 @@ static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def,
return -EFAULT;
for (iter = 0; iter < rngcat_len; iter += 4) {
- cat_high = ntohs(get_unaligned((__be16 *)&rngcat[iter]));
+ cat_high = get_unaligned_be16(&rngcat[iter]);
if ((iter + 4) <= rngcat_len)
- cat_low = ntohs(
- get_unaligned((__be16 *)&rngcat[iter + 2]));
+ cat_low = get_unaligned_be16(&rngcat[iter + 2]);
else
cat_low = 0;
@@ -1188,10 +1187,9 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
u16 cat_high;
for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) {
- cat_high = ntohs(get_unaligned((__be16 *)&net_cat[net_iter]));
+ cat_high = get_unaligned_be16(&net_cat[net_iter]);
if ((net_iter + 4) <= net_cat_len)
- cat_low = ntohs(
- get_unaligned((__be16 *)&net_cat[net_iter + 2]));
+ cat_low = get_unaligned_be16(&net_cat[net_iter + 2]);
else
cat_low = 0;
@@ -1562,7 +1560,7 @@ int cipso_v4_validate(unsigned char **option)
}
rcu_read_lock();
- doi_def = cipso_v4_doi_search(ntohl(get_unaligned((__be32 *)&opt[2])));
+ doi_def = cipso_v4_doi_search(get_unaligned_be32(&opt[2]));
if (doi_def == NULL) {
err_offset = 2;
goto validate_return_locked;
@@ -1843,7 +1841,7 @@ static int cipso_v4_getattr(const unsigned char *cipso,
if (cipso_v4_cache_check(cipso, cipso[1], secattr) == 0)
return 0;
- doi = ntohl(get_unaligned((__be32 *)&cipso[2]));
+ doi = get_unaligned_be32(&cipso[2]);
rcu_read_lock();
doi_def = cipso_v4_doi_search(doi);
if (doi_def == NULL)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index c67d00e8c600..87397351ddac 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -691,7 +691,8 @@ static void icmp_unreach(struct sk_buff *skb)
NIPQUAD(iph->daddr));
} else {
info = ip_rt_frag_needed(net, iph,
- ntohs(icmph->un.frag.mtu));
+ ntohs(icmph->un.frag.mtu),
+ skb->dev);
if (!info)
goto out;
}
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 6250f4239b61..2769dc4a4c84 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -292,7 +292,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
struct iphdr *pip;
struct igmpv3_report *pig;
- skb = alloc_skb(size + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
+ skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
if (skb == NULL)
return NULL;
@@ -653,7 +653,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
return -1;
}
- skb=alloc_skb(IGMP_SIZE+LL_RESERVED_SPACE(dev), GFP_ATOMIC);
+ skb=alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
if (skb == NULL) {
ip_rt_put(rt);
return -1;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 7b4bad6d572f..ff77a4a7f9ec 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -397,7 +397,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
iph = ip_hdr(skb);
/*
- * RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the checksum.
+ * RFC1122: 3.2.1.2 MUST silently discard any IP frame that fails the checksum.
*
* Is the datagram acceptable?
*
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 08349267ceb4..e527628f56cf 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -753,23 +753,15 @@ static inline int ip_ufo_append_data(struct sock *sk,
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum = 0;
sk->sk_sndmsg_off = 0;
- }
- err = skb_append_datato_frags(sk,skb, getfrag, from,
- (length - transhdrlen));
- if (!err) {
- /* specify the length of each IP datagram fragment*/
+ /* specify the length of each IP datagram fragment */
skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
__skb_queue_tail(&sk->sk_write_queue, skb);
-
- return 0;
}
- /* There is not enough support do UFO ,
- * so follow normal path
- */
- kfree_skb(skb);
- return err;
+
+ return skb_append_datato_frags(sk, skb, getfrag, from,
+ (length - transhdrlen));
}
/*
@@ -863,9 +855,9 @@ int ip_append_data(struct sock *sk,
csummode = CHECKSUM_PARTIAL;
inet->cork.length += length;
- if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
- (rt->u.dst.dev->features & NETIF_F_UFO)) {
-
+ if (((length> mtu) || !skb_queue_empty(&sk->sk_write_queue)) &&
+ (sk->sk_protocol == IPPROTO_UDP) &&
+ (rt->u.dst.dev->features & NETIF_F_UFO)) {
err = ip_ufo_append_data(sk, getfrag, from, length, hh_len,
fragheaderlen, transhdrlen, mtu,
flags);
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 4d8d95404f45..e0514e82308e 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1186,7 +1186,14 @@ int ip_getsockopt(struct sock *sk, int level,
int compat_ip_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
- int err = do_ip_getsockopt(sk, level, optname, optval, optlen);
+ int err;
+
+ if (optname == MCAST_MSFILTER)
+ return compat_mc_getsockopt(sk, level, optname, optval, optlen,
+ ip_getsockopt);
+
+ err = do_ip_getsockopt(sk, level, optname, optval, optlen);
+
#ifdef CONFIG_NETFILTER
/* we need to exclude all possible ENOPROTOOPTs except default case */
if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 0f42d1c1f690..ed45037ce9be 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -412,12 +412,12 @@ static struct packet_type rarp_packet_type __initdata = {
.func = ic_rarp_recv,
};
-static inline void ic_rarp_init(void)
+static inline void __init ic_rarp_init(void)
{
dev_add_pack(&rarp_packet_type);
}
-static inline void ic_rarp_cleanup(void)
+static inline void __init ic_rarp_cleanup(void)
{
dev_remove_pack(&rarp_packet_type);
}
@@ -682,7 +682,7 @@ static void __init ic_bootp_init_ext(u8 *e)
/*
* Initialize the DHCP/BOOTP mechanism.
*/
-static inline void ic_bootp_init(void)
+static inline void __init ic_bootp_init(void)
{
int i;
@@ -696,7 +696,7 @@ static inline void ic_bootp_init(void)
/*
* DHCP/BOOTP cleanup.
*/
-static inline void ic_bootp_cleanup(void)
+static inline void __init ic_bootp_cleanup(void)
{
dev_remove_pack(&bootp_packet_type);
}
@@ -710,14 +710,14 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
struct net_device *dev = d->dev;
struct sk_buff *skb;
struct bootp_pkt *b;
- int hh_len = LL_RESERVED_SPACE(dev);
struct iphdr *h;
/* Allocate packet */
- skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
+ skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15,
+ GFP_KERNEL);
if (!skb)
return;
- skb_reserve(skb, hh_len);
+ skb_reserve(skb, LL_RESERVED_SPACE(dev));
b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));
memset(b, 0, sizeof(struct bootp_pkt));
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index dde28a250d92..4b1c16cbb16b 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -148,7 +148,7 @@ const char * ip_vs_state_name(__u16 proto, int state)
struct ip_vs_protocol *pp = ip_vs_proto_get(proto);
if (pp == NULL || pp->state_name == NULL)
- return "ERR!";
+ return (IPPROTO_IP == proto) ? "NONE" : "ERR!";
return pp->state_name(state);
}
diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c
index a842676e1c69..4bf835e1d86d 100644
--- a/net/ipv4/ipvs/ip_vs_proto_ah.c
+++ b/net/ipv4/ipvs/ip_vs_proto_ah.c
@@ -160,6 +160,7 @@ static void ah_exit(struct ip_vs_protocol *pp)
struct ip_vs_protocol ip_vs_protocol_ah = {
.name = "AH",
.protocol = IPPROTO_AH,
+ .num_states = 1,
.dont_defrag = 1,
.init = ah_init,
.exit = ah_exit,
diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c
index aef0d3ee8e44..db6a6b7b1a0b 100644
--- a/net/ipv4/ipvs/ip_vs_proto_esp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_esp.c
@@ -159,6 +159,7 @@ static void esp_exit(struct ip_vs_protocol *pp)
struct ip_vs_protocol ip_vs_protocol_esp = {
.name = "ESP",
.protocol = IPPROTO_ESP,
+ .num_states = 1,
.dont_defrag = 1,
.init = esp_init,
.exit = esp_exit,
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index 620e40ff79a9..b83dc14b0a4d 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -594,6 +594,7 @@ static void ip_vs_tcp_exit(struct ip_vs_protocol *pp)
struct ip_vs_protocol ip_vs_protocol_tcp = {
.name = "TCP",
.protocol = IPPROTO_TCP,
+ .num_states = IP_VS_TCP_S_LAST,
.dont_defrag = 0,
.appcnt = ATOMIC_INIT(0),
.init = ip_vs_tcp_init,
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 1caa2908373f..75771cb3cd6f 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -409,6 +409,7 @@ static void udp_exit(struct ip_vs_protocol *pp)
struct ip_vs_protocol ip_vs_protocol_udp = {
.name = "UDP",
.protocol = IPPROTO_UDP,
+ .num_states = IP_VS_UDP_S_LAST,
.dont_defrag = 0,
.init = udp_init,
.exit = udp_exit,
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 69c56663cc9a..eff54efe0351 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -288,11 +288,16 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
char *p;
int i;
+ if (buflen < sizeof(struct ip_vs_sync_mesg)) {
+ IP_VS_ERR_RL("sync message header too short\n");
+ return;
+ }
+
/* Convert size back to host byte order */
m->size = ntohs(m->size);
if (buflen != m->size) {
- IP_VS_ERR("bogus message\n");
+ IP_VS_ERR_RL("bogus sync message size\n");
return;
}
@@ -307,9 +312,48 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
for (i=0; i<m->nr_conns; i++) {
unsigned flags, state;
- s = (struct ip_vs_sync_conn *)p;
+ if (p + SIMPLE_CONN_SIZE > buffer+buflen) {
+ IP_VS_ERR_RL("bogus conn in sync message\n");
+ return;
+ }
+ s = (struct ip_vs_sync_conn *) p;
flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
+ flags &= ~IP_VS_CONN_F_HASHED;
+ if (flags & IP_VS_CONN_F_SEQ_MASK) {
+ opt = (struct ip_vs_sync_conn_options *)&s[1];
+ p += FULL_CONN_SIZE;
+ if (p > buffer+buflen) {
+ IP_VS_ERR_RL("bogus conn options in sync message\n");
+ return;
+ }
+ } else {
+ opt = NULL;
+ p += SIMPLE_CONN_SIZE;
+ }
+
state = ntohs(s->state);
+ if (!(flags & IP_VS_CONN_F_TEMPLATE)) {
+ pp = ip_vs_proto_get(s->protocol);
+ if (!pp) {
+ IP_VS_ERR_RL("Unsupported protocol %u in sync msg\n",
+ s->protocol);
+ continue;
+ }
+ if (state >= pp->num_states) {
+ IP_VS_DBG(2, "Invalid %s state %u in sync msg\n",
+ pp->name, state);
+ continue;
+ }
+ } else {
+ /* protocol in templates is not used for state/timeout */
+ pp = NULL;
+ if (state > 0) {
+ IP_VS_DBG(2, "Invalid template state %u in sync msg\n",
+ state);
+ state = 0;
+ }
+ }
+
if (!(flags & IP_VS_CONN_F_TEMPLATE))
cp = ip_vs_conn_in_get(s->protocol,
s->caddr, s->cport,
@@ -345,14 +389,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
IP_VS_ERR("ip_vs_conn_new failed\n");
return;
}
- cp->state = state;
} else if (!cp->dest) {
dest = ip_vs_try_bind_dest(cp);
- if (!dest) {
- /* it is an unbound entry created by
- * synchronization */
- cp->flags = flags | IP_VS_CONN_F_HASHED;
- } else
+ if (dest)
atomic_dec(&dest->refcnt);
} else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) &&
(cp->state != state)) {
@@ -371,23 +410,22 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
}
}
- if (flags & IP_VS_CONN_F_SEQ_MASK) {
- opt = (struct ip_vs_sync_conn_options *)&s[1];
+ if (opt)
memcpy(&cp->in_seq, opt, sizeof(*opt));
- p += FULL_CONN_SIZE;
- } else
- p += SIMPLE_CONN_SIZE;
-
atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
cp->state = state;
- pp = ip_vs_proto_get(s->protocol);
- cp->timeout = pp->timeout_table[cp->state];
+ cp->old_state = cp->state;
+ /*
+ * We can not recover the right timeout for templates
+ * in all cases, we can not find the right fwmark
+ * virtual service. If needed, we can do it for
+ * non-fwmark persistent services.
+ */
+ if (!(flags & IP_VS_CONN_F_TEMPLATE) && pp->timeout_table)
+ cp->timeout = pp->timeout_table[state];
+ else
+ cp->timeout = (3*60*HZ);
ip_vs_conn_put(cp);
-
- if (p > buffer+buflen) {
- IP_VS_ERR("bogus message\n");
- return;
- }
}
}
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 719be29f7506..26a37cedcf2e 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -296,9 +296,8 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
if (v->data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- nskb = skb_copy_expand(e->skb, 0,
- diff - skb_tailroom(e->skb),
- GFP_ATOMIC);
+ nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
+ diff, GFP_ATOMIC);
if (!nskb) {
printk(KERN_WARNING "ip_queue: error "
"in mangle, dropping packet\n");
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 22d8e7cd9197..1819ad7ab910 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -169,14 +169,14 @@ clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
/* create proc dir entry */
sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip));
- c->pde = proc_create(buffer, S_IWUSR|S_IRUSR,
- clusterip_procdir, &clusterip_proc_fops);
+ c->pde = proc_create_data(buffer, S_IWUSR|S_IRUSR,
+ clusterip_procdir,
+ &clusterip_proc_fops, c);
if (!c->pde) {
kfree(c);
return NULL;
}
}
- c->pde->data = c;
#endif
write_lock_bh(&clusterip_lock);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index cacb9cb27dab..5a955c440364 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -303,7 +303,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
const struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_tuple tuple;
- NF_CT_TUPLE_U_BLANK(&tuple);
+ memset(&tuple, 0, sizeof(tuple));
tuple.src.u3.ip = inet->rcv_saddr;
tuple.src.u.tcp.port = inet->sport;
tuple.dst.u3.ip = inet->daddr;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 11d7f753a820..fead049daf43 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -322,7 +322,6 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
unsigned int flags)
{
struct inet_sock *inet = inet_sk(sk);
- int hh_len;
struct iphdr *iph;
struct sk_buff *skb;
unsigned int iphlen;
@@ -336,13 +335,12 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
if (flags&MSG_PROBE)
goto out;
- hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
-
- skb = sock_alloc_send_skb(sk, length+hh_len+15,
- flags&MSG_DONTWAIT, &err);
+ skb = sock_alloc_send_skb(sk,
+ length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
+ flags & MSG_DONTWAIT, &err);
if (skb == NULL)
goto error;
- skb_reserve(skb, hh_len);
+ skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ce25a13f3430..92f90ae46f4a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1430,11 +1430,13 @@ static inline unsigned short guess_mtu(unsigned short old_mtu)
}
unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
- unsigned short new_mtu)
+ unsigned short new_mtu,
+ struct net_device *dev)
{
- int i;
+ int i, k;
unsigned short old_mtu = ntohs(iph->tot_len);
struct rtable *rth;
+ int ikeys[2] = { dev->ifindex, 0 };
__be32 skeys[2] = { iph->saddr, 0, };
__be32 daddr = iph->daddr;
unsigned short est_mtu = 0;
@@ -1442,34 +1444,38 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
if (ipv4_config.no_pmtu_disc)
return 0;
- for (i = 0; i < 2; i++) {
- unsigned hash = rt_hash(daddr, skeys[i], 0);
+ for (k = 0; k < 2; k++) {
+ for (i = 0; i < 2; i++) {
+ unsigned hash = rt_hash(daddr, skeys[i], ikeys[k]);
- rcu_read_lock();
- for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
- rth = rcu_dereference(rth->u.dst.rt_next)) {
- if (rth->fl.fl4_dst == daddr &&
- rth->fl.fl4_src == skeys[i] &&
- rth->rt_dst == daddr &&
- rth->rt_src == iph->saddr &&
- rth->fl.iif == 0 &&
- !(dst_metric_locked(&rth->u.dst, RTAX_MTU)) &&
- net_eq(dev_net(rth->u.dst.dev), net) &&
- rth->rt_genid == atomic_read(&rt_genid)) {
+ rcu_read_lock();
+ for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
+ rth = rcu_dereference(rth->u.dst.rt_next)) {
unsigned short mtu = new_mtu;
+ if (rth->fl.fl4_dst != daddr ||
+ rth->fl.fl4_src != skeys[i] ||
+ rth->rt_dst != daddr ||
+ rth->rt_src != iph->saddr ||
+ rth->fl.oif != ikeys[k] ||
+ rth->fl.iif != 0 ||
+ dst_metric_locked(&rth->u.dst, RTAX_MTU) ||
+ !net_eq(dev_net(rth->u.dst.dev), net) ||
+ rth->rt_genid != atomic_read(&rt_genid))
+ continue;
+
if (new_mtu < 68 || new_mtu >= old_mtu) {
/* BSD 4.2 compatibility hack :-( */
if (mtu == 0 &&
- old_mtu >= rth->u.dst.metrics[RTAX_MTU-1] &&
+ old_mtu >= dst_metric(&rth->u.dst, RTAX_MTU) &&
old_mtu >= 68 + (iph->ihl << 2))
old_mtu -= iph->ihl << 2;
mtu = guess_mtu(old_mtu);
}
- if (mtu <= rth->u.dst.metrics[RTAX_MTU-1]) {
- if (mtu < rth->u.dst.metrics[RTAX_MTU-1]) {
+ if (mtu <= dst_metric(&rth->u.dst, RTAX_MTU)) {
+ if (mtu < dst_metric(&rth->u.dst, RTAX_MTU)) {
dst_confirm(&rth->u.dst);
if (mtu < ip_rt_min_pmtu) {
mtu = ip_rt_min_pmtu;
@@ -1483,15 +1489,15 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
est_mtu = mtu;
}
}
+ rcu_read_unlock();
}
- rcu_read_unlock();
}
return est_mtu ? : new_mtu;
}
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
{
- if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= 68 &&
+ if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= 68 &&
!(dst_metric_locked(dst, RTAX_MTU))) {
if (mtu < ip_rt_min_pmtu) {
mtu = ip_rt_min_pmtu;
@@ -1607,7 +1613,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
sizeof(rt->u.dst.metrics));
if (fi->fib_mtu == 0) {
rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu;
- if (rt->u.dst.metrics[RTAX_LOCK-1] & (1 << RTAX_MTU) &&
+ if (dst_metric_locked(&rt->u.dst, RTAX_MTU) &&
rt->rt_gateway != rt->rt_dst &&
rt->u.dst.dev->mtu > 576)
rt->u.dst.metrics[RTAX_MTU-1] = 576;
@@ -1618,14 +1624,14 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
} else
rt->u.dst.metrics[RTAX_MTU-1]= rt->u.dst.dev->mtu;
- if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0)
+ if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0)
rt->u.dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl;
- if (rt->u.dst.metrics[RTAX_MTU-1] > IP_MAX_MTU)
+ if (dst_metric(&rt->u.dst, RTAX_MTU) > IP_MAX_MTU)
rt->u.dst.metrics[RTAX_MTU-1] = IP_MAX_MTU;
- if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0)
+ if (dst_metric(&rt->u.dst, RTAX_ADVMSS) == 0)
rt->u.dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->u.dst.dev->mtu - 40,
ip_rt_min_advmss);
- if (rt->u.dst.metrics[RTAX_ADVMSS-1] > 65535 - 40)
+ if (dst_metric(&rt->u.dst, RTAX_ADVMSS) > 65535 - 40)
rt->u.dst.metrics[RTAX_ADVMSS-1] = 65535 - 40;
#ifdef CONFIG_NET_CLS_ROUTE
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 3a6be23d222f..6a250828b767 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -285,14 +285,12 @@ int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
if (in_flight >= tp->snd_cwnd)
return 1;
- if (!sk_can_gso(sk))
- return 0;
-
left = tp->snd_cwnd - in_flight;
- if (sysctl_tcp_tso_win_divisor)
- return left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd;
- else
- return left <= tcp_max_burst(tp);
+ if (sk_can_gso(sk) &&
+ left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd &&
+ left * tp->mss_cache < sk->sk_gso_max_size)
+ return 1;
+ return left <= tcp_max_burst(tp);
}
EXPORT_SYMBOL_GPL(tcp_is_cwnd_limited);
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index eb5b9854c8c7..4a1221e5e8ee 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -15,8 +15,8 @@
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/math64.h>
#include <net/tcp.h>
-#include <asm/div64.h>
#define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation
* max_cwnd = snd_cwnd * beta
@@ -128,7 +128,7 @@ static u32 cubic_root(u64 a)
* x = ( 2 * x + a / x ) / 3
* k+1 k k
*/
- x = (2 * x + (u32)div64_64(a, (u64)x * (u64)(x - 1)));
+ x = (2 * x + (u32)div64_u64(a, (u64)x * (u64)(x - 1)));
x = ((x * 341) >> 10);
return x;
}
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c
index 44618b675916..bfcbd148a89d 100644
--- a/net/ipv4/tcp_hybla.c
+++ b/net/ipv4/tcp_hybla.c
@@ -101,8 +101,10 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
if (!tcp_is_cwnd_limited(sk, in_flight))
return;
- if (!ca->hybla_en)
- return tcp_reno_cong_avoid(sk, ack, in_flight);
+ if (!ca->hybla_en) {
+ tcp_reno_cong_avoid(sk, ack, in_flight);
+ return;
+ }
if (ca->rho == 0)
hybla_recalc_param(sk);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0298f80681f2..b54d9d37b636 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -66,6 +66,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sysctl.h>
+#include <net/dst.h>
#include <net/tcp.h>
#include <net/inet_common.h>
#include <linux/ipsec.h>
@@ -113,8 +114,6 @@ int sysctl_tcp_abc __read_mostly;
#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED)
#define FLAG_ANY_PROGRESS (FLAG_FORWARD_PROGRESS|FLAG_SND_UNA_ADVANCED)
-#define IsSackFrto() (sysctl_tcp_frto == 0x2)
-
#define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH)
#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
@@ -605,7 +604,7 @@ static u32 tcp_rto_min(struct sock *sk)
u32 rto_min = TCP_RTO_MIN;
if (dst && dst_metric_locked(dst, RTAX_RTO_MIN))
- rto_min = dst->metrics[RTAX_RTO_MIN - 1];
+ rto_min = dst_metric(dst, RTAX_RTO_MIN);
return rto_min;
}
@@ -769,7 +768,7 @@ void tcp_update_metrics(struct sock *sk)
dst->metrics[RTAX_RTTVAR - 1] = m;
else
dst->metrics[RTAX_RTTVAR-1] -=
- (dst->metrics[RTAX_RTTVAR-1] - m)>>2;
+ (dst_metric(dst, RTAX_RTTVAR) - m)>>2;
}
if (tp->snd_ssthresh >= 0xFFFF) {
@@ -788,21 +787,21 @@ void tcp_update_metrics(struct sock *sk)
dst->metrics[RTAX_SSTHRESH-1] =
max(tp->snd_cwnd >> 1, tp->snd_ssthresh);
if (!dst_metric_locked(dst, RTAX_CWND))
- dst->metrics[RTAX_CWND-1] = (dst->metrics[RTAX_CWND-1] + tp->snd_cwnd) >> 1;
+ dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_cwnd) >> 1;
} else {
/* Else slow start did not finish, cwnd is non-sense,
ssthresh may be also invalid.
*/
if (!dst_metric_locked(dst, RTAX_CWND))
- dst->metrics[RTAX_CWND-1] = (dst->metrics[RTAX_CWND-1] + tp->snd_ssthresh) >> 1;
- if (dst->metrics[RTAX_SSTHRESH-1] &&
+ dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_ssthresh) >> 1;
+ if (dst_metric(dst, RTAX_SSTHRESH) &&
!dst_metric_locked(dst, RTAX_SSTHRESH) &&
- tp->snd_ssthresh > dst->metrics[RTAX_SSTHRESH-1])
+ tp->snd_ssthresh > dst_metric(dst, RTAX_SSTHRESH))
dst->metrics[RTAX_SSTHRESH-1] = tp->snd_ssthresh;
}
if (!dst_metric_locked(dst, RTAX_REORDERING)) {
- if (dst->metrics[RTAX_REORDERING-1] < tp->reordering &&
+ if (dst_metric(dst, RTAX_REORDERING) < tp->reordering &&
tp->reordering != sysctl_tcp_reordering)
dst->metrics[RTAX_REORDERING-1] = tp->reordering;
}
@@ -1172,8 +1171,8 @@ static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb,
struct tcp_sack_block_wire *sp, int num_sacks,
u32 prior_snd_una)
{
- u32 start_seq_0 = ntohl(get_unaligned(&sp[0].start_seq));
- u32 end_seq_0 = ntohl(get_unaligned(&sp[0].end_seq));
+ u32 start_seq_0 = get_unaligned_be32(&sp[0].start_seq);
+ u32 end_seq_0 = get_unaligned_be32(&sp[0].end_seq);
int dup_sack = 0;
if (before(start_seq_0, TCP_SKB_CB(ack_skb)->ack_seq)) {
@@ -1181,8 +1180,8 @@ static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb,
tcp_dsack_seen(tp);
NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV);
} else if (num_sacks > 1) {
- u32 end_seq_1 = ntohl(get_unaligned(&sp[1].end_seq));
- u32 start_seq_1 = ntohl(get_unaligned(&sp[1].start_seq));
+ u32 end_seq_1 = get_unaligned_be32(&sp[1].end_seq);
+ u32 start_seq_1 = get_unaligned_be32(&sp[1].start_seq);
if (!after(end_seq_0, end_seq_1) &&
!before(start_seq_0, start_seq_1)) {
@@ -1453,8 +1452,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb,
for (i = 0; i < num_sacks; i++) {
int dup_sack = !i && found_dup_sack;
- sp[used_sacks].start_seq = ntohl(get_unaligned(&sp_wire[i].start_seq));
- sp[used_sacks].end_seq = ntohl(get_unaligned(&sp_wire[i].end_seq));
+ sp[used_sacks].start_seq = get_unaligned_be32(&sp_wire[i].start_seq);
+ sp[used_sacks].end_seq = get_unaligned_be32(&sp_wire[i].end_seq);
if (!tcp_is_sackblock_valid(tp, dup_sack,
sp[used_sacks].start_seq,
@@ -1685,6 +1684,11 @@ static inline void tcp_reset_reno_sack(struct tcp_sock *tp)
tp->sacked_out = 0;
}
+static int tcp_is_sackfrto(const struct tcp_sock *tp)
+{
+ return (sysctl_tcp_frto == 0x2) && !tcp_is_reno(tp);
+}
+
/* F-RTO can only be used if TCP has never retransmitted anything other than
* head (SACK enhanced variant from Appendix B of RFC4138 is more robust here)
*/
@@ -1701,7 +1705,7 @@ int tcp_use_frto(struct sock *sk)
if (icsk->icsk_mtup.probe_size)
return 0;
- if (IsSackFrto())
+ if (tcp_is_sackfrto(tp))
return 1;
/* Avoid expensive walking of rexmit queue if possible */
@@ -1791,7 +1795,7 @@ void tcp_enter_frto(struct sock *sk)
/* Earlier loss recovery underway (see RFC4138; Appendix B).
* The last condition is necessary at least in tp->frto_counter case.
*/
- if (IsSackFrto() && (tp->frto_counter ||
+ if (tcp_is_sackfrto(tp) && (tp->frto_counter ||
((1 << icsk->icsk_ca_state) & (TCPF_CA_Recovery|TCPF_CA_Loss))) &&
after(tp->high_seq, tp->snd_una)) {
tp->frto_highmark = tp->high_seq;
@@ -1838,9 +1842,16 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
}
- /* Don't lost mark skbs that were fwd transmitted after RTO */
- if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) &&
- !after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark)) {
+ /* Marking forward transmissions that were made after RTO lost
+ * can cause unnecessary retransmissions in some scenarios,
+ * SACK blocks will mitigate that in some but not in all cases.
+ * We used to not mark them but it was causing break-ups with
+ * receivers that do only in-order receival.
+ *
+ * TODO: we could detect presence of such receiver and select
+ * different behavior per flow.
+ */
+ if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) {
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
tp->lost_out += tcp_skb_pcount(skb);
}
@@ -1856,7 +1867,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
tp->reordering = min_t(unsigned int, tp->reordering,
sysctl_tcp_reordering);
tcp_set_ca_state(sk, TCP_CA_Loss);
- tp->high_seq = tp->frto_highmark;
+ tp->high_seq = tp->snd_nxt;
TCP_ECN_queue_cwr(tp);
tcp_clear_retrans_hints_partial(tp);
@@ -2478,7 +2489,7 @@ static void tcp_try_to_open(struct sock *sk, int flag)
tcp_verify_left_out(tp);
- if (tp->retrans_out == 0)
+ if (!tp->frto_counter && tp->retrans_out == 0)
tp->retrans_stamp = 0;
if (flag & FLAG_ECE)
@@ -3123,7 +3134,7 @@ static int tcp_process_frto(struct sock *sk, int flag)
return 1;
}
- if (!IsSackFrto() || tcp_is_reno(tp)) {
+ if (!tcp_is_sackfrto(tp)) {
/* RFC4138 shortcoming in step 2; should also have case c):
* ACK isn't duplicate nor advances window, e.g., opposite dir
* data, winupdate
@@ -3340,7 +3351,7 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
switch (opcode) {
case TCPOPT_MSS:
if (opsize == TCPOLEN_MSS && th->syn && !estab) {
- u16 in_mss = ntohs(get_unaligned((__be16 *)ptr));
+ u16 in_mss = get_unaligned_be16(ptr);
if (in_mss) {
if (opt_rx->user_mss &&
opt_rx->user_mss < in_mss)
@@ -3369,8 +3380,8 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
((estab && opt_rx->tstamp_ok) ||
(!estab && sysctl_tcp_timestamps))) {
opt_rx->saw_tstamp = 1;
- opt_rx->rcv_tsval = ntohl(get_unaligned((__be32 *)ptr));
- opt_rx->rcv_tsecr = ntohl(get_unaligned((__be32 *)(ptr+4)));
+ opt_rx->rcv_tsval = get_unaligned_be32(ptr);
+ opt_rx->rcv_tsecr = get_unaligned_be32(ptr + 4);
}
break;
case TCPOPT_SACK_PERM:
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 0e9bc120707d..cd601a866c2f 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2214,9 +2214,6 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
struct tcp_iter_state *s;
int err;
- if (unlikely(afinfo == NULL))
- return -EINVAL;
-
err = seq_open_net(inode, file, &afinfo->seq_ops,
sizeof(struct tcp_iter_state));
if (err < 0)
@@ -2241,10 +2238,9 @@ int tcp_proc_register(struct net *net, struct tcp_seq_afinfo *afinfo)
afinfo->seq_ops.next = tcp_seq_next;
afinfo->seq_ops.stop = tcp_seq_stop;
- p = proc_net_fops_create(net, afinfo->name, S_IRUGO, &afinfo->seq_fops);
- if (p)
- p->data = afinfo;
- else
+ p = proc_create_data(afinfo->name, S_IRUGO, net->proc_net,
+ &afinfo->seq_fops, afinfo);
+ if (!p)
rc = -ENOMEM;
return rc;
}
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index be24d6ee34bd..14504dada116 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -167,8 +167,10 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
struct tcp_sock *tp = tcp_sk(sk);
struct vegas *vegas = inet_csk_ca(sk);
- if (!vegas->doing_vegas_now)
- return tcp_reno_cong_avoid(sk, ack, in_flight);
+ if (!vegas->doing_vegas_now) {
+ tcp_reno_cong_avoid(sk, ack, in_flight);
+ return;
+ }
/* The key players are v_beg_snd_una and v_beg_snd_nxt.
*
@@ -229,7 +231,8 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
*/
tcp_reno_cong_avoid(sk, ack, in_flight);
} else {
- u32 rtt, target_cwnd, diff;
+ u32 rtt, diff;
+ u64 target_cwnd;
/* We have enough RTT samples, so, using the Vegas
* algorithm, we determine if we should increase or
@@ -252,8 +255,9 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
* We keep it as a fixed point number with
* V_PARAM_SHIFT bits to the right of the binary point.
*/
- target_cwnd = ((old_wnd * vegas->baseRTT)
- << V_PARAM_SHIFT) / rtt;
+ target_cwnd = ((u64)old_wnd * vegas->baseRTT);
+ target_cwnd <<= V_PARAM_SHIFT;
+ do_div(target_cwnd, rtt);
/* Calculate the difference between the window we had,
* and the window we would like to have. This quantity
@@ -279,7 +283,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
* utilization.
*/
tp->snd_cwnd = min(tp->snd_cwnd,
- (target_cwnd >>
+ ((u32)target_cwnd >>
V_PARAM_SHIFT)+1);
} else if (tp->snd_cwnd <= tp->snd_ssthresh) {
diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c
index d16689e98516..d08b2e855c22 100644
--- a/net/ipv4/tcp_veno.c
+++ b/net/ipv4/tcp_veno.c
@@ -119,8 +119,10 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
struct tcp_sock *tp = tcp_sk(sk);
struct veno *veno = inet_csk_ca(sk);
- if (!veno->doing_veno_now)
- return tcp_reno_cong_avoid(sk, ack, in_flight);
+ if (!veno->doing_veno_now) {
+ tcp_reno_cong_avoid(sk, ack, in_flight);
+ return;
+ }
/* limited by applications */
if (!tcp_is_cwnd_limited(sk, in_flight))
@@ -133,7 +135,8 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
*/
tcp_reno_cong_avoid(sk, ack, in_flight);
} else {
- u32 rtt, target_cwnd;
+ u64 target_cwnd;
+ u32 rtt;
/* We have enough rtt samples, so, using the Veno
* algorithm, we determine the state of the network.
@@ -141,8 +144,9 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
rtt = veno->minrtt;
- target_cwnd = ((tp->snd_cwnd * veno->basertt)
- << V_PARAM_SHIFT) / rtt;
+ target_cwnd = (tp->snd_cwnd * veno->basertt);
+ target_cwnd <<= V_PARAM_SHIFT;
+ do_div(target_cwnd, rtt);
veno->diff = (tp->snd_cwnd << V_PARAM_SHIFT) - target_cwnd;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 1f535e315188..db1cb7c96d63 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1605,10 +1605,9 @@ int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo)
afinfo->seq_ops.next = udp_seq_next;
afinfo->seq_ops.stop = udp_seq_stop;
- p = proc_net_fops_create(net, afinfo->name, S_IRUGO, &afinfo->seq_fops);
- if (p)
- p->data = afinfo;
- else
+ p = proc_create_data(afinfo->name, S_IRUGO, net->proc_net,
+ &afinfo->seq_fops, afinfo);
+ if (!p)
rc = -ENOMEM;
return rc;
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0af2e055f883..48cdce9c696c 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -780,7 +780,7 @@ slow_path:
* Allocate buffer.
*/
- if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
+ if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
IP6_INC_STATS(ip6_dst_idev(skb->dst),
IPSTATS_MIB_FRAGFAILS);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index db6fdc1498aa..56d55fecf8ec 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -1127,6 +1127,10 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
if (level != SOL_IPV6)
return -ENOPROTOOPT;
+ if (optname == MCAST_MSFILTER)
+ return compat_mc_getsockopt(sk, level, optname, optval, optlen,
+ ipv6_getsockopt);
+
err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
#ifdef CONFIG_NETFILTER
/* we need to exclude all possible ENOPROTOOPTs except default case */
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 54f91efdae58..fd632dd7f98d 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1411,7 +1411,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
IPV6_TLV_PADN, 0 };
/* we assume size > sizeof(ra) here */
- skb = sock_alloc_send_skb(sk, size + LL_RESERVED_SPACE(dev), 1, &err);
+ skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err);
if (!skb)
return NULL;
@@ -1790,7 +1790,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
payload_len = len + sizeof(ra);
full_len = sizeof(struct ipv6hdr) + payload_len;
- skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err);
+ skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
if (skb == NULL) {
rcu_read_lock();
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 2c74885f8355..a55fc05b8125 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -479,7 +479,7 @@ static void __ndisc_send(struct net_device *dev,
skb = sock_alloc_send_skb(sk,
(MAX_HEADER + sizeof(struct ipv6hdr) +
- len + LL_RESERVED_SPACE(dev)),
+ len + LL_ALLOCATED_SPACE(dev)),
1, &err);
if (!skb) {
ND_PRINTK0(KERN_ERR
@@ -1521,7 +1521,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
buff = sock_alloc_send_skb(sk,
(MAX_HEADER + sizeof(struct ipv6hdr) +
- len + LL_RESERVED_SPACE(dev)),
+ len + LL_ALLOCATED_SPACE(dev)),
1, &err);
if (buff == NULL) {
ND_PRINTK0(KERN_ERR
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 92a36c9e5402..2eff3ae8977d 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -298,9 +298,8 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
if (v->data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- nskb = skb_copy_expand(e->skb, 0,
- diff - skb_tailroom(e->skb),
- GFP_ATOMIC);
+ nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
+ diff, GFP_ATOMIC);
if (!nskb) {
printk(KERN_WARNING "ip6_queue: OOM "
"in mangle, dropping packet\n");
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index ca8b82f96fe5..df0736a4cafa 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -247,13 +247,11 @@ int snmp6_register_dev(struct inet6_dev *idev)
if (!proc_net_devsnmp6)
return -ENOENT;
- p = proc_create(idev->dev->name, S_IRUGO,
- proc_net_devsnmp6, &snmp6_seq_fops);
+ p = proc_create_data(idev->dev->name, S_IRUGO,
+ proc_net_devsnmp6, &snmp6_seq_fops, idev);
if (!p)
return -ENOMEM;
- p->data = idev;
-
idev->stats.proc_dir_entry = p;
return 0;
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 396f0ea11090..232e0dc45bf5 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -609,7 +609,6 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
struct ipv6_pinfo *np = inet6_sk(sk);
struct ipv6hdr *iph;
struct sk_buff *skb;
- unsigned int hh_len;
int err;
if (length > rt->u.dst.dev->mtu) {
@@ -619,13 +618,12 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
if (flags&MSG_PROBE)
goto out;
- hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
-
- skb = sock_alloc_send_skb(sk, length+hh_len+15,
- flags&MSG_DONTWAIT, &err);
+ skb = sock_alloc_send_skb(sk,
+ length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
+ flags & MSG_DONTWAIT, &err);
if (skb == NULL)
goto error;
- skb_reserve(skb, hh_len);
+ skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 7b247e3a16fe..798cabc7535b 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -197,6 +197,7 @@ static void ip6_frag_expire(unsigned long data)
{
struct frag_queue *fq;
struct net_device *dev = NULL;
+ struct net *net;
fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
@@ -207,7 +208,8 @@ static void ip6_frag_expire(unsigned long data)
fq_kill(fq);
- dev = dev_get_by_index(&init_net, fq->iif);
+ net = container_of(fq->q.net, struct net, ipv6.frags);
+ dev = dev_get_by_index(net, fq->iif);
if (!dev)
goto out;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a493ad9b8914..12bba0880345 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1243,11 +1243,11 @@ install_route:
}
}
- if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0)
+ if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0)
rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1;
- if (!rt->u.dst.metrics[RTAX_MTU-1])
+ if (!dst_metric(&rt->u.dst, RTAX_MTU))
rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev);
- if (!rt->u.dst.metrics[RTAX_ADVMSS-1])
+ if (!dst_metric(&rt->u.dst, RTAX_ADVMSS))
rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst));
rt->u.dst.dev = dev;
rt->rt6i_idev = idev;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 4b2f1033994e..5a6fab95569f 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -596,9 +596,9 @@ static int ipip6_rcv(struct sk_buff *skb)
}
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
- kfree_skb(skb);
read_unlock(&ipip6_lock);
out:
+ kfree_skb(skb);
return 0;
}
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index bfacef8b76f4..a6f99b5a1499 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -40,6 +40,8 @@
#include <net/irda/discovery.h>
+#include <asm/unaligned.h>
+
/*
* Function irlmp_add_discovery (cachelog, discovery)
*
@@ -87,7 +89,7 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
*/
hashbin_remove_this(cachelog, (irda_queue_t *) node);
/* Check if hints bits are unchanged */
- if(u16ho(node->data.hints) == u16ho(new->data.hints))
+ if (get_unaligned((__u16 *)node->data.hints) == get_unaligned((__u16 *)new->data.hints))
/* Set time of first discovery for this node */
new->firststamp = node->firststamp;
kfree(node);
@@ -281,9 +283,9 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn,
/* Mask out the ones we don't want :
* We want to match the discovery mask, and to get only
* the most recent one (unless we want old ones) */
- if ((u16ho(discovery->data.hints) & mask) &&
+ if ((get_unaligned((__u16 *)discovery->data.hints) & mask) &&
((old_entries) ||
- ((jiffies - discovery->firststamp) < j_timeout)) ) {
+ ((jiffies - discovery->firststamp) < j_timeout))) {
/* Create buffer as needed.
* As this function get called a lot and most time
* we don't have anything to put in the log (we are
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index d2620410cb0a..76c3057d0179 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -555,10 +555,8 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
ircomm_tty_shutdown(self);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
+ tty_ldisc_flush(tty);
tty->closing = 0;
self->tty = NULL;
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 9e15c82960fe..4a105dc32dcd 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -451,12 +451,14 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
n = 2;
/* Get length, MSB first */
- len = be16_to_cpu(get_unaligned((__be16 *)(fp+n))); n += 2;
+ len = get_unaligned_be16(fp + n);
+ n += 2;
IRDA_DEBUG(4, "%s(), len=%d\n", __func__, len);
/* Get object ID, MSB first */
- obj_id = be16_to_cpu(get_unaligned((__be16 *)(fp+n))); n += 2;
+ obj_id = get_unaligned_be16(fp + n);
+ n += 2;
type = fp[n++];
IRDA_DEBUG(4, "%s(), Value type = %d\n", __func__, type);
@@ -506,7 +508,7 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
value = irias_new_string_value(fp+n);
break;
case IAS_OCT_SEQ:
- value_len = be16_to_cpu(get_unaligned((__be16 *)(fp+n)));
+ value_len = get_unaligned_be16(fp + n);
n += 2;
/* Will truncate to IAS_MAX_OCTET_STRING bytes */
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 1f81f8e7c61d..7bf5b913828b 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -1062,7 +1062,8 @@ void irlmp_discovery_expiry(discinfo_t *expiries, int number)
for(i = 0; i < number; i++) {
/* Check if we should notify client */
if ((client->expir_callback) &&
- (client->hint_mask.word & u16ho(expiries[i].hints)
+ (client->hint_mask.word &
+ get_unaligned((__u16 *)expiries[i].hints)
& 0x7f7f) )
client->expir_callback(&(expiries[i]),
EXPIRY_TIMEOUT,
@@ -1086,7 +1087,7 @@ discovery_t *irlmp_get_discovery_response(void)
IRDA_ASSERT(irlmp != NULL, return NULL;);
- u16ho(irlmp->discovery_rsp.data.hints) = irlmp->hints.word;
+ put_unaligned(irlmp->hints.word, (__u16 *)irlmp->discovery_rsp.data.hints);
/*
* Set character set for device name (we use ASCII), and
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index a4f1439ffdd8..cf9a4b531a98 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -9,6 +9,8 @@
*/
#include "irnet_irda.h" /* Private header */
+#include <linux/seq_file.h>
+#include <asm/unaligned.h>
/*
* PPP disconnect work: we need to make sure we're in
@@ -1672,7 +1674,7 @@ irnet_discovery_indication(discinfo_t * discovery,
/* Notify the control channel */
irnet_post_event(NULL, IRNET_DISCOVER,
discovery->saddr, discovery->daddr, discovery->info,
- u16ho(discovery->hints));
+ get_unaligned((__u16 *)discovery->hints));
DEXIT(IRDA_OCB_TRACE, "\n");
}
@@ -1703,7 +1705,7 @@ irnet_expiry_indication(discinfo_t * expiry,
/* Notify the control channel */
irnet_post_event(NULL, IRNET_EXPIRE,
expiry->saddr, expiry->daddr, expiry->info,
- u16ho(expiry->hints));
+ get_unaligned((__u16 *)expiry->hints));
DEXIT(IRDA_OCB_TRACE, "\n");
}
@@ -1717,34 +1719,23 @@ irnet_expiry_indication(discinfo_t * expiry,
*/
#ifdef CONFIG_PROC_FS
-/*------------------------------------------------------------------*/
-/*
- * Function irnet_proc_read (buf, start, offset, len, unused)
- *
- * Give some info to the /proc file system
- */
static int
-irnet_proc_read(char * buf,
- char ** start,
- off_t offset,
- int len)
+irnet_proc_show(struct seq_file *m, void *v)
{
irnet_socket * self;
char * state;
int i = 0;
- len = 0;
-
/* Get the IrNET server information... */
- len += sprintf(buf+len, "IrNET server - ");
- len += sprintf(buf+len, "IrDA state: %s, ",
+ seq_printf(m, "IrNET server - ");
+ seq_printf(m, "IrDA state: %s, ",
(irnet_server.running ? "running" : "dead"));
- len += sprintf(buf+len, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
- len += sprintf(buf+len, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
+ seq_printf(m, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
+ seq_printf(m, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
/* Do we need to continue ? */
if(!irnet_server.running)
- return len;
+ return 0;
/* Protect access to the instance list */
spin_lock_bh(&irnet_server.spinlock);
@@ -1754,23 +1745,23 @@ irnet_proc_read(char * buf,
while(self != NULL)
{
/* Start printing info about the socket. */
- len += sprintf(buf+len, "\nIrNET socket %d - ", i++);
+ seq_printf(m, "\nIrNET socket %d - ", i++);
/* First, get the requested configuration */
- len += sprintf(buf+len, "Requested IrDA name: \"%s\", ", self->rname);
- len += sprintf(buf+len, "daddr: %08x, ", self->rdaddr);
- len += sprintf(buf+len, "saddr: %08x\n", self->rsaddr);
+ seq_printf(m, "Requested IrDA name: \"%s\", ", self->rname);
+ seq_printf(m, "daddr: %08x, ", self->rdaddr);
+ seq_printf(m, "saddr: %08x\n", self->rsaddr);
/* Second, get all the PPP info */
- len += sprintf(buf+len, " PPP state: %s",
+ seq_printf(m, " PPP state: %s",
(self->ppp_open ? "registered" : "unregistered"));
if(self->ppp_open)
{
- len += sprintf(buf+len, ", unit: ppp%d",
+ seq_printf(m, ", unit: ppp%d",
ppp_unit_number(&self->chan));
- len += sprintf(buf+len, ", channel: %d",
+ seq_printf(m, ", channel: %d",
ppp_channel_index(&self->chan));
- len += sprintf(buf+len, ", mru: %d",
+ seq_printf(m, ", mru: %d",
self->mru);
/* Maybe add self->flags ? Later... */
}
@@ -1789,10 +1780,10 @@ irnet_proc_read(char * buf,
state = "weird";
else
state = "idle";
- len += sprintf(buf+len, "\n IrDA state: %s, ", state);
- len += sprintf(buf+len, "daddr: %08x, ", self->daddr);
- len += sprintf(buf+len, "stsap_sel: %02x, ", self->stsap_sel);
- len += sprintf(buf+len, "dtsap_sel: %02x\n", self->dtsap_sel);
+ seq_printf(m, "\n IrDA state: %s, ", state);
+ seq_printf(m, "daddr: %08x, ", self->daddr);
+ seq_printf(m, "stsap_sel: %02x, ", self->stsap_sel);
+ seq_printf(m, "dtsap_sel: %02x\n", self->dtsap_sel);
/* Next socket, please... */
self = (irnet_socket *) hashbin_get_next(irnet_server.list);
@@ -1801,8 +1792,21 @@ irnet_proc_read(char * buf,
/* Spin lock end */
spin_unlock_bh(&irnet_server.spinlock);
- return len;
+ return 0;
}
+
+static int irnet_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, irnet_proc_show, NULL);
+}
+
+static const struct file_operations irnet_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = irnet_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
#endif /* PROC_FS */
@@ -1841,7 +1845,7 @@ irda_irnet_init(void)
#ifdef CONFIG_PROC_FS
/* Add a /proc file for irnet infos */
- create_proc_info_entry("irnet", 0, proc_irda, irnet_proc_read);
+ proc_create("irnet", 0, proc_irda, &irnet_proc_fops);
#endif /* CONFIG_PROC_FS */
/* Setup the IrNET server */
diff --git a/net/irda/irnet/irnet_irda.h b/net/irda/irnet/irnet_irda.h
index 0ba92d0d5204..3e408952a3f1 100644
--- a/net/irda/irnet/irnet_irda.h
+++ b/net/irda/irnet/irnet_irda.h
@@ -159,14 +159,6 @@ static void
DISCOVERY_MODE,
void *);
#endif
-/* -------------------------- PROC ENTRY -------------------------- */
-#ifdef CONFIG_PROC_FS
-static int
- irnet_proc_read(char *,
- char **,
- off_t,
- int);
-#endif /* CONFIG_PROC_FS */
/**************************** VARIABLES ****************************/
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 2403a31fe0f6..9e7236ff6bcc 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1498,7 +1498,8 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
err = xfrm_state_update(x);
xfrm_audit_state_add(x, err ? 0 : 1,
- audit_get_loginuid(current), 0);
+ audit_get_loginuid(current),
+ audit_get_sessionid(current), 0);
if (err < 0) {
x->km.state = XFRM_STATE_DEAD;
@@ -1552,7 +1553,8 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
km_state_notify(x, &c);
out:
xfrm_audit_state_delete(x, err ? 0 : 1,
- audit_get_loginuid(current), 0);
+ audit_get_loginuid(current),
+ audit_get_sessionid(current), 0);
xfrm_state_put(x);
return err;
@@ -1728,6 +1730,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
return -EINVAL;
audit_info.loginuid = audit_get_loginuid(current);
+ audit_info.sessionid = audit_get_sessionid(current);
audit_info.secid = 0;
err = xfrm_state_flush(proto, &audit_info);
if (err)
@@ -2324,7 +2327,8 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
hdr->sadb_msg_type != SADB_X_SPDUPDATE);
xfrm_audit_policy_add(xp, err ? 0 : 1,
- audit_get_loginuid(current), 0);
+ audit_get_loginuid(current),
+ audit_get_sessionid(current), 0);
if (err)
goto out;
@@ -2406,7 +2410,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
return -ENOENT;
xfrm_audit_policy_delete(xp, err ? 0 : 1,
- audit_get_loginuid(current), 0);
+ audit_get_loginuid(current),
+ audit_get_sessionid(current), 0);
if (err)
goto out;
@@ -2667,7 +2672,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
if (delete) {
xfrm_audit_policy_delete(xp, err ? 0 : 1,
- audit_get_loginuid(current), 0);
+ audit_get_loginuid(current),
+ audit_get_sessionid(current), 0);
if (err)
goto out;
@@ -2767,6 +2773,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
int err;
audit_info.loginuid = audit_get_loginuid(current);
+ audit_info.sessionid = audit_get_sessionid(current);
audit_info.secid = 0;
err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
if (err)
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 879e7210458a..19efc3a6a932 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -255,14 +255,23 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
{
char buf[50];
+ struct ieee80211_key *key;
if (!sdata->debugfsdir)
return;
- sprintf(buf, "../keys/%d", sdata->default_key->debugfs.cnt);
- sdata->debugfs.default_key =
- debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
+ /* this is running under the key lock */
+
+ key = sdata->default_key;
+ if (key) {
+ sprintf(buf, "../keys/%d", key->debugfs.cnt);
+ sdata->debugfs.default_key =
+ debugfs_create_symlink("default_key",
+ sdata->debugfsdir, buf);
+ } else
+ ieee80211_debugfs_key_remove_default(sdata);
}
+
void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
{
if (!sdata)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8e53ce7ed444..c7314bf4bec2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -354,7 +354,7 @@ struct ieee80211_if_sta {
int preq_queue_len;
struct mesh_stats mshstats;
struct mesh_config mshcfg;
- u8 mesh_seqnum[3];
+ u32 mesh_seqnum;
bool accepting_plinks;
#endif
u16 aid;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 80954a512185..06e88a5a036d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -54,6 +54,15 @@ int ieee80211_if_add(struct net_device *dev, const char *name,
if (!ndev)
return -ENOMEM;
+ ndev->needed_headroom = local->tx_headroom +
+ 4*6 /* four MAC addresses */
+ + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */
+ + 6 /* mesh */
+ + 8 /* rfc1042/bridge tunnel */
+ - ETH_HLEN /* ethernet hard_header_len */
+ + IEEE80211_ENCRYPT_HEADROOM;
+ ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
+
ret = dev_alloc_name(ndev, ndev->name);
if (ret < 0)
goto fail;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e9a978979d38..915afadb0602 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -255,22 +255,8 @@ static int ieee80211_open(struct net_device *dev)
switch (sdata->vif.type) {
case IEEE80211_IF_TYPE_WDS:
- if (is_zero_ether_addr(sdata->u.wds.remote_addr))
+ if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
return -ENOLINK;
-
- /* Create STA entry for the WDS peer */
- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
- GFP_KERNEL);
- if (!sta)
- return -ENOMEM;
-
- sta->flags |= WLAN_STA_AUTHORIZED;
-
- res = sta_info_insert(sta);
- if (res) {
- /* STA has been freed */
- return res;
- }
break;
case IEEE80211_IF_TYPE_VLAN:
if (!sdata->u.vlan.ap)
@@ -337,10 +323,8 @@ static int ieee80211_open(struct net_device *dev)
conf.type = sdata->vif.type;
conf.mac_addr = dev->dev_addr;
res = local->ops->add_interface(local_to_hw(local), &conf);
- if (res && !local->open_count && local->ops->stop)
- local->ops->stop(local_to_hw(local));
if (res)
- return res;
+ goto err_stop;
ieee80211_if_config(dev);
ieee80211_reset_erp_info(dev);
@@ -353,9 +337,29 @@ static int ieee80211_open(struct net_device *dev)
netif_carrier_on(dev);
}
+ if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
+ /* Create STA entry for the WDS peer */
+ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
+ GFP_KERNEL);
+ if (!sta) {
+ res = -ENOMEM;
+ goto err_del_interface;
+ }
+
+ sta->flags |= WLAN_STA_AUTHORIZED;
+
+ res = sta_info_insert(sta);
+ if (res) {
+ /* STA has been freed */
+ goto err_del_interface;
+ }
+ }
+
if (local->open_count == 0) {
res = dev_open(local->mdev);
WARN_ON(res);
+ if (res)
+ goto err_del_interface;
tasklet_enable(&local->tx_pending_tasklet);
tasklet_enable(&local->tasklet);
}
@@ -390,6 +394,12 @@ static int ieee80211_open(struct net_device *dev)
netif_start_queue(dev);
return 0;
+ err_del_interface:
+ local->ops->remove_interface(local_to_hw(local), &conf);
+ err_stop:
+ if (!local->open_count && local->ops->stop)
+ local->ops->stop(local_to_hw(local));
+ return res;
}
static int ieee80211_stop(struct net_device *dev)
@@ -975,6 +985,7 @@ static int __ieee80211_if_config(struct net_device *dev,
conf.ssid_len = sdata->u.sta.ssid_len;
} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
conf.beacon = beacon;
+ conf.beacon_control = control;
ieee80211_start_mesh(dev);
} else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
conf.ssid = sdata->u.ap.ssid;
@@ -1755,6 +1766,7 @@ fail_wep:
fail_rate:
ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
unregister_netdevice(local->mdev);
+ local->mdev = NULL;
fail_dev:
rtnl_unlock();
sta_info_stop(local);
@@ -1762,8 +1774,10 @@ fail_sta_info:
debugfs_hw_del(local);
destroy_workqueue(local->hw.workqueue);
fail_workqueue:
- ieee80211_if_free(local->mdev);
- local->mdev = NULL;
+ if (local->mdev != NULL) {
+ ieee80211_if_free(local->mdev);
+ local->mdev = NULL;
+ }
fail_mdev_alloc:
wiphy_unregister(local->hw.wiphy);
return result;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 594a3356a508..697ef67f96b6 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
+#include <asm/unaligned.h>
#include "ieee80211_i.h"
#include "mesh.h"
@@ -167,8 +168,8 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
struct rmc_entry *p, *n;
/* Don't care about endianness since only match matters */
- memcpy(&seqnum, mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum));
- idx = mesh_hdr->seqnum[0] & rmc->idx_mask;
+ memcpy(&seqnum, &mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum));
+ idx = le32_to_cpu(mesh_hdr->seqnum) & rmc->idx_mask;
list_for_each_entry_safe(p, n, &rmc->bucket[idx].list, list) {
++entries;
if (time_after(jiffies, p->exp_time) ||
@@ -393,18 +394,10 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
{
meshhdr->flags = 0;
meshhdr->ttl = sdata->u.sta.mshcfg.dot11MeshTTL;
+ put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum);
+ sdata->u.sta.mesh_seqnum++;
- meshhdr->seqnum[0] = sdata->u.sta.mesh_seqnum[0]++;
- meshhdr->seqnum[1] = sdata->u.sta.mesh_seqnum[1];
- meshhdr->seqnum[2] = sdata->u.sta.mesh_seqnum[2];
-
- if (sdata->u.sta.mesh_seqnum[0] == 0) {
- sdata->u.sta.mesh_seqnum[1]++;
- if (sdata->u.sta.mesh_seqnum[1] == 0)
- sdata->u.sta.mesh_seqnum[2]++;
- }
-
- return 5;
+ return 6;
}
void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 9ee3affab346..2e161f6d8288 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -140,7 +140,7 @@ struct rmc_entry {
struct mesh_rmc {
struct rmc_entry bucket[RMC_BUCKETS];
- u8 idx_mask;
+ u32 idx_mask;
};
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 3df809222d1c..af0cd1e3e213 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -120,7 +120,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
*pos++ = WLAN_EID_PREP;
break;
default:
- kfree(skb);
+ kfree_skb(skb);
return -ENOTSUPP;
break;
}
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 5845dc21ce85..99c2d360888e 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -158,19 +158,25 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0)
return -ENOSPC;
- read_lock(&pathtbl_resize_lock);
-
new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
if (!new_mpath) {
atomic_dec(&sdata->u.sta.mpaths);
err = -ENOMEM;
goto endadd2;
}
+ new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
+ if (!new_node) {
+ kfree(new_mpath);
+ atomic_dec(&sdata->u.sta.mpaths);
+ err = -ENOMEM;
+ goto endadd2;
+ }
+
+ read_lock(&pathtbl_resize_lock);
memcpy(new_mpath->dst, dst, ETH_ALEN);
new_mpath->dev = dev;
new_mpath->flags = 0;
skb_queue_head_init(&new_mpath->frame_queue);
- new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
new_node->mpath = new_mpath;
new_mpath->timer.data = (unsigned long) new_mpath;
new_mpath->timer.function = mesh_path_timer;
@@ -202,7 +208,6 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
endadd:
spin_unlock(&mesh_paths->hashwlock[hash_idx]);
-endadd2:
read_unlock(&pathtbl_resize_lock);
if (!err && grow) {
struct mesh_table *oldtbl, *newtbl;
@@ -215,10 +220,12 @@ endadd2:
return -ENOMEM;
}
rcu_assign_pointer(mesh_paths, newtbl);
+ write_unlock(&pathtbl_resize_lock);
+
synchronize_rcu();
mesh_table_free(oldtbl, false);
- write_unlock(&pathtbl_resize_lock);
}
+endadd2:
return err;
}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a5e5c31c23ab..4adba09e80ca 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -665,6 +665,26 @@ static void ieee80211_authenticate(struct net_device *dev,
mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
}
+static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss,
+ struct ieee80211_supported_band *sband,
+ u64 *rates)
+{
+ int i, j, count;
+ *rates = 0;
+ count = 0;
+ for (i = 0; i < bss->supp_rates_len; i++) {
+ int rate = (bss->supp_rates[i] & 0x7F) * 5;
+
+ for (j = 0; j < sband->n_bitrates; j++)
+ if (sband->bitrates[j].bitrate == rate) {
+ *rates |= BIT(j);
+ count++;
+ break;
+ }
+ }
+
+ return count;
+}
static void ieee80211_send_assoc(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
@@ -673,11 +693,12 @@ static void ieee80211_send_assoc(struct net_device *dev,
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
u8 *pos, *ies;
- int i, len;
+ int i, len, count, rates_len, supp_rates_len;
u16 capab;
struct ieee80211_sta_bss *bss;
int wmm = 0;
struct ieee80211_supported_band *sband;
+ u64 rates = 0;
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
@@ -740,24 +761,39 @@ static void ieee80211_send_assoc(struct net_device *dev,
*pos++ = ifsta->ssid_len;
memcpy(pos, ifsta->ssid, ifsta->ssid_len);
+ /* all supported rates should be added here but some APs
+ * (e.g. D-Link DAP 1353 in b-only mode) don't like that
+ * Therefore only add rates the AP supports */
+ rates_len = ieee80211_compatible_rates(bss, sband, &rates);
+ supp_rates_len = rates_len;
+ if (supp_rates_len > 8)
+ supp_rates_len = 8;
+
len = sband->n_bitrates;
- if (len > 8)
- len = 8;
- pos = skb_put(skb, len + 2);
+ pos = skb_put(skb, supp_rates_len + 2);
*pos++ = WLAN_EID_SUPP_RATES;
- *pos++ = len;
- for (i = 0; i < len; i++) {
- int rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
- }
+ *pos++ = supp_rates_len;
- if (sband->n_bitrates > len) {
- pos = skb_put(skb, sband->n_bitrates - len + 2);
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos++ = sband->n_bitrates - len;
- for (i = len; i < sband->n_bitrates; i++) {
+ count = 0;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if (BIT(i) & rates) {
int rate = sband->bitrates[i].bitrate;
*pos++ = (u8) (rate / 5);
+ if (++count == 8)
+ break;
+ }
+ }
+
+ if (count == 8) {
+ pos = skb_put(skb, rates_len - count + 2);
+ *pos++ = WLAN_EID_EXT_SUPP_RATES;
+ *pos++ = rates_len - count;
+
+ for (i++; i < sband->n_bitrates; i++) {
+ if (BIT(i) & rates) {
+ int rate = sband->bitrates[i].bitrate;
+ *pos++ = (u8) (rate / 5);
+ }
}
}
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index ae75d4178739..ff5c380f3c13 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -85,7 +85,7 @@ static int rate_control_pid_events_open(struct inode *inode, struct file *file)
struct rc_pid_sta_info *sinfo = inode->i_private;
struct rc_pid_event_buffer *events = &sinfo->events;
struct rc_pid_events_file_info *file_info;
- unsigned int status;
+ unsigned long status;
/* Allocate a state struct */
file_info = kmalloc(sizeof(*file_info), GFP_KERNEL);
@@ -135,7 +135,7 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
char pb[RC_PID_PRINT_BUF_SIZE];
int ret;
int p;
- unsigned int status;
+ unsigned long status;
/* Check if there is something to read. */
if (events->next_entry == file_info->next_entry) {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 02f436a86061..1958bfb361c6 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1305,11 +1305,11 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
if (is_multicast_ether_addr(skb->data)) {
if (*mesh_ttl > 0) {
xmit_skb = skb_copy(skb, GFP_ATOMIC);
- if (!xmit_skb && net_ratelimit())
+ if (xmit_skb)
+ xmit_skb->pkt_type = PACKET_OTHERHOST;
+ else if (net_ratelimit())
printk(KERN_DEBUG "%s: failed to clone "
"multicast frame\n", dev->name);
- else
- xmit_skb->pkt_type = PACKET_OTHERHOST;
} else
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.sta,
dropped_frames_ttl);
@@ -1395,7 +1395,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
padding = ((4 - subframe_len) & 0x3);
/* the last MSDU has no padding */
if (subframe_len > remaining) {
- printk(KERN_DEBUG "%s: wrong buffer size", dev->name);
+ printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name);
return RX_DROP_UNUSABLE;
}
@@ -1418,7 +1418,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
eth = (struct ethhdr *) skb_pull(skb, ntohs(len) +
padding);
if (!eth) {
- printk(KERN_DEBUG "%s: wrong buffer size ",
+ printk(KERN_DEBUG "%s: wrong buffer size\n",
dev->name);
dev_kfree_skb(frame);
return RX_DROP_UNUSABLE;
@@ -1952,7 +1952,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
if (!skb_new) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: failed to copy "
- "multicast frame for %s",
+ "multicast frame for %s\n",
wiphy_name(local->hw.wiphy),
prev->dev->name);
continue;
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index dddbfd60f351..09093da24af6 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -230,10 +230,8 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
iv16 = data[hdr_len] << 8;
iv16 += data[hdr_len + 2];
- iv32 = data[hdr_len + 4] +
- (data[hdr_len + 5] >> 8) +
- (data[hdr_len + 6] >> 16) +
- (data[hdr_len + 7] >> 24);
+ iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) |
+ (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24);
#ifdef CONFIG_TKIP_DEBUG
printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n",
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index f35eaea98e73..1d7dd54aacef 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1562,13 +1562,13 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
* be cloned. This could happen, e.g., with Linux bridge code passing
* us broadcast frames. */
- if (head_need > 0 || skb_cloned(skb)) {
+ if (head_need > 0 || skb_header_cloned(skb)) {
#if 0
printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes "
"of headroom\n", dev->name, head_need);
#endif
- if (skb_cloned(skb))
+ if (skb_header_cloned(skb))
I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
else
I802_DEBUG_INC(local->tx_expand_skb_head);
@@ -1898,6 +1898,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
control->flags |= IEEE80211_TXCTL_NO_ACK;
+ control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
control->retry_limit = 1;
control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index cc9f715c7bfc..24a465c4df09 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -153,15 +153,15 @@ int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
/* 7.1.3.5a.2 */
switch (ae) {
case 0:
- return 5;
+ return 6;
case 1:
- return 11;
+ return 12;
case 2:
- return 17;
+ return 18;
case 3:
- return 23;
+ return 24;
default:
- return 5;
+ return 6;
}
}
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 64faa3dc488f..dc1598b86004 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -394,7 +394,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
qd->handle);
if (!q->queues[i]) {
q->queues[i] = &noop_qdisc;
- printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i);
+ printk(KERN_ERR "%s child qdisc %i creation failed\n",
+ dev->name, i);
}
}
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index c1fc0f1a641c..aa8d80c35e28 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -90,6 +90,7 @@ config NF_CT_PROTO_DCCP
tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
depends on EXPERIMENTAL && NF_CONNTRACK
depends on NETFILTER_ADVANCED
+ default IP_DCCP
help
With this option enabled, the layer 3 independent connection
tracking code will be able to do state tracking on DCCP connections.
@@ -104,6 +105,7 @@ config NF_CT_PROTO_SCTP
tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
depends on EXPERIMENTAL && NF_CONNTRACK
depends on NETFILTER_ADVANCED
+ default IP_SCTP
help
With this option enabled, the layer 3 independent connection
tracking code will be able to do state tracking on SCTP connections.
@@ -532,6 +534,7 @@ config NETFILTER_XT_MATCH_DCCP
tristate '"dccp" protocol match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
+ default IP_DCCP
help
With this option enabled, you will be able to use the iptables
`dccp' match in order to match on DCCP source/destination ports
@@ -725,6 +728,7 @@ config NETFILTER_XT_MATCH_SCTP
tristate '"sctp" protocol match support (EXPERIMENTAL)'
depends on NETFILTER_XTABLES && EXPERIMENTAL
depends on NETFILTER_ADVANCED
+ default IP_SCTP
help
With this option enabled, you will be able to use the
`sctp' match in order to match on SCTP source/destination ports
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 4eac65c74ed0..c4b1799da5d7 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -104,7 +104,7 @@ nf_ct_get_tuple(const struct sk_buff *skb,
const struct nf_conntrack_l3proto *l3proto,
const struct nf_conntrack_l4proto *l4proto)
{
- NF_CT_TUPLE_U_BLANK(tuple);
+ memset(tuple, 0, sizeof(*tuple));
tuple->src.l3num = l3num;
if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
@@ -151,7 +151,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
const struct nf_conntrack_l3proto *l3proto,
const struct nf_conntrack_l4proto *l4proto)
{
- NF_CT_TUPLE_U_BLANK(inverse);
+ memset(inverse, 0, sizeof(*inverse));
inverse->src.l3num = orig->src.l3num;
if (l3proto->invert_tuple(inverse, orig) == 0)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 16774ecd1c4e..0edefcfc5949 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -472,6 +472,9 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
goto nla_put_failure;
nla_nest_end(skb, nest_parms);
+ if (ctnetlink_dump_id(skb, ct) < 0)
+ goto nla_put_failure;
+
if (events & IPCT_DESTROY) {
if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 9f4900069561..2f9bbc058b48 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -870,6 +870,7 @@ static int process_sdp(struct sk_buff *skb,
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+ struct nf_conn_help *help = nfct_help(ct);
unsigned int matchoff, matchlen;
unsigned int mediaoff, medialen;
unsigned int sdpoff;
@@ -959,6 +960,9 @@ static int process_sdp(struct sk_buff *skb,
if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK)
ret = nf_nat_sdp_session(skb, dptr, sdpoff, datalen, &rtp_addr);
+ if (ret == NF_ACCEPT && i > 0)
+ help->help.ct_sip_info.invite_cseq = cseq;
+
return ret;
}
static int process_invite_response(struct sk_buff *skb,
@@ -967,14 +971,14 @@ static int process_invite_response(struct sk_buff *skb,
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+ struct nf_conn_help *help = nfct_help(ct);
if ((code >= 100 && code <= 199) ||
(code >= 200 && code <= 299))
return process_sdp(skb, dptr, datalen, cseq);
- else {
+ else if (help->help.ct_sip_info.invite_cseq == cseq)
flush_expectations(ct, true);
- return NF_ACCEPT;
- }
+ return NF_ACCEPT;
}
static int process_update_response(struct sk_buff *skb,
@@ -983,14 +987,14 @@ static int process_update_response(struct sk_buff *skb,
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+ struct nf_conn_help *help = nfct_help(ct);
if ((code >= 100 && code <= 199) ||
(code >= 200 && code <= 299))
return process_sdp(skb, dptr, datalen, cseq);
- else {
+ else if (help->help.ct_sip_info.invite_cseq == cseq)
flush_expectations(ct, true);
- return NF_ACCEPT;
- }
+ return NF_ACCEPT;
}
static int process_prack_response(struct sk_buff *skb,
@@ -999,14 +1003,14 @@ static int process_prack_response(struct sk_buff *skb,
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+ struct nf_conn_help *help = nfct_help(ct);
if ((code >= 100 && code <= 199) ||
(code >= 200 && code <= 299))
return process_sdp(skb, dptr, datalen, cseq);
- else {
+ else if (help->help.ct_sip_info.invite_cseq == cseq)
flush_expectations(ct, true);
- return NF_ACCEPT;
- }
+ return NF_ACCEPT;
}
static int process_bye_request(struct sk_buff *skb,
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index b59871f6bdda..46ea542d0df9 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -296,11 +296,11 @@ static int nf_conntrack_standalone_init_proc(void)
pde = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops);
if (!pde)
goto out_nf_conntrack;
- pde = create_proc_entry("nf_conntrack", S_IRUGO, init_net.proc_net_stat);
+
+ pde = proc_create("nf_conntrack", S_IRUGO, init_net.proc_net_stat,
+ &ct_cpu_seq_fops);
if (!pde)
goto out_stat_nf_conntrack;
- pde->proc_fops = &ct_cpu_seq_fops;
- pde->owner = THIS_MODULE;
return 0;
out_stat_nf_conntrack:
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index bbd26893c0c4..582ec3efc8a5 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -214,7 +214,7 @@ int nf_queue(struct sk_buff *skb,
segs = skb_gso_segment(skb, 0);
kfree_skb(skb);
- if (unlikely(IS_ERR(segs)))
+ if (IS_ERR(segs))
return 1;
do {
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 2c9fe5c12894..3447025ce068 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -454,9 +454,8 @@ nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e)
if (data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- nskb = skb_copy_expand(e->skb, 0,
- diff - skb_tailroom(e->skb),
- GFP_ATOMIC);
+ nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
+ diff, GFP_ATOMIC);
if (!nskb) {
printk(KERN_WARNING "nf_queue: OOM "
"in mangle, dropping packet\n");
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index f52f7f810ac4..5d75cd86ebb3 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -787,7 +787,7 @@ static const struct file_operations xt_table_ops = {
.open = xt_table_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = seq_release_net,
};
static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos)
@@ -936,25 +936,24 @@ int xt_proto_init(struct net *net, int af)
#ifdef CONFIG_PROC_FS
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
- proc = proc_net_fops_create(net, buf, 0440, &xt_table_ops);
+ proc = proc_create_data(buf, 0440, net->proc_net, &xt_table_ops,
+ (void *)(unsigned long)af);
if (!proc)
goto out;
- proc->data = (void *)(unsigned long)af;
-
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
- proc = proc_net_fops_create(net, buf, 0440, &xt_match_ops);
+ proc = proc_create_data(buf, 0440, net->proc_net, &xt_match_ops,
+ (void *)(unsigned long)af);
if (!proc)
goto out_remove_tables;
- proc->data = (void *)(unsigned long)af;
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
- proc = proc_net_fops_create(net, buf, 0440, &xt_target_ops);
+ proc = proc_create_data(buf, 0440, net->proc_net, &xt_target_ops,
+ (void *)(unsigned long)af);
if (!proc)
goto out_remove_matches;
- proc->data = (void *)(unsigned long)af;
#endif
return 0;
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
index 3b2aa56833b9..9685b6fcbc81 100644
--- a/net/netfilter/xt_TCPOPTSTRIP.c
+++ b/net/netfilter/xt_TCPOPTSTRIP.c
@@ -90,7 +90,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
const struct xt_target *target, const void *targinfo)
{
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
- unsigned int tcphoff;
+ int tcphoff;
u_int8_t nexthdr;
nexthdr = ipv6h->nexthdr;
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index b15e7e2fa143..d7e8983cd37f 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -4,12 +4,11 @@
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/skbuff.h>
+#include <linux/math64.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_connbytes.h>
#include <net/netfilter/nf_conntrack.h>
-#include <asm/div64.h>
-
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("Xtables: Number of packets/bytes per connection matching");
@@ -82,7 +81,7 @@ connbytes_mt(const struct sk_buff *skb, const struct net_device *in,
break;
}
if (pkts != 0)
- what = div64_64(bytes, pkts);
+ what = div64_u64(bytes, pkts);
break;
}
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 40d344b21453..6809af542a2c 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -237,15 +237,15 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
hinfo->family = family;
hinfo->rnd_initialized = 0;
spin_lock_init(&hinfo->lock);
- hinfo->pde = proc_create(minfo->name, 0,
+ hinfo->pde =
+ proc_create_data(minfo->name, 0,
family == AF_INET ? hashlimit_procdir4 :
hashlimit_procdir6,
- &dl_file_ops);
+ &dl_file_ops, hinfo);
if (!hinfo->pde) {
vfree(hinfo);
return -1;
}
- hinfo->pde->data = hinfo;
setup_timer(&hinfo->timer, htable_gc, (unsigned long )hinfo);
hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval);
@@ -301,15 +301,15 @@ static int htable_create(struct xt_hashlimit_mtinfo1 *minfo,
hinfo->rnd_initialized = 0;
spin_lock_init(&hinfo->lock);
- hinfo->pde = proc_create(minfo->name, 0,
+ hinfo->pde =
+ proc_create_data(minfo->name, 0,
family == AF_INET ? hashlimit_procdir4 :
hashlimit_procdir6,
- &dl_file_ops);
+ &dl_file_ops, hinfo);
if (hinfo->pde == NULL) {
vfree(hinfo);
return -1;
}
- hinfo->pde->data = hinfo;
setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo);
hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval);
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index 500528d60cd7..c63e9333c755 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -179,3 +179,5 @@ module_exit(iprange_mt_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
+MODULE_ALIAS("ipt_iprange");
+MODULE_ALIAS("ip6t_iprange");
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index d282ad1570a7..0099da5b2591 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1780,6 +1780,7 @@ int __init netlbl_unlabel_defconf(void)
* messages so don't worry to much about these values. */
security_task_getsecid(current, &audit_info.secid);
audit_info.loginuid = 0;
+ audit_info.sessionid = 0;
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (entry == NULL)
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index b17d4203806e..68706b4e3bf8 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -107,7 +107,9 @@ struct audit_buffer *netlbl_audit_start_common(int type,
if (audit_buf == NULL)
return NULL;
- audit_log_format(audit_buf, "netlabel: auid=%u", audit_info->loginuid);
+ audit_log_format(audit_buf, "netlabel: auid=%u ses=%u",
+ audit_info->loginuid,
+ audit_info->sessionid);
if (audit_info->secid != 0 &&
security_secid_to_secctx(audit_info->secid,
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h
index 6d7f4ab46c2b..6caef8b20611 100644
--- a/net/netlabel/netlabel_user.h
+++ b/net/netlabel/netlabel_user.h
@@ -51,6 +51,7 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb,
{
audit_info->secid = NETLINK_CB(skb).sid;
audit_info->loginuid = NETLINK_CB(skb).loginuid;
+ audit_info->sessionid = NETLINK_CB(skb).sessionid;
}
/* NetLabel NETLINK I/O functions */
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 46f3e44bb83a..9b97f8006c9c 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1248,6 +1248,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
NETLINK_CB(skb).pid = nlk->pid;
NETLINK_CB(skb).dst_group = dst_group;
NETLINK_CB(skb).loginuid = audit_get_loginuid(current);
+ NETLINK_CB(skb).sessionid = audit_get_sessionid(current);
security_task_getsecid(current, &(NETLINK_CB(skb).sid));
memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 25070240d4ae..2cee87da4441 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -743,7 +743,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
if (len > dev->mtu+reserve)
goto out_unlock;
- skb = sock_alloc_send_skb(sk, len + LL_RESERVED_SPACE(dev),
+ skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
msg->msg_flags & MSG_DONTWAIT, &err);
if (skb==NULL)
goto out_unlock;
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 5053a53ba24f..bd593871c81e 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -1066,12 +1066,12 @@ out:
#ifdef CONFIG_PROC_FS
static void *rose_node_start(struct seq_file *seq, loff_t *pos)
- __acquires(rose_neigh_list_lock)
+ __acquires(rose_node_list_lock)
{
struct rose_node *rose_node;
int i = 1;
- spin_lock_bh(&rose_neigh_list_lock);
+ spin_lock_bh(&rose_node_list_lock);
if (*pos == 0)
return SEQ_START_TOKEN;
@@ -1090,9 +1090,9 @@ static void *rose_node_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void rose_node_stop(struct seq_file *seq, void *v)
- __releases(rose_neigh_list_lock)
+ __releases(rose_node_list_lock)
{
- spin_unlock_bh(&rose_neigh_list_lock);
+ spin_unlock_bh(&rose_node_list_lock);
}
static int rose_node_show(struct seq_file *seq, void *v)
diff --git a/net/rxrpc/ar-transport.c b/net/rxrpc/ar-transport.c
index bb282a6a19f0..64069c8769a5 100644
--- a/net/rxrpc/ar-transport.c
+++ b/net/rxrpc/ar-transport.c
@@ -184,12 +184,13 @@ void rxrpc_put_transport(struct rxrpc_transport *trans)
ASSERTCMP(atomic_read(&trans->usage), >, 0);
trans->put_time = get_seconds();
- if (unlikely(atomic_dec_and_test(&trans->usage)))
+ if (unlikely(atomic_dec_and_test(&trans->usage))) {
_debug("zombie");
/* let the reaper determine the timeout to avoid a race with
* overextending the timeout if the reaper is running at the
* same time */
rxrpc_queue_delayed_work(&rxrpc_transport_reap, 0);
+ }
_leave("");
}
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 64b2d136c78e..1d421d059caf 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -6,7 +6,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Authors: Jamal Hadi Salim (2005)
+ * Authors: Jamal Hadi Salim (2005-8)
*
*/
@@ -34,6 +34,7 @@ static struct tcf_hashinfo simp_hash_info = {
.lock = &simp_lock,
};
+#define SIMP_MAX_DATA 32
static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
{
struct tcf_defact *d = a->priv;
@@ -69,23 +70,28 @@ static int tcf_simp_release(struct tcf_defact *d, int bind)
return ret;
}
-static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata)
+static int alloc_defdata(struct tcf_defact *d, char *defdata)
{
- d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL);
+ d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL);
if (unlikely(!d->tcfd_defdata))
return -ENOMEM;
- d->tcfd_datalen = datalen;
+
return 0;
}
-static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata)
+static void reset_policy(struct tcf_defact *d, char *defdata,
+ struct tc_defact *p)
{
- kfree(d->tcfd_defdata);
- return alloc_defdata(d, datalen, defdata);
+ spin_lock_bh(&d->tcf_lock);
+ d->tcf_action = p->action;
+ memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
+ strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+ spin_unlock_bh(&d->tcf_lock);
}
static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
[TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) },
+ [TCA_DEF_DATA] = { .type = NLA_STRING, .len = SIMP_MAX_DATA },
};
static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
@@ -95,28 +101,24 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
struct tc_defact *parm;
struct tcf_defact *d;
struct tcf_common *pc;
- void *defdata;
- u32 datalen = 0;
+ char *defdata;
int ret = 0, err;
if (nla == NULL)
return -EINVAL;
- err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL);
+ err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy);
if (err < 0)
return err;
if (tb[TCA_DEF_PARMS] == NULL)
return -EINVAL;
- parm = nla_data(tb[TCA_DEF_PARMS]);
- defdata = nla_data(tb[TCA_DEF_DATA]);
- if (defdata == NULL)
+ if (tb[TCA_DEF_DATA] == NULL)
return -EINVAL;
- datalen = nla_len(tb[TCA_DEF_DATA]);
- if (datalen == 0)
- return -EINVAL;
+ parm = nla_data(tb[TCA_DEF_PARMS]);
+ defdata = nla_data(tb[TCA_DEF_DATA]);
pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info);
if (!pc) {
@@ -126,11 +128,12 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
return -ENOMEM;
d = to_defact(pc);
- ret = alloc_defdata(d, datalen, defdata);
+ ret = alloc_defdata(d, defdata);
if (ret < 0) {
kfree(pc);
return ret;
}
+ d->tcf_action = parm->action;
ret = ACT_P_CREATED;
} else {
d = to_defact(pc);
@@ -138,13 +141,9 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
tcf_simp_release(d, bind);
return -EEXIST;
}
- realloc_defdata(d, datalen, defdata);
+ reset_policy(d, defdata, parm);
}
- spin_lock_bh(&d->tcf_lock);
- d->tcf_action = parm->action;
- spin_unlock_bh(&d->tcf_lock);
-
if (ret == ACT_P_CREATED)
tcf_hash_insert(pc, &simp_hash_info);
return ret;
@@ -172,7 +171,7 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
opt.bindcnt = d->tcf_bindcnt - bind;
opt.action = d->tcf_action;
NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
- NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata);
+ NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index b741618e4d54..d355e5e47fe3 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -219,6 +219,7 @@ static void dev_watchdog(unsigned long arg)
printk(KERN_INFO "NETDEV WATCHDOG: %s: transmit timed out\n",
dev->name);
dev->tx_timeout(dev);
+ WARN_ON_ONCE(1);
}
if (!mod_timer(&dev->watchdog_timer, round_jiffies(jiffies + dev->watchdog_timeo)))
dev_hold(dev);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 66148cc4759e..5bc1ed490180 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1197,12 +1197,16 @@ static inline int htb_parent_last_child(struct htb_class *cl)
return 1;
}
-static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q)
+static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl,
+ struct Qdisc *new_q)
{
struct htb_class *parent = cl->parent;
BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity);
+ if (parent->cmode != HTB_CAN_SEND)
+ htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level);
+
parent->level = 0;
memset(&parent->un.inner, 0, sizeof(parent->un.inner));
INIT_LIST_HEAD(&parent->un.leaf.drop_list);
@@ -1300,7 +1304,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
htb_deactivate(q, cl);
if (last_child)
- htb_parent_to_leaf(cl, new_q);
+ htb_parent_to_leaf(q, cl, new_q);
if (--cl->refcnt == 0)
htb_destroy_class(sch, cl);
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index a20e2ef7704b..f0463d757a98 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -521,7 +521,8 @@ static void sfq_destroy(struct Qdisc *sch)
struct sfq_sched_data *q = qdisc_priv(sch);
tcf_destroy_chain(q->filter_list);
- del_timer(&q->perturb_timer);
+ q->perturb_period = 0;
+ del_timer_sync(&q->perturb_timer);
}
static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 81b606424e12..bbc7107c86cf 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2418,7 +2418,8 @@ static int sctp_process_param(struct sctp_association *asoc,
break;
case SCTP_PARAM_IPV6_ADDRESS:
- asoc->peer.ipv6_address = 1;
+ if (PF_INET6 == asoc->base.sk->sk_family)
+ asoc->peer.ipv6_address = 1;
break;
case SCTP_PARAM_HOST_NAME_ADDRESS:
@@ -2829,6 +2830,19 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
addr_param = (union sctp_addr_param *)
((void *)asconf_param + sizeof(sctp_addip_param_t));
+ switch (addr_param->v4.param_hdr.type) {
+ case SCTP_PARAM_IPV6_ADDRESS:
+ if (!asoc->peer.ipv6_address)
+ return SCTP_ERROR_INV_PARAM;
+ break;
+ case SCTP_PARAM_IPV4_ADDRESS:
+ if (!asoc->peer.ipv4_address)
+ return SCTP_ERROR_INV_PARAM;
+ break;
+ default:
+ return SCTP_ERROR_INV_PARAM;
+ }
+
af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
if (unlikely(!af))
return SCTP_ERROR_INV_PARAM;
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index d75530ff2a6d..c9966713282a 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -316,31 +316,28 @@ static int create_cache_proc_entries(struct cache_detail *cd)
cd->proc_ent->owner = cd->owner;
cd->channel_ent = cd->content_ent = NULL;
- p = proc_create("flush", S_IFREG|S_IRUSR|S_IWUSR,
- cd->proc_ent, &cache_flush_operations);
+ p = proc_create_data("flush", S_IFREG|S_IRUSR|S_IWUSR,
+ cd->proc_ent, &cache_flush_operations, cd);
cd->flush_ent = p;
if (p == NULL)
goto out_nomem;
p->owner = cd->owner;
- p->data = cd;
if (cd->cache_request || cd->cache_parse) {
- p = proc_create("channel", S_IFREG|S_IRUSR|S_IWUSR,
- cd->proc_ent, &cache_file_operations);
+ p = proc_create_data("channel", S_IFREG|S_IRUSR|S_IWUSR,
+ cd->proc_ent, &cache_file_operations, cd);
cd->channel_ent = p;
if (p == NULL)
goto out_nomem;
p->owner = cd->owner;
- p->data = cd;
}
if (cd->cache_show) {
- p = proc_create("content", S_IFREG|S_IRUSR|S_IWUSR,
- cd->proc_ent, &content_file_operations);
+ p = proc_create_data("content", S_IFREG|S_IRUSR|S_IWUSR,
+ cd->proc_ent, &content_file_operations, cd);
cd->content_ent = p;
if (p == NULL)
goto out_nomem;
p->owner = cd->owner;
- p->data = cd;
}
return 0;
out_nomem:
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index c6061a4346c8..50b049c6598a 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -224,16 +224,10 @@ EXPORT_SYMBOL_GPL(rpc_print_iostats);
static inline struct proc_dir_entry *
do_register(const char *name, void *data, const struct file_operations *fops)
{
- struct proc_dir_entry *ent;
-
rpc_proc_init();
dprintk("RPC: registering /proc/net/rpc/%s\n", name);
- ent = proc_create(name, 0, proc_net_rpc, fops);
- if (ent) {
- ent->data = data;
- }
- return ent;
+ return proc_create_data(name, 0, proc_net_rpc, fops, data);
}
struct proc_dir_entry *
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index d74c2d269539..01c7e311b904 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -18,7 +18,6 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/xdr.h>
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index 665e856675a4..b4f0525f91af 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -82,6 +82,6 @@ EXPORT_SYMBOL_GPL(register_net_sysctl_table);
void unregister_net_sysctl_table(struct ctl_table_header *header)
{
- return unregister_sysctl_table(header);
+ unregister_sysctl_table(header);
}
EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 325404fd4eb5..5a0e4878d3b7 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -279,15 +279,14 @@ static inline void k_term_timer(struct timer_list *timer)
/*
* TIPC message buffer code
*
- * TIPC message buffer headroom reserves space for a link-level header
- * (in case the message is sent off-node),
- * while ensuring TIPC header is word aligned for quicker access
+ * TIPC message buffer headroom reserves space for the worst-case
+ * link-level device header (in case the message is sent off-node).
*
- * The largest header currently supported is 18 bytes, which is used when
- * the standard 14 byte Ethernet header has 4 added bytes for VLAN info
+ * Note: Headroom should be a multiple of 4 to ensure the TIPC header fields
+ * are word aligned for quicker access
*/
-#define BUF_HEADROOM 20u
+#define BUF_HEADROOM LL_MAX_HEADER
struct tipc_skb_cb {
void *handle;
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 2519129c6d21..3f964db908a7 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -25,11 +25,11 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
struct dst_entry *dst = skb->dst;
int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
- skb_headroom(skb);
+ int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
- if (nhead > 0)
- return pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
+ if (nhead > 0 || ntail > 0)
+ return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
- /* Check tail too... */
return 0;
}
@@ -150,7 +150,7 @@ static int xfrm_output_gso(struct sk_buff *skb)
segs = skb_gso_segment(skb, 0);
kfree_skb(skb);
- if (unlikely(IS_ERR(segs)))
+ if (IS_ERR(segs))
return PTR_ERR(segs);
do {
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index e0c0390613c0..cae9fd815543 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -762,6 +762,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
if (err) {
xfrm_audit_policy_delete(pol, 0,
audit_info->loginuid,
+ audit_info->sessionid,
audit_info->secid);
return err;
}
@@ -777,6 +778,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
if (err) {
xfrm_audit_policy_delete(pol, 0,
audit_info->loginuid,
+ audit_info->sessionid,
audit_info->secid);
return err;
}
@@ -819,6 +821,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
write_unlock_bh(&xfrm_policy_lock);
xfrm_audit_policy_delete(pol, 1, audit_info->loginuid,
+ audit_info->sessionid,
audit_info->secid);
xfrm_policy_kill(pol);
@@ -841,6 +844,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
xfrm_audit_policy_delete(pol, 1,
audit_info->loginuid,
+ audit_info->sessionid,
audit_info->secid);
xfrm_policy_kill(pol);
killed++;
@@ -2472,14 +2476,14 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
}
void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
- u32 auid, u32 secid)
+ uid_t auid, u32 sessionid, u32 secid)
{
struct audit_buffer *audit_buf;
audit_buf = xfrm_audit_start("SPD-add");
if (audit_buf == NULL)
return;
- xfrm_audit_helper_usrinfo(auid, secid, audit_buf);
+ xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf);
audit_log_format(audit_buf, " res=%u", result);
xfrm_audit_common_policyinfo(xp, audit_buf);
audit_log_end(audit_buf);
@@ -2487,14 +2491,14 @@ void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
EXPORT_SYMBOL_GPL(xfrm_audit_policy_add);
void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
- u32 auid, u32 secid)
+ uid_t auid, u32 sessionid, u32 secid)
{
struct audit_buffer *audit_buf;
audit_buf = xfrm_audit_start("SPD-delete");
if (audit_buf == NULL)
return;
- xfrm_audit_helper_usrinfo(auid, secid, audit_buf);
+ xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf);
audit_log_format(audit_buf, " res=%u", result);
xfrm_audit_common_policyinfo(xp, audit_buf);
audit_log_end(audit_buf);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index fac27ce770d5..72fddafd891a 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -496,7 +496,8 @@ expired:
km_state_expired(x, 1, 0);
xfrm_audit_state_delete(x, err ? 0 : 1,
- audit_get_loginuid(current), 0);
+ audit_get_loginuid(current),
+ audit_get_sessionid(current), 0);
out:
spin_unlock(&x->lock);
@@ -603,6 +604,7 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
(err = security_xfrm_state_delete(x)) != 0) {
xfrm_audit_state_delete(x, 0,
audit_info->loginuid,
+ audit_info->sessionid,
audit_info->secid);
return err;
}
@@ -641,6 +643,7 @@ restart:
err = xfrm_state_delete(x);
xfrm_audit_state_delete(x, err ? 0 : 1,
audit_info->loginuid,
+ audit_info->sessionid,
audit_info->secid);
xfrm_state_put(x);
@@ -2123,14 +2126,14 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
}
void xfrm_audit_state_add(struct xfrm_state *x, int result,
- u32 auid, u32 secid)
+ uid_t auid, u32 sessionid, u32 secid)
{
struct audit_buffer *audit_buf;
audit_buf = xfrm_audit_start("SAD-add");
if (audit_buf == NULL)
return;
- xfrm_audit_helper_usrinfo(auid, secid, audit_buf);
+ xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf);
xfrm_audit_helper_sainfo(x, audit_buf);
audit_log_format(audit_buf, " res=%u", result);
audit_log_end(audit_buf);
@@ -2138,14 +2141,14 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result,
EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
void xfrm_audit_state_delete(struct xfrm_state *x, int result,
- u32 auid, u32 secid)
+ uid_t auid, u32 sessionid, u32 secid)
{
struct audit_buffer *audit_buf;
audit_buf = xfrm_audit_start("SAD-delete");
if (audit_buf == NULL)
return;
- xfrm_audit_helper_usrinfo(auid, secid, audit_buf);
+ xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf);
xfrm_audit_helper_sainfo(x, audit_buf);
audit_log_format(audit_buf, " res=%u", result);
audit_log_end(audit_buf);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 22a30ae582a2..a1b0fbe3ea35 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -407,6 +407,9 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
struct xfrm_state *x;
int err;
struct km_event c;
+ uid_t loginuid = NETLINK_CB(skb).loginuid;
+ u32 sessionid = NETLINK_CB(skb).sessionid;
+ u32 sid = NETLINK_CB(skb).sid;
err = verify_newsa_info(p, attrs);
if (err)
@@ -422,8 +425,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
else
err = xfrm_state_update(x);
- xfrm_audit_state_add(x, err ? 0 : 1, NETLINK_CB(skb).loginuid,
- NETLINK_CB(skb).sid);
+ xfrm_audit_state_add(x, err ? 0 : 1, loginuid, sessionid, sid);
if (err < 0) {
x->km.state = XFRM_STATE_DEAD;
@@ -478,6 +480,9 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
int err = -ESRCH;
struct km_event c;
struct xfrm_usersa_id *p = nlmsg_data(nlh);
+ uid_t loginuid = NETLINK_CB(skb).loginuid;
+ u32 sessionid = NETLINK_CB(skb).sessionid;
+ u32 sid = NETLINK_CB(skb).sid;
x = xfrm_user_state_lookup(p, attrs, &err);
if (x == NULL)
@@ -502,8 +507,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
km_state_notify(x, &c);
out:
- xfrm_audit_state_delete(x, err ? 0 : 1, NETLINK_CB(skb).loginuid,
- NETLINK_CB(skb).sid);
+ xfrm_audit_state_delete(x, err ? 0 : 1, loginuid, sessionid, sid);
xfrm_state_put(x);
return err;
}
@@ -1123,6 +1127,9 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
struct km_event c;
int err;
int excl;
+ uid_t loginuid = NETLINK_CB(skb).loginuid;
+ u32 sessionid = NETLINK_CB(skb).sessionid;
+ u32 sid = NETLINK_CB(skb).sid;
err = verify_newpolicy_info(p);
if (err)
@@ -1141,8 +1148,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
* a type XFRM_MSG_UPDPOLICY - JHS */
excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
err = xfrm_policy_insert(p->dir, xp, excl);
- xfrm_audit_policy_add(xp, err ? 0 : 1, NETLINK_CB(skb).loginuid,
- NETLINK_CB(skb).sid);
+ xfrm_audit_policy_add(xp, err ? 0 : 1, loginuid, sessionid, sid);
if (err) {
security_xfrm_policy_free(xp->security);
@@ -1371,9 +1377,12 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
NETLINK_CB(skb).pid);
}
} else {
- xfrm_audit_policy_delete(xp, err ? 0 : 1,
- NETLINK_CB(skb).loginuid,
- NETLINK_CB(skb).sid);
+ uid_t loginuid = NETLINK_CB(skb).loginuid;
+ u32 sessionid = NETLINK_CB(skb).sessionid;
+ u32 sid = NETLINK_CB(skb).sid;
+
+ xfrm_audit_policy_delete(xp, err ? 0 : 1, loginuid, sessionid,
+ sid);
if (err != 0)
goto out;
@@ -1399,6 +1408,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
int err;
audit_info.loginuid = NETLINK_CB(skb).loginuid;
+ audit_info.sessionid = NETLINK_CB(skb).sessionid;
audit_info.secid = NETLINK_CB(skb).sid;
err = xfrm_state_flush(p->proto, &audit_info);
if (err)
@@ -1546,6 +1556,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
return err;
audit_info.loginuid = NETLINK_CB(skb).loginuid;
+ audit_info.sessionid = NETLINK_CB(skb).sessionid;
audit_info.secid = NETLINK_CB(skb).sid;
err = xfrm_policy_flush(type, &audit_info);
if (err)
@@ -1604,9 +1615,11 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
read_unlock(&xp->lock);
err = 0;
if (up->hard) {
+ uid_t loginuid = NETLINK_CB(skb).loginuid;
+ uid_t sessionid = NETLINK_CB(skb).sessionid;
+ u32 sid = NETLINK_CB(skb).sid;
xfrm_policy_delete(xp, p->dir);
- xfrm_audit_policy_delete(xp, 1, NETLINK_CB(skb).loginuid,
- NETLINK_CB(skb).sid);
+ xfrm_audit_policy_delete(xp, 1, loginuid, sessionid, sid);
} else {
// reset the timers here?
@@ -1640,9 +1653,11 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
km_state_expired(x, ue->hard, current->pid);
if (ue->hard) {
+ uid_t loginuid = NETLINK_CB(skb).loginuid;
+ uid_t sessionid = NETLINK_CB(skb).sessionid;
+ u32 sid = NETLINK_CB(skb).sid;
__xfrm_state_delete(x);
- xfrm_audit_state_delete(x, 1, NETLINK_CB(skb).loginuid,
- NETLINK_CB(skb).sid);
+ xfrm_audit_state_delete(x, 1, loginuid, sessionid, sid);
}
err = 0;
out: