Netdev List
 help / color / mirror / Atom feed
* [net PATCH 4/7] bnx2x: display the correct duplex value
From: Yuval Mintz @ 2012-09-10 15:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: eilong, Yaniv Rosner, Yuval Mintz
In-Reply-To: <1347292135-30250-1-git-send-email-yuvalmin@broadcom.com>

From: Yaniv Rosner <yaniv.rosner@broadcom.com>

Prior to this fix, the driver reported the chip's active duplex state
is always 'full', even if using half-duplex mode.

Signed-off-by: Yaniv Rosner <yaniv.rosner@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 40a7b8d..b046beb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -5434,7 +5434,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
 		switch (speed_mask) {
 		case GP_STATUS_10M:
 			vars->line_speed = SPEED_10;
-			if (vars->duplex == DUPLEX_FULL)
+			if (is_duplex == DUPLEX_FULL)
 				vars->link_status |= LINK_10TFD;
 			else
 				vars->link_status |= LINK_10THD;
@@ -5442,7 +5442,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
 
 		case GP_STATUS_100M:
 			vars->line_speed = SPEED_100;
-			if (vars->duplex == DUPLEX_FULL)
+			if (is_duplex == DUPLEX_FULL)
 				vars->link_status |= LINK_100TXFD;
 			else
 				vars->link_status |= LINK_100TXHD;
@@ -5451,7 +5451,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
 		case GP_STATUS_1G:
 		case GP_STATUS_1G_KX:
 			vars->line_speed = SPEED_1000;
-			if (vars->duplex == DUPLEX_FULL)
+			if (is_duplex == DUPLEX_FULL)
 				vars->link_status |= LINK_1000TFD;
 			else
 				vars->link_status |= LINK_1000THD;
@@ -5459,7 +5459,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
 
 		case GP_STATUS_2_5G:
 			vars->line_speed = SPEED_2500;
-			if (vars->duplex == DUPLEX_FULL)
+			if (is_duplex == DUPLEX_FULL)
 				vars->link_status |= LINK_2500TFD;
 			else
 				vars->link_status |= LINK_2500THD;
@@ -5533,6 +5533,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
 
 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
 		if (SINGLE_MEDIA_DIRECT(params)) {
+			vars->duplex = duplex;
 			bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
 			if (phy->req_line_speed == SPEED_AUTO_NEG)
 				bnx2x_xgxs_an_resolve(phy, params, vars,
@@ -5627,6 +5628,7 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
 					LINK_STATUS_PARALLEL_DETECTION_USED;
 			}
 			bnx2x_ext_phy_resolve_fc(phy, params, vars);
+			vars->duplex = duplex;
 		}
 	}
 
-- 
1.7.9.rc2

^ permalink raw reply related

* [net PATCH 0/7] bnx2x: bug fixes for net
From: Yuval Mintz @ 2012-09-10 15:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: eilong, Yuval Mintz

Hi Dave,

This patch series contains various bug fixes for the bnx2x driver -
about half of them are link related, while the other either add
code missing in previous git commits or fix erroneous flows.

Please consider applying this patch series to 'net'.

Thanks,
Yuval Mintz

^ permalink raw reply

* [net PATCH 2/7] bnx2x: fix stats copying logic
From: Yuval Mintz @ 2012-09-10 15:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: eilong, Yuval Mintz
In-Reply-To: <1347292135-30250-1-git-send-email-yuvalmin@broadcom.com>

FW needs the driver statistics for management. Current logic is broken
in that the function that gathers the port statistics does not copy
its own statistics to a place where the FW can use it.
This patch causes every function that can pass statistics to the FW to
do so.

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index d848dc9..a1d0446 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -101,6 +101,11 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)
 	if (CHIP_REV_IS_SLOW(bp))
 		return;
 
+	/* Update MCP's statistics if possible */
+	if (bp->func_stx)
+		memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats,
+		       sizeof(bp->func_stats));
+
 	/* loader */
 	if (bp->executer_idx) {
 		int loader_idx = PMF_DMAE_C(bp);
@@ -128,8 +133,6 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)
 
 	} else if (bp->func_stx) {
 		*stats_comp = 0;
-		memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats,
-		       sizeof(bp->func_stats));
 		bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
 	}
 }
-- 
1.7.9.rc2

^ permalink raw reply related

* [net PATCH 1/7] bnx2x: Avoid sending multiple statistics queries
From: Yuval Mintz @ 2012-09-10 15:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: eilong, Dmitry Kravkov, Yuval Mintz
In-Reply-To: <1347292135-30250-1-git-send-email-yuvalmin@broadcom.com>

From: Dmitry Kravkov <dmitry@broadcom.com>

During traffic when DCB is enabled, it is possible for multiple instances
of statistics queries to be sent to the chip - this may cause the FW to assert.

This patch prevents the sending of an additional instance of statistics query
while the previous query hasn't completed.

Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index 332db64..d848dc9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -1151,9 +1151,11 @@ static void bnx2x_stats_update(struct bnx2x *bp)
 	if (bp->port.pmf)
 		bnx2x_hw_stats_update(bp);
 
-	if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) {
-		BNX2X_ERR("storm stats were not updated for 3 times\n");
-		bnx2x_panic();
+	if (bnx2x_storm_stats_update(bp)) {
+		if (bp->stats_pending++ == 3) {
+			BNX2X_ERR("storm stats were not updated for 3 times\n");
+			bnx2x_panic();
+		}
 		return;
 	}
 
-- 
1.7.9.rc2

^ permalink raw reply related

* [PATCH -next] net: fix net/core/sock.c build error
From: Randy Dunlap @ 2012-09-10 16:13 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linux-next, LKML, netdev, David Miller
In-Reply-To: <20120910172407.c5ad953c008165fcd862bd3c@canb.auug.org.au>

From: Randy Dunlap <rdunlap@xenotime.net>

Fix net/core/sock.c build error when CONFIG_INET is not enabled:

net/built-in.o: In function `sock_edemux':
(.text+0xd396): undefined reference to `inet_twsk_put'

Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
---
 net/core/sock.c |    2 ++
 1 file changed, 2 insertions(+)

--- linux-next-20120910.orig/net/core/sock.c
+++ linux-next-20120910/net/core/sock.c
@@ -1525,9 +1525,11 @@ void sock_edemux(struct sk_buff *skb)
 {
 	struct sock *sk = skb->sk;
 
+#ifdef CONFIG_INET
 	if (sk->sk_state == TCP_TIME_WAIT)
 		inet_twsk_put(inet_twsk(sk));
 	else
+#endif
 		sock_put(sk);
 }
 EXPORT_SYMBOL(sock_edemux);

^ permalink raw reply

* [PATCH v2] lxt PHY: Support for the buggy LXT973 rev A2
From: Christophe Leroy @ 2012-09-10 15:45 UTC (permalink / raw)
  To: David S Miller; +Cc: netdev, linux-kernel

This patch adds proper handling of the buggy revision A2 of LXT973 phy, adding
precautions linked to ERRATA Item 4:

Item 4: MDIO Interface and Repeated Polling
Problem: Repeated polling of odd-numbered registers via the MDIO interface
	randomly returns the contents of the previous even register.
Implication: Managed applications may not obtain the correct register contents
	when a particular register is monitored for device status.
Workaround: None.
Status: This erratum has been previously fixed (in rev A3)


Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

diff -u linux-3.5-vanilla/drivers/net/phy/lxt.c linux-3.5/drivers/net/phy/lxt.c
--- linux-3.5-vanilla/drivers/net/phy/lxt.c	2012-07-21 22:58:29.000000000 +0200
+++ linux-3.5/drivers/net/phy/lxt.c	2012-09-07 18:08:54.000000000 +0200
@@ -7,6 +7,10 @@
  *
  * Copyright (c) 2004 Freescale Semiconductor, Inc.
  *
+ * Copyright (c) 2010 CSSI
+ *
+ * Added support for buggy LXT973 rev A2
+ *
  * 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
@@ -54,8 +58,12 @@
 #define MII_LXT971_ISR		19  /* Interrupt Status Register */
 
 /* register definitions for the 973 */
-#define MII_LXT973_PCR 16 /* Port Configuration Register */
+#define MII_LXT973_PCR		16 /* Port Configuration Register */
 #define PCR_FIBER_SELECT 1
+#define MII_LXT973_SFR		27  /* Special Function Register */
+
+#define PHYDEV_PRIV_FIBER	1
+#define PHYDEV_PRIV_REVA2	2
 
 MODULE_DESCRIPTION("Intel LXT PHY driver");
 MODULE_AUTHOR("Andy Fleming");
@@ -99,6 +107,9 @@
 	return err;
 }
 
