Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v4 1/1] can: add pruss CAN driver.
From: Wolfgang Grandegger @ 2011-04-25 20:06 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: sachi-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/,
	davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
	Subhasish Ghosh, nsekhar-l0cyMroinI0, open list,
	CAN NETWORK DRIVERS, Netdev-u79uwXL29TY76Z2rM5mHXA,
	m-watkins-l0cyMroinI0,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <4DB1A3B7.7060300-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

Hi,

On 04/22/2011 05:50 PM, Marc Kleine-Budde wrote:
> On 04/22/2011 02:11 PM, Subhasish Ghosh wrote:
>> This patch adds support for the CAN device emulated on PRUSS.
> 
> After commenting the code inline, some remarks:
> - Your tx path looks broken, see commits inline
> - Please setup a proper struct to describe your register layout, make
>   use of arrays for rx and tx
> - don't use u32, s32 for not hardware related variables like return
>   codes and loop counter.
> - the routines that load and save the can data bytes from/into your
>   mailbox look way to complicated. Please write down the layout so that
>   we can think of a elegant way to do it
> - a lot of functions unconditionally return 0, make them void if no
>   error can happen
> - think about using managed devices, that would simplify the probe and
>   release function

I agree with Marc's comments and would like to add:

- Use just *one* value per sysfs file

A few more comments inline...

