Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] sh_eth: remove 'register_type' field from 'struct sh_eth_plat_data'
From: Sergei Shtylyov @ 2013-08-21 12:49 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: netdev, davem, lethal, linux-sh
In-Reply-To: <20555348.Y63SQY2deS@avalon>

Hello.

On 21-08-2013 4:39, Laurent Pinchart wrote:

>>>>>>> Now that the 'register_type' field of the 'sh_eth' driver's platform
>>>>>>> data is not used by the driver anymore, it's time to remove it and
>>>>>>> its initializers from the SH platform code. Also  move *enum*
>>>>>>> declaring values for this  field from <linux/sh_eth.h>  to  the  local
>>>>>>> driver's header file as they're only needed by the driver itself
>>>>>>> now...

>>>>>>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

>>>> [...]

>>>>>>>     /* Driver's parameters */
>>>>>>>     #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
>>>>>>>     #define SH4_SKB_RX_ALIGN    32
>>>>>>>
>>>>>>> Index: net-next/include/linux/sh_eth.h
>>>>>>> ===================================================================
>>>>>>> --- net-next.orig/include/linux/sh_eth.h
>>>>>>> +++ net-next/include/linux/sh_eth.h
>>>>>>> @@ -5,17 +5,10 @@
>>>>>>>
>>>>>>>     #include <linux/if_ether.h>
>>>>>>>
>>>>>>>     enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
>>>>>>>
>>>>>>> -enum {
>>>>>>> -    SH_ETH_REG_GIGABIT,
>>>>>>> -    SH_ETH_REG_FAST_RCAR,
>>>>>>> -    SH_ETH_REG_FAST_SH4,
>>>>>>> -    SH_ETH_REG_FAST_SH3_SH2
>>>>>>> -};
>>>>>>>
>>>>>>>     struct sh_eth_plat_data {
>>>>>>>
>>>>>>>         int phy;
>>>>>>>         int edmac_endian;

>>>>>> Wouldn't it make sense to move the edmac_endian field to
>>>>>> sh_eth_cpu_data as well ?

>>>>> No, it depends on the SoC endianness which is determined by power-on pin
>>>>> strapping -- which is board specific.

>>> Does SoC endianness affect the ARM core endianness, the ethernet registers
>>> endianness, or both ?

>> Both, AFAIK.

>>> If it affects the ARM core endianness only, the kernel needs to be
>>> compiled in little-endian or big-endian mode anyway, and the sh_eth driver
>>> should use cpu_to_le32() unconditionally. If it affects both the ARM core
>>> and the ethernet controller there's not need to care about the endianness,
>>> as it will always be good.

>> No, it won't unless you're using __raw_{readl|writel}() accessors. The
>> driver doesn't do it. {readl|writel}() and io{read|write}32() that use them
>> always assume LE ordering of memory.

>>> We only need to care about it if it affects the ethernet controller
>>> registers only, which would seem weird to me.

>> Unfortunately, you are wrong.

> Care to explain *why* ? There might be bugs in the driver (such as using the
> wrong I/O accessors), but I don't see why we need to configure the endianness
> through platform data.

    Re-read my reply about the power-on pin strapping please. The SoC 
endianness setting gets read from the external source to the SoC, i.e. it's 
determined by the board.

WBR, Sergei


^ permalink raw reply

* [PATCH v3] KPortReserve : kernel version of portreserve utility
From: Tetsuo Handa @ 2013-08-21 12:39 UTC (permalink / raw)
  To: linux-kernel, linux-security-module, netdev
In-Reply-To: <201308111150.EJG69287.LtOFFMOOFJSHQV@I-love.SAKURA.ne.jp>

Hello.

A good summary on this proposal written by Jake Edge is available at
http://lwn.net/SubscriberLink/563178/c8a2e2fd4a794a9e/ .

Changes from version 2:

(1) Report number of rejections, the name of process and its pid, up to once
    per a minute, in order to be able to figure out unexpected rejection
    which could be caused by misconfiguration / misunderstanding.

    Aug 21 21:28:38 localhost kernel: [  139.438347] KPortReserve:(#1): Rejected bind(22) by /root/testapp1 (pid=4636)
    Aug 21 21:31:25 localhost kernel: [  306.755200] KPortReserve:(#3): Rejected bind(80) by /root/testapp2 (pid=4688)

(2) Updated Kconfig help.

Regards.
--------------------
>From efc84232e6df17ad0a7359fb9f4b72b4f4a02ed6 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Wed, 21 Aug 2013 21:19:28 +0900
Subject: [PATCH v3] KPortReserve : kernel version of portreserve utility

This module reserves local port like /proc/sys/net/ipv4/ip_local_reserved_ports
does, but this module is designed for stopping bind() requests with non-zero
local port numbers from unwanted programs.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 security/Kconfig               |    6 +
 security/Makefile              |    2 +
 security/kportreserve/Kconfig  |   43 +++
 security/kportreserve/Makefile |    1 +
 security/kportreserve/kpr.c    |  573 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 625 insertions(+), 0 deletions(-)
 create mode 100644 security/kportreserve/Kconfig
 create mode 100644 security/kportreserve/Makefile
 create mode 100644 security/kportreserve/kpr.c

diff --git a/security/Kconfig b/security/Kconfig
index e9c6ac7..f4058ff 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -122,6 +122,7 @@ source security/smack/Kconfig
 source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 source security/yama/Kconfig
+source security/kportreserve/Kconfig
 
 source security/integrity/Kconfig
 
@@ -132,6 +133,7 @@ choice
 	default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
 	default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
 	default DEFAULT_SECURITY_YAMA if SECURITY_YAMA
+	default DEFAULT_SECURITY_KPR if SECURITY_KPR
 	default DEFAULT_SECURITY_DAC
 
 	help
@@ -153,6 +155,9 @@ choice
 	config DEFAULT_SECURITY_YAMA
 		bool "Yama" if SECURITY_YAMA=y
 
+	config DEFAULT_SECURITY_KPR
+		bool "KPortReserve" if SECURITY_KPR=y
+
 	config DEFAULT_SECURITY_DAC
 		bool "Unix Discretionary Access Controls"
 
@@ -165,6 +170,7 @@ config DEFAULT_SECURITY
 	default "tomoyo" if DEFAULT_SECURITY_TOMOYO
 	default "apparmor" if DEFAULT_SECURITY_APPARMOR
 	default "yama" if DEFAULT_SECURITY_YAMA
+	default "kpr" if DEFAULT_SECURITY_KPR
 	default "" if DEFAULT_SECURITY_DAC
 
 endmenu
diff --git a/security/Makefile b/security/Makefile
index c26c81e..87f95cc 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -8,6 +8,7 @@ subdir-$(CONFIG_SECURITY_SMACK)		+= smack
 subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR)	+= apparmor
 subdir-$(CONFIG_SECURITY_YAMA)		+= yama
+subdir-$(CONFIG_SECURITY_KPR)		+= kportreserve
 
 # always enable default capabilities
 obj-y					+= commoncap.o
@@ -23,6 +24,7 @@ obj-$(CONFIG_AUDIT)			+= lsm_audit.o
 obj-$(CONFIG_SECURITY_TOMOYO)		+= tomoyo/built-in.o
 obj-$(CONFIG_SECURITY_APPARMOR)		+= apparmor/built-in.o
 obj-$(CONFIG_SECURITY_YAMA)		+= yama/built-in.o
+obj-$(CONFIG_SECURITY_KPR)		+= kportreserve/built-in.o
 obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
 
 # Object integrity file lists
diff --git a/security/kportreserve/Kconfig b/security/kportreserve/Kconfig
new file mode 100644
index 0000000..41049ae
--- /dev/null
+++ b/security/kportreserve/Kconfig
@@ -0,0 +1,43 @@
+config SECURITY_KPR
+	bool "KPortReserve support"
+	depends on SECURITY
+	select SECURITY_NETWORK
+	select SECURITY_FS
+	default n
+	help
+	  This selects local port reserving module which is similar to
+	  /proc/sys/net/ipv4/ip_local_reserved_ports . But this module is
+	  designed for stopping bind() requests with non-zero local port
+	  numbers from unwanted programs using white list reservations.
+
+	  If you are unsure how to answer this question, answer N.
+
+	  Specifications:
+
+	  Use "$port $identifier" format to add reservation.
+	  Use "del $port $identifier" format to remove reservation.
+
+	  The $port is a single port number between 0 and 65535.
+	  The $identifier is an identifier word in TOMOYO's string
+	  representation rule (i.e. consists with only ASCII printable
+	  characters). Upon successful execve() operation, $identifier is
+	  automatically replaced with the filename passed to execve()
+	  operation succeeds. For example, $identifier of current thread will
+	  be changed to /usr/sbin/httpd if execve("/usr/sbin/httpd") succeeds.
+	  The kernel threads get <kernel> as the identifier, with an exception
+	  that the userspace processes will also get <kernel> as the identifier
+	  if execve("<kernel>") (i.e. executing a program named <kernel>
+	  located in the current directory) succeeds.
+
+	  Example:
+
+	  Configuring
+
+	  # echo "10000 /bin/bash" > /sys/kernel/security/kportreserve/entry
+	  # echo "20000 <kernel>" > /sys/kernel/security/kportreserve/entry
+
+	  will allow /bin/bash to bind() on port 10000 and allow <kernel> to
+	  bind() on port 20000.
+
+	  Note that only port numbers which have at least one reservation are
+	  checked by this module.
diff --git a/security/kportreserve/Makefile b/security/kportreserve/Makefile
new file mode 100644
index 0000000..6342521
--- /dev/null
+++ b/security/kportreserve/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SECURITY_KPR) := kpr.o
diff --git a/security/kportreserve/kpr.c b/security/kportreserve/kpr.c
new file mode 100644
index 0000000..67bfdcb
--- /dev/null
+++ b/security/kportreserve/kpr.c
@@ -0,0 +1,573 @@
+/*
+ * kpr.c - kernel version of portreserve.
+ */
+#include <linux/security.h>
+#include <linux/vmalloc.h>
+#include <linux/net.h>
+#include <linux/inet.h>
+#include <linux/uaccess.h>
+#include <linux/binfmts.h>
+#include <net/sock.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+
+/* Max length of a line. */
+#define MAX_LINE_LEN 16384
+
+/* Port numbers with at least one whitelist element exists. */
+static unsigned long reserved_port_map[65536 / BITS_PER_LONG];
+
+/* Whitelist element. */
+struct reserved_port_entry {
+	struct list_head list;
+	u16 port;
+	char id[0];
+};
+/* List of whitelist elements. */
+static LIST_HEAD(reserved_port_list);
+
+/* Per a "struct cred" info. */
+struct task_name_info {
+	atomic_t users;
+	char id[0];
+};
+
+/**
+ * kpr_cred_alloc_blank - Target for security_cred_alloc_blank().
+ *
+ * @new: Pointer to "struct cred".
+ * @gfp: Memory allocation flags.
+ *
+ * Returns 0.
+ */
+static int kpr_cred_alloc_blank(struct cred *new, gfp_t gfp)
+{
+	new->security = NULL;
+	return 0;
+}
+
+/**
+ * kpr_cred_prepare - Target for security_prepare_creds().
+ *
+ * @new: Pointer to "struct cred".
+ * @old: Pointer to "struct cred".
+ * @gfp: Memory allocation flags.
+ *
+ * Returns 0.
+ */
+static int kpr_cred_prepare(struct cred *new, const struct cred *old,
+			       gfp_t gfp)
+{
+	struct task_name_info *info = old->security;
+	new->security = info;
+	if (info)
+		atomic_inc(&info->users);
+	return 0;
+}
+
+/**
+ * kpr_cred_transfer - Target for security_transfer_creds().
+ *
+ * @new: Pointer to "struct cred".
+ * @old: Pointer to "struct cred".
+ */
+static void kpr_cred_transfer(struct cred *new, const struct cred *old)
+{
+	kpr_cred_prepare(new, old, 0);
+}
+
+/**
+ * kpr_cred_free - Target for security_cred_free().
+ *
+ * @cred: Pointer to "struct cred".
+ */
+static void kpr_cred_free(struct cred *cred)
+{
+	struct task_name_info *info = cred->security;
+	if (info && atomic_dec_and_test(&info->users))
+		kfree(info);
+}
+
+/**
+ * kpr_make_info - Encode binary string to ascii string.
+ *
+ * @str: String in binary format.
+ *
+ * Returns pointer to "struct task_info_name" with @str in ascii format on
+ * success, NULL otherwise.
+ *
+ * This function uses kmalloc(), so caller must kfree() if this function
+ * didn't return NULL.
+ */
+static struct task_name_info *kpr_make_info(const char *str)
+{
+	int i;
+	int len = 0;
+	struct task_name_info *info;
+	const char *p = str;
+	char *cp;
+	const int str_len = strlen(str);
+
+	for (i = 0; i < str_len; i++) {
+		const unsigned char c = p[i];
+		if (c == '\\')
+			len += 2;
+		else if (c > ' ' && c < 127)
+			len++;
+		else
+			len += 4;
+	}
+	len++;
+	info = kmalloc(sizeof(*info) + len, GFP_KERNEL);
+	if (!info)
+		return NULL;
+	atomic_set(&info->users, 1);
+	cp = info->id;
+	p = str;
+	for (i = 0; i < str_len; i++) {
+		const unsigned char c = p[i];
+		if (c == '\\') {
+			*cp++ = '\\';
+			*cp++ = '\\';
+		} else if (c > ' ' && c < 127) {
+			*cp++ = c;
+		} else {
+			*cp++ = '\\';
+			*cp++ = (c >> 6) + '0';
+			*cp++ = ((c >> 3) & 7) + '0';
+			*cp++ = (c & 7) + '0';
+		}
+	}
+	*cp = '\0';
+	return info;
+}
+
+/**
+ * kpr_correct_word - Validate a string.
+ *
+ * @string: The string to check.
+ *
+ * Check whether the given string follows the naming rules.
+ * Returns true if @string follows the naming rules, false otherwise.
+ */
+static bool kpr_correct_word(const char *string)
+{
+	if (!*string)
+		return false;
+	while (1) {
+		unsigned char c = *string++;
+		if (!c)
+			return true;
+		if (c == '\\') {
+			c = *string++;
+			switch (c) {
+			case '\\':  /* "\\" */
+				continue;
+			case '0':   /* "\ooo" */
+			case '1':
+			case '2':
+			case '3':
+				{
+					unsigned char d;
+					unsigned char e;
+					c -= '0';
+					d = *string++ - '0';
+					if (d > 7)
+						break;
+					e = *string++ - '0';
+					if (e > 7)
+						break;
+					c = (c << 6) + (d << 3) + (e);
+					if (c <= ' ' || c >= 127)
+						continue;
+				}
+			}
+			return false;
+		} else if (c <= ' ' || c >= 127) {
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * kpr_bprm_set_creds - Target for security_bprm_set_creds().
+ *
+ * @bprm: Pointer to "struct linux_binprm".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int kpr_bprm_set_creds(struct linux_binprm *bprm)
+{
+	const int rc = cap_bprm_set_creds(bprm);
+
+	if (rc)
+		return rc;
+	if (!bprm->cred_prepared) {
+		struct task_name_info *info = kpr_make_info(bprm->filename);
+
+		if (!info)
+			return -ENOMEM;
+		kpr_cred_free(bprm->cred);
+		bprm->cred->security = info;
+	}
+	return 0;
+}
+
+
+/**
+ * kpr_socket_bind - Check permission for bind().
+ *
+ * @sock:     Pointer to "struct socket".
+ * @addr:     Pointer to "struct sockaddr".
+ * @addr_len: Size of @addr.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int kpr_socket_bind(struct socket *sock, struct sockaddr *addr,
+			   int addr_len)
+{
+	u16 port;
+	switch (sock->sk->sk_family) {
+	case PF_INET:
+	case PF_INET6:
+		break;
+	default:
+		return 0;
+	}
+	switch (sock->type) {
+	case SOCK_STREAM:
+	case SOCK_DGRAM:
+		break;
+	default:
+		return 0;
+	}
+	switch (addr->sa_family) {
+	case AF_INET:
+		if (addr_len < sizeof(struct sockaddr_in))
+			return 0;
+		port = ((struct sockaddr_in *) addr)->sin_port;
+		break;
+	case AF_INET6:
+		if (addr_len < SIN6_LEN_RFC2133)
+			return 0;
+		port = ((struct sockaddr_in6 *) addr)->sin6_port;
+		break;
+	default:
+		return 0;
+	}
+	port = ntohs(port);
+	if (!test_bit(port, reserved_port_map))
+		return 0;
+	{
+		static atomic_t counter = ATOMIC_INIT(0);
+		static u64 last_time;
+		u64 now_time;
+		struct reserved_port_entry *ptr;
+		bool reserved = false;
+		const char *id = ((struct task_name_info *)
+				  current_security())->id;
+
+		rcu_read_lock();
+		list_for_each_entry_rcu(ptr, &reserved_port_list, list) {
+			if (port != ptr->port)
+				continue;
+			if (strcmp(id, ptr->id)) {
+				reserved = true;
+				continue;
+			}
+			reserved = false;
+			break;
+		}
+		rcu_read_unlock();
+		if (!reserved)
+			return 0;
+		/*
+		 * Notify up to once per a minute, in case of rejection by
+		 * inappropriate configuration.
+		 */
+		now_time = jiffies_64;
+		atomic_inc(&counter);
+		if (!last_time || now_time > last_time + 60 * HZ) {
+			last_time = now_time;
+			pr_info("KPortReserve:(#%u): Rejected bind(%d) by %s (pid=%d)\n",
+				atomic_read(&counter), port, id, current->pid);
+		}
+		return -EADDRINUSE;
+	}
+}
+
+/**
+ * kpr_entry_read - Read current configuration.
+ *
+ * @file:  Pointer to "struct file".
+ * @buf:   Pointer to buffer.
+ * @count: Size of @buf.
+ * @ppos:  Offset of @file.
+ *
+ * Returns bytes read on success, negative value otherwise.
+ */
+static ssize_t kpr_entry_read(struct file *file, char __user *buf,
+			      size_t count, loff_t *ppos)
+{
+	ssize_t copied = 0;
+	int error = 0;
+	int record = 0;
+	loff_t offset = 0;
+	char *data = vmalloc(MAX_LINE_LEN);
+	if (!data)
+		return -ENOMEM;
+	while (1) {
+		struct reserved_port_entry *ptr;
+		int i = 0;
+		data[0] = '\0';
+		rcu_read_lock();
+		list_for_each_entry_rcu(ptr, &reserved_port_list, list) {
+			if (i++ < record)
+				continue;
+			snprintf(data, MAX_LINE_LEN - 1, "%u %s\n", ptr->port,
+				 ptr->id);
+			break;
+		}
+		rcu_read_unlock();
+		if (!data[0])
+			break;
+		for (i = 0; data[i]; i++) {
+			if (offset++ < *ppos)
+				continue;
+			if (put_user(data[i], buf)) {
+				error = -EFAULT;
+				break;
+			}
+			buf++;
+			copied++;
+			(*ppos)++;
+		}
+		record++;
+	}
+	vfree(data);
+	return copied ? copied : error;
+}
+
+/**
+ * kpr_normalize_line - Format string.
+ *
+ * @buffer: The line to normalize.
+ *
+ * Returns nothing.
+ *
+ * Leading and trailing whitespaces are removed.
+ * Multiple whitespaces are packed into single space.
+ */
+static void kpr_normalize_line(unsigned char *buffer)
+{
+	unsigned char *sp = buffer;
+	unsigned char *dp = buffer;
+	bool first = true;
+	while (*sp && (*sp <= ' ' || *sp >= 127))
+		sp++;
+	while (*sp) {
+		if (!first)
+			*dp++ = ' ';
+		first = false;
+		while (*sp > ' ' && *sp < 127)
+			*dp++ = *sp++;
+		while (*sp && (*sp <= ' ' || *sp >= 127))
+			sp++;
+	}
+	*dp = '\0';
+}
+
+/**
+ * kpr_find_entry - Find an existing entry.
+ *
+ * @port: Port number.
+ * @id:   Identifier. NULL for any.
+ *
+ * Returns pointer to existing entry if found, NULL otherwise.
+ */
+static struct reserved_port_entry *kpr_find_entry(const u16 port,
+						  const char *id)
+{
+	struct reserved_port_entry *ptr;
+	bool found = false;
+	rcu_read_lock();
+	list_for_each_entry_rcu(ptr, &reserved_port_list, list) {
+		if (port != ptr->port)
+			continue;
+		if (id && strcmp(id, ptr->id))
+			continue;
+		found = true;
+		break;
+	}
+	rcu_read_unlock();
+	return found ? ptr : NULL;
+}
+
+/**
+ * kpr_update_entry - Update the list of whitelist elements.
+ *
+ * @data: Line of data to parse.
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds a mutex to protect from concurrent updates.
+ */
+static int kpr_update_entry(const char *data)
+{
+	struct reserved_port_entry *ptr;
+	unsigned int port;
+	int len;
+	if (sscanf(data, "%u", &port) == 1 && port < 65536) {
+		const char *cp = strchr(data, ' ');
+		if (!cp++ || !kpr_correct_word(cp))
+			return -EINVAL;
+		if (kpr_find_entry(port, cp))
+			return 0;
+		len = strlen(cp) + 1;
+		ptr = kmalloc(sizeof(*ptr) + len, GFP_KERNEL);
+		if (!ptr)
+			return -ENOMEM;
+		ptr->port = (u16) port;
+		strcpy(ptr->id, cp);
+		list_add_tail_rcu(&ptr->list, &reserved_port_list);
+		set_bit(ptr->port, reserved_port_map);
+	} else if (sscanf(data, "del %u", &port) == 1 && port < 65536) {
+		const char *cp = strchr(data + 4, ' ');
+		if (!cp++ || !kpr_correct_word(cp))
+			return -EINVAL;
+		ptr = kpr_find_entry(port, cp);
+		if (!ptr)
+			return 0;
+		list_del_rcu(&ptr->list);
+		synchronize_rcu();
+		kfree(ptr);
+		if (!kpr_find_entry(port, NULL))
+			clear_bit(ptr->port, reserved_port_map);
+	} else {
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * kpr_entry_write - Update current configuration.
+ *
+ * @file:  Pointer to "struct file".
+ * @buf:   Domainname to transit to.
+ * @count: Size of @buf.
+ * @ppos:  Unused.
+ *
+ * Returns bytes parsed on success, negative value otherwise.
+ */
+static ssize_t kpr_entry_write(struct file *file, const char __user *buf,
+			       size_t count, loff_t *ppos)
+{
+	char *data;
+	ssize_t copied = 0;
+	int error;
+	if (!count)
+		return 0;
+	if (count > MAX_LINE_LEN - 1)
+		count = MAX_LINE_LEN - 1;
+	data = vmalloc(count + 1);
+	if (!data)
+		return -ENOMEM;
+	if (copy_from_user(data, buf, count)) {
+		error = -EFAULT;
+		goto out;
+	}
+	data[count] = '\0';
+	while (1) {
+		static DEFINE_MUTEX(lock);
+		char *cp = strchr(data, '\n');
+		int len;
+		if (!cp) {
+			error = -EINVAL;
+			break;
+		}
+		*cp = '\0';
+		len = strlen(data) + 1;
+		kpr_normalize_line(data);
+		if (mutex_lock_interruptible(&lock)) {
+			error = -EINTR;
+			break;
+		}
+		error = kpr_update_entry(data);
+		mutex_unlock(&lock);
+		if (error < 0)
+			break;
+		copied += len;
+		memmove(data, data + len, strlen(data + len) + 1);
+	}
+out:
+	vfree(data);
+	return copied ? copied : error;
+}
+
+/* List of hooks. */
+static struct security_operations kpr_ops = {
+	.name             = "kpr",
+	.cred_prepare     = kpr_cred_prepare,
+	.cred_alloc_blank = kpr_cred_alloc_blank,
+	.cred_transfer    = kpr_cred_transfer,
+	.cred_free        = kpr_cred_free,
+	.bprm_set_creds   = kpr_bprm_set_creds,
+	.socket_bind      = kpr_socket_bind,
+};
+
+static bool kpr_registered;
+
+/**
+ * kpr_register - Register this module.
+ *
+ * Returns 0.
+ */
+static int __init kpr_register(void)
+{
+	struct cred *cred = (struct cred *) current_cred();
+	struct task_name_info *info;
+	const char kernel_name[] = "<kernel>";
+
+	if (!security_module_enable(&kpr_ops))
+		return 0;
+	info = kmalloc(sizeof(*info) + sizeof(kernel_name), GFP_KERNEL);
+	if (!info)
+		goto out;
+	atomic_set(&info->users, 1);
+	strcpy(info->id, kernel_name);
+	cred->security = info;
+	if (register_security(&kpr_ops))
+		goto out;
+	kpr_registered = true;
+	pr_info("KPortReserve initialized\n");
+	return 0;
+out:
+	panic("Failure registering kportreserve");
+}
+security_initcall(kpr_register);
+
+/* Operations for /sys/kernel/security/kportreserve/entry interface. */
+static const struct file_operations kpr_entry_operations = {
+	.write = kpr_entry_write,
+	.read  = kpr_entry_read,
+};
+
+/**
+ * kpr_init - Initialize this module.
+ *
+ * Returns 0.
+ */
+static int __init kpr_init(void)
+{
+	if (kpr_registered) {
+		struct dentry *kpr_dir = securityfs_create_dir("kportreserve",
+							       NULL);
+		if (!kpr_dir ||
+		    !securityfs_create_file("entry", 0644, kpr_dir, NULL,
+					    &kpr_entry_operations))
+			panic("Failure registering kportreserve");
+	}
+	return 0;
+}
+fs_initcall(kpr_init);
-- 
1.7.1

^ permalink raw reply related

* Performance regression 3.11 with macvlan between 2 linux guests (bisected)
From: Christian Borntraeger @ 2013-08-21 12:38 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: David S. Miller, netdev, Michael S. Tsirkin, Matthew Rosato,
	Jason Wang

Vlad,

the patch 

commit 3e4f8b787370978733ca6cae452720a4f0c296b8
Author: Vlad Yasevich <vyasevic@redhat.com>
Date:   Tue Jun 25 16:04:22 2013 -0400

    macvtap: Perform GSO on forwarding path.

causes a severe performance regression for 2 Linux guests with virtio-net
connected via macvlan/vtap doing iperf workload. (2GBit vs. 20Gbit)

If I understand the patch correctly, we now check for gso depending on the
macvlan features. If the underlying hardware does not support the necessary
offloads then we will do segmentation, even if we keep the whole traffic internal
between two guests and even if both guests supports LRO,GSO etc.
---snip---
[...]
+       features = netif_skb_features(skb) & vlan->tap_features;
+       if (netif_needs_gso(skb, features)) {
+               struct sk_buff *segs = __skb_gso_segment(skb, features, false);
[...]

---snip---
Shouldnt we take the features of the target device or even better do the gsoing in the
target device driver?

Christian

FYI, the underlying HW has:

Features for eth0:
rx-checksumming: off [fixed]
tx-checksumming: off
	tx-checksum-ipv4: off [fixed]
	tx-checksum-ip-generic: off [fixed]
	tx-checksum-ipv6: off [fixed]
	tx-checksum-fcoe-crc: off [fixed]
	tx-checksum-sctp: off [fixed]
scatter-gather: off
	tx-scatter-gather: off [fixed]
	tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: off
	tx-tcp-segmentation: off [fixed]
	tx-tcp-ecn-segmentation: off [fixed]
	tx-tcp6-segmentation: off [fixed]
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: off [requested on]
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: off [fixed]
tx-vlan-offload: off [fixed]
ntuple-filters: off [fixed]
receive-hashing: off [fixed]
highdma: off [fixed]
rx-vlan-filter: on [fixed]
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: off [fixed]
tx-gre-segmentation: off [fixed]
tx-udp_tnl-segmentation: off [fixed]
tx-mpls-segmentation: off [fixed]
fcoe-mtu: off [fixed]
tx-nocache-copy: off
loopback: off [fixed]
rx-fcs: off [fixed]
rx-all: off [fixed]
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]

^ permalink raw reply

* Re: [PATCH net-next] ip6_tunnel: ensure to always have a link local address
From: Nicolas Dichtel @ 2013-08-21 12:11 UTC (permalink / raw)
  To: Bjørn Mork; +Cc: David Miller, netdev, yoshfuji
In-Reply-To: <8761uz6zra.fsf@nemi.mork.no>

Le 21/08/2013 13:37, Bjørn Mork a écrit :
> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>
>> Le 21/08/2013 11:02, Bjørn Mork a écrit :
>>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>>> Le 21/08/2013 08:48, David Miller a écrit :
>>>>
>>>>> Applied, but this brings up an issue I keep noticing.
>>>>>
>>>>> We talk about eth_random_addr() and "uniqueness" together all the
>>>>> time, but the former never implies the latter.
>>>>>
>>>>> And we're going to run into situations where any conflicts generated
>>>>> by this random address generater will cause reall failures.
>>>>>
>>>>> Therefore we'll have to create a system to prevent them.  Probably
>>>>> using some simple table that keeps track of the addresses we've
>>>>> generated.
>>>>>
>>>> Ok, I will look at this.
>>>
>>> Are eth_random_addr() collisions really any different than interfaces
>>> having the same address for other reasons?
>> I would tend to say yes, it's different.
>> It's easy for an administrator to fix a configuration for a physical
>> interface, because it's statically configured and there is a limited
>> number of interfaces.
>>
>> For virtual interfaces, they can be dynamically created and destroyed
>> by daemons and we can have a lot of interfaces. Hence it could be hard
>> to fix them.
>
> If they are created by daemons then it should be up to the daemons to
> fix them.  Or?
>
>> Trying to avoid these errors at kernel level could be useful.
>
> I strongly believe in fixing configuration issues in userspace if at all
> possible.  You are setting a new policy every time you implement an
> automatic fix or workaround.  It is so much better to keep that out of
> the kernel, or the next question you will face is "How do I change this
> policy? I want the addresses to be assigned by function Y"
>
> I see no reason why the daemon creating these interfaces can't also
> fixup any collisions.  Or maybe better: If your daemon create millions
> of interfaces, and cares about unique addresses, then it should
> implement it's own address management.
Ok ok, you convince me ;-)

I will wait David feedback.

>
>> I've start to write a patch, and to test it I've just run a simple
>> test which generate 1 000 000 of random addresses. I've run it several
>> times (maybe not enough ;-)) and I never get a duplicated address...
>
> Well, there are only 2^46 combinations so you are guaranteed to hit a
> collision if you just generate 70 368 744 177 665 random addresses :-)
Yes, it was just to say that the function which generate these addresses has a 
"good" entropy ;-)

