Netdev List
 help / color / mirror / Atom feed
* Re: Network hangs with 2.6.30.5
From: Holger Hoffstaette @ 2009-09-01 15:32 UTC (permalink / raw)
  To: netdev
In-Reply-To: <pan.2009.09.01.14.17.06.671250@googlemail.com>

On Tue, 01 Sep 2009 16:17:08 +0200, Holger Hoffstaette wrote:

[network regressions in .30]

> I do have an older Intel Gbit card identified thusly: 00:0b.0 Ethernet
> controller: Intel Corporation 82545GM Gigabit Ethernet Controller (rev 04)
> 
> and enabled all sorts of offloading:
> 
> $ethtool -k eth0
> Offload parameters for eth0:
> rx-checksumming: on
> tx-checksumming: on
> scatter-gather: on
> tcp segmentation offload: on
> udp fragmentation offload: off
> generic segmentation offload: on
> 
> Maybe that is the culprit, as Eric Dumazet suspected in his mail..I will
> try the latest .30 stable again without that, but in any case something is
> indeed very broken in there.

So I just tried .30.5 again. Indeed the offloading seems to play a role:
with everything enabled I cannot even reliably ssh into the machine (only
"sometimes"?); however without any offloading things get "a bit better"
and squid even serves up some pages..for a while. Then it seems to hang,
swallow requests or not finish them. The tested sites reliably work for
the Windows client when it bypasses squid, as does DNS (also served from
the box). It *seems* to affect incoming traffic more than outgoing - e.g.
mail or news polling seemed to kick off and finish just fine.
Rebooting back into .29 fixes everything. Last time I tried
.31rc-something (4 IIRC) it exhibited the same problems.

I'm open to suggestions and willing to help fix this but need this machine
for actual work. :/

-h



^ permalink raw reply

* Re: UDP is bypassing qdisc statistics ....
From: Christoph Lameter @ 2009-09-01 19:30 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Eric Dumazet, Mark Smith, Jarek Poplawski, netdev, davem
In-Reply-To: <4A9D2DBF.8030200@trash.net>

On Tue, 1 Sep 2009, Patrick McHardy wrote:

> That explains it. The bnx2 driver uses multiple TX queues, but
> tc_dump_qdisc() only dumps the statistics from queue number 0.

There are no stats in other queues either... This is the result after
sending 10000 or so packets. Maybe I am not catching all the qdiscs?

(this is the result of a pretty raw patch to dump all qdiscs)

#cat /proc/net/qdisc_stats
Type Device State Bytes Packets Qlen Backlog Drops Requeues Overlimits
TX root <NULL> 0 0 0 0 0 0 0 0
RX root <NULL> 0 0 0 0 0 0 0 0
TX root  eth0 0 24830 155 0 0 0 0 0
RX root <NULL> 0 0 0 0 0 0 0 0
TX root <NULL> 0 0 0 0 0 0 0 0
RX root <NULL> 0 0 0 0 0 0 0 0
TX root <NULL> 0 0 0 0 0 0 0 0
RX root <NULL> 0 0 0 0 0 0 0 0
TX root <NULL> 0 0 0 0 0 0 0 0
RX root <NULL> 0 0 0 0 0 0 0 0

---
 net/sched/sch_api.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

Index: linux-2.6/net/sched/sch_api.c
===================================================================
--- linux-2.6.orig/net/sched/sch_api.c	2009-08-31 21:19:04.000000000 +0000
+++ linux-2.6/net/sched/sch_api.c	2009-09-01 14:30:40.000000000 +0000
@@ -1699,6 +1699,69 @@ static const struct file_operations psch
 	.llseek = seq_lseek,
 	.release = single_release,
 };
+
+static void dump_qdisc(struct seq_file *seq, struct Qdisc *q, char *inout, char *text)
+{
+	seq_printf(seq, "%2s %2s %5s %lx %lld %d %d %d %d %d %d\n",
+		inout, text, q->dev_queue->dev->name, q->state,
+		q->bstats.bytes, q->bstats.packets,
+		q->qstats.qlen, q->qstats.backlog, q->qstats.drops,
+		q->qstats.requeues, q->qstats.overlimits);
+}
+
+static void dump_qdisc_root(struct seq_file *seq, struct Qdisc *root, char *inout)
+{
+	struct Qdisc *q;
+	int n = 0;
+
+	if (!root)
+		return;
+
+	dump_qdisc(seq, root, inout, "root");
+
+	list_for_each_entry(q, &root->list, list) {
+		char buffer[10];
+
+		sprintf(buffer,"%d", ++n);
+		dump_qdisc(seq, q, inout, buffer);
+	}
+}
+
+
+static int qdisc_show(struct seq_file *seq, void *v)
+{
+	struct net_device *dev;
+
+	seq_printf(seq, "Type Device State Bytes Packets "
+			"Qlen Backlog Drops Requeues Overlimits\n");
+
+	read_lock(&dev_base_lock);
+
+	for_each_netdev(&init_net, dev) {
+		struct netdev_queue *dev_queue;
+
+		dev_queue = netdev_get_tx_queue(dev, 0);
+		dump_qdisc_root(seq, dev_queue->qdisc_sleeping, "TX");
+		dev_queue = &dev->rx_queue;
+		dump_qdisc_root(seq, dev_queue->qdisc_sleeping, "RX");
+	}
+
+	read_unlock(&dev_base_lock);
+	return 0;
+}
+
+static int qdisc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, qdisc_show, PDE(inode)->data);
+}
+
+static const struct file_operations qdisc_fops = {
+	.owner = THIS_MODULE,
+	.open = qdisc_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
 #endif

 static int __init pktsched_init(void)
@@ -1706,6 +1769,7 @@ static int __init pktsched_init(void)
 	register_qdisc(&pfifo_qdisc_ops);
 	register_qdisc(&bfifo_qdisc_ops);
 	proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
+	proc_net_fops_create(&init_net, "qdisc_stats", 0, &qdisc_fops);

 	rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
 	rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL);

^ permalink raw reply

* Re: [PATCH 04/19] convert hamradio drivers to netdev_txreturnt_t
From: Thomas Sailer @ 2009-09-01 15:30 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, linux-hams, netdev
In-Reply-To: <20090901055128.780933432@vyatta.com>

On Mon, 2009-08-31 at 22:50 -0700, Stephen Hemminger wrote:
> plain text document attachment (hamradio-tx.patch)
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

for drivers/net/hamradio/hdlcdrv.c:
Acked-by: Thomas Sailer <t.sailer@alumni.ethz.ch>



^ permalink raw reply

* [PATCH net-next] can: sja1000: fix network statistics update
From: Wolfgang Grandegger @ 2009-09-01 15:29 UTC (permalink / raw)
  To: Linux Netdev List; +Cc: SocketCAN Core Mailing List