>> Signed-off-by: Subhasish Ghosh <subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
>> ---
>>  drivers/net/can/Kconfig     |    7 +
>>  drivers/net/can/Makefile    |    1 +
>>  drivers/net/can/pruss_can.c | 1074 +++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 1082 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/net/can/pruss_can.c
>>
>> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
>> index 5dec456..4682a4f 100644
>> --- a/drivers/net/can/Kconfig
>> +++ b/drivers/net/can/Kconfig
>> @@ -111,6 +111,13 @@ config PCH_CAN
>>  	  embedded processor.
>>  	  This driver can access CAN bus.
>>  
>> +config CAN_TI_DA8XX_PRU
>> +	depends on CAN_DEV && ARCH_DAVINCI && ARCH_DAVINCI_DA850
>> +	tristate "PRU based CAN emulation for DA8XX"
>> +	---help---
>> +	Enable this to emulate a CAN controller on the PRU of DA8XX.
>> +	If not sure, mark N
> 
> Please indent the help text with 1 tab and 2 spaces
> 
>> +
>>  source "drivers/net/can/mscan/Kconfig"
>>  
>>  source "drivers/net/can/sja1000/Kconfig"
>> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
>> index 53c82a7..d0b7cbd 100644
>> --- a/drivers/net/can/Makefile
>> +++ b/drivers/net/can/Makefile
>> @@ -15,6 +15,7 @@ obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
>>  obj-$(CONFIG_CAN_MSCAN)		+= mscan/
>>  obj-$(CONFIG_CAN_AT91)		+= at91_can.o
>>  obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
>> +obj-$(CONFIG_CAN_TI_DA8XX_PRU)	+= pruss_can.o
>>  obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
>>  obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
>>  obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
>> diff --git a/drivers/net/can/pruss_can.c b/drivers/net/can/pruss_can.c
>> new file mode 100644
>> index 0000000..7702509
>> --- /dev/null
>> +++ b/drivers/net/can/pruss_can.c
...
> is this array const?
>> +static u32 pruss_intc_init[19][3] = {
>> +	{PRUSS_INTC_POLARITY0,		PRU_INTC_REGMAP_MASK,	0xFFFFFFFF},
>> +	{PRUSS_INTC_POLARITY1,		PRU_INTC_REGMAP_MASK,	0xFFFFFFFF},
>> +	{PRUSS_INTC_TYPE0,		PRU_INTC_REGMAP_MASK,	0x1C000000},
>> +	{PRUSS_INTC_TYPE1,		PRU_INTC_REGMAP_MASK,	0},
>> +	{PRUSS_INTC_GLBLEN,		0,			1},
>> +	{PRUSS_INTC_HOSTMAP0,		PRU_INTC_REGMAP_MASK,	0x03020100},
>> +	{PRUSS_INTC_HOSTMAP1,		PRU_INTC_REGMAP_MASK,	0x07060504},
>> +	{PRUSS_INTC_HOSTMAP2,		PRU_INTC_REGMAP_MASK,	0x0000908},
>> +	{PRUSS_INTC_CHANMAP0,		PRU_INTC_REGMAP_MASK,	0},
>> +	{PRUSS_INTC_CHANMAP8,		PRU_INTC_REGMAP_MASK,	0x00020200},
>> +	{PRUSS_INTC_STATIDXCLR,		0,			32},
>> +	{PRUSS_INTC_STATIDXCLR,		0,			19},
>> +	{PRUSS_INTC_ENIDXSET,		0,			19},
>> +	{PRUSS_INTC_STATIDXCLR,		0,			18},
>> +	{PRUSS_INTC_ENIDXSET,		0,			18},
>> +	{PRUSS_INTC_STATIDXCLR,		0,			34},
>> +	{PRUSS_INTC_ENIDXSET,		0,			34},
>> +	{PRUSS_INTC_ENIDXSET,		0,			32},
>> +	{PRUSS_INTC_HOSTINTEN,		0,			5}
> 
> please add ","

Also a struct to describe each entry would improve readability.
Then you could also use ARRAY_SIZE.

>> +};
...
>> +static int pru_can_set_bittiming(struct net_device *ndev)
>> +{
>> +	struct can_emu_priv *priv = netdev_priv(ndev);
>> +	struct can_bittiming *bt = &priv->can.bittiming;
>> +	u32 value;
>> +
>> +	value = priv->can.clock.freq / bt->bitrate;
>> +	pruss_writel(priv->dev, PRUSS_CAN_TIMING_VAL_TX, value);
>> +	pruss_writel(priv->dev, PRUSS_CAN_BIT_TIMING_VAL_RX, value);
>> +
>> +	value = (bt->phase_seg2 + bt->phase_seg1 +
>> +			bt->prop_seg + 1) * bt->brp;
>> +	value = (value >> 1) - PRUSS_CAN_TIMER_SETUP_DELAY;
>> +	value = (value << 16) | value;
>> +	pruss_writel(priv->dev, PRUSS_CAN_TIMING_VAL_RX, value);
>> +
>> +	value = (PRUSS_CAN_GPIO_SETUP_DELAY *
>> +		(priv->clk_freq_pru / 1000000) / 1000) /
>> +		PRUSS_CAN_DELAY_LOOP_LENGTH;

This calculation looks delicate. 64-bit math would be safer.

>> +
>> +	pruss_writel(priv->dev, PRUSS_CAN_TIMING_SETUP, value);
>> +	return 0;
>> +}
...
>> +static int pru_can_err(struct net_device *ndev, int int_status,
>> +			     int err_status)
>> +{
>> +	struct can_emu_priv *priv = netdev_priv(ndev);
>> +	struct net_device_stats *stats = &ndev->stats;
>> +	struct can_frame *cf;
>> +	struct sk_buff *skb;
>> +	u32 tx_err_cnt, rx_err_cnt;
>> +
>> +	skb = alloc_can_err_skb(ndev, &cf);
>> +	if (!skb) {
>> +		if (printk_ratelimit())
>> +			dev_err(priv->dev,
>> +				"alloc_can_err_skb() failed\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	if (err_status & PRUSS_CAN_GSR_BIT_EPM) {	/* error passive int */
>> +		priv->can.state = CAN_STATE_ERROR_PASSIVE;
>> +		++priv->can.can_stats.error_passive;
>> +		cf->can_id |= CAN_ERR_CRTL;
>> +		tx_err_cnt = pru_can_get_error_cnt(priv->dev,
>> +						PRUSS_CAN_TX_PRU_1);
>> +		rx_err_cnt = pru_can_get_error_cnt(priv->dev,
>> +						PRUSS_CAN_RX_PRU_0);
>> +		if (tx_err_cnt > PRUSS_CAN_ERROR_ACTIVE - 1)
>> +			cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
>> +		if (rx_err_cnt > PRUSS_CAN_ERROR_ACTIVE - 1)
>> +			cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
>> +
>> +		dev_dbg(priv->ndev->dev.parent, "Error passive interrupt\n");
>> +	}
>> +
>> +	if (err_status & PRUSS_CAN_GSR_BIT_BFM) {
>> +		priv->can.state = CAN_STATE_BUS_OFF;
>> +		cf->can_id |= CAN_ERR_BUSOFF;
>> +		/*
>> +		 *      Disable all interrupts in bus-off to avoid int hog
>> +		 *      this should be handled by the pru
>> +		 */
>> +		pru_can_mask_ints(priv->dev, PRUSS_CAN_TX_PRU_1, false);
>> +		pru_can_mask_ints(priv->dev, PRUSS_CAN_RX_PRU_0, false);
>> +		can_bus_off(ndev);
>> +		dev_dbg(priv->ndev->dev.parent, "Bus off mode\n");
>> +	}
>> +
>> +	netif_rx(skb);

You should use netif_receive_skb(skb) here as well.

>> +	stats->rx_packets++;
>> +	stats->rx_bytes += cf->can_dlc;
>> +	return 0;
>> +}
>> +
>> +static int pru_can_rx_poll(struct napi_struct *napi, int quota)
>> +{
>> +	struct net_device *ndev = napi->dev;
>> +	struct can_emu_priv *priv = netdev_priv(ndev);
>> +	u32 bit_set, mbxno = 0;
>> +	u32 num_pkts = 0;
>> +
>> +	if (!netif_running(ndev))
>> +		return 0;
>> +
>> +	do {
>> +		/* rx int sys_evt -> 33 */
>> +		pru_can_clr_intc_status(priv->dev, PRUSS_CAN_RX_PRU_0);
>> +		if (pru_can_intr_stat_get(priv->dev, &priv->can_rx_cntx))
>> +			return num_pkts;
>> +
>> +		if (PRUSS_CAN_ISR_BIT_RRI & priv->can_rx_cntx.intr_stat) {
>> +			mbxno = PRUSS_CAN_RTR_BUFF_NUM;
>> +			pru_can_rx(ndev, mbxno);
>> +			num_pkts++;
>> +		} else {
>> +			/* Extract the mboxno from the status */
>> +			bit_set = fls(priv->can_rx_cntx.intr_stat & 0xFF);
>> +			if (bit_set) {
>> +				num_pkts++;
>> +				mbxno = bit_set - 1;
>> +				if (PRUSS_CAN_ISR_BIT_ESI & priv->can_rx_cntx.
>> +				    intr_stat) {

				if (PRUSS_CAN_ISR_BIT_ESI &
				    priv->can_rx_cntx.intr_stat) {

Is more readable.


>> +					pru_can_gbl_stat_get(priv->dev,
>> +						&priv->can_rx_cntx);
>> +						pru_can_err(ndev,
>> +					priv->can_rx_cntx.intr_stat,
>> +					priv->can_rx_cntx.gbl_stat);

Please fix bogous indention.

>> +				} else
>> +					pru_can_rx(ndev, mbxno);
>> +			} else
>> +				break;
>> +		}
>> +	} while (((PRUSS_CAN_TX_INT_STAT & pru_can_get_intc_status(priv->dev))
>> +						&& (num_pkts < quota)));
>> +
>> +	/* Enable packet interrupt if all pkts are handled */
>> +	if (!(PRUSS_CAN_TX_INT_STAT & pru_can_get_intc_status(priv->dev))) {
>> +		napi_complete(napi);
>> +		/* Re-enable RX mailbox interrupts */
>> +		pru_can_mask_ints(priv->dev, PRUSS_CAN_RX_PRU_0, true);
>> +	}
>> +	return num_pkts;
>> +}
...
>> +/* Shows all the mailbox IDs */
>> +static ssize_t pru_sysfs_mbx_id_show(struct device *dev,
>> +		struct device_attribute *attr, char *buf)
>> +{
>> +	struct can_emu_priv *priv = netdev_priv(to_net_dev(dev));
>> +
>> +	return snprintf(buf, PAGE_SIZE, "<mbx_no:mbx_id>\n"
>> +					"0:0x%X 1:0x%X 2:0x%X 3:0x%X "
>> +					"4:0x%X 5:0x%X 6:0x%X 7:0x%X\n",
>> +					priv->mbx_id[0], priv->mbx_id[1],
>> +					priv->mbx_id[2], priv->mbx_id[3],
>> +					priv->mbx_id[4], priv->mbx_id[5],
>> +					priv->mbx_id[6], priv->mbx_id[7]);
>> +}

As mentioned above, just one value per sysfs file, please...

>> +/*
>> + * Sets Mailbox IDs
>> + * This should be programmed as mbx_num:mbx_id (in hex)
>> + * eg: $ echo 0:0x123 > /sys/class/net/can0/mbx_id
>> + */

... which would also avoid string parsing.

>> +static int __devinit pru_can_probe(struct platform_device *pdev)
>> +{
>> +	struct net_device *ndev = NULL;
>> +	const struct da850_evm_pruss_can_data *pdata;
>> +	struct can_emu_priv *priv = NULL;
>> +	struct device *dev = &pdev->dev;
>> +	struct clk *clk_pruss;
>> +	const struct firmware *fw_rx;
>> +	const struct firmware *fw_tx;
>> +	u32 err;
> use int
>> +
>> +	pdata = dev->platform_data;
>> +	if (!pdata) {
>> +		dev_err(&pdev->dev, "platform data not found\n");
>> +		return -EINVAL;
>> +	}
>> +	(pdata->setup)();
> 
> no need fot the ( )
> 
>> +
>> +	ndev = alloc_candev(sizeof(struct can_emu_priv), PRUSS_CAN_MB_MAX + 1);
>> +	if (!ndev) {
>> +		dev_err(&pdev->dev, "alloc_candev failed\n");
>> +		err = -ENOMEM;
>> +		goto probe_exit;
>> +	}
>> +
>> +	ndev->sysfs_groups[0] = &pru_sysfs_attr_group;
>> +
>> +	priv = netdev_priv(ndev);
>> +
>> +	priv->trx_irq = platform_get_irq(to_platform_device(dev->parent), 0);
>> +	if (!priv->trx_irq) {
>> +		dev_err(&pdev->dev, "unable to get pru "
>> +						"interrupt resources!\n");
>> +		err = -ENODEV;
>> +		goto probe_exit;
>> +	}
>> +
>> +	priv->ndev = ndev;
>> +	priv->dev = dev;
>> +
>> +	priv->can.bittiming_const = &pru_can_bittiming_const;
>> +	priv->can.do_set_bittiming = pru_can_set_bittiming;
>> +	priv->can.do_set_mode = pru_can_set_mode;
>> +	priv->can.do_get_state = pru_can_get_state;

Please remove that callback. It's not needed as state changes are
handled properly.

>> +	priv->can_tx_cntx.pruno = PRUSS_CAN_TX_PRU_1;
>> +	priv->can_rx_cntx.pruno = PRUSS_CAN_RX_PRU_0;
>> +
>> +	/* we support local echo, no arp */
>> +	ndev->flags |= (IFF_ECHO | IFF_NOARP);
> 
> no need to se NOARP
> 
>> +
>> +	/* pdev->dev->device_private->driver_data = ndev */
>> +	platform_set_drvdata(pdev, ndev);
>> +	SET_NETDEV_DEV(ndev, &pdev->dev);
>> +	ndev->netdev_ops = &pru_can_netdev_ops;
>> +
>> +	priv->clk_timer = clk_get(&pdev->dev, "pll1_sysclk2");
>> +	if (IS_ERR(priv->clk_timer)) {
>> +		dev_err(&pdev->dev, "no timer clock available\n");
>> +		err = PTR_ERR(priv->clk_timer);
>> +		priv->clk_timer = NULL;
>> +		goto probe_exit_candev;
>> +	}
>> +
>> +	priv->can.clock.freq = clk_get_rate(priv->clk_timer);
>> +
>> +	clk_pruss = clk_get(NULL, "pruss");
>> +	if (IS_ERR(clk_pruss)) {
>> +		dev_err(&pdev->dev, "no clock available: pruss\n");
>> +		err = -ENODEV;
>> +		goto probe_exit_clk;
>> +	}
>> +	priv->clk_freq_pru = clk_get_rate(clk_pruss);
>> +	clk_put(clk_pruss);
> 
> why do you put the clock here?
>> +
>> +	err = register_candev(ndev);
>> +	if (err) {
>> +		dev_err(&pdev->dev, "register_candev() failed\n");
>> +		err = -ENODEV;
>> +		goto probe_exit_clk;
>> +	}
>> +
>> +	err = request_firmware(&fw_tx, "PRU_CAN_Emulation_Tx.bin",
>> +			&pdev->dev);
>> +	if (err) {
>> +		dev_err(&pdev->dev, "can't load firmware\n");
>> +		err = -ENODEV;
>> +		goto probe_exit_clk;
>> +	}
>> +
>> +	dev_info(&pdev->dev, "fw_tx size %d. downloading...\n", fw_tx->size);
>> +
>> +	err = request_firmware(&fw_rx, "PRU_CAN_Emulation_Rx.bin",
>> +			&pdev->dev);
>> +	if (err) {
>> +		dev_err(&pdev->dev, "can't load firmware\n");
>> +		err = -ENODEV;
>> +		goto probe_release_fw;
>> +	}
>> +	dev_info(&pdev->dev, "fw_rx size %d. downloading...\n", fw_rx->size);
>> +
>> +	/* init the pru */
>> +	pru_can_emu_init(priv->dev, priv->can.clock.freq);
>> +	udelay(200);
>> +
>> +	netif_napi_add(ndev, &priv->napi, pru_can_rx_poll,
>> +					PRUSS_DEF_NAPI_WEIGHT);
> 
> personally I'd wait to add the interface to napi until the firmware is
> loaded.
> 
>> +
>> +	pruss_enable(priv->dev, PRUSS_CAN_RX_PRU_0);
>> +	pruss_enable(priv->dev, PRUSS_CAN_TX_PRU_1);
>> +
>> +	/* download firmware into pru */
>> +	err = pruss_load(priv->dev, PRUSS_CAN_RX_PRU_0,
>> +		(u32 *)fw_rx->data, (fw_rx->size / 4));
>> +	if (err) {
>> +		dev_err(&pdev->dev, "firmware download error\n");
>> +		err = -ENODEV;
>> +		goto probe_release_fw_1;
>> +	}
>> +	release_firmware(fw_rx);
>> +	err = pruss_load(priv->dev, PRUSS_CAN_TX_PRU_1,
>> +		(u32 *)fw_tx->data, (fw_tx->size / 4));
>> +	if (err) {
>> +		dev_err(&pdev->dev, "firmware download error\n");
>> +		err = -ENODEV;
>> +		goto probe_release_fw_1;
>> +	}
>> +	release_firmware(fw_tx);
>> +
>> +	pruss_run(priv->dev, PRUSS_CAN_RX_PRU_0);
>> +	pruss_run(priv->dev, PRUSS_CAN_TX_PRU_1);
>> +
>> +	dev_info(&pdev->dev,
>> +		 "%s device registered (trx_irq = %d,  clk = %d)\n",
>> +		 PRUSS_CAN_DRV_NAME, priv->trx_irq, priv->can.clock.freq);
>> +
>> +	return 0;
>> +
>> +probe_release_fw_1:
>> +	release_firmware(fw_rx);
>> +probe_release_fw:
>> +	release_firmware(fw_tx);
>> +probe_exit_clk:
>> +	clk_put(priv->clk_timer);
>> +probe_exit_candev:
>> +	if (NULL != ndev)
>> +		free_candev(ndev);
>> +probe_exit:
>> +	return err;
>> +}

Thanks,

Wolfgang.

^ permalink raw reply

* Re: pull request: wireless-next-2.6 2011-04-25
From: David Miller @ 2011-04-25 20:04 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20110425.125835.189703400.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>

From: David Miller <davem@davemloft.net>
Date: Mon, 25 Apr 2011 12:58:35 -0700 (PDT)

> From: "John W. Linville" <linville@tuxdriver.com>
> Date: Mon, 25 Apr 2011 15:30:17 -0400
> 
>> Here is another big batch of updates intended for 2.6.40...
>> 
>> There is the usual huge batch of changes for ath9k, and iwlagn, a bunch
>> for ath9k_htc, rt2x00, and ath5k, a few more for mwifiex, and a handful
>> of others.  Also included is a big batch of Bluetooth updates as well.
>> 
>> Please let me know if there are problems!
> 
> Pulled, thanks a lot John.

I guess watching the build logs for new warnings is too old fashioned
for people, and besides Dave will do it for everyone anyways right?

And this one is a real bug too. :-/

I'll push this out to net-next-2.6 on top of the wireless-next pull,
but please be more mindful in the future.

--------------------
From bf734843120b905bacc3d24c88d7455ae70bf6e1 Mon Sep 17 00:00:00 2001
From: David S. Miller <davem@davemloft.net>
Date: Mon, 25 Apr 2011 13:03:02 -0700
Subject: [PATCH] bluetooth: Fix use-before-initiailized var.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

net/bluetooth/l2cap_core.c: In function ‘l2cap_recv_frame’:
net/bluetooth/l2cap_core.c:3612:15: warning: ‘sk’ may be used uninitialized in this function
net/bluetooth/l2cap_core.c:3612:15: note: ‘sk’ was declared here

Actually the problem is in the inline function l2cap_data_channel(), we
branch to the label 'done' which tests 'sk' before we set it to anything.

Initialize it to NULL to fix this.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 net/bluetooth/l2cap_core.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d47de2b..8cfa2a6 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3609,7 +3609,7 @@ drop:
 static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
 {
 	struct l2cap_chan *chan;
-	struct sock *sk;
+	struct sock *sk = NULL;
 	struct l2cap_pinfo *pi;
 	u16 control;
 	u8 tx_seq;
-- 
1.7.4.5


^ permalink raw reply related

* Re: pull request: wireless-next-2.6 2011-04-25
From: David Miller @ 2011-04-25 19:58 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20110425193017.GC28814-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>

From: "John W. Linville" <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Date: Mon, 25 Apr 2011 15:30:17 -0400

> Here is another big batch of updates intended for 2.6.40...
> 
> There is the usual huge batch of changes for ath9k, and iwlagn, a bunch
> for ath9k_htc, rt2x00, and ath5k, a few more for mwifiex, and a handful
> of others.  Also included is a big batch of Bluetooth updates as well.
> 
> Please let me know if there are problems!

Pulled, thanks a lot John.
--
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

* pull request: wireless-next-2.6 2011-04-25
From: John W. Linville @ 2011-04-25 19:30 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev

Dave,

Here is another big batch of updates intended for 2.6.40...

There is the usual huge batch of changes for ath9k, and iwlagn, a bunch
for ath9k_htc, rt2x00, and ath5k, a few more for mwifiex, and a handful
of others.  Also included is a big batch of Bluetooth updates as well.

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit b71d1d426d263b0b6cb5760322efebbfc89d4463:

  inet: constify ip headers and in6_addr (2011-04-22 11:04:14 -0700)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git for-davem

Amitkumar Karwar (4):
      mwifiex: cleanup ioctl wait queue and abstraction layer
      mwifiex: remove unused function parameters
      mwifiex: remove some macro definitions
      mwifiex: optimize driver initialization code

Antonio Ospite (1):
      rfkill: Regulator consumer driver for rfkill

Bing Zhao (2):
      mwifiex: fix cmd_skb headroom decreasing issue
      mwifiex: rename function mwifiex_is_ba_stream_avail

Brian Cavagnolo (1):
      mwl8k: use traffic threshold to decide when to start ampdu

Chaoming Li (1):
      rtlwifi: rtl8192ce: Fix LED initialization

Felix Fietkau (23):
      ath9k: fix PS-Poll reception on AR9160 and earlier
      ath9k: fix too early enabling of rx during ath_startrecv()
      ath9k_hw: remove unnecessary parts of the AR9380 SREV check
      ath5k: fix tx status reporting issues
      ath5k: fix short preamble rate duration value
      ath5k: fix SIFS time handling
      ath5k: fix slot time handling
      ath5k: optimize tx descriptor setup
      ath5k: remove ts_rate from ath5k_tx_status
      ath5k: optimize tx status processing
      ath5k: optimize rx status processing
      ath5k: remove ts_retry from ath5k_tx_status
      ath5k: clean up debugfs code
      ath5k: reduce interrupt load caused by rx/tx interrupts
      mac80211: receive EAP frames from a station in an AP VLAN on the main AP
      ath5k: disable 5 GHz support if a 2.4 GHz radio is detected
      ath: unshare struct ath_bus_ops between ath5k and ath9k
      ath5k: add a new bus op for reading the mac address
      ath5k: fix the EEPROM check for hw AES crypto support
      ath5k: disable 5 GHz support for the dualband PHY chip on dual-radio AR5312
      mac80211: add a function for setting the TIM bit for a specific station
      ath9k: fix powersave frame filtering/buffering in AP mode
      ath9k: assign keycache slots to unencrypted stations

Gabor Juhos (1):
      ath9k: introduce ATH9K_{PCI,AHB} config options

Garen Tamrazian (1):
      iwlagn: fix radar frame rejection

Gertjan van Wingerde (6):
      rt2x00: Linksys WUSB600N rev2 is a RT3572 device.
      rt2x00: Allow dynamic addition of PCI/USB IDs.
      rt2x00: Add USB IDs.
      rt2x00: RT33xx device support is no longer experimental.
      rt2x00: Enable support for RT53xx PCI devices by default.
      rt2x00: Merge rt2x00ht.c contents in other files.

Gustavo F. Padovan (26):
      Bluetooth: Create struct l2cap_chan
      Bluetooth: Use struct list_head for L2CAP channels list
      Bluetooth: Remove struct del_list
      Bluetooth: Move ident to struct l2cap_chan
      Bluetooth: Move conf_{req,rsp} stuff to struct l2cap_chan
      Bluetooth: clean up l2cap_sock_recvmsg()
      Bluetooth: Move conn_state to struct l2cap_chan
      Bluetooth: Move of ERTM *_seq vars to struct l2cap_chan
      Bluetooth: Move more ERTM stuff to struct l2cap_chan
      Bluetooth: Move SDU related vars to struct l2cap_chan
      Bluetooth: Move remote info to struct l2cap_chan
      Bluetooth: Move ERTM timers to struct l2cap_chan
      Bluetooth: Move srej and busy queues to struct l2cap_chan
      Bluetooth: Move busy workqueue to struct l2cap_chan
      Bluetooth: Fix lockdep warning with skb list lock
      Bluetooth: Move SREJ list to struct l2cap_chan
      Bluetooth: Remove some sk references from l2cap_core.c
      Bluetooth: Remove unneeded uninitialized_vars()
      Bluetooth: Move tx queue to struct l2cap_chan
      Bluetooth: Fix wrong comparison in listen()
      Bluetooth: Clean up ath3k_load_firmware()
      Bluetooth: Add proper handling of received LE data
      Bluetooth: Check return value of hci_recv_stream_fragment()
      Bluetooth: Don't lock sock inside l2cap_get_sock_by_scid()
      Bluetooth: Fix another locking unbalance
      Bluetooth: Fix lockdep warning in L2CAP

Helmut Schaa (7):
      rt2x00: Fix stuck queue in tx failure case
      rt2x00: Make rt2x00_queue_entry_for_each more flexible
      rt2x00: Use correct TBTT_SYNC config in AP mode
      rt2x00: Update TX_SW_CFG2 init value
      rt2x00: Use TXOP_HTTXOP for beacons
      rt2x00: Always inline rt2x00pci_enable_interrupt
      rt2x00: Optimize register access in rt2800pci

Ivo van Doorn (5):
      rt2x00: Split rt2x00dev->flags
      rt2x00: Decrease association time for USB devices
      rt2x00: Optimize register access in rt2800usb
      rt2x00: Implement get_ringparam callback function
      rt2x00: Implement get_antenna and set_antenna callback functions

Javier Cardona (9):
      nl80211: rename NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE
      cfg80211/nl80211: Add userspace authentication flag to mesh setup
      mac80211: ignore peers if security is enabled for this mesh
      nl80211/mac80211: let userspace authenticate stations
      mac80211: Let user space receive and send mesh auth/deauth frames
      mac80211: ignore peer link requests from unauthenticated stations.
      nl80211/mac80211: Perform PLINK_ACTION on new station
      nl80211: New notification to discover mesh peer candidates.
      mac80211: send notification on new peer candidate for our secure mesh

Jiejing Zhang (1):
      Bluetooth: hci_uart: check the return value of recv()

Johannes Berg (7):
      iwlwifi: fix bugs in change_interface
      iwlagn: clean up & autodetect statistics
      iwlagn: downgrade warning on unknown TLV
      iwlagn: remove most BUG_ON instances
      iwlagn: verify that huge commands are synchronous
      iwlagn: use huge command for beacon
      mac80211: explain padding in place of rate field

Johannes Stezenbach (4):
      rt2800usb: read TX_STA_FIFO asynchronously
      rt2x00: fix queue timeout checks
      rt2800usb: handle TX status timeouts
      rt2800usb: add timer to handle TX_STA_FIFO

John W. Linville (6):
      ath5k: improve pcal error handling for ENOMEM case
      ath5k: improve comments for optimized tx descriptor setup
      ath9k: avoid using trinary operator w/ TX_STAT_INC
      Merge branch 'wireless-next-2.6' of git://git.kernel.org/.../iwlwifi/iwlwifi-2.6
      Merge branch 'master' of git://git.kernel.org/.../padovan/bluetooth-next-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6 into for-davem

Kevin Gan (1):
      Bluetooth: btmrvl: support Marvell Bluetooth device SD8787

Larry Finger (1):
      rtlwifi: Fix unitialized variable warnings

Layne Edwards (1):
      rt2x00: Enable WLAN LED on Ralink SoC (rt305x) devices

Luis R. Rodriguez (1):
      ath: fix 0x6C for beaconing/passive scan flags based on country IE

Mark Davis (1):
      rt2800usb: Add seven new USB IDs

Mohammed Shafi Shajakhan (1):
      {mac|nl}80211: Add station connected time

Nishant Sarmukadam (1):
      mwl8k: interrupt handling changes

Paul Bolle (1):
      iwl4965: drop a lone pr_err()

Rajkumar Manoharan (10):
      ath9k_hw: Fix instable target power control b/w CCK/OFDM
      ath9k: Fix kernel panic on module unload
      ath9k_hw: Remove unused code in AR9287 eeprom
      ath9k_hw: update Ar9003 intervals to fix carrier leak
      ath9k_hw: update AR9003 low_ob_db_tx_gain to improve spur performance
      ath9k: Fix improper beacon slot selection in IBSS
      ath9k_htc: Add debugfs support to change debug mask
      ath9k_htc: Cleanup HTC debugfs
      ath9k_htc: Fix free slot value for cab queue
      ath9k: Fix beacon generation on foreign channel

Randy Dunlap (1):
      mac80211: fix debugfs printk format warning

Senthil Balasubramanian (3):
      ath9k: Add RSSI information from control and extension chains
      ath9k: Update gain table for AR9485
      ath: Add a missing world regulatory domain 0x6C

Sergei Shtylyov (1):
      iwlegacy: use pci_dev->revision

Sujith Manoharan (40):
      ath9k_htc: Remove AR7010 v1.0 support
      ath9k_htc: Rename firmware
      ath9k_htc: Add a WMI command to get the firmware version
      ath9k_htc: Fix WMI and beacon header
      ath9k_htc: Add beacon slots
      ath9k_htc: Add TSF adjust capability
      ath9k_htc: Configure the beacon queue
      ath9k_htc: Handle buffered frames in AP mode
      ath9k_htc: Fix beacon miss under heavy load
      ath9k_htc: Queue WMI events
      ath9k_htc: Move debug code to a separate file
      ath9k_htc: Add RX error statistics
      ath9k_htc: Fix RX length check
      ath9k_htc: Remove unused WMI commands
      ath9k_htc: Use SKB's private area for TX parameters
      ath9k_htc: Sync struct ath9k_htc_target_sta with FW
      ath9k_htc: Sync struct ath9k_htc_target_vif with FW
      ath9k_htc: Sync struct ath9k_htc_cap_target with FW
      ath9k_htc: Remove unused WMI_WLAN_TXCOMP_EVENTID
      ath9k_htc: Move TX specific stuff to a separate structure
      ath9k_htc: Reduce TX queue size
      ath9k_htc: Sync MGMT/DATA packet headers with firmware
      ath9k_htc: Add a new WMI event WMI_TXSTATUS_EVENTID
      ath9k_htc: Increase URB count for REG_IN pipe
      ath9k_htc: Fix TX queue management
      ath9k_htc: Introduce new HTC API
      ath9k_htc: Move endpoint header parsing to TX tasklet
      ath9k_htc: Add TX slots
      ath9k_htc: Use helper functions for TX processing
      ath9k_htc: Drain pending TX frames properly
      ath9k_htc: Optimize HTC start/stop API
      ath9k_htc: Drain packets on station removal
      ath9k_htc: Add support for TX completion
      ath9k_htc: Add a debugfs file to dump TX slot information
      ath9k_htc: Add a debugfs file showing endpoint status
      ath9k_htc: Add a timer to cleanup WMI events
      ath9k_htc: Use separate URB pool for management frames
      ath9k_htc: Use helper routines for transmission
      ath9k_htc: Add detailed firmware statistics
      ath9k_htc: Enable AP and P2P modes

Szymon Janc (1):
      Bluetooth: Fix Out Of Band pairing when mgmt interface is disabled

Vasanthakumar Thiagarajan (2):
      ath9k: Implement integer mode for AR9485
      ath9k: Register id table for platform device

Vivek Natarajan (2):
      mac80211: Check for queued frames before entering power save.
      ath9k: Implement dev_tx_frames_pending callback.

Wey-Yi Guy (18):
      iwlagn: remove un-necessary function pointer
      iwlagn: PAPD read for 2000 series devices
      iwlagn: no 3945 define needed
      iwlagn: remove unused 3945 define
      iwlagn: cleanup to remove the reference for 3945
      iwlagn: remove more reference to legacy devices
      iwlagn: remove un-needed configuration
      iwlagn: more cleanup to remove unused reference
      iwlagn: all _agn devices support power save mode
      iwlagn: tx power calib always done in firmware
      iwlagn: sensitivity and chain noise done by driver
      iwlagn: use direct call for led functions
      iwlagn: always support uCode trace
      iwlagn: temperature should be measure for all _agn devices
      iwlagn: no 5.2GHz/HT40 support for bgn devices
      iwlagn: remove un-necessary ieee80211_ops
      iwlagn: remove legacy ops
      iwlagn: remove led_ops

Yogesh Ashok Powar (4):
      mwifiex: use common keyinfo bitmap for different key types
      mwl8k: Fix checkpatch.pl and sparse warnings and errors
      mwifiex: remove redundant "return" at end of void function
      mwifiex: remove redundant local variables and comments

cozybit Inc (1):
      mac80211: Allocate new mesh path and portal tables before taking locks

roel (2):
      ath9k_hw: index out of bounds
      ath9k: index out of bounds

root (1):
      iwlwifi: remove extranious macro from firmware define

 drivers/bluetooth/Kconfig                          |    4 +-
 drivers/bluetooth/ath3k.c                          |    3 -
 drivers/bluetooth/btmrvl_sdio.c                    |  124 ++-
 drivers/bluetooth/btmrvl_sdio.h                    |   68 +-
 drivers/bluetooth/hci_ath.c                        |    7 +-
 drivers/bluetooth/hci_h4.c                         |    7 +-
 drivers/bluetooth/hci_ldisc.c                      |    6 +-
 drivers/net/wireless/ath/ath.h                     |    9 +-
 drivers/net/wireless/ath/ath5k/ahb.c               |   28 +
 drivers/net/wireless/ath/ath5k/ath5k.h             |   31 +-
 drivers/net/wireless/ath/ath5k/attach.c            |    7 +-
 drivers/net/wireless/ath/ath5k/base.c              |   71 +-
 drivers/net/wireless/ath/ath5k/base.h              |    7 +-
 drivers/net/wireless/ath/ath5k/caps.c              |    3 +
 drivers/net/wireless/ath/ath5k/debug.c             |   65 +-
 drivers/net/wireless/ath/ath5k/debug.h             |   17 -
 drivers/net/wireless/ath/ath5k/desc.c              |  158 +--
 drivers/net/wireless/ath/ath5k/eeprom.c            |  158 +--
 drivers/net/wireless/ath/ath5k/mac80211-ops.c      |    9 +
 drivers/net/wireless/ath/ath5k/pci.c               |   32 +
 drivers/net/wireless/ath/ath5k/pcu.c               |   35 +-
 drivers/net/wireless/ath/ath5k/qcu.c               |    4 +-
 drivers/net/wireless/ath/ath9k/Kconfig             |   21 +-
 drivers/net/wireless/ath/ath9k/Makefile            |    6 +-
 drivers/net/wireless/ath/ath9k/ahb.c               |   14 +-
 drivers/net/wireless/ath/ath9k/ar9002_mac.c        |   12 +-
 drivers/net/wireless/ath/ath9k/ar9002_phy.h        |    6 +
 .../net/wireless/ath/ath9k/ar9003_2p2_initvals.h   |  178 ++--
 drivers/net/wireless/ath/ath9k/ar9003_mac.c        |   12 +-
 drivers/net/wireless/ath/ath9k/ar9003_phy.c        |   17 +-
 drivers/net/wireless/ath/ath9k/ar9485_initvals.h   |   10 +-
 drivers/net/wireless/ath/ath9k/ath9k.h             |   12 +-
 drivers/net/wireless/ath/ath9k/beacon.c            |   44 +-
 drivers/net/wireless/ath/ath9k/debug.c             |   40 +-
 drivers/net/wireless/ath/ath9k/debug.h             |    7 +
 drivers/net/wireless/ath/ath9k/eeprom.h            |    6 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c         |   26 +
 drivers/net/wireless/ath/ath9k/eeprom_9287.c       |   25 +-
 drivers/net/wireless/ath/ath9k/hif_usb.c           |  334 ++++--
 drivers/net/wireless/ath/ath9k/hif_usb.h           |    7 +-
 drivers/net/wireless/ath/ath9k/htc.h               |  211 ++-
 drivers/net/wireless/ath/ath9k/htc_drv_beacon.c    |  318 ++++-
 drivers/net/wireless/ath/ath9k/htc_drv_debug.c     |  505 ++++++++
 drivers/net/wireless/ath/ath9k/htc_drv_gpio.c      |   12 +-
 drivers/net/wireless/ath/ath9k/htc_drv_init.c      |   91 +-
 drivers/net/wireless/ath/ath9k/htc_drv_main.c      |  322 ++----
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c      |  790 +++++++++---
 drivers/net/wireless/ath/ath9k/htc_hst.c           |   50 +-
 drivers/net/wireless/ath/ath9k/htc_hst.h           |   14 +-
 drivers/net/wireless/ath/ath9k/hw-ops.h            |    5 +
 drivers/net/wireless/ath/ath9k/hw.c                |   45 +-
 drivers/net/wireless/ath/ath9k/hw.h                |    9 +
 drivers/net/wireless/ath/ath9k/mac.h               |    1 -
 drivers/net/wireless/ath/ath9k/main.c              |   63 +
 drivers/net/wireless/ath/ath9k/phy.h               |    1 -
 drivers/net/wireless/ath/ath9k/rc.c                |    3 +-
 drivers/net/wireless/ath/ath9k/recv.c              |    6 +-
 drivers/net/wireless/ath/ath9k/reg.h               |   35 +-
 drivers/net/wireless/ath/ath9k/wmi.c               |  122 ++-
 drivers/net/wireless/ath/ath9k/wmi.h               |   80 +-
 drivers/net/wireless/ath/ath9k/xmit.c              |  111 ++-
 drivers/net/wireless/ath/key.c                     |    6 +-
 drivers/net/wireless/ath/regd.c                    |    8 +-
 drivers/net/wireless/ath/regd_common.h             |    2 +
 drivers/net/wireless/iwlegacy/iwl-4965-rs.c        |    1 -
 drivers/net/wireless/iwlegacy/iwl4965-base.c       |    2 +-
 drivers/net/wireless/iwlwifi/Makefile              |    2 +-
 drivers/net/wireless/iwlwifi/iwl-1000.c            |   24 +-
 drivers/net/wireless/iwlwifi/iwl-2000.c            |   43 +-
 drivers/net/wireless/iwlwifi/iwl-5000.c            |   34 +-
 drivers/net/wireless/iwlwifi/iwl-6000.c            |   52 +-
 drivers/net/wireless/iwlwifi/iwl-agn-calib.c       |   43 +-
 drivers/net/wireless/iwlwifi/iwl-agn-calib.h       |    4 +-
 drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c     |  134 +--
 drivers/net/wireless/iwlwifi/iwl-agn-led.c         |   73 --
 drivers/net/wireless/iwlwifi/iwl-agn-led.h         |   33 -
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c         |   39 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rs.h          |    1 -
 drivers/net/wireless/iwlwifi/iwl-agn-rxon.c        |   13 +
 drivers/net/wireless/iwlwifi/iwl-agn-ucode.c       |    3 +
 drivers/net/wireless/iwlwifi/iwl-agn.c             |   66 +-
 drivers/net/wireless/iwlwifi/iwl-agn.h             |    3 +-
 drivers/net/wireless/iwlwifi/iwl-commands.h        |   64 -
 drivers/net/wireless/iwlwifi/iwl-core.c            |   71 +-
 drivers/net/wireless/iwlwifi/iwl-core.h            |   56 +-
 drivers/net/wireless/iwlwifi/iwl-debugfs.c         |   53 +-
 drivers/net/wireless/iwlwifi/iwl-dev.h             |   44 +-
 drivers/net/wireless/iwlwifi/iwl-eeprom.c          |    6 -
 drivers/net/wireless/iwlwifi/iwl-eeprom.h          |    1 -
 drivers/net/wireless/iwlwifi/iwl-fh.h              |   38 +-
 drivers/net/wireless/iwlwifi/iwl-hcmd.c            |   12 +-
 drivers/net/wireless/iwlwifi/iwl-helpers.h         |   13 +
 drivers/net/wireless/iwlwifi/iwl-led.c             |   30 +-
 drivers/net/wireless/iwlwifi/iwl-led.h             |    1 +
 drivers/net/wireless/iwlwifi/iwl-power.c           |   17 +-
 drivers/net/wireless/iwlwifi/iwl-prph.h            |   16 +-
 drivers/net/wireless/iwlwifi/iwl-rx.c              |  319 +++---
 drivers/net/wireless/iwlwifi/iwl-sta.c             |    9 +-
 drivers/net/wireless/iwlwifi/iwl-tx.c              |   39 +-
 drivers/net/wireless/mwifiex/11n.c                 |   34 +-
 drivers/net/wireless/mwifiex/11n.h                 |   53 +-
 drivers/net/wireless/mwifiex/11n_aggr.c            |    5 +-
 drivers/net/wireless/mwifiex/11n_rxreorder.c       |   36 +-
 drivers/net/wireless/mwifiex/11n_rxreorder.h       |    6 +-
 drivers/net/wireless/mwifiex/README                |    2 +-
 drivers/net/wireless/mwifiex/cfg80211.c            |  224 ++---
 drivers/net/wireless/mwifiex/cfp.c                 |   17 +-
 drivers/net/wireless/mwifiex/cmdevt.c              |  194 ++--
 drivers/net/wireless/mwifiex/debugfs.c             |    7 +-
 drivers/net/wireless/mwifiex/decl.h                |   38 +-
 drivers/net/wireless/mwifiex/fw.h                  |   29 +-
 drivers/net/wireless/mwifiex/init.c                |   14 +-
 drivers/net/wireless/mwifiex/ioctl.h               |    3 +-
 drivers/net/wireless/mwifiex/join.c                |  128 +--
 drivers/net/wireless/mwifiex/main.c                |  174 +--
 drivers/net/wireless/mwifiex/main.h                |  142 +--
 drivers/net/wireless/mwifiex/scan.c                |  154 +--
 drivers/net/wireless/mwifiex/sdio.c                |   49 +-
 drivers/net/wireless/mwifiex/sta_cmd.c             |  127 +-
 drivers/net/wireless/mwifiex/sta_cmdresp.c         |   47 +-
 drivers/net/wireless/mwifiex/sta_event.c           |   25 +-
 drivers/net/wireless/mwifiex/sta_ioctl.c           | 1081 +++-------------
 drivers/net/wireless/mwifiex/sta_tx.c              |    8 +-
 drivers/net/wireless/mwifiex/txrx.c                |    4 +-
 drivers/net/wireless/mwifiex/util.c                |   55 +-
 drivers/net/wireless/mwifiex/wmm.c                 |   24 +-
 drivers/net/wireless/mwifiex/wmm.h                 |    8 +-
 drivers/net/wireless/mwl8k.c                       |   77 +-
 drivers/net/wireless/rt2x00/Kconfig                |   26 +-
 drivers/net/wireless/rt2x00/Makefile               |    1 -
 drivers/net/wireless/rt2x00/rt2400pci.c            |   29 +-
 drivers/net/wireless/rt2x00/rt2500pci.c            |   28 +-
 drivers/net/wireless/rt2x00/rt2500usb.c            |   85 +-
 drivers/net/wireless/rt2x00/rt2800lib.c            |  135 ++-
 drivers/net/wireless/rt2x00/rt2800pci.c            |  244 ++--
 drivers/net/wireless/rt2x00/rt2800usb.c            |  621 ++++++----
 drivers/net/wireless/rt2x00/rt2x00.h               |   97 +-
 drivers/net/wireless/rt2x00/rt2x00config.c         |   77 +-
 drivers/net/wireless/rt2x00/rt2x00crypto.c         |    4 +-
 drivers/net/wireless/rt2x00/rt2x00debug.c          |   42 +-
 drivers/net/wireless/rt2x00/rt2x00dev.c            |   23 +-
 drivers/net/wireless/rt2x00/rt2x00firmware.c       |    2 +-
 drivers/net/wireless/rt2x00/rt2x00ht.c             |  136 --
 drivers/net/wireless/rt2x00/rt2x00lib.h            |   34 +-
 drivers/net/wireless/rt2x00/rt2x00link.c           |   12 +-
 drivers/net/wireless/rt2x00/rt2x00mac.c            |   95 ++-
 drivers/net/wireless/rt2x00/rt2x00pci.c            |   12 +-
 drivers/net/wireless/rt2x00/rt2x00pci.h            |   12 +-
 drivers/net/wireless/rt2x00/rt2x00queue.c          |  159 ++-
 drivers/net/wireless/rt2x00/rt2x00queue.h          |   33 +-
 drivers/net/wireless/rt2x00/rt2x00usb.c            |  126 ++-
 drivers/net/wireless/rt2x00/rt2x00usb.h            |   31 +-
 drivers/net/wireless/rt2x00/rt61pci.c              |   64 +-
 drivers/net/wireless/rt2x00/rt73usb.c              |  189 ++--
 drivers/net/wireless/rtlwifi/base.c                |   12 +-
 drivers/net/wireless/rtlwifi/pci.c                 |    3 +-
 drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c  |    2 +-
 drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c  |    2 +-
 drivers/net/wireless/rtlwifi/rtl8192ce/led.c       |   14 +-
 drivers/net/wireless/rtlwifi/rtl8192ce/led.h       |    1 -
 drivers/net/wireless/rtlwifi/rtl8192ce/rf.c        |    4 +-
 drivers/net/wireless/rtlwifi/rtl8192ce/sw.c        |    1 -
 drivers/net/wireless/rtlwifi/rtl8192cu/hw.c        |    2 +-
 include/linux/nl80211.h                            |   34 +-
 include/linux/rfkill-regulator.h                   |   48 +
 include/net/bluetooth/l2cap.h                      |  130 +-
 include/net/cfg80211.h                             |   33 +-
 include/net/mac80211.h                             |   16 +
 net/bluetooth/hci_event.c                          |    4 +
 net/bluetooth/l2cap_core.c                         | 1344 +++++++++++---------
 net/bluetooth/l2cap_sock.c                         |   72 +-
 net/mac80211/cfg.c                                 |   29 +-
 net/mac80211/debugfs_sta.c                         |   26 +
 net/mac80211/driver-ops.h                          |   13 +
 net/mac80211/driver-trace.h                        |   20 +
 net/mac80211/ieee80211_i.h                         |    5 +-
 net/mac80211/main.c                                |    9 +-
 net/mac80211/mesh.c                                |   14 +-
 net/mac80211/mesh.h                                |    3 +-
 net/mac80211/mesh_pathtbl.c                        |   49 +-
 net/mac80211/mesh_plink.c                          |   35 +-
 net/mac80211/mlme.c                                |   17 +-
 net/mac80211/rx.c                                  |   26 +-
 net/mac80211/sta_info.c                            |   16 +-
 net/mac80211/sta_info.h                            |    5 +
 net/mac80211/tx.c                                  |    2 +-
 net/rfkill/Kconfig                                 |   11 +
 net/rfkill/Makefile                                |    1 +
 net/rfkill/rfkill-regulator.c                      |  164 +++
 net/wireless/mesh.c                                |   23 +-
 net/wireless/nl80211.c                             |   67 +-
 net/wireless/nl80211.h                             |    4 +
 192 files changed, 7204 insertions(+), 5938 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/htc_drv_debug.c
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-led.c
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-led.h
 delete mode 100644 drivers/net/wireless/rt2x00/rt2x00ht.c
 create mode 100644 include/linux/rfkill-regulator.h
 create mode 100644 net/rfkill/rfkill-regulator.c

Omnibus patch available here:

	http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2011-04-25.patch.bz2

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [PATCH net-next-2.6] be2net: Fixed a bug in be_cmd_get_regs().
From: David Miller @ 2011-04-25 19:14 UTC (permalink / raw)
  To: somnath.kotur; +Cc: netdev
In-Reply-To: <8a31447a-9317-4569-ae2b-865feb9ce594@exht1.ad.emulex.com>

From: Somnath Kotur <somnath.kotur@emulex.com>
Date: Thu, 21 Apr 2011 18:48:12 +0530

> Resending patch as the 'changelog' got missed out in my previous submission.
> 
> Same WRB entry was being reused over different iterations of a 
> loop while issuing non-embedded IOCTL requests.Fixed couple of minor bugs 
> in this path as well.
> Re-factored code to alloc/free memory for DMA outside of loop
> 
> 
> Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>

Applied, thanks.

^ permalink raw reply

* Re: [patch net-next-2.6] bonding: move processing of recv handlers into handle_frame()
From: David Miller @ 2011-04-25 19:00 UTC (permalink / raw)
  To: jpirko
  Cc: netdev, shemminger, kaber, fubar, eric.dumazet, nicolas.2p.debian,
	andy
In-Reply-To: <1303220896-9092-1-git-send-email-jpirko@redhat.com>

From: Jiri Pirko <jpirko@redhat.com>
Date: Tue, 19 Apr 2011 15:48:16 +0200

> Since now when bonding uses rx_handler, all traffic going into bond
> device goes thru bond_handle_frame. So there's no need to go back into
> bonding code later via ptype handlers. This patch converts
> original ptype handlers into "bonding receive probes". These functions
> are called from bond_handle_frame and they are registered per-mode.
> 
> Note that vlan packets are also handled because they are always untagged
> thanks to vlan_untag()
> 
> Note that this also allows arpmon for eth-bond-bridge-vlan topology.
> 
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] net: make WARN_ON in dev_disable_lro() useful
From: David Miller @ 2011-04-25 18:56 UTC (permalink / raw)
  To: eric.dumazet; +Cc: mirq-linux, netdev
In-Reply-To: <1303449113.13893.2.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 22 Apr 2011 07:11:53 +0200

> Le vendredi 22 avril 2011 à 00:42 +0200, Michał Mirosław a écrit :
>> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>> ---
>>  net/core/dev.c |    3 ++-
>>  1 files changed, 2 insertions(+), 1 deletions(-)
>> 
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 3871bf6..3421184 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -1315,7 +1315,8 @@ void dev_disable_lro(struct net_device *dev)
>>  		return;
>>  
>>  	__ethtool_set_flags(dev, flags & ~ETH_FLAG_LRO);
>> -	WARN_ON(dev->features & NETIF_F_LRO);
>> +	if (unlikely(dev->features & NETIF_F_LRO))
>> +		netdev_WARN(dev, "failed to disable LRO!\n");
>>  }
>>  EXPORT_SYMBOL(dev_disable_lro);
>>  
> 
> Yes, as suggested one month ago
> http://permalink.gmane.org/gmane.linux.network/189951
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied, thanks.

^ permalink raw reply

* Re: Oops in 2.6.39 include/net/dst.h: dst_metrics_write_ptr() running l2tp over ipsec
From: David Miller @ 2011-04-25 18:54 UTC (permalink / raw)
  To: berny156; +Cc: eric.dumazet, linux-kernel, netdev
In-Reply-To: <4DB54450.90806@gmx.de>

From: Held Bernhard <berny156@gmx.de>
Date: Mon, 25 Apr 2011 11:52:16 +0200

> Am 25.04.2011 10:07, schrieb Eric Dumazet:
>> From: Held Bernhard<berny156@gmx.de>
 ...
>> Thanks for your report and patch.
>>
>> Maybe following patch is the way to fix this, please test it.
>>
>>
>> [PATCH] net: provide cow_metrics() methods to blackhole dst_ops
 ...
>> The oops happens in dst_metrics_write_ptr()
>> include/net/dst.h:124: return dst->ops->cow_metrics(dst, p);
>>
>> dst->ops->cow_metrics is NULL and causes the oops.
>>
>> Provide cow_metrics() methods, like we did in commit 214f45c91bb
>> (net: provide default_advmss() methods to blackhole dst_ops)
>>
>> Signed-off-by: Held Bernhard<berny156@gmx.de>
>> Signed-off-by: Eric Dumazet<eric.dumazet@gmail.com>
 ...
> Your patch works flawlessly.
> 
> Thanks for the quick response!

Applied, thanks everyone.

^ permalink raw reply

* Re: [PATCHv5] usbnet: Resubmit interrupt URB once if halted
From: Paul Stewart @ 2011-04-25 18:41 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: Alan Stern, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	bhutchings-s/n/eUQHGBpZroRs9YW3xA
In-Reply-To: <201104240836.47491.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>

On Sat, Apr 23, 2011 at 11:36 PM, Oliver Neukum <oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org> wrote:
> Am Freitag, 22. April 2011, 17:59:15 schrieb Paul Stewart:
>> >
>> >>       free_netdev(net);
>> >>       usb_put_dev (xdev);
>> >>  }
>> >> @@ -1285,6 +1291,10 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
>> >>                * wake the device
>> >>                */
>> >>               netif_device_attach (dev->net);
>> >> +
>> >> +             /* Stop interrupt URBs */
>> >> +             if (dev->interrupt)
>> >> +                     usb_kill_urb(dev->interrupt);
>> >>       }
>> >>       return 0;
>> >>  }
>> >
>> > There is a subtle question here: When is the best time to kill the
>> > interrupt URB?  Without knowing any of the details, I'd guess that the
>> > interrupt URB reports asynchronous events and the driver could run into
>> > trouble if one of those events occurred while everything else was
>> > turned off.  This suggests that the interrupt URB should be killed as
>> > soon as possible rather than as late as possible.  But maybe it doesn't
>> > matter; it all depends on the design of the driver.
>>
>> I'm not sure I can answer this question either.  As it stands, nobody
>> was killing them before.  Just trying to make it better.
>
> Hm. Are we looking at the same code?