^ permalink raw reply

* Re: ADSL/ATM linklayer tc shaping regression fix commits for stable
From: Jesper Dangaard Brouer @ 2013-08-21 12:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: stable, netdev, linux-kernel, bufferbloat-list, David Miller,
	Eric Dumazet, Dave Taht
In-Reply-To: <20130820151650.GA18016@kroah.com>


On Tue, 20 Aug 2013 08:16:50 -0700
Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
> On Tue, Aug 20, 2013 at 01:26:29PM +0200, Jesper Dangaard Brouer wrote:
[...]
 
> If there are issues with 3.10, that's a different story.
> 
> > Refactor improvements (v3.11-rc1):
> >  commit 130d3d68b52 (net_sched: psched_ratecfg_precompute() improvements)

Needed because it fixes the accuracy of the rate calc.

> > The linklayer ATM/ADSL fix, reached 3.11-rc6:
> >  commit 8a8e3d84b17 (net_sched: restore "linklayer atm" handling)

Needed because we broke userspace interface.

> David sends me the networking patches for the stable tree, and if he
> thinks these are applicable, then I'll take them.

DaveM, please?  What do you want me to do, submit this req/patches somehow?

(Can see that is not currently on your stable queue via:
http://patchwork.ozlabs.org/bundle/davem/stable/?state=*)

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Sr. Network Kernel Developer at Red Hat
  Author of http://www.iptv-analyzer.org
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* Re: [RFC PATCH 1/3] of: provide a binding for the 'fixed-link' property
From: Florian Fainelli @ 2013-08-21 11:46 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Thomas Petazzoni, Grant Likely, Rob Herring, David S. Miller,
	Lior Amsalem, netdev, devicetree-discuss@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20130812083746.GM26614@pengutronix.de>

2013/8/12 Sascha Hauer <s.hauer@pengutronix.de>:
> On Mon, Aug 12, 2013 at 10:16:49AM +0200, Thomas Petazzoni wrote:
>> Dear Sascha Hauer,
>>
>> On Mon, 12 Aug 2013 08:38:06 +0200, Sascha Hauer wrote:
>>
>> > > This patch adds:
>> > >
>> > >  * A documentation for the Device Tree property "fixed-link".
>> > >
>> > >  * A of_phy_register_fixed_link() OF helper, which provided an OF node
>> > >    that contains a "fixed-link" property, registers the corresponding
>> > >    fixed PHY.
>> > >
>> > >  * Removes the warning on the of_phy_connect_fixed_link() that says
>> > >    new drivers should not use it, since Grant Likely indicated that
>> > >    this "fixed-link" property is indeed the way to go.
>> > >
>> >
>> > Any progress with this series?
>>
>> I am not sure there really was a consensus yet on what the DT binding
>> looks like. As soon as there is a consensus, I'm definitely willing to
>> make progress on this series.
>>
>> > We have more and more boards here with exactly the same problem as
>> > Thomas has. For reasons stated below I don't like this binding, but
>> > still it would solve my problem.
>>
>> Ok.
>>
>> > > +Example:
>> > > +
>> > > +ethernet@0 {
>> > > + ...
>> > > + fixed-link = <1 1 1000 0 0>;
>> > > + ...
>> > > +};
>> >
>> > I must say I don't like this binding at all for two reasons.
>>
>> As I explained, this binding was chosen for this RFC for two reasons:
>>
>>  * It's the binding used on PowerPC platforms to represent fixed links.
>>  * It allows to encode all the informations into a single property,
>>    which avoids the need for a separate DT node for a "fake PHY", which
>>    isn't a representation of the hardware.
>
> The fake phy is avoided by making the other side of the link what it
> really is: An ethernet switch. I'm currently not aware of a situation
> where a fixed link is needed and the other side is not a switch.

There is such hardware out there, some platforms have a MoCA PHY which
is responsible for the signaling/control path while the data-path can
be connected to a slightly modified Ethernet MAC.

> And I
> can't think of a situation in which the other side of the other side of
> the fixed link really is pure 'virtual', I mean there always must be
> something connected, right?

I agree, there is something on the other end in every case.

>
>>
>> > First the positional arguments make it impossible to add optional
>> > arguments to the link.
>> >
>> > Second the other side of the link is most likely a switch. Once this
>> > switch has its own node in the devicetree it seems like having a phandle
>> > to the switch here would be better.
>>
>> So, in other words, what you're suggesting is something like:
>>
>>       ethernet@0 {
>>               reg = <...>;
>>               interrupt = <...>;
>>               phy = <&phy0>;
>>               phy0: phy@0 {
>>                       fixed-link;
>>                       speed = <1000>;
>>                       full-duplex;
>>                       ...
>>               };
>>       };
>
> Yes, this looks good. ePAPR suggests naming the phy property
> "phy-handle" instead of just "phy", but that's just details. In case the
> phy really is a switch the phandle could just point to a i2c device instead
> of the ethernet node.

I do like this representation better than the existing fixed-link property.
--
Florian

^ permalink raw reply

* Re: [PATCH net-next] ip6_tunnel: ensure to always have a link local address
From: Bjørn Mork @ 2013-08-21 11:37 UTC (permalink / raw)
  To: nicolas.dichtel; +Cc: David Miller, netdev, yoshfuji
In-Reply-To: <5214958F.1080907@6wind.com>

Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:

> Le 21/08/2013 11:02, Bjørn Mork a écrit :
>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>> Le 21/08/2013 08:48, David Miller a écrit :
>>>
>>>> Applied, but this brings up an issue I keep noticing.
>>>>
>>>> We talk about eth_random_addr() and "uniqueness" together all the
>>>> time, but the former never implies the latter.
>>>>
>>>> And we're going to run into situations where any conflicts generated
>>>> by this random address generater will cause reall failures.
>>>>
>>>> Therefore we'll have to create a system to prevent them.  Probably
>>>> using some simple table that keeps track of the addresses we've
>>>> generated.
>>>>
>>> Ok, I will look at this.
>>
>> Are eth_random_addr() collisions really any different than interfaces
>> having the same address for other reasons?
> I would tend to say yes, it's different.
> It's easy for an administrator to fix a configuration for a physical
> interface, because it's statically configured and there is a limited
> number of interfaces.
>
> For virtual interfaces, they can be dynamically created and destroyed
> by daemons and we can have a lot of interfaces. Hence it could be hard
> to fix them.

If they are created by daemons then it should be up to the daemons to
fix them.  Or?

> Trying to avoid these errors at kernel level could be useful.

I strongly believe in fixing configuration issues in userspace if at all
possible.  You are setting a new policy every time you implement an
automatic fix or workaround.  It is so much better to keep that out of
the kernel, or the next question you will face is "How do I change this
policy? I want the addresses to be assigned by function Y"

I see no reason why the daemon creating these interfaces can't also
fixup any collisions.  Or maybe better: If your daemon create millions
of interfaces, and cares about unique addresses, then it should
implement it's own address management.

> I've start to write a patch, and to test it I've just run a simple
> test which generate 1 000 000 of random addresses. I've run it several
> times (maybe not enough ;-)) and I never get a duplicated address...