+/* register definitions for the 973 */
+#define MII_LXT973_PCR 16 /* Port Configuration Register */
+#define PCR_FIBER_SELECT 1
 
 static int lxt971_ack_interrupt(struct phy_device *phydev)
 {
@@ -122,9 +133,141 @@
 	return err;
 }
 
+/*
+ * ERRATA on LXT973
+ *
+ * Item 4: MDIO Interface and Repeated Polling
+ * Problem: Repeated polling of odd-numbered registers via the MDIO interface randomly returns the
+ * 	contents of the previous even register.
+ * Implication: Managed applications may not obtain the correct register contents when a particular
+ * 	register is monitored for device status.
+ * Workaround: None.
+ * Status: This erratum has been previously fixed (in rev A3)
+ *
+ */
+
+static int lxt973a2_update_link(struct phy_device *phydev)
+{
+	int status;
+	int control;
+	int retry = 8; /* we try 8 times */
+
+	/* Do a fake read */
+	status = phy_read(phydev, MII_BMSR);
+
+	if (status < 0)
+		return status;
+
+	control = phy_read(phydev, MII_BMCR);
+	if (control < 0)
+		return control;
+
+	do {
+		/* Read link and autonegotiation status */
+		status = phy_read(phydev, MII_BMSR);
+	} while (status>=0 && retry-- && status == control);
+
+	if (status < 0)
+		return status;
+
+	if ((status & BMSR_LSTATUS) == 0)
+		phydev->link = 0;
+	else
+		phydev->link = 1;
+
+	return 0;
+}
+
+int lxt973a2_read_status(struct phy_device *phydev)
+{
+	int adv;
+	int err;
+	int lpa;
+	int lpagb = 0;
+
+	/* Update the link, but return if there was an error */
+	err = lxt973a2_update_link(phydev);
+	if (err)
+		return err;
+
+	if (AUTONEG_ENABLE == phydev->autoneg) {
+		int retry = 1;
+		
+		adv = phy_read(phydev, MII_ADVERTISE);
+
+		if (adv < 0)
+			return adv;
+
+		do {
+			lpa = phy_read(phydev, MII_LPA);
+
+			if (lpa < 0)
+				return lpa;
+
+			/* If both registers are equal, it is suspect but not impossible, hence a new try */	
+		} while (lpa == adv && retry--);
+
+		lpa &= adv;
+
+		phydev->speed = SPEED_10;
+		phydev->duplex = DUPLEX_HALF;
+		phydev->pause = phydev->asym_pause = 0;
+
+		if (lpagb & (LPA_1000FULL | LPA_1000HALF)) {
+			phydev->speed = SPEED_1000;
+
+			if (lpagb & LPA_1000FULL)
+				phydev->duplex = DUPLEX_FULL;
+		} else if (lpa & (LPA_100FULL | LPA_100HALF)) {
+			phydev->speed = SPEED_100;
+
+			if (lpa & LPA_100FULL)
+				phydev->duplex = DUPLEX_FULL;
+		} else
+			if (lpa & LPA_10FULL)
+				phydev->duplex = DUPLEX_FULL;
+
+		if (phydev->duplex == DUPLEX_FULL){
+			phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
+			phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
+		}
+	} else {
+		int bmcr = phy_read(phydev, MII_BMCR);
+
+		if (bmcr < 0)
+			return bmcr;
+
+		if (bmcr & BMCR_FULLDPLX)
+			phydev->duplex = DUPLEX_FULL;
+		else
+			phydev->duplex = DUPLEX_HALF;
+
+		if (bmcr & BMCR_SPEED1000)
+			phydev->speed = SPEED_1000;
+		else if (bmcr & BMCR_SPEED100)
+			phydev->speed = SPEED_100;
+		else
+			phydev->speed = SPEED_10;
+
+		phydev->pause = phydev->asym_pause = 0;
+	}
+
+	return 0;
+}
+
+static int lxt973_read_status(struct phy_device *phydev)
+{
+	return (int)phydev->priv&PHYDEV_PRIV_REVA2 ? lxt973a2_read_status(phydev) : genphy_read_status(phydev);
+}
+
 static int lxt973_probe(struct phy_device *phydev)
 {
 	int val = phy_read(phydev, MII_LXT973_PCR);
+	int priv = 0;
+
+	phydev->priv = NULL;
+
+	if (val<0) return val;
 
 	if (val & PCR_FIBER_SELECT) {
 		/*
@@ -136,17 +279,24 @@
 		val &= ~BMCR_ANENABLE;
 		phy_write(phydev, MII_BMCR, val);
 		/* Remember that the port is in fiber mode. */
-		phydev->priv = lxt973_probe;
-	} else {
-		phydev->priv = NULL;
+		priv |= PHYDEV_PRIV_FIBER;
 	}
+	val = phy_read(phydev, MII_PHYSID2);
+
+	if (val<0) return val;
+
+	if ((val & 0xf) == 0) { /* rev A2 */
+		dev_info(&phydev->dev, " LXT973 revision A2 has bugs\n");
+		priv |= PHYDEV_PRIV_REVA2;
+	}
+	phydev->priv = (void*)priv;
 	return 0;
 }
 
 static int lxt973_config_aneg(struct phy_device *phydev)
 {
 	/* Do nothing if port is in fiber mode. */
-	return phydev->priv ? 0 : genphy_config_aneg(phydev);
+	return (int)phydev->priv&PHYDEV_PRIV_FIBER ? 0 : genphy_config_aneg(phydev);
 }
 
 static struct phy_driver lxt970_driver = {
@@ -184,7 +334,10 @@
 	.flags		= 0,
 	.probe		= lxt973_probe,
 	.config_aneg	= lxt973_config_aneg,
-	.read_status	= genphy_read_status,
+	.read_status	= lxt973_read_status,
+	.suspend	= genphy_suspend,
+	.resume		= genphy_resume,
+	.isolate	= genphy_isolate,
 	.driver 	= { .owner = THIS_MODULE,},
 };
 

^ permalink raw reply

* Re: kernel 3.5.2/amd64: iwlwifi 0000:03:00.0: failed to allocate pci memory
From: Marc MERLIN @ 2012-09-10 15:34 UTC (permalink / raw)
  To: Johannes Berg
  Cc: wey-yi.w.guy-ral2JQCrhuEAvxtiuMwx3w, ilw-VuQAYsv1563Yd54FQh9/CA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-q7rQbLoQdy39qxiX1TGQuw
In-Reply-To: <1347272641.4272.1.camel-8Nb76shvtaUJvtFkdXX2HixXY32XiHfO@public.gmane.org>