Perhaps not.  I'm working out of the netdev-2.6 git repository.  Is
this the wrong place?

> usbnet_suspend now has:
>
>                /*
>                 * accelerate emptying of the rx and queues, to avoid
>                 * having everything error out.
>                 */
>                netif_device_detach (dev->net);
>                usbnet_terminate_urbs(dev);
>                usb_kill_urb(dev->interrupt);
>
> This suggests that if you want to resubmit the interrupt URB in resume()
> you do it first. Which drivers use the interrupt URB?

The asix driver uses it fo signal link status.

>
>        Regards
>                Oliver
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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 2/9] net-ethtool: Convert (hw_/vlan_/wanted_)features fields from u32 type to u64.
From: Mahesh Bandewar @ 2011-04-25 18:14 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev, Michał Mirosław
In-Reply-To: <1303623041.3032.97.camel@localhost>

On Sat, Apr 23, 2011 at 10:30 PM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
> On Fri, 2011-04-22 at 16:36 -0700, Mahesh Bandewar wrote:
>> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
>> ---
>>  include/linux/ethtool.h |   26 +++++++------
>>  net/core/ethtool.c      |   89 ++++++++++++++++------------------------------
>>  2 files changed, 45 insertions(+), 70 deletions(-)
>>
>> diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
>> index 9de3127..71e8a02 100644
>> --- a/include/linux/ethtool.h
>> +++ b/include/linux/ethtool.h
>> @@ -605,10 +605,10 @@ struct ethtool_flash {
>>   * @never_changed: mask of features not changeable for any device
>>   */
>>  struct ethtool_get_features_block {
>> -     __u32   available;
>> -     __u32   requested;
>> -     __u32   active;
>> -     __u32   never_changed;
>> +     __u64   available;
>> +     __u64   requested;
>> +     __u64   active;
>> +     __u64   never_changed;
>>  };
>>
>>  /**
>> @@ -618,10 +618,11 @@ struct ethtool_get_features_block {
>>   *       out: number of elements in features[] needed to hold all features
>>   * @features: state of features
>>   */
>> +/* TODO Why is this needed XXX */
>
> Precisely to allow for expansion to more than 32 bits.
>
:) That comment was not supposed to be part of the patch and was just
to aid my thinking while we were discussing about the approach to
extend features. (I thought) if we have decided not to use use arrays,
then why to complicate this interface, so was attempting to simplify
the interface.