Well, there are only 2^46 combinations so you are guaranteed to hit a
collision if you just generate 70 368 744 177 665 random addresses :-)


Bjørn

^ permalink raw reply

* Re: Re: [PATCH-SR9700] Merge USB 1.1 Ethernet Adapter SR9700 DeviceDriver into the Linux Kernel
From: Joe Perches @ 2013-08-21 11:34 UTC (permalink / raw)
  To: liujunliang_ljl
  Cc: Francois Romieu, gregkh, sunhecheng, linux-usb, netdev,
	linux-kernel
In-Reply-To: <201308211807295009698@163.com>

On Wed, 2013-08-21 at 18:07 +0800, liujunliang_ljl wrote:
> 		Thanks a lot and I have been fixed all the problems mentioned above. please check the following patch and thanks again. 

Just trivial comments below:

> diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
[]
> +static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
> +{
> +	usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
> +					value, reg, NULL, 0);
> +}
> +
> +static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg, __le16 *value)
> +{
[]
> +	netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
> +	       phy, reg, *value, ret);

You have a lot of code that uses inconsistent
indentation.  Code in drivers/net and drivers/usb/net
generally prefers to use alignment to parenthesis for
multi-line statements

The first could use

	usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
			       value, reg, NULL, 0);

and the second

	netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
		   phy, reg, *value, ret);