On Mon, Sep 10, 2012 at 12:24:01PM +0200, Johannes Berg wrote:
> On Sat, 2012-09-08 at 20:57 +0200, Johannes Berg wrote:
> 
> > > [856806.497959]  [<ffffffff810cf54c>] warn_alloc_failed+0x117/0x12c
> > > [856806.497963]  [<ffffffff810d23af>] __alloc_pages_nodemask+0x6e3/0x792
> > > [856806.497969]  [<ffffffff812b7f41>] ? pfn_to_dma_pte+0x116/0x15e
> > > [856806.497976]  [<ffffffff810ff58b>] alloc_pages_current+0xcd/0xee
> > > [856806.497979]  [<ffffffff810cecca>] __get_free_pages+0x9/0x45
> > > [856806.497982]  [<ffffffff812ba67d>] intel_alloc_coherent+0x84/0xe7
> > > [856806.497986]  [<ffffffff81085cf8>] ? arch_local_irq_save+0x15/0x1b
> > > [856806.497999]  [<ffffffffa0b84afc>] iwl_ucode_callback+0xa49/0xc0d [iwlwifi]
> > 
> > Yes, unfortunately we need a whole bunch of contiguous memory to load
> > the firmware.
> > 
> > > Any ideas?
> > 
> > Nothing we can do from the driver side, I'm afraid.
> 
> Turns out I was wrong. Here's a patch you can test. Note that we still
> need a lot of DMA-coherent memory for other things, but at least for the
> firmware image we don't.

Thanks for that, I'll try it out and report back if I have other problems
(it's hard to prove that it worked since I don't have the fragmented memory
right away).

Marc
-- 
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems ....
                                      .... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/  
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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: [PATCH v2] rndis_wlan: remove pointless check from rndis_scan()
From: Jussi Kivilinna @ 2012-09-10 15:33 UTC (permalink / raw)
  To: Wei Yongjun; +Cc: linville, yongjun_wei, linux-wireless, netdev
In-Reply-To: <CAPgLHd8FG3pEz3FZ=1ux=h5sKGXwykXc=qafb=OzEQKXWU9uuw@mail.gmail.com>

Quoting Wei Yongjun <weiyj.lk@gmail.com>:

> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
> In rndis_scan(), 'request' is actually always valid pointer and
> the !request check is unneeded, so remove it.
>
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

Acked-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>

> ---
>  drivers/net/wireless/rndis_wlan.c | 3 ---
>  1 file changed, 3 deletions(-)
>
> diff --git a/drivers/net/wireless/rndis_wlan.c  
> b/drivers/net/wireless/rndis_wlan.c
> index 7a4ae9e..bd1f0cb 100644
> --- a/drivers/net/wireless/rndis_wlan.c
> +++ b/drivers/net/wireless/rndis_wlan.c
> @@ -1959,9 +1959,6 @@ static int rndis_scan(struct wiphy *wiphy,
>  	 */
>  	rndis_check_bssid_list(usbdev, NULL, NULL);
>
> -	if (!request)
> -		return -EINVAL;
> -
>  	if (priv->scan_request && priv->scan_request != request)
>  		return -EBUSY;
>
>
>
>
>

^ permalink raw reply

* Re: kernel 3.5.2/amd64: iwlwifi 0000:03:00.0: failed to allocate pci memory
From: Larry Finger @ 2012-09-10 15:12 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Marc MERLIN, wey-yi.w.guy-ral2JQCrhuEAvxtiuMwx3w,
	ilw-VuQAYsv1563Yd54FQh9/CA, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-q7rQbLoQdy39qxiX1TGQuw
In-Reply-To: <1347272641.4272.1.camel-8Nb76shvtaUJvtFkdXX2HixXY32XiHfO@public.gmane.org>

On 09/10/2012 05:24 AM, Johannes Berg wrote:
> On Sat, 2012-09-08 at 20:57 +0200, Johannes Berg wrote:
>
>>> [856806.497959]  [<ffffffff810cf54c>] warn_alloc_failed+0x117/0x12c
>>> [856806.497963]  [<ffffffff810d23af>] __alloc_pages_nodemask+0x6e3/0x792
>>> [856806.497969]  [<ffffffff812b7f41>] ? pfn_to_dma_pte+0x116/0x15e
>>> [856806.497976]  [<ffffffff810ff58b>] alloc_pages_current+0xcd/0xee
>>> [856806.497979]  [<ffffffff810cecca>] __get_free_pages+0x9/0x45
>>> [856806.497982]  [<ffffffff812ba67d>] intel_alloc_coherent+0x84/0xe7
>>> [856806.497986]  [<ffffffff81085cf8>] ? arch_local_irq_save+0x15/0x1b
>>> [856806.497999]  [<ffffffffa0b84afc>] iwl_ucode_callback+0xa49/0xc0d [iwlwifi]
>>
>> Yes, unfortunately we need a whole bunch of contiguous memory to load
>> the firmware.
>>
>>> Any ideas?
>>
>> Nothing we can do from the driver side, I'm afraid.
>
> Turns out I was wrong. Here's a patch you can test. Note that we still
> need a lot of DMA-coherent memory for other things, but at least for the
> firmware image we don't.
>
> http://p.sipsolutions.net/11ea33b376a5bac5.txt

That patch looks like a good way to solve the problem; however, some 
architectures need an explicit "#include <linux/vmalloc.h>" somewhere in the 
headers, even though x86 does not, and I did not see it in the patch. I didn't 
do a lot of checking, but grep did not find one in the existing code.

Larry


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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: Regression associated with commit c8628155ece3 - "tcp: reduce out_of_order memory use"
From: Eric Dumazet @ 2012-09-10 15:04 UTC (permalink / raw)
  To: Larry Finger
  Cc: linville-2XuSBdqkA4R54TAoqtyWWQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA, netdev
In-Reply-To: <504DFEFF.6060004-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>

On Mon, 2012-09-10 at 09:53 -0500, Larry Finger wrote:

> Eric,
> 
> What is the md5sum for the firmware file /lib/firmware/rtlwifi/rtl8712u.bin? 
> Over the weekend, there was a report of another device that had problems with 
> firmware that was added to the linux-firmware repo in July with md5sum of 
> c6f3b7b880aefb7b3f249428d659bdbb. An older version with md5sum of 
> 200fd952db3cc9259b1fd05e3e51966f works in that case. I'll send you this one 
> privately.
> 
> I have a Netgear WNDR3300 and also get the addbareq events, but I do not get 
> freezes. I'm not sure the message is correlated.
> 

It seems I have the c6f3b7b880aefb7b3f249428d659bdbb one
# md5sum /data/src/linux-firmware/rtlwifi/rtl8712u.bin /lib/firmware/rtlwifi/rtl8712u.bin
c6f3b7b880aefb7b3f249428d659bdbb  /data/src/linux-firmware/rtlwifi/rtl8712u.bin
c6f3b7b880aefb7b3f249428d659bdbb  /lib/firmware/rtlwifi/rtl8712u.bin

Since I have linux-firmware tree, should I go back to initial commit 
commit 8f919160792e4702c6b7a67a243cea4f757407e4
Author: Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
Date:   Mon Nov 1 23:56:52 2010 -0500

    linux-firmware: Add firmware files for Realtek RTL8712U and
RTL8192CE

Thanks !



--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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: [PATCH net-next v2 2/4] xfrm: invalidate dst on policy insertion/deletion
From: Nicolas Dichtel @ 2012-09-10 14:56 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: davem, eric.dumazet, sri, linux-sctp, netdev
In-Reply-To: <504DF77B.7070000@gmail.com>

Le 10/09/2012 16:21, Vlad Yasevich a écrit :
> On 09/10/2012 09:22 AM, Nicolas Dichtel wrote:
>> When a policy is inserted or deleted, all dst should be recalculated.
>>
>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>> ---
>>   net/xfrm/xfrm_policy.c | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
>> index 741a32a..67f456d 100644
>> --- a/net/xfrm/xfrm_policy.c
>> +++ b/net/xfrm/xfrm_policy.c
>> @@ -602,6 +602,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy
>> *policy, int excl)
>>       xfrm_pol_hold(policy);
>>       net->xfrm.policy_count[dir]++;
>>       atomic_inc(&flow_cache_genid);
>> +    rt_genid_bump(net);
>>       if (delpol)
>>           __xfrm_policy_unlink(delpol, dir);
>>       policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
>>
>
> What about security_load_policy() and security_set_bools(). They also bumps the
> flow_cache_genid by way of selinux_xfrm_notify_policyload().
Right. I'm not familiar with this part, but it seems you're right, rt_genid 
should be bumped too.