The member "tx_bytes" of "struct net_device_stats" should be
incremented when the interrupt is done and an "arbitration
lost error" is a TX error and the statistics should be updated
accordingly.

Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/sja1000/sja1000.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: net-next-2.6/drivers/net/can/sja1000/sja1000.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/sja1000/sja1000.c
+++ net-next-2.6/drivers/net/can/sja1000/sja1000.c
@@ -242,7 +242,6 @@ static netdev_tx_t sja1000_start_xmit(st
 					    struct net_device *dev)
 {
 	struct sja1000_priv *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	struct can_frame *cf = (struct can_frame *)skb->data;
 	uint8_t fi;
 	uint8_t dlc;
@@ -276,7 +275,6 @@ static netdev_tx_t sja1000_start_xmit(st
 	for (i = 0; i < dlc; i++)
 		priv->write_reg(priv, dreg++, cf->data[i]);
 
-	stats->tx_bytes += dlc;
 	dev->trans_start = jiffies;
 
 	can_put_echo_skb(skb, dev, 0);
@@ -428,7 +426,7 @@ static int sja1000_err(struct net_device
 		dev_dbg(dev->dev.parent, "arbitration lost interrupt\n");
 		alc = priv->read_reg(priv, REG_ALC);
 		priv->can.can_stats.arbitration_lost++;
-		stats->rx_errors++;
+		stats->tx_errors++;
 		cf->can_id |= CAN_ERR_LOSTARB;
 		cf->data[0] = alc & 0x1f;
 	}
@@ -486,6 +484,7 @@ irqreturn_t sja1000_interrupt(int irq, v
 
 		if (isrc & IRQ_TI) {
 			/* transmission complete interrupt */
+		  	stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xf;
 			stats->tx_packets++;
 			can_get_echo_skb(dev, 0);
 			netif_wake_queue(dev);

^ permalink raw reply

* Re: UDP is bypassing qdisc statistics ....
From: Eric Dumazet @ 2009-09-01 15:28 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Patrick McHardy, Mark Smith, Jarek Poplawski, netdev, davem
In-Reply-To: <alpine.DEB.1.10.0909011504030.12112@V090114053VZO-1>

Christoph Lameter a écrit :
> On Tue, 1 Sep 2009, Eric Dumazet wrote:
> 
>> Hmm, my bnx2 still displays correct info here (BCM5708S) ; so maybe Christoph has a
>> real multiqueue NIC adapter ? I thought he mentioned a mono queue NIC earlier.
> 
> I have no clue if it is or not. I have never used those features.
> 
> dmesg says:
> 
> Broadcom NetXtreme II BCM5709 1000Base-T (C0) PCI Express
> 
> Is that a multiqueue adapter?

You should see that in /proc/interrupts, if I correctly understand bnx2.c

Just to be sure :
With following patch I got in my syslog :

[    8.789048] rx_rings=1 real_num_tx_queues=1
[    9.005700] rx_rings=1 real_num_tx_queues=1

So my bnx2 is mono-queue :(


diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 06b9011..573d6b3 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -6144,6 +6144,7 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
 	bp->dev->real_num_tx_queues = bp->num_tx_rings;

 	bp->num_rx_rings = bp->irq_nvecs;
+	pr_err("rx_rings=%d real_num_tx_queues=%d\n", bp->num_rx_rings,  bp->num_tx_rings);
 }

 /* Called with rtnl_lock */



^ permalink raw reply related

* [PATCH net-next] can: add can_free_echo_skb() for upcoming drivers
From: Wolfgang Grandegger @ 2009-09-01 15:26 UTC (permalink / raw)
  To: Linux Netdev List; +Cc: SocketCAN Core Mailing List

This patch adds the function can_free_echo_skb to the CAN
device interface to allow upcoming drivers to release echo
skb's in case of error.

Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/dev.c   |   18 +++++++++++++++++-
 include/linux/can/dev.h |    1 +
 2 files changed, 18 insertions(+), 1 deletion(-)

Index: net-next-2.6/drivers/net/can/dev.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/dev.c
+++ net-next-2.6/drivers/net/can/dev.c
@@ -315,7 +315,7 @@ void can_get_echo_skb(struct net_device 
 {
 	struct can_priv *priv = netdev_priv(dev);
 
-	if ((dev->flags & IFF_ECHO) && priv->echo_skb[idx]) {
+	if (priv->echo_skb[idx]) {
 		netif_rx(priv->echo_skb[idx]);
 		priv->echo_skb[idx] = NULL;
 	}
@@ -323,6 +323,22 @@ void can_get_echo_skb(struct net_device 
 EXPORT_SYMBOL_GPL(can_get_echo_skb);
 
 /*
+  * Remove the skb from the stack and free it.
+  *
+  * The function is typically called when TX failed.
+  */
+void can_free_echo_skb(struct net_device *dev, int idx)
+{
+	struct can_priv *priv = netdev_priv(dev);
+
+	if (priv->echo_skb[idx]) {
+		kfree_skb(priv->echo_skb[idx]);
+		priv->echo_skb[idx] = NULL;
+	}
+}
+EXPORT_SYMBOL_GPL(can_free_echo_skb);
+
+/*
  * CAN device restart for bus-off recovery
  */
 void can_restart(unsigned long data)
Index: net-next-2.6/include/linux/can/dev.h
===================================================================
--- net-next-2.6.orig/include/linux/can/dev.h
+++ net-next-2.6/include/linux/can/dev.h
@@ -66,5 +66,6 @@ void can_bus_off(struct net_device *dev)
 
 void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx);
 void can_get_echo_skb(struct net_device *dev, int idx);
+void can_free_echo_skb(struct net_device *dev, int idx);
 
 #endif /* CAN_DEV_H */

^ permalink raw reply

* Re: netconsole as normal console for userspace messages?
From: Matt Mackall @ 2009-09-01 15:15 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: Arkadiusz Miskiewicz, netdev
In-Reply-To: <20090901101612.GB5222@ff.dom.local>

On Tue, 2009-09-01 at 10:16 +0000, Jarek Poplawski wrote:
> On 30-08-2009 02:12, Arkadiusz Miskiewicz wrote:
> > Hi,
> Hi,
> 
> > 
> > Can netconsole be somehow used to see userspace messages, too? Something 
> > similar to console=ttySX... just =netconsole.
> > 
> 
> AFAIK it can't, but AFAICR some time ago the netconsole maintainer
> gave some hope to some Debian guy with a similar question.

It is, as they say, just a simple matter of programming to get a full
bidirectional console out of it. As cool as that would be, I just
haven't had time for it.

-- 
http://selenic.com : development and support for Mercurial and Linux



^ permalink raw reply

* Re: UDP is bypassing qdisc statistics ....
From: Christoph Lameter @ 2009-09-01 19:05 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Patrick McHardy, Mark Smith, Jarek Poplawski, netdev, davem
In-Reply-To: <4A9D3687.2020101@gmail.com>

On Tue, 1 Sep 2009, Eric Dumazet wrote:

> Hmm, my bnx2 still displays correct info here (BCM5708S) ; so maybe Christoph has a
> real multiqueue NIC adapter ? I thought he mentioned a mono queue NIC earlier.

I have no clue if it is or not. I have never used those features.

dmesg says:

Broadcom NetXtreme II BCM5709 1000Base-T (C0) PCI Express

Is that a multiqueue adapter?

^ permalink raw reply

* RE: [PATCHv5 3/3] vhost_net: a kernel-level virtio server
From: Xin, Xiaohui @ 2009-09-01 14:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: mst@redhat.com, netdev@vger.kernel.org,
	virtualization@lists.linux-foundation.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, mingo@elte.hu, linux-mm@kvack.org,
	akpm@linux-foundation.org, hpa@zytor.com,
	gregory.haskins@gmail.com
In-Reply-To: <200908311723.34067.arnd@arndb.de>

>I don't think we should do that with the tun/tap driver. By design, tun/tap is a way to interact >with the
>networking stack as if coming from a device. The only way this connects to an external >adapter is through
>a bridge or through IP routing, which means that it does not correspond to a specific NIC.
>I have worked on a driver I called 'macvtap' in lack of a better name, to add a new tap >frontend to
>the 'macvlan' driver. Since macvlan lets you add slaves to a single NIC device, this gives you >a direct
>connection between one or multiple tap devices to an external NIC, which works a lot better >than when
>you have a bridge inbetween. There is also work underway to add a bridging capability to >macvlan, so
>you can communicate directly between guests like you can do with a bridge.
>Michael's vhost_net can plug into the same macvlan infrastructure, so the work is >complementary.

We use TUN/TAP device to implement the prototype, and agree that it's not the only
choice here. We'd compare the two if possible.
And what we cares more about is the modification in the kernel like the net_dev and 
skb structures' modifications, thanks.

Thanks
Xiaohui

-----Original Message-----
From: Arnd Bergmann [mailto:arnd@arndb.de] 
Sent: Monday, August 31, 2009 11:24 PM
To: Xin, Xiaohui
Cc: mst@redhat.com; netdev@vger.kernel.org; virtualization@lists.linux-foundation.org; kvm@vger.kernel.org; linux-kernel@vger.kernel.org; mingo@elte.hu; linux-mm@kvack.org; akpm@linux-foundation.org; hpa@zytor.com; gregory.haskins@gmail.com
Subject: Re: [PATCHv5 3/3] vhost_net: a kernel-level virtio server

On Monday 31 August 2009, Xin, Xiaohui wrote:
> 
> Hi, Michael
> That's a great job. We are now working on support VMDq on KVM, and since the VMDq hardware presents L2 sorting
> based on MAC addresses and VLAN tags, our target is to implement a zero copy solution using VMDq.

I'm also interested in helping there, please include me in the discussions.

> We stared
> from the virtio-net architecture. What we want to proposal is to use AIO combined with direct I/O:
> 1) Modify virtio-net Backend service in Qemu to submit aio requests composed from virtqueue.

right, that sounds useful.

> 2) Modify TUN/TAP device to support aio operations and the user space buffer directly mapping into the host kernel.
> 3) Let a TUN/TAP device binds to single rx/tx queue from the NIC.

I don't think we should do that with the tun/tap driver. By design, tun/tap is a way to interact with the
networking stack as if coming from a device. The only way this connects to an external adapter is through
a bridge or through IP routing, which means that it does not correspond to a specific NIC.

I have worked on a driver I called 'macvtap' in lack of a better name, to add a new tap frontend to
the 'macvlan' driver. Since macvlan lets you add slaves to a single NIC device, this gives you a direct
connection between one or multiple tap devices to an external NIC, which works a lot better than when
you have a bridge inbetween. There is also work underway to add a bridging capability to macvlan, so
you can communicate directly between guests like you can do with a bridge.

Michael's vhost_net can plug into the same macvlan infrastructure, so the work is complementary.

> 4) Modify the net_dev and skb structure to permit allocated skb to use user space directly mapped payload
> buffer address rather then kernel allocated.

yes.

> As zero copy is also your goal, we are interested in what's in your mind, and would like to collaborate with you if possible.
> BTW, we will send our VMDq write-up very soon.

Ok, cool.

	Arnd <><

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: UDP is bypassing qdisc statistics ....
From: Eric Dumazet @ 2009-09-01 14:58 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: Christoph Lameter, Mark Smith, Jarek Poplawski, netdev, davem
In-Reply-To: <4A9D2DBF.8030200@trash.net>

Patrick McHardy a écrit :
> Christoph Lameter wrote:
>> Eric: This occurs with a Broadcom driver (bnx2). There is only one
>> network device up and the IP statistics are correctly incremented.
> 
> That explains it. The bnx2 driver uses multiple TX queues, but
> tc_dump_qdisc() only dumps the statistics from queue number 0.
> 
> Not sure whether we should sum them up or dump the statistics
> from each queue (or both). Summing them up avoids userspace
> visible changes when drivers are converted to multiq.

Ok mystery solved, partially at least :)

Hmm, my bnx2 still displays correct info here (BCM5708S) ; so maybe Christoph has a
real multiqueue NIC adapter ? I thought he mentioned a mono queue NIC earlier.

Dumping stats for each queue would be better for admin point of view IMHO
(restricted to real_num_tx_queues I guess, since bnx2 allocates 8 queues per device.



^ permalink raw reply

* Re: UDP is bypassing qdisc statistics ....
From: Christoph Lameter @ 2009-09-01 18:29 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Eric Dumazet, Mark Smith, Jarek Poplawski, netdev, davem
In-Reply-To: <4A9D2DBF.8030200@trash.net>

On Tue, 1 Sep 2009, Patrick McHardy wrote:

> Christoph Lameter wrote:
> > Eric: This occurs with a Broadcom driver (bnx2). There is only one
> > network device up and the IP statistics are correctly incremented.
>
> That explains it. The bnx2 driver uses multiple TX queues, but
> tc_dump_qdisc() only dumps the statistics from queue number 0.
>
> Not sure whether we should sum them up or dump the statistics
> from each queue (or both). Summing them up avoids userspace
> visible changes when drivers are converted to multiq.

Well I have almost finished a /proc/net/qdisc_stats that shows *all*
qdisc queues. Did this primarily for debugging since I do not know too
much about the netlink stuff.



^ permalink raw reply

* Re: Network hangs with 2.6.30.5
From: Holger Hoffstaette @ 2009-09-01 14:17 UTC (permalink / raw)
  To: netdev
In-Reply-To: <7D2F0769-2994-4BB8-B107-DEF2B1346B3A@gmail.com>

On Tue, 01 Sep 2009 19:50:38 +1000, Clifford Heath wrote:

> I sent this email last Friday, but received no response.
> 
> As far as I can see, some recent work in the stable Linux kernel has
> broken the TCP stack, at least on my (pretty common) hardware. Can anyone
> confirm that they've seen and perhaps fixed similar symptoms, or at least
> tell me what else I need to do to help them identify the problem?

Unfortunately I can't offer clues but *can* confirm that every kernel
since .30 has also exhibited strange networking regressions, to the point
where I had to give up even trying to understand from the changelogs who
was changing what, when, where and why and what the actual symptom is.

With .29 everything works fine; everything since .30 has trouble with
either samba or squid (both of which are the main purposes of that
particular machine). After all the initial regressions with epoll in .30 I
suspected that and built squid without epoll, but no improvement;
connecting over the network is broken (spurious connections, timeouts,
sometimes partial successes) whereas using squid from localhost (via
loopback) seems to work fine. It also seems to work fine for a friend on
.30 so the software is unlikely to be the problem.

I do have an older Intel Gbit card identified thusly:
00:0b.0 Ethernet controller: Intel Corporation 82545GM Gigabit Ethernet Controller (rev 04)

and enabled all sorts of offloading:

$ethtool -k eth0     
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp segmentation offload: on
udp fragmentation offload: off
generic segmentation offload: on

Maybe that is the culprit, as Eric Dumazet suspected in his mail..I will
try the latest .30 stable again without that, but in any case something is
indeed very broken in there.

-h



^ permalink raw reply

* Re: UDP is bypassing qdisc statistics ....
From: Patrick McHardy @ 2009-09-01 14:20 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Eric Dumazet, Mark Smith, Jarek Poplawski, netdev, davem
In-Reply-To: <alpine.DEB.1.10.0909011358030.15578@V090114053VZO-1>

Christoph Lameter wrote:
> Eric: This occurs with a Broadcom driver (bnx2). There is only one
> network device up and the IP statistics are correctly incremented.

That explains it. The bnx2 driver uses multiple TX queues, but
tc_dump_qdisc() only dumps the statistics from queue number 0.

Not sure whether we should sum them up or dump the statistics
from each queue (or both). Summing them up avoids userspace
visible changes when drivers are converted to multiq.

^ permalink raw reply

* Re: UDP is bypassing qdisc statistics ....
From: Christoph Lameter @ 2009-09-01 18:03 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Mark Smith, Jarek Poplawski, netdev, davem
In-Reply-To: <20090901063726.GA5222@ff.dom.local>

Eric: This occurs with a Broadcom driver (bnx2). There is only one
network device up and the IP statistics are correctly incremented.

#ip ro
10.2.36.0/24 dev eth0  proto kernel  scope link  src 10.2.36.121
default via 10.2.36.3 dev eth0
#ip ro get 10.2.36.120
10.2.36.120 dev eth0  src 10.2.36.121
    cache  mtu 1500 advmss 1460 hoplimit 64
ip ro get 239.0.192.2
multicast 239.0.192.2 dev eth0  src 10.2.36.121
    cache <mc>  mtu 1500 advmss 1460 hoplimit 64

dmesg:

[    1.560094] Broadcom NetXtreme II Gigabit Ethernet Driver bnx2 v2.0.1
(May 6, 2009)
[    1.560192]   alloc irq_desc for 36 on node 0
[    1.560193]   alloc kstat_irqs on node 0
[    1.560197] alloc irq_2_iommu on node 0
[    1.560204] bnx2 0000:01:00.0: PCI INT A -> GSI 36 (level, low) -> IRQ
36
[    1.560275] bnx2 0000:01:00.0: setting latency timer to 64
[    1.560394] bnx2 0000:01:00.0: firmware: requesting
bnx2/bnx2-mips-09-4.6.17.fw


$ netstat -su
IcmpMsg:
    InType0: 4
    InType3: 1
    OutType3: 1
    OutType8: 4
Udp:
    44363 packets received
    0 packets to unknown port received.
    0 packet receive errors
    4363620 packets sent
    SndbufErrors: 738519
UdpLite:
IpExt:
    InMcastPkts: 1289
    OutMcastPkts: 5057780
    InOctets: 13956676
    OutOctets: 1672676365
    InMcastOctets: 36164
    OutMcastOctets: 1658949880

(Your patch to account for TX errors was applied)

clameter@rd-gateway3-deb64:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:21:9b:8f:9f:1b
          inet addr:10.2.36.121  Bcast:10.2.36.255  Mask:255.255.255.0
          inet6 addr: fe80::221:9bff:fe8f:9f1b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:50091 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4367178 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:14928488 (14.2 MiB)  TX bytes:1509122809 (1.4 GiB)
          Interrupt:36 Memory:d6000000-d6012800

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:89 errors:0 dropped:0 overruns:0 frame:0
          TX packets:89 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:7114 (6.9 KiB)  TX bytes:7114 (6.9 KiB)




^ permalink raw reply

* [PATCH] sky2: Use 32bit read to read Y2_VAUX_AVAIL
From: Mike McCormack @ 2009-09-01 13:54 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

B0_CTST is a 24bit register according to the vendor driver (sk98lin).
A 16bit read on B0_CTST will always return 0 for Y2_VAUX_AVAIL (1<<16),
 so use a 32bit read when testing Y2_VAUX_AVAIL

Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
 drivers/net/sky2.c |    2 +-
 drivers/net/sky2.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7108b12..d1f3b46 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -273,7 +273,7 @@ static void sky2_power_aux(struct sky2_hw *hw)
 			    Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
 
 	/* switch power to VAUX */
-	if (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL)
+	if (sky2_read32(hw, B0_CTST) & Y2_VAUX_AVAIL)
 		sky2_write8(hw, B0_POWER_CTRL,
 			    (PC_VAUX_ENA | PC_VCC_ENA |
 			     PC_VAUX_ON | PC_VCC_OFF));
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 34042ff..e0f23a1 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -260,7 +260,7 @@ enum csr_regs {
 	Y2_CFG_AER      = 0x1d00,	/* PCI Advanced Error Report region */
 };
 
-/*	B0_CTST			16 bit	Control/Status register */
+/*	B0_CTST			24 bit	Control/Status register */
 enum {
 	Y2_VMAIN_AVAIL	= 1<<17,/* VMAIN available (YUKON-2 only) */
 	Y2_VAUX_AVAIL	= 1<<16,/* VAUX available (YUKON-2 only) */
-- 
1.5.6.5


^ permalink raw reply related

* Re: [Bugme-new] [Bug 13803] New: hso: Tx timed out.
From: Fathi Boudra @ 2009-09-01 13:44 UTC (permalink / raw)
  To: Jan Dumon; +Cc: linux-usb, netdev, bugzilla-daemon, bugme-daemon, Andrew Morton
In-Reply-To: <4A71991E.90308@option.com>

On Thu, Jul 30, 2009 at 2:59 PM, Jan Dumon<j.dumon@option.com> wrote:
> Is still possible to send AT commands and get any network traffic through
> once this problem occurred, or is there no communication at all possible
> with the module ?

no it's not possible to send other AT command.
Minicom fails to connect on any ttyHSx port.

> Can you try again with debug enabled (module parameter debug=0x1F) ?

find attached the log file.

> Since it works on USB 1.1 but not on USB 2.0, my first guess would be that
> there's something wrong with the host controller or the host controller
> driver.

I should also mention I'm using a Transmeta Crusoe CPU board.

^ permalink raw reply

* Re: [PATCH 3/3] Revert Backoff [v3]: Calculate TCP's connection close threshold as a time value.
From: Ilpo Järvinen @ 2009-09-01 13:41 UTC (permalink / raw)
  To: Damian Lukowski; +Cc: Netdev, David Miller
In-Reply-To: <4A9D0554.1010508@tvk.rwth-aachen.de>

On Tue, 1 Sep 2009, Damian Lukowski wrote:

>> I'm fine with this approach as no matter what we would do the previous
>> approach just isn't fitting the new model that breaks the assumptions
>> behind the previous model. I don't expect the change in the timing to be
>> significant for anybody unless one did copy our code exactly somewhere
>> (including rtt calculation). ...but if somebody has some objections in
>> this, please speak up! After all, it will change how the sysctl behaves.
>>
>> Perhaps we should mention this artificial timing change in ip-sysctl.txt
>> too...?
>>
>> It would be worth to do a trivial pull-the-plug testing comparing this
>> and the previous approach in the rto < TCP_RTO_MIN region without any
>> icmps to verify that this didn't change the timing a bit, afaict, it
>> shouldn't (If you didn't do that already). Just to be on very sure grounds.
>
> thanks for reviewing all the patches.
> Which region do you mean exactly? I mean, rto < TCP_RTO_MIN should be
> impossible by definition, shouldn't it?

Right, I was careless in the wording. I meant with a low rtt'ed flow which 
lower bounds rto to TCP_RTO_MIN.

> However, there are differences between new and old timing, which maybe
> should be discussed. The new timeout values can deviate from the old
> approach by up to the value of the last actual RTO. Consider following:
>
> retries2 is set to 15 and MIN_RTO/MAX_RTO are 0.2 and 120 seconds,
> respectively. retrans_timed_out() calculates 924.6 seconds as timeout,
> regardless of the actual RTO.

My point was to take a connection which has rtt below the lower bound and 
this the actual RTO should be at TCP_RTO_MIN.

> Assume, that rtt measurement calculates
> 0.4 seconds as RTO before connectivity breaks.
> An unpatched TCP - as well as patched TCP without ICMPs - will do the
> standard backoff procedure and fire it's 15th retransmission after 924.4
> seconds, i.e. 0.2 seconds before the calculated timeout of 924.6 seconds.
>
> Then, patched TCP will wait for the next RTO, before checking again if the
> timeout expired - and will finally time out 119.8 seconds later
> than calculated. However, unpatched TCP will also wait until the 16th RTO
> (924.4 + 120 seconds) and then time out. So in this case, the effective
> timeouts for unpatched and patched TCP without ICMPs are the same, though
> not intended by retransmits_timed_out().

If RTO value was > MIN_RTO to begin with there will be the obvious 
difference.

> I have made a simple test with a netem delay of 30ms at the sender,
> and retries2 set to 6:
> Unpatched TCP times out after ~29.7 seconds,
> patched TCP without ICMPs also after ~29.7 seconds,

Thanks for your efforts in this, these times I was mostly interested in. 
Seems very good.

> Anyway, what is the procedure for further updates?
>
> As David has applied the current patches, I assume that I should post a 
> new series of two subpatches; one concerning your suggestions and the 
> second concerning the ip-sysctl.txt update?

Your guessed right, once applied no updates to the previous version but 
you take what Dave currently has as base (in net-next) and build on top of 
that.


-- 
  i.

^ permalink raw reply

* [PATCH] sky2: Create buffer alloc and free helpers
From: Mike McCormack @ 2009-09-01 13:21 UTC (permalink / raw)
  To: davem; +Cc: netdev

Refactor similar two sections of code that free buffers into one.
Only call tx_init if all buffer allocations succeed.

Signed-off-by: Mike McCormack <mikem@ring3k.org>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
---
 drivers/net/sky2.c |  113 +++++++++++++++++++++++++++------------------------
 1 files changed, 60 insertions(+), 53 deletions(-)

diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index c7c0a5b..0e4c5c1 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1399,6 +1399,61 @@ nomem:
 	return -ENOMEM;
 }
 
+static int sky2_alloc_buffers(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+
+	/* must be power of 2 */
+	sky2->tx_le = pci_alloc_consistent(hw->pdev,
+					   sky2->tx_ring_size *
+					   sizeof(struct sky2_tx_le),
+					   &sky2->tx_le_map);
+	if (!sky2->tx_le)
+		goto nomem;
+
+	sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
+				GFP_KERNEL);
+	if (!sky2->tx_ring)
+		goto nomem;
+
+	sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
+					   &sky2->rx_le_map);
+	if (!sky2->rx_le)
+		goto nomem;
+	memset(sky2->rx_le, 0, RX_LE_BYTES);
+
+	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
+				GFP_KERNEL);
+	if (!sky2->rx_ring)
+		goto nomem;
+
+	return 0;
+nomem:
+	return -ENOMEM;
+}
+
+static void sky2_free_buffers(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+
+	if (sky2->rx_le) {
+		pci_free_consistent(hw->pdev, RX_LE_BYTES,
+				    sky2->rx_le, sky2->rx_le_map);
+		sky2->rx_le = NULL;
+	}
+	if (sky2->tx_le) {
+		pci_free_consistent(hw->pdev,
+				    sky2->tx_ring_size * sizeof(struct sky2_tx_le),
+				    sky2->tx_le, sky2->tx_le_map);
+		sky2->tx_le = NULL;
+	}
+	kfree(sky2->tx_ring);
+	kfree(sky2->rx_ring);
+
+	sky2->tx_ring = NULL;
+	sky2->rx_ring = NULL;
+}
+
 /* Bring up network interface. */
 static int sky2_up(struct net_device *dev)
 {
@@ -1406,7 +1461,7 @@ static int sky2_up(struct net_device *dev)
 	struct sky2_hw *hw = sky2->hw;
 	unsigned port = sky2->port;
 	u32 imask, ramsize;
-	int cap, err = -ENOMEM;
+	int cap, err;
 	struct net_device *otherdev = hw->dev[sky2->port^1];
 
 	/*
@@ -1425,32 +1480,12 @@ static int sky2_up(struct net_device *dev)
 
 	netif_carrier_off(dev);
 
-	/* must be power of 2 */
-	sky2->tx_le = pci_alloc_consistent(hw->pdev,
-					   sky2->tx_ring_size *
-					   sizeof(struct sky2_tx_le),
-					   &sky2->tx_le_map);
-	if (!sky2->tx_le)
-		goto err_out;
-
-	sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
-				GFP_KERNEL);
-	if (!sky2->tx_ring)
+	err = sky2_alloc_buffers(sky2);
+	if (err)
 		goto err_out;
 
 	tx_init(sky2);
 