>>  struct ethtool_gfeatures {
>>       __u32   cmd;
>>       __u32   size;
>> -     struct ethtool_get_features_block features[0];
>> +     struct ethtool_get_features_block features;
>>  };
>>
>>  /**
>> @@ -630,8 +631,8 @@ struct ethtool_gfeatures {
>>   * @requested: values of features to be changed
>>   */
>>  struct ethtool_set_features_block {
>> -     __u32   valid;
>> -     __u32   requested;
>> +     __u64   valid;
>> +     __u64   requested;
>>  };
>>
>>  /**
>> @@ -640,10 +641,11 @@ struct ethtool_set_features_block {
>>   * @size: array size of the features[] array
>>   * @features: feature change masks
>>   */
>> +/* TODO Why is this needed XXX */
>>  struct ethtool_sfeatures {
>>       __u32   cmd;
>>       __u32   size;
>> -     struct ethtool_set_features_block features[0];
>> +     struct ethtool_set_features_block features;
>>  };
> [...]
>
> These structures are part of the userland API, but they are new in
> 2.6.39.  So they can still be changed up until 2.6.39 is released, but
> not afterwards.
>
got it!

> If we think 64 bits will be enough for the next 10 years, then let's
> just go with a single 64-bit feature word.  If we're not so sure then
> then the ethtool API should continue to allow for multiple words
> (whether 32-bit or 64-bit).
>
I think even 64 bits may not be enough, so in the earlier thread I had
mentioned that, this would (probably) give us next two years! I didn't
know this constraint though.

--mahesh..

> Ben.
>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
>

^ permalink raw reply

* ar9280+802.11na+ath9k+kismet don't capture data packets
From: Антон @ 2011-04-25 17:54 UTC (permalink / raw)
  To: netdev

Hello!

The platform uses D-link DIR-825 Atheros AR7161, with two AR9280(802.11bgn and 802.11an)
kismet-2010-07-R1 is installed to OpenWrt Backfire Trunk. Used driver ath9k of compat-wireless-2011-04-19.
For tests I use D-Link Dir-825 AP and D-Link DWA-160. Connection speed is 300 Mbps at 36 channel.
Kismet captures PHY and Control packets, and don't capture the data packets.