^ permalink raw reply

* Re: Regression associated with commit c8628155ece3 - "tcp: reduce out_of_order memory use"
From: Larry Finger @ 2012-09-10 14:53 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: linville, linux-wireless, netdev
In-Reply-To: <1347266366.1234.1267.camel@edumazet-glaptop>

On 09/10/2012 03:39 AM, Eric Dumazet wrote:
> On Mon, 2012-08-27 at 12:55 -0500, Larry Finger wrote:
>
>> I have prepared a patch to fix all the unchecked allocations.
>>
>> Over the weekend I made some progress. To test the latest vendor driver, I
>> installed a 32-bit system. Their driver is not compatible with a 64-bit system.
>> I found that not only did the vendor driver work with secure sites, but so did
>> the in-kernel version. I now have tcpdump output for the 32-bit case that works,
>> and the 64-bit case that fails. It seems likely that I missed some 32/64 bit
>> incompatibility when I did the conversion.
>>
>> Thanks for all your help in trying to resolve this issue.
>>
>> Larry
>>
>>
>
> Hi Larry
>
> It appears I have a D-Link N300 (DWA-131) nano USB adapter, using
> staging/rtl8712 driver.
>
> I tried many kernel versions (including 3.3) and none seems to work
> reliably.
>
> Sometime, I have some traffic but only for about 50 frames...
> It might be because my access point is a netgear wndr3800, because I
> have following warning a bit before the freezes :
>
> r8712u: [r8712_got_addbareq_event_callback] mac = 20:4e:7f:5a:cd:30, sea = 80, tid = 0

Eric,

What is the md5sum for the firmware file /lib/firmware/rtlwifi/rtl8712u.bin? 
Over the weekend, there was a report of another device that had problems with 
firmware that was added to the linux-firmware repo in July with md5sum of 
c6f3b7b880aefb7b3f249428d659bdbb. An older version with md5sum of 
200fd952db3cc9259b1fd05e3e51966f works in that case. I'll send you this one 
privately.

I have a Netgear WNDR3300 and also get the addbareq events, but I do not get 
freezes. I'm not sure the message is correlated.

Larry

^ permalink raw reply

* Re: [tcpdump-workers] Modular arithmetic
From: Andi Kleen @ 2012-09-10 14:49 UTC (permalink / raw)
  To: David Laight; +Cc: George Bakos, tcpdump-workers, Jay Schulist, netdev
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B6FE4@saturn3.aculab.com>

> What about the other OS - eg all the BSDs?
> I had a vague idea that BPF was supposed to be reasonable portable.

Linux already has a variety of BPF extensions I believe.
But most of them were not targetted for tcpdump, but for other tools.

-Andi
-- 
ak@linux.intel.com -- Speaking for myself only

^ permalink raw reply

* Re: [PATCH net-next v2 3/4] ipv6: use net->rt_genid to check dst validity
From: Nicolas Dichtel @ 2012-09-10 14:44 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: davem, eric.dumazet, sri, linux-sctp, netdev
In-Reply-To: <504DFC9D.9010402@gmail.com>