Maximal use of 8 space indentation tabs followed by
minimal spaces.

There are many of these above.

> +static int sr9700_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, u8 *data)
[]
> +	for (i = 0; i < eeprom->len / 2; i++)
> +			ret = sr_read_eeprom_word(dev, eeprom->offset / 2 + i, &ebuf[i]);

One too many tabs for the second line, a few of these...

[]

> +static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc)
[]
> +	if (rc == 1)
> +			return le16_to_cpu(res) | BMSR_LSTATUS;
> +	else
> +			return le16_to_cpu(res) & ~BMSR_LSTATUS;

The code below the returns here is unreachable.

> +
> +	netdev_dbg(dev->net,
> +	       "sr_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
> +	       phy_id, loc, le16_to_cpu(res));
> +
> +	return le16_to_cpu(res);
> +}

You might try to use scripts/checkpatch.pl --strict if you
care about these.  It should flag most of these coding
style inconsistencies.

^ permalink raw reply

* Re: [RFC PATCH 1/3] of: provide a binding for the 'fixed-link' property
From: Florian Fainelli @ 2013-08-21 11:25 UTC (permalink / raw)
  To: Christian Gmeiner
  Cc: Sascha Hauer, Thomas Petazzoni, Lior Amsalem, netdev,
	devicetree-discuss@lists.ozlabs.org, Rob Herring, Grant Likely,
	David S. Miller, linux-arm-kernel@lists.infradead.org
In-Reply-To: <CAH9NwWewcDE57g8qgy4aeOeQpfE_RA8hT+cQ9U2_gOFEWKAUDQ@mail.gmail.com>

2013/8/21 Christian Gmeiner <christian.gmeiner@gmail.com>:
> --
> Christian Gmeiner, MSc
>
>
> 2013/8/12 Sascha Hauer <s.hauer@pengutronix.de>:
>> On Mon, Aug 12, 2013 at 10:16:49AM +0200, Thomas Petazzoni wrote:
>>> Dear Sascha Hauer,
>>>
>>> On Mon, 12 Aug 2013 08:38:06 +0200, Sascha Hauer wrote:
>>>
>>> > > This patch adds:
>>> > >
>>> > >  * A documentation for the Device Tree property "fixed-link".
>>> > >
>>> > >  * A of_phy_register_fixed_link() OF helper, which provided an OF node
>>> > >    that contains a "fixed-link" property, registers the corresponding
>>> > >    fixed PHY.
>>> > >
>>> > >  * Removes the warning on the of_phy_connect_fixed_link() that says
>>> > >    new drivers should not use it, since Grant Likely indicated that
>>> > >    this "fixed-link" property is indeed the way to go.
>>> > >
>>> >
>>> > Any progress with this series?
>>>
>>> I am not sure there really was a consensus yet on what the DT binding
>>> looks like. As soon as there is a consensus, I'm definitely willing to
>>> make progress on this series.
>>>
>>> > We have more and more boards here with exactly the same problem as
>>> > Thomas has. For reasons stated below I don't like this binding, but
>>> > still it would solve my problem.
>>>
>>> Ok.
>>>
>>> > > +Example:
>>> > > +
>>> > > +ethernet@0 {
>>> > > + ...
>>> > > + fixed-link = <1 1 1000 0 0>;
>>> > > + ...
>>> > > +};
>>> >
>>> > I must say I don't like this binding at all for two reasons.
>>>
>>> As I explained, this binding was chosen for this RFC for two reasons:
>>>
>>>  * It's the binding used on PowerPC platforms to represent fixed links.
>>>  * It allows to encode all the informations into a single property,
>>>    which avoids the need for a separate DT node for a "fake PHY", which
>>>    isn't a representation of the hardware.
>>
>> The fake phy is avoided by making the other side of the link what it
>> really is: An ethernet switch. I'm currently not aware of a situation
>> where a fixed link is needed and the other side is not a switch. And I
>> can't think of a situation in which the other side of the other side of
>> the fixed link really is pure 'virtual', I mean there always must be
>> something connected, right?
>>
>>>
>>> > First the positional arguments make it impossible to add optional
>>> > arguments to the link.
>>> >
>>> > Second the other side of the link is most likely a switch. Once this
>>> > switch has its own node in the devicetree it seems like having a phandle
>>> > to the switch here would be better.
>>>
>>> So, in other words, what you're suggesting is something like:
>>>
>>>       ethernet@0 {
>>>               reg = <...>;
>>>               interrupt = <...>;
>>>               phy = <&phy0>;
>>>               phy0: phy@0 {
>>>                       fixed-link;
>>>                       speed = <1000>;
>>>                       full-duplex;
>>>                       ...
>>>               };
>>>       };
>>
>> Yes, this looks good. ePAPR suggests naming the phy property
>> "phy-handle" instead of just "phy", but that's just details. In case the
>> phy really is a switch the phandle could just point to a i2c device instead
>> of the ethernet node.
>>
>
> I have here a I.MX6 based board where I have the same issue that the
> MAC is directly
> connected to a switch. The switch has 5 phys (5 port 100mbt switch)
> but the phy5 is not
> physically connected to my FEC MAC as my hw guy has chosen to do it without it.
> In general it is not a bad idea and I got networking working in u-boot
> quite easily.