/etc/config/wireless

config wifi-device radio0
option type mac80211
option channel 11
option macaddr 00:18:e7:ec:b0:5f
option hwmode 11ng
option hwmode_11n g
option htmode HT40+
list ht_capab HT40-
list ht_capab HT40+
list ht_capab HT20

config wifi-iface
option device radio0
option mode monitor

config wifi-device radio1
option type mac80211
option channel 36
option macaddr 00:18:e7:ec:b0:60
option hwmode 11na
option hwmode_11n a
option htmode HT40+
list ht_capab HT40-
list ht_capab HT40+
list ht_capab HT20

config wifi-iface
option device radio1
option mode monitor

device wlan0 entered promiscuous mode
device wlan1 entered promiscuous mode

iwconfig

wlan0 IEEE 802.11bgn Mode:Monitor Tx-Power=27 dBm
RTS thr:off Fragment thr:off
Power Management:on

wlan1 IEEE 802.11an Mode:Monitor Tx-Power=17 dBm
RTS thr:off Fragment thr:off
Power Management:on

Transferred to file 600 Mb
After that ifconfig issued:
ifconfig
wlan0 Link encap:UNSPEC HWaddr 00-18-E7-EC-B0-5F-00-47-00-00-00-00-00-00-0
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:9865 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3043414 (2.9 MiB) TX bytes:0 (0.0 B)

wlan1 Link encap:UNSPEC HWaddr 00-18-E7-EC-B0-60-00-47-00-00-00-00-00-00-0
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:365275 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:20117793 (19.1 MiB) TX bytes:0 (0.0 B)

Sniffing result:
MAC Src                  MAC Dst                Channel Signal Type Crypt                     Packets SSID
00:18:E7:FD:8E:D8   00:19:5B:7E:09:CE  6          -42      AP    WEP                    7629      q183
00:18:E7:FD:8E:DA  F0:7D:68:71:40:DC  36         -60      AP    TKIP WPA PSK... 1703      q183-media
1C:65:9D:21:27:8F    00:18:E7:FD:8E:D8   6         -65      AP     WEP                    2607      q183
00:00:00:00:00:00     00:18:E7:FD:8E:D8   -          -65      AP     -                           370415   -
00:19:5B:7E:09:CE   00:18:E7:FD:8E:D8   -          -67      Probe WEP                    124        q183
F0:7D:68:71:40:DC   00:18:E7:FD:8E:DA   -          -39     AP      TKIP WPA PSK... 41          q183-media

Captures the driver ath9k data packets in the mode 802.11na? Can be said about this with 100% certainty? Checked it?

^ permalink raw reply

* Re: Linux TCP's Robustness to Multipath Packet Reordering
From: Eric Dumazet @ 2011-04-25 15:38 UTC (permalink / raw)
  To: Dominik Kaspar; +Cc: Carsten Wolff, netdev
In-Reply-To: <BANLkTi=xns1Gdjyt-SX3yDETSQfO23rXXg@mail.gmail.com>

Le lundi 25 avril 2011 à 16:35 +0200, Dominik Kaspar a écrit :
> Hi Eric and Carsten,
> 
> Thanks a lot for your quick replies. I don't have a tcpdump of this
> experiment, but here is the tcp_probe log that the plot is based on
> (I'll run a new test using tcpdump if you think that's more useful):
> 
> http://home.simula.no/~kaspar/static/mptcp-emu-wlan-hspa-00.log
> 
> I have also noticed what Carsten mentions, the tcp_reordering value is
> essential for this whole behavior. When I start an experiment and
> increase sysctl.net.ipv4.tcp_reordering during the running connection,
> the TCP throughput immediately jumps close to the aggregate of both
> paths. Without intervention, as in this experiment, tcp_reordering
> starts out as 3 and then makes small oscillations between 3 and 12 for
> more than 2 minutes. At about second 141, TCP somehow finds a new
> highest reordering value (23) and at the same time, the throughput
> jumps up "to the next level". The value of 23 is then used all the way
> until second 603, when the reordering value becomes 32 and the
> throughput again jumps up a level.
> 
> I understand that tp->reordering is increased when reordering is
> detected, but what causes tp->reordering to sometimes be decreased
> back to 3? Also, why does a decrease back to 3 not make the whole
> procedure start all over again? For example, at second 1013.64,
> tp->reordering falls from 127 down to 3. A second later (1014.93) it
> then suddenly increases from 3 up to 32 without considering any
> numbers in between. Why it is now suddenly so fast? At the very
> beginning, it took 600 seconds to grow from 3 to 32 and afterward it
> just takes a second...?
> 
> For the experiments, all default TCP options were used, meaning that
> SACK, DSACK, Timestamps, were all enabled. Not sure how to turn on/off
> TSO... so that is probably enabled, too. Path emulation is done with
> tc/netem at the receiver interfaces (eth1, eth2) with this script:
> 

Since you have at sender a rule to spoof destination address of packets,
you should make sure you dont send "super packets (up to 64Kbytes)",
because it would stress the multipath more than you wanted to. This way,
you send only normal packets (1500 MTU).

ethtool -K eth0 tso off
ethtool -K eth0 gso off

I am pretty sure it should help your (atypic) workload.

> http://home.simula.no/~kaspar/static/netem.sh
> 
> Greetings,
> Dominik



^ permalink raw reply

* Re: [PATCH net-next-2.6 v4 4/5] sctp: Add ASCONF operation on the single-homed host
From: Michio Honda @ 2011-04-25 15:34 UTC (permalink / raw)
  To: Wei Yongjun; +Cc: netdev, lksctp-developers
In-Reply-To: <4DB4E04C.70609@cn.fujitsu.com>

I just re-submitted cumulative patches.  

About your suggestion to split the patch that reset route at the reception of ASCONF-ACK, I removed those codes.  
Because we'd already reset the route just before ASCONF, so not needed after the ASCONF-ACK reception.  
I believe the other parts follow all your comments.  
I also cleaned up many parts in single-homed host support patch.  

Thanks,
- Michio

On Apr 25, 2011, at 11:45 , Wei Yongjun wrote:

> 
>> Yes, I think the association cannot be kept, if the single-homed ASCONF receiver moves to the new network before sending ASCONF-ACK.  
>> Am I missing?
> 
> Oh, yeah, you are right.:-)
> 
>> Thanks,
>> - Michio
>> 
>> On Apr 25, 2011, at 11:02 , Wei Yongjun wrote:
>> 
>>>> Hi, 
>>>> 
>>>> Such operation would not be supported by specification, in Sec.5.3 in RFC 5061:
>>>>  F1)  When adding an IP address to an association, the IP address is
>>>>       NOT considered fully added to the association until the ASCONF-
>>>>       ACK arrives.  This means that until such time as the ASCONF
>>>>       containing the add is acknowledged, the sender MUST NOT use the
>>>>       new IP address as a source for ANY SCTP packet except on
>>>>       carrying an ASCONF Chunk. 
>>>> 
>>>> I think this means we cannot send ASCONF-ACK from the new address even if it bundles ASCONF...
>>> If so, both side do not have valid address to send the such
>>> ASCONF-ACK, and can not recv ASCONF-ACK.
>>> 
>>>> - Michio
>>>> 
>>>> On Apr 25, 2011, at 9:57 , Wei Yongjun wrote:
>>>> 
>>>>>> On Apr 22, 2011, at 13:10 , Wei Yongjun wrote:
>>>>>> 
>>>>>>>> Since the sender MUST NOT use the  new IP address as a source for ANY SCTP
>>>>>>>> packet except on  carrying an ASCONF Chunk. And ASCONF chunk can be bundled.
>>>>>>>> How about this change. If so, you do not need change to sctp_outq_tail();
>>>>>>>> 
>>>>>>>> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
>>>>>>>> index 1c88c89..bd6cc9c 100644
>>>>>>>> --- a/net/sctp/outqueue.c
>>>>>>>> +++ b/net/sctp/outqueue.c
>>>>>>>> @@ -754,6 +754,13 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
>>>>>>>> 	 */
>>>>>>>> 
>>>>>>>> 	list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
>>>>>>>> +		/* RFC 5061, 5.3
>>>>>>>> +		 * F1) This ...
>>>>>>>> +		 */
>>>>>>>> +		if (q->asoc->src_out_of_asoc_ok &&
>>>>>>>> +		    chunk->chunk_hdr->type != SCTP_CID_ASCONF)
>>>>>>> SCTP_CID_ASCONF_ACK should be also allowed, the peer may
>>>>>>> send ASCONF to do the same thing at the same time.
>>>>>> Sorry for my bad understanding, 
>>>>>> Do you mean the situation: "the peer (ASCONF receiver) may send ASCONF-ACK to the unconfirmed destination"?
>>>>>> Or do you mean following situation?
>>>>>> 1. the pear sends ADD/DEL ASCONF to me, 
>>>>>> 2. I receive it, 
>>>>>> 3. I migrate to the other network and get new address, 
>>>>>> 4. I send ASCONF-ACK to the peer from the new address
>>>>> Yes, If both side send ADD/DEL ASCONF to del the last one
>>>>> address at the same time like this:
>>>>> 
>>>>> ASCONF  -----    ------ASCONF
>>>>> (ADD/DEL)    \  /     (ADD/DEL)
>>>>>            \/        
>>>>>            /\
>>>>>      <----/  \----->
>>>>> ASCONF-ACK---\  /------ASCONF-ACK
>>>>>            \/
>>>>>            /\
>>>>>      <----/  \----->
>>>>> 
>>>>> But I do not test for it. Not sure we need to do this, can you
>>>>> check this before commit your new patchset?
>>>>> 
>>>>> 
>>>>>>>> +			continue;
>>>>>>>> +
>>>>>>>> 		list_del_init(&chunk->list);
>>>>>>>> 
>>>>>>>> 		/* Pick the right transport to use. */
>>>>>>>> @@ -881,6 +888,9 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
>>>>>>>> 		}
>>>>>>>> 	}
>>>>>>>> 
>>>>>>>> +	if (q->asoc->src_out_of_asoc_ok)
>>>>>>>> +		goto sctp_flush_out;
>>>>>>>> +
>>>>>>>> 	/* Is it OK to send data chunks?  */
>>>>>>>> 	switch (asoc->state) {
>>>>>>>> 	case SCTP_STATE_COOKIE_ECHOED:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>> --
>>>>>>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>> 
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> 


^ permalink raw reply

* [PATCH net-next-2.6 v5 5/5] sctp: Add ASCONF operation on the single-homed host
From: Michio Honda @ 2011-04-25 15:24 UTC (permalink / raw)
  To: netdev; +Cc: lksctp-developers

SCTP can change the IP address on the single-homed host.  
In this case, the SCTP association transmits an ASCONF packet including addition of the new IP address and deletion of the old address.  This patch implements this functionality.  
In this case, the ASCONF chunk is added to the beginning of the queue, because the other chunks cannot be transmitted in this state.  

Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp>
---
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index c70d8cc..d7a4ee3 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -441,4 +441,8 @@ enum {
  */
 #define SCTP_AUTH_RANDOM_LENGTH 32
 
+/* ASCONF PARAMETERS */
+#define SCTP_ASCONF_V4_PARAM_LEN 16
+#define SCTP_ASCONF_V6_PARAM_LEN 28
+
 #endif /* __sctp_constants_h__ */
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index cc9185c..db4e9d0 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1901,6 +1901,8 @@ struct sctp_association {
 	 * after reaching 4294967295.
 	 */
 	__u32 addip_serial;
+	union sctp_addr *asconf_addr_del_pending;
+	int src_out_of_asoc_ok;
 
 	/* SCTP AUTH: list of the endpoint shared keys.  These
 	 * keys are provided out of band by the user applicaton
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 6b04287..2082d0a 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -279,6 +279,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
 	asoc->peer.asconf_capable = 0;
 	if (sctp_addip_noauth)
 		asoc->peer.asconf_capable = 1;
+	asoc->asconf_addr_del_pending = NULL;
+	asoc->src_out_of_asoc_ok = 0;
 
 	/* Create an input queue.  */
 	sctp_inq_init(&asoc->base.inqueue);
@@ -443,6 +445,10 @@ void sctp_association_free(struct sctp_association *asoc)
 
 	asoc->peer.transport_count = 0;
 
+	/* Free pending address space being deleted */
+	if (asoc->asconf_addr_del_pending != NULL)
+		kfree(asoc->asconf_addr_del_pending);
+
 	/* Free any cached ASCONF_ACK chunk. */
 	sctp_assoc_free_asconf_acks(asoc);
 
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 865ce7b..56c97ce 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -332,6 +332,13 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
 				matchlen = bmatchlen;
 			}
 		}
+		if (laddr->state == SCTP_ADDR_NEW && asoc->src_out_of_asoc_ok) {
+			bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
+			if (!baddr || (matchlen < bmatchlen)) {
+				baddr = &laddr->a;
+				matchlen = bmatchlen;
+			}
+		}
 	}
 
 	if (baddr) {
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 26dc005..28bccde 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -744,6 +744,16 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 	 */
 
 	list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
+		/* RFC 5061, 5.3
+		 * F1) This means that until such time as the ASCONF
+		 * containing the add is acknowledged, the sender MUST
+		 * NOT use the new IP address as a source for ANY SCTP
+		 * packet except on carrying an ASCONF Chunk.
+		 */
+		if (asoc->src_out_of_asoc_ok &&
+		    chunk->chunk_hdr->type != SCTP_CID_ASCONF)
+			continue;
+
 		list_del_init(&chunk->list);
 
 		/* Pick the right transport to use. */
@@ -871,6 +881,9 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 		}
 	}
 
+	if (q->asoc->src_out_of_asoc_ok)
+		goto sctp_flush_out;
+
 	/* Is it OK to send data chunks?  */
 	switch (asoc->state) {
 	case SCTP_STATE_COOKIE_ECHOED:
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 152976e..0733273 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -510,7 +510,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
 		sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port));
 		rcu_read_lock();
 		list_for_each_entry_rcu(laddr, &bp->address_list, list) {
-			if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
+			if (!laddr->valid || (laddr->state == SCTP_ADDR_DEL) ||
+			    (laddr->state != SCTP_ADDR_SRC &&
+			    !asoc->src_out_of_asoc_ok))
 				continue;
 			if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
 				goto out_unlock;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index de98665..f341ab2 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2744,6 +2744,12 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
 	int			addr_param_len = 0;
 	int 			totallen = 0;
 	int 			i;
+	sctp_addip_param_t del_param; /* 8 Bytes (Type 0xC002, Len and CrrID) */
+	struct sctp_af *del_af;
+	int del_addr_param_len = 0;
+	int del_paramlen = sizeof(sctp_addip_param_t);
+	union sctp_addr_param del_addr_param; /* (v4) 8 Bytes, (v6) 20 Bytes */
+	int			del_pickup = 0;
 
 	/* Get total length of all the address parameters. */
 	addr_buf = addrs;
@@ -2756,6 +2762,17 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
 		totallen += addr_param_len;
 
 		addr_buf += af->sockaddr_len;
+		if (asoc->asconf_addr_del_pending && !del_pickup) {
+			if (!sctp_in_scope(asoc->asconf_addr_del_pending,
+			    sctp_scope(addr)))
+				continue;
+			/* reuse the parameter length from the same scope one */
+			totallen += paramlen;
+			totallen += addr_param_len;
+			del_pickup = 1;
+			asoc->src_out_of_asoc_ok = 1;
+			SCTP_DEBUG_PRINTK("mkasconf_update_ip: picked same-scope del_pending addr, totallen for all addresses is %d\n", totallen);
+		}
 	}
 
 	/* Create an asconf chunk with the required length. */