Le 10/09/2012 16:43, Vlad Yasevich a écrit :
> On 09/10/2012 10:34 AM, Nicolas Dichtel wrote:
>> Le 10/09/2012 16:29, Vlad Yasevich a écrit :
>>> On 09/10/2012 09:22 AM, Nicolas Dichtel wrote:
>>>> IPv6 dst should take care of rt_genid too. When a xfrm policy is
>>>> inserted or
>>>> deleted, all dst should be invalidated.
>>>> To force the validation, dst entries should be created with
>>>> ->obsolete set to
>>>> DST_OBSOLETE_FORCE_CHK. This was already the case for all functions
>>>> calling
>>>> ip6_dst_alloc(), except for ip6_rt_copy().
>>>>
>>>> As a consequence, we can remove the specific code in
>>>> inet6_connection_sock.
>>>>
>>>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>>>> ---
>>>>   include/net/ip6_fib.h            |  2 +-
>>>>   net/ipv6/inet6_connection_sock.c | 23 +----------------------
>>>>   net/ipv6/route.c                 | 17 +++++++++++++----
>>>>   3 files changed, 15 insertions(+), 27 deletions(-)
>>>>
>>>> diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
>>>> index cd64cf3..5eb93f4 100644
>>>> --- a/include/net/ip6_fib.h
>>>> +++ b/include/net/ip6_fib.h
>>>> @@ -113,7 +113,7 @@ struct rt6_info {
>>>>       unsigned long            _rt6i_peer;
>>>>
>>>>   #ifdef CONFIG_XFRM
>>>> -    u32                rt6i_flow_cache_genid;
>>>> +    u32                rt6i_genid;
>>>>   #endif
>>>>       /* more non-fragment space at head required */
>>>>       unsigned short            rt6i_nfheader_len;
>>>> diff --git a/net/ipv6/inet6_connection_sock.c
>>>> b/net/ipv6/inet6_connection_sock.c
>>>> index 0251a60..c4f9341 100644
>>>> --- a/net/ipv6/inet6_connection_sock.c
>>>> +++ b/net/ipv6/inet6_connection_sock.c
>>>> @@ -175,33 +175,12 @@ void __inet6_csk_dst_store(struct sock *sk, struct
>>>> dst_entry *dst,
>>>>                  const struct in6_addr *saddr)
>>>>   {
>>>>       __ip6_dst_store(sk, dst, daddr, saddr);
>>>> -
>>>> -#ifdef CONFIG_XFRM
>>>> -    {
>>>> -        struct rt6_info *rt = (struct rt6_info  *)dst;
>>>> -        rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
>>>> -    }
>>>> -#endif
>>>>   }
>>>>
>>>>   static inline
>>>>   struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
>>>>   {
>>>> -    struct dst_entry *dst;
>>>> -
>>>> -    dst = __sk_dst_check(sk, cookie);
>>>> -
>>>> -#ifdef CONFIG_XFRM
>>>> -    if (dst) {
>>>> -        struct rt6_info *rt = (struct rt6_info *)dst;
>>>> -        if (rt->rt6i_flow_cache_genid !=
>>>> atomic_read(&flow_cache_genid)) {
>>>> -            __sk_dst_reset(sk);
>>>> -            dst = NULL;
>>>> -        }
>>>> -    }
>>>> -#endif
>>>> -
>>>> -    return dst;
>>>> +    return __sk_dst_check(sk, cookie);
>>>>   }
>>>>
>>>>   static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
>>>> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
>>>> index 339d921..db7b78f 100644
>>>> --- a/net/ipv6/route.c
>>>> +++ b/net/ipv6/route.c
>>>> @@ -281,13 +281,16 @@ static inline struct rt6_info
>>>> *ip6_dst_alloc(struct net
>>>> *net,
>>>>                            struct fib6_table *table)
>>>>   {
>>>>       struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
>>>> -                    0, DST_OBSOLETE_NONE, flags);
>>>> +                    0, DST_OBSOLETE_FORCE_CHK, flags);
>>>>
>>>>       if (rt) {
>>>>           struct dst_entry *dst = &rt->dst;
>>>>
>>>>           memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
>>>>           rt6_init_peer(rt, table ? &table->tb6_peers :
>>>> net->ipv6.peers);
>>>> +#ifdef CONFIG_XFRM
>>>> +        rt->rt6i_genid = rt_genid(net);
>>>> +#endif
>>>
>>> This isn't XFRM dependent any more, is it?
>> Not dependent, but for IPv6, it's only usefull when xfrm is set. Goal of
>> this ifdef was to avoid the test if xfrm is not used.
>
> It's not the usage,  it's enable at build time and that's almost always on.  Now
> the cache behavior is different when XFRM is excluded from the kernel build.
>
> Before the ifdef was needed since you were actually looking at xfrm variable.
> Not anymore.   The ifdef doesn't make sense.
Ok, I will remove it.

^ permalink raw reply

* Re: [PATCH net-next v2 3/4] ipv6: use net->rt_genid to check dst validity
From: Vlad Yasevich @ 2012-09-10 14:43 UTC (permalink / raw)
  To: nicolas.dichtel; +Cc: davem, eric.dumazet, sri, linux-sctp, netdev
In-Reply-To: <504DFA84.40409@6wind.com>

On 09/10/2012 10:34 AM, Nicolas Dichtel wrote:
> Le 10/09/2012 16:29, Vlad Yasevich a écrit :
>> On 09/10/2012 09:22 AM, Nicolas Dichtel wrote:
>>> IPv6 dst should take care of rt_genid too. When a xfrm policy is
>>> inserted or
>>> deleted, all dst should be invalidated.
>>> To force the validation, dst entries should be created with
>>> ->obsolete set to
>>> DST_OBSOLETE_FORCE_CHK. This was already the case for all functions
>>> calling
>>> ip6_dst_alloc(), except for ip6_rt_copy().
>>>
>>> As a consequence, we can remove the specific code in
>>> inet6_connection_sock.
>>>
>>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>>> ---
>>>   include/net/ip6_fib.h            |  2 +-
>>>   net/ipv6/inet6_connection_sock.c | 23 +----------------------
>>>   net/ipv6/route.c                 | 17 +++++++++++++----
>>>   3 files changed, 15 insertions(+), 27 deletions(-)
>>>
>>> diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
>>> index cd64cf3..5eb93f4 100644
>>> --- a/include/net/ip6_fib.h
>>> +++ b/include/net/ip6_fib.h
>>> @@ -113,7 +113,7 @@ struct rt6_info {
>>>       unsigned long            _rt6i_peer;
>>>
>>>   #ifdef CONFIG_XFRM
>>> -    u32                rt6i_flow_cache_genid;
>>> +    u32                rt6i_genid;
>>>   #endif
>>>       /* more non-fragment space at head required */
>>>       unsigned short            rt6i_nfheader_len;
>>> diff --git a/net/ipv6/inet6_connection_sock.c
>>> b/net/ipv6/inet6_connection_sock.c
>>> index 0251a60..c4f9341 100644
>>> --- a/net/ipv6/inet6_connection_sock.c
>>> +++ b/net/ipv6/inet6_connection_sock.c
>>> @@ -175,33 +175,12 @@ void __inet6_csk_dst_store(struct sock *sk, struct
>>> dst_entry *dst,
>>>                  const struct in6_addr *saddr)
>>>   {
>>>       __ip6_dst_store(sk, dst, daddr, saddr);
>>> -
>>> -#ifdef CONFIG_XFRM
>>> -    {
>>> -        struct rt6_info *rt = (struct rt6_info  *)dst;
>>> -        rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
>>> -    }
>>> -#endif
>>>   }
>>>
>>>   static inline
>>>   struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
>>>   {
>>> -    struct dst_entry *dst;
>>> -
>>> -    dst = __sk_dst_check(sk, cookie);
>>> -
>>> -#ifdef CONFIG_XFRM
>>> -    if (dst) {
>>> -        struct rt6_info *rt = (struct rt6_info *)dst;
>>> -        if (rt->rt6i_flow_cache_genid !=
>>> atomic_read(&flow_cache_genid)) {
>>> -            __sk_dst_reset(sk);
>>> -            dst = NULL;
>>> -        }
>>> -    }
>>> -#endif
>>> -
>>> -    return dst;
>>> +    return __sk_dst_check(sk, cookie);
>>>   }
>>>
>>>   static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
>>> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
>>> index 339d921..db7b78f 100644
>>> --- a/net/ipv6/route.c
>>> +++ b/net/ipv6/route.c
>>> @@ -281,13 +281,16 @@ static inline struct rt6_info
>>> *ip6_dst_alloc(struct net
>>> *net,
>>>                            struct fib6_table *table)
>>>   {
>>>       struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
>>> -                    0, DST_OBSOLETE_NONE, flags);
>>> +                    0, DST_OBSOLETE_FORCE_CHK, flags);
>>>
>>>       if (rt) {
>>>           struct dst_entry *dst = &rt->dst;
>>>
>>>           memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
>>>           rt6_init_peer(rt, table ? &table->tb6_peers :
>>> net->ipv6.peers);
>>> +#ifdef CONFIG_XFRM
>>> +        rt->rt6i_genid = rt_genid(net);
>>> +#endif
>>
>> This isn't XFRM dependent any more, is it?
> Not dependent, but for IPv6, it's only usefull when xfrm is set. Goal of
> this ifdef was to avoid the test if xfrm is not used.

It's not the usage,  it's enable at build time and that's almost always 
on.  Now the cache behavior is different when XFRM is excluded from the 
kernel build.

Before the ifdef was needed since you were actually looking at xfrm 
variable.  Not anymore.   The ifdef doesn't make sense.

-vlad

^ permalink raw reply

* Re: [PATCH net-next v2] Take care of xfrm policy when checking dst entries
From: Nicolas Dichtel @ 2012-09-10 14:38 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: davem, eric.dumazet, sri, linux-sctp, netdev
In-Reply-To: <504DFA97.7070509@gmail.com>

Le 10/09/2012 16:35, Vlad Yasevich a écrit :
> On 09/10/2012 09:22 AM, Nicolas Dichtel wrote:
>> The goal of these patches is to fix the following problem: a session is
>> established (TCP, SCTP) and after a new policy is inserted. The current
>> code does not recalculate the route, thus the traffic is not encrypted.
>>
>> The patch propose to check flow_cache_genid value when checking a dst
>> entry, which is incremented each time a policy is inserted or deleted.
>>
>> v2: use net->ipv4.rt_genid instead of flow_cache_genid (and thus save a test
>>      in fast path). Also move it to net->rt_genid, to be able to use it for IPv6
>>      too. Note that IPv6 will have one more test in fast path.
>>
>> Patches are tested with TCP and SCTP, IPv4 and IPv6.
>>
>> Comments are welcome.
>>
>> Regards,
>> Nicolas
>>
>
> I am not sure this is right...  This has a side-effect that when an
> rt_cache_flush() is called, it invalidates IPv6 routes a well....
>
> Its all fine and good do this when a new policy is added, but not when IPv4
> routing table changes.
I already ask for this side effect, Eric answers me:
http://marc.info/?l=linux-netdev&m=134728265000776&w=2

^ permalink raw reply

* Re: [PATCH net-next v2] Take care of xfrm policy when checking dst entries
From: Vlad Yasevich @ 2012-09-10 14:35 UTC (permalink / raw)
  To: Nicolas Dichtel; +Cc: davem, eric.dumazet, sri, linux-sctp, netdev
In-Reply-To: <1347283338-4249-1-git-send-email-nicolas.dichtel@6wind.com>

On 09/10/2012 09:22 AM, Nicolas Dichtel wrote:
> The goal of these patches is to fix the following problem: a session is
> established (TCP, SCTP) and after a new policy is inserted. The current
> code does not recalculate the route, thus the traffic is not encrypted.
>
> The patch propose to check flow_cache_genid value when checking a dst
> entry, which is incremented each time a policy is inserted or deleted.
>
> v2: use net->ipv4.rt_genid instead of flow_cache_genid (and thus save a test
>      in fast path). Also move it to net->rt_genid, to be able to use it for IPv6
>      too. Note that IPv6 will have one more test in fast path.
>
> Patches are tested with TCP and SCTP, IPv4 and IPv6.
>
> Comments are welcome.
>
> Regards,
> Nicolas
>

I am not sure this is right...  This has a side-effect that when an 
rt_cache_flush() is called, it invalidates IPv6 routes a well....

Its all fine and good do this when a new policy is added, but not when 
IPv4 routing table changes.

-vlad

^ permalink raw reply

* Re: [PATCH net-next v2 3/4] ipv6: use net->rt_genid to check dst validity
From: Nicolas Dichtel @ 2012-09-10 14:34 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: davem, eric.dumazet, sri, linux-sctp, netdev
In-Reply-To: <504DF950.4010401@gmail.com>

Le 10/09/2012 16:29, Vlad Yasevich a écrit :
> On 09/10/2012 09:22 AM, Nicolas Dichtel wrote:
>> IPv6 dst should take care of rt_genid too. When a xfrm policy is inserted or
>> deleted, all dst should be invalidated.
>> To force the validation, dst entries should be created with ->obsolete set to
>> DST_OBSOLETE_FORCE_CHK. This was already the case for all functions calling
>> ip6_dst_alloc(), except for ip6_rt_copy().
>>
>> As a consequence, we can remove the specific code in inet6_connection_sock.
>>
>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>> ---
>>   include/net/ip6_fib.h            |  2 +-
>>   net/ipv6/inet6_connection_sock.c | 23 +----------------------
>>   net/ipv6/route.c                 | 17 +++++++++++++----
>>   3 files changed, 15 insertions(+), 27 deletions(-)
>>
>> diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
>> index cd64cf3..5eb93f4 100644
>> --- a/include/net/ip6_fib.h
>> +++ b/include/net/ip6_fib.h
>> @@ -113,7 +113,7 @@ struct rt6_info {
>>       unsigned long            _rt6i_peer;
>>
>>   #ifdef CONFIG_XFRM
>> -    u32                rt6i_flow_cache_genid;
>> +    u32                rt6i_genid;
>>   #endif
>>       /* more non-fragment space at head required */
>>       unsigned short            rt6i_nfheader_len;
>> diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
>> index 0251a60..c4f9341 100644
>> --- a/net/ipv6/inet6_connection_sock.c
>> +++ b/net/ipv6/inet6_connection_sock.c
>> @@ -175,33 +175,12 @@ void __inet6_csk_dst_store(struct sock *sk, struct
>> dst_entry *dst,
>>                  const struct in6_addr *saddr)
>>   {
>>       __ip6_dst_store(sk, dst, daddr, saddr);
>> -
>> -#ifdef CONFIG_XFRM
>> -    {
>> -        struct rt6_info *rt = (struct rt6_info  *)dst;
>> -        rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
>> -    }
>> -#endif
>>   }
>>
>>   static inline
>>   struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
>>   {
>> -    struct dst_entry *dst;
>> -
>> -    dst = __sk_dst_check(sk, cookie);
>> -
>> -#ifdef CONFIG_XFRM
>> -    if (dst) {
>> -        struct rt6_info *rt = (struct rt6_info *)dst;
>> -        if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
>> -            __sk_dst_reset(sk);
>> -            dst = NULL;
>> -        }
>> -    }
>> -#endif
>> -
>> -    return dst;
>> +    return __sk_dst_check(sk, cookie);
>>   }
>>
>>   static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
>> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
>> index 339d921..db7b78f 100644
>> --- a/net/ipv6/route.c
>> +++ b/net/ipv6/route.c
>> @@ -281,13 +281,16 @@ static inline struct rt6_info *ip6_dst_alloc(struct net
>> *net,
>>                            struct fib6_table *table)
>>   {
>>       struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
>> -                    0, DST_OBSOLETE_NONE, flags);
>> +                    0, DST_OBSOLETE_FORCE_CHK, flags);
>>
>>       if (rt) {
>>           struct dst_entry *dst = &rt->dst;
>>
>>           memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
>>           rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
>> +#ifdef CONFIG_XFRM
>> +        rt->rt6i_genid = rt_genid(net);
>> +#endif
>
> This isn't XFRM dependent any more, is it?
Not dependent, but for IPv6, it's only usefull when xfrm is set. Goal of this 
ifdef was to avoid the test if xfrm is not used.

^ permalink raw reply

* Re: [PATCH net-next v2 3/4] ipv6: use net->rt_genid to check dst validity
From: Vlad Yasevich @ 2012-09-10 14:29 UTC (permalink / raw)
  To: Nicolas Dichtel; +Cc: davem, eric.dumazet, sri, linux-sctp, netdev
In-Reply-To: <1347283338-4249-4-git-send-email-nicolas.dichtel@6wind.com>

On 09/10/2012 09:22 AM, Nicolas Dichtel wrote:
> IPv6 dst should take care of rt_genid too. When a xfrm policy is inserted or
> deleted, all dst should be invalidated.
> To force the validation, dst entries should be created with ->obsolete set to
> DST_OBSOLETE_FORCE_CHK. This was already the case for all functions calling
> ip6_dst_alloc(), except for ip6_rt_copy().
>
> As a consequence, we can remove the specific code in inet6_connection_sock.
>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
> ---
>   include/net/ip6_fib.h            |  2 +-
>   net/ipv6/inet6_connection_sock.c | 23 +----------------------
>   net/ipv6/route.c                 | 17 +++++++++++++----
>   3 files changed, 15 insertions(+), 27 deletions(-)
>
> diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
> index cd64cf3..5eb93f4 100644
> --- a/include/net/ip6_fib.h
> +++ b/include/net/ip6_fib.h
> @@ -113,7 +113,7 @@ struct rt6_info {
>   	unsigned long			_rt6i_peer;
>
>   #ifdef CONFIG_XFRM
> -	u32				rt6i_flow_cache_genid;
> +	u32				rt6i_genid;
>   #endif
>   	/* more non-fragment space at head required */
>   	unsigned short			rt6i_nfheader_len;
> diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
> index 0251a60..c4f9341 100644
> --- a/net/ipv6/inet6_connection_sock.c
> +++ b/net/ipv6/inet6_connection_sock.c
> @@ -175,33 +175,12 @@ void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
>   			   const struct in6_addr *saddr)
>   {
>   	__ip6_dst_store(sk, dst, daddr, saddr);
> -
> -#ifdef CONFIG_XFRM
> -	{
> -		struct rt6_info *rt = (struct rt6_info  *)dst;
> -		rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
> -	}
> -#endif
>   }
>
>   static inline
>   struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
>   {
> -	struct dst_entry *dst;
> -
> -	dst = __sk_dst_check(sk, cookie);
> -
> -#ifdef CONFIG_XFRM
> -	if (dst) {
> -		struct rt6_info *rt = (struct rt6_info *)dst;
> -		if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
> -			__sk_dst_reset(sk);
> -			dst = NULL;
> -		}
> -	}
> -#endif
> -
> -	return dst;
> +	return __sk_dst_check(sk, cookie);
>   }
>
>   static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index 339d921..db7b78f 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -281,13 +281,16 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
>   					     struct fib6_table *table)
>   {
>   	struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
> -					0, DST_OBSOLETE_NONE, flags);
> +					0, DST_OBSOLETE_FORCE_CHK, flags);
>
>   	if (rt) {
>   		struct dst_entry *dst = &rt->dst;
>
>   		memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
>   		rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
> +#ifdef CONFIG_XFRM
> +		rt->rt6i_genid = rt_genid(net);
> +#endif

This isn't XFRM dependent any more, is it?

-vlad

>   	}
>   	return rt;
>   }
> @@ -1031,6 +1034,15 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
>
>   	rt = (struct rt6_info *) dst;
>
> +	/* All IPV6 dsts are created with ->obsolete set to the value
> +	 * DST_OBSOLETE_FORCE_CHK which forces validation calls down
> +	 * into this function always.
> +	 */
> +#ifdef CONFIG_XFRM
> +	if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
> +		return NULL;
> +#endif
> +
>   	if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
>   		if (rt->rt6i_peer_genid != rt6_peer_genid()) {
>   			if (!rt6_has_peer(rt))
> @@ -1397,8 +1409,6 @@ int ip6_route_add(struct fib6_config *cfg)
>   		goto out;
>   	}
>
> -	rt->dst.obsolete = -1;
> -
>   	if (cfg->fc_flags & RTF_EXPIRES)
>   		rt6_set_expires(rt, jiffies +
>   				clock_t_to_jiffies(cfg->fc_expires));
> @@ -2093,7 +2103,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
>   	rt->dst.input = ip6_input;
>   	rt->dst.output = ip6_output;
>   	rt->rt6i_idev = idev;
> -	rt->dst.obsolete = -1;
>
>   	rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
>   	if (anycast)
>