-	sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
-					   &sky2->rx_le_map);
-	if (!sky2->rx_le)
-		goto err_out;
-	memset(sky2->rx_le, 0, RX_LE_BYTES);
-
-	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
-				GFP_KERNEL);
-	if (!sky2->rx_ring)
-		goto err_out;
-
 	sky2_mac_init(hw, port);
 
 	/* Register is number of 4K blocks on internal RAM buffer. */
@@ -1507,22 +1542,7 @@ static int sky2_up(struct net_device *dev)
 	return 0;
 
 err_out:
-	if (sky2->rx_le) {
-		pci_free_consistent(hw->pdev, RX_LE_BYTES,
-				    sky2->rx_le, sky2->rx_le_map);
-		sky2->rx_le = NULL;
-	}
-	if (sky2->tx_le) {
-		pci_free_consistent(hw->pdev,
-				    sky2->tx_ring_size * sizeof(struct sky2_tx_le),
-				    sky2->tx_le, sky2->tx_le_map);
-		sky2->tx_le = NULL;
-	}
-	kfree(sky2->tx_ring);
-	kfree(sky2->rx_ring);
-
-	sky2->tx_ring = NULL;
-	sky2->rx_ring = NULL;
+	sky2_free_buffers(sky2);
 	return err;
 }
 