@@ -2778,6 +2795,19 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
 
 		addr_buf += af->sockaddr_len;
 	}
+	if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
+		addr = asoc->asconf_addr_del_pending;
+		del_af = sctp_get_af_specific(addr->v4.sin_family);
+		del_addr_param_len = del_af->to_addr_param(addr,
+		    &del_addr_param);
+		del_param.param_hdr.type = SCTP_PARAM_DEL_IP;
+		del_param.param_hdr.length = htons(del_paramlen +
+		    del_addr_param_len);
+		del_param.crr_id = i;
+
+		sctp_addto_chunk(retval, del_paramlen, &del_param);
+		sctp_addto_chunk(retval, del_addr_param_len, &del_addr_param);
+	}
 	return retval;
 }
 
@@ -3193,7 +3223,8 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
 		local_bh_enable();
 		list_for_each_entry(transport, &asoc->peer.transport_addr_list,
 				transports) {
-			if (transport->state == SCTP_ACTIVE)
+			if (transport->state == SCTP_ACTIVE &&
+			    !asoc->src_out_of_asoc_ok)
 				continue;
 			dst_release(transport->dst);
 			sctp_transport_route(transport, NULL,
@@ -3203,6 +3234,11 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
 	case SCTP_PARAM_DEL_IP:
 		local_bh_disable();
 		sctp_del_bind_addr(bp, &addr);
+		if (asoc->asconf_addr_del_pending != NULL &&
+		    sctp_cmp_addr_exact(asoc->asconf_addr_del_pending, &addr)) {
+			kfree(asoc->asconf_addr_del_pending);
+			asoc->asconf_addr_del_pending = NULL;
+		}
 		local_bh_enable();
 		list_for_each_entry(transport, &asoc->peer.transport_addr_list,
 				transports) {
@@ -3361,6 +3397,9 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
 		asconf_len -= length;
 	}
 
+	if (no_err && asoc->src_out_of_asoc_ok)
+		asoc->src_out_of_asoc_ok = 0;
+
 	/* Free the cached last sent asconf chunk. */
 	list_del_init(&asconf->transmitted_list);
 	sctp_chunk_free(asconf);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 3951a10..481293d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -583,10 +583,6 @@ static int sctp_send_asconf_add_ip(struct sock		*sk,
 			goto out;
 		}
 
-		retval = sctp_send_asconf(asoc, chunk);
-		if (retval)
-			goto out;
-
 		/* Add the new addresses to the bind address list with
 		 * use_as_src set to 0.
 		 */
@@ -599,6 +595,23 @@ static int sctp_send_asconf_add_ip(struct sock		*sk,
 						    SCTP_ADDR_NEW, GFP_ATOMIC);
 			addr_buf += af->sockaddr_len;
 		}
+		if (asoc->src_out_of_asoc_ok) {
+			struct sctp_transport *trans;
+
+			list_for_each_entry(trans,
+			    &asoc->peer.transport_addr_list, transports) {
+				/* Clear the source and route cache */
+				dst_release(trans->dst);
+				trans->cwnd = min(4*asoc->pathmtu, max_t(__u32,
+				    2*asoc->pathmtu, 4380));
+				trans->ssthresh = asoc->peer.i.a_rwnd;
+				trans->rto = asoc->rto_initial;
+				trans->rtt = trans->srtt = trans->rttvar = 0;
+				sctp_transport_route(trans, NULL,
+				    sctp_sk(asoc->base.sk));
+			}
+		}
+		retval = sctp_send_asconf(asoc, chunk);
 	}
 
 out:
@@ -711,7 +724,9 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
 	struct sctp_sockaddr_entry *saddr;
 	int 			i;
 	int 			retval = 0;
+	int			stored = 0;
 
+	chunk = NULL;
 	if (!sctp_addip_enable)
 		return retval;
 
@@ -762,8 +777,32 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
 		bp = &asoc->base.bind_addr;
 		laddr = sctp_find_unmatch_addr(bp, (union sctp_addr *)addrs,
 					       addrcnt, sp);
-		if (!laddr)
-			continue;
+		if ((laddr == NULL) && (addrcnt == 1)) {
+			if (asoc->asconf_addr_del_pending)
+				continue;
+			asoc->asconf_addr_del_pending =
+			    kzalloc(sizeof(union sctp_addr), GFP_ATOMIC);
+			asoc->asconf_addr_del_pending->sa.sa_family =
+				    addrs->sa_family;
+			asoc->asconf_addr_del_pending->v4.sin_port =
+				    htons(bp->port);
+			if (addrs->sa_family == AF_INET) {
+				struct sockaddr_in *sin;
+
+				sin = (struct sockaddr_in *)addrs;
+				asoc->asconf_addr_del_pending->v4.sin_addr.s_addr = sin->sin_addr.s_addr;
+			} else if (addrs->sa_family == AF_INET6) {
+				struct sockaddr_in6 *sin6;
+
+				sin6 = (struct sockaddr_in6 *)addrs;
+				ipv6_addr_copy(&asoc->asconf_addr_del_pending->v6.sin6_addr, &sin6->sin6_addr);
+			}
+			SCTP_DEBUG_PRINTK_IPADDR("send_asconf_del_ip: keep the last address asoc: %p ",
+			    " at %p\n", asoc, asoc->asconf_addr_del_pending,
+			    asoc->asconf_addr_del_pending);
+			stored = 1;
+			goto skip_mkasconf;
+		}
 
 		/* We do not need RCU protection throughout this loop
 		 * because this is done under a socket lock from the
@@ -776,6 +815,7 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
 			goto out;
 		}
 
+skip_mkasconf:
 		/* Reset use_as_src flag for the addresses in the bind address
 		 * list that are to be deleted.
 		 */
@@ -801,6 +841,9 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
 					     sctp_sk(asoc->base.sk));
 		}
 
+		if (stored)
+			/* We don't need to transmit ASCONF */
+			continue;
 		retval = sctp_send_asconf(asoc, chunk);
 	}
 out:


^ permalink raw reply related

* [PATCH net-next-2.6 v5 4/5] sctp: Add ADD/DEL ASCONF handling at the receiver
From: Michio Honda @ 2011-04-25 15:23 UTC (permalink / raw)
  To: netdev; +Cc: lksctp-developers

This patch fixes the problem that the original code cannot delete the remote address where the corresponding transport is currently directed, even when the ASCONF is sent from the other address (this situation happens when the single-homed sender transmits  ASCONF with ADD and DEL.)  

Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp>
---
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index de98665..a9f25d7 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2990,7 +2990,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 		 * an Error Cause TLV set to the new error code 'Request to
 		 * Delete Source IP Address'
 		 */
-		if (sctp_cmp_addr_exact(sctp_source(asconf), &addr))
+		if (sctp_cmp_addr_exact(&asconf->source, &addr))
 			return SCTP_ERROR_DEL_SRC_IP;
 
 		/* Section 4.2.2


^ permalink raw reply related

* [PATCH net-next-2.6 v5 3/5] sctp: Add socket option operation for Auto-ASCONF
From: Michio Honda @ 2011-04-25 15:23 UTC (permalink / raw)
  To: netdev; +Cc: lksctp-developers

This patch allows the application to operate Auto-ASCONF on/off behavior via setsockopt() and getsockopt().  

Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp>
---
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index e73ebda..36bf64b 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -91,6 +91,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_PEER_AUTH_CHUNKS	26	/* Read only */
 #define SCTP_LOCAL_AUTH_CHUNKS	27	/* Read only */
 #define SCTP_GET_ASSOC_NUMBER	28	/* Read only */
+#define SCTP_AUTO_ASCONF       29
 
 /* Internal Socket Options. Some of the sctp library functions are
  * implemented using these socket options.
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 3951a10..c9be08a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3341,6 +3341,46 @@ static int sctp_setsockopt_del_key(struct sock *sk,
 
 }
 
+/*
+ * 8.1.23 SCTP_AUTO_ASCONF
+ *
+ * This option will enable or disable the use of the automatic generation of
+ * ASCONF chunks to add and delete addresses to an existing association.  Note
+ * that this option has two caveats namely: a) it only affects sockets that
+ * are bound to all addresses available to the SCTP stack, and b) the system
+ * administrator may have an overriding control that turns the ASCONF feature
+ * off no matter what setting the socket option may have.
+ * This option expects an integer boolean flag, where a non-zero value turns on
+ * the option, and a zero value turns off the option.
+ * Note. In this implementation, socket operation overrides default parameter
+ * being set by sysctl as well as FreeBSD implementation
+ */
+static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval,
+					unsigned int optlen)
+{
+	int val;
+	struct sctp_sock *sp = sctp_sk(sk);
+
+	if (optlen < sizeof(int))
+		return -EINVAL;
+	if (get_user(val, (int __user *)optval))
+		return -EFAULT;
+	if (!sctp_is_ep_boundall(sk) && val)
+		return -EINVAL;
+	if ((val && sp->do_auto_asconf) || (!val && !sp->do_auto_asconf))
+		return 0;
+
+	if (val == 0 && sp->do_auto_asconf) {
+		list_del(&sp->auto_asconf_list);
+		sp->do_auto_asconf = 0;
+	} else if (val && !sp->do_auto_asconf) {
+		list_add_tail(&sp->auto_asconf_list,
+		    &sctp_auto_asconf_splist);
+		sp->do_auto_asconf = 1;
+	}
+	return 0;
+}
+
 
 /* API 6.2 setsockopt(), getsockopt()
  *
@@ -3488,6 +3528,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
 	case SCTP_AUTH_DELETE_KEY:
 		retval = sctp_setsockopt_del_key(sk, optval, optlen);
 		break;
+	case SCTP_AUTO_ASCONF:
+		retval = sctp_setsockopt_auto_asconf(sk, optval, optlen);
+		break;
 	default:
 		retval = -ENOPROTOOPT;
 		break;
@@ -5283,6 +5326,28 @@ static int sctp_getsockopt_assoc_number(struct sock *sk, int len,
 	return 0;
 }
 
+/*
+ * 8.1.23 SCTP_AUTO_ASCONF
+ * See the corresponding setsockopt entry as description
+ */
+static int sctp_getsockopt_auto_asconf(struct sock *sk, int len,
+				   char __user *optval, int __user *optlen)
+{
+	int val = 0;
+
+	if (len < sizeof(int))
+		return -EINVAL;
+
+	len = sizeof(int);
+	if (sctp_sk(sk)->do_auto_asconf && sctp_is_ep_boundall(sk))
+		val = 1;
+	if (put_user(len, optlen))
+		return -EFAULT;
+	if (copy_to_user(optval, &val, len))
+		return -EFAULT;
+	return 0;
+}
+
 SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
 				char __user *optval, int __user *optlen)
 {
@@ -5415,6 +5480,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
 	case SCTP_GET_ASSOC_NUMBER:
 		retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen);
 		break;
+	case SCTP_AUTO_ASCONF:
+		retval = sctp_getsockopt_auto_asconf(sk, len, optval, optlen);
+		break;
 	default:
 		retval = -ENOPROTOOPT;
 		break;


^ permalink raw reply related

* [PATCH net-next-2.6 v5 2/5] sctp: Add sysctl support for Auto-ASCONF
From: Michio Honda @ 2011-04-25 15:23 UTC (permalink / raw)
  To: netdev; +Cc: lksctp-developers

This patch allows the system administrator to change default Auto-ASCONF on/off behavior via an sysctl value.  

Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp>
---
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 50cb57f..6b39529 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -183,6 +183,13 @@ static ctl_table sctp_table[] = {
 		.proc_handler	= proc_dointvec,
 	},
 	{
+		.procname	= "default_auto_asconf",
+		.data		= &sctp_default_auto_asconf,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+	},
+	{
 		.procname	= "prsctp_enable",
 		.data		= &sctp_prsctp_enable,
 		.maxlen		= sizeof(int),



^ permalink raw reply related

* [PATCH net-next-2.6 v5 1/5] sctp: Add Auto-ASCONF support
From: Michio Honda @ 2011-04-25 15:23 UTC (permalink / raw)
  To: netdev; +Cc: lksctp-developers

SCTP reconfigure the IP addresses in the association by using ASCONF chunks as mentioned in RFC5061.  
For example, we can start to use the newly configured IP address in the existing association.  
ASCONF operation is invoked in two ways: 
First is done by the application to call sctp_bindx() system call.  
Second is automatic operation in the SCTP stack with address events in the host computer (called auto_asconf) .  
The former is already implemented, and this patch implement the latter.  

Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp>
---
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 505845d..8678cbd 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -121,6 +121,7 @@ extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
 				     int flags);
 extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
 extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
+void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *, int);
 
 /*
  * sctp/socket.c
@@ -135,6 +136,7 @@ void sctp_sock_rfree(struct sk_buff *skb);
 void sctp_copy_sock(struct sock *newsk, struct sock *sk,
 		    struct sctp_association *asoc);
 extern struct percpu_counter sctp_sockets_allocated;
+int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
 
 /*
  * sctp/primitive.c
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index cc9185c..e8adbda 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -205,6 +205,11 @@ extern struct sctp_globals {
 	 * It is a list of sctp_sockaddr_entry.
 	 */
 	struct list_head local_addr_list;
+	int default_auto_asconf;
+	struct list_head addr_waitq;
+	struct timer_list addr_wq_timer;
+	struct list_head auto_asconf_splist;
+	spinlock_t addr_wq_lock;
 
 	/* Lock that protects the local_addr_list writers */
 	spinlock_t addr_list_lock;
@@ -264,6 +269,11 @@ extern struct sctp_globals {
 #define sctp_port_hashtable		(sctp_globals.port_hashtable)
 #define sctp_local_addr_list		(sctp_globals.local_addr_list)
 #define sctp_local_addr_lock		(sctp_globals.addr_list_lock)
+#define sctp_auto_asconf_splist		(sctp_globals.auto_asconf_splist)
+#define sctp_addr_waitq			(sctp_globals.addr_waitq)
+#define sctp_addr_wq_timer		(sctp_globals.addr_wq_timer)
+#define sctp_addr_wq_lock		(sctp_globals.addr_wq_lock)
+#define sctp_default_auto_asconf	(sctp_globals.default_auto_asconf)
 #define sctp_scope_policy		(sctp_globals.ipv4_scope_policy)
 #define sctp_addip_enable		(sctp_globals.addip_enable)
 #define sctp_addip_noauth		(sctp_globals.addip_noauth_enable)
@@ -341,6 +351,8 @@ struct sctp_sock {
 	atomic_t pd_mode;
 	/* Receive to here while partial delivery is in effect. */
 	struct sk_buff_head pd_lobby;
+	struct list_head auto_asconf_list;
+	int do_auto_asconf;
 };
 
 static inline struct sctp_sock *sctp_sk(const struct sock *sk)
@@ -796,6 +808,8 @@ struct sctp_sockaddr_entry {
 	__u8 valid;
 };
 
+#define SCTP_ADDRESS_TICK_DELAY	500
+
 typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *);
 
 /* This structure holds lists of chunks as we are assembling for
@@ -1239,6 +1253,7 @@ sctp_scope_t sctp_scope(const union sctp_addr *);
 int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope);
 int sctp_is_any(struct sock *sk, const union sctp_addr *addr);
 int sctp_addr_is_valid(const union sctp_addr *addr);
+int sctp_is_ep_boundall(struct sock *sk);
 
 
 /* What type of endpoint?  */
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index faf71d1..869267b 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -536,6 +536,21 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
 	return 0;
 }
 