^ permalink raw reply

* Re: [PATCH v3 0/7] mv643xx.c: Add basic device tree support.
From: Arnd Bergmann @ 2012-09-10 14:22 UTC (permalink / raw)
  To: Ian Molton
  Cc: thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	andrew-g2DYL2Zd6BY, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	ben.dooks-4yDnlxn2s6sWdaTGBSpHTA, dale-1viX+2+OPRFcxvNqPlePQg,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ, David Miller,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <502D201E.9030304-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org>

On Thursday 16 August 2012, Ian Molton wrote:
> Ping :)
> 
> Can we get some consensus on the right approach here? I'm loathe to code
> this if its going to be rejected.
> 
> I'd prefer the driver to be properly split so we dont have the MDIO
> driver mapping the ethernet drivers address spaces, but if thats not
> going to be merged, I'm not feeling like doing the work for nothing.
> 
> If the driver is to use the overlapping-address mapped-by-the-mdio
> scheme, then so be it, but I could do with knowing.
> 
> Another point against the latter scheme is that the MDIO driver could
> sensibly be used (the block is identical) on the ArmadaXP, which has 4
> ethernet blocks rather than two, yet grouped in two pairs with a
> discontiguous address range.
> 
> I'd like to get this moved along as soon as possible though.

Following up on the old discussion, I talked briefly about this
issue with BenH at the kernel summit. The outcome basically is that
it's a bit sad to have incompatible bindings, but it's not the end
of the world,and it's more important to do it right this time.

