Netdev List
 help / color / mirror / Atom feed
* Re: [RFC PATCH v2 linux-next] et131x: Promote staging et131x driver to drivers/net
From: Dan Carpenter @ 2013-01-23 10:31 UTC (permalink / raw)
  To: Mark Einon; +Cc: davem, gregkh, sfr, devel, netdev, linux-kernel
In-Reply-To: <1358935859-29525-1-git-send-email-mark.einon@gmail.com>

On Wed, Jan 23, 2013 at 10:10:58AM +0000, Mark Einon wrote:
> diff --git a/drivers/net/ethernet/agere/Kconfig b/drivers/net/ethernet/agere/Kconfig
> new file mode 100644
> index 0000000..6854966
> --- /dev/null
> +++ b/drivers/net/ethernet/agere/Kconfig
> @@ -0,0 +1,32 @@
> +#
> +# Agere device configuration
> +#
> +
> +config NET_VENDOR_AGERE
> +       bool "Agere devices"
> +       default y
> +       depends on PCI
> +       ---help---
> +         If you have a network (Ethernet) card belonging to this class, say Y
> +         and read the Ethernet-HOWTO, available from
> +         <http://www.tldp.org/docs.html#howto>.
> +
> +         Note that the answer to this question doesn't directly affect the
> +         kernel: saying N will just cause the configurator to skip all
> +         the questions about Atheros devices. If you say Y, you will be asked
                                ^^^^^^^
Agere?

> +         for your specific card in the following questions.
> +

I think you should just leave this block out entirely.  It doesn't
save time for anyone.

regards,
dan carpenter

^ permalink raw reply

* [net-next.git] net: phy: realtek: add rtl8211e driver
From: Giuseppe CAVALLARO @ 2013-01-23 10:30 UTC (permalink / raw)
  To: netdev; +Cc: Giuseppe Cavallaro

This patch adds the minimal driver to manage the
Realtek RTL8211E 10/100/1000 Transceivers.

Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/phy/realtek.c |   50 +++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 72f9347..8e7af83 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -23,6 +23,8 @@
 #define RTL821x_INER_INIT	0x6400
 #define RTL821x_INSR		0x13
 
+#define	RTL8211E_INER_LINK_STAT	0x10
+
 MODULE_DESCRIPTION("Realtek PHY driver");
 MODULE_AUTHOR("Johnson Leung");
 MODULE_LICENSE("GPL");
@@ -36,7 +38,7 @@ static int rtl821x_ack_interrupt(struct phy_device *phydev)
 	return (err < 0) ? err : 0;
 }
 
-static int rtl821x_config_intr(struct phy_device *phydev)
+static int rtl8211b_config_intr(struct phy_device *phydev)
 {
 	int err;
 
@@ -49,28 +51,63 @@ static int rtl821x_config_intr(struct phy_device *phydev)
 	return err;
 }
 
+static int rtl8211e_config_intr(struct phy_device *phydev)
+{
+	int err;
+
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+		err = phy_write(phydev, RTL821x_INER,
+				RTL8211E_INER_LINK_STAT);
+	else
+		err = phy_write(phydev, RTL821x_INER, 0);
+
+	return err;
+}
+
 /* RTL8211B */
-static struct phy_driver rtl821x_driver = {
+static struct phy_driver rtl8211b_driver = {
 	.phy_id		= 0x001cc912,
-	.name		= "RTL821x Gigabit Ethernet",
+	.name		= "RTL8211B Gigabit Ethernet",
 	.phy_id_mask	= 0x001fffff,
 	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.config_aneg	= &genphy_config_aneg,
 	.read_status	= &genphy_read_status,
 	.ack_interrupt	= &rtl821x_ack_interrupt,
-	.config_intr	= &rtl821x_config_intr,
+	.config_intr	= &rtl8211b_config_intr,
+	.driver		= { .owner = THIS_MODULE,},
+};
+
+/* RTL8211E */
+static struct phy_driver rtl8211e_driver = {
+	.phy_id		= 0x001cc915,
+	.name		= "RTL8211E Gigabit Ethernet",
+	.phy_id_mask	= 0x001fffff,
+	.features	= PHY_GBIT_FEATURES,
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_aneg	= &genphy_config_aneg,
+	.read_status	= &genphy_read_status,
+	.ack_interrupt	= &rtl821x_ack_interrupt,
+	.config_intr	= &rtl8211e_config_intr,
+	.suspend	= genphy_suspend,
+	.resume		= genphy_resume,
 	.driver		= { .owner = THIS_MODULE,},
 };
 
 static int __init realtek_init(void)
 {
-	return phy_driver_register(&rtl821x_driver);
+	int ret;
+
+	ret = phy_driver_register(&rtl8211b_driver);
+	if (ret < 0)
+		return -ENODEV;
+	return phy_driver_register(&rtl8211e_driver);
 }
 
 static void __exit realtek_exit(void)
 {
-	phy_driver_unregister(&rtl821x_driver);
+	phy_driver_unregister(&rtl8211b_driver);
+	phy_driver_unregister(&rtl8211e_driver);
 }
 
 module_init(realtek_init);
@@ -78,6 +115,7 @@ module_exit(realtek_exit);
 
 static struct mdio_device_id __maybe_unused realtek_tbl[] = {
 	{ 0x001cc912, 0x001fffff },
+	{ 0x001cc915, 0x001fffff },
 	{ }
 };
 
-- 
1.7.4.4

^ permalink raw reply related

* [PATCH (net.git) 2/2] net: phy: icplus: fix broken INTR pin settings
From: Giuseppe CAVALLARO @ 2013-01-23 10:22 UTC (permalink / raw)
  To: netdev; +Cc: Giuseppe CAVALLARO
In-Reply-To: <1358936557-31540-1-git-send-email-peppe.cavallaro@st.com>

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>

This patch fixes the setting of the INTR pin that is
valid for IP101 A/G device and not for the IP1001.

Reported-by: Anunay Saxena <anunay.saxena@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/phy/icplus.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index c0e0924..b5ddd50 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -139,11 +139,6 @@ static int ip1001_config_init(struct phy_device *phydev)
 	if (c < 0)
 		return c;
 
-	/* INTR pin used: speed/link/duplex will cause an interrupt */
-	c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT);
-	if (c < 0)
-		return c;
-
 	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
 	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
 	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
@@ -178,6 +173,11 @@ static int ip101a_g_config_init(struct phy_device *phydev)
 	if (c < 0)
 		return c;
 
+	/* INTR pin used: speed/link/duplex will cause an interrupt */
+	c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT);
+	if (c < 0)
+		return c;
+
 	/* Enable Auto Power Saving mode */
 	c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
 	c |= IP101A_G_APS_ON;
-- 
1.7.4.4

^ permalink raw reply related

* [PATCH (net.git) 1/2] net: phy: icplus: Use the RGMII interface mode to configure clock delays
From: Giuseppe CAVALLARO @ 2013-01-23 10:22 UTC (permalink / raw)
  To: netdev; +Cc: Stuart Menefy, Giuseppe Cavallaro

From: Stuart Menefy <stuart.menefy@st.com>

Like several other PHY devices which support RGMII, the IC+1001 allows
additional delays to by added to the RX_CLK and TX_CLK signals to
compensate for skew between the clock and data signals. Previously this
was always enabled, but this change makes use of the different RGMII
interface modes to allow the user to specify whether this should be
enabled.

Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/phy/icplus.c |   21 ++++++++++++++++-----
 1 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index d5199cb..c0e0924 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -36,8 +36,9 @@ MODULE_LICENSE("GPL");
 
 /* IP101A/G - IP1001 */
 #define IP10XX_SPEC_CTRL_STATUS		16	/* Spec. Control Register */
+#define IP1001_RXPHASE_SEL		(1<<0)	/* Add delay on RX_CLK */
+#define IP1001_TXPHASE_SEL		(1<<1)	/* Add delay on TX_CLK */
 #define IP1001_SPEC_CTRL_STATUS_2	20	/* IP1001 Spec. Control Reg 2 */
-#define IP1001_PHASE_SEL_MASK		3	/* IP1001 RX/TXPHASE_SEL */
 #define IP1001_APS_ON			11	/* IP1001 APS Mode  bit */
 #define IP101A_G_APS_ON			2	/* IP101A/G APS Mode bit */
 #define IP101A_G_IRQ_CONF_STATUS	0x11	/* Conf Info IRQ & Status Reg */
@@ -143,14 +144,24 @@ static int ip1001_config_init(struct phy_device *phydev)
 	if (c < 0)
 		return c;
 
-	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
-		/* Additional delay (2ns) used to adjust RX clock phase
-		 * at RGMII interface */
+	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
+
 		c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
 		if (c < 0)
 			return c;
 
-		c |= IP1001_PHASE_SEL_MASK;
+		c &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
+
+		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+			c |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
+		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+			c |= IP1001_RXPHASE_SEL;
+		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+			c |= IP1001_TXPHASE_SEL;
+
 		c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
 		if (c < 0)
 			return c;
-- 
1.7.4.4

^ permalink raw reply related

* [PATCH][net-next] gianfar: Restore promisc mode on gfar_init_mac()
From: Claudiu Manoil @ 2013-01-23 10:18 UTC (permalink / raw)
  To: netdev; +Cc: Claudiu Manoil, Voncken C Acksys

Reactivate promiscuous mode in H/W upon gfar_init_mac(), if the
net dev requires it (IFF_PROMISC flag set).
This way the promisc mode is preserved accross device reset conditions
like tx timeout, device restore, a.s.o.

Signed-off-by: Voncken C Acksys <cedric.voncken@acksys.fr>
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
 drivers/net/ethernet/freescale/gianfar.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index bffb2ed..e765b9b 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -355,6 +355,10 @@ static void gfar_init_mac(struct net_device *ndev)
 		gfar_write(&regs->rir0, DEFAULT_RIR0);
 	}
 
+	/* Restore PROMISC mode */
+	if (ndev->flags & IFF_PROMISC)
+		rctrl |= RCTRL_PROM;
+
 	if (ndev->features & NETIF_F_RXCSUM)
 		rctrl |= RCTRL_CHECKSUMMING;
 
-- 
1.6.6

^ permalink raw reply related

* [RFC PATCH v2 linux-next] et131x: Promote staging et131x driver to drivers/net
From: Mark Einon @ 2013-01-23 10:10 UTC (permalink / raw)
  To: davem, gregkh, sfr; +Cc: netdev, devel, linux-kernel, dan.carpenter, Mark Einon
In-Reply-To: <1358541648-29922-1-git-send-email-mark.einon@gmail.com>

This patch moves the et131x gigabit ethernet driver from drivers/staging
to drivers/net/ethernet/agere.