@@ -1877,20 +1897,7 @@ static int sky2_down(struct net_device *dev)
 
 	sky2_rx_clean(sky2);
 
-	pci_free_consistent(hw->pdev, RX_LE_BYTES,
-			    sky2->rx_le, sky2->rx_le_map);
-	kfree(sky2->rx_ring);
-
-	pci_free_consistent(hw->pdev,
-			    sky2->tx_ring_size * sizeof(struct sky2_tx_le),
-			    sky2->tx_le, sky2->tx_le_map);
-	kfree(sky2->tx_ring);
-
-	sky2->tx_le = NULL;
-	sky2->rx_le = NULL;
-
-	sky2->rx_ring = NULL;
-	sky2->tx_ring = NULL;
+	sky2_free_buffers(sky2);
 
 	return 0;
 }
-- 
1.5.6.5



^ permalink raw reply related

* Re: [PATCH 3/3] Revert Backoff [v3]: Calculate TCP's connection close threshold as a time value.
From: Ilpo Järvinen @ 2009-09-01 13:23 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Damian Lukowski, Netdev
In-Reply-To: <4A9D12AE.8050109@gmail.com>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 4264 bytes --]

On Tue, 1 Sep 2009, Eric Dumazet wrote:

> Damian Lukowski a écrit :
>> Eric Dumazet schrieb:
>>> Damian Lukowski a écrit :
>>>> RFC 1122 specifies two threshold values R1 and R2 for connection timeouts,
>>>> which may represent a number of allowed retransmissions or a timeout value.
>>>> Currently linux uses sysctl_tcp_retries{1,2} to specify the thresholds
>>>> in number of allowed retransmissions.
>>>>
>>>> For any desired threshold R2 (by means of time) one can specify tcp_retries2
>>>> (by means of number of retransmissions) such that TCP will not time out
>>>> earlier than R2. This is the case, because the RTO schedule follows a fixed
>>>> pattern, namely exponential backoff.
>>>>
>>>> However, the RTO behaviour is not predictable any more if RTO backoffs can be
>>>> reverted, as it is the case in the draft
>>>> "Make TCP more Robust to Long Connectivity Disruptions"
>>>> (http://tools.ietf.org/html/draft-zimmermann-tcp-lcd).
>>>>
>>>> In the worst case TCP would time out a connection after 3.2 seconds, if the
>>>> initial RTO equaled MIN_RTO and each backoff has been reverted.
>>>>
>>>> This patch introduces a function retransmits_timed_out(N),
>>>> which calculates the timeout of a TCP connection, assuming an initial
>>>> RTO of MIN_RTO and N unsuccessful, exponentially backed-off retransmissions.
>>>>
>>>> Whenever timeout decisions are made by comparing the retransmission counter
>>>> to some value N, this function can be used, instead.
>>>>
>>>> The meaning of tcp_retries2 will be changed, as many more RTO retransmissions
>>>> can occur than the value indicates. However, it yields a timeout which is
>>>> similar to the one of an unpatched, exponentially backing off TCP in the same
>>>> scenario. As no application could rely on an RTO greater than MIN_RTO, there
>>>> should be no risk of a regression.
>>>>
>>>> Signed-off-by: Damian Lukowski <damian@tvk.rwth-aachen.de>
>>>> ---
>>>>  include/net/tcp.h    |   18 ++++++++++++++++++
>>>>  net/ipv4/tcp_timer.c |   11 +++++++----
>>>>  2 files changed, 25 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>>>> index c35b329..17d1a88 100644
>>>> --- a/include/net/tcp.h
>>>> +++ b/include/net/tcp.h
>>>> @@ -1247,6 +1247,24 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu
>>>>  #define tcp_for_write_queue_from_safe(skb, tmp, sk)			\
>>>>  	skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp)
>>>>
>>>> +static inline bool retransmits_timed_out(const struct sock *sk,
>>>> +					 unsigned int boundary)
>>>> +{
>>>> +	int limit, K;
>>>> +	if (!inet_csk(sk)->icsk_retransmits)
>>>> +		return false;
>>>> +
>>>> +	K = ilog2(TCP_RTO_MAX/TCP_RTO_MIN);
>>>> +
>>>> +	if (boundary <= K)
>>>> +		limit = ((2 << boundary) - 1) * TCP_RTO_MIN;
>>>> +	else
>>>> +		limit = ((2 << K) - 1) * TCP_RTO_MIN +
>>>> +			(boundary - K) * TCP_RTO_MAX;
>>> Doing this computation might allow us to respect RFC 1122 here :
>>>
>>> "The value of R2 SHOULD correspond to at least 100 seconds."
>>>
>>> adding a third parameter to retransmits_timed_out(), min_limit,
>>> being 100*HZ if sysctl_tcp_retries2 was used...
>>>
>>> limit = min(min_limit, limit);
>>
>> Hi.
>> Hm, with this restriction, we would make it a MUST instead of a SHOULD.
>> The current approach does also allow retries2 values, which can yield
>> lower timeouts than 100 seconds.
>> I could implement the min_timeout, but in my opinion, the 100 seconds
>> shouldn't be enforced. We could make a patch later, which introduces a
>> lower limit to the sysctl, so the user gets feedback, if he tries to adjust
>> the limit below the recommended 100 seconds, or something like that.
>>
>
> Fair enough, this 100 seconds limit is only a hint, not an enforcement.

Please excuse my curiousness. Were you aiming for some particular case 
with this thought of a lower bound? ...To me it seems quite a small 
difference. I can understand that one can construct a scenario with small 
retries and heterogenous rtts but how significant that is in practice 
whether we timeout 100s or slightly earlier the small rtt'ed ones (as the 
enforced limits are anyway quite strict I doubt we really would care that 
much on those hanging around for long).

-- 
  i.

^ permalink raw reply

* Re: 2.6.31 ARP related problems with multiple macvlan NICs
From: Eric W. Biederman @ 2009-09-01 13:20 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: netdev, Eric Dumazet
In-Reply-To: <Pine.LNX.4.64.0909011347350.19568@zuben.voltaire.com>

Or Gerlitz <ogerlitz@voltaire.com> writes:

> Using multiple (e.g 2) macvlan devices set over the same uplink NIC
> and 2.6.31-rc7 I can get only one of the macvlan devices to respond on
> arp request where the same scheme works fine on 2.6.29.1 and 2.6.30.
>
> The only devices for which the system responds on ARP request is the
> first match in the routing table, e.g mv0 below. Next are the commands
> I am using to set the environment that reproduces the problem.
>
> Looking on net/ipv4/arp.c I do someting that may be related which
> was commited for 2.6.30 and reverted for -stable and .31 so the
> fact that this test actually works with 2.6.29.1/2.6.30 makes me
> think that the problem I see is not directly connected to the "ipv4: arp
> announce, arp_proxy and windows ip conflict verification" commit/revert.
>
> The problem is also not directly related to macvlan, I think, e.g
> I have the same issue when having multiple veth pairs connected
> to a bridge, only ping to/through the first routing hit works.

I just tested.  If the two macvlans are in separate network namespaces
all is well, so definitely not macvlan.

As you have observed there are no real changes to arp.c

Interesting I can reproduce this to machines on the same network
segment but not to machines on different network segments.

Weird.


Eric

^ permalink raw reply

* Re: [PATCH 18/19] wireless: convert drivers to netdev_tx_t
From: John W. Linville @ 2009-09-01 13:18 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: David Miller, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20090901055130.266010870-ZtmgI6mnKB3QT0dZR+AlfA@public.gmane.org>

On Mon, Aug 31, 2009 at 10:50:57PM -0700, Stephen Hemminger wrote:
> Mostly just simple conversions:
>   * ray_cs had bogus return of NET_TX_LOCKED but driver
>     was not using NETIF_F_LLTX
>   * hostap and ipw2x00 had some code that returned value
>     from a called function that also had to change to return netdev_tx_t
> 
> Signed-off-by: Stephen Hemminger <shemminger-ZtmgI6mnKB3QT0dZR+AlfA@public.gmane.org>

ACK

-- 
John W. Linville		Someday the world will need a hero, and you
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org			might be all we have.  Be ready.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: Does ESP support 64 bit sequence numbering for authentication hash ?
From: Steffen Klassert @ 2009-09-01 12:42 UTC (permalink / raw)
  To: Alex Badea; +Cc: Herbert Xu, djenkins, linux-crypto, netdev
In-Reply-To: <4A9D1239.8000900@ixiacom.com>

On Tue, Sep 01, 2009 at 03:23:21PM +0300, Alex Badea wrote:
> 
> A while ago I implemented a rough version of ESN support. It's against
> an ancient 2.6.7 kernel though, and is only superficially tested.
> 
> I suppose there's no reason not to publish them here, if only for
> historical reasons. My apologies to anyone not interested :)
> 

I'll have a look whether I can use some parts of it, thanks.

^ permalink raw reply

* Re: H.245v10+ support in nf_conntrack_h323?
From: Mark Brown @ 2009-09-01 12:32 UTC (permalink / raw)
  To: Andreas Jaggi; +Cc: Patrick McHardy, Jing Min Zhao, netdev
In-Reply-To: <20090901121033.GA18731@urbino.open.ch>

On Tue, Sep 01, 2009 at 02:10:33PM +0200, Andreas Jaggi wrote:

> For me it looks like nf_conntrack_h323 is not only doing connection
> tracking, but also doing protocol enforcement (by dropping packets which
> do not correspond exactly to H.245v7).
> Perhaps there should be a config option to disable the protocol
> enforcement?

It's not going to be a deliberate attempt at enforcement that's the
issue here - doing any substantial enforcement would require a full
decode of the PER messages, involving having a full copy of the (rather
large) ASN.1 in the kernel.  It's much more likely that a shortcut taken
in decoding the message is getting confused by something that the
endpoint is choosing to send, a brief glance at the ASN.1 code certainly
suggests that to me.  Chances are it's not even a new v10 feature that's
causing the issue.

^ permalink raw reply

* Re: [PATCH 3/3] Revert Backoff [v3]: Calculate TCP's connection close threshold as a time value.
From: Eric Dumazet @ 2009-09-01 12:25 UTC (permalink / raw)
  To: Damian Lukowski; +Cc: Netdev
In-Reply-To: <4A9D0A67.6070000@tvk.rwth-aachen.de>

Damian Lukowski a écrit :
> Eric Dumazet schrieb:
>> Damian Lukowski a écrit :
>>> RFC 1122 specifies two threshold values R1 and R2 for connection timeouts,
>>> which may represent a number of allowed retransmissions or a timeout value.
>>> Currently linux uses sysctl_tcp_retries{1,2} to specify the thresholds
>>> in number of allowed retransmissions.
>>>
>>> For any desired threshold R2 (by means of time) one can specify tcp_retries2
>>> (by means of number of retransmissions) such that TCP will not time out
>>> earlier than R2. This is the case, because the RTO schedule follows a fixed
>>> pattern, namely exponential backoff.
>>>
>>> However, the RTO behaviour is not predictable any more if RTO backoffs can be
>>> reverted, as it is the case in the draft
>>> "Make TCP more Robust to Long Connectivity Disruptions"
>>> (http://tools.ietf.org/html/draft-zimmermann-tcp-lcd).
>>>
>>> In the worst case TCP would time out a connection after 3.2 seconds, if the
>>> initial RTO equaled MIN_RTO and each backoff has been reverted.
>>>
>>> This patch introduces a function retransmits_timed_out(N),
>>> which calculates the timeout of a TCP connection, assuming an initial
>>> RTO of MIN_RTO and N unsuccessful, exponentially backed-off retransmissions.
>>>
>>> Whenever timeout decisions are made by comparing the retransmission counter
>>> to some value N, this function can be used, instead.
>>>
>>> The meaning of tcp_retries2 will be changed, as many more RTO retransmissions
>>> can occur than the value indicates. However, it yields a timeout which is
>>> similar to the one of an unpatched, exponentially backing off TCP in the same
>>> scenario. As no application could rely on an RTO greater than MIN_RTO, there
>>> should be no risk of a regression.
>>>
>>> Signed-off-by: Damian Lukowski <damian@tvk.rwth-aachen.de>
>>> ---
>>>  include/net/tcp.h    |   18 ++++++++++++++++++
>>>  net/ipv4/tcp_timer.c |   11 +++++++----
>>>  2 files changed, 25 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>>> index c35b329..17d1a88 100644
>>> --- a/include/net/tcp.h
>>> +++ b/include/net/tcp.h
>>> @@ -1247,6 +1247,24 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu
>>>  #define tcp_for_write_queue_from_safe(skb, tmp, sk)			\
>>>  	skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp)
>>>  
>>> +static inline bool retransmits_timed_out(const struct sock *sk,
>>> +					 unsigned int boundary)
>>> +{
>>> +	int limit, K;
>>> +	if (!inet_csk(sk)->icsk_retransmits)
>>> +		return false;
>>> +
>>> +	K = ilog2(TCP_RTO_MAX/TCP_RTO_MIN);
>>> +
>>> +	if (boundary <= K)
>>> +		limit = ((2 << boundary) - 1) * TCP_RTO_MIN;
>>> +	else
>>> +		limit = ((2 << K) - 1) * TCP_RTO_MIN +
>>> +			(boundary - K) * TCP_RTO_MAX;
>> Doing this computation might allow us to respect RFC 1122 here :
>>  
>> "The value of R2 SHOULD correspond to at least 100 seconds."
>>
>> adding a third parameter to retransmits_timed_out(), min_limit,
>> being 100*HZ if sysctl_tcp_retries2 was used...
>>
>> limit = min(min_limit, limit);
> 
> Hi.
> Hm, with this restriction, we would make it a MUST instead of a SHOULD.
> The current approach does also allow retries2 values, which can yield
> lower timeouts than 100 seconds.
> I could implement the min_timeout, but in my opinion, the 100 seconds
> shouldn't be enforced. We could make a patch later, which introduces a
> lower limit to the sysctl, so the user gets feedback, if he tries to adjust
> the limit below the recommended 100 seconds, or something like that.
> 

Fair enough, this 100 seconds limit is only a hint, not an enforcement.

^ permalink raw reply

* Re: Does ESP support 64 bit sequence numbering for authentication hash ?
From: Alex Badea @ 2009-09-01 12:23 UTC (permalink / raw)
  To: Steffen Klassert; +Cc: Herbert Xu, djenkins, linux-crypto, netdev
In-Reply-To: <20090901120915.GA12646@secunet.com>

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

On 09/01/2009 03:09 PM, Steffen Klassert wrote:
> On Thu, Jan 15, 2009 at 04:56:44PM +1100, Herbert Xu wrote:
>> Dean Jenkins <djenkins@mvista.com> wrote:
>>> Does ESP support 64 bit sequence numbering for use with the
>>> authentication HMAC ?
>> We don't support 64-bit sequence numbers yet.  If you look at
>> struct xfrm_replay_state which is where we store the sequence
>> number internally you'll find that it uses u32s.
>>
>> Patches for 64-bit support are welcome of course.
>>
> 
> Is there actually anybody working on 64-bit sequence number support?
> If not, I'd start to look at it.

A while ago I implemented a rough version of ESN support. It's against
an ancient 2.6.7 kernel though, and is only superficially tested.

I suppose there's no reason not to publish them here, if only for
historical reasons. My apologies to anyone not interested :)


Alex Badea (6):
      xfrm: move xfrm_replay_{check,advance} to their own source file
      xfrm: introduce XFRM_STATE_ESN flag, and extended replay structure
      xfrm: add generic support for replay protection with Extended
Sequence Numbers
      ipsec: Extended Sequence Numbers support for ESP
      ipsec: Extended Sequence Numbers support for AH
      xfrm: add test harness for Extended Sequence Numbers replay
protection algorithm


Best regards,
Alex

[-- Attachment #2: 0001-xfrm-move-xfrm_replay_-check-advance-to-their-own.patch --]
[-- Type: text/x-diff, Size: 3040 bytes --]

>From 2831af26b9783da9b311e8442b0cd19df3f4b422 Mon Sep 17 00:00:00 2001
From: Alex Badea <abadea@ixiacom.com>
Date: Thu, 18 Jun 2009 16:41:06 +0300
Subject: [PATCH] xfrm: move xfrm_replay_{check,advance} to their own source file

---
 src/net/xfrm/Makefile      |    2 +-
 src/net/xfrm/xfrm_replay.c |   46 ++++++++++++++++++++++++++++++++++++++++++++
 src/net/xfrm/xfrm_state.c  |   44 ------------------------------------------
 3 files changed, 47 insertions(+), 45 deletions(-)
 create mode 100644 src/net/xfrm/xfrm_replay.c

diff --git a/src/net/xfrm/Makefile b/src/net/xfrm/Makefile
index 3d076b5..5540fc5 100644
--- a/src/net/xfrm/Makefile
+++ b/src/net/xfrm/Makefile
@@ -3,6 +3,6 @@
 #
 obj-$(CONFIG_CAVIUM) += xfrm_cavium_stub.o
 obj-$(CONFIG_XFRM) += xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o xfrm_output.o \
-	xfrm_export.o
+	xfrm_replay.o xfrm_export.o
 obj-$(CONFIG_XFRM_USER) += xfrm_user.o
 
diff --git a/src/net/xfrm/xfrm_replay.c b/src/net/xfrm/xfrm_replay.c
new file mode 100644
index 0000000..6a7350d
--- /dev/null
+++ b/src/net/xfrm/xfrm_replay.c
@@ -0,0 +1,46 @@
+#include <net/xfrm.h>
+
+int xfrm_replay_check(struct xfrm_state *x, u32 seq)
+{
+	u32 diff;
+
+	seq = ntohl(seq);
+
+	if (unlikely(seq == 0))
+		return -EINVAL;
+
+	if (likely(seq > x->replay.seq))
+		return 0;
+
+	diff = x->replay.seq - seq;
+	if (diff >= x->props.replay_window) {
+		x->stats.replay_window++;
+		return -EINVAL;
+	}
+
+	if (x->replay.bitmap & (1U << diff)) {
+		x->stats.replay++;
+		return -EINVAL;
+	}
+	return 0;
+}
+
+void xfrm_replay_advance(struct xfrm_state *x, u32 seq)
+{
+	u32 diff;
+
+	seq = ntohl(seq);
+
+	if (seq > x->replay.seq) {
+		diff = seq - x->replay.seq;
+		if (diff < x->props.replay_window)
+			x->replay.bitmap = ((x->replay.bitmap) << diff) | 1;
+		else
+			x->replay.bitmap = 1;
+		x->replay.seq = seq;
+	} else {
+		diff = x->replay.seq - seq;
+		x->replay.bitmap |= (1U << diff);
+	}
+}
+
diff --git a/src/net/xfrm/xfrm_state.c b/src/net/xfrm/xfrm_state.c
index e43c5e3..3afa72a 100644
--- a/src/net/xfrm/xfrm_state.c
+++ b/src/net/xfrm/xfrm_state.c
@@ -671,50 +671,6 @@ out:
 }
 
 