Just make sure that you use different values for the 'compatible'
strings and then do what you need to get the ARM hardware working.

Ideally, the new binding should be written in a way that powerpc
machines can use the same one, but the existing ones all use
an version of Open Firmware that is not going to get updated
and it's also not too likely that we are going to see new
powerpc machines based on this chip.

	Arnd

^ permalink raw reply

* Re: [PATCH net-next v2 2/4] xfrm: invalidate dst on policy insertion/deletion
From: Vlad Yasevich @ 2012-09-10 14:21 UTC (permalink / raw)
  To: Nicolas Dichtel; +Cc: davem, eric.dumazet, sri, linux-sctp, netdev
In-Reply-To: <1347283338-4249-3-git-send-email-nicolas.dichtel@6wind.com>

On 09/10/2012 09:22 AM, Nicolas Dichtel wrote:
> When a policy is inserted or deleted, all dst should be recalculated.
>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
> ---
>   net/xfrm/xfrm_policy.c | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index 741a32a..67f456d 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -602,6 +602,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
>   	xfrm_pol_hold(policy);
>   	net->xfrm.policy_count[dir]++;
>   	atomic_inc(&flow_cache_genid);
> +	rt_genid_bump(net);
>   	if (delpol)
>   		__xfrm_policy_unlink(delpol, dir);
>   	policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
>

What about security_load_policy() and security_set_bools(). They also 
bumps the flow_cache_genid by way of selinux_xfrm_notify_policyload().

-vlad

^ permalink raw reply

* RE: [PATCH 2/3] ipv6, route: remove BACKTRACK() macro
From: David Laight @ 2012-09-10 13:54 UTC (permalink / raw)
  To: Cong Wang, netdev; +Cc: David S. Miller
In-Reply-To: <1347281326-26890-2-git-send-email-amwang@redhat.com>

> Subject: [PATCH 2/3] ipv6, route: remove BACKTRACK() macro
> 
> It doesn't save any code, nor it helps readability.
> 
> Signed-off-by: Cong Wang <amwang@redhat.com>
> ---
>  net/ipv6/route.c |   48 ++++++++++++++++++++++++++++--------------------
>  1 files changed, 28 insertions(+), 20 deletions(-)
> 
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index b130bf2..71267e9 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -675,24 +675,6 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
>  }
>  #endif
> 
> -#define BACKTRACK(__net, saddr)			\
> -do { \
> -	if (rt == __net->ipv6.ip6_null_entry) {	\
> -		struct fib6_node *pn; \
> -		while (1) { \
> -			if (fn->fn_flags & RTN_TL_ROOT) \
> -				goto out; \
> -			pn = fn->parent; \
> -			if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \
> -				fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); \
> -			else \
> -				fn = pn; \
> -			if (fn->fn_flags & RTN_RTINFO) \
> -				goto restart; \
> -		} \
> -	} \
> -} while (0)
> -

It does, however, seem to avoid replicating some relatively complex logic.
OTOH goto out of a #define and hidden parameters (rt, fn ...) are not nice.

Maybe the 'while (1)' part can be an inline function?

	David

^ permalink raw reply

* Re: [PATCH 2/3] ipv6, route: remove BACKTRACK() macro
From: Shan Wei @ 2012-09-10 13:43 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, David S. Miller
In-Reply-To: <1347281326-26890-2-git-send-email-amwang@redhat.com>

Cong Wang said, at 2012/9/10 20:48:
> It doesn't save any code, nor it helps readability.
> 
> Signed-off-by: Cong Wang <amwang@redhat.com>

this macro, don't reduce showing lines?
with it, more readability on terminal, right?

P.S. when doing backport work, some bored patches influence me.
this patch and [PATCH 3/3] are typical. :-)