+int sctp_is_ep_boundall(struct sock *sk)
+{
+	struct sctp_bind_addr *bp;
+	struct sctp_sockaddr_entry *addr;
+
+	bp = &sctp_sk(sk)->ep->base.bind_addr;
+	if (sctp_list_single_entry(&bp->address_list)) {
+		addr = list_entry(bp->address_list.next,
+				  struct sctp_sockaddr_entry, list);
+		if (sctp_is_any(sk, &addr->a))
+			return 1;
+	}
+	return 0;
+}
+
 /********************************************************************
  * 3rd Level Abstractions
  ********************************************************************/
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 865ce7b..3a74d42 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -105,6 +105,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
 			addr->valid = 1;
 			spin_lock_bh(&sctp_local_addr_lock);
 			list_add_tail_rcu(&addr->list, &sctp_local_addr_list);
+			sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW);
 			spin_unlock_bh(&sctp_local_addr_lock);
 		}
 		break;
@@ -115,6 +116,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
 			if (addr->a.sa.sa_family == AF_INET6 &&
 					ipv6_addr_equal(&addr->a.v6.sin6_addr,
 						&ifa->addr)) {
+				sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL);
 				found = 1;
 				addr->valid = 0;
 				list_del_rcu(&addr->list);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 152976e..f9b0f9b 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -636,6 +636,160 @@ static void sctp_v4_ecn_capable(struct sock *sk)
 	INET_ECN_xmit(sk);
 }
 
+void sctp_addr_wq_timeout_handler(unsigned long arg)
+{
+	struct sctp_sockaddr_entry *addrw = NULL;
+	union sctp_addr *addr = NULL;
+	struct sctp_sock *sp = NULL;
+
+	spin_lock_bh(&sctp_addr_wq_lock);
+retry_wq:
+	if (list_empty(&sctp_addr_waitq)) {
+		SCTP_DEBUG_PRINTK("sctp_addrwq_timo_handler: nothing in addr waitq\n");
+		spin_unlock_bh(&sctp_addr_wq_lock);
+		return;
+	}
+	addrw = list_first_entry(&sctp_addr_waitq, struct sctp_sockaddr_entry,
+			list);
+	addr = &addrw->a;
+	SCTP_DEBUG_PRINTK_IPADDR("sctp_addrwq_timo_handler: the first ent in wq %p is ",
+	    " for cmd %d at entry %p\n", &sctp_addr_waitq, addr, addrw->state,
+	    addrw);
+
+	/* Now we send an ASCONF for each association */
+	/* Note. we currently don't handle link local IPv6 addressees */
+	if (addr->sa.sa_family == AF_INET6) {
+		struct in6_addr *in6 = (struct in6_addr *)&addr->v6.sin6_addr;
+
+		if (ipv6_addr_type(&addr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
+			SCTP_DEBUG_PRINTK("sctp_timo_handler: link local, hence don't tell sockets\n");
+			list_del(&addrw->list);
+			kfree(addrw);
+			goto retry_wq;
+		}
+		if (ipv6_chk_addr(&init_net, in6, NULL, 0) == 0 &&
+		    addrw->state == SCTP_ADDR_NEW) {
+			unsigned long timeo_val;
+
+			SCTP_DEBUG_PRINTK("sctp_timo_handler: this is on DAD, trying %d sec later\n",
+			    SCTP_ADDRESS_TICK_DELAY);
+			timeo_val = jiffies;
+			timeo_val += msecs_to_jiffies(SCTP_ADDRESS_TICK_DELAY);
+			mod_timer(&sctp_addr_wq_timer, timeo_val);
+			spin_unlock_bh(&sctp_addr_wq_lock);
+			return;
+		}
+	}
+	list_for_each_entry(sp, &sctp_auto_asconf_splist, auto_asconf_list) {
+		struct sock *sk;
+
+		sk = sctp_opt2sk(sp);
+		/* ignore bound-specific endpoints */
+		if (!sctp_is_ep_boundall(sk))
+			continue;
+		sctp_bh_lock_sock(sk);
+		if (sctp_asconf_mgmt(sp, addrw) < 0) {
+			SCTP_DEBUG_PRINTK("sctp_addrwq_timo_handler: sctp_asconf_mgmt failed\n");
+			sctp_bh_unlock_sock(sk);
+			continue;
+		}
+		sctp_bh_unlock_sock(sk);
+	}
+
+	list_del(&addrw->list);
+	kfree(addrw);
+
+	if (!list_empty(&sctp_addr_waitq))
+		goto retry_wq;
+
+	spin_unlock_bh(&sctp_addr_wq_lock);
+}
+
+static void sctp_free_addr_wq()
+{
+	struct sctp_sockaddr_entry *addrw = NULL;
+	struct sctp_sockaddr_entry *temp = NULL;
+
+	spin_lock_bh(&sctp_addr_wq_lock);
+	del_timer(&sctp_addr_wq_timer);
+	list_for_each_entry_safe(addrw, temp, &sctp_addr_waitq, list) {
+		list_del(&addrw->list);
+		kfree(addrw);
+	}
+	spin_unlock_bh(&sctp_addr_wq_lock);
+}
+
+/* lookup the entry for the same address in the addr_waitq
+ * sctp_addr_wq MUST be locked
+ */
+static struct sctp_sockaddr_entry *sctp_addr_wq_lookup(struct sctp_sockaddr_entry *addr)
+{
+	struct sctp_sockaddr_entry *addrw;
+
+	list_for_each_entry(addrw, &sctp_addr_waitq, list) {
+		if (addrw->a.sa.sa_family != addr->a.sa.sa_family)
+			continue;
+		if (addrw->a.sa.sa_family == AF_INET) {
+			if (addrw->a.v4.sin_addr.s_addr ==
+			    addr->a.v4.sin_addr.s_addr)
+				return addrw;
+		} else if (addrw->a.sa.sa_family == AF_INET6) {
+			if (ipv6_addr_equal(&addrw->a.v6.sin6_addr,
+			    &addr->a.v6.sin6_addr))
+				return addrw;
+		}
+	}
+	return NULL;
+}
+
+void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *addr, int cmd)
+{
+	struct sctp_sockaddr_entry *addrw = NULL;
+	unsigned long timeo_val;
+	union sctp_addr *tmpaddr;
+
+	/* first, we check if an opposite message already exist in the queue.
+	 * If we found such message, it is removed.
+	 * This operation is a bit stupid, but the DHCP client attaches the
+	 * new address after a couple of addition and deletion of that address
+	 */
+
+	spin_lock_bh(&sctp_addr_wq_lock);
+	/* Offsets existing events in addr_wq */
+	addrw = sctp_addr_wq_lookup(addr);
+	tmpaddr = &addrw->a;
+	if (addrw) {
+		if (addrw->state != cmd) {
+			SCTP_DEBUG_PRINTK_IPADDR("sctp_addr_wq_mgmt offsets existing entry for %d ",
+			    " in wq %p\n", addrw->state, tmpaddr,
+			    &sctp_addr_waitq);
+			list_del(&addrw->list);
+			kfree(addrw);
+		}
+		spin_unlock_bh(&sctp_addr_wq_lock);
+		return;
+	}
+
+	/* OK, we have to add the new address to the wait queue */
+	addrw = kmemdup(addr, sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
+	if (addrw == NULL) {
+		spin_unlock_bh(&sctp_addr_wq_lock);
+		return;
+	}
+	addrw->state = cmd;
+	list_add_tail(&addrw->list, &sctp_addr_waitq);
+	tmpaddr = &addrw->a;
+	SCTP_DEBUG_PRINTK_IPADDR("sctp_addr_wq_mgmt add new entry for cmd:%d ",
+	    " in wq %p\n", addrw->state, tmpaddr, &sctp_addr_waitq);
+
+	if (!timer_pending(&sctp_addr_wq_timer)) {
+		timeo_val = jiffies;
+		timeo_val += msecs_to_jiffies(SCTP_ADDRESS_TICK_DELAY);
+		mod_timer(&sctp_addr_wq_timer, timeo_val);
+	}
+	spin_unlock_bh(&sctp_addr_wq_lock);
+}
+
 /* Event handler for inet address addition/deletion events.
  * The sctp_local_addr_list needs to be protocted by a spin lock since
  * multiple notifiers (say IPv4 and IPv6) may be running at the same
@@ -663,6 +817,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
 			addr->valid = 1;
 			spin_lock_bh(&sctp_local_addr_lock);
 			list_add_tail_rcu(&addr->list, &sctp_local_addr_list);
+			sctp_addr_wq_mgmt(addr, SCTP_ADDR_NEW);
 			spin_unlock_bh(&sctp_local_addr_lock);
 		}
 		break;
@@ -673,6 +828,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
 			if (addr->a.sa.sa_family == AF_INET &&
 					addr->a.v4.sin_addr.s_addr ==
 					ifa->ifa_local) {
+				sctp_addr_wq_mgmt(addr, SCTP_ADDR_DEL);
 				found = 1;
 				addr->valid = 0;
 				list_del_rcu(&addr->list);
@@ -1256,6 +1412,7 @@ SCTP_STATIC __init int sctp_init(void)
 	/* Disable ADDIP by default. */
 	sctp_addip_enable = 0;
 	sctp_addip_noauth = 0;
+	sctp_default_auto_asconf = 0;
 
 	/* Enable PR-SCTP by default. */
 	sctp_prsctp_enable = 1;
@@ -1280,6 +1437,13 @@ SCTP_STATIC __init int sctp_init(void)
 	spin_lock_init(&sctp_local_addr_lock);
 	sctp_get_local_addr_list();
 
+	/* Initialize the address event list */
+	INIT_LIST_HEAD(&sctp_addr_waitq);
+	INIT_LIST_HEAD(&sctp_auto_asconf_splist);
+	spin_lock_init(&sctp_addr_wq_lock);
+	sctp_addr_wq_timer.expires = 0;
+	setup_timer(&sctp_addr_wq_timer, sctp_addr_wq_timeout_handler, 0);
+
 	status = sctp_v4_protosw_init();
 
 	if (status)
@@ -1351,6 +1515,7 @@ SCTP_STATIC __exit void sctp_exit(void)
 	/* Unregister with inet6/inet layers. */
 	sctp_v6_del_protocol();
 	sctp_v4_del_protocol();
+	sctp_free_addr_wq();
 
 	/* Free the control endpoint.  */
 	inet_ctl_sock_destroy(sctp_ctl_sock);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 3951a10..c433e97 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -807,6 +807,37 @@ out:
 	return retval;
 }
 
+/* set addr events to assocs in the endpoint.  ep and addr_wq must be locked */
+int
+sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
+{
+	struct sock *sk = sctp_opt2sk(sp);
+	union sctp_addr *addr = NULL;
+	int cmd;
+	int error = 0;
+
+	addr = &addrw->a;
+	addr->v4.sin_port = htons(sp->ep->base.bind_addr.port);
+	cmd = addrw->state;
+
+	SCTP_DEBUG_PRINTK("sctp_asconf_mgmt sp:%p\n", sp);
+	if (cmd == SCTP_ADDR_NEW) {
+		error = sctp_send_asconf_add_ip(sk, (struct sockaddr *)addr, 1);
+		if (error) {
+			SCTP_DEBUG_PRINTK("asconf_mgmt: send_asconf_add_ip returns %d\n", error);
+			return error;
+		}
+	} else if (cmd == SCTP_ADDR_DEL) {
+		error = sctp_send_asconf_del_ip(sk, (struct sockaddr *)addr, 1);
+		if (error) {
+			SCTP_DEBUG_PRINTK("asconf_mgmt: send_asconf_del_ip returns %d\n", error);
+			return error;
+		}
+	}
+
+	return 0;
+}
+
 /* Helper for tunneling sctp_bindx() requests through sctp_setsockopt()
  *
  * API 8.1
@@ -3770,6 +3801,13 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
 	local_bh_disable();
 	percpu_counter_inc(&sctp_sockets_allocated);
 	sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+	if (sctp_default_auto_asconf) {
+		list_add_tail(&sp->auto_asconf_list,
+		    &sctp_auto_asconf_splist);
+		sp->do_auto_asconf = 1;
+	} else
+		sp->do_auto_asconf = 0;
+	SCTP_DEBUG_PRINTK("sctp_init_sk sk:%p ep:%p\n", sk, ep);
 	local_bh_enable();
 
 	return 0;
@@ -3779,11 +3817,17 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
 SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
 {
 	struct sctp_endpoint *ep;
+	struct sctp_sock *sp;
 
 	SCTP_DEBUG_PRINTK("sctp_destroy_sock(sk: %p)\n", sk);
 
 	/* Release our hold on the endpoint. */
-	ep = sctp_sk(sk)->ep;
+	sp = sctp_sk(sk);
+	ep = sp->ep;
+	if (sp->do_auto_asconf) {
+		sp->do_auto_asconf = 0;
+		list_del(&sp->auto_asconf_list);
+	}
 	sctp_endpoint_free(ep);
 	local_bh_disable();
 	percpu_counter_dec(&sctp_sockets_allocated);


^ permalink raw reply related

* [PATCH net-next-2.6 v5 0/5] sctp: Patch series
From: Michio Honda @ 2011-04-25 15:22 UTC (permalink / raw)
  To: netdev; +Cc: lksctp-developers

Series of 5 patches to support auto_asconf and the other related functionalities that auto_asconf relies on. 

Cheers,
- Michio

[1/5] Add Auto-ASCONF support
[2/5] Add sysctl support for Auto-ASCONF
[3/5] Add socket option operation for Auto-ASCONF
[4/5] Add ADD/DEL ASCONF handling at the receiver
[5/5] Add ASCONF operation on the single-homed host

^ permalink raw reply

* Re: Linux TCP's Robustness to Multipath Packet Reordering
From: Dominik Kaspar @ 2011-04-25 14:35 UTC (permalink / raw)
  To: Eric Dumazet, Carsten Wolff; +Cc: netdev
In-Reply-To: <1303730701.2747.110.camel@edumazet-laptop>

Hi Eric and Carsten,

Thanks a lot for your quick replies. I don't have a tcpdump of this
experiment, but here is the tcp_probe log that the plot is based on
(I'll run a new test using tcpdump if you think that's more useful):

http://home.simula.no/~kaspar/static/mptcp-emu-wlan-hspa-00.log