-int xfrm_replay_check(struct xfrm_state *x, u32 seq)
-{
-	u32 diff;
-
-	seq = ntohl(seq);
-
-	if (unlikely(seq == 0))
-		return -EINVAL;
-
-	if (likely(seq > x->replay.seq))
-		return 0;
-
-	diff = x->replay.seq - seq;
-	if (diff >= x->props.replay_window) {
-		x->stats.replay_window++;
-		return -EINVAL;
-	}
-
-	if (x->replay.bitmap & (1U << diff)) {
-		x->stats.replay++;
-		return -EINVAL;
-	}
-	return 0;
-}
-
-void xfrm_replay_advance(struct xfrm_state *x, u32 seq)
-{
-	u32 diff;
-
-	seq = ntohl(seq);
-
-	if (seq > x->replay.seq) {
-		diff = seq - x->replay.seq;
-		if (diff < x->props.replay_window)
-			x->replay.bitmap = ((x->replay.bitmap) << diff) | 1;
-		else
-			x->replay.bitmap = 1;
-		x->replay.seq = seq;
-	} else {
-		diff = x->replay.seq - seq;
-		x->replay.bitmap |= (1U << diff);
-	}
-}
-
 int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl)
 {
 	int i;
-- 
1.5.4.3


[-- Attachment #3: 0002-xfrm-introduce-XFRM_STATE_ESN-flag-and-extended-re.patch --]
[-- Type: text/x-diff, Size: 921 bytes --]

>From dcfe6e052d43cac53d40e031b857b5f1ce06a26b Mon Sep 17 00:00:00 2001
From: Alex Badea <abadea@ixiacom.com>
Date: Thu, 18 Jun 2009 16:46:44 +0300
Subject: [PATCH] xfrm: introduce XFRM_STATE_ESN flag, and extended replay structure

---
 src/include/linux/xfrm.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/src/include/linux/xfrm.h b/src/include/linux/xfrm.h
index 5bd2274..00b1f57 100644
--- a/src/include/linux/xfrm.h
+++ b/src/include/linux/xfrm.h
@@ -74,6 +74,12 @@ struct xfrm_replay_state
 	__u32	bitmap;
 };
 
+struct xfrm_replay_state_ext
+{
+	__u32	oseq_hi;
+	__u32	seq_hi;
+};
+
 struct xfrm_algo {
 	char	alg_name[64];
 	int	alg_key_len;    /* in bits */
@@ -171,6 +177,7 @@ struct xfrm_usersa_info {
 	__u8				replay_window;
 	__u8				flags;
 #define XFRM_STATE_NOECN	1
+#define XFRM_STATE_ESN		64	/* Extended Sequence Numbers */
 };
 
 struct xfrm_usersa_id {
-- 
1.5.4.3


[-- Attachment #4: 0003-xfrm-add-generic-support-for-replay-protection-with.patch --]
[-- Type: text/x-diff, Size: 5534 bytes --]

>From 7aa47cdff60f5a1a7b48bc6100daea710f0ffa37 Mon Sep 17 00:00:00 2001
From: Alex Badea <abadea@ixiacom.com>
Date: Thu, 18 Jun 2009 17:03:39 +0300
Subject: [PATCH] xfrm: add generic support for replay protection with Extended Sequence Numbers

---
 src/include/net/xfrm.h     |    2 +
 src/net/ipv4/xfrm4_input.c |    2 +-
 src/net/ipv6/xfrm6_input.c |    2 +-
 src/net/xfrm/xfrm_export.c |    1 +
 src/net/xfrm/xfrm_replay.c |   77 +++++++++++++++++++++++++++++++++++++++----
 5 files changed, 74 insertions(+), 10 deletions(-)

diff --git a/src/include/net/xfrm.h b/src/include/net/xfrm.h
index bf0daff..1f9feb5 100644
--- a/src/include/net/xfrm.h
+++ b/src/include/net/xfrm.h
@@ -132,6 +132,7 @@ struct xfrm_state
 
 	/* State for replay detection */
 	struct xfrm_replay_state replay;
+	struct xfrm_replay_state_ext replay_ext;
 
 	/* Statistics */
 	struct xfrm_stats	stats;
@@ -819,6 +820,7 @@ extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
 extern void xfrm_state_delete(struct xfrm_state *x);
 extern void xfrm_state_flush(u8 proto);
 extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
+extern u32 xfrm_replay_seqhi(struct xfrm_state *x, u32 seq);
 extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
 extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl);
 extern int xfrm_check_output(struct xfrm_state *x, struct sk_buff *skb, unsigned short family);
diff --git a/src/net/ipv4/xfrm4_input.c b/src/net/ipv4/xfrm4_input.c
index d3284b1..d2d58df 100644
--- a/src/net/ipv4/xfrm4_input.c
+++ b/src/net/ipv4/xfrm4_input.c
@@ -91,7 +91,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
 		/* only the first xfrm gets the encap type */
 		encap_type = 0;
 
-		if (x->props.replay_window)
+		if (x->props.replay_window || (x->props.flags & XFRM_STATE_ESN))
 			xfrm_replay_advance(x, seq);
 
 		x->curlft.bytes += skb->len;
diff --git a/src/net/ipv6/xfrm6_input.c b/src/net/ipv6/xfrm6_input.c
index 075f8b4..be7f4d7 100644
--- a/src/net/ipv6/xfrm6_input.c
+++ b/src/net/ipv6/xfrm6_input.c
@@ -75,7 +75,7 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
 		if (nexthdr <= 0)
 			goto drop_unlock;
 
-		if (x->props.replay_window)
+		if (x->props.replay_window || (x->props.flags & XFRM_STATE_ESN))
 			xfrm_replay_advance(x, seq);
 
 		x->curlft.bytes += skb->len;
diff --git a/src/net/xfrm/xfrm_export.c b/src/net/xfrm/xfrm_export.c
index fdd4d0e..25cb97e 100644
--- a/src/net/xfrm/xfrm_export.c
+++ b/src/net/xfrm/xfrm_export.c
@@ -25,6 +25,7 @@ EXPORT_SYMBOL(xfrm_state_get_afinfo);
 EXPORT_SYMBOL(xfrm_state_put_afinfo);
 EXPORT_SYMBOL(xfrm_state_delete_tunnel);
 EXPORT_SYMBOL(xfrm_replay_check);
+EXPORT_SYMBOL(xfrm_replay_seqhi);
 EXPORT_SYMBOL(xfrm_replay_advance);
 EXPORT_SYMBOL(xfrm_check_selectors);
 EXPORT_SYMBOL(xfrm_check_output);
diff --git a/src/net/xfrm/xfrm_replay.c b/src/net/xfrm/xfrm_replay.c
index 6a7350d..96ccdb3 100644
--- a/src/net/xfrm/xfrm_replay.c
+++ b/src/net/xfrm/xfrm_replay.c
@@ -1,18 +1,67 @@
 #include <net/xfrm.h>
 
+/** Given a state and a Seql, figure out Seqh (for ESN) */
+u32 xfrm_replay_seqhi(struct xfrm_state *x, u32 seq)
+{
+	if (unlikely(!(x->props.flags & XFRM_STATE_ESN))) {
+		BUG();
+		return 0;
+	}
+
+	seq = ntohl(seq);
+	
+	const u32 bottom = x->replay.seq - x->props.replay_window + 1;
+	u32 seq_hi = x->replay_ext.seq_hi;
+
+	if (likely(x->replay.seq >= x->props.replay_window - 1)) {
+		/* A. same subspace */
+		if (unlikely(seq < bottom))
+			seq_hi++;
+	} else {
+		/* B. window spans two subspaces */
+		if (unlikely(seq >= bottom))
+			seq_hi--;
+	}
+	return seq_hi;
+}
+
+
 int xfrm_replay_check(struct xfrm_state *x, u32 seq)
 {
 	u32 diff;
 
 	seq = ntohl(seq);
 
-	if (unlikely(seq == 0))
-		return -EINVAL;
+	if (unlikely(seq == 0)) {
+		if (!(x->props.flags & XFRM_STATE_ESN))
+			return -EINVAL;
+		if (x->replay_ext.seq_hi == 0 && (x->replay.seq < x->props.replay_window - 1))
+			return -EINVAL;
+	}
 
-	if (likely(seq > x->replay.seq))
-		return 0;
+	if (x->props.flags & XFRM_STATE_ESN) {
+		const u32 wsize = x->props.replay_window;
+		const u32 top = x->replay.seq;
+		const u32 bottom = top - wsize + 1;
+
+		diff = top - seq;
+		if (likely(top >= wsize - 1)) {
+			/* A. same subspace */
+			if (likely(seq > top) || seq < bottom)
+				return 0;
+		} else {
+			/* B. window spans two subspaces */
+			if (likely(seq > top && seq < bottom))
+				return 0;
+			if (seq >= bottom)
+				diff = ~seq + top + 1;
+		}
+	} else {
+		if (likely(seq > x->replay.seq))
+			return 0;
+		diff = x->replay.seq - seq;
+	}
 
-	diff = x->replay.seq - seq;
 	if (diff >= x->props.replay_window) {
 		x->stats.replay_window++;
 		return -EINVAL;
@@ -28,19 +77,31 @@ int xfrm_replay_check(struct xfrm_state *x, u32 seq)
 void xfrm_replay_advance(struct xfrm_state *x, u32 seq)
 {
 	u32 diff;
+	int wrap = 0;
+	
+	if (x->props.flags & XFRM_STATE_ESN) {
+		u32 seq_hi = xfrm_replay_seqhi(x, seq);
+		wrap = seq_hi - x->replay_ext.seq_hi;
+	}
 
 	seq = ntohl(seq);
 
-	if (seq > x->replay.seq) {
-		diff = seq - x->replay.seq;
+	if ((!wrap && seq > x->replay.seq) || wrap > 0) {
+		if (likely(!wrap))
+			diff = seq - x->replay.seq;
+		else
+			diff = ~x->replay.seq + seq + 1;
+
 		if (diff < x->props.replay_window)
 			x->replay.bitmap = ((x->replay.bitmap) << diff) | 1;
 		else
 			x->replay.bitmap = 1;
 		x->replay.seq = seq;
+
+		if (unlikely(wrap > 0))
+			x->replay_ext.seq_hi++;
 	} else {
 		diff = x->replay.seq - seq;
 		x->replay.bitmap |= (1U << diff);
 	}
 }
-
-- 
1.5.4.3


[-- Attachment #5: 0004-ipsec-Extended-Sequence-Numbers-support-for-ESP.patch --]
[-- Type: text/x-diff, Size: 5367 bytes --]

>From d503604d592dac8232780d9442b67c4b051cf602 Mon Sep 17 00:00:00 2001
From: Alex Badea <abadea@ixiacom.com>
Date: Thu, 18 Jun 2009 17:07:45 +0300
Subject: [PATCH] ipsec: Extended Sequence Numbers support for ESP

---
 src/include/net/esp.h |   14 ++++++++++++--
 src/net/ipv4/esp4.c   |   18 +++++++++++++++---
 src/net/ipv6/esp6.c   |   15 +++++++++++++--
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/src/include/net/esp.h b/src/include/net/esp.h
index a513d14..d39711c 100644
--- a/src/include/net/esp.h
+++ b/src/include/net/esp.h
@@ -2,6 +2,7 @@
 #define _NET_ESP_H
 
 #include <net/xfrm.h>
+#include <asm/scatterlist.h>
 
 struct esp_data
 {
@@ -28,8 +29,10 @@ struct esp_data
 		int			icv_trunc_len;
 		void			(*icv)(struct esp_data*,
 		                               struct sk_buff *skb,
-		                               int offset, int len, u8 *icv);
+		                               int offset, int len,
+					       u32 seq_hi, u8 *icv);
 		struct crypto_tfm	*tfm;
+		unsigned		esn:1;		/* Extended Sequence Number enabled */
 	} auth;
 };
 
@@ -39,7 +42,7 @@ extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
 
 static inline void
 esp_hmac_digest(struct esp_data *esp, struct sk_buff *skb, int offset,
-                int len, u8 *auth_data)
+                int len, u32 seq_hi, u8 *auth_data)
 {
 	struct crypto_tfm *tfm = esp->auth.tfm;
 	char *icv = esp->auth.work_icv;
@@ -47,6 +50,13 @@ esp_hmac_digest(struct esp_data *esp, struct sk_buff *skb, int offset,
 	memset(auth_data, 0, esp->auth.icv_trunc_len);
 	crypto_hmac_init(tfm, esp->auth.key, &esp->auth.key_len);
 	skb_icv_walk(skb, tfm, offset, len, crypto_hmac_update);
+	if (unlikely(esp->auth.esn)) {
+		struct scatterlist sg;
+		sg.page = virt_to_page(&seq_hi);
+		sg.offset = offset_in_page(&seq_hi);
+		sg.length = sizeof(u32);
+		crypto_hmac_update(tfm, &sg, 1);
+	}
 	crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, icv);
 	memcpy(auth_data, icv, esp->auth.icv_trunc_len);
 }
diff --git a/src/net/ipv4/esp4.c b/src/net/ipv4/esp4.c
index 014dd87..6b73373 100644
--- a/src/net/ipv4/esp4.c
+++ b/src/net/ipv4/esp4.c
@@ -209,6 +209,8 @@ int esp_output(struct sk_buff **pskb)
 
 	esph->spi = x->id.spi;
 	esph->seq_no = htonl(++x->replay.oseq);
+	if (unlikely(!x->replay.oseq))
+		x->replay_ext.oseq_hi++;
 
 	if (esp->conf.ivlen)
 		crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
@@ -234,8 +236,11 @@ int esp_output(struct sk_buff **pskb)
 	}
 
 	if (esp->auth.icv_full_len) {
+		printk("%s: oseq=%u oseq_hi=%d\n", __FUNCTION__, x->replay.oseq, x->replay_ext.oseq_hi);
 		esp->auth.icv(esp, *pskb, (u8*)esph-(*pskb)->data,
-		              sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);
+		              sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen,
+			      x->replay_ext.oseq_hi,
+			      trailer->tail);
 		pskb_put(*pskb, trailer, alen);
 	}
 
@@ -286,8 +291,13 @@ int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
 	if (esp->auth.icv_full_len) {
 		u8 sum[esp->auth.icv_full_len];
 		u8 sum1[alen];
-		
-		esp->auth.icv(esp, skb, 0, skb->len-alen, sum);
+
+		u32 seq_hi = 0;
+		if (x->props.flags & XFRM_STATE_ESN) {
+			u32 seq = ((struct ip_esp_hdr *) skb->data)->seq_no;
+			seq_hi = xfrm_replay_seqhi(x, seq);
+		}
+		esp->auth.icv(esp, skb, 0, skb->len-alen, seq_hi, sum);
 
 		if (skb_copy_bits(skb, skb->len-alen, sum1, alen))
 			BUG();
@@ -539,6 +549,8 @@ int esp_init_state(struct xfrm_state *x, void *args)
 		if (esp->auth.tfm == NULL)
 			goto error;
 		esp->auth.icv = esp_hmac_digest;
+		if (x->props.flags & XFRM_STATE_ESN)
+			esp->auth.esn = 1;
 
 		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
 		BUG_ON(!aalg_desc);
diff --git a/src/net/ipv6/esp6.c b/src/net/ipv6/esp6.c
index 6ad9c12..6b9a27e 100644
--- a/src/net/ipv6/esp6.c
+++ b/src/net/ipv6/esp6.c
@@ -163,6 +163,8 @@ int esp6_output(struct sk_buff **pskb)
 
 	esph->spi = x->id.spi;
 	esph->seq_no = htonl(++x->replay.oseq);
+	if (unlikely(!x->replay.oseq))
+		x->replay_ext.oseq_hi++;
 
 	if (esp->conf.ivlen)
 		crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
@@ -189,7 +191,9 @@ int esp6_output(struct sk_buff **pskb)
 
 	if (esp->auth.icv_full_len) {
 		esp->auth.icv(esp, *pskb, (u8*)esph-(*pskb)->data,
-			sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);
+			sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen+clen,
+			x->replay_ext.oseq_hi,
+			trailer->tail);
 		pskb_put(*pskb, trailer, alen);
 	}
 
@@ -248,7 +252,12 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
 		u8 sum[esp->auth.icv_full_len];
 		u8 sum1[alen];
 
-		esp->auth.icv(esp, skb, 0, skb->len-alen, sum);
+		u32 seq_hi = 0;
+		if (x->props.flags & XFRM_STATE_ESN) {
+			u32 seq = ((struct ipv6_esp_hdr *) skb->data)->seq_no;
+			seq_hi = xfrm_replay_seqhi(x, seq);
+		}
+		esp->auth.icv(esp, skb, 0, skb->len-alen, seq_hi, sum);
 
 		if (skb_copy_bits(skb, skb->len-alen, sum1, alen))
 			BUG();
@@ -409,6 +418,8 @@ int esp6_init_state(struct xfrm_state *x, void *args)
 		if (esp->auth.tfm == NULL)
 			goto error;
 		esp->auth.icv = esp_hmac_digest;
+		if (x->props.flags & XFRM_STATE_ESN)
+			esp->auth.esn = 1;
  
 		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
 		BUG_ON(!aalg_desc);
-- 
1.5.4.3


[-- Attachment #6: 0005-ipsec-Extended-Sequence-Numbers-support-for-AH.patch --]
[-- Type: text/x-diff, Size: 4489 bytes --]

>From 8c573d0716e88e514a7064991838f6a482e861f4 Mon Sep 17 00:00:00 2001
From: Alex Badea <abadea@ixiacom.com>
Date: Thu, 18 Jun 2009 17:12:23 +0300
Subject: [PATCH] ipsec: Extended Sequence Numbers support for AH

---
 src/include/net/ah.h |   14 ++++++++++++--
 src/net/ipv4/ah4.c   |   12 ++++++++++--
 src/net/ipv6/ah6.c   |   12 ++++++++++--
 3 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/src/include/net/ah.h b/src/include/net/ah.h
index ceff00a..9b7b4fb 100644
--- a/src/include/net/ah.h
+++ b/src/include/net/ah.h
@@ -2,6 +2,7 @@
 #define _NET_AH_H
 
 #include <net/xfrm.h>
+#include <asm/scatterlist.h>
 
 /* This is the maximum truncated ICV length that we know of. */
 #define MAX_AH_AUTH_LEN	12
@@ -15,19 +16,28 @@ struct ah_data
 	int			icv_trunc_len;
 
 	void			(*icv)(struct ah_data*,
-	                               struct sk_buff *skb, u8 *icv);
+	                               struct sk_buff *skb,
+				       u32 seq_hi, u8 *icv);
 
 	struct crypto_tfm	*tfm;
+	unsigned		esn:1;
 };
 
 static inline void
-ah_hmac_digest(struct ah_data *ahp, struct sk_buff *skb, u8 *auth_data)
+ah_hmac_digest(struct ah_data *ahp, struct sk_buff *skb, u32 seq_hi, u8 *auth_data)
 {
 	struct crypto_tfm *tfm = ahp->tfm;
 
 	memset(auth_data, 0, ahp->icv_trunc_len);
 	crypto_hmac_init(tfm, ahp->key, &ahp->key_len);
 	skb_icv_walk(skb, tfm, 0, skb->len, crypto_hmac_update);
+	if (unlikely(ahp->esn)) {
+		struct scatterlist sg;
+		sg.page = virt_to_page(&seq_hi);
+		sg.offset = offset_in_page(&seq_hi);
+		sg.length = sizeof(u32);
+		crypto_hmac_update(tfm, &sg, 1);
+	}
 	crypto_hmac_final(tfm, ahp->key, &ahp->key_len, ahp->work_icv);
 	memcpy(auth_data, ahp->work_icv, ahp->icv_trunc_len);
 }
diff --git a/src/net/ipv4/ah4.c b/src/net/ipv4/ah4.c
index 0d62398..c0cc4b1 100644
--- a/src/net/ipv4/ah4.c
+++ b/src/net/ipv4/ah4.c
@@ -121,7 +121,9 @@ static int ah_output(struct sk_buff **pskb)
 	ah->reserved = 0;
 	ah->spi = x->id.spi;
 	ah->seq_no = htonl(++x->replay.oseq);
-	ahp->icv(ahp, *pskb, ah->auth_data);
+	if (unlikely(!x->replay.oseq))
+		x->replay_ext.oseq_hi++;
+	ahp->icv(ahp, *pskb, x->replay_ext.oseq_hi, ah->auth_data);
 	top_iph->tos = iph->tos;
 	top_iph->ttl = iph->ttl;
 	if (x->props.mode) {
@@ -202,9 +204,13 @@ int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buf
         {
 		u8 auth_data[MAX_AH_AUTH_LEN];
 		
+		u32 seq_hi = 0;
+		if (x->props.flags & XFRM_STATE_ESN)
+			seq_hi = xfrm_replay_seqhi(x, ah->seq_no);
+		
 		memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
 		skb_push(skb, skb->data - skb->nh.raw);
-		ahp->icv(ahp, skb, ah->auth_data);
+		ahp->icv(ahp, skb, seq_hi, ah->auth_data);
 		if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {
 			x->stats.integrity_failed++;
 			goto out;
@@ -265,6 +271,8 @@ static int ah_init_state(struct xfrm_state *x, void *args)
 	if (!ahp->tfm)
 		goto error;
 	ahp->icv = ah_hmac_digest;
+	if (x->props.flags & XFRM_STATE_ESN)
+		ahp->esn = 1;
 	
 	/*
 	 * Lookup the algorithm description maintained by xfrm_algo,
diff --git a/src/net/ipv6/ah6.c b/src/net/ipv6/ah6.c
index 185092c..67db5c2 100644
--- a/src/net/ipv6/ah6.c
+++ b/src/net/ipv6/ah6.c
@@ -213,7 +213,9 @@ int ah6_output(struct sk_buff **pskb)
 	ah->reserved = 0;
 	ah->spi = x->id.spi;
 	ah->seq_no = htonl(++x->replay.oseq);
-	ahp->icv(ahp, *pskb, ah->auth_data);
+	if (unlikely(!x->replay.oseq))
+		x->replay_ext.oseq_hi++;
+	ahp->icv(ahp, *pskb, x->replay_ext.oseq_hi, ah->auth_data);
 
 	if (x->props.mode) {
 		(*pskb)->nh.ipv6h->hop_limit   = iph->hop_limit;
@@ -320,10 +322,14 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
         {
 		u8 auth_data[MAX_AH_AUTH_LEN];
 
+		u32 seq_hi = 0;
+		if (x->props.flags & XFRM_STATE_ESN)
+			seq_hi = xfrm_replay_seqhi(x, ah->seq_no);
+
 		memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
 		memset(ah->auth_data, 0, ahp->icv_trunc_len);
 		skb_push(skb, skb->data - skb->nh.raw);
-		ahp->icv(ahp, skb, ah->auth_data);
+		ahp->icv(ahp, skb, seq_hi, ah->auth_data);
 		if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {
 			LIMIT_NETDEBUG(
 				printk(KERN_WARNING "ipsec ah authentication error\n"));
@@ -402,6 +408,8 @@ static int ah6_init_state(struct xfrm_state *x, void *args)
 	if (!ahp->tfm)
 		goto error;
 	ahp->icv = ah_hmac_digest;
+	if (x->props.flags & XFRM_STATE_ESN)
+		ahp->esn = 1;
 	
 	/*
 	 * Lookup the algorithm description maintained by xfrm_algo,
-- 
1.5.4.3


[-- Attachment #7: 0006-xfrm-add-test-harness-for-Extended-Sequence-Numbers.patch --]
[-- Type: text/x-diff, Size: 7584 bytes --]

>From 813d3e12e5f207d037bb1570a35519da77227f0e Mon Sep 17 00:00:00 2001
From: Alex Badea <abadea@ixiacom.com>
Date: Mon, 29 Jun 2009 12:29:25 +0300
Subject: [PATCH] xfrm: add test harness for Extended Sequence Numbers replay protection algorithm

---
 test/esn/SConstruct |   15 +++
 test/esn/harness.c  |  257 +++++++++++++++++++++++++++++++++++++++++++++++++++
 test/esn/harness.h  |   37 ++++++++
 3 files changed, 309 insertions(+), 0 deletions(-)
 create mode 100644 test/esn/SConstruct
 create mode 100644 test/esn/harness.c
 create mode 100644 test/esn/harness.h

diff --git a/test/esn/SConstruct b/test/esn/SConstruct
new file mode 100644
index 0000000..55177a4
--- /dev/null
+++ b/test/esn/SConstruct
@@ -0,0 +1,15 @@
+env = Environment(
+	CCFLAGS = ['-g', '-Wall', '-Werror', '--include=harness.h'],
+	LINKFLAGS = ['-g'],
+	CPPPATH = ['.', '../../src/include'],
+)
+
+env.Append(
+        CCFLAGS = ['-fprofile-arcs', '-ftest-coverage'],
+        LINKFLAGS = ['-fprofile-arcs', '-ftest-coverage'],
+)
+
+env.Program('test-esn', [
+	'harness.c',
+	'../../src/net/xfrm/xfrm_replay.c',
+])
diff --git a/test/esn/harness.c b/test/esn/harness.c
new file mode 100644
index 0000000..d026023
--- /dev/null
+++ b/test/esn/harness.c
@@ -0,0 +1,257 @@
+#include "harness.h"
+#include <string.h>
+
+static void print_bitmap(struct xfrm_state *x)
+{
+	unsigned k;
+	u32 bm = x->replay.bitmap;
+
+	printk("bitmap: %u [", x->replay.seq - x->props.replay_window + 1);
+	bm <<= 32 - x->props.replay_window;
+	for (k = 0; k < x->props.replay_window; k++) {
+		if (k && !(k % 4))
+			printk(" ");
+		printk("%c", (bm & (1 << 31)) ? '1' : '-');
+		bm <<= 1;
+	}
+	printk("] %u\n", x->replay.seq);
+}
+
+static int do_replay(struct xfrm_state *x, u64 seq64, unsigned should_fail)
+{
+	printk("\ntest: #%llu (%llu / %llu)\n",
+		seq64,
+		seq64 >> 32,
+		seq64 & 0xffffffff);
+	print_bitmap(x);
+	printk("w=%u bottom=%u top(replay.seq)=%u|%u\n",
+		x->props.replay_window,
+		x->replay.seq - x->props.replay_window + 1,
+		x->replay_ext.seq_hi,
+		x->replay.seq);
+
+	u32 seq = htonl(seq64 & 0xffffffff);
+	if (xfrm_replay_check(x, seq)) {
+		printk("### replay check failed\n");
+		if (!should_fail)
+			BUG();
+		return -1;
+	}
+	
+	if (x->props.flags & XFRM_STATE_ESN) {
+		u32 seq_hi = xfrm_replay_seqhi(x, seq);
+		printk("seq_hi=%u\n", seq_hi);
+		if (seq_hi != (seq64 >> 32)) {
+			/* this is equivalent to the integrity check */
+			printk("### seq_hi check failed (expected %llu)\n", seq64 >> 32);
+			if (!should_fail) 
+				BUG();
+			return -1;
+		}
+	}
+
+	if (should_fail) {
+		printk("### replay check didn't fail -- and should have\n");
+		BUG();
+	}
+
+	xfrm_replay_advance(x, seq);
+	return 0;
+}
+
+static inline int test_replay_pass(struct xfrm_state *x, u64 seq64)
+{
+	return do_replay(x, seq64, 0);
+}
+
+static inline int test_replay_fail(struct xfrm_state *x, u64 seq64)
+{
+	return do_replay(x, seq64, 1);
+}
+
+static void init_state(struct xfrm_state *x)
+{
+	memset(x, 0, sizeof(struct xfrm_state));
+	x->props.replay_window = 8;
+}
+
+static void init_state_esn(struct xfrm_state *x)
+{
+	init_state(x);
+	x->props.flags |= XFRM_STATE_ESN;
+}
+
+static void banner(const char *text)
+{
+	printk("\n\n================================================================\n");
+	printk("===== %s\n\n", text);
+
+}
+
+static void sep(void)
+{
+	printk("\n\n-----\n\n");
+}
+
+static void test_0(void)
+{
+	struct xfrm_state st, *x = &st;
+
+	banner("seq == 0");
+	init_state_esn(x);
+	test_replay_fail(x, 0);
+	test_replay_pass(x, 1);
+	test_replay_fail(x, 0);
+	test_replay_pass(x, 128);
+	test_replay_fail(x, 0);
+	test_replay_pass(x, (1ULL << 32) - 20);
+	test_replay_fail(x, 0);
+	test_replay_pass(x, (1ULL << 32));
+	test_replay_pass(x, (1ULL << 32) + 20);
+}
+
+static void test_1(void)
+{
+	struct xfrm_state st, *x = &st;
+	unsigned k;
+	u64 seq64 = 1;
+
+	banner("linear sequence, wrapping");
+	init_state_esn(x);
+
+	seq64 = 1;
+	for (k = 1; k < 5; k++)
+		test_replay_pass(x, seq64++);
+	sep();
+	seq64 = 0xfffffff0;
+	for (k = 0; k < 16; k++)
+		test_replay_pass(x, seq64++);
+	sep();
+	for (k = 0; k < 10; k++)
+		test_replay_pass(x, seq64++);
+}
+
+static void test_2(void)
+{
+	struct xfrm_state st, *x = &st;
+	unsigned k;
+	u64 seq64 = 1;
+
+	banner("short sequence with a few replays");
+	init_state_esn(x);
+
+	for (k = 0; k < 64; k++)
+		test_replay_pass(x, seq64++);
+	/* out-of-window */
+	test_replay_fail(x, 1);
+	test_replay_fail(x, 2);
+	test_replay_fail(x, 3);
+	/* in-window */
+	test_replay_fail(x, 60);
+	test_replay_fail(x, 63);
+
+	test_replay_pass(x, seq64++);
+}
+
+static void test_3(void)
+{
+	struct xfrm_state st, *x = &st;
+
+	banner("swiss cheese");
+	init_state_esn(x);
+	
+	test_replay_pass(x, 3);
+	test_replay_pass(x, 9);
+	test_replay_pass(x, 5);
+	test_replay_fail(x, 5);	/* replayed */
+	test_replay_pass(x, 16);
+	test_replay_fail(x, 4);	/* out of window */
+	test_replay_pass(x, 10);
+}
+
+static void test_4(void)
+{
+	struct xfrm_state st, *x = &st;
+	u64 edge = (1ULL << 32);
+
+	banner("swiss cheese with wrapping");
+	init_state_esn(x);
+	
+	test_replay_pass(x, 1);
+	test_replay_pass(x, 128);
+	test_replay_pass(x, edge + 2);
+	test_replay_pass(x, edge - 2);
+	test_replay_pass(x, edge);
+	test_replay_pass(x, edge + 3);
+	test_replay_pass(x, edge + 1);
+
+	test_replay_fail(x, edge + 1);
+	test_replay_fail(x, edge);
+	test_replay_fail(x, edge - 2);
+	test_replay_pass(x, edge - 1);
+}
+
+static void test_5(void)
+{
+	struct xfrm_state st, *x = &st;
+	unsigned k;
+	u64 seq64 = 1;
+
+	banner("sparse");
+	init_state_esn(x);
+	
+	for (k = 1; k < 10; k++) {
+		seq64 += 2149536563U; /* random prime */
+		test_replay_pass(x, seq64);
+	}
+}
+
+static void test_plain_1(void)
+{
+	struct xfrm_state st, *x = &st;
+	unsigned k;
+	u64 seq64 = 1;
+
+	banner("non-ESN in-sequence");
+	init_state(x);
+
+	for (k = 1; k < 10; k++)
+		test_replay_pass(x, seq64++);
+	for (k = 1; k < 3; k++)
+		test_replay_pass(x, seq64 += 13);
+	for (k = 1; k < 3; k++)
+		test_replay_pass(x, seq64 += 5);
+}
+
+static void test_plain_2(void)
+{
+	struct xfrm_state st, *x = &st;
+
+	banner("non-ESN replay check");
+	init_state(x);
+
+	test_replay_fail(x, 0);	/* seq == 0 */
+	test_replay_pass(x, 3);
+	test_replay_pass(x, 9);
+	test_replay_pass(x, 5);
+	test_replay_fail(x, 5);	/* replayed */
+	test_replay_pass(x, 16);
+	test_replay_fail(x, 4);	/* out of window */
+	test_replay_pass(x, 10);
+}
+
+int main(int argc, char *argv[])
+{
+	test_0();
+	test_1();
+	test_2();
+	test_3();
+	test_4();
+	test_5();
+	test_plain_1();
+	test_plain_2();
+
+	sep();
+	printk("all done.\n");
+	return 0;
+}
diff --git a/test/esn/harness.h b/test/esn/harness.h
new file mode 100644
index 0000000..1e4277b
--- /dev/null
+++ b/test/esn/harness.h
@@ -0,0 +1,37 @@
+#ifndef _HARNESS_H
+#define _HARNESS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <linux/xfrm.h>
+
+#define printk		printf
+#define likely(x)	x
+#define unlikely(x)	x
+#define BUG()		abort()
+#define _NET_XFRM_H
+
+typedef u_int8_t u8;
+typedef u_int32_t u32;
+typedef u_int64_t u64;
+
+struct xfrm_state {
+	struct {
+		u8 flags;
+		u8 replay_window;
+	} props;
+	struct xfrm_replay_state replay;
+	struct xfrm_replay_state_ext replay_ext;
+	struct xfrm_stats stats;
+};
+
+#define XFRM_STATE_ESN	64
+
+extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
+extern u32 xfrm_replay_seqhi(struct xfrm_state *x, u32 seq);
+extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
+
+#endif
-- 
1.5.4.3


^ permalink raw reply related


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