Netdev List
 help / color / mirror / Atom feed
* [PATCH] netfilter: check the length of the data before dereferencing it
From: Changli Gao @ 2012-04-01 14:22 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Patrick McHardy, David S. Miller, netfilter-devel, netdev,
	Changli Gao

We should check the length of the data before dereferencing it when parsing
the TCP options.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
 net/netfilter/nf_conntrack_proto_tcp.c |    4 ++++
 1 file changed, 4 insertions(+)
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 361eade..9e446c5 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -404,6 +404,8 @@ static void tcp_options(const struct sk_buff *skb,
 			length--;
 			continue;
 		default:
+			if (length < 2)
+				return;
 			opsize=*ptr++;
 			if (opsize < 2) /* "silly options" */
 				return;
@@ -464,6 +466,8 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
 			length--;
 			continue;
 		default:
+			if (length < 2)
+				return;
 			opsize = *ptr++;
 			if (opsize < 2) /* "silly options" */
 				return;

^ permalink raw reply related

* [PATCHv1] ipv6: Fix RTM_GETROUTE's interpretation of RTA_IIF to be consistent with ipv4
From: Shmulik Ladkani @ 2012-04-01 14:03 UTC (permalink / raw)
  To: David S. Miller, netdev
  Cc: linux-kernel, Eric Dumazet, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy

In IPv4, if an RTA_IIF attribute is specified within an RTM_GETROUTE
message, then a route is searched as if a packet was received on the
specified 'iif' interface.

However in IPv6, RTA_IIF is not interpreted in the same way:
'inet6_rtm_getroute()' always calls 'ip6_route_output()', regardless the
RTA_IIF attribute.

As a result, in IPv6 there's no way to use RTM_GETROUTE in order to look
for a route as if a packet was received on a specific interface.

Fix 'inet6_rtm_getroute()' so that RTA_IIF is interpreted as "lookup a
route as if a packet was received on the specified interface", similar
to IPv4's 'inet_rtm_getroute()' interpretation.

Reported-by: Ami Koren <amikoren@yahoo.com>
Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
---

Tested on v3.2.6. Patch applies to v3.3.

Few points to review:

1) An alternative: construction of an skb within 'inet6_rtm_getroute()'
   and then calling 'ip6_route_input()' with the skb as an argument.
   Thus, no need to split common code of 'ip6_route_input()'.
   Less elegant IMO.
 
2) Better name for the new common function 'ip6_route_input_lookup()'
   Will happily accept any better suggestions.

3) In IPv4 the 'ip_route_input()' call within 'inet_rtm_getroute()'is
   protected by a 'local_bh_disable()' since dawn of history.
   Not sure if similar protection needed within 'inet6_rtm_getroute()'.

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 22b7664..1178345 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -868,6 +868,16 @@ static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *
 	return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
 }
 
+static struct dst_entry *ip6_route_input_lookup(struct net *net,
+						struct net_device *dev,
+						struct flowi6 *fl6, int flags)
+{
+	if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG)
+		flags |= RT6_LOOKUP_F_IFACE;
+
+	return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input);
+}
+
 void ip6_route_input(struct sk_buff *skb)
 {
 	const struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -882,10 +892,7 @@ void ip6_route_input(struct sk_buff *skb)
 		.flowi6_proto = iph->nexthdr,
 	};
 
-	if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG)
-		flags |= RT6_LOOKUP_F_IFACE;
-
-	skb_dst_set(skb, fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_input));
+	skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags));
 }
 
 static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
@@ -2520,7 +2527,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
 	struct sk_buff *skb;
 	struct rtmsg *rtm;
 	struct flowi6 fl6;
-	int err, iif = 0;
+	int err, iif = 0, oif = 0;
 
 	err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
 	if (err < 0)
@@ -2547,15 +2554,29 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
 		iif = nla_get_u32(tb[RTA_IIF]);
 
 	if (tb[RTA_OIF])
-		fl6.flowi6_oif = nla_get_u32(tb[RTA_OIF]);
+		oif = nla_get_u32(tb[RTA_OIF]);
 
 	if (iif) {
 		struct net_device *dev;
+		int flags = 0;
+
 		dev = __dev_get_by_index(net, iif);
 		if (!dev) {
 			err = -ENODEV;
 			goto errout;
 		}
+
+		fl6.flowi6_iif = iif;
+
+		if (!ipv6_addr_any(&fl6.saddr))
+			flags |= RT6_LOOKUP_F_HAS_SADDR;
+
+		rt = (struct rt6_info *)ip6_route_input_lookup(net, dev, &fl6,
+							       flags);
+	} else {
+		fl6.flowi6_oif = oif;
+
+		rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6);
 	}
 
 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
@@ -2570,7 +2591,6 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
 	skb_reset_mac_header(skb);
 	skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
 
-	rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl6);
 	skb_dst_set(skb, &rt->dst);
 
 	err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,

^ permalink raw reply related

* [PATCH] Implement IP_EVIL socket option (RFC 3514)
From: Martin Lucina @ 2012-04-01 12:53 UTC (permalink / raw)
  To: linux-kernel, netdev; +Cc: Martin Lucina

This patch implements the IP_EVIL socket option, allowing user-space
applications to set the Security Flag in the IPv4 Header, aka "evil" bit,
as defined in RFC 3514.

Signed-off-by: Martin Lucina <martin@lucina.net>
---
 include/linux/in.h      |    1 +
 include/net/inet_sock.h |    1 +
 net/ipv4/af_inet.c      |    1 +
 net/ipv4/ip_output.c    |    2 ++
 net/ipv4/ip_sockglue.c  |    9 ++++++++-
 5 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/include/linux/in.h b/include/linux/in.h