This is completely debatable and left to your own use case here.

>
> http://patchwork.ozlabs.org/patch/266558/
>
> Now I am interested in a solution and I think that a fixed-phy is the wrong way.
> I like the fixed-link solution more as it models the real world
> better. In my example I
> do not have any phy, but I have a fixed-link.
>
> &fec {
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_enet_1>;
>         fixed-link = <0 1 100 0 0>;
>         status = "okay";
> };

As was already raised before, this representation has a couple of issues:
- not easily extendable
- not self-explanatory
- it transpires some internal OS concepts such as id/address to the binding

On the other side I prefer the other representation for all of the
opposite reasons above and it actually represents some kind of a PHY
device which is not discoverable via usual means such as MDIO, but
which still needs to be known by the Ethernet MAC to work correctly.

To move forward, we really need a better argumentation than "I do not like it".
-- 
Florian

^ permalink raw reply

* Re: [PATCH V3] ipv6: handle Redirect ICMP Message with no Redirected Header option
From: Hannes Frederic Sowa @ 2013-08-21 11:17 UTC (permalink / raw)
  To: Duan Jiong; +Cc: davem, netdev
In-Reply-To: <521468C4.5020700@cn.fujitsu.com>

On Wed, Aug 21, 2013 at 03:14:12PM +0800, Duan Jiong wrote:
> From: Duan Jiong <duanj.fnst@cn.fujitsu.com>
> 
> rfc 4861 says the Redirected Header option is optional, so
> the kernel should not drop the Redirect Message that has no
> Redirected Header option. In this patch, the function
> ip6_redirect_no_header() is introduced to deal with that
> condition.
> 
> Signed-off-by: Duan Jiong <duanj.fnst@cn.fujitsu.com>

Sorry for being so picky about local socket delivery before. You were right
all along.

I just tested and reviewed this patch and everything is fine:

Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>

Just out of curiosity, can you tell because of which devices you did
this patch?

Thanks,

  Hannes

^ permalink raw reply

* Re: [RFC PATCH 1/3] of: provide a binding for the 'fixed-link' property
From: Christian Gmeiner @ 2013-08-21 10:55 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Thomas Petazzoni, Lior Amsalem, netdev, devicetree-discuss,
	Rob Herring, Florian Fainelli, Grant Likely, David S. Miller,
	linux-arm-kernel
In-Reply-To: <20130812083746.GM26614@pengutronix.de>

--
Christian Gmeiner, MSc


2013/8/12 Sascha Hauer <s.hauer@pengutronix.de>:
> On Mon, Aug 12, 2013 at 10:16:49AM +0200, Thomas Petazzoni wrote:
>> Dear Sascha Hauer,
>>
>> On Mon, 12 Aug 2013 08:38:06 +0200, Sascha Hauer wrote:
>>
>> > > This patch adds:
>> > >
>> > >  * A documentation for the Device Tree property "fixed-link".
>> > >
>> > >  * A of_phy_register_fixed_link() OF helper, which provided an OF node
>> > >    that contains a "fixed-link" property, registers the corresponding
>> > >    fixed PHY.
>> > >
>> > >  * Removes the warning on the of_phy_connect_fixed_link() that says
>> > >    new drivers should not use it, since Grant Likely indicated that
>> > >    this "fixed-link" property is indeed the way to go.
>> > >
>> >
>> > Any progress with this series?
>>
>> I am not sure there really was a consensus yet on what the DT binding
>> looks like. As soon as there is a consensus, I'm definitely willing to
>> make progress on this series.
>>
>> > We have more and more boards here with exactly the same problem as
>> > Thomas has. For reasons stated below I don't like this binding, but
>> > still it would solve my problem.
>>
>> Ok.
>>
>> > > +Example:
>> > > +
>> > > +ethernet@0 {
>> > > + ...
>> > > + fixed-link = <1 1 1000 0 0>;
>> > > + ...
>> > > +};
>> >
>> > I must say I don't like this binding at all for two reasons.
>>
>> As I explained, this binding was chosen for this RFC for two reasons:
>>
>>  * It's the binding used on PowerPC platforms to represent fixed links.
>>  * It allows to encode all the informations into a single property,
>>    which avoids the need for a separate DT node for a "fake PHY", which
>>    isn't a representation of the hardware.
>
> The fake phy is avoided by making the other side of the link what it
> really is: An ethernet switch. I'm currently not aware of a situation
> where a fixed link is needed and the other side is not a switch. And I
> can't think of a situation in which the other side of the other side of
> the fixed link really is pure 'virtual', I mean there always must be
> something connected, right?
>
>>
>> > First the positional arguments make it impossible to add optional
>> > arguments to the link.
>> >
>> > Second the other side of the link is most likely a switch. Once this
>> > switch has its own node in the devicetree it seems like having a phandle
>> > to the switch here would be better.
>>
>> So, in other words, what you're suggesting is something like:
>>
>>       ethernet@0 {
>>               reg = <...>;
>>               interrupt = <...>;
>>               phy = <&phy0>;
>>               phy0: phy@0 {
>>                       fixed-link;
>>                       speed = <1000>;
>>                       full-duplex;
>>                       ...
>>               };
>>       };
>
> Yes, this looks good. ePAPR suggests naming the phy property
> "phy-handle" instead of just "phy", but that's just details. In case the
> phy really is a switch the phandle could just point to a i2c device instead
> of the ethernet node.
>

I have here a I.MX6 based board where I have the same issue that the
MAC is directly
connected to a switch. The switch has 5 phys (5 port 100mbt switch)
but the phy5 is not
physically connected to my FEC MAC as my hw guy has chosen to do it without it.
In general it is not a bad idea and I got networking working in u-boot
quite easily.

http://patchwork.ozlabs.org/patch/266558/

Now I am interested in a solution and I think that a fixed-phy is the wrong way.
I like the fixed-link solution more as it models the real world
better. In my example I
do not have any phy, but I have a fixed-link.

&fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet_1>;
        fixed-link = <0 1 100 0 0>;
        status = "okay";
};

--
Christian Gmeiner, MSc

^ permalink raw reply

* Re: [PATCH] netns: unix: only allow to find out unix socket in same net namespace
From: Eric W. Biederman @ 2013-08-21 10:42 UTC (permalink / raw)
  To: Gao feng
  Cc: systemd-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	libvir-list-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
	netdev-u79uwXL29TY76Z2rM5mHXA, Linux Containers,
	lxc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <52146AC2.5070409-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>

Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org> writes:

> right now I only take note of the unix socket /run/systemd/private,
> but there may have many similar unix sockets, they can exist in any
> path. the strange problems will still happen.

It could just as easily have been a fifo in the filesystem, and the
result would have been the same.

The network namespace are all about communicating between network
namespaces and that is what was allowed here.

If you don't want a socket or a fifo or any other file to be used by a
container don't give it access to it.  It really is that simple.

Eric

^ permalink raw reply

* [PATCH RFC net-next] net: epoll support for busy poll
From: Eliezer Tamir @ 2013-08-21 10:39 UTC (permalink / raw)
  To: David Miller
  Cc: linux-kernel, netdev, e1000-devel, Eilon Greenstein, Amir Vadai,
	Eric Dumazet, Willem de Bruijn, Eliezer Tamir

Add busy poll support to epoll.

Background:
The persistent nature of epoll allows us to have a long lasting context
that we use to keep track of which device queues we expect traffic
to come on for the sockets monitored by an epoll file.

Design:
We tried to make epoll changes as small as possible and to keep
networking structures out of eventpoll.c.
All of the epoll changes have nop placeholders for when busy poll
is not defined.

Instead of remembering the napi_id for all the sockets in an epoll,
we only track the first socket we see with any unique napi_id.
The rational for this is that while there may be many thousands of
sockets tracked by a single epoll, we expect to only see a handful
of unique napi_ids in most cases.

A list of "unique" sockets is linked to struct epoll.
Struct busy_poll_id_index serves as the element of this list.

In sk_mark_napi_id() we notice and record the following events:
1. the napid_id of an sk changes
2. the socket receives data through napi poll
in epoll_poll_callback() and ep_table_queue_proc() if these
events happened, we check if we need to update the list.

Locking:
ep->busy_list is protected by ep->lock, with irqs disabled.
busy_poll indices use RCU.
sk_ll_state uses bitpos.

Performance:
using sockperf, Intel X520 NICs,
Supermicro 6026TT-BTF systems with E5-2690 Xeon CPUs
100 UDP sockets avg. latency 5.756 (std-dev 0.510)
1k  UDP sockets avg. latency 5.780 (std-dev 0.536)
10k UDP sockets avg. latency 6.269 (std-dev 0.611)

Open issues:
warn_busy_list_empty() happens under load with memcached.
Should we add some hysteresis so the queue list does not change too fast?
As usual suggestions about naming, where to put things and overall design
are most welcome.

Credit:
Eliel Louzoun and Matthew Wilcox: parts of the event handling algorithm.
Willem de Brujin: advice on style, where to put things, RCU.

Special thanks for finding bugs in earlier versions: Julie Cummings.

Signed-off-by: Eliezer Tamir <eliezer.tamir@linux.intel.com>
---

 fs/eventpoll.c          |  131 +++++++++++++++++++++++++++++
 include/linux/poll.h    |    2 
 include/net/busy_poll.h |  216 +++++++++++++++++++++++++++++++++++++++++++++--
 include/net/sock.h      |    1 
 4 files changed, 341 insertions(+), 9 deletions(-)

diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 9ad17b15..f432599 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -42,6 +42,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/compat.h>
+#include <net/busy_poll.h>
 
 /*
  * LOCKING:
@@ -215,6 +216,9 @@ struct eventpoll {
 	/* used to optimize loop detection check */
 	int visited;
 	struct list_head visited_list_link;
+
+	/* list of busy poll indices with active unique busy-poll ids */
+	struct busy_list busy_list;
 };
 
 /* Wait structure used by the poll hooks */
@@ -233,6 +237,10 @@ struct eppoll_entry {
 
 	/* The wait queue head that linked the "wait" wait queue item */
 	wait_queue_head_t *whead;
+
+	/* Is this file in the busy wait list for our waiter */
+	struct busy_state busy;
+
 };
 
 /* Wrapper struct used by poll queueing */
@@ -375,6 +383,103 @@ static inline int ep_events_available(struct eventpoll *ep)
 	return !list_empty(&ep->rdllist) || ep->ovflist != EP_UNACTIVE_PTR;
 }
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+/*
+ * if busy polling is on and the file for this pwq is a socket,
+ * return a pointer to struct socket
+ */
+static inline struct socket *ep_sock_from_pwq(struct eppoll_entry *pwq)
+{
+	struct file *file = pwq->base->ffd.file;
+	struct inode *inode = file_inode(file);
+
+	if (!net_busy_loop_on())
+		return NULL;
+
+	if (!S_ISSOCK(inode->i_mode))
+		return NULL;
+
+	return file->private_data;
+}
+
+/*
+ * check if a socket might need to be added or removed from busy poll list
+ * must be called with ep->lock taken, irqs disabled
+ */
+static inline void eppoll_check_busy_poll(struct eventpoll *ep,
+					  struct eppoll_entry *pwq)
+{
+	struct socket *sock = ep_sock_from_pwq(pwq);
+
+	if (!sock)
+		return;
+
+	busy_poll_update_socket(sock, &ep->busy_list, &pwq->busy.listed);
+}
+
+/*
+ * attempt to delete on removal even if !net_busy_loop_on because it may have
+ * been turned off while we have sockets on the list
+ */
+static inline void eppoll_del_busy_poll(struct eventpoll *ep,
+					struct eppoll_entry *pwq)
+{
+	struct socket *sock = pwq->busy.listed ? ep_sock_from_pwq(pwq) : NULL;
+	unsigned long flags;
+
+	if (sock) {
+		spin_lock_irqsave(&ep->lock, flags);
+		busy_poll_delete_socket(&ep->busy_list, sock);
+		pwq->busy.listed = false;
+		spin_unlock_irqrestore(&ep->lock, flags);
+	}
+}
+
+/*
+ * called from ep_poll() when there is nothing for the user
+ * and busy polling is on
+ */
+static inline void epoll_busy_loop(struct eventpoll *ep, unsigned long end)
+{
+	struct busy_poll_id_index *idx;
+
+	rcu_read_lock_bh();
+
+	while (!busy_loop_timeout(end) && !need_resched()) {
+		list_for_each_entry_rcu(idx, &ep->busy_list.head, list) {
+			if (napi_id_busy_loop(idx->napi_id) &&
+			    ep_events_available(ep))
+				goto out;
+		}
+	}
+out:
+	rcu_read_unlock_bh();
+}
+
+#else /* CONFIG_NET_RX_BUSY_POLL */
+
+static inline struct socket *ep_sock_from_pwq(struct eppoll_entry *pwq)
+{
+	return NULL;
+}
+
+static inline void eppoll_check_busy_poll(struct eventpoll *ep,
+					  struct eppoll_entry *pwq)
+{
+}
+
+static inline void eppoll_del_busy_poll(struct eventpoll *ep,
+					struct eppoll_entry *pwq)
+{
+}
+
+static inline void epoll_busy_loop(struct eventpoll *ep, unsigned long end)
+{
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
+
+
 /**
  * ep_call_nested - Perform a bound (possibly) nested call, by checking
  *                  that the recursion limit is not exceeded, and that
@@ -536,6 +641,7 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
 
 		list_del(&pwq->llink);
 		ep_remove_wait_queue(pwq);
+		eppoll_del_busy_poll(ep, pwq);
 		kmem_cache_free(pwq_cache, pwq);
 	}
 }
@@ -755,6 +861,10 @@ static void ep_free(struct eventpoll *ep)
 		epi = rb_entry(rbp, struct epitem, rbn);
 		ep_remove(ep, epi);
 	}
+
+	/* at this stage ep->ll_list should be empty */
+	warn_busy_list_empty(&ep->busy_list);
+
 	mutex_unlock(&ep->mtx);
 
 	mutex_unlock(&epmutex);
@@ -920,6 +1030,7 @@ static int ep_alloc(struct eventpoll **pep)
 	init_waitqueue_head(&ep->wq);
 	init_waitqueue_head(&ep->poll_wait);
 	INIT_LIST_HEAD(&ep->rdllist);
+	init_busy_list(&ep->busy_list);
 	ep->rbr = RB_ROOT;
 	ep->ovflist = EP_UNACTIVE_PTR;
 	ep->user = user;
@@ -987,6 +1098,8 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
 
 	spin_lock_irqsave(&ep->lock, flags);
 
+	eppoll_check_busy_poll(ep, ep_pwq_from_wait(wait));
+
 	/*
 	 * If the event mask does not contain any poll(2) event, we consider the
 	 * descriptor to be disabled. This condition is likely the effect of the
@@ -1066,9 +1179,11 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
 		init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
 		pwq->whead = whead;
 		pwq->base = epi;
+		init_busy_state(&pwq->busy);
 		add_wait_queue(whead, &pwq->wait);
 		list_add_tail(&pwq->llink, &epi->pwqlist);
 		epi->nwait++;
+		eppoll_check_busy_poll(epi->ep, pwq);
 	} else {
 		/* We have to signal that an error occurred */
 		epi->nwait = -1;
@@ -1559,6 +1674,7 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
 	long slack = 0;
 	wait_queue_t wait;
 	ktime_t expires, *to = NULL;
+	unsigned long busy_loop_end = 0;
 
 	if (timeout > 0) {
 		struct timespec end_time = ep_set_mstimeout(timeout);
@@ -1577,6 +1693,21 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
 	}
 
 fetch_events:
+
+	/*
+	 * Busy poll if globally on and supporting sockets found && no events,
+	 * busy loop will return if need_resched or ep_events_available.
+	 *
+	 * we must do our busy polling with irqs enabled
+	 */
+
+	if (epoll_can_busy_loop(&ep->busy_list) && !ep_events_available(ep)) {
+		if (!busy_loop_end)
+			busy_loop_end = busy_loop_end_time();
+
+		epoll_busy_loop(ep, busy_loop_end);
+	}
+
 	spin_lock_irqsave(&ep->lock, flags);
 
 	if (!ep_events_available(ep)) {
diff --git a/include/linux/poll.h b/include/linux/poll.h
index c08386f..8de6133 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -69,7 +69,7 @@ static inline unsigned long poll_requested_events(const poll_table *p)
 static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
 {
 	pt->_qproc = qproc;
-	pt->_key   = ~0UL; /* all events enabled */
+	pt->_key   = ~(unsigned long) POLL_BUSY_LOOP;
 }
 
 struct poll_table_entry {
diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h
index 8a358a2..048de8c 100644
--- a/include/net/busy_poll.h
+++ b/include/net/busy_poll.h
@@ -37,6 +37,12 @@ extern unsigned int sysctl_net_busy_poll __read_mostly;
 #define LL_FLUSH_FAILED		-1
 #define LL_FLUSH_BUSY		-2
 
+enum {
+	SK_LL_STATE_EVICT,	/* napi id changed or became invalid */
+	SK_LL_STATE_MISS,	/* date came through napi poll */
+	SK_LL_STATE_MISS_2,	/* data came through napi poll twice in a row */
+};
+
 static inline bool net_busy_loop_on(void)
 {
 	return sysctl_net_busy_poll;
@@ -89,6 +95,24 @@ static inline bool busy_loop_timeout(unsigned long end_time)
 	return time_after(now, end_time);
 }
 
+/* must be called with rcu_read_lock_bh
+ * ops->ndo_ll_poll must not be null
+ */
+static inline bool __napi_busy_loop(const struct net_device_ops *ops,
+				struct napi_struct *napi)
+{
+	int rc = ops->ndo_busy_poll(napi);
+
+	if (rc > 0) {
+		/* local bh are disabled so it is ok to use _BH */
+		NET_ADD_STATS_BH(dev_net(napi->dev),
+				 LINUX_MIB_BUSYPOLLRXPACKETS, rc);
+		return true;
+	}
+
+	return false;
+}
+
 /* when used in sock_poll() nonblock is known at compile time to be true
  * so the loop and end_time will be optimized out
  */
@@ -114,16 +138,11 @@ static inline bool sk_busy_loop(struct sock *sk, int nonblock)
 		goto out;
 
 	do {
-		rc = ops->ndo_busy_poll(napi);
+		rc = __napi_busy_loop(ops, napi);
 
 		if (rc == LL_FLUSH_FAILED)
 			break; /* permanent failure */
 
-		if (rc > 0)
-			/* local bh are disabled so it is ok to use _BH */
-			NET_ADD_STATS_BH(sock_net(sk),
-					 LINUX_MIB_BUSYPOLLRXPACKETS, rc);
-
 	} while (!nonblock && skb_queue_empty(&sk->sk_receive_queue) &&
 		 !need_resched() && !busy_loop_timeout(end_time));
 
@@ -133,6 +152,18 @@ out:
 	return rc;
 }
 
+/* must be called with rcu_read_lock_bh */
+static inline bool napi_id_busy_loop(unsigned int id)
+{
+	struct napi_struct *napi = napi_by_id(id);
+	const struct net_device_ops *ops = napi->dev->netdev_ops;
+
+	if (!napi || !ops->ndo_busy_poll)
+		return false;
+
+	return __napi_busy_loop(ops, napi);
+}
+
 /* used in the NIC receive handler to mark the skb */
 static inline void skb_mark_napi_id(struct sk_buff *skb,
 				    struct napi_struct *napi)
@@ -140,13 +171,154 @@ static inline void skb_mark_napi_id(struct sk_buff *skb,
 	skb->napi_id = napi->napi_id;
 }
 
-/* used in the protocol hanlder to propagate the napi_id to the socket */
+/* Used in the protocol handler to propagate the napi_id to the socket.
+ * If the id changes or if we came from napi, record this for epoll.
+ */
 static inline void sk_mark_napi_id(struct sock *sk, struct sk_buff *skb)
 {
-	sk->sk_napi_id = skb->napi_id;
+	if (unlikely(sk->sk_napi_id != skb->napi_id)) {
+
+		sk->sk_napi_id = skb->napi_id;
+		set_bit(SK_LL_STATE_EVICT, &sk->sk_ll_state);
+
+		/* if the new id is valid, also try to re-insert */
+		if (sk->sk_napi_id)
+			set_bit(SK_LL_STATE_MISS_2, &sk->sk_ll_state);
+
+	/* Lazy detect when the queue needs updating:
+	 * we only suspect something needs an update,
+	 * if we get here twice in a row in softirq or irq context.
+	 * credit: Eliel Louzoun
+	 */
+	} else if (unlikely(sk->sk_napi_id && (in_serving_softirq() ||
+					       in_irq()))) {
+		if (test_and_set_bit(SK_LL_STATE_MISS, &sk->sk_ll_state))
+			set_bit(SK_LL_STATE_MISS_2, &sk->sk_ll_state);
+	} else {
+		clear_bit(SK_LL_STATE_MISS, &sk->sk_ll_state);
+		clear_bit(SK_LL_STATE_MISS_2, &sk->sk_ll_state);
+	}
+
+}
+
+/* epoll support */
+
+/* The list will typically have 0-2 elements,
+ * so there is no point of doing anything fancier than a simple linked list
+*/
+
+/* used for epoll support */
+struct busy_poll_id_index {
+	struct list_head list;
+	struct rcu_head	 free_rcu;
+	unsigned int     napi_id;
+	struct sock      *sk;
+};
+
+/* used in struct eventpoll */
+struct busy_list {
+	struct list_head head;
+};
+
+/* used in eppoll_entry */
+struct busy_state {
+	bool listed;
+};
+
+static inline void init_busy_list(struct busy_list *list)
+{
+	INIT_LIST_HEAD(&list->head);
+}
+
+static inline void warn_busy_list_empty(struct busy_list *list)
+{
+	WARN_ONCE(!list_empty(&list->head),
+		  "ep busy poll list not empty on free\n");
+}
+
+static inline void init_busy_state(struct busy_state *state)
+{
+	state->listed = false;
+}
+
+static inline bool epoll_can_busy_loop(struct busy_list *list)
+{
+	return  net_busy_loop_on() && !list_empty(&list->head);
+}
+
+/* must be called with the lock protecting list held */
+static inline bool busy_poll_insert_socket(struct busy_list *list,
+					   struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+	unsigned int id = sk->sk_napi_id;
+	struct busy_poll_id_index *idx;
+
+
+	/* make sure this id is not in the list */
+	list_for_each_entry(idx, &list->head, list)
+		if (idx->napi_id == id)
+			return false;
+
+	idx = kmalloc(sizeof(struct busy_poll_id_index), GFP_ATOMIC);
+
+	if (!idx)
+		return false;
+
+	idx->napi_id = id;
+	idx->sk = sk;
+	list_add_tail(&idx->list, &list->head);
+
+	return true;
+}
+
+/* must be called with the lock protecting list held */
+static inline bool busy_poll_delete_socket(struct busy_list *list,
+					   struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+	unsigned int id = sk->sk_napi_id;
+	struct busy_poll_id_index *idx;
+
+	list_for_each_entry(idx, &list->head, list)
+		if (idx->sk == sk) {
+			list_del_rcu(&idx->list);
+			kfree_rcu(idx, free_rcu);
+			return true;
+		}
+
+	/* should never reach here */
+	WARN_ONCE(true, "busy_poll_delete_id %x not on list\n", id);
+	return false;
+}
+
+/* must be called with the lock protecting list held */
+static inline void busy_poll_update_socket(struct socket *sock,
+					   struct busy_list *list,
+					   bool *listed)
+{
+	struct sock *sk = sock->sk;
+	unsigned long *state = &sk->sk_ll_state;
+
+	/* should almost always be false */
+	if (unlikely(*state)) {
+
+		bool evict = test_and_clear_bit(SK_LL_STATE_EVICT, state);
+		bool insert = test_and_clear_bit(SK_LL_STATE_MISS_2, state);
+
+		if (*listed && evict)
+			*listed = !busy_poll_delete_socket(list, sock);
+
+		if (!*listed && insert) {
+			clear_bit(SK_LL_STATE_MISS, state);
+			*listed = busy_poll_insert_socket(list, sock);
+		}
+
+	}
 }
 
 #else /* CONFIG_NET_RX_BUSY_POLL */
+
 static inline unsigned long net_busy_loop_on(void)
 {
 	return 0;
@@ -162,6 +334,11 @@ static inline bool sk_can_busy_loop(struct sock *sk)
 	return false;
 }
 
+static inline bool napi_id_busy_loop(unsigned int id)
+{
+	return false;
+}
+
 static inline void skb_mark_napi_id(struct sk_buff *skb,
 				    struct napi_struct *napi)
 {
@@ -181,5 +358,28 @@ static inline bool sk_busy_loop(struct sock *sk, int nonblock)
 	return false;
 }
 
+struct busy_poll_id_index { };
+
+struct busy_list { };
+
+struct busy_state { };
+
+static inline void init_busy_list(struct busy_list *list)
+{
+}
+
+static inline void warn_busy_list_empty(struct busy_list *list)
+{
+}
+
+static inline void init_busy_state(struct busy_state *state)
+{
+}
+
+static inline bool epoll_can_busy_loop(struct busy_list *list)
+{
+	return false;
+}
+
 #endif /* CONFIG_NET_RX_BUSY_POLL */
 #endif /* _LINUX_NET_BUSY_POLL_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index e4bbcbf..0537109 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -330,6 +330,7 @@ struct sock {
 #ifdef CONFIG_NET_RX_BUSY_POLL
 	unsigned int		sk_napi_id;
 	unsigned int		sk_ll_usec;
+	unsigned long		sk_ll_state;
 #endif
 	atomic_t		sk_drops;
 	int			sk_rcvbuf;

^ permalink raw reply related

* [PATCH 4/4] tun: Get skfilter layout
From: Pavel Emelyanov @ 2013-08-21 10:32 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <521496EF.8090909@parallels.com>

The only thing we may have from tun device is the fprog, whic contains
the number of filter elements and a pointer to (user-space) memory
where the elements are. The program itself may not be available if the
device is persistent and detached.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
---
 drivers/net/tun.c           |   10 ++++++++++
 include/uapi/linux/if_tun.h |    1 +
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 6acbdbc..60a1e93 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -2042,6 +2042,16 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 		tun_detach_filter(tun, tun->numqueues);
 		break;
 
+	case TUNGETFILTER:
+		ret = -EINVAL;
+		if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
+			break;
+		ret = -EFAULT;
+		if (copy_to_user(argp, &tun->fprog, sizeof(tun->fprog)))
+			break;
+		ret = 0;
+		break;
+
 	default:
 		ret = -EINVAL;
 		break;
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index cc127b2..e9502dd 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -57,6 +57,7 @@
 #define TUNSETVNETHDRSZ _IOW('T', 216, int)
 #define TUNSETQUEUE  _IOW('T', 217, int)
 #define TUNSETIFINDEX	_IOW('T', 218, unsigned int)
+#define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001
-- 
1.7.6.5

^ permalink raw reply related

* [PATCH 3/4] tun: Allow to skip filter on attach
From: Pavel Emelyanov @ 2013-08-21 10:32 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <521496EF.8090909@parallels.com>

There's a small problem with sk-filters on tun devices. Consider
an application doing this sequence of steps:

fd = open("/dev/net/tun");
ioctl(fd, TUNSETIFF, { .ifr_name = "tun0" });
ioctl(fd, TUNATTACHFILTER, &my_filter);
ioctl(fd, TUNSETPERSIST, 1);
close(fd);

At that point the tun0 will remain in the system and will keep in
mind that there should be a socket filter at address '&my_filter'.

If after that we do

fd = open("/dev/net/tun");
ioctl(fd, TUNSETIFF, { .ifr_name = "tun0" });

we most likely receive the -EFAULT error, since tun_attach() would
try to connect the filter back. But (!) if we provide a filter at
address &my_filter, then tun0 will be created and the "new" filter
would be attached, but application may not know about that.

This may create certain problems to anyone using tun-s, but it's
critical problem for c/r -- if we meet a persistent tun device
with a filter in mind, we will not be able to attach to it to dump
its state (flags, owner, address, vnethdr size, etc.).

The proposal is to allow to attach to tun device (with TUNSETIFF)
w/o attaching the filter to the tun-file's socket. After this
attach app may e.g clean the device by dropping the filter, it
doesn't want to have one, or (in case of c/r) get information
about the device with tun ioctls.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
---
 drivers/net/tun.c           |   12 +++++++-----
 include/uapi/linux/if_tun.h |    1 +
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index db43a24..6acbdbc 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -501,7 +501,7 @@ static void tun_detach_all(struct net_device *dev)
 		module_put(THIS_MODULE);
 }
 
-static int tun_attach(struct tun_struct *tun, struct file *file)
+static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filter)
 {
 	struct tun_file *tfile = file->private_data;
 	int err;
@@ -526,7 +526,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
 	err = 0;
 
 	/* Re-attach the filter to presist device */
-	if (tun->filter_attached == true) {
+	if (!skip_filter && (tun->filter_attached == true)) {
 		err = sk_attach_filter(&tun->fprog, tfile->socket.sk);
 		if (!err)
 			goto out;
@@ -1557,7 +1557,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		if (err < 0)
 			return err;
 
-		err = tun_attach(tun, file);
+		err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER);
 		if (err < 0)
 			return err;
 
@@ -1631,7 +1631,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		dev->vlan_features = dev->features;
 
 		INIT_LIST_HEAD(&tun->disabled);
-		err = tun_attach(tun, file);
+		err = tun_attach(tun, file, false);
 		if (err < 0)
 			goto err_free_dev;
 
@@ -1795,7 +1795,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
 		ret = security_tun_dev_attach_queue(tun->security);
 		if (ret < 0)
 			goto unlock;
-		ret = tun_attach(tun, file);
+		ret = tun_attach(tun, file, false);
 	} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
 		tun = rtnl_dereference(tfile->tun);
 		if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached)