All the existing issues noted for this driver have been resolved, apart
from one performance issue where some fragmented packets suffer from
frame receive errors.

Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
 MAINTAINERS                                        |   11 ++++---
 drivers/net/ethernet/Kconfig                       |    1 +
 drivers/net/ethernet/Makefile                      |    1 +
 drivers/net/ethernet/agere/Kconfig                 |   32 ++++++++++++++++++++
 .../et131x => net/ethernet/agere}/Makefile         |    1 +
 .../et131x => net/ethernet/agere}/et131x.c         |    0
 .../et131x => net/ethernet/agere}/et131x.h         |    0
 drivers/staging/Kconfig                            |    2 --
 drivers/staging/Makefile                           |    1 -
 drivers/staging/et131x/Kconfig                     |   10 ------
 drivers/staging/et131x/README                      |   16 ----------
 11 files changed, 41 insertions(+), 34 deletions(-)
 create mode 100644 drivers/net/ethernet/agere/Kconfig
 rename drivers/{staging/et131x => net/ethernet/agere}/Makefile (98%)
 rename drivers/{staging/et131x => net/ethernet/agere}/et131x.c (100%)
 rename drivers/{staging/et131x => net/ethernet/agere}/et131x.h (100%)
 delete mode 100644 drivers/staging/et131x/Kconfig
 delete mode 100644 drivers/staging/et131x/README

diff --git a/MAINTAINERS b/MAINTAINERS
index e80447a..cb09e9e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3029,6 +3029,12 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
 F:	drivers/video/s1d13xxxfb.c
 F:	include/video/s1d13xxxfb.h
 
+ET131X NETWORK DRIVER
+M:	Mark Einon <mark.einon@gmail.com>
+L:	netdev@vger.kernel.org
+S:	Maintained
+F:	drivers/net/ethernet/agere
+
 ETHEREXPRESS-16 NETWORK DRIVER
 M:	Philip Blundell <philb@gnu.org>
 L:	netdev@vger.kernel.org
@@ -7473,11 +7479,6 @@ M:	David Rowe <david@rowetel.com>
 S:	Odd Fixes
 F:	drivers/staging/echo/
 
-STAGING - ET131X NETWORK DRIVER
-M:	Mark Einon <mark.einon@gmail.com>
-S:	Odd Fixes
-F:	drivers/staging/et131x/
-
 STAGING - FLARION FT1000 DRIVERS
 M:	Marek Belisko <marek.belisko@gmail.com>
 S:	Odd Fixes
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ed956e0..4b4edbb 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -20,6 +20,7 @@ config SUNGEM_PHY
 source "drivers/net/ethernet/3com/Kconfig"
 source "drivers/net/ethernet/adaptec/Kconfig"
 source "drivers/net/ethernet/aeroflex/Kconfig"
+source "drivers/net/ethernet/agere/Kconfig"
 source "drivers/net/ethernet/alteon/Kconfig"
 source "drivers/net/ethernet/amd/Kconfig"
 source "drivers/net/ethernet/apple/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 8268d85..7a96adb 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_NET_VENDOR_3COM) += 3com/
 obj-$(CONFIG_NET_VENDOR_8390) += 8390/
 obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/
 obj-$(CONFIG_GRETH) += aeroflex/
+obj-$(CONFIG_NET_VENDOR_AGERE) += agere/
 obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
 obj-$(CONFIG_NET_VENDOR_AMD) += amd/
 obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
diff --git a/drivers/net/ethernet/agere/Kconfig b/drivers/net/ethernet/agere/Kconfig
new file mode 100644
index 0000000..6854966
--- /dev/null
+++ b/drivers/net/ethernet/agere/Kconfig
@@ -0,0 +1,32 @@
+#
+# Agere device configuration
+#
+
+config NET_VENDOR_AGERE
+       bool "Agere devices"
+       default y
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Atheros devices. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_AGERE
+
+config ET131X
+       tristate "Agere ET-1310 Gigabit Ethernet support"
+       depends on PCI
+       select PHYLIB
+       ---help---
+         This driver supports Agere ET-1310 ethernet adapters.
+
+         To compile this driver as a module, choose M here. The module
+         will be called et131x.
+
+endif # NET_VENDOR_AGERE
+
diff --git a/drivers/staging/et131x/Makefile b/drivers/net/ethernet/agere/Makefile
similarity index 98%
rename from drivers/staging/et131x/Makefile
rename to drivers/net/ethernet/agere/Makefile
index 027ff94..740f413 100644
--- a/drivers/staging/et131x/Makefile
+++ b/drivers/net/ethernet/agere/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_ET131X) += et131x.o
+
diff --git a/drivers/staging/et131x/et131x.c b/drivers/net/ethernet/agere/et131x.c
similarity index 100%
rename from drivers/staging/et131x/et131x.c
rename to drivers/net/ethernet/agere/et131x.c
diff --git a/drivers/staging/et131x/et131x.h b/drivers/net/ethernet/agere/et131x.h
similarity index 100%
rename from drivers/staging/et131x/et131x.h
rename to drivers/net/ethernet/agere/et131x.h
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 0b47a06..5dee726 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -24,8 +24,6 @@ menuconfig STAGING
 
 if STAGING
 
-source "drivers/staging/et131x/Kconfig"
-
 source "drivers/staging/slicoss/Kconfig"
 
 source "drivers/staging/usbip/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index b026ea3..6983d77 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -5,7 +5,6 @@ obj-$(CONFIG_STAGING)		+= staging.o
 
 obj-y				+= media/
 obj-y				+= net/
-obj-$(CONFIG_ET131X)		+= et131x/
 obj-$(CONFIG_SLICOSS)		+= slicoss/
 obj-$(CONFIG_USBIP_CORE)	+= usbip/
 obj-$(CONFIG_W35UND)		+= winbond/
diff --git a/drivers/staging/et131x/Kconfig b/drivers/staging/et131x/Kconfig
deleted file mode 100644
index 8190f2a..0000000
--- a/drivers/staging/et131x/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config ET131X
-	tristate "Agere ET-1310 Gigabit Ethernet support"
-	depends on PCI && NET && NETDEVICES
-	select PHYLIB
-	default n
-	---help---
-	  This driver supports Agere ET-1310 ethernet adapters.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called et131x.
diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README
deleted file mode 100644
index 38537d4..0000000
--- a/drivers/staging/et131x/README
+++ /dev/null
@@ -1,16 +0,0 @@
-This is a driver for the ET1310 network device.
-
-Based on the driver found at https://sourceforge.net/projects/et131x/
-
-Cleaned up immensely by Olaf Hartman and Christoph Hellwig <hch@infradead.org>
-
-Note, the powermanagement options were removed from the vendor provided
-driver as they did not build properly at the time.
-
-TODO:
-	- some rx packets have CRC/code/frame errors
-
-Please send patches to:
-	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-	Mark Einon <mark.einon@gmail.com>
-
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH RESEND] ipv6: add anti-spoofing checks for 6to4 and 6rd
From: Hannes Frederic Sowa @ 2013-01-23 10:02 UTC (permalink / raw)
  To: netdev; +Cc: davem, yoshfuji

This patch adds anti-spoofing checks in sit.c as specified in RFC3964
section 5.2 for 6to4 and RFC5969 section 12 for 6rd. I left out the
checks which could easily be implemented with netfilter.

Specifically this patch adds following logic (based loosely on the
pseudocode in RFC3964 section 5.2):

if prefix (inner_src_v6) == rd6_prefix (2002::/16 is the default)
        and outer_src_v4 != embedded_ipv4 (inner_src_v6)
                drop
if prefix (inner_dst_v6) == rd6_prefix (or 2002::/16 is the default)
        and outer_dst_v4 != embedded_ipv4 (inner_dst_v6)
                drop
accept

To accomplish the specified security checks proposed by above RFCs,
it is still necessary to employ uRPF filters with netfilter. These new
checks only kick in if the employed addresses are within the 2002::/16 or
another range specified by the 6rd-prefix (which defaults to 2002::/16).

Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
 net/ipv6/sit.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index cfba99b..5a09f13 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -73,6 +73,8 @@ static int ipip6_tunnel_init(struct net_device *dev);
 static void ipip6_tunnel_setup(struct net_device *dev);
 static void ipip6_dev_free(struct net_device *dev);
 static struct rtnl_link_ops sit_link_ops __read_mostly;
+static inline __be32 try_6rd(const struct in6_addr *v6dst,
+			     struct ip_tunnel *tunnel);
 
 static int sit_net_id __read_mostly;
 struct sit_net {
@@ -590,6 +592,22 @@ out:
 	return err;
 }
 
+static int sit_chk_encap_addr(struct ip_tunnel *tunnel, const __be32 *addr,
+			      const struct in6_addr *addr6)
+{
+#ifdef CONFIG_IPV6_SIT_6RD
+	if (ipv6_prefix_equal(addr6, &tunnel->ip6rd.prefix,
+			      tunnel->ip6rd.prefixlen) &&
+	    *addr != try_6rd(addr6, tunnel))
+		return 0;
+#else
+	if (addr6->s6_addr16[0] == htons(0x2002) &&
+	    *addr != try_6rd(addr6, tunnel))
+		return 0;
+#endif
+	return 1;
+}
+
 static int ipip6_rcv(struct sk_buff *skb)
 {
 	const struct iphdr *iph;
@@ -613,8 +631,15 @@ static int ipip6_rcv(struct sk_buff *skb)
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
 
-		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
-		    !isatap_chksrc(skb, iph, tunnel)) {
+		if (tunnel->dev->priv_flags & IFF_ISATAP) {
+			if (!isatap_chksrc(skb, iph, tunnel)) {
+				tunnel->dev->stats.rx_errors++;
+				goto out;
+			}
+		} else if (!sit_chk_encap_addr(tunnel, &iph->saddr,
+					       &ipv6_hdr(skb)->saddr) ||
+			   !sit_chk_encap_addr(tunnel, &iph->daddr,
+					       &ipv6_hdr(skb)->daddr)) {
 			tunnel->dev->stats.rx_errors++;
 			goto out;
 		}
-- 
1.7.11.7

^ permalink raw reply related

* Re: [patch]  Gianfar : Enable promiscous mode after queue time out
From: Claudiu Manoil @ 2013-01-23  9:58 UTC (permalink / raw)
  To: Cedric VONCKEN; +Cc: netdev
In-Reply-To: <773DB8A82AB6A046AE0195C68612A319014B7309@sbs2003.acksys.local>

On 1/21/2013 6:24 PM, Cedric VONCKEN wrote:
> 	Hi all,
>
> 	When the Netdev tx queue timeout occurred, the function
> gfar_timeout(..) is called. This function calls indirectly the
> gfar_init_mac(..) function.
>
>   	In this function, the rctrl register is set to a default value.
>
>   	If the Promiscuous is enable on the net dev ( flag IFF_PROMISC
> is  set), the gfar_init_function does not reactivate it.
>
>   	The Promiscuous mode is used for example when the netdev is
> bridged.
>   	
>   	I apply this patch on the kernel 3.8-rc4 to fix it.
>
> 	Signed-off-by : Voncken C Acksys <cedric.voncken@acksys.fr>
>
> --- a/drivers/net/ethernet/freescale/gianfar.c
> +++ b/drivers/net/ethernet/freescale/gianfar.c
> @@ -349,6 +349,11 @@ static void gfar_init_mac(struct net_dev
>   	/* Configure the coalescing support */
>   	gfar_configure_coalescing(priv, 0xFF, 0xFF);
>
> +	if (ndev->flags & IFF_PROMISC) {
> +		/* Set RCTRL to PROM */
> +		rctrl |= RCTRL_PROM;
> +	}
> +
>   	if (priv->rx_filer_enable) {
>   		rctrl |= RCTRL_FILREN;
>   		/* Program the RIR0 reg with the required distribution
> */
>
>
>
>
>

Hello Cedric,

I'll take care of this code change and I'll send a properly formatted 
patch for it.
Besides, gfar_init_mac() may be called for numerous other reasons than 
tx timeout, like changing MTU, changing ring params, restoring the 
interface etc. (any reset condition), so I'll rephrase the patch comment 
too.

Thanks,
Claudiu

^ permalink raw reply

* Re: Unix Socket buffer attribution
From: Hannes Frederic Sowa @ 2013-01-23  9:59 UTC (permalink / raw)
  To: Yannick Koehler; +Cc: netdev
In-Reply-To: <CAJ4BwwFZo=ktoNBpw14yxyvR1QPQ_xVzKRs=R7qv03g1uwn8pg@mail.gmail.com>

On Mon, Jan 21, 2013 at 09:01:53PM -0500, Yannick Koehler wrote:
>   I believe that the problem is that once we move the skb into the
> client's receive queue we need to decrease the sk_wmem_alloc variable
> of the server socket since that skb is no more tied to the server.
> The code should then account for this memory as part of the
> sk_rmem_alloc variable on the client's socket.  The function
> "skb_set_owner_r(skb,owner)" would seem to be the function to do that,
> so it would seem to me.

Your analysis does make sense. Could you cook a patch?

Thanks,

  Hannes

^ permalink raw reply

* Re: [Qemu-devel] tap devices not receiving packets from a bridge
From: Michael S. Tsirkin @ 2013-01-23 10:03 UTC (permalink / raw)
  To: Peter Lieven; +Cc: Stefan Hajnoczi, qemu-devel, netdev
In-Reply-To: <50FE5607.9020405@dlhnet.de>

On Tue, Jan 22, 2013 at 10:04:07AM +0100, Peter Lieven wrote:
> On 23.11.2012 12:01, Michael S. Tsirkin wrote:
> >On Fri, Nov 23, 2012 at 10:41:21AM +0100, Peter Lieven wrote:
> >>
> >>Am 23.11.2012 um 08:02 schrieb Stefan Hajnoczi:
> >>
> >>>On Thu, Nov 22, 2012 at 03:29:52PM +0100, Peter Lieven wrote:
> >>>>is anyone aware of a problem with the linux network bridge that in very rare circumstances stops
> >>>>a bridge from sending pakets to a tap device?
> >>>>
> >>>>My problem occurs in conjunction with vanilla qemu-kvm-1.2.0 and Ubuntu Kernel 3.2.0-34.53
> >>>>which is based on Linux 3.2.33.
> >>>>
> >>>>I was not yet able to reproduce the issue, it happens in really rare cases. The symptom is that
> >>>>the tap does not have any TX packets. RX is working fine. I see the packets coming in at
> >>>>the physical interface on the host, but they are not forwarded to the tap interface.
> >>>>The bridge itself has learnt the mac address of the vServer that is connected to the tap interface.
> >>>>It does not help to toggle the bridge link status,  the tap interface status or the interface in the vServer.
> >>>>It seems that problem occurs if a tap interface that has previously been used, but set to nonpersistent
> >>>>is set persistent again and then is by chance assigned to the same vServer (=same mac address on same
> >>>>bridge) again. Unfortunately it seems not to be reproducible.
> >>>
> >>>Not sure but this patch from Michael Tsirkin may help - it solves an
> >>>issue with persistent tap devices:
> >>>
> >>>http://patchwork.ozlabs.org/patch/198598/
> >>
> >>Hi Stefan,
> >>
> >>thanks for the pointer. I have seen this patch, but I have neglected it because it was dealing
> >>with persistent taps. But maybe the taps in the kernel are not deleted directly.
> >>Can you remember what the syptomps of the above issue have been? Sorry for
> >>being vague, but I currently have no clue whats going on.
> >>
> >>Can someone who has more internal knowledge of the bridging/tap code say if qemu can
> >>be responsible at all if the tap device is not receiving packets from the bridge.
> >>
> >>If I have the following config. Lets say packets coming in via physical interface eth1.123,
> >>and a bridge called br123.I further have a virtual machine with tap0. Both eth1.123
> >>and tap0 are member of br123.
> >>
> >>If the issue occurs the vServer has no network connectivity inbound. If I sent a ping
> >>from the vServer I see it on tap0 and leaving on eth1.123. I see further the arp reply coming
> >>in via eth1.123, but the reply can't be seen on tap0.
> >>
> >>Peter
> >
> >If guest is not consuming packets, a TX queue in tap device
> >will with time overrun (there's space for 1000 packets there).
> >This is code from tun:
> >
> >         if (skb_queue_len(&tfile->socket.sk->sk_receive_queue)
> >                           >= dev->tx_queue_len / tun->numqueues){
> >                 if (!(tun->flags & TUN_ONE_QUEUE)) {
> >                         /* Normal queueing mode. */
> >                         /* Packet scheduler handles dropping of further
> >  * packets. */
> >                         netif_stop_subqueue(dev, txq);
> >
> >                         /* We won't see all dropped packets
> >  * individually, so overrun
> >                          * error is more appropriate. */
> >                         dev->stats.tx_fifo_errors++;
> >
> >
> >So you can detect that this triggered by looking at fifo errors counter in device.
> >
> >Once this happens TX queue is stopped, then you hit this path:
> >
> >                         if (!netif_xmit_stopped(txq)) {
> >                                 __this_cpu_inc(xmit_recursion);
> >                                 rc = dev_hard_start_xmit(skb, dev, txq);
> >                                 __this_cpu_dec(xmit_recursion);
> >                                 if (dev_xmit_complete(rc)) {
> >                                         HARD_TX_UNLOCK(dev, txq);
> >                                         goto out;
> >                                 }
> >                         }
> >
> >so packets are not passed to device anymore.
> >It will stay this way until guest consumes some packets and
> >queue is restarted.
> 
> After some time I again have a vServer in this state. It seems not like there
> are no TX errors.
> 
> # ifconfig tap10
> tap10     Link encap:Ethernet  HWaddr 7a:59:20:6f:e7:e5
>           inet6 addr: fe80::7859:20ff:fe6f:e7e5/64 Scope:Link
>           UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
>           RX packets:197431 errors:0 dropped:0 overruns:0 frame:0
>           TX packets:264309 errors:0 dropped:0 overruns:2 carrier:0
>           collisions:0 txqueuelen:500
>           RX bytes:13842063 (13.8 MB)  TX bytes:35092821 (35.0 MB)
> 
> It seems like the bridge is not forwarding any packets to the tap device anymore altough it has learnt
> the MAC-Adresses and there are also broadcast packets coming in.
> 
> Any more ideas where I could debug?
> 
> Peter
> 
> >
> >>>
> >>>Stefan

Hmm. So there are two overrun errors that triggered, so
it's possible after the second one the queue got stuck in an xoff state.
You'd have to use something like systemtap or kdb to poke at the
queue state to see whether xoff flag is set and/or look
at the receive queue length.

For future, we can try to set TUN_ONE_QUEUE flag on the interface,
or try applying this patch
5d097109257c03a71845729f8db6b5770c4bbedc
in kernel see if this helps.

-- 
MST

^ permalink raw reply

* Re: v3 for tcp friends?
From: Li Yu @ 2013-01-23  9:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Eric Dumazet, Bruce Curtis
In-Reply-To: <50FFAFE7.5030707@gmail.com>

于 2013年01月23日 17:39, Li Yu 写道:
> 于 2013年01月23日 15:58, Li Yu 写道:
>> 于 2013年01月23日 15:21, Li Yu 写道:
>>> 于 2013年01月23日 14:46, Eric Dumazet 写道:
>>>> On Wed, 2013-01-23 at 14:12 +0800, Li Yu wrote:
>>>>> Oops, this hang is not since TCP friends patch!
>>>>>
>>>>> sk_sndbuf_get() is broken by 32 bits integer overflow
>>>>> because of so large value in net.ipv4.tcp_{rmem,wmem}.
>>>>>
>>>>> but this hang also can be found in net-next.git
>>>>> (3.8.0-rc3+), if we run below commands, then all new
>>>>> TCP connections stop working!
>>>>>
>>>>> # when TCP friends is disabled
>>>>> sysctl -w net.ipv4.tcp_rmem="4096 4294967296 4294967296" # 4GB
>>>>> sysctl -w net.ipv4.tcp_wmem="4096 4294967296 4294967296"
>>>>
>>>> Right we need to make sure we dont overflow.
>>>>
>>>> Try the following fix :
>>>>
>>>> diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
>>>> index a25e1d2..1459145 100644
>>>> --- a/net/ipv4/sysctl_net_ipv4.c
>>>> +++ b/net/ipv4/sysctl_net_ipv4.c
>>>> @@ -549,14 +549,16 @@ static struct ctl_table ipv4_table[] = {
>>>>           .data        = &sysctl_tcp_wmem,
>>>>           .maxlen        = sizeof(sysctl_tcp_wmem),
>>>>           .mode        = 0644,
>>>> -        .proc_handler    = proc_dointvec
>>>> +        .extra1        = &zero,
>
> If we added below:
>
> +static int one = 1;
> +static int int_max = INT_MAX;
> ....
> +               .extra1     = &one,
> +        .extra2        = &int_max,
>

The "int_max" may be unnecessary here :)

> The bug is fixed without TCP friends.
>
> Maybe, TCP friends need to use long integer to record result
> of "sk->sk_sndbuf + sk->sk_friend->sk_rcvbuf" ?
>
> BTW: This overflow problem also breaks UDP sockets.

Unix domain sockets is broken too, and any other ?

thanks

Yu

>
> Thanks
>
> Yu
>
>>>> +        .proc_handler    = proc_dointvec_minmax
>>>>       },
>>>>       {
>>>>           .procname    = "tcp_rmem",
>>>>           .data        = &sysctl_tcp_rmem,
>>>>           .maxlen        = sizeof(sysctl_tcp_rmem),
>>>>           .mode        = 0644,
>>>> -        .proc_handler    = proc_dointvec
>>>> +        .extra1        = &zero,
>>>> +        .proc_handler    = proc_dointvec_minmax
>>>>       },
>>>>       {
>>>>           .procname    = "tcp_app_win",
>>>>
>>>>
>>>>
>>> Thanks for so quick reply, I will test it soon.
>>>
>>> however I suspect whether this patch could fix overflow if we merged TCP
>>> friends patch in future.
>>>
>>
>> Tested on 3.7.0-rc1+, but bug is still alive
>> with disabled TCP friends ...
>>
>> Thanks
>>
>> Yu
>>
>>> With TCP friends, we have source like below, or TCP friends should care
>>> this ?
>>>
>>> static inline int sk_sndbuf_get(const struct sock *sk)
>>> {
>>>          if (sk->sk_friend)
>>>                  return sk->sk_sndbuf + sk->sk_friend->sk_rcvbuf;
>>>          else
>>>                  return sk->sk_sndbuf;
>>> }
>>>
>>> static inline bool sk_stream_memory_free(const struct sock *sk)
>>> {
>>>          return sk_wmem_queued_get(sk) < sk_sndbuf_get(sk);
>>> }
>>>
>>> So sk_sndbuf_get() still may be overflow when we have right value in
>>> net.ipv4.tcp_{rmem,wmem}.
>>>
>>> Thanks
>>
>

^ permalink raw reply

* Re: [PATCH net-next 1/3] net: stmmac: add gmac autoneg set for SGMII, TBI, and RTBI
From: Giuseppe CAVALLARO @ 2013-01-23  9:42 UTC (permalink / raw)
  To: Byungho An
  Cc: netdev, linux-kernel, davem, jeffrey.t.kirsher, kgene.kim, cpgs
In-Reply-To: <01e201cdf5a3$1f3e1890$5dba49b0$@samsung.com>

Hello Byungho

On 1/18/2013 6:41 PM, Byungho An wrote:
> Hello Peppe,
>
> On 1/15/2013 11:28 PM, Giuseppe CAVALLARO write:
>> On 1/15/2013 10:45 PM, Byungho An wrote:
>>>
>>> This patch adds gmac autoneg set function for SGMII, TBI, or RTBI
>>> interface. In case of PHY's autoneg is set, gmac's autoneg enable bit
>>> should set. After checking phy's autoneg if phydev's autoneg is '1'
>>> gmac's ANE bit set for those interface.
>>
>> Sorry I've some doubts about these patches.
>>
>> Firstly if the MAC is able to manage RGMII/SGMII etc this should be
> verified
>> by looking at the HW cap register: i.e. PCS bit.
>>
>>     (I have no HW that support this so I cannot do any tests).
>>
> I agree with you and actually I tried to use a PCS bit previously.
> (PCS bit indicates TBI, SGMII, or RTBI PHY interface)
> But I was confused which one I should use among PSC, ACTPHYIF or phydev to
> recognize the interface.
> At this time, I want to add auto-negotiation enable because sgmii interface
> is not working without ANE using PCS bit(in H/W feature register).
>

really strange, from the synopsys databook we should only look at the RO 
bit in the HW cap reg just to understand if the feature is supported.

>> In case of this feature is actually supported then the driver could manage
>> everything bypassing the MDIO.
>> IMO, we could not need to call the stmmac_phy_init and we should not use
>> the PHYLIB.
>> I mean if we have the PCS module we could have a minimal support to get
>> link status, restart ANE etc w/o using at all the PHYLIB (so w/o touching
> the
>> PHY regs via the MDIO/MDC).
>>
> Yes. For example SGMII/RGMII/SMII Status Register is useful to know status
> so we can use this register to manage status of SGMII/RGMII/SMII
>
>
>>     It could also be useful to complete the support with the RGMII... no
>>     extra effort should be needed while adding SGMII if you look at the
>>     core registers.
>>     If you add the RGMII on some platforms we could guarantee to manage
>>     the fix_mac_speed (see stmmac doc).
>>
> Unfortunately I have only the SGMII.

no problem, I'll complete it by my hand later.

>
>> Looking at the other your patches, the ethtool support is not completed. I
>> expected to restart ANE, get/set link property etc.
>>
> What is link property? It means link up, speed and duplex mode.
> Are there anything else?
> I think get link property is already working using ethtool.
> In case of SGMII/RGMII/SMII, I think we can use SGMII/RGMII/SMII Status
> Register for link status.
>
> I have a question regarding it.
> In the mainline code, there is hardcode interrupt mask in
> dwmac1000_core_init function.
> When I try to get interrupt for link change, interrupt is not occurred
> because of this mask.
> Can we modify that?

yes you can. I had wrote an initial patch that started doing something.
I have tested it on my boards and I can send it to the mailing list to 
be reviewed. Maybe you can build your patch on top of it.

>> Also pay attention to properly treat EEE. Maybe, as first stage we should
>> disable the feature in this case. We will see it later.
>> The question is that we could not be able to use some extra features that
>> currently need to dialog more with the PHY device. I mean what we actually
>> do by using PHYLIB.
> OK. As I understood, using gmac register instead of phydev or phylib...
> I agree. In my opinion gmac and phy communicate using mdio each other, after
> that gmac can get updated status.

yep, this is the point :-)

>>
>>>
>>> Signed-off-by: Byungho An <bh74.an@samsung.com>
>>> ---
>>>    drivers/net/ethernet/stmicro/stmmac/common.h         |    1 +
>>>    drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c |   11
>> +++++++++++
>>>    drivers/net/ethernet/stmicro/stmmac/stmmac_main.c    |    9 +++++++++
>>>    3 files changed, 21 insertions(+)
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h
>>> b/drivers/net/ethernet/stmicro/stmmac/common.h
>>> index 186d148..72ba769 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
>>> @@ -344,6 +344,7 @@ struct stmmac_ops {
>>>    	void (*reset_eee_mode) (void __iomem *ioaddr);
>>>    	void (*set_eee_timer) (void __iomem *ioaddr, int ls, int tw);
>>>    	void (*set_eee_pls) (void __iomem *ioaddr, int link);
>>> +	void (*set_autoneg) (void __iomem *ioaddr);
>>>    };
>>>
>>>    struct mac_link {
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
>>> b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
>>> index bfe0226..a0737b39 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
>>> @@ -297,6 +297,16 @@ static void  dwmac1000_set_eee_timer(void
>> __iomem
>>> *ioaddr, int ls, int tw)
>>>    	writel(value, ioaddr + LPI_TIMER_CTRL);
>>>    }
>>>
>>> +static void dwmac1000_set_autoneg(void __iomem *ioaddr) {
>>> +	u32 value;
>>> +
>>> +	value = readl(ioaddr + GMAC_AN_CTRL);
>>> +	value |= 0x1000;
>>
>> pls use define instead of raw values ... see below.
>>
>>> +	writel(value, ioaddr + GMAC_AN_CTRL); }
>>> +
>>> +
>>>    static const struct stmmac_ops dwmac1000_ops = {
>>>    	.core_init = dwmac1000_core_init,
>>>    	.rx_ipc = dwmac1000_rx_ipc_enable,
>>> @@ -311,6 +321,7 @@ static const struct stmmac_ops dwmac1000_ops = {
>>>    	.reset_eee_mode =  dwmac1000_reset_eee_mode,
>>>    	.set_eee_timer =  dwmac1000_set_eee_timer,
>>>    	.set_eee_pls =  dwmac1000_set_eee_pls,
>>> +	.set_autoneg =  dwmac1000_set_autoneg,
>>>    };
>>>
>>>    struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr) diff
>>> --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> index f07c061..3e28934 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> @@ -1007,6 +1007,7 @@ static int stmmac_open(struct net_device *dev)
>>>    {
>>>    	struct stmmac_priv *priv = netdev_priv(dev);
>>>    	int ret;
>>> +	int interface = priv->plat->interface;
>>>
>>>    	clk_prepare_enable(priv->stmmac_clk);
>>>
>>> @@ -1041,6 +1042,14 @@ static int stmmac_open(struct net_device *dev)
>>>    	/* Initialize the MAC Core */
>>>    	priv->hw->mac->core_init(priv->ioaddr);
>>>
>>> +	/* If phy autoneg is on, set gmac autoneg for SGMII, TBI and RTBI*/
>>> +	if (interface == PHY_INTERFACE_MODE_SGMII ||
>>> +	    interface == PHY_INTERFACE_MODE_TBI ||
>>> +	    interface == PHY_INTERFACE_MODE_RTBI) {
>>> +		if (priv->phydev->autoneg)
>>> +			priv->hw->mac->set_autoneg(priv->ioaddr);
>>> +	}
>>
>> we could use the following instead of priv->hw->mac->set_autoneg:
>>
>> static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool restart) {
>>       int value = GMAC_CTRL_ANE_EN;
>>
>>       if (restart)
>>           value |= GMAC_CTRL_ANE_RESTART;
>>
>>       writel(value, ioaddr +GMAC_AN_CTRL); }
>>
>> where we should defines all the missing macros for the registers 48, 49
> ...
> Actually I tested this code for restart autonegotiation, but even though I
> changed link (1Gb -> 100Mb) phy's link is not changed.
> For more detail, first time 1Gb I changed the link during system working and
> then check speed using ethtool/mii-tool.
> I think phy also should do autonegotiation (I'm not sure this is just for
> the SGMII). Without phy auto negotiation  gmac is not working.
>
> OK, I'll try to check functionality and make macros.
> Anyway as a first step, I want to complete to the code regarding ANE (ctrl
> function, macros, ethtool support for link status etc..)
> I'll send new code before making patch soon.

thanks you

>>
>> /* RGMI/SGMII defines */
>> #define GMAC_CTRL_ANE_SGMII_RAL (1 << 18)
>> #define GMAC_CTRL_ANE_EN       (1 << 12)
>> #define GMAC_CTRL_ANE_RESTART  (1 << 9)
>>
>> The handler should store the link status that will be used to pass the
> info to
>> the ethtool for example. We need to manage speed and duplex etc.
>>
>> What happens if you run "ethtool eth0" command?
>> Or if you run mii-tool?
>> I expect to get the right speed and duplex at least.
> So far, I can get right data speed and duplex and autoneg.
>
>>
>> Concerning the stmmac_set_pauseparam I'm also not sure you are doing the
>> right thing. Note that you are not restarting the ANE at all ... (this is
> what the
>> phy_start_aneg does). If set the bit 12 then you are enabling the ane. To
>> restart it, you need to set the bit 9 in the reg 48.
>>
>> I can support you on all the points above. Let me know.
>>
>> BR,
>> peppe
>>
> OK, thank you and happy new year.

Also to you :-)

let me know for any progresses etc.

Peppe

> Byungho An
>
>>> +
>>>    	/* Request the IRQ lines */
>>>    	ret = request_irq(dev->irq, stmmac_interrupt,
>>>    			 IRQF_SHARED, dev->name, dev);
>>>
>
>
>

^ permalink raw reply

* Re: v3 for tcp friends?
From: Li Yu @ 2013-01-23  9:39 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Eric Dumazet, Bruce Curtis
In-Reply-To: <50FF9836.4060106@gmail.com>

于 2013年01月23日 15:58, Li Yu 写道:
> 于 2013年01月23日 15:21, Li Yu 写道:
>> 于 2013年01月23日 14:46, Eric Dumazet 写道:
>>> On Wed, 2013-01-23 at 14:12 +0800, Li Yu wrote:
>>>> Oops, this hang is not since TCP friends patch!
>>>>
>>>> sk_sndbuf_get() is broken by 32 bits integer overflow
>>>> because of so large value in net.ipv4.tcp_{rmem,wmem}.
>>>>
>>>> but this hang also can be found in net-next.git
>>>> (3.8.0-rc3+), if we run below commands, then all new
>>>> TCP connections stop working!
>>>>
>>>> # when TCP friends is disabled
>>>> sysctl -w net.ipv4.tcp_rmem="4096 4294967296 4294967296" # 4GB
>>>> sysctl -w net.ipv4.tcp_wmem="4096 4294967296 4294967296"
>>>
>>> Right we need to make sure we dont overflow.
>>>
>>> Try the following fix :
>>>
>>> diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
>>> index a25e1d2..1459145 100644
>>> --- a/net/ipv4/sysctl_net_ipv4.c
>>> +++ b/net/ipv4/sysctl_net_ipv4.c
>>> @@ -549,14 +549,16 @@ static struct ctl_table ipv4_table[] = {
>>>           .data        = &sysctl_tcp_wmem,
>>>           .maxlen        = sizeof(sysctl_tcp_wmem),
>>>           .mode        = 0644,
>>> -        .proc_handler    = proc_dointvec
>>> +        .extra1        = &zero,

If we added below:

+static int one = 1;
+static int int_max = INT_MAX;
....
+               .extra1     = &one,
+		.extra2	    = &int_max,

The bug is fixed without TCP friends.

Maybe, TCP friends need to use long integer to record result
of "sk->sk_sndbuf + sk->sk_friend->sk_rcvbuf" ?

BTW: This overflow problem also breaks UDP sockets.

Thanks

Yu

>>> +        .proc_handler    = proc_dointvec_minmax
>>>       },
>>>       {
>>>           .procname    = "tcp_rmem",
>>>           .data        = &sysctl_tcp_rmem,
>>>           .maxlen        = sizeof(sysctl_tcp_rmem),
>>>           .mode        = 0644,
>>> -        .proc_handler    = proc_dointvec
>>> +        .extra1        = &zero,
>>> +        .proc_handler    = proc_dointvec_minmax
>>>       },
>>>       {
>>>           .procname    = "tcp_app_win",
>>>
>>>
>>>
>> Thanks for so quick reply, I will test it soon.
>>
>> however I suspect whether this patch could fix overflow if we merged TCP
>> friends patch in future.
>>
>
> Tested on 3.7.0-rc1+, but bug is still alive
> with disabled TCP friends ...
>
> Thanks
>
> Yu
>
>> With TCP friends, we have source like below, or TCP friends should care
>> this ?
>>
>> static inline int sk_sndbuf_get(const struct sock *sk)
>> {
>>          if (sk->sk_friend)
>>                  return sk->sk_sndbuf + sk->sk_friend->sk_rcvbuf;
>>          else
>>                  return sk->sk_sndbuf;
>> }
>>
>> static inline bool sk_stream_memory_free(const struct sock *sk)
>> {
>>          return sk_wmem_queued_get(sk) < sk_sndbuf_get(sk);
>> }
>>
>> So sk_sndbuf_get() still may be overflow when we have right value in
>> net.ipv4.tcp_{rmem,wmem}.
>>
>> Thanks
>

^ permalink raw reply

* Re: [BUG] Bug in netprio_cgroup and netcls_cgroup ?
From: Daniel Wagner @ 2013-01-23  9:24 UTC (permalink / raw)
  To: John Fastabend
  Cc: Li Zefan, John Fastabend, Neil Horman, Daniel Wagner, LKML,
	netdev-u79uwXL29TY76Z2rM5mHXA, Cgroups
In-Reply-To: <50FF287C.70906-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On 23.01.2013 01:02, John Fastabend wrote:
> [...]
>
>>>
>>> OK, I guess we should do something similar in the netprio, netcls
>>> cgroups and
>>> yes document it as you noted in your last comment.
>>
>> Here is my attempt to add such a check. I really don't know if this is
>> the
>> correct way to do so. To test this I have written a test program, which
>> seems to test the right thing. Please have a look and let me know if
>> it is correct: http://www.monom.org/misc/scm_rights.c
>>
>> And here a dirty first version of the patch:
>>
>>
>>  From 49a78d907eaf31c16673025e7e3b4844e419e416 Mon Sep 17 00:00:00 2001
>> From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
>> Date: Tue, 22 Jan 2013 11:08:22 +0100
>> Subject: [PATCH] net: net_prio: Block attach if a socket is shared
>>
>> ---
>>   net/core/netprio_cgroup.c | 30 ++++++++++++++++++++++++++++++
>>   1 file changed, 30 insertions(+)
>>
>> diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
>> index 847c02b..de4e6c5 100644
>> --- a/net/core/netprio_cgroup.c
>> +++ b/net/core/netprio_cgroup.c
>> @@ -274,9 +274,39 @@ static struct cftype ss_files[] = {
>>       { }    /* terminate */
>>   };
>>
>> +static int check_cnt(const void *v, struct file *file, unsigned n)
>> +{
>> +    unsigned *flag = (unsigned *)v;
>> +    int err;
>> +
>> +    struct socket *sock = sock_from_file(file, &err);
>> +    if (sock && file_count(file) > 1)
>> +        *flag = 1;
>> +
>
> I think this check will catch a lot of cases that are not necessarily
> sharing a socket across tasks though. For example iscsid passes a file
> descriptor to the kernel which does a sockfd_lookup() incrementing
> f_count. Similarly look at dup/clone/etc.

Yep, I expected that this patch was too simple.

> In many of these cases I believe it should be OK to move the task
> around when the sockets are not shared between multiple tasks.

Do you know of a different way to identify the shared sockets?

thanks,
daniel

^ permalink raw reply

* [Patch net-next 2/2] netpoll: use the net namespace of current process instead of init_net
From: Cong Wang @ 2013-01-23  9:02 UTC (permalink / raw)
  To: netdev; +Cc: Eric W. Biederman, David S. Miller, Cong Wang
In-Reply-To: <1358931731-17438-1-git-send-email-amwang@redhat.com>

From: Cong Wang <amwang@redhat.com>

This will allow us to setup netconsole in a different namespace
rather than where init_net is.

Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 net/core/netpoll.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a6f39b6..c3b2589 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -1046,11 +1046,16 @@ int netpoll_setup(struct netpoll *np)
 {
 	struct net_device *ndev = NULL;
 	struct in_device *in_dev;
+	struct net *net = &init_net;
+	struct nsproxy *ns = task_nsproxy(current);
 	int err;
 
 	rtnl_lock();
-	if (np->dev_name)
-		ndev = __dev_get_by_name(&init_net, np->dev_name);
+	if (np->dev_name) {
+		if (ns != NULL)
+			net = get_net(ns->net_ns);
+		ndev = __dev_get_by_name(net, np->dev_name);
+	}
 	if (!ndev) {
 		np_err(np, "%s doesn't exist, aborting\n", np->dev_name);
 		err = -ENODEV;
@@ -1159,6 +1164,8 @@ int netpoll_setup(struct netpoll *np)
 put:
 	dev_put(ndev);
 unlock:
+	if (net != &init_net)
+		put_net(net);
 	rtnl_unlock();
 	return err;
 }
-- 
1.7.7.6

^ permalink raw reply related

* [Patch net-next 1/2] netpoll: use ipv6_addr_equal() to compare ipv6 addr
From: Cong Wang @ 2013-01-23  9:02 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Cong Wang

From: Cong Wang <amwang@redhat.com>

ipv6_addr_equal() is faster.

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 net/core/netpoll.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index e2f79a1..a6f39b6 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -635,7 +635,7 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo
 
 		spin_lock_irqsave(&npinfo->rx_lock, flags);
 		list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) {
-			if (memcmp(daddr, &np->local_ip, sizeof(*daddr)))
+			if (!ipv6_addr_equal(daddr, &np->local_ip.in6))
 				continue;
 
 			hlen = LL_RESERVED_SPACE(np->dev);
@@ -828,9 +828,9 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
 		if (udp6_csum_init(skb, uh, IPPROTO_UDP))
 			goto out;
 		list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) {
-			if (memcmp(&np->local_ip.in6, &ip6h->daddr, sizeof(struct in6_addr)) != 0)
+			if (!ipv6_addr_equal(&np->local_ip.in6, &ip6h->daddr))
 				continue;
-			if (memcmp(&np->remote_ip.in6, &ip6h->saddr, sizeof(struct in6_addr)) != 0)
+			if (!ipv6_addr_equal(&np->remote_ip.in6, &ip6h->saddr))
 				continue;
 			if (np->local_port && np->local_port != ntohs(uh->dest))
 				continue;
-- 
1.7.7.6

^ permalink raw reply related

* [PATCH 8/8] xfrm: Remove unused defines
From: Steffen Klassert @ 2013-01-23  8:19 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1358929144-17806-1-git-send-email-steffen.klassert@secunet.com>

XFRM_REPLAY_SEQ, XFRM_REPLAY_OSEQ and XFRM_REPLAY_SEQ_MASK
were introduced years ago but actually never used.

Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 include/net/xfrm.h |    4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 63445ed..421f764 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -557,10 +557,6 @@ struct xfrm_migrate {
 };
 
 #define XFRM_KM_TIMEOUT                30
-/* which seqno */
-#define XFRM_REPLAY_SEQ		1
-#define XFRM_REPLAY_OSEQ	2
-#define XFRM_REPLAY_SEQ_MASK	3
 /* what happened */
 #define XFRM_REPLAY_UPDATE	XFRM_AE_CR
 #define XFRM_REPLAY_TIMEOUT	XFRM_AE_CE
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 7/8] xfrm: use separated locks to protect pointers of struct xfrm_state_afinfo
From: Steffen Klassert @ 2013-01-23  8:19 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1358929144-17806-1-git-send-email-steffen.klassert@secunet.com>

From: Cong Wang <amwang@redhat.com>

afinfo->type_map and afinfo->mode_map deserve separated locks,
they are different things.

We should just take RCU read lock to protect afinfo itself,
but not for the inner pointers.

Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/xfrm/xfrm_state.c |   43 ++++++++++++++++++-------------------------
 1 file changed, 18 insertions(+), 25 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1522f19..0adae91 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -168,57 +168,45 @@ int __xfrm_state_delete(struct xfrm_state *x);
 int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
 void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
 
-static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
-{
-	struct xfrm_state_afinfo *afinfo;
-	if (unlikely(family >= NPROTO))
-		return NULL;
-	spin_lock_bh(&xfrm_state_afinfo_lock);
-	afinfo = xfrm_state_afinfo[family];
-	if (unlikely(!afinfo))
-		spin_unlock_bh(&xfrm_state_afinfo_lock);
-	return afinfo;
-}
-
-static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
-{
-	spin_unlock_bh(&xfrm_state_afinfo_lock);
-}
-
+static DEFINE_SPINLOCK(xfrm_type_lock);
 int xfrm_register_type(const struct xfrm_type *type, unsigned short family)
 {
-	struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
+	struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
 	const struct xfrm_type **typemap;
 	int err = 0;
 
 	if (unlikely(afinfo == NULL))
 		return -EAFNOSUPPORT;
 	typemap = afinfo->type_map;
+	spin_lock_bh(&xfrm_type_lock);
 
 	if (likely(typemap[type->proto] == NULL))
 		typemap[type->proto] = type;
 	else
 		err = -EEXIST;
-	xfrm_state_unlock_afinfo(afinfo);
+	spin_unlock_bh(&xfrm_type_lock);
+	xfrm_state_put_afinfo(afinfo);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_register_type);
 
 int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family)
 {
-	struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
+	struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
 	const struct xfrm_type **typemap;
 	int err = 0;
 
 	if (unlikely(afinfo == NULL))
 		return -EAFNOSUPPORT;
 	typemap = afinfo->type_map;
+	spin_lock_bh(&xfrm_type_lock);
 
 	if (unlikely(typemap[type->proto] != type))
 		err = -ENOENT;
 	else
 		typemap[type->proto] = NULL;
-	xfrm_state_unlock_afinfo(afinfo);
+	spin_unlock_bh(&xfrm_type_lock);
+	xfrm_state_put_afinfo(afinfo);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_unregister_type);
@@ -255,6 +243,7 @@ static void xfrm_put_type(const struct xfrm_type *type)
 	module_put(type->owner);
 }
 
+static DEFINE_SPINLOCK(xfrm_mode_lock);
 int xfrm_register_mode(struct xfrm_mode *mode, int family)
 {
 	struct xfrm_state_afinfo *afinfo;
@@ -264,12 +253,13 @@ int xfrm_register_mode(struct xfrm_mode *mode, int family)
 	if (unlikely(mode->encap >= XFRM_MODE_MAX))
 		return -EINVAL;
 
-	afinfo = xfrm_state_lock_afinfo(family);
+	afinfo = xfrm_state_get_afinfo(family);
 	if (unlikely(afinfo == NULL))
 		return -EAFNOSUPPORT;
 
 	err = -EEXIST;
 	modemap = afinfo->mode_map;
+	spin_lock_bh(&xfrm_mode_lock);
 	if (modemap[mode->encap])
 		goto out;
 
@@ -282,7 +272,8 @@ int xfrm_register_mode(struct xfrm_mode *mode, int family)
 	err = 0;
 
 out:
-	xfrm_state_unlock_afinfo(afinfo);
+	spin_unlock_bh(&xfrm_mode_lock);
+	xfrm_state_put_afinfo(afinfo);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_register_mode);
@@ -296,19 +287,21 @@ int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
 	if (unlikely(mode->encap >= XFRM_MODE_MAX))
 		return -EINVAL;
 
-	afinfo = xfrm_state_lock_afinfo(family);
+	afinfo = xfrm_state_get_afinfo(family);
 	if (unlikely(afinfo == NULL))
 		return -EAFNOSUPPORT;
 
 	err = -ENOENT;
 	modemap = afinfo->mode_map;
+	spin_lock_bh(&xfrm_mode_lock);
 	if (likely(modemap[mode->encap] == mode)) {
 		modemap[mode->encap] = NULL;
 		module_put(mode->afinfo->owner);
 		err = 0;
 	}
 
-	xfrm_state_unlock_afinfo(afinfo);
+	spin_unlock_bh(&xfrm_mode_lock);
+	xfrm_state_put_afinfo(afinfo);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_unregister_mode);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 6/8] xfrm: replace rwlock on xfrm_km_list with rcu
From: Steffen Klassert @ 2013-01-23  8:19 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1358929144-17806-1-git-send-email-steffen.klassert@secunet.com>

From: Cong Wang <amwang@redhat.com>

Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/xfrm/xfrm_state.c |   58 +++++++++++++++++++++++++------------------------
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 64780a6..1522f19 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1644,27 +1644,26 @@ static void xfrm_replay_timer_handler(unsigned long data)
 }
 
 static LIST_HEAD(xfrm_km_list);
-static DEFINE_RWLOCK(xfrm_km_lock);
 
 void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c)
 {
 	struct xfrm_mgr *km;
 
-	read_lock(&xfrm_km_lock);
-	list_for_each_entry(km, &xfrm_km_list, list)
+	rcu_read_lock();
+	list_for_each_entry_rcu(km, &xfrm_km_list, list)
 		if (km->notify_policy)
 			km->notify_policy(xp, dir, c);
-	read_unlock(&xfrm_km_lock);
+	rcu_read_unlock();
 }
 
 void km_state_notify(struct xfrm_state *x, const struct km_event *c)
 {
 	struct xfrm_mgr *km;
-	read_lock(&xfrm_km_lock);
-	list_for_each_entry(km, &xfrm_km_list, list)
+	rcu_read_lock();
+	list_for_each_entry_rcu(km, &xfrm_km_list, list)
 		if (km->notify)
 			km->notify(x, c);
-	read_unlock(&xfrm_km_lock);
+	rcu_read_unlock();
 }
 
 EXPORT_SYMBOL(km_policy_notify);
@@ -1694,13 +1693,13 @@ int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
 	int err = -EINVAL, acqret;
 	struct xfrm_mgr *km;
 
-	read_lock(&xfrm_km_lock);
-	list_for_each_entry(km, &xfrm_km_list, list) {
+	rcu_read_lock();
+	list_for_each_entry_rcu(km, &xfrm_km_list, list) {
 		acqret = km->acquire(x, t, pol);
 		if (!acqret)
 			err = acqret;
 	}
-	read_unlock(&xfrm_km_lock);
+	rcu_read_unlock();
 	return err;
 }
 EXPORT_SYMBOL(km_query);
@@ -1710,14 +1709,14 @@ int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
 	int err = -EINVAL;
 	struct xfrm_mgr *km;
 
-	read_lock(&xfrm_km_lock);
-	list_for_each_entry(km, &xfrm_km_list, list) {
+	rcu_read_lock();
+	list_for_each_entry_rcu(km, &xfrm_km_list, list) {
 		if (km->new_mapping)
 			err = km->new_mapping(x, ipaddr, sport);
 		if (!err)
 			break;
 	}
-	read_unlock(&xfrm_km_lock);
+	rcu_read_unlock();
 	return err;
 }
 EXPORT_SYMBOL(km_new_mapping);
@@ -1746,15 +1745,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 	int ret;
 	struct xfrm_mgr *km;
 
-	read_lock(&xfrm_km_lock);
-	list_for_each_entry(km, &xfrm_km_list, list) {
+	rcu_read_lock();
+	list_for_each_entry_rcu(km, &xfrm_km_list, list) {
 		if (km->migrate) {
 			ret = km->migrate(sel, dir, type, m, num_migrate, k);
 			if (!ret)
 				err = ret;
 		}
 	}
-	read_unlock(&xfrm_km_lock);
+	rcu_read_unlock();
 	return err;
 }
 EXPORT_SYMBOL(km_migrate);
@@ -1766,15 +1765,15 @@ int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address
 	int ret;
 	struct xfrm_mgr *km;
 
-	read_lock(&xfrm_km_lock);
-	list_for_each_entry(km, &xfrm_km_list, list) {
+	rcu_read_lock();
+	list_for_each_entry_rcu(km, &xfrm_km_list, list) {
 		if (km->report) {
 			ret = km->report(net, proto, sel, addr);
 			if (!ret)
 				err = ret;
 		}
 	}
-	read_unlock(&xfrm_km_lock);
+	rcu_read_unlock();
 	return err;
 }
 EXPORT_SYMBOL(km_report);
@@ -1798,14 +1797,14 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
 		goto out;
 
 	err = -EINVAL;
-	read_lock(&xfrm_km_lock);
-	list_for_each_entry(km, &xfrm_km_list, list) {
+	rcu_read_lock();
+	list_for_each_entry_rcu(km, &xfrm_km_list, list) {
 		pol = km->compile_policy(sk, optname, data,
 					 optlen, &err);
 		if (err >= 0)
 			break;
 	}
-	read_unlock(&xfrm_km_lock);
+	rcu_read_unlock();
 
 	if (err >= 0) {
 		xfrm_sk_policy_insert(sk, err, pol);
@@ -1819,20 +1818,23 @@ out:
 }
 EXPORT_SYMBOL(xfrm_user_policy);
 
+static DEFINE_SPINLOCK(xfrm_km_lock);
+
 int xfrm_register_km(struct xfrm_mgr *km)
 {
-	write_lock_bh(&xfrm_km_lock);
-	list_add_tail(&km->list, &xfrm_km_list);
-	write_unlock_bh(&xfrm_km_lock);
+	spin_lock_bh(&xfrm_km_lock);
+	list_add_tail_rcu(&km->list, &xfrm_km_list);
+	spin_unlock_bh(&xfrm_km_lock);
 	return 0;
 }
 EXPORT_SYMBOL(xfrm_register_km);
 
 int xfrm_unregister_km(struct xfrm_mgr *km)
 {
-	write_lock_bh(&xfrm_km_lock);
-	list_del(&km->list);
-	write_unlock_bh(&xfrm_km_lock);
+	spin_lock_bh(&xfrm_km_lock);
+	list_del_rcu(&km->list);
+	spin_unlock_bh(&xfrm_km_lock);
+	synchronize_rcu();
 	return 0;
 }
 EXPORT_SYMBOL(xfrm_unregister_km);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 5/8] xfrm: replace rwlock on xfrm_state_afinfo with rcu
From: Steffen Klassert @ 2013-01-23  8:19 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1358929144-17806-1-git-send-email-steffen.klassert@secunet.com>

From: Cong Wang <amwang@redhat.com>

Similar to commit 418a99ac6ad487dc9c42e6b0e85f941af56330f2
(Replace rwlock on xfrm_policy_afinfo with rcu), the rwlock
on xfrm_state_afinfo can be replaced by RCU too.

Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/xfrm/xfrm_state.c |   33 ++++++++++++++++-----------------
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 05db236..64780a6 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -158,8 +158,8 @@ out_unlock:
 	mutex_unlock(&hash_resize_mutex);
 }
 
-static DEFINE_RWLOCK(xfrm_state_afinfo_lock);
-static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
+static DEFINE_SPINLOCK(xfrm_state_afinfo_lock);
+static struct xfrm_state_afinfo __rcu *xfrm_state_afinfo[NPROTO];
 
 static DEFINE_SPINLOCK(xfrm_state_gc_lock);
 
@@ -173,17 +173,16 @@ static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
 	struct xfrm_state_afinfo *afinfo;
 	if (unlikely(family >= NPROTO))
 		return NULL;
-	write_lock_bh(&xfrm_state_afinfo_lock);
+	spin_lock_bh(&xfrm_state_afinfo_lock);
 	afinfo = xfrm_state_afinfo[family];
 	if (unlikely(!afinfo))
-		write_unlock_bh(&xfrm_state_afinfo_lock);
+		spin_unlock_bh(&xfrm_state_afinfo_lock);
 	return afinfo;
 }
 
 static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
-	__releases(xfrm_state_afinfo_lock)
 {
-	write_unlock_bh(&xfrm_state_afinfo_lock);
+	spin_unlock_bh(&xfrm_state_afinfo_lock);
 }
 
 int xfrm_register_type(const struct xfrm_type *type, unsigned short family)
@@ -1845,12 +1844,12 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
 		return -EINVAL;
 	if (unlikely(afinfo->family >= NPROTO))
 		return -EAFNOSUPPORT;
-	write_lock_bh(&xfrm_state_afinfo_lock);
+	spin_lock_bh(&xfrm_state_afinfo_lock);
 	if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
 		err = -ENOBUFS;
 	else
-		xfrm_state_afinfo[afinfo->family] = afinfo;
-	write_unlock_bh(&xfrm_state_afinfo_lock);
+		rcu_assign_pointer(xfrm_state_afinfo[afinfo->family], afinfo);
+	spin_unlock_bh(&xfrm_state_afinfo_lock);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_state_register_afinfo);
@@ -1862,14 +1861,15 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
 		return -EINVAL;
 	if (unlikely(afinfo->family >= NPROTO))
 		return -EAFNOSUPPORT;
-	write_lock_bh(&xfrm_state_afinfo_lock);
+	spin_lock_bh(&xfrm_state_afinfo_lock);
 	if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
 		if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
 			err = -EINVAL;
 		else
-			xfrm_state_afinfo[afinfo->family] = NULL;
+			RCU_INIT_POINTER(xfrm_state_afinfo[afinfo->family], NULL);
 	}
-	write_unlock_bh(&xfrm_state_afinfo_lock);
+	spin_unlock_bh(&xfrm_state_afinfo_lock);
+	synchronize_rcu();
 	return err;
 }
 EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
@@ -1879,17 +1879,16 @@ static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
 	struct xfrm_state_afinfo *afinfo;
 	if (unlikely(family >= NPROTO))
 		return NULL;
-	read_lock(&xfrm_state_afinfo_lock);
-	afinfo = xfrm_state_afinfo[family];
+	rcu_read_lock();
+	afinfo = rcu_dereference(xfrm_state_afinfo[family]);
 	if (unlikely(!afinfo))
-		read_unlock(&xfrm_state_afinfo_lock);
+		rcu_read_unlock();
 	return afinfo;
 }
 
 static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
-	__releases(xfrm_state_afinfo_lock)
 {
-	read_unlock(&xfrm_state_afinfo_lock);
+	rcu_read_unlock();
 }
 
 /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 4/8] crypto: aesni-intel - remove rfc3686(ctr(aes)), utilize rfc3686 from ctr-module instead
From: Steffen Klassert @ 2013-01-23  8:19 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1358929144-17806-1-git-send-email-steffen.klassert@secunet.com>

From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>

rfc3686 in CTR module is now able of using asynchronous ctr(aes) from
aesni-intel, so rfc3686(ctr(aes)) in aesni-intel is no longer needed.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 arch/x86/crypto/aesni-intel_glue.c |   37 ------------------------------------
 1 file changed, 37 deletions(-)

diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 1b9c22b..a0795da 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -40,10 +40,6 @@
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
 
-#if defined(CONFIG_CRYPTO_CTR) || defined(CONFIG_CRYPTO_CTR_MODULE)
-#define HAS_CTR
-#endif
-
 #if defined(CONFIG_CRYPTO_PCBC) || defined(CONFIG_CRYPTO_PCBC_MODULE)
 #define HAS_PCBC
 #endif
@@ -395,12 +391,6 @@ static int ablk_ctr_init(struct crypto_tfm *tfm)
 	return ablk_init_common(tfm, "__driver-ctr-aes-aesni");
 }
 
-#ifdef HAS_CTR
-static int ablk_rfc3686_ctr_init(struct crypto_tfm *tfm)
-{
-	return ablk_init_common(tfm, "rfc3686(__driver-ctr-aes-aesni)");
-}
-#endif
 #endif
 
 #ifdef HAS_PCBC
@@ -1158,33 +1148,6 @@ static struct crypto_alg aesni_algs[] = { {
 			.maxauthsize	= 16,
 		},
 	},
-#ifdef HAS_CTR
-}, {
-	.cra_name		= "rfc3686(ctr(aes))",
-	.cra_driver_name	= "rfc3686-ctr-aes-aesni",
-	.cra_priority		= 400,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= 1,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_rfc3686_ctr_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize = AES_MIN_KEY_SIZE +
-				       CTR_RFC3686_NONCE_SIZE,
-			.max_keysize = AES_MAX_KEY_SIZE +
-				       CTR_RFC3686_NONCE_SIZE,
-			.ivsize	     = CTR_RFC3686_IV_SIZE,
-			.setkey	     = ablk_set_key,
-			.encrypt     = ablk_encrypt,
-			.decrypt     = ablk_decrypt,
-			.geniv	     = "seqiv",
-		},
-	},
-#endif
 #endif
 #ifdef HAS_PCBC
 }, {
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 3/8] crypto: ctr - make rfc3686 asynchronous block cipher
From: Steffen Klassert @ 2013-01-23  8:18 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1358929144-17806-1-git-send-email-steffen.klassert@secunet.com>

From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>

Some hardware crypto drivers register asynchronous ctr(aes), which is left
unused in IPSEC because rfc3686 template only supports synchronous block
ciphers. Some other drivers register rfc3686(ctr(aes)) to workaround this
limitation but not all.

This patch changes rfc3686 to use asynchronous block ciphers, to allow async
ctr(aes) algorithms to be utilized automatically by IPSEC.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 crypto/ctr.c    |  173 +++++++++++++++++++++++++++++++++++--------------------
 crypto/tcrypt.c |    4 ++
 crypto/tcrypt.h |    1 +
 3 files changed, 115 insertions(+), 63 deletions(-)

diff --git a/crypto/ctr.c b/crypto/ctr.c
index 4ca7222..1f2997c 100644
--- a/crypto/ctr.c
+++ b/crypto/ctr.c
@@ -12,6 +12,7 @@
 
 #include <crypto/algapi.h>
 #include <crypto/ctr.h>
+#include <crypto/internal/skcipher.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -25,10 +26,15 @@ struct crypto_ctr_ctx {
 };
 
 struct crypto_rfc3686_ctx {
-	struct crypto_blkcipher *child;
+	struct crypto_ablkcipher *child;
 	u8 nonce[CTR_RFC3686_NONCE_SIZE];
 };
 
+struct crypto_rfc3686_req_ctx {
+	u8 iv[CTR_RFC3686_BLOCK_SIZE];
+	struct ablkcipher_request subreq CRYPTO_MINALIGN_ATTR;
+};
+
 static int crypto_ctr_setkey(struct crypto_tfm *parent, const u8 *key,
 			     unsigned int keylen)
 {
@@ -243,11 +249,11 @@ static struct crypto_template crypto_ctr_tmpl = {
 	.module = THIS_MODULE,
 };
 
-static int crypto_rfc3686_setkey(struct crypto_tfm *parent, const u8 *key,
-				 unsigned int keylen)
+static int crypto_rfc3686_setkey(struct crypto_ablkcipher *parent,
+				 const u8 *key, unsigned int keylen)
 {
-	struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(parent);
-	struct crypto_blkcipher *child = ctx->child;
+	struct crypto_rfc3686_ctx *ctx = crypto_ablkcipher_ctx(parent);
+	struct crypto_ablkcipher *child = ctx->child;
 	int err;
 
 	/* the nonce is stored in bytes at end of key */
@@ -259,59 +265,64 @@ static int crypto_rfc3686_setkey(struct crypto_tfm *parent, const u8 *key,
 
 	keylen -= CTR_RFC3686_NONCE_SIZE;
 
-	crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
-	crypto_blkcipher_set_flags(child, crypto_tfm_get_flags(parent) &
-					  CRYPTO_TFM_REQ_MASK);
-	err = crypto_blkcipher_setkey(child, key, keylen);
-	crypto_tfm_set_flags(parent, crypto_blkcipher_get_flags(child) &
-				     CRYPTO_TFM_RES_MASK);
+	crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+	crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(parent) &
+				    CRYPTO_TFM_REQ_MASK);
+	err = crypto_ablkcipher_setkey(child, key, keylen);
+	crypto_ablkcipher_set_flags(parent, crypto_ablkcipher_get_flags(child) &
+				    CRYPTO_TFM_RES_MASK);
 
 	return err;
 }
 
-static int crypto_rfc3686_crypt(struct blkcipher_desc *desc,
-				struct scatterlist *dst,
-				struct scatterlist *src, unsigned int nbytes)
+static int crypto_rfc3686_crypt(struct ablkcipher_request *req)
 {
-	struct crypto_blkcipher *tfm = desc->tfm;
-	struct crypto_rfc3686_ctx *ctx = crypto_blkcipher_ctx(tfm);
-	struct crypto_blkcipher *child = ctx->child;
-	unsigned long alignmask = crypto_blkcipher_alignmask(tfm);
-	u8 ivblk[CTR_RFC3686_BLOCK_SIZE + alignmask];
-	u8 *iv = PTR_ALIGN(ivblk + 0, alignmask + 1);
-	u8 *info = desc->info;
-	int err;
+	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
+	struct crypto_rfc3686_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+	struct crypto_ablkcipher *child = ctx->child;
+	unsigned long align = crypto_ablkcipher_alignmask(tfm);
+	struct crypto_rfc3686_req_ctx *rctx =
+		(void *)PTR_ALIGN((u8 *)ablkcipher_request_ctx(req), align + 1);
+	struct ablkcipher_request *subreq = &rctx->subreq;
+	u8 *iv = rctx->iv;
 
 	/* set up counter block */
 	memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
-	memcpy(iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE);
+	memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->info, CTR_RFC3686_IV_SIZE);
 
 	/* initialize counter portion of counter block */
 	*(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
 		cpu_to_be32(1);
 
-	desc->tfm = child;
-	desc->info = iv;
-	err = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes);
-	desc->tfm = tfm;
-	desc->info = info;
+	ablkcipher_request_set_tfm(subreq, child);
+	ablkcipher_request_set_callback(subreq, req->base.flags,
+					req->base.complete, req->base.data);
+	ablkcipher_request_set_crypt(subreq, req->src, req->dst, req->nbytes,
+				     iv);
 
-	return err;
+	return crypto_ablkcipher_encrypt(subreq);
 }
 
 static int crypto_rfc3686_init_tfm(struct crypto_tfm *tfm)
 {
 	struct crypto_instance *inst = (void *)tfm->__crt_alg;
-	struct crypto_spawn *spawn = crypto_instance_ctx(inst);
+	struct crypto_skcipher_spawn *spawn = crypto_instance_ctx(inst);
 	struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm);
-	struct crypto_blkcipher *cipher;
+	struct crypto_ablkcipher *cipher;
+	unsigned long align;
 
-	cipher = crypto_spawn_blkcipher(spawn);
+	cipher = crypto_spawn_skcipher(spawn);
 	if (IS_ERR(cipher))
 		return PTR_ERR(cipher);
 
 	ctx->child = cipher;
 
+	align = crypto_tfm_alg_alignmask(tfm);
+	align &= ~(crypto_tfm_ctx_alignment() - 1);
+	tfm->crt_ablkcipher.reqsize = align +
+		sizeof(struct crypto_rfc3686_req_ctx) +
+		crypto_ablkcipher_reqsize(cipher);
+
 	return 0;
 }
 
@@ -319,74 +330,110 @@ static void crypto_rfc3686_exit_tfm(struct crypto_tfm *tfm)
 {
 	struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	crypto_free_blkcipher(ctx->child);
+	crypto_free_ablkcipher(ctx->child);
 }
 
 static struct crypto_instance *crypto_rfc3686_alloc(struct rtattr **tb)
 {
+	struct crypto_attr_type *algt;
 	struct crypto_instance *inst;
 	struct crypto_alg *alg;
+	struct crypto_skcipher_spawn *spawn;
+	const char *cipher_name;
 	int err;
 
-	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
-	if (err)
+	algt = crypto_get_attr_type(tb);
+	err = PTR_ERR(algt);
+	if (IS_ERR(algt))
 		return ERR_PTR(err);
 
-	alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_BLKCIPHER,
-				  CRYPTO_ALG_TYPE_MASK);
-	err = PTR_ERR(alg);
-	if (IS_ERR(alg))
+	if ((algt->type ^ CRYPTO_ALG_TYPE_BLKCIPHER) & algt->mask)
+		return ERR_PTR(-EINVAL);
+
+	cipher_name = crypto_attr_alg_name(tb[1]);
+	err = PTR_ERR(cipher_name);
+	if (IS_ERR(cipher_name))
 		return ERR_PTR(err);
 
+	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
+	if (!inst)
+		return ERR_PTR(-ENOMEM);
+
+	spawn = crypto_instance_ctx(inst);
+
+	crypto_set_skcipher_spawn(spawn, inst);
+	err = crypto_grab_skcipher(spawn, cipher_name, 0,
+				   crypto_requires_sync(algt->type,
+							algt->mask));
+	if (err)
+		goto err_free_inst;
+
+	alg = crypto_skcipher_spawn_alg(spawn);
+
 	/* We only support 16-byte blocks. */
 	err = -EINVAL;
-	if (alg->cra_blkcipher.ivsize != CTR_RFC3686_BLOCK_SIZE)
-		goto out_put_alg;
+	if (alg->cra_ablkcipher.ivsize != CTR_RFC3686_BLOCK_SIZE)
+		goto err_drop_spawn;
 
 	/* Not a stream cipher? */
 	if (alg->cra_blocksize != 1)
-		goto out_put_alg;
+		goto err_drop_spawn;
 
-	inst = crypto_alloc_instance("rfc3686", alg);
-	if (IS_ERR(inst))
-		goto out;
+	err = -ENAMETOOLONG;
+	if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "rfc3686(%s)",
+		     alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
+		goto err_drop_spawn;
+	if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+		     "rfc3686(%s)", alg->cra_driver_name) >=
+			CRYPTO_MAX_ALG_NAME)
+		goto err_drop_spawn;
 
-	inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
 	inst->alg.cra_priority = alg->cra_priority;
 	inst->alg.cra_blocksize = 1;
 	inst->alg.cra_alignmask = alg->cra_alignmask;
-	inst->alg.cra_type = &crypto_blkcipher_type;
 
-	inst->alg.cra_blkcipher.ivsize = CTR_RFC3686_IV_SIZE;
-	inst->alg.cra_blkcipher.min_keysize = alg->cra_blkcipher.min_keysize
-					      + CTR_RFC3686_NONCE_SIZE;
-	inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize
-					      + CTR_RFC3686_NONCE_SIZE;
+	inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+			      (alg->cra_flags & CRYPTO_ALG_ASYNC);
+	inst->alg.cra_type = &crypto_ablkcipher_type;
+
+	inst->alg.cra_ablkcipher.ivsize = CTR_RFC3686_IV_SIZE;
+	inst->alg.cra_ablkcipher.min_keysize =
+		alg->cra_ablkcipher.min_keysize + CTR_RFC3686_NONCE_SIZE;
+	inst->alg.cra_ablkcipher.max_keysize =
+		alg->cra_ablkcipher.max_keysize + CTR_RFC3686_NONCE_SIZE;
 
-	inst->alg.cra_blkcipher.geniv = "seqiv";
+	inst->alg.cra_ablkcipher.geniv = "seqiv";
+
+	inst->alg.cra_ablkcipher.setkey = crypto_rfc3686_setkey;
+	inst->alg.cra_ablkcipher.encrypt = crypto_rfc3686_crypt;
+	inst->alg.cra_ablkcipher.decrypt = crypto_rfc3686_crypt;
 
 	inst->alg.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx);
 
 	inst->alg.cra_init = crypto_rfc3686_init_tfm;
 	inst->alg.cra_exit = crypto_rfc3686_exit_tfm;
 
-	inst->alg.cra_blkcipher.setkey = crypto_rfc3686_setkey;
-	inst->alg.cra_blkcipher.encrypt = crypto_rfc3686_crypt;
-	inst->alg.cra_blkcipher.decrypt = crypto_rfc3686_crypt;
-
-out:
-	crypto_mod_put(alg);
 	return inst;
 
-out_put_alg:
-	inst = ERR_PTR(err);
-	goto out;
+err_drop_spawn:
+	crypto_drop_skcipher(spawn);
+err_free_inst:
+	kfree(inst);
+	return ERR_PTR(err);
+}
+
+static void crypto_rfc3686_free(struct crypto_instance *inst)
+{
+	struct crypto_skcipher_spawn *spawn = crypto_instance_ctx(inst);
+
+	crypto_drop_skcipher(spawn);
+	kfree(inst);
 }
 
 static struct crypto_template crypto_rfc3686_tmpl = {
 	.name = "rfc3686",
 	.alloc = crypto_rfc3686_alloc,
-	.free = crypto_ctr_free,
+	.free = crypto_rfc3686_free,
 	.module = THIS_MODULE,
 };
 
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 7ae2130..87ef7d6 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1591,6 +1591,10 @@ static int do_test(int m)
 				   speed_template_16_24_32);
 		test_acipher_speed("ofb(aes)", DECRYPT, sec, NULL, 0,
 				   speed_template_16_24_32);
+		test_acipher_speed("rfc3686(ctr(aes))", ENCRYPT, sec, NULL, 0,
+				   speed_template_20_28_36);
+		test_acipher_speed("rfc3686(ctr(aes))", DECRYPT, sec, NULL, 0,
+				   speed_template_20_28_36);
 		break;
 
 	case 501:
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index cd20685..ecdeeb1 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -51,6 +51,7 @@ static u8 speed_template_8_16[] = {8, 16, 0};
 static u8 speed_template_8_32[] = {8, 32, 0};
 static u8 speed_template_16_32[] = {16, 32, 0};
 static u8 speed_template_16_24_32[] = {16, 24, 32, 0};
+static u8 speed_template_20_28_36[] = {20, 28, 36, 0};
 static u8 speed_template_32_40_48[] = {32, 40, 48, 0};
 static u8 speed_template_32_48[] = {32, 48, 0};
 static u8 speed_template_32_48_64[] = {32, 48, 64, 0};
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 2/8] xfrm_algo: probe asynchronous block ciphers instead of synchronous
From: Steffen Klassert @ 2013-01-23  8:18 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1358929144-17806-1-git-send-email-steffen.klassert@secunet.com>

From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>

IPSEC uses block ciphers asynchronous, but probes only for synchronous block
ciphers and makes ealg entries only available if synchronous block cipher is
found. So with setup, where hardware crypto driver registers asynchronous
block ciphers and software crypto module is not build, ealg is not marked
as being available.

Use crypto_has_ablkcipher instead and remove ASYNC mask.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/xfrm/xfrm_algo.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 4ce2d93..f9a5495 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -700,8 +700,7 @@ void xfrm_probe_algs(void)
 	}
 
 	for (i = 0; i < ealg_entries(); i++) {
-		status = crypto_has_blkcipher(ealg_list[i].name, 0,
-					      CRYPTO_ALG_ASYNC);
+		status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0);
 		if (ealg_list[i].available != status)
 			ealg_list[i].available = status;
 	}
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 1/8] xfrm: removes a superfluous check and add a statistic
From: Steffen Klassert @ 2013-01-23  8:18 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1358929144-17806-1-git-send-email-steffen.klassert@secunet.com>

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

Remove the check if x->km.state equal to XFRM_STATE_VALID in
xfrm_state_check_expire(), which will be done before call
xfrm_state_check_expire().

add a LINUX_MIB_XFRMOUTSTATEINVALID statistic to record the
outbound error due to invalid xfrm state.

Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 include/uapi/linux/snmp.h |    1 +
 net/xfrm/xfrm_output.c    |    6 ++++++
 net/xfrm/xfrm_proc.c      |    1 +
 net/xfrm/xfrm_state.c     |    3 ---
 4 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
index fdfba23..b49eab8 100644
--- a/include/uapi/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
@@ -278,6 +278,7 @@ enum
 	LINUX_MIB_XFRMOUTPOLDEAD,		/* XfrmOutPolDead */
 	LINUX_MIB_XFRMOUTPOLERROR,		/* XfrmOutPolError */
 	LINUX_MIB_XFRMFWDHDRERROR,		/* XfrmFwdHdrError*/
+	LINUX_MIB_XFRMOUTSTATEINVALID,		/* XfrmOutStateInvalid */
 	__LINUX_MIB_XFRMMAX
 };
 
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 95a338c..3670526 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -61,6 +61,12 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 		}
 
 		spin_lock_bh(&x->lock);
+
+		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
+			goto error_nolock;
+		}
+
 		err = xfrm_state_check_expire(x);
 		if (err) {
 			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEEXPIRED);
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index d0a1af8..6039038 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -43,6 +43,7 @@ static const struct snmp_mib xfrm_mib_list[] = {
 	SNMP_MIB_ITEM("XfrmOutPolDead", LINUX_MIB_XFRMOUTPOLDEAD),
 	SNMP_MIB_ITEM("XfrmOutPolError", LINUX_MIB_XFRMOUTPOLERROR),
 	SNMP_MIB_ITEM("XfrmFwdHdrError", LINUX_MIB_XFRMFWDHDRERROR),
+	SNMP_MIB_ITEM("XfrmOutStateInvalid", LINUX_MIB_XFRMOUTSTATEINVALID),
 	SNMP_MIB_SENTINEL
 };
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3459692..05db236 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1370,9 +1370,6 @@ int xfrm_state_check_expire(struct xfrm_state *x)
 	if (!x->curlft.use_time)
 		x->curlft.use_time = get_seconds();
 
-	if (x->km.state != XFRM_STATE_VALID)
-		return -EINVAL;
-
 	if (x->curlft.bytes >= x->lft.hard_byte_limit ||
 	    x->curlft.packets >= x->lft.hard_packet_limit) {
 		x->km.state = XFRM_STATE_EXPIRED;
-- 
1.7.9.5

^ permalink raw reply related

* pull request (net-next): ipsec-next 2013-01-23
From: Steffen Klassert @ 2013-01-23  8:18 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev

1) Add a statistic counter for invalid output states and
   remove a superfluous state valid check, from Li RongQing.

2) Probe for asynchronous block ciphers instead of synchronous block
   ciphers to make the asynchronous variants available even if no
   synchronous block ciphers are found, from Jussi Kivilinna.

3) Make rfc3686 asynchronous block cipher and make use of
   the new asynchronous variant, from Jussi Kivilinna.

4) Replace some rwlocks by rcu, from Cong Wang.

5) Remove some unused defines.

Please pull or let me know if there are problems.

Thanks!

The following changes since commit 483f777266f5da205459c290994bd3cda5f1f6bc:

  drivers/net: remove orphaned references to micro channel (2013-01-06 21:13:33 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git testing

for you to fetch changes up to 02bfd8ecf5cf980ede53e30a903b102924fc32f4:

  xfrm: Remove unused defines (2013-01-21 11:19:04 +0100)

----------------------------------------------------------------
Cong Wang (3):
      xfrm: replace rwlock on xfrm_state_afinfo with rcu
      xfrm: replace rwlock on xfrm_km_list with rcu
      xfrm: use separated locks to protect pointers of struct xfrm_state_afinfo

Jussi Kivilinna (3):
      xfrm_algo: probe asynchronous block ciphers instead of synchronous
      crypto: ctr - make rfc3686 asynchronous block cipher
      crypto: aesni-intel - remove rfc3686(ctr(aes)), utilize rfc3686 from ctr-module instead

Li RongQing (1):
      xfrm: removes a superfluous check and add a statistic

Steffen Klassert (1):
      xfrm: Remove unused defines

 arch/x86/crypto/aesni-intel_glue.c |   37 --------
 crypto/ctr.c                       |  173 +++++++++++++++++++++++-------------
 crypto/tcrypt.c                    |    4 +
 crypto/tcrypt.h                    |    1 +
 include/net/xfrm.h                 |    4 -
 include/uapi/linux/snmp.h          |    1 +
 net/xfrm/xfrm_algo.c               |    3 +-
 net/xfrm/xfrm_output.c             |    6 ++
 net/xfrm/xfrm_proc.c               |    1 +
 net/xfrm/xfrm_state.c              |  131 +++++++++++++--------------
 10 files changed, 185 insertions(+), 176 deletions(-)

^ permalink raw reply


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