index e0337f1..6814c0f 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -86,6 +86,7 @@ struct in_addr {
 
 #define IP_MINTTL       21
 #define IP_NODEFRAG     22
+#define IP_EVIL         23
 
 /* IP_MTU_DISCOVER values */
 #define IP_PMTUDISC_DONT		0	/* Never send DF frames */
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index ae17e13..37aaf9b 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -168,6 +168,7 @@ struct inet_sock {
 				transparent:1,
 				mc_all:1,
 				nodefrag:1;
+	__u8			evil;
 	__u8			rcv_tos;
 	int			uc_index;
 	int			mc_index;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 10e3751..b165dfb 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -356,6 +356,7 @@ lookup_protocol:
 	inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0;
 
 	inet->nodefrag = 0;
+	inet->evil = 0; /* Don't be evil */
 
 	if (SOCK_RAW == sock->type) {
 		inet->inet_num = protocol;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 4910176..c1b4b15 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -157,6 +157,8 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
 		iph->frag_off = htons(IP_DF);
 	else
 		iph->frag_off = 0;
+	if (inet->evil)
+		iph->frag_off |= 1<<15;
 	iph->ttl      = ip_select_ttl(inet, &rt->dst);
 	iph->daddr    = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
 	iph->saddr    = saddr;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 2fd0fba..f26d45c 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -463,7 +463,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
 			     (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
 			     (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
 			     (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
-			     (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
+			     (1<<IP_MINTTL) | (1<<IP_NODEFRAG) |
+			     (1<<IP_EVIL))) ||
 	    optname == IP_UNICAST_IF ||
 	    optname == IP_MULTICAST_TTL ||
 	    optname == IP_MULTICAST_ALL ||
@@ -598,6 +599,9 @@ static int do_ip_setsockopt(struct sock *sk, int level,
 		}
 		inet->nodefrag = val ? 1 : 0;
 		break;
+	case IP_EVIL:
+		inet->evil = val ? 1 : 0;
+		break;
 	case IP_MTU_DISCOVER:
 		if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_PROBE)
 			goto e_inval;
@@ -1176,6 +1180,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
 	case IP_NODEFRAG:
 		val = inet->nodefrag;
 		break;
+	case IP_EVIL:
+		val = inet->evil;
+		break;
 	case IP_MTU_DISCOVER:
 		val = inet->pmtudisc;
 		break;
-- 
1.7.9.1

^ permalink raw reply related

* [PATCH RESEND] net: lpc_eth: Fix rename of dev_hw_addr_random
From: Roland Stigge @ 2012-04-01 11:33 UTC (permalink / raw)
  To: netdev, linux-kernel, kevin.wells, linux-arm-kernel; +Cc: Roland Stigge

In parallel to the integration of lpc_eth.c, dev_hw_addr_random() has been
renamed to eth_hw_addr_random(). This patch fixes the resulting current compile
error in the new driver lpc_eth.c.

Signed-off-by: Roland Stigge <stigge@antcom.de>

---

 Applies to v3.4-rc1

 drivers/net/ethernet/nxp/lpc_eth.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- linux-2.6.orig/drivers/net/ethernet/nxp/lpc_eth.c
+++ linux-2.6/drivers/net/ethernet/nxp/lpc_eth.c
@@ -1441,7 +1441,7 @@ static int lpc_eth_drv_probe(struct plat
 	}
 #endif
 	if (!is_valid_ether_addr(ndev->dev_addr))
-		dev_hw_addr_random(ndev, ndev->dev_addr);
+		eth_hw_addr_random(ndev);
 
 	/* Reset the ethernet controller */
 	__lpc_eth_reset(pldat);

^ permalink raw reply

* [PATCH] m68k/atari: EtherNEC - rewrite to use mainstream ne.c, take two
From: Michael Schmitz @ 2012-04-01  8:49 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: Geert Uytterhoeven, linux-m68k, netdev
In-Reply-To: <4F5A0679.1020604@windriver.com>

Hi Paul, Geert,
> And on re-reading the comments in the other part of the patch, i.e.
> "...emulates the card interrupt via a timer"  --perhaps the driver
> should be just fixed to support generic netpoll, instead of adding
> an arch specific thing that amounts to netpoll.  Then anyone can
> attempt to limp along and use one of these ancient relics w/o IRQ.
>   
Here's take two of my patch to convert the m68k Atari ROM port Ethernet 
driver to use mainstream ne.c, with minimal changes to the core NE2000 
code.

In particular:

Changes to core net code:
* add a platform specific IRQ flag, so ne.c can share a hardware or 
timer interrupt with some other interrupt source.

Changes to arch/m68k code:
* register the 8390 platform device on Atari only if the hardware is present
* retain the old driver (atari_ethernec.c in Geert's tree) under a 
different config option, to be removed soon.

Regarding your suggestion that netpoll be used instead of a dedicated 
timer interrupt: no changes to ne.c or 8390p.c are required to use 
netpoll, it all works out of the box. All that is needed to use the 
driver with netpoll is setting the device interrupt to some source that  
can be registered, and enabling CONFIG_NETPOLL. Interrupt rate and hence 
throughput is lower with netpoll though, which is why I still prefer the 
dedicated timer option.

Comments?

Cheers,

  Michael Schmitz

Signed-off-by: Michael Schmitz <schmitz@debian.org>

--
 arch/m68k/atari/config.c                   |   41 
+++++++++++++++++++++++++---
 drivers/net/Space.c                        |    2 +-
 drivers/net/ethernet/8390/8390.h           |    8 +++++
 drivers/net/ethernet/8390/Kconfig          |   18 +++++++++++-
 drivers/net/ethernet/8390/Makefile         |    3 +-
 drivers/net/ethernet/8390/atari_ethernec.c |    6 ++--
 drivers/net/ethernet/8390/ne.c             |    5 ++-
 7 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 22375e0..6cff09f 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -664,6 +664,35 @@ static void atari_get_hardware_list(struct seq_file *m)
  */
 
 #define ATARI_ETHERNEC_PHYS_ADDR    0xfffa0000
+#define ATARI_ETHERNEC_BASE        0x300
+#define ATARI_ETHERNEC_IRQ        IRQ_MFP_TIMD
+
+static struct resource rtl8019_resources[] = {
+    [0] = {
+        .name    = "rtl9019-regs",
+        .start    = ATARI_ETHERNEC_BASE,
+        .end    = ATARI_ETHERNEC_BASE + 0x20 - 1,
+        .flags    = IORESOURCE_IO,
+    },
+    [1] = {
+        .name    = "rtl9019-irq",
+        .start    = ATARI_ETHERNEC_IRQ,
+        .end    = ATARI_ETHERNEC_IRQ,
+        .flags    = IORESOURCE_IRQ,
+    },
+};
+
+static struct platform_device rtl8019_device = {
+    .name        = "ne",
+    .id        = -1,
+    .num_resources    = ARRAY_SIZE(rtl8019_resources),
+    .resource    = rtl8019_resources,
+};
+
+static struct platform_device *atari_ethernec_devices[] __initdata = {
+    &rtl8019_device
+};
+
 
 #define ATARI_ETHERNAT_PHYS_ADDR    0x80000000
 #define ATARI_ETHERNAT_IRQ        196
@@ -690,6 +719,7 @@ static struct platform_device smc91x_device = {
     .resource    = smc91x_resources,
 };
 
+
 #define ATARI_USB_PHYS_ADDR    0x80000010
 #define ATARI_USB_IRQ        195
 
@@ -753,7 +783,8 @@ static struct platform_device 
*atari_ethernat_devices[] __initdata = {
     &isp1160_device
 };
 
-#if IS_ENABLED(CONFIG_ATARI_ETHERNEC) || IS_ENABLED(CONFIG_ATARI_ETHERNAT)
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC) || 
IS_ENABLED(CONFIG_ATARI_ETHERNAT) \
+ || IS_ENABLED(CONFIG_ATARI_ETHERNEC_OLD)
 irqreturn_t atari_timerd_interrupt(int irq, void *dev_id)
 {
     return IRQ_HANDLED;
@@ -762,16 +793,17 @@ irqreturn_t atari_timerd_interrupt(int irq, void 
*dev_id)
 
 int __init atari_platform_init(void)
 {
-    int rv = -ENODEV, ret, need_timer = 0;
+    int rv = -ENODEV, rv1 = -ENODEV, need_timer = 0;
     unsigned char *enatc_virt, *enec_virt;
 
     if (!MACH_IS_ATARI)
         return -ENODEV;
 
-#if IS_ENABLED(CONFIG_ATARI_ETHERNEC)
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC) || 
IS_ENABLED(CONFIG_ATARI_ETHERNEC_OLD)
     enec_virt = (unsigned char *)ioremap((ATARI_ETHERNEC_PHYS_ADDR), 0xf);
     if (hwreg_present(enec_virt)) {
         need_timer = 1;
+        rv1 = platform_add_devices(atari_ethernec_devices, 
ARRAY_SIZE(atari_ethernec_devices));
     }
     iounmap(enec_virt);
 #endif
@@ -788,6 +820,7 @@ int __init atari_platform_init(void)
 #endif
 
     if (need_timer) {
+        int ret;
         const char *name = "Timer D dummy interrupt";
 
         /* timer routine set up in atari_ethernec_probe() */
@@ -802,7 +835,7 @@ int __init atari_platform_init(void)
         }
     }
 
-    if (ret) return ret;
+    if (rv1) return rv1;
     return rv;   
 }
 
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index d5e8882..548b73b 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -243,7 +243,7 @@ static struct devprobe2 m68k_probes[] __initdata = {
 #ifdef CONFIG_ATARILANCE    /* Lance-based Atari ethernet boards */
     {atarilance_probe, 0},
 #endif
-#ifdef CONFIG_ATARI_ETHERNEC    /* NE2000 based ROM port ethernet cards */
+#ifdef CONFIG_ATARI_ETHERNEC_OLD    /* NE2000 based ROM port ethernet 
cards */
     {atari_ethernec_probe, 0},
 #endif
 #ifdef CONFIG_SUN3LANCE         /* sun3 onboard Lance chip */
diff --git a/drivers/net/ethernet/8390/8390.h 
b/drivers/net/ethernet/8390/8390.h
index ef325ff..9416245 100644
--- a/drivers/net/ethernet/8390/8390.h
+++ b/drivers/net/ethernet/8390/8390.h
@@ -32,6 +32,14 @@ extern void ei_poll(struct net_device *dev);
 extern void eip_poll(struct net_device *dev);
 #endif
 
+/* Some platforms may need special IRQ flags */
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC)
+#  define EI_IRQ_FLAGS    IRQF_SHARED
+#endif
+
+#ifndef EI_IRQ_FLAGS
+#  define EI_IRQ_FLAGS    0
+#endif
 
 /* Without I/O delay - non ISA or later chips */
 extern void NS8390_init(struct net_device *dev, int startp);
diff --git a/drivers/net/ethernet/8390/Kconfig 
b/drivers/net/ethernet/8390/Kconfig
index b801056..75875f2 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -226,11 +226,27 @@ config APNE
 config ATARI_ETHERNEC
     tristate "Atari EtherNEC Ethernet support"
     depends on ATARI_ROM_ISA
-    help
+    select CRC32
+    ---help---
+      Say Y to include support for the EtherNEC network adapter for the
+      ROM port. The driver works by polling instead of interrupts, so it
+      is quite slow.
+
+      To compile this driver as a module, choose M here: the module
+      will be called ne.
+
+config ATARI_ETHERNEC_OLD
+    tristate "Atari EtherNEC Ethernet support - obsolete driver"
+    depends on ATARI_ROM_ISA
+    select CRC32
+    ---help---
       Say Y to include support for the EtherNEC network adapter for the
       ROM port. The driver works by polling instead of interrupts, so it
       is quite slow.
 
+      To compile this driver as a module, choose M here: the module
+      will be called atari_ethernec.
+
 config NE3210
     tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)"
     depends on PCI && EISA && EXPERIMENTAL
diff --git a/drivers/net/ethernet/8390/Makefile 
b/drivers/net/ethernet/8390/Makefile
index d896466..e620355 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -6,7 +6,8 @@ obj-$(CONFIG_MAC8390) += mac8390.o
 obj-$(CONFIG_AC3200) += ac3200.o 8390.o
 obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_ARM_ETHERH) += etherh.o
-obj-$(CONFIG_ATARI_ETHERNEC) += atari_ethernec.o 8390.o
+obj-$(CONFIG_ATARI_ETHERNEC_OLD) += atari_ethernec.o 8390.o
+obj-$(CONFIG_ATARI_ETHERNEC) += ne.o 8390p.o
 obj-$(CONFIG_AX88796) += ax88796.o
 obj-$(CONFIG_E2100) += e2100.o 8390.o
 obj-$(CONFIG_EL2) += 3c503.o 8390p.o
diff --git a/drivers/net/ethernet/8390/atari_ethernec.c 
b/drivers/net/ethernet/8390/atari_ethernec.c
index 086d968..5e8fb97 100644
--- a/drivers/net/ethernet/8390/atari_ethernec.c
+++ b/drivers/net/ethernet/8390/atari_ethernec.c
@@ -185,13 +185,13 @@ bad_clone_list[] __initdata = {
 #  define DCR_VAL 0x4b
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
    defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) 
|| \
-   defined(CONFIG_ATARI_ETHERNEC) || defined(CONFIG_ATARI_ETHERNEC_MODULE)
+   IS_ENABLED(CONFIG_ATARI_ETHERNEC_OLD)
 #  define DCR_VAL 0x48        /* 8-bit mode */
 #else
 #  define DCR_VAL 0x49
 #endif
 
-#if defined(CONFIG_ATARI_ETHERNEC) || defined(CONFIG_ATARI_ETHERNEC_MODULE)
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC_OLD)
 #  define ETHERNEC_RTL_8019_BASE 0x300
 #  define ETHERNEC_RTL_8019_IRQ IRQ_MFP_TIMD
 #endif
@@ -357,7 +357,7 @@ struct net_device * __init atari_ethernec_probe(int 
unit)
     sprintf(dev->name, "eth%d", unit);
     netdev_boot_setup_check(dev);
 
-#if defined(CONFIG_ATARI_ETHERNEC)
+#if defined(CONFIG_ATARI_ETHERNEC_OLD)
     dev->base_addr = ETHERNEC_RTL_8019_BASE;
     dev->irq = ETHERNEC_RTL_8019_IRQ;
 #endif
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index f92ea2a..39678fc 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -165,7 +165,8 @@ bad_clone_list[] __initdata = {
 #if defined(CONFIG_PLAT_MAPPI)
 #  define DCR_VAL 0x4b
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
-   defined(CONFIG_MACH_TX49XX)
+   defined(CONFIG_MACH_TX49XX) || \
+   IS_ENABLED(CONFIG_ATARI_ETHERNEC)
 #  define DCR_VAL 0x48        /* 8-bit mode */
 #else
 #  define DCR_VAL 0x49
@@ -492,7 +493,7 @@ static int __init ne_probe1(struct net_device *dev, 
unsigned long ioaddr)
 
     /* Snarf the interrupt now.  There's no point in waiting since we 
cannot
        share and the board will usually be enabled. */
-    ret = request_irq(dev->irq, eip_interrupt, 0, name, dev);
+    ret = request_irq(dev->irq, eip_interrupt, EI_IRQ_FLAGS, name, dev);
     if (ret) {
         printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
         goto err_out;

^ permalink raw reply related

* [PATCH] ipv6: fix array index in ip6_mc_add_src()
From: roy.qing.li @ 2012-04-01  8:45 UTC (permalink / raw)
  To: netdev

From: RongQing.Li <roy.qing.li@gmail.com>

Convert array index from the loop bound to the loop index.

Signed-off-by: RongQing.Li <roy.qing.li@gmail.com> 
---
 net/ipv6/mcast.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 16c33e3..c6378de 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2044,7 +2044,7 @@ static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
 		if (!delta)
 			pmc->mca_sfcount[sfmode]--;
 		for (j=0; j<i; j++)
-			(void) ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]);
+			ip6_mc_del1_src(pmc, sfmode, &psfsrc[j]);
 	} else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) {
 		struct ip6_sf_list *psf;
 
-- 
1.7.1

^ permalink raw reply related

* be2net: when can I expect roce support patch will be merged?
From: Parav.Pandit-iH1Dq9VlAzfQT0dZR+AlfA @ 2012-04-01  8:36 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA

Hi,

Did you get chance to merge below be2net patch for supporing RoCE driver?
http://marc.info/?l=linux-rdma&m=133279326217836&w=2

Once this is done, Roland can merge ocrdma RoCE driver addition to his tree. This NIC driver patch is required to merge ocrdma patch.
When can I expect this patch to be merged to net-next git tree?
Let me know if there any issue with the patch that I got to resolve.

Regards,
Parav Pandit

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: ipv6: RTM_GETROUTE inconsistent interpretation of RTA_IIF
From: Shmulik Ladkani @ 2012-04-01  7:28 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, davem, kuznet, jmorris, yoshfuji, kaber
In-Reply-To: <1333263839.2325.4665.camel@edumazet-glaptop>

On Sun, 01 Apr 2012 09:03:59 +0200 Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Sun, 2012-04-01 at 09:18 +0300, Shmulik Ladkani wrote:
> > (Bump)
> > 
> > Any reason not to submit a patch that fixes the below issue?
> 
> Hi Shmulik
> 
> No reason I can think about. Are you planning to provide this yourself ?

Yes.

Just wanted to make sure ipv6's RTA_IIF interpretation is not deliberate.

Regards,
Shmulik

^ permalink raw reply

* Re: [PATCH V4 8/8] net/mlx4_en: Set max rate-limit for a TC
From: Or Gerlitz @ 2012-04-01  7:04 UTC (permalink / raw)
  To: David Miller; +Cc: amirv, eric.dumazet, netdev, roland, yevgenyp, oren, amirv
In-Reply-To: <20120329.172544.1685598375831468260.davem@davemloft.net>

On Fri, Mar 30, 2012 at 12:25 AM, David Miller <davem@davemloft.net> wrote:
>
> From: Amir Vadai <amirv@mellanox.com>
> Date: Thu, 29 Mar 2012 20:27:20 +0200
>
> > I was in a rush to send it on time and missed it (of course I tested
> > only tc 0 so didn't see it in my tests too).
>
> Being in a rush when you expect others to spend time reviewing your
> code is an extremely selfish act.

Hi Dave,

Yep, a mistake was done here, but as they say "only he who never does
never errs..."
so Amir will surely learn from that, and so am I - here wearing the
internal reviewer hat,
didn't review V4 deep enough. We spotted also some vzalloc calls in
the patches which
are under the HW QoS model debate and will fix there as well. V5 will
be also against
net-next but depending on your decision maybe it can still go to 3.4?

Or.

^ permalink raw reply

* Re: ipv6: RTM_GETROUTE inconsistent interpretation of RTA_IIF
From: Eric Dumazet @ 2012-04-01  7:03 UTC (permalink / raw)
  To: Shmulik Ladkani; +Cc: netdev, davem, kuznet, jmorris, yoshfuji, kaber
In-Reply-To: <20120401091807.2f4614f2@pixies.home.jungo.com>

On Sun, 2012-04-01 at 09:18 +0300, Shmulik Ladkani wrote:
> (Bump)
> 
> Any reason not to submit a patch that fixes the below issue?

Hi Shmulik

No reason I can think about. Are you planning to provide this yourself ?

^ permalink raw reply

* ipv6: RTM_GETROUTE inconsistent interpretation of RTA_IIF
From: Shmulik Ladkani @ 2012-04-01  6:18 UTC (permalink / raw)
  To: netdev, davem; +Cc: kuznet, jmorris, yoshfuji, kaber
In-Reply-To: <20120329150311.51fe0e2d@pixies.home.jungo.com>

(Bump)

Any reason not to submit a patch that fixes the below issue?

Regards,
Shmulik

On Thu, 29 Mar 2012 15:03:11 +0200 Shmulik Ladkani <shmulik.ladkani@gmail.com> wrote:
> Hi,
> 
> In IPv4, if the RTA_IIF attribute is specified in an RTM_GETROUTE
> message, then a route is searched as if a packet was received on the
> specified iif interface - i.e. 'inet_rtm_getroute()' calls
> 'ip_route_input()'.
> 
> However in IPv6, RTA_IIF is not interpreted in the same way:
> 'inet6_rtm_getroute()' always calls 'ip6_route_output()', regardless the
> RTA_IIF attribute.
> 
> As a result, in IPv6 there's no way to use RTM_GETROUTE in order to look
> for a route as if a packet was received on a specific interface.
> 
> I'd like to modify 'inet6_rtm_getroute()' so that RTA_IIF is interpreted
> in the same way as in IPv4's 'inet_rtm_getroute()'.
> 
> Before I come up with a patch, I'd like to know whether current
> interpretation of RTA_IIF in 'inet6_rtm_getroute()' is deliberate.

^ permalink raw reply

* Re: ipv6: tunnel: hang when destroying ipv6 tunnel
From: Eric Dumazet @ 2012-04-01  5:07 UTC (permalink / raw)
  To: Sasha Levin
  Cc: Oleg Nesterov, davem, kuznet, jmorris, yoshfuji, Patrick McHardy,
	netdev, linux-kernel@vger.kernel.org List, Dave Jones,
	Tetsuo Handa
In-Reply-To: <CA+1xoqe1Wc_uifrKsko6hu+py9Ahz3Q0p1tRxup09jmh2NZ1rw@mail.gmail.com>

On Sun, 2012-04-01 at 01:26 +0200, Sasha Levin wrote:
> On Sat, Mar 31, 2012 at 11:43 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
> > On Sat, Mar 31, 2012 at 11:34 PM, Oleg Nesterov <oleg@redhat.com> wrote:
> >> On 03/31, Eric Dumazet wrote:
> >>>
> >>> On Sat, 2012-03-31 at 19:51 +0200, Sasha Levin wrote:
> >>> > Hi all,
> >>> >
> >>> > It appears that a hang may occur when destroying an ipv6 tunnel, which
> >>> > I've reproduced several times in a KVM vm.
> >>
> >> kernel version?
> >
> > latest linux-next
> >
> >>> > [ 1561.564172] INFO: task kworker/u:2:3140 blocked for more than 120 seconds.
> >>
> >> And nobody else?
> >
> > Some more messages follow a bit later which get stuck in vfs related code.
> >
> >> It would be nice to know what sysrq-t says, in particular the trace
> >> of khelper thread is interesting.
> >
> > Sure, I'll get one when it happens again.
> 
> So here's the stack of the usermode thread:
> 
> [  336.614015] kworker/u:2     S ffff880062c13000  5176  4539   3031 0x00000000
> [  336.614015]  ffff880062fb38d0 0000000000000082 ffff880062fb3860
> 0000000000000001
> [  336.614015]  ffff880062fb3fd8 00000000001d4580 ffff880062fb2010
> 00000000001d4580
> [  336.614015]  00000000001d4580 00000000001d4580 ffff880062fb3fd8
> 00000000001d4580
> [  336.614015] Call Trace:
> [  336.614015]  [<ffffffff826a8e54>] schedule+0x24/0x70
> [  336.614015]  [<ffffffff825fd66d>] p9_client_rpc+0x13d/0x360
> [  336.614015]  [<ffffffff810d7850>] ? wake_up_bit+0x40/0x40
> [  336.614015]  [<ffffffff810e3671>] ? get_parent_ip+0x11/0x50
> [  336.614015]  [<ffffffff810e399d>] ? sub_preempt_count+0x9d/0xd0
> [  336.614015]  [<ffffffff825ff5ff>] p9_client_walk+0x8f/0x220
> [  336.614015]  [<ffffffff815a8e3b>] v9fs_vfs_lookup+0xab/0x1c0
> [  336.614015]  [<ffffffff811ee0c0>] d_alloc_and_lookup+0x40/0x80
> [  336.614015]  [<ffffffff811fdea0>] ? d_lookup+0x30/0x50
> [  336.614015]  [<ffffffff811f0aea>] do_lookup+0x28a/0x3b0
> [  336.614015]  [<ffffffff817c9117>] ? security_inode_permission+0x17/0x20
> [  336.614015]  [<ffffffff811f1c07>] link_path_walk+0x167/0x420
> [  336.614015]  [<ffffffff811ee630>] ? generic_readlink+0xb0/0xb0
> [  336.614015]  [<ffffffff81896d88>] ? __raw_spin_lock_init+0x38/0x70
> [  336.614015]  [<ffffffff811f24da>] path_openat+0xba/0x500
> [  336.614015]  [<ffffffff81057253>] ? sched_clock+0x13/0x20
> [  336.614015]  [<ffffffff810ed805>] ? sched_clock_local+0x25/0x90
> [  336.614015]  [<ffffffff810ed940>] ? sched_clock_cpu+0xd0/0x120
> [  336.614015]  [<ffffffff811f2a34>] do_filp_open+0x44/0xa0
> [  336.614015]  [<ffffffff81119acd>] ? __lock_release+0x8d/0x1d0
> [  336.614015]  [<ffffffff810e3671>] ? get_parent_ip+0x11/0x50
> [  336.614015]  [<ffffffff810e399d>] ? sub_preempt_count+0x9d/0xd0
> [  336.614015]  [<ffffffff826aa7f0>] ? _raw_spin_unlock+0x30/0x60
> [  336.614015]  [<ffffffff811ea74d>] open_exec+0x2d/0xf0
> [  336.614015]  [<ffffffff811eb888>] do_execve_common+0x128/0x320
> [  336.614015]  [<ffffffff811ebb05>] do_execve+0x35/0x40
> [  336.614015]  [<ffffffff810589e5>] sys_execve+0x45/0x70
> [  336.614015]  [<ffffffff826acc28>] kernel_execve+0x68/0xd0
> [  336.614015]  [<ffffffff810cd6a6>] ? ____call_usermodehelper+0xf6/0x130
> [  336.614015]  [<ffffffff810cd6f9>] call_helper+0x19/0x20
> [  336.614015]  [<ffffffff826acbb4>] kernel_thread_helper+0x4/0x10
> [  336.614015]  [<ffffffff810e3f80>] ? finish_task_switch+0x80/0x110
> [  336.614015]  [<ffffffff826aaeb4>] ? retint_restore_args+0x13/0x13
> [  336.614015]  [<ffffffff810cd6e0>] ? ____call_usermodehelper+0x130/0x130
> [  336.614015]  [<ffffffff826acbb0>] ? gs_change+0x13/0x13
> 
> While it seems that 9p is the culprit, I have to point out that this
> bug is easily reproducible, and it happens each time due to a
> call_usermode_helper() call. Other than that 9p behaves perfectly and
> I'd assume that I'd be seeing other things break besides
> call_usermode_helper() related ones.

OK then there is a third process (might be a 9p related one trying to
serve this RPC request) blocking on one of the mutex hold by your first
process (the one invoking call_usermodehelper())

Maybe kobject_uevent_env() should not use UMH_WAIT_EXEC  to get a non
blocking guarantee.

^ permalink raw reply

* Re: ipv6: tunnel: hang when destroying ipv6 tunnel
From: Tetsuo Handa @ 2012-04-01  3:21 UTC (permalink / raw)
  To: levinsasha928, oleg
  Cc: eric.dumazet, davem, kuznet, jmorris, yoshfuji, kaber, netdev,
	linux-kernel, davej
In-Reply-To: <CA+1xoqe1Wc_uifrKsko6hu+py9Ahz3Q0p1tRxup09jmh2NZ1rw@mail.gmail.com>

Sasha Levin wrote:
> While it seems that 9p is the culprit, I have to point out that this
> bug is easily reproducible, and it happens each time due to a
> call_usermode_helper() call. Other than that 9p behaves perfectly and
> I'd assume that I'd be seeing other things break besides
> call_usermode_helper() related ones.

I think one of below two patches can catch the bug if this is a usermodehelper
related bug. Please try.

----- Patch 1 -----
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 01394b6..3e63319 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -571,7 +571,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 	 * flag, for khelper thread is already waiting for the thread at
 	 * wait_for_completion() in do_fork().
 	 */
-	if (wait != UMH_NO_WAIT && current == kmod_thread_locker) {
+	if (WARN_ON(wait != UMH_NO_WAIT && current == kmod_thread_locker)) {
 		retval = -EBUSY;
 		goto out;
 	}


----- Patch 2 -----
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 9efeae6..1350670 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -48,10 +48,10 @@ static inline int request_module_nowait(const char *name, ...) { return -ENOSYS;
 struct cred;
 struct file;
 
-#define UMH_NO_WAIT	0	/* don't wait at all */
-#define UMH_WAIT_EXEC	1	/* wait for the exec, but not the process */
-#define UMH_WAIT_PROC	2	/* wait for the process to complete */
-#define UMH_KILLABLE	4	/* wait for EXEC/PROC killable */
+#define UMH_NO_WAIT	0x10	/* don't wait at all */
+#define UMH_WAIT_EXEC	0x11	/* wait for the exec, but not the process */
+#define UMH_WAIT_PROC	0x12	/* wait for the process to complete */
+#define UMH_KILLABLE	0x04	/* wait for EXEC/PROC killable */
 
 struct subprocess_info {
 	struct work_struct work;
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 957a7aa..ecfd3d5 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -483,6 +483,18 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 	DECLARE_COMPLETION_ONSTACK(done);
 	int retval = 0;
 
+	if (unlikely(wait == -1 || wait == 0 || wait == 1)) {
+		WARN(1, "Requesting for usermode helper with hardcoded wait "
+		     "flag. Change to use UMH_* symbols and recompile, or "
+		     "this request will fail on Linux 3.4.\n");
+		if (wait == -1)
+			wait = UMH_NO_WAIT;
+		else if (wait == 0)
+			wait = UMH_WAIT_EXEC;
+		else
+			wait = UMH_WAIT_PROC;
+	}
+
 	helper_lock();
 	if (sub_info->path[0] == '\0')
 		goto out;

^ permalink raw reply related

* Re: [PATCH] net: bpf_jit: fix BPF_S_ALU_AND_K compilation
From: Indan Zupancic @ 2012-03-31 23:47 UTC (permalink / raw)
  To: Greg KH; +Cc: Eric Dumazet, netdev, stable, linux-kernel
In-Reply-To: <20120331151327.GA25059@kroah.com>

On Sun, April 1, 2012 01:13, Greg KH wrote:
> <formletter>
>
> This is not the correct way to submit patches for inclusion in the
> stable kernel tree.  Please read Documentation/stable_kernel_rules.txt
> for how to do this properly.
>
> </formletter>

Thanks for pointing that out. It won't happen again.

Greetings,

Indan

^ permalink raw reply

* Re: ipv6: tunnel: hang when destroying ipv6 tunnel
From: Sasha Levin @ 2012-03-31 23:26 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Eric Dumazet, davem, kuznet, jmorris, yoshfuji, Patrick McHardy,
	netdev, linux-kernel@vger.kernel.org List, Dave Jones,
	Tetsuo Handa
In-Reply-To: <CA+1xoqcAXyh306=2=QKWyM3BE44=MT+nsuRQn5YLOLgbtZqicA@mail.gmail.com>

On Sat, Mar 31, 2012 at 11:43 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
> On Sat, Mar 31, 2012 at 11:34 PM, Oleg Nesterov <oleg@redhat.com> wrote:
>> On 03/31, Eric Dumazet wrote:
>>>
>>> On Sat, 2012-03-31 at 19:51 +0200, Sasha Levin wrote:
>>> > Hi all,
>>> >
>>> > It appears that a hang may occur when destroying an ipv6 tunnel, which
>>> > I've reproduced several times in a KVM vm.
>>
>> kernel version?
>
> latest linux-next
>
>>> > [ 1561.564172] INFO: task kworker/u:2:3140 blocked for more than 120 seconds.
>>
>> And nobody else?
>
> Some more messages follow a bit later which get stuck in vfs related code.
>
>> It would be nice to know what sysrq-t says, in particular the trace
>> of khelper thread is interesting.
>
> Sure, I'll get one when it happens again.

So here's the stack of the usermode thread:

[  336.614015] kworker/u:2     S ffff880062c13000  5176  4539   3031 0x00000000
[  336.614015]  ffff880062fb38d0 0000000000000082 ffff880062fb3860
0000000000000001
[  336.614015]  ffff880062fb3fd8 00000000001d4580 ffff880062fb2010
00000000001d4580
[  336.614015]  00000000001d4580 00000000001d4580 ffff880062fb3fd8
00000000001d4580
[  336.614015] Call Trace:
[  336.614015]  [<ffffffff826a8e54>] schedule+0x24/0x70
[  336.614015]  [<ffffffff825fd66d>] p9_client_rpc+0x13d/0x360
[  336.614015]  [<ffffffff810d7850>] ? wake_up_bit+0x40/0x40
[  336.614015]  [<ffffffff810e3671>] ? get_parent_ip+0x11/0x50
[  336.614015]  [<ffffffff810e399d>] ? sub_preempt_count+0x9d/0xd0
[  336.614015]  [<ffffffff825ff5ff>] p9_client_walk+0x8f/0x220
[  336.614015]  [<ffffffff815a8e3b>] v9fs_vfs_lookup+0xab/0x1c0
[  336.614015]  [<ffffffff811ee0c0>] d_alloc_and_lookup+0x40/0x80
[  336.614015]  [<ffffffff811fdea0>] ? d_lookup+0x30/0x50
[  336.614015]  [<ffffffff811f0aea>] do_lookup+0x28a/0x3b0
[  336.614015]  [<ffffffff817c9117>] ? security_inode_permission+0x17/0x20
[  336.614015]  [<ffffffff811f1c07>] link_path_walk+0x167/0x420
[  336.614015]  [<ffffffff811ee630>] ? generic_readlink+0xb0/0xb0
[  336.614015]  [<ffffffff81896d88>] ? __raw_spin_lock_init+0x38/0x70
[  336.614015]  [<ffffffff811f24da>] path_openat+0xba/0x500
[  336.614015]  [<ffffffff81057253>] ? sched_clock+0x13/0x20
[  336.614015]  [<ffffffff810ed805>] ? sched_clock_local+0x25/0x90
[  336.614015]  [<ffffffff810ed940>] ? sched_clock_cpu+0xd0/0x120
[  336.614015]  [<ffffffff811f2a34>] do_filp_open+0x44/0xa0
[  336.614015]  [<ffffffff81119acd>] ? __lock_release+0x8d/0x1d0
[  336.614015]  [<ffffffff810e3671>] ? get_parent_ip+0x11/0x50
[  336.614015]  [<ffffffff810e399d>] ? sub_preempt_count+0x9d/0xd0
[  336.614015]  [<ffffffff826aa7f0>] ? _raw_spin_unlock+0x30/0x60
[  336.614015]  [<ffffffff811ea74d>] open_exec+0x2d/0xf0
[  336.614015]  [<ffffffff811eb888>] do_execve_common+0x128/0x320
[  336.614015]  [<ffffffff811ebb05>] do_execve+0x35/0x40
[  336.614015]  [<ffffffff810589e5>] sys_execve+0x45/0x70
[  336.614015]  [<ffffffff826acc28>] kernel_execve+0x68/0xd0
[  336.614015]  [<ffffffff810cd6a6>] ? ____call_usermodehelper+0xf6/0x130
[  336.614015]  [<ffffffff810cd6f9>] call_helper+0x19/0x20
[  336.614015]  [<ffffffff826acbb4>] kernel_thread_helper+0x4/0x10
[  336.614015]  [<ffffffff810e3f80>] ? finish_task_switch+0x80/0x110
[  336.614015]  [<ffffffff826aaeb4>] ? retint_restore_args+0x13/0x13
[  336.614015]  [<ffffffff810cd6e0>] ? ____call_usermodehelper+0x130/0x130
[  336.614015]  [<ffffffff826acbb0>] ? gs_change+0x13/0x13

While it seems that 9p is the culprit, I have to point out that this
bug is easily reproducible, and it happens each time due to a
call_usermode_helper() call. Other than that 9p behaves perfectly and
I'd assume that I'd be seeing other things break besides
call_usermode_helper() related ones.

^ permalink raw reply

* [RFC] mac80211:  Support on-channel scan option.
From: greearb @ 2012-03-31 22:29 UTC (permalink / raw)
  To: netdev; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

This based on an idea posted by Stanislaw Gruszka,
though I accept full blame for the implementation!

This is compile-tested only at this point.

The idea is to let users scan on the current operating
channel without interrupting normal traffic more than
absolutely necessary (changing power level might reset
some hardware, for instance).

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 d9798a3... b64d3c3... M	net/mac80211/ieee80211_i.h
:100644 100644 1633648... 5bee3ea... M	net/mac80211/main.c
:100644 100644 bcfe8c7... c4d7a50... M	net/mac80211/rx.c
:100644 100644 c70e176... 591fdea... M	net/mac80211/scan.c
 net/mac80211/ieee80211_i.h |    3 ++
 net/mac80211/main.c        |    4 ++-
 net/mac80211/rx.c          |    2 +
 net/mac80211/scan.c        |   80 ++++++++++++++++++++++++++++++-------------
 4 files changed, 64 insertions(+), 25 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d9798a3..b64d3c3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -785,6 +785,8 @@ struct tpt_led_trigger {
  *	well be on the operating channel
  * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to
  *	determine if we are on the operating channel or not
+ * @SCAN_ONCHANNEL_SCANNING:  Do a software scan on only the current operating
+ *	channel. This should not interrupt normal traffic.
  * @SCAN_COMPLETED: Set for our scan work function when the driver reported
  *	that the scan completed.
  * @SCAN_ABORTED: Set for our scan work function when the driver reported
@@ -793,6 +795,7 @@ struct tpt_led_trigger {
 enum {
 	SCAN_SW_SCANNING,
 	SCAN_HW_SCANNING,
+	SCAN_ONCHANNEL_SCANNING,
 	SCAN_COMPLETED,
 	SCAN_ABORTED,
 };
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 1633648..5bee3ea 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -47,7 +47,8 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
 	if (atomic_read(&local->iff_allmultis))
 		new_flags |= FIF_ALLMULTI;
 
-	if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning))
+	if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning))
 		new_flags |= FIF_BCN_PRBRESP_PROMISC;
 
 	if (local->fif_probe_req || local->probe_req_reg)
@@ -148,6 +149,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 	}
 
 	if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 	    test_bit(SCAN_HW_SCANNING, &local->scanning))
 		power = chan->max_power;
 	else
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bcfe8c7..c4d7a50 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -425,6 +425,7 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
 
 	if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
 	    test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 	    local->sched_scanning)
 		return ieee80211_scan_rx(rx->sdata, skb);
 
@@ -2919,6 +2920,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 		local->dot11ReceivedFragmentCount++;
 
 	if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
+		     test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 		     test_bit(SCAN_SW_SCANNING, &local->scanning)))
 		status->rx_flags |= IEEE80211_RX_IN_SCAN;
 
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c70e176..591fdea 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -387,6 +387,29 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
 	return 0;
 }
 
+static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
+					    unsigned long *next_delay)
+{
+	int i;
+	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
+	enum ieee80211_band band = local->hw.conf.channel->band;
+
+	for (i = 0; i < local->scan_req->n_ssids; i++)
+		ieee80211_send_probe_req(
+			sdata, NULL,
+			local->scan_req->ssids[i].ssid,
+			local->scan_req->ssids[i].ssid_len,
+			local->scan_req->ie, local->scan_req->ie_len,
+			local->scan_req->rates[band], false,
+			local->scan_req->no_cck);
+
+	/*
+	 * After sending probe requests, wait for probe responses
+	 * on the channel.
+	 */
+	*next_delay = IEEE80211_CHANNEL_TIME;
+	local->next_scan_state = SCAN_DECISION;
+}
 
 static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 				  struct cfg80211_scan_request *req)
@@ -438,6 +461,33 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 	local->scan_req = req;
 	local->scan_sdata = sdata;
 
+	/* If we are scanning only on the current channel, then
+	 * we do not need to stop normal activities
+	 */
+	if ((req->n_channels == 1) &&
+	    (req->channels[0]->center_freq ==
+	     local->hw.conf.channel->center_freq)) {
+		unsigned long next_delay;
+		__set_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);
+		ieee80211_recalc_idle(local);
+		ieee80211_configure_filter(local); /* accept probe-responses */
+		/* We need to set power level at maximum rate for scanning. */
+		ieee80211_hw_config(local, 0);
+
+		if (req->channels[0]->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
+		    !local->scan_req->n_ssids) {
+			next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+		} else {
+			ieee80211_scan_state_send_probe(local, &next_delay);
+			next_delay = IEEE80211_CHANNEL_TIME;
+		}
+
+		/* Now, just wait a bit and we are all done! */
+		ieee80211_queue_delayed_work(&local->hw, &local->scan_work,
+					     next_delay);
+		return 0;
+	}
+
 	if (local->ops->hw_scan)
 		__set_bit(SCAN_HW_SCANNING, &local->scanning);
 	else
@@ -598,30 +648,6 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
 	local->next_scan_state = SCAN_SEND_PROBE;
 }
 
-static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
-					    unsigned long *next_delay)
-{
-	int i;
-	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
-	enum ieee80211_band band = local->hw.conf.channel->band;
-
-	for (i = 0; i < local->scan_req->n_ssids; i++)
-		ieee80211_send_probe_req(
-			sdata, NULL,
-			local->scan_req->ssids[i].ssid,
-			local->scan_req->ssids[i].ssid_len,
-			local->scan_req->ie, local->scan_req->ie_len,
-			local->scan_req->rates[band], false,
-			local->scan_req->no_cck);
-
-	/*
-	 * After sending probe requests, wait for probe responses
-	 * on the channel.
-	 */
-	*next_delay = IEEE80211_CHANNEL_TIME;
-	local->next_scan_state = SCAN_DECISION;
-}
-
 static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
 					 unsigned long *next_delay)
 {
@@ -672,6 +698,12 @@ void ieee80211_scan_work(struct work_struct *work)
 
 	sdata = local->scan_sdata;
 
+	/* When scanning on-channel, the first-callback means completeed. */
+	if (test_and_clear_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) {
+		aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
+		goto out_complete;
+	}
+
 	if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
 		aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
 		goto out_complete;
-- 
1.7.3.4

^ permalink raw reply related

* Re: [PATCH v5 1/2] Ethernet driver for the WIZnet W5300 chip
From: Mark Brown @ 2012-03-31 21:45 UTC (permalink / raw)
  To: Mike Sinkovsky; +Cc: netdev, linux-kernel
In-Reply-To: <1333090806-27988-1-git-send-email-msink@permonline.ru>

On Fri, Mar 30, 2012 at 01:00:05PM +0600, Mike Sinkovsky wrote:
> Based on original driver from chip manufacturer, but nearly full rewite.
> 
> Tested and used in production with Blackfin BF531 embedded processor.

My comments on the other WIZnet driver look like they apply to this one
too.

^ permalink raw reply

* Re: ipv6: tunnel: hang when destroying ipv6 tunnel
From: Sasha Levin @ 2012-03-31 21:43 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Eric Dumazet, davem, kuznet, jmorris, yoshfuji, Patrick McHardy,
	netdev, linux-kernel@vger.kernel.org List, Dave Jones,
	Tetsuo Handa
In-Reply-To: <20120331213423.GA21219@redhat.com>

On Sat, Mar 31, 2012 at 11:34 PM, Oleg Nesterov <oleg@redhat.com> wrote:
> On 03/31, Eric Dumazet wrote:
>>
>> On Sat, 2012-03-31 at 19:51 +0200, Sasha Levin wrote:
>> > Hi all,
>> >
>> > It appears that a hang may occur when destroying an ipv6 tunnel, which
>> > I've reproduced several times in a KVM vm.
>
> kernel version?

latest linux-next

>> > [ 1561.564172] INFO: task kworker/u:2:3140 blocked for more than 120 seconds.
>
> And nobody else?

Some more messages follow a bit later which get stuck in vfs related code.

> It would be nice to know what sysrq-t says, in particular the trace
> of khelper thread is interesting.

Sure, I'll get one when it happens again.

>> Something is wrong here, call_usermodehelper_exec ( ... UMH_WAIT_EXEC)
>> should not block forever.
>
> Yes, unless it triggers another request_module()...
>
> Tetsuo, could you please take a look? Unlikely, but may be this
> is fixed by your kmod-avoid-deadlock-by-recursive-kmod-call.patch
> in -mm ?
>
> Oleg.
>

^ permalink raw reply

* Re: ipv6: tunnel: hang when destroying ipv6 tunnel
From: Oleg Nesterov @ 2012-03-31 21:34 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Sasha Levin, davem, kuznet, jmorris, yoshfuji, Patrick McHardy,
	netdev, linux-kernel@vger.kernel.org List, Dave Jones,
	Tetsuo Handa
In-Reply-To: <1333227549.2325.4051.camel@edumazet-glaptop>

On 03/31, Eric Dumazet wrote:
>
> On Sat, 2012-03-31 at 19:51 +0200, Sasha Levin wrote:
> > Hi all,
> >
> > It appears that a hang may occur when destroying an ipv6 tunnel, which
> > I've reproduced several times in a KVM vm.

kernel version?

> > [ 1561.564172] INFO: task kworker/u:2:3140 blocked for more than 120 seconds.

And nobody else?

It would be nice to know what sysrq-t says, in particular the trace
of khelper thread is interesting.

> Something is wrong here, call_usermodehelper_exec ( ... UMH_WAIT_EXEC)
> should not block forever.

Yes, unless it triggers another request_module()...

Tetsuo, could you please take a look? Unlikely, but may be this
is fixed by your kmod-avoid-deadlock-by-recursive-kmod-call.patch
in -mm ?

Oleg.

^ permalink raw reply

* Re: sendmmsg: put_user vs __put_user
From: David Miller @ 2012-03-31 21:27 UTC (permalink / raw)
  To: drepper; +Cc: netdev, linux-kernel
In-Reply-To: <CAOPLpQewA-AduBudgH5FK6Kz_=nHv6eFhGD29TkAosPTdP4ZHg@mail.gmail.com>

From: Ulrich Drepper <drepper@gmail.com>
Date: Sat, 31 Mar 2012 08:30:25 -0400

> On Fri, Mar 30, 2012 at 20:51, David Miller <davem@davemloft.net> wrote:
>> Compat processes are not able to generate virtual addresses anywhere
>> near the range where the kernel resides, so the address range
>> verification done by put_user() is completely superfluous and
>> therefore not necessary.  The normal exception handling done by the
>> access is completely sufficient.
> 
> I was more thinking about the effects of might_fault() then additional tests.

This is very clearly in a context where locks are not held and sleeping
would be fine, so I don't see any value in that either.

^ permalink raw reply

* Re: [PATCH v5 2/2] Ethernet driver for the WIZnet W5100 chip
From: Mark Brown @ 2012-03-31 21:23 UTC (permalink / raw)
  To: Mike Sinkovsky; +Cc: netdev, linux-kernel
In-Reply-To: <1333090806-27988-2-git-send-email-msink@permonline.ru>

On Fri, Mar 30, 2012 at 01:00:06PM +0600, Mike Sinkovsky wrote:

> +config WIZNET_W5100
> +	tristate "WIZnet W5100 Ethernet support"
> +	depends on ARM || BLACKFIN

What are the architecture dependencies here?

> +static irqreturn_t w5100_interrupt(int irq, void *ndev_instance)
> +{
> +	struct net_device *ndev = ndev_instance;
> +	struct w5100_priv *priv = netdev_priv(ndev);
> +
> +	int ir = w5100_read(priv, W5100_S0_IR);
> +	w5100_write(priv, W5100_S0_IR, ir);
> +
> +	if (ir & S0_IR_RECV) {
> +		if (napi_schedule_prep(&priv->napi)) {
> +			w5100_write(priv, W5100_IMR, 0);
> +			mmiowb();
> +			__napi_schedule(&priv->napi);
> +		}
> +	}
> +
> +	if (ir & S0_IR_SENDOK) {
> +		if (unlikely(netif_queue_stopped(ndev)))
> +			netif_wake_queue(ndev);
> +	}
> +
> +	return IRQ_HANDLED;

This unconditionally acknowledges the interrupt even if one wasn't
reported by the device.

> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0)
> +		return irq;
> +	ret = devm_request_irq(&pdev->dev, irq, w5100_interrupt,
> +			       IRQ_TYPE_LEVEL_LOW, name, ndev);
> +	if (ret < 0)
> +		return ret;
> +	priv->irq = irq;
> +
> +	link = platform_get_resource(pdev, IORESOURCE_IO, 0);
> +	if (!link) {
> +		priv->link_gpio = -1;

This is rather an abuse of the resource API and will run into trouble on
device tree based systems.  You should use platform data for non-DT
systems.

> +		if (request_irq(priv->link_irq, w5100_detect_link,
> +				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> +				link_name, priv->ndev) < 0)

Suggest using request_any_context_irq() to increase the range of
supported interrupt controllers.

> +err_register:
> +	free_netdev(ndev);
> +	platform_set_drvdata(pdev, NULL);
> +	dev_info(&pdev->dev, "probe failed (%d)\n", err);

This will be done for you by the driver core.

^ permalink raw reply

* [patch net-next 4/4] team: add loadbalance mode
From: Jiri Pirko @ 2012-03-31 21:01 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, bhutchings, shemminger, raise.sail,
	nuno.martins, matt
In-Reply-To: <1333227682-10235-1-git-send-email-jpirko@redhat.com>

This patch introduces new team mode. It's TX port is selected by
user-set BPF hash function.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 drivers/net/team/Kconfig                 |   11 ++
 drivers/net/team/Makefile                |    1 +
 drivers/net/team/team_mode_loadbalance.c |  188 ++++++++++++++++++++++++++++++
 3 files changed, 200 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/team/team_mode_loadbalance.c

diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig
index 248a144..89024d5 100644
--- a/drivers/net/team/Kconfig
+++ b/drivers/net/team/Kconfig
@@ -40,4 +40,15 @@ config NET_TEAM_MODE_ACTIVEBACKUP
 	  To compile this team mode as a module, choose M here: the module
 	  will be called team_mode_activebackup.
 
+config NET_TEAM_MODE_LOADBALANCE
+	tristate "Load-balance mode support"
+	depends on NET_TEAM
+	---help---
+	  This mode provides load balancing functionality. Tx port selection
+	  is done using BPF function set up from userspace (bpf_hash_func
+	  option)
+
+	  To compile this team mode as a module, choose M here: the module
+	  will be called team_mode_loadbalance.
+
 endif # NET_TEAM
diff --git a/drivers/net/team/Makefile b/drivers/net/team/Makefile
index 85f2028..fb9f4c1 100644
--- a/drivers/net/team/Makefile
+++ b/drivers/net/team/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_NET_TEAM) += team.o
 obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o
 obj-$(CONFIG_NET_TEAM_MODE_ACTIVEBACKUP) += team_mode_activebackup.o
+obj-$(CONFIG_NET_TEAM_MODE_LOADBALANCE) += team_mode_loadbalance.o
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
new file mode 100644
index 0000000..ed20f39
--- /dev/null
+++ b/drivers/net/team/team_mode_loadbalance.c
@@ -0,0 +1,188 @@
+/*
+ * drivers/net/team/team_mode_loadbalance.c - Load-balancing mode for team
+ * Copyright (c) 2012 Jiri Pirko <jpirko@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/if_team.h>
+
+struct lb_priv {
+	struct sk_filter __rcu *fp;
+	struct sock_fprog *orig_fprog;
+};
+
+static struct lb_priv *lb_priv(struct team *team)
+{
+	return (struct lb_priv *) &team->mode_priv;
+}
+
+static bool lb_transmit(struct team *team, struct sk_buff *skb)
+{
+	struct sk_filter *fp;
+	struct team_port *port;
+	unsigned int hash;
+	int port_index;
+
+	fp = rcu_dereference(lb_priv(team)->fp);
+	if (unlikely(!fp))
+		goto drop;
+	hash = SK_RUN_FILTER(fp, skb);
+	port_index = hash % team->port_count;
+	port = team_get_port_by_index_rcu(team, port_index);
+	if (unlikely(!port))
+		goto drop;
+	skb->dev = port->dev;
+	if (dev_queue_xmit(skb))
+		return false;
+	return true;
+
+drop:
+	dev_kfree_skb_any(skb);
+	return false;
+}
+
+static int lb_bpf_func_get(struct team *team, void *arg)
+{
+	struct team_option_binary *tbinary = team_optarg_tbinary(arg);
+
+	memset(tbinary, 0, sizeof(*tbinary));
+	if (!lb_priv(team)->orig_fprog)
+		return 0;
+
+	tbinary->data_len = lb_priv(team)->orig_fprog->len *
+			    sizeof(struct sock_filter);
+	tbinary->data = lb_priv(team)->orig_fprog->filter;
+	return 0;
+}
+
+static int __fprog_create(struct sock_fprog **pfprog, u32 data_len,
+			  void *data)
+{
+	struct sock_fprog *fprog;
+	struct sock_filter *filter = (struct sock_filter *) data;
+
+	if (data_len % sizeof(struct sock_filter))
+		return -EINVAL;
+	fprog = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL);
+	if (!fprog)
+		return -ENOMEM;
+	fprog->filter = kmemdup(filter, data_len, GFP_KERNEL);
+	if (!fprog->filter) {
+		kfree(fprog);
+		return -ENOMEM;
+	}
+	fprog->len = data_len / sizeof(struct sock_filter);
+	*pfprog = fprog;
+	return 0;
+}
+
+static void __fprog_destroy(struct sock_fprog *fprog)
+{
+	kfree(fprog->filter);
+	kfree(fprog);
+}
+
+static int lb_bpf_func_set(struct team *team, void *arg)
+{
+	struct team_option_binary *tbinary = team_optarg_tbinary(arg);
+	struct sk_filter *fp = NULL;
+	struct sock_fprog *fprog = NULL;
+	int err;
+
+	if (tbinary->data_len) {
+		err = __fprog_create(&fprog, tbinary->data_len,
+				     tbinary->data);
+		if (err)
+			return err;
+		err = sk_unattached_filter_create(&fp, fprog);
+		if (err) {
+			__fprog_destroy(fprog);
+			return err;
+		}
+	}
+
+	if (lb_priv(team)->orig_fprog) {
+		/* Clear old filter data */
+		__fprog_destroy(lb_priv(team)->orig_fprog);
+		sk_unattached_filter_destroy(lb_priv(team)->fp);
+	}
+
+	rcu_assign_pointer(lb_priv(team)->fp, fp);
+	lb_priv(team)->orig_fprog = fprog;
+	return 0;
+}
+
+static const struct team_option lb_options[] = {
+	{
+		.name = "bpf_hash_func",
+		.type = TEAM_OPTION_TYPE_BINARY,
+		.getter = lb_bpf_func_get,
+		.setter = lb_bpf_func_set,
+	},
+};
+
+int lb_init(struct team *team)
+{
+	return team_options_register(team, lb_options,
+				     ARRAY_SIZE(lb_options));
+}
+
+void lb_exit(struct team *team)
+{
+	team_options_unregister(team, lb_options,
+				ARRAY_SIZE(lb_options));
+}
+
+static int lb_port_enter(struct team *team, struct team_port *port)
+{
+	return team_port_set_team_mac(port);
+}
+
+static void lb_port_change_mac(struct team *team, struct team_port *port)
+{
+	team_port_set_team_mac(port);
+}
+
+static const struct team_mode_ops lb_mode_ops = {
+	.init			= lb_init,
+	.exit			= lb_exit,
+	.transmit		= lb_transmit,
+	.port_enter		= lb_port_enter,
+	.port_change_mac	= lb_port_change_mac,
+};
+
+static struct team_mode lb_mode = {
+	.kind		= "loadbalance",
+	.owner		= THIS_MODULE,
+	.priv_size	= sizeof(struct lb_priv),
+	.ops		= &lb_mode_ops,
+};
+
+static int __init lb_init_module(void)
+{
+	return team_mode_register(&lb_mode);
+}
+
+static void __exit lb_cleanup_module(void)
+{
+	team_mode_unregister(&lb_mode);
+}
+
+module_init(lb_init_module);
+module_exit(lb_cleanup_module);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>");
+MODULE_DESCRIPTION("Load-balancing mode for team");
+MODULE_ALIAS("team-mode-loadbalance");
-- 
1.7.9.1

^ permalink raw reply related

* [patch net-next 3/4] team: add binary option type
From: Jiri Pirko @ 2012-03-31 21:01 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, bhutchings, shemminger, raise.sail,
	nuno.martins, matt
In-Reply-To: <1333227682-10235-1-git-send-email-jpirko@redhat.com>

For transfering generic binary data (e.g. BPF code), introduce new
binary option type.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 drivers/net/team/team.c |   28 ++++++++++++++++++++++++----
 include/linux/if_team.h |    8 ++++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 8f81805..9ad52b5b 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1145,10 +1145,7 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = {
 	},
 	[TEAM_ATTR_OPTION_CHANGED]		= { .type = NLA_FLAG },
 	[TEAM_ATTR_OPTION_TYPE]			= { .type = NLA_U8 },
-	[TEAM_ATTR_OPTION_DATA] = {
-		.type = NLA_BINARY,
-		.len = TEAM_STRING_MAX_LEN,
-	},
+	[TEAM_ATTR_OPTION_DATA]			= { .type = NLA_BINARY },
 };
 
 static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
@@ -1256,6 +1253,7 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
 	list_for_each_entry(option, &team->option_list, list) {
 		struct nlattr *option_item;
 		long arg;
+		struct team_option_binary tbinary;
 
 		/* Include only changed options if fill all mode is not on */
 		if (!fillall && !option->changed)
@@ -1282,6 +1280,13 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
 			NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_DATA,
 				       (char *) arg);
 			break;
+		case TEAM_OPTION_TYPE_BINARY:
+			NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY);
+			arg = (long) &tbinary;
+			team_option_get(team, option, &arg);
+			NLA_PUT(skb, TEAM_ATTR_OPTION_DATA,
+				tbinary.data_len, tbinary.data);
+			break;
 		default:
 			BUG();
 		}
@@ -1366,6 +1371,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
 		case NLA_STRING:
 			opt_type = TEAM_OPTION_TYPE_STRING;
 			break;
+		case NLA_BINARY:
+			opt_type = TEAM_OPTION_TYPE_BINARY;
+			break;
 		default:
 			goto team_put;
 		}
@@ -1374,19 +1382,31 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
 		list_for_each_entry(option, &team->option_list, list) {
 			long arg;
 			struct nlattr *opt_data_attr;
+			struct team_option_binary tbinary;
+			int data_len;
 
 			if (option->type != opt_type ||
 			    strcmp(option->name, opt_name))
 				continue;
 			opt_found = true;
 			opt_data_attr = mode_attrs[TEAM_ATTR_OPTION_DATA];
+			data_len = nla_len(opt_data_attr);
 			switch (opt_type) {
 			case TEAM_OPTION_TYPE_U32:
 				arg = nla_get_u32(opt_data_attr);
 				break;
 			case TEAM_OPTION_TYPE_STRING:
+				if (data_len > TEAM_STRING_MAX_LEN) {
+					err = -EINVAL;
+					goto team_put;
+				}
 				arg = (long) nla_data(opt_data_attr);
 				break;
+			case TEAM_OPTION_TYPE_BINARY:
+				tbinary.data_len = data_len;
+				tbinary.data = nla_data(opt_data_attr);
+				arg = (long) &tbinary;
+				break;
 			default:
 				BUG();
 			}
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 58404b0..41163ac 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -68,6 +68,7 @@ struct team_mode_ops {
 enum team_option_type {
 	TEAM_OPTION_TYPE_U32,
 	TEAM_OPTION_TYPE_STRING,
+	TEAM_OPTION_TYPE_BINARY,
 };
 
 struct team_option {
@@ -82,6 +83,13 @@ struct team_option {
 	bool removed;
 };
 
+struct team_option_binary {
+	u32 data_len;
+	void *data;
+};
+
+#define team_optarg_tbinary(arg) (*((struct team_option_binary **) arg))
+
 struct team_mode {
 	struct list_head list;
 	const char *kind;
-- 
1.7.9.1

^ permalink raw reply related

* [patch net-next 2/4] filter: add XOR operation
From: Jiri Pirko @ 2012-03-31 21:01 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, bhutchings, shemminger, raise.sail,
	nuno.martins, matt
In-Reply-To: <1333227682-10235-1-git-send-email-jpirko@redhat.com>

Add XOR instruction fo BPF machine. Needed for computing packet hashes.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 include/linux/filter.h |    4 +++-
 net/core/filter.c      |    4 ++++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 92dd993..7209099 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -126,7 +126,8 @@ struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
 #define SKF_AD_HATYPE	28
 #define SKF_AD_RXHASH	32
 #define SKF_AD_CPU	36
-#define SKF_AD_MAX	40
+#define SKF_AD_ALU_XOR_X	40
+#define SKF_AD_MAX	44
 #define SKF_NET_OFF   (-0x100000)
 #define SKF_LL_OFF    (-0x200000)
 
@@ -231,6 +232,7 @@ enum {
 	BPF_S_ANC_HATYPE,
 	BPF_S_ANC_RXHASH,
 	BPF_S_ANC_CPU,
+	BPF_S_ANC_ALU_XOR_X,
 };
 
 #endif /* __KERNEL__ */
diff --git a/net/core/filter.c b/net/core/filter.c
index cfbea88..5099c4b 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -315,6 +315,9 @@ load_b:
 		case BPF_S_ANC_CPU:
 			A = raw_smp_processor_id();
 			continue;
+		case BPF_S_ANC_ALU_XOR_X:
+			A ^= X;
+			continue;
 		case BPF_S_ANC_NLATTR: {
 			struct nlattr *nla;
 
@@ -559,6 +562,7 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
 			ANCILLARY(HATYPE);
 			ANCILLARY(RXHASH);
 			ANCILLARY(CPU);
+			ANCILLARY(ALU_XOR_X);
 			}
 		}
 		ftest->code = code;
-- 
1.7.9.1

^ permalink raw reply related

* [patch net-next 1/4] filter: Allow to create sk-unattached filters
From: Jiri Pirko @ 2012-03-31 21:01 UTC (permalink / raw)
  To: netdev
  Cc: davem, eric.dumazet, bhutchings, shemminger, raise.sail,
	nuno.martins, matt
In-Reply-To: <1333227682-10235-1-git-send-email-jpirko@redhat.com>

Today, BPF filters are bind to sockets. Since BPF machine becomes handy
for other purposes, this patch allows to create unattached filter.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 include/linux/filter.h |    3 ++
 net/core/filter.c      |   66 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 8eeb205..92dd993 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -153,6 +153,9 @@ static inline unsigned int sk_filter_len(const struct sk_filter *fp)
 extern int sk_filter(struct sock *sk, struct sk_buff *skb);
 extern unsigned int sk_run_filter(const struct sk_buff *skb,
 				  const struct sock_filter *filter);
+extern int sk_unattached_filter_create(struct sk_filter **pfp,
+				       struct sock_fprog *fprog);
+extern void sk_unattached_filter_destroy(struct sk_filter *fp);
 extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
 extern int sk_detach_filter(struct sock *sk);
 extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
diff --git a/net/core/filter.c b/net/core/filter.c
index 5dea452..cfbea88 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -587,6 +587,67 @@ void sk_filter_release_rcu(struct rcu_head *rcu)
 }
 EXPORT_SYMBOL(sk_filter_release_rcu);
 
+static int __sk_prepare_filter(struct sk_filter *fp)
+{
+	int err;
+
+	fp->bpf_func = sk_run_filter;
+
+	err = sk_chk_filter(fp->insns, fp->len);
+	if (err)
+		return err;
+
+	bpf_jit_compile(fp);
+	return 0;
+}
+
+/**
+ *	sk_unattached_filter_create - create an unattached filter
+ *	@fprog: the filter program
+ *	@sk: the socket to use
+ *
+ * Create a filter independent ofr any socket. We first run some
+ * sanity checks on it to make sure it does not explode on us later.
+ * If an error occurs or there is insufficient memory for the filter
+ * a negative errno code is returned. On success the return is zero.
+ */
+int sk_unattached_filter_create(struct sk_filter **pfp,
+				struct sock_fprog *fprog)
+{
+	struct sk_filter *fp;
+	unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
+	int err;
+
+	/* Make sure new filter is there and in the right amounts. */
+	if (fprog->filter == NULL)
+		return -EINVAL;
+
+	fp = kmalloc(fsize + sizeof(*fp), GFP_KERNEL);
+	if (!fp)
+		return -ENOMEM;
+	memcpy(fp->insns, fprog->filter, fsize);
+
+	atomic_set(&fp->refcnt, 1);
+	fp->len = fprog->len;
+
+	err = __sk_prepare_filter(fp);
+	if (err)
+		goto free_mem;
+
+	*pfp = fp;
+	return 0;
+free_mem:
+	kfree(fp);
+	return err;
+}
+EXPORT_SYMBOL_GPL(sk_unattached_filter_create);
+
+void sk_unattached_filter_destroy(struct sk_filter *fp)
+{
+	sk_filter_release(fp);
+}
+EXPORT_SYMBOL_GPL(sk_unattached_filter_destroy);
+
 /**
  *	sk_attach_filter - attach a socket filter
  *	@fprog: the filter program
@@ -617,16 +678,13 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
 
 	atomic_set(&fp->refcnt, 1);
 	fp->len = fprog->len;
-	fp->bpf_func = sk_run_filter;
 
-	err = sk_chk_filter(fp->insns, fp->len);
+	err = __sk_prepare_filter(fp);
 	if (err) {
 		sk_filter_uncharge(sk, fp);
 		return err;
 	}
 
-	bpf_jit_compile(fp);
-
 	old_fp = rcu_dereference_protected(sk->sk_filter,
 					   sock_owned_by_user(sk));
 	rcu_assign_pointer(sk->sk_filter, fp);
-- 
1.7.9.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