I have also noticed what Carsten mentions, the tcp_reordering value is
essential for this whole behavior. When I start an experiment and
increase sysctl.net.ipv4.tcp_reordering during the running connection,
the TCP throughput immediately jumps close to the aggregate of both
paths. Without intervention, as in this experiment, tcp_reordering
starts out as 3 and then makes small oscillations between 3 and 12 for
more than 2 minutes. At about second 141, TCP somehow finds a new
highest reordering value (23) and at the same time, the throughput
jumps up "to the next level". The value of 23 is then used all the way
until second 603, when the reordering value becomes 32 and the
throughput again jumps up a level.

I understand that tp->reordering is increased when reordering is
detected, but what causes tp->reordering to sometimes be decreased
back to 3? Also, why does a decrease back to 3 not make the whole
procedure start all over again? For example, at second 1013.64,
tp->reordering falls from 127 down to 3. A second later (1014.93) it
then suddenly increases from 3 up to 32 without considering any
numbers in between. Why it is now suddenly so fast? At the very
beginning, it took 600 seconds to grow from 3 to 32 and afterward it
just takes a second...?

For the experiments, all default TCP options were used, meaning that
SACK, DSACK, Timestamps, were all enabled. Not sure how to turn on/off
TSO... so that is probably enabled, too. Path emulation is done with
tc/netem at the receiver interfaces (eth1, eth2) with this script:

http://home.simula.no/~kaspar/static/netem.sh

Greetings,
Dominik


On Mon, Apr 25, 2011 at 1:25 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le lundi 25 avril 2011 à 12:37 +0200, Dominik Kaspar a écrit :
>> Hello,
>>
>> Knowing how critical packet reordering is for standard TCP, I am
>> currently testing how robust Linux TCP is when packets are forwarded
>> over multiple paths (with different bandwidth and RTT). Since Linux
>> TCP adapts its "dupAck threshold" to an estimated level of packet
>> reordering, I expect it to be much more robust than a standard TCP
>> that strictly follows the RFCs. Indeed, as you can see in the
>> following plot, my experiments show a step-wise adaptation of Linux
>> TCP to heavy reordering. After many minutes, Linux TCP finally reaches
>> a data throughput close to the perfect aggregated data rate of two
>> paths (emulated with characteristics similar to IEEE 802.11b (WLAN)
>> and a 3G link (HSPA)):
>>
>> http://home.simula.no/~kaspar/static/mptcp-emu-wlan-hspa-00.png
>>
>> Does anyone have clues what's going on here? Why does the aggregated
>> throughput increase in steps? And what could be the reason it takes
>> minutes to adapt to the full capacity, when in other cases, Linux TCP
>> adapts much faster (for example if the bandwidth of both paths are
>> equal). I would highly appreciate some advice from the netdev
>> community.
>>
>> Implementation details:
>> This multipath TCP experiment ran between a sending machine with a
>> single Ethernet interface (eth0) and a client with two Ethernet
>> interfaces (eth1, eth2). The machines are connected through a switch
>> and tc/netem is used to emulate the bandwidth and RTT of both paths.
>> TCP connections are established using iperf between eth0 and eth1 (the
>> primary path). At the sender, an iptables' NFQUEUE is used to "spoof"
>> the destination IP address of outgoing packets and force some to
>> travel to eth2 instead of eth1 (the secondary path). This multipath
>> scheduling happens in proportion to the emulated bandwidths, so if the
>> paths are set to 500 and 1000 KB/s, then packets are distributed in a
>> 1:2 ratio. At the client, iptables' RAWDNAT is used to translate the
>> spoofed IP addresses back to their original, so that all packets end
>> up at eth1, although a portion actually travelled to eth2. ACKs are
>> not scheduled over multiple paths, but always travel back on the
>> primary path. TCP does not notice anything of the multipath
>> forwarding, except the side-effect of packet reordering, which can be
>> huge if the path RTTs are set very differently.
>>
>
> Hi Dominik
>
> Implementation details of the tc/netem stages are important to fully
> understand how TCP stack can react.
>
> Is TSO active at sender side for example ?
>
> Your results show that only some exceptional events make bandwidth
> really change.
>
> A tcpdump/pcap of ~10.000 first packets would be nice to provide (not on
> mailing list, but on your web site)

^ permalink raw reply

* Re: [PATCH] af_unix: Only allow recv on connected seqpacket sockets.
From: Eric W. Biederman @ 2011-04-25 14:26 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, xemul, dan, stable
In-Reply-To: <20110424.120519.226767465.davem@davemloft.net>

David Miller <davem@davemloft.net> writes:

> From: ebiederm@xmission.com (Eric W. Biederman)
> Date: Sun, 24 Apr 2011 04:54:57 -0700
>
>> +static int unix_seqpacket_recvmsg(struct kiocb *iocb, struct socket *sock,
>> +			      struct msghdr *msg, size_t size,
>> +			      int flags)
>> +{
>> +	struct sock *sk = sock->sk;
>> +
>> +	if (sk->sk_state != TCP_ESTABLISHED)
>> +		return -ENOTCONN;
>
> As for unix_seqpacket_sendmsg(), you need to add a check for sock_error()
> or similar here otherwise -ECONNRESET is not reported correctly.
>
> In fact, recvmsg() is even harder than sendmsg() to handle correctly,
> because we have to also properly report EOF on seqpacket sockets which
> have RCV_SHUTDOWN set.
>
> So a lot more work has to go into this change to make it fix the bug
> without also breaking existing semantics.

Really?

When I read through the code I am failing to see the issues you are
seeing.

When the other socket in an established connection calls unix_shutdown
or unix_release_sock.  sk->sk_shutdown is changed, but sk_state is
left at TCP_ESTABLISHED.  Therefore we do not need a special
case in unix_seqpacket_recvmsg to handle the RCV_SHUTDOWN case
because in any case where that applies we will be in TCP_ESTABLISHED
and we will simply call unix_dgram_recvmsg.

As for ECONNRESET when I look a look at the code it appears to be
another variant of the other side calling shutdown or close.   So if
it applies we should remain in TCP_ESTABLISHED, and
unix_seqpacket_recvmsg should not need to do anything.

So looking at this the only times I can see that sk_state would
not be TCP_ESTABLISHED in a unix domain seqpacket socket are.
- On a listening socket, where calling recvmsg is what this
  patch is meant to address.
- Before we call connect or listen.
  Which appears to be equally broken today.  The only errors
  I can see happening in the case we are not connected today
  are blocking forever or returning -EINTR if we timeout.

Adding sock_error() handling into the new unix_seqpacket_recvmsg makes a
fair amount of sense but adding a new call to sock_error in that path
seems marginally more likely to change error codes and break existing
apps.  We already have a few other unconditional error codes before
we check sk_err in unix_dgram_recvmsg. 


> Anyways, see:
>
> commit 6e14891f4d16f8a9e0bc3a8408f73b3aed93ab0a
> Author: James Morris <jmorris@redhat.com>
> Date:   Fri Nov 19 07:02:41 2004 -0800
>
>     [AF_UNIX]: Don't lose ECONNRESET in unix_seqpacket_sendmsg()
>     
>     The fix for SELinux w/SOCK_SEQPACKET had an error,
>     noted by Alan Cox.  This fixes it.
>     
>     Signed-off-by: James Morris <jmorris@redhat.com>
>     Signed-off-by: David S. Miller <davem@davemloft.net>

Looking into it.  That patch appears to have been unnecessary.
We never transition out of the state TCP_ESTABLISHED once we get
there, and we can never get ECONNRESET unless we are connected.

Arguably we could reduce unix_seqpacket_sendmsg to simply 

static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,
  				  struct msghdr *msg, size_t len)
{
	if (msg->msgnamelen)
        	msg->msgnamelen = 0;
        return unix_dgram_sendmsg(kiocb, sock, msg, len);
}

But I think having the explicit TCP_ESTABLISHED check makes for better
maintainability, of unix_dgram_sendmesg.

So having gone through all of that it looks like my patch needs a
comment saying that once we are in TCP_ESTABLISHED we cannot leave,
and that nothing can happen before we are TCP_ESTABLISHED.

We can use sock_error to check sk_err, as it seems good hygiene
but it also appears pointless.  Especially for recvmsg where ECONNRESET
never applies.

Eric


> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index 16faa9d..8902c4a 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1513,13 +1513,18 @@ out_err:
>  static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,
>  				  struct msghdr *msg, size_t len)
>  {
> +	int err;
>  	struct sock *sk = sock->sk;
>  	
> +	err = sock_error(sk);
> +	if (err)
> +		return err;
> +
>  	if (sk->sk_state != TCP_ESTABLISHED)
>  		return -ENOTCONN;
>  
> -	if (msg->msg_name || msg->msg_namelen)
> -		return -EINVAL;
> +	if (msg->msg_namelen)
> +		msg->msg_namelen = 0;
>  
>  	return unix_dgram_sendmsg(kiocb, sock, msg, len);
>  }

^ permalink raw reply

* Re: Linux TCP's Robustness to Multipath Packet Reordering
From: Carsten Wolff @ 2011-04-25 12:59 UTC (permalink / raw)
  To: Dominik Kaspar; +Cc: netdev
In-Reply-To: <BANLkTimpgXCpweZKCihCQkLjSZw5zL4=Pg@mail.gmail.com>

Hi Dominik,

On Monday 25 April 2011, Dominik Kaspar wrote:
> Hello,
> 
> Knowing how critical packet reordering is for standard TCP, I am
> currently testing how robust Linux TCP is when packets are forwarded
> over multiple paths (with different bandwidth and RTT). Since Linux
> TCP adapts its "dupAck threshold" to an estimated level of packet
> reordering, I expect it to be much more robust than a standard TCP
> that strictly follows the RFCs. Indeed, as you can see in the
> following plot, my experiments show a step-wise adaptation of Linux
> TCP to heavy reordering. After many minutes, Linux TCP finally reaches
> a data throughput close to the perfect aggregated data rate of two
> paths (emulated with characteristics similar to IEEE 802.11b (WLAN)
> and a 3G link (HSPA)):
> 
> http://home.simula.no/~kaspar/static/mptcp-emu-wlan-hspa-00.png
> 
> Does anyone have clues what's going on here? Why does the aggregated
> throughput increase in steps? And what could be the reason it takes
> minutes to adapt to the full capacity, when in other cases, Linux TCP
> adapts much faster (for example if the bandwidth of both paths are
> equal). I would highly appreciate some advice from the netdev
> community.

the throughput increase in steps is most likely caused by Linux's reordering 
detection and quantization. The DupThresh (tp->reordering) is only increased 
when reordering is detected and is then set to a value that depends on current 
inflight/pipe. This means, on a path with only reordering and no loss, where a 
very large DupThresh is best, you will see those steps in the throughput 
everytime when Linux detects reordering during a time where cwnd is large. 
This on the other hand depends purely on timing/luck.
Linux is also only able to quantize reordering during disorder state, which 
leaves out many possible quantization samples, escpecially the larger ones, 
which would increase DupThresh to higher values.

Also, reordering detection depends very much on TCP options. Which TCP Options 
were enabled in your test? Timestamps? D-SACK?

Carsten

> 
> Implementation details:
> This multipath TCP experiment ran between a sending machine with a
> single Ethernet interface (eth0) and a client with two Ethernet
> interfaces (eth1, eth2). The machines are connected through a switch
> and tc/netem is used to emulate the bandwidth and RTT of both paths.
> TCP connections are established using iperf between eth0 and eth1 (the
> primary path). At the sender, an iptables' NFQUEUE is used to "spoof"
> the destination IP address of outgoing packets and force some to
> travel to eth2 instead of eth1 (the secondary path). This multipath
> scheduling happens in proportion to the emulated bandwidths, so if the
> paths are set to 500 and 1000 KB/s, then packets are distributed in a
> 1:2 ratio. At the client, iptables' RAWDNAT is used to translate the
> spoofed IP addresses back to their original, so that all packets end
> up at eth1, although a portion actually travelled to eth2. ACKs are
> not scheduled over multiple paths, but always travel back on the
> primary path. TCP does not notice anything of the multipath
> forwarding, except the side-effect of packet reordering, which can be
> huge if the path RTTs are set very differently.
> 
> Best regards,
> Dominik
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
           /\-´-/\
          (  @ @  )
________o0O___^___O0o________

^ permalink raw reply

* Re: Oops in 2.6.39 include/net/dst.h: dst_metrics_write_ptr() running l2tp over ipsec
From: Eric Dumazet @ 2011-04-25 12:49 UTC (permalink / raw)
  To: Held Bernhard; +Cc: linux-kernel, David S. Miller, netdev
In-Reply-To: <4DB54450.90806@gmx.de>

Le lundi 25 avril 2011 à 11:52 +0200, Held Bernhard a écrit :

> Your patch works flawlessly.
> 

Well, its your patch :)

> Thanks for the quick response!

Thanks for testing.

^ permalink raw reply

* Re: Hight speed data sending from custom IP out of kernel
From: Michal Simek @ 2011-04-25 12:48 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: juice, netdev
In-Reply-To: <1303734625.2747.121.camel@edumazet-laptop>

Eric Dumazet wrote:
> Le lundi 25 avril 2011 à 14:27 +0200, Eric Dumazet a écrit :
>> Le lundi 25 avril 2011 à 14:18 +0200, Michal Simek a écrit :
>>
>>>> Now, if all you want to do is send many packets from pktgen (with only
>>>> ID changing), you could add a fast path to not rebuild from scratch new
>>>> packets.
>>> What do you mean?
>>
>> If you know your device has X slots in its TX ring buffer, you would
>> have to maintain at least X+1 skbs in pktgen to make sure you reuse an
>> skb while its previous logical content was sent on wire.
>>
>> Then you are free to only change iph->id and iph->check very fast.
>>

got it. There is an option to setup number of BDs in the driver where I need to 
use half skb because of nr_frags=2 where two BDs are used.

> 
> Checking skb->users would also be a good way to know if TX completion
> released skb reference. If your module owns the last reference, it can
> do a recycle.

Ok. I see that dev_kfree_skb(consume_skb).

Thanks will try,
Michal

-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

^ permalink raw reply

* Re: Hight speed data sending from custom IP out of kernel
From: Eric Dumazet @ 2011-04-25 12:30 UTC (permalink / raw)
  To: monstr; +Cc: juice, netdev
In-Reply-To: <1303734468.2747.120.camel@edumazet-laptop>

Le lundi 25 avril 2011 à 14:27 +0200, Eric Dumazet a écrit :
> Le lundi 25 avril 2011 à 14:18 +0200, Michal Simek a écrit :
> 
> > > 
> > > Now, if all you want to do is send many packets from pktgen (with only
> > > ID changing), you could add a fast path to not rebuild from scratch new
> > > packets.
> > 
> > What do you mean?
> 
> 
> If you know your device has X slots in its TX ring buffer, you would
> have to maintain at least X+1 skbs in pktgen to make sure you reuse an
> skb while its previous logical content was sent on wire.
> 
> Then you are free to only change iph->id and iph->check very fast.
> 

Checking skb->users would also be a good way to know if TX completion
released skb reference. If your module owns the last reference, it can
do a recycle.





^ 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