@@ -1883,6 +1883,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 
 		if (tfile->detached)
 			ifr.ifr_flags |= IFF_DETACH_QUEUE;
+		if (!tfile->socket.sk->sk_filter)
+			ifr.ifr_flags |= IFF_NOFILTER;
 
 		if (copy_to_user(argp, &ifr, ifreq_len))
 			ret = -EFAULT;
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index c58d023..cc127b2 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -71,6 +71,7 @@
 #define IFF_DETACH_QUEUE 0x0400
 /* read-only flag */
 #define IFF_PERSIST	0x0800
+#define IFF_NOFILTER	0x1000
 
 /* Socket options */
 #define TUN_TX_TIMESTAMP 1
-- 
1.7.6.5

^ permalink raw reply related

* [PATCH 2/4] tun: Report whether the queue is attached or not
From: Pavel Emelyanov @ 2013-08-21 10:32 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <521496EF.8090909@parallels.com>

Multiqueue tun devices allow to attach and detach from its queues
while keeping the interface itself set on file.

Knowing this is critical for the checkpoint part of criu project.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
---
 drivers/net/tun.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 4b65fbc..db43a24 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1881,6 +1881,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 	case TUNGETIFF:
 		tun_get_iff(current->nsproxy->net_ns, tun, &ifr);
 