> ---
>  net/ipv6/route.c |   48 ++++++++++++++++++++++++++++--------------------
>  1 files changed, 28 insertions(+), 20 deletions(-)
> 
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index b130bf2..71267e9 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -675,24 +675,6 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
>  }
>  #endif
>  
> -#define BACKTRACK(__net, saddr)			\
> -do { \
> -	if (rt == __net->ipv6.ip6_null_entry) {	\
> -		struct fib6_node *pn; \
> -		while (1) { \
> -			if (fn->fn_flags & RTN_TL_ROOT) \
> -				goto out; \
> -			pn = fn->parent; \
> -			if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \
> -				fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); \
> -			else \
> -				fn = pn; \
> -			if (fn->fn_flags & RTN_RTINFO) \
> -				goto restart; \
> -		} \
> -	} \
> -} while (0)
> -
>  static struct rt6_info *ip6_pol_route_lookup(struct net *net,
>  					     struct fib6_table *table,
>  					     struct flowi6 *fl6, int flags)
> @@ -705,7 +687,20 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
>  restart:
>  	rt = fn->leaf;
>  	rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags);
> -	BACKTRACK(net, &fl6->saddr);
> +	if (rt == net->ipv6.ip6_null_entry) {
> +		struct fib6_node *pn;
> +		while (1) {
> +			if (fn->fn_flags & RTN_TL_ROOT)
> +				goto out;
> +			pn = fn->parent;
> +			if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn)
> +				fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, &fl6->saddr);
> +			else
> +				fn = pn;
> +			if (fn->fn_flags & RTN_RTINFO)
> +				goto restart;
> +		}
> +	}
>  out:
>  	dst_use(&rt->dst, jiffies);
>  	read_unlock_bh(&table->tb6_lock);
> @@ -867,7 +862,20 @@ restart_2:
>  restart:
>  	rt = rt6_select(fn, oif, strict | reachable);
>  
> -	BACKTRACK(net, &fl6->saddr);
> +	if (rt == net->ipv6.ip6_null_entry) {
> +		struct fib6_node *pn;
> +		while (1) {
> +			if (fn->fn_flags & RTN_TL_ROOT)
> +				goto out;
> +			pn = fn->parent;
> +			if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn)
> +				fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, &fl6->saddr);
> +			else
> +				fn = pn;
> +			if (fn->fn_flags & RTN_RTINFO)
> +				goto restart;
> +		}
> +	}
>  	if (rt == net->ipv6.ip6_null_entry ||
>  	    rt->rt6i_flags & RTF_CACHE)
>  		goto out;
> 

^ permalink raw reply

* [PATCH net-next v2 4/4] ipv6: use DST_* macro to set obselete field
From: Nicolas Dichtel @ 2012-09-10 13:22 UTC (permalink / raw)
  To: vyasevich, davem, eric.dumazet; +Cc: sri, linux-sctp, netdev, Nicolas Dichtel
In-Reply-To: <1347283338-4249-1-git-send-email-nicolas.dichtel@6wind.com>

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv6/route.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index db7b78f..99b41cc 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -226,7 +226,7 @@ static struct rt6_info ip6_null_entry_template = {
 	.dst = {
 		.__refcnt	= ATOMIC_INIT(1),
 		.__use		= 1,
-		.obsolete	= -1,
+		.obsolete	= DST_OBSOLETE_FORCE_CHK,
 		.error		= -ENETUNREACH,
 		.input		= ip6_pkt_discard,
 		.output		= ip6_pkt_discard_out,
@@ -246,7 +246,7 @@ static struct rt6_info ip6_prohibit_entry_template = {
 	.dst = {
 		.__refcnt	= ATOMIC_INIT(1),
 		.__use		= 1,
-		.obsolete	= -1,
+		.obsolete	= DST_OBSOLETE_FORCE_CHK,
 		.error		= -EACCES,
 		.input		= ip6_pkt_prohibit,
 		.output		= ip6_pkt_prohibit_out,
@@ -261,7 +261,7 @@ static struct rt6_info ip6_blk_hole_entry_template = {
 	.dst = {
 		.__refcnt	= ATOMIC_INIT(1),
 		.__use		= 1,
-		.obsolete	= -1,
+		.obsolete	= DST_OBSOLETE_FORCE_CHK,
 		.error		= -EINVAL,
 		.input		= dst_discard,
 		.output		= dst_discard,
-- 
1.7.12

^ permalink raw reply related

* [PATCH net-next v2 3/4] ipv6: use net->rt_genid to check dst validity
From: Nicolas Dichtel @ 2012-09-10 13:22 UTC (permalink / raw)
  To: vyasevich, davem, eric.dumazet; +Cc: sri, linux-sctp, netdev, Nicolas Dichtel
In-Reply-To: <1347283338-4249-1-git-send-email-nicolas.dichtel@6wind.com>

IPv6 dst should take care of rt_genid too. When a xfrm policy is inserted or
deleted, all dst should be invalidated.
To force the validation, dst entries should be created with ->obsolete set to
DST_OBSOLETE_FORCE_CHK. This was already the case for all functions calling
ip6_dst_alloc(), except for ip6_rt_copy().

As a consequence, we can remove the specific code in inet6_connection_sock.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/net/ip6_fib.h            |  2 +-
 net/ipv6/inet6_connection_sock.c | 23 +----------------------
 net/ipv6/route.c                 | 17 +++++++++++++----
 3 files changed, 15 insertions(+), 27 deletions(-)

diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index cd64cf3..5eb93f4 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -113,7 +113,7 @@ struct rt6_info {
 	unsigned long			_rt6i_peer;
 
 #ifdef CONFIG_XFRM
-	u32				rt6i_flow_cache_genid;
+	u32				rt6i_genid;
 #endif
 	/* more non-fragment space at head required */
 	unsigned short			rt6i_nfheader_len;
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 0251a60..c4f9341 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -175,33 +175,12 @@ void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
 			   const struct in6_addr *saddr)
 {
 	__ip6_dst_store(sk, dst, daddr, saddr);
-
-#ifdef CONFIG_XFRM
-	{
-		struct rt6_info *rt = (struct rt6_info  *)dst;
-		rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
-	}
-#endif
 }
 
 static inline
 struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
 {
-	struct dst_entry *dst;
-
-	dst = __sk_dst_check(sk, cookie);
-
-#ifdef CONFIG_XFRM
-	if (dst) {
-		struct rt6_info *rt = (struct rt6_info *)dst;
-		if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
-			__sk_dst_reset(sk);
-			dst = NULL;
-		}
-	}
-#endif
-
-	return dst;
+	return __sk_dst_check(sk, cookie);
 }
 
 static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 339d921..db7b78f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -281,13 +281,16 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
 					     struct fib6_table *table)
 {
 	struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
-					0, DST_OBSOLETE_NONE, flags);
+					0, DST_OBSOLETE_FORCE_CHK, flags);
 
 	if (rt) {
 		struct dst_entry *dst = &rt->dst;
 
 		memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
 		rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
+#ifdef CONFIG_XFRM
+		rt->rt6i_genid = rt_genid(net);
+#endif
 	}
 	return rt;
 }
@@ -1031,6 +1034,15 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
 
 	rt = (struct rt6_info *) dst;
 
+	/* All IPV6 dsts are created with ->obsolete set to the value
+	 * DST_OBSOLETE_FORCE_CHK which forces validation calls down
+	 * into this function always.
+	 */
+#ifdef CONFIG_XFRM
+	if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
+		return NULL;
+#endif
+
 	if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
 		if (rt->rt6i_peer_genid != rt6_peer_genid()) {
 			if (!rt6_has_peer(rt))
@@ -1397,8 +1409,6 @@ int ip6_route_add(struct fib6_config *cfg)
 		goto out;
 	}
 
-	rt->dst.obsolete = -1;
-
 	if (cfg->fc_flags & RTF_EXPIRES)
 		rt6_set_expires(rt, jiffies +
 				clock_t_to_jiffies(cfg->fc_expires));
@@ -2093,7 +2103,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
 	rt->dst.input = ip6_input;
 	rt->dst.output = ip6_output;
 	rt->rt6i_idev = idev;
-	rt->dst.obsolete = -1;
 
 	rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
 	if (anycast)
-- 
1.7.12

^ 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