+		if (tfile->detached)
+			ifr.ifr_flags |= IFF_DETACH_QUEUE;
+
 		if (copy_to_user(argp, &ifr, ifreq_len))
 			ret = -EFAULT;
 		break;
-- 
1.7.6.5

^ permalink raw reply related

* [PATCH 1/4] tun: Add ability to create tun device with given index
From: Pavel Emelyanov @ 2013-08-21 10:31 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <521496EF.8090909@parallels.com>

Tun devices cannot be created with ifidex user wants, but it's
required by checkpoint-restore project.

Long time ago such ability was implemented for rtnl_ops-based
interface for creating links (9c7dafbf net: Allow to create links
with given ifindex), but the only API for creating and managing
tuntap devices is ioctl-based and is evolving with adding new ones
(cde8b15f tuntap: add ioctl to attach or detach a file form tuntap
device).

Following that trend, here's how a new ioctl that sets the ifindex
for device, that _will_ be created by TUNSETIFF ioctl looks like.
So those who want a tuntap device with the ifindex N, should open
the tun device, call ioctl(fd, TUNSETIFINDEX, &N), then call TUNSETIFF.
If the index N is busy, then the register_netdev will find this out
and the ioctl would be failed with -EBUSY.

If setifindex is not called, then it will be generated as before.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
---
 drivers/net/tun.c           |   21 ++++++++++++++++++++-
 include/uapi/linux/if_tun.h |    1 +
 2 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 7ed13cc..4b65fbc 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -138,7 +138,10 @@ struct tun_file {
 	struct fasync_struct *fasync;
 	/* only used for fasnyc */
 	unsigned int flags;
-	u16 queue_index;
+	union {
+		u16 queue_index;
+		unsigned int ifindex;
+	};
 	struct list_head next;
 	struct tun_struct *detached;
 };
@@ -1601,6 +1604,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
 		dev_net_set(dev, net);
 		dev->rtnl_link_ops = &tun_link_ops;
+		dev->ifindex = tfile->ifindex;
 
 		tun = netdev_priv(dev);
 		tun->dev = dev;
@@ -1817,6 +1821,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 	kgid_t group;
 	int sndbuf;
 	int vnet_hdr_sz;
+	unsigned int ifindex;
 	int ret;
 
 	if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) {
@@ -1851,6 +1856,19 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 			ret = -EFAULT;
 		goto unlock;
 	}
+	if (cmd == TUNSETIFINDEX) {
+		ret = -EPERM;
+		if (tun)
+			goto unlock;
+
+		ret = -EFAULT;
+		if (copy_from_user(&ifindex, argp, sizeof(ifindex)))
+			goto unlock;
+
+		ret = 0;
+		tfile->ifindex = ifindex;
+		goto unlock;
+	}
 
 	ret = -EBADFD;
 	if (!tun)
@@ -2099,6 +2117,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
 	rcu_assign_pointer(tfile->tun, NULL);
 	tfile->net = get_net(current->nsproxy->net_ns);
 	tfile->flags = 0;
+	tfile->ifindex = 0;
 
 	rcu_assign_pointer(tfile->socket.wq, &tfile->wq);
 	init_waitqueue_head(&tfile->wq.wait);
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index 1870ee2..c58d023 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -56,6 +56,7 @@
 #define TUNGETVNETHDRSZ _IOR('T', 215, int)
 #define TUNSETVNETHDRSZ _IOW('T', 216, int)
 #define TUNSETQUEUE  _IOW('T', 217, int)
+#define TUNSETIFINDEX	_IOW('T', 218, unsigned int)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001
-- 
1.7.6.5

^ permalink raw reply related

* [PATCH net-next 0/4] tun: Some bits required for tun's checkpoint-restore (v2)
From: Pavel Emelyanov @ 2013-08-21 10:31 UTC (permalink / raw)
  To: David Miller, Linux Netdev List

Hi,

After taking a closer look on tun checkpoint-restore I've found several
issues with the tun's API that make it impossible to dump and restore
the state of tun device and attached tun-files.

The proposed API changes are all about extending the existing ioctl-based
stuff. Patches fit today's net-next.

This v2 has David's comments about patch #1 fixed. All the rest is the same.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

^ permalink raw reply

* Re: [PATCH net-next] ip6_tunnel: ensure to always have a link local address
From: Nicolas Dichtel @ 2013-08-21 10:25 UTC (permalink / raw)
  To: Bjørn Mork; +Cc: David Miller, netdev, yoshfuji
In-Reply-To: <87haej76wz.fsf@nemi.mork.no>

Le 21/08/2013 11:02, Bjørn Mork a écrit :
> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>> Le 21/08/2013 08:48, David Miller a écrit :
>>
>>> Applied, but this brings up an issue I keep noticing.
>>>
>>> We talk about eth_random_addr() and "uniqueness" together all the
>>> time, but the former never implies the latter.
>>>
>>> And we're going to run into situations where any conflicts generated
>>> by this random address generater will cause reall failures.
>>>
>>> Therefore we'll have to create a system to prevent them.  Probably
>>> using some simple table that keeps track of the addresses we've
>>> generated.
>>>
>> Ok, I will look at this.
>
> Are eth_random_addr() collisions really any different than interfaces
> having the same address for other reasons?
I would tend to say yes, it's different.
It's easy for an administrator to fix a configuration for a physical interface, 
because it's statically configured and there is a limited number of interfaces.

For virtual interfaces, they can be dynamically created and destroyed by daemons 
and we can have a lot of interfaces. Hence it could be hard to fix them. Trying 
to avoid these errors at kernel level could be useful.

I've start to write a patch, and to test it I've just run a simple test which 
generate 1 000 000 of random addresses. I've run it several times (maybe not 
enough ;-)) and I never get a duplicated address...

^ permalink raw reply

* [PATCH] be2net: fix disabling TX in be_close()
From: Sathya Perla @ 2013-08-21 10:22 UTC (permalink / raw)
  To: netdev

commit fba875591 disabled TX in be_close() to protect be_xmit() from
touching freed up queues in the AER recovery flow.
But, TX must be disabled *before* cleaning up TX completions in the
close() path, not after. This allows be_tx_compl_clean() to free up
all TX-req skbs that were notified to the HW.

Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 181edb5..4559c35 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2563,8 +2563,8 @@ static int be_close(struct net_device *netdev)
 	/* Wait for all pending tx completions to arrive so that
 	 * all tx skbs are freed.
 	 */
-	be_tx_compl_clean(adapter);
 	netif_tx_disable(netdev);
+	be_tx_compl_clean(adapter);
 
 	be_rx_qs_destroy(adapter);
 
-- 
1.8.3.4

^ permalink raw reply related

* Re: [PATCH 1/2] net: can: at91_can: use platform_set_drvdata()
From: Marc Kleine-Budde @ 2013-08-21 10:16 UTC (permalink / raw)
  To: Libo Chen; +Cc: wg, davem, linux-can, netdev, linux-kernel, lizefan
In-Reply-To: <1377080103-33872-1-git-send-email-libo.chen@huawei.com>

[-- Attachment #1: Type: text/plain, Size: 596 bytes --]

On 08/21/2013 12:15 PM, Libo Chen wrote:
> Use the wrapper functions for getting and setting the driver data using
> platform_device instead of using dev_set_drvdata() with &pdev->dev,
> so we can directly pass a struct platform_device.
> 
> Signed-off-by: Libo Chen <libo.chen@huawei.com>

tnx, applied.

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply

* Re: [PATCH 2/2] net: can: flexcan: use platform_set_drvdata()
From: Marc Kleine-Budde @ 2013-08-21 10:17 UTC (permalink / raw)
  To: Libo Chen; +Cc: wg, linux-can, davem, netdev, linux-kernel, lizefan
In-Reply-To: <1377080108-33780-1-git-send-email-libo.chen@huawei.com>

[-- Attachment #1: Type: text/plain, Size: 596 bytes --]

On 08/21/2013 12:15 PM, Libo Chen wrote:
> Use the wrapper functions for getting and setting the driver data using
> platform_device instead of using dev_set_drvdata() with &pdev->dev,
> so we can directly pass a struct platform_device.
> 
> Signed-off-by: Libo Chen <libo.chen@huawei.com>

tnx, applied.

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply

* [PATCH] net: phy: mdio-octeon: use platform_set_drvdata()
From: Libo Chen @ 2013-08-21 10:15 UTC (permalink / raw)
  To: davem, grant.likely, rob.herring
  Cc: david.daney, wfp5p, gregkh, sachin.kamat, netdev, linux-kernel,
	lizefan, libo.chen

Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_set_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/phy/mdio-octeon.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index b51fa1f..7f18f80 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -222,7 +222,7 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
 	bus->mii_bus->read = octeon_mdiobus_read;
 	bus->mii_bus->write = octeon_mdiobus_write;
 
-	dev_set_drvdata(&pdev->dev, bus);
+	platform_set_drvdata(pdev, bus);
 
 	err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node);
 	if (err)
-- 
1.7.1

^ permalink raw reply related

* [PATCH] net: irda: pxaficp_ir: use platform_set_drvdata()
From: Libo Chen @ 2013-08-21 10:15 UTC (permalink / raw)
  To: samuel, davem; +Cc: netdev, linux-kernel, lizefan, libo.chen

Use the wrapper functions for getting and setting the driver data using
platform_device instead of using deva_set_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/irda/pxaficp_ir.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 964b116..3eeaaf8 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -915,7 +915,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
 	err = register_netdev(dev);
 
 	if (err == 0)
-		dev_set_drvdata(&pdev->dev, dev);
+		platform_set_drvdata(pdev, dev);
 
 	if (err) {
 		if (si->pdata->shutdown)
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/2] net: can: flexcan: use platform_set_drvdata()
From: Libo Chen @ 2013-08-21 10:15 UTC (permalink / raw)
  To: wg, mkl; +Cc: linux-can, davem, netdev, linux-kernel, lizefan, libo.chen

Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_set_drvdata() with &pdev->dev,
so we can directly pass a struct platform_device.

Signed-off-by: Libo Chen <libo.chen@huawei.com>
---
 drivers/net/can/flexcan.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 7b0be09..9978de7 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -1087,7 +1087,7 @@ static int flexcan_probe(struct platform_device *pdev)
 
 	netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
 
-	dev_set_drvdata(&pdev->dev, dev);
+	platform_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	err = register_flexcandev(dev);
-- 
1.7.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox