Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] net/802/tr.c: s/struct rif_cache_s/struct rif_cache/
From: David S. Miller @ 2005-05-25 23:43 UTC (permalink / raw)
  To: adobriyan; +Cc: netdev
In-Reply-To: <200505242148.03588.adobriyan@gmail.com>

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 24 May 2005 21:48:03 +0400

> "_s" suffix is certainly of hungarian origin.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] tokenring: be'ify trh_hdr, trllc, rif_cache_s
From: David S. Miller @ 2005-05-25 23:43 UTC (permalink / raw)
  To: adobriyan; +Cc: netdev
In-Reply-To: <200505242146.53270.adobriyan@gmail.com>

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 24 May 2005 21:46:53 +0400

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied, thanks.

^ permalink raw reply

* Re: [XFRM] Call dst_check() with appropriate cookie
From: David S. Miller @ 2005-05-25 23:40 UTC (permalink / raw)
  To: herbert; +Cc: yoshfuji, netdev, kazunori
In-Reply-To: <20050524115914.GA697@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 24 May 2005 21:59:14 +1000

> On Tue, May 24, 2005 at 05:49:31PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@ wrote:
> > 
> > [XFRM] Call dst_check() with appropriate cookie
> > 
> > This fixes infinite loop issue with IPv6 tunnel mode.
> > 
> > Signed-off-by: Kazunori Miyazawa <kazunori@miyazawa.org>
> > Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> 
> Looks good.
> 
> Acked-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied, thanks everyone.

^ permalink raw reply

* Re: [PATCH 2/2][NET] rename struct tcp_listen_opt to struct listen_sock
From: David S. Miller @ 2005-05-25 23:37 UTC (permalink / raw)
  To: acme; +Cc: netdev
In-Reply-To: <20050524011758.GJ26989@conectiva.com.br>

From: acme@ghostprotocols.net (Arnaldo Carvalho de Melo)
Date: Mon, 23 May 2005 22:17:58 -0300

> rsync://rsync.kernel.org/pub/scm/linux/kernel/git/acme/net-2.6.13.git

Both changes look good, pulled.  It should show up on kernel.org
in a little bit.

^ permalink raw reply

* [PATCH] uninitialized variable in prism54 isl38xx_trigger_device
From: Olaf Hering @ 2005-05-25 23:16 UTC (permalink / raw)
  To: Jeff Garzik, netdev, prism54-private


drivers/net/wireless/prism54/isl_38xx.c:131: warning: 'current_time.tv_sec' is used uninitialized in this function
drivers/net/wireless/prism54/isl_38xx.c:131: warning: 'current_time.tv_usec' is used uninitialized in this function

Signed-off-by: Olaf Hering <olh@suse.de>
Index: linux-2.6.12-rc5-olh/drivers/net/wireless/prism54/isl_38xx.c
===================================================================
--- linux-2.6.12-rc5-olh.orig/drivers/net/wireless/prism54/isl_38xx.c
+++ linux-2.6.12-rc5-olh/drivers/net/wireless/prism54/isl_38xx.c
@@ -112,10 +112,10 @@ isl38xx_handle_wakeup(isl38xx_control_bl
 void
 isl38xx_trigger_device(int asleep, void __iomem *device_base)
 {
-	struct timeval current_time;
 	u32 reg, counter = 0;
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
+	struct timeval current_time;
 	DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
 #endif
 
@@ -126,11 +126,11 @@ isl38xx_trigger_device(int asleep, void 
 		do_gettimeofday(&current_time);
 		DEBUG(SHOW_TRACING, "%08li.%08li Device wakeup triggered\n",
 		      current_time.tv_sec, (long)current_time.tv_usec);
-#endif
 
 		DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
 		      current_time.tv_sec, (long)current_time.tv_usec,
 		      readl(device_base + ISL38XX_CTRL_STAT_REG));
+#endif
 		udelay(ISL38XX_WRITEIO_DELAY);
 
 		reg = readl(device_base + ISL38XX_INT_IDENT_REG);
@@ -148,10 +148,12 @@ isl38xx_trigger_device(int asleep, void 
 				counter++;
 			}
 
+#if VERBOSE > SHOW_ERROR_MESSAGES
 			DEBUG(SHOW_TRACING,
 			      "%08li.%08li Device register read %08x\n",
 			      current_time.tv_sec, (long)current_time.tv_usec,
 			      readl(device_base + ISL38XX_CTRL_STAT_REG));
+#endif
 			udelay(ISL38XX_WRITEIO_DELAY);
 
 #if VERBOSE > SHOW_ERROR_MESSAGES

^ permalink raw reply

* Re: [git patches try2] 2.6.x net driver updates
From: Jeff Garzik @ 2005-05-25 23:03 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andrew Morton, Netdev, Linux Kernel
In-Reply-To: <42950334.9090402@pobox.com>

Jeff Garzik wrote:
> Not specialized at all.  I do one pull at a time, so git-pull-script 
> suffices with a simple addition to call git-resolve-script with the 
> branch as $4, and a simple addition to git-resolve-script to add 'branch 

Correction: new $4 arg was added to git-resolve-script, not git-pull-script

^ permalink raw reply

* Re: RFC: PHY Abstraction Layer II
From: Kumar Gala @ 2005-05-25 23:00 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Netdev, David S. Miller, ML linuxppc-embedded
In-Reply-To: <30d87aabd768216ef8bee800f3e09b9e@freescale.com>

Jeff,

Where do we stand on this.  Are there changes you feel need to be made? 
  Some other issue?  It would like to know what we need to do to get 
this in post 2.6.12.

thanks

- kumar

On May 10, 2005, at 12:04 PM, Fleming Andy-afleming wrote:

>
>
> On Apr 17, 2005, at 08:00, James Chapman wrote:
>
> > Andy Fleming wrote:
> >> Ok, here's the new patch with changes suggested by James Chapman:
>  >
>  > I guess I still have questions about the way interrupts are used.
>  >
>  > Using an interrupt to schedule a work queue which then sets a 
> variable
> > that is used by a timer seems odd. Why not do all the work in the 
> work
>  > queue and schedule it from the interrupt handler or timer?
>
> Ok, I've set up a new system for handling interrupts.  There are now
>  two "special" interrupt values, PHY_POLL, and PHY_IGNORE_INTERRUPT. 
>  The first one is used to indicate that the PHY layer will poll the PHY
> for state changes, and won't enable interrupts.  The second indicates
> that the PHY layer will neither poll, nor enable interrupts, and thus
> will allow the driver to handle interrupts.  The PHY layer will still
> operate its state machine, though.
>
> The driver must insure a couple things:
>
> 1) It must set phydev->state to PHY_CHANGELINK
> 2) It must do that in a work queue (or other non-interrupt time)
>
> The first one tells the PHY layer that the link state changed (it has
> to grab a lock to do this).  The second one is required in order to
> properly take the lock.
>
> >
>  > Also, did you mean to leave the #if 0 code in davicom.c?
>
> For now.  It worked around a problem some people were reporting, so I'd
> like to see if they report it again now that the code's out.  If so,
> they have a fairly easy fix, and I can reinsert it (or at least
> reevaluate it) in the future.
>
> >
>  > /james
>
> Andy
> <phy_05_09_2005.patch><ATT191442.txt>

^ permalink raw reply

* Re: [git patches try2] 2.6.x net driver updates
From: Jeff Garzik @ 2005-05-25 22:59 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andrew Morton, Netdev, Linux Kernel
In-Reply-To: <Pine.LNX.4.58.0505251200040.2307@ppc970.osdl.org>

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

Linus Torvalds wrote:
> 
> On Wed, 25 May 2005, Jeff Garzik wrote:
> 
>>Does this work better?
> 
> 
> Looks good.

Groovy.


> If this was automated, are your changes to git-pull-script generic enough 
> to be useful for others, or did you do a totally specialized one for just 
> the "lots of heads in the same directory" case?

Not specialized at all.  I do one pull at a time, so git-pull-script 
suffices with a simple addition to call git-resolve-script with the 
branch as $4, and a simple addition to git-resolve-script to add 'branch 
$foo' to merge_msg.  See attached (note the patch includes my earlier 
'optimization' patch).

On this last run, I actually just ignored git-pull-script and simply ran 
git-resolve-script -- since all my objects are in-tree already, I don't 
need the fetch step:

git-resolve-script $(cat .git/HEAD ) $(cat .git/refs/heads/amd8111) \
    /spare/repo/netdev-2.6 amd8111

	Jeff



[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 1666 bytes --]

--- git-resolve-script	2005-05-25 15:21:32.772604549 -0400
+++ /usr/local/bin/git-resolve-script	2005-05-25 13:30:59.568504275 -0400
@@ -7,6 +7,7 @@
 head="$1"
 merge="$2"
 merge_repo="$3"
+merge_name=${4:-HEAD}
 
 : ${GIT_DIR=.git}
 : ${GIT_OBJECT_DIRECTORY="${SHA1_FILE_DIRECTORY-"$GIT_DIR/objects"}"}
@@ -20,7 +21,7 @@
 # but we do want it.
 #
 if [ "$merge_repo" == "" ]; then
-	echo "git-resolve-script <head> <remote> <merge-repo-name>"
+	echo "git-resolve-script <head> <remote> <merge-repo-name> <branch-name>"
 	exit 1
 fi
 
@@ -39,23 +40,23 @@
 	echo "Destroying all noncommitted data!"
 	echo "Kill me within 3 seconds.."
 	sleep 3
-	git-read-tree -m $merge && git-checkout-cache -f -u -a
+	git-read-tree -m $merge && git-checkout-cache -f -a && git-update-cache --refresh
 	echo $merge > "$GIT_DIR"/HEAD
 	git-diff-tree -p ORIG_HEAD HEAD | diffstat -p1
 	exit 0
 fi
 echo "Trying to merge $merge into $head"
 git-read-tree -m $common $head $merge
-merge_msg="Merge of $merge_repo"
+merge_msg="Merge of $merge_repo branch $merge_name"
 result_tree=$(git-write-tree  2> /dev/null)
 if [ $? -ne 0 ]; then
 	echo "Simple merge failed, trying Automatic merge"
 	git-merge-cache git-merge-one-file-script -a
-	merge_msg="Automatic merge of $merge_repo"
+	merge_msg="Automatic merge of $merge_repo branch $merge_name"
 	result_tree=$(git-write-tree) || exit 1
 fi
 result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
 echo "Committed merge $result_commit"
 echo $result_commit > "$GIT_DIR"/HEAD
-git-checkout-cache -f -u -a
+git-checkout-cache -f -a && git-update-cache --refresh
 git-diff-tree -p ORIG_HEAD HEAD | diffstat -p1

^ permalink raw reply

* Re: Interdomain/interpartition communication without a checksum
From: David S. Miller @ 2005-05-25 22:39 UTC (permalink / raw)
  To: jdmason; +Cc: netdev, niv, habanero
In-Reply-To: <20050517163420.GA19251@us.ibm.com>

From: Jon Mason <jdmason@us.ibm.com>
Date: Tue, 17 May 2005 11:34:20 -0500

> --- ../xen-unstable-pristine/linux-2.6.11-xen0/include/linux/skbuff.h	2005-03-02 01:38:38.000000000 -0600
> +++ linux-2.6.11-xen0/include/linux/skbuff.h	2005-05-13 10:43:08.000000000 -0500
> @@ -37,6 +37,10 @@
>  #define CHECKSUM_HW 1
>  #define CHECKSUM_UNNECESSARY 2
>  
> +#define SKB_CLONED	1
> +#define SKB_NOHDR	2
> +#define SKB_FDW_NO_CSUM	4
> +


You create SKB_NOHDR yet do not make use of it to
replace skb->nohdr.

> @@ -603,7 +603,7 @@ int pskb_expand_head(struct sk_buff *skb
>  	skb->mac.raw += off;
>  	skb->h.raw   += off;
>  	skb->nh.raw  += off;
> -	skb->cloned   = 0;
> +	skb->flags    &= SKB_CLONED;
>  	atomic_set(&skb_shinfo(skb)->dataref, 1);
>  	return 0;

This does not clear SKB_CLONED, it makes it the only possible
bit set.  Clearly this was not your intention.

^ permalink raw reply

* Re: [PATCH] bonding using arp_ip_target may stay down with active path
From: David S. Miller @ 2005-05-25 22:21 UTC (permalink / raw)
  To: fubar; +Cc: eparis, netdev, jgarzik, bonding-devel
In-Reply-To: <200505232121.j4NLLaYa000837@death.nxdomain.ibm.com>


Fixed patch applied, thanks a lot Jay.

^ permalink raw reply

* Re: [PATCH 1/6] bnx2: Fix excessive stack usage
From: David S. Miller @ 2005-05-25 22:18 UTC (permalink / raw)
  To: jgarzik; +Cc: mchan, netdev
In-Reply-To: <4292BEF6.2080804@pobox.com>

From: Jeff Garzik <jgarzik@pobox.com>
Date: Tue, 24 May 2005 01:43:18 -0400

> > Signed-off-by: Michael Chan <mchan@broadcom.com>
> 
> ACK

I've integrated the new bnx2 driver, with all updated
bug fixes.  I'll push this upstream shortly.

Thanks everyone.

^ permalink raw reply

* Re: [PATCH] dummy: improve performance
From: David S. Miller @ 2005-05-25 22:11 UTC (permalink / raw)
  To: util; +Cc: netdev
In-Reply-To: <Pine.LNX.4.62.0505201306110.29305@webhosting.rdsbv.ro>

From: "Catalin(ux aka Dino) BOIE" <util@deuroconsult.ro>
Date: Fri, 20 May 2005 13:11:24 +0300 (EEST)

> I tested the speed and seems very low (both old version and the new one).
> Something like 37Mbits/s. It is normal?
> I can easily get 80Mbit/s on the same machine on ethernet.

How are you receiving packets on the dummy device for
performance testing?  This device is a transmit blackhole
and receives no packets :-)

I really don't see a real need for your patch, dummy device
performance cannot be claimed to be important at all.

^ permalink raw reply

* Re: [PATCH] (3/3) netem: allow random reordering (with fix)
From: David S. Miller @ 2005-05-25 22:08 UTC (permalink / raw)
  To: shemminger; +Cc: netdev, netem
In-Reply-To: <20050524152610.256d248a@dxpl.pdx.osdl.net>


All 3 netem patches applied, thanks Stephen.

^ permalink raw reply

* Re: [PATCH] [BRIDGE]
From: Stephen Hemminger @ 2005-05-25 21:46 UTC (permalink / raw)
  To: Catalin(ux aka Dino) BOIE; +Cc: netdev, davem
In-Reply-To: <20050525091427.35621a21@dxpl.pdx.osdl.net>

Here is the revised version, it deals with checksum mixtures better and
ignores stuff until bridge is up.

Index: bridge/net/bridge/br_private.h
===================================================================
--- bridge.orig/net/bridge/br_private.h
+++ bridge/net/bridge/br_private.h
@@ -174,6 +174,7 @@ extern int br_add_if(struct net_bridge *
 extern int br_del_if(struct net_bridge *br,
 	      struct net_device *dev);
 extern int br_min_mtu(const struct net_bridge *br);
+extern void br_features_recompute(struct net_bridge *br);
 
 /* br_input.c */
 extern int br_handle_frame_finish(struct sk_buff *skb);
Index: bridge/net/bridge/br_notify.c
===================================================================
--- bridge.orig/net/bridge/br_notify.c
+++ bridge/net/bridge/br_notify.c
@@ -65,6 +65,15 @@ static int br_device_event(struct notifi
 		}
 		break;
 
+	case NETDEV_FEAT_CHANGE:
+		if (br->dev->flags & IFF_UP) 
+			br_features_recompute(br);
+
+		/* could do recursive feature change notification
+		 * but who would care?? 
+		 */
+		break;
+
 	case NETDEV_DOWN:
 		if (br->dev->flags & IFF_UP)
 			br_stp_disable_port(p);
Index: bridge/net/bridge/br_device.c
===================================================================
--- bridge.orig/net/bridge/br_device.c
+++ bridge/net/bridge/br_device.c
@@ -21,10 +21,7 @@
 
 static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
 {
-	struct net_bridge *br;
-
-	br = dev->priv;
-
+	struct net_bridge *br = netdev_priv(dev);
 	return &br->statistics;
 }
 
@@ -54,9 +51,11 @@ int br_dev_xmit(struct sk_buff *skb, str
 
 static int br_dev_open(struct net_device *dev)
 {
-	netif_start_queue(dev);
+	struct net_bridge *br = netdev_priv(dev);
 
-	br_stp_enable_bridge(dev->priv);
+	br_features_recompute(br);
+	netif_start_queue(dev);
+	br_stp_enable_bridge(br);
 
 	return 0;
 }
@@ -67,7 +66,7 @@ static void br_dev_set_multicast_list(st
 
 static int br_dev_stop(struct net_device *dev)
 {
-	br_stp_disable_bridge(dev->priv);
+	br_stp_disable_bridge(netdev_priv(dev));
 
 	netif_stop_queue(dev);
 
@@ -76,7 +75,7 @@ static int br_dev_stop(struct net_device
 
 static int br_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if ((new_mtu < 68) || new_mtu > br_min_mtu(dev->priv))
+	if (new_mtu < 68 || new_mtu > br_min_mtu(netdev_priv(dev)))
 		return -EINVAL;
 
 	dev->mtu = new_mtu;
Index: bridge/net/bridge/br_if.c
===================================================================
--- bridge.orig/net/bridge/br_if.c
+++ bridge/net/bridge/br_if.c
@@ -314,6 +314,28 @@ int br_min_mtu(const struct net_bridge *
 	return mtu;
 }
 
+/*
+ * Recomputes features using slave's features
+ */
+void br_features_recompute(struct net_bridge *br)
+{
+	struct net_bridge_port *p;
+	unsigned long features, checksum;
+
+	features = NETIF_F_SG | NETIF_F_FRAGLIST 
+		| NETIF_F_HIGHDMA | NETIF_F_TSO;
+	checksum = NETIF_F_IP_CSUM;	/* least commmon subset */
+
+	list_for_each_entry(p, &br->port_list, list) {
+		if (!(p->dev->features 
+		      & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
+			checksum = 0;
+		features &= p->dev->features;
+	}
+
+	br->dev->features = features | checksum | NETIF_F_LLTX;
+}
+
 /* called with RTNL */
 int br_add_if(struct net_bridge *br, struct net_device *dev)
 {
@@ -368,6 +390,7 @@ int br_del_if(struct net_bridge *br, str
 
 	spin_lock_bh(&br->lock);
 	br_stp_recalculate_bridge_id(br);
+	br_features_recompute(br);
 	spin_unlock_bh(&br->lock);
 
 	return 0;

^ permalink raw reply

* Re: [PATCH] Scalable TCP
From: Stephen Hemminger @ 2005-05-25 21:00 UTC (permalink / raw)
  To: John Heffner; +Cc: netdev
In-Reply-To: <200505251550.42252.jheffner@psc.edu>

Okay, integrated it but there were some funky whitespace issues
probably because of mailer stuff.

^ permalink raw reply

* [PATCH] netem update for 2.4
From: Stephen Hemminger @ 2005-05-25 20:59 UTC (permalink / raw)
  To: David S. Miller; +Cc: netem, netdev

This includes the netem changes for 2.6 retargeted for 2.4
It covers:
	* make duplication reinsert from root to fix qlen issues
	* just use embedded qdisc for queueing to avoid qlen issues
	* probabilistic reordering support

Index: netem-2.4/net/sched/sch_netem.c
===================================================================
--- netem-2.4.orig/net/sched/sch_netem.c
+++ netem-2.4/net/sched/sch_netem.c
@@ -56,7 +56,6 @@
 
 struct netem_sched_data {
 	struct Qdisc	*qdisc;
-	struct sk_buff_head delayed;
 	struct timer_list timer;
 
 	u32 latency;
@@ -66,11 +65,12 @@ struct netem_sched_data {
 	u32 gap;
 	u32 jitter;
 	u32 duplicate;
+	u32 reorder;
 
 	struct crndstate {
 		unsigned long last;
 		unsigned long rho;
-	} delay_cor, loss_cor, dup_cor;
+	} delay_cor, loss_cor, dup_cor, reorder_cor;
 
 	struct disttable {
 		u32  size;
@@ -140,81 +140,79 @@ static long tabledist(unsigned long mu, 
 	return  x / NETEM_DIST_SCALE + (sigma / NETEM_DIST_SCALE) * t + mu;
 }
 
-/* Put skb in the private delayed queue. */
-static int delay_skb(struct Qdisc *sch, struct sk_buff *skb)
+/*
+ * Insert one skb into qdisc.
+ * Note: parent depends on return value to account for queue length.
+ * 	NET_XMIT_DROP: queue length didn't change.
+ *      NET_XMIT_SUCCESS: one skb was queued.
+ */
+static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
 	struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb;
- 	psched_tdiff_t td;
-  	psched_time_t now;
-  	
-  	PSCHED_GET_TIME(now);
-	td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist);
-	PSCHED_TADD2(now, td, cb->time_to_send);
-	
-	/* Always queue at tail to keep packets in order */
-	if (likely(q->delayed.qlen < q->limit)) {
-		__skb_queue_tail(&q->delayed, skb);
-		sch->stats.bytes += skb->len;
-		sch->stats.packets++;
- 
-		if (!timer_pending(&q->timer)) {
-			q->timer.expires = jiffies + PSCHED_US2JIFFIE(td);
-			add_timer(&q->timer);
-		}
-		return NET_XMIT_SUCCESS;
-	}
-
-	sch->stats.drops++;
-	kfree_skb(skb);
-	return NET_XMIT_DROP;
-}
+	struct sk_buff *skb2;
+	int ret;
+	int count = 1;
 
-static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
-{
-	struct netem_sched_data *q = qdisc_priv(sch);
+	pr_debug("netem_enqueue skb=%p\n", skb);
 
-	pr_debug("netem_enqueue skb=%p @%lu\n", skb, jiffies);
+	/* Random duplication */
+	if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor))
+		++count;
 
 	/* Random packet drop 0 => none, ~0 => all */
-	if (q->loss && q->loss >= get_crandom(&q->loss_cor)) {
-		pr_debug("netem_enqueue: random loss\n");
+	if (q->loss && q->loss >= get_crandom(&q->loss_cor))
+		--count;
+
+	if (count == 0) {
 		sch->stats.drops++;
 		kfree_skb(skb);
-		return 0;	/* lie about loss so TCP doesn't know */
+		return NET_XMIT_DROP;
 	}
 
-	/* Random duplication */
-	if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) {
-		struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
-
-		pr_debug("netem_enqueue: dup %p\n", skb2);
-		if (skb2)
-			delay_skb(sch, skb2);
-	}
-
-	/* If doing simple delay then gap == 0 so all packets
-	 * go into the delayed holding queue
-	 * otherwise if doing out of order only "1 out of gap"
-	 * packets will be delayed.
+	/*
+	 * If we need to duplicate packet, then re-insert at top of the
+	 * qdisc tree, since parent queuer expects that only one
+	 * skb will be queued.
 	 */
-	if (q->counter < q->gap) {
-		int ret;
-
+	if (count > 1 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
+		struct Qdisc *rootq = sch->dev->qdisc;
+		u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
+		q->duplicate = 0;
+
+		rootq->enqueue(skb2, rootq);
+		q->duplicate = dupsave;
+	}
+
+	if (q->gap == 0 		/* not doing reordering */
+	    || q->counter < q->gap 	/* inside last reordering gap */
+	    || q->reorder < get_crandom(&q->reorder_cor)) {
+		psched_time_t now;
+		PSCHED_GET_TIME(now);
+		PSCHED_TADD2(now, tabledist(q->latency, q->jitter, 
+					    &q->delay_cor, q->delay_dist),
+			     cb->time_to_send);
 		++q->counter;
 		ret = q->qdisc->enqueue(skb, q->qdisc);
-		if (likely(ret == NET_XMIT_SUCCESS)) {
-			sch->q.qlen++;
-			sch->stats.bytes += skb->len;
-			sch->stats.packets++;
-		} else
-			sch->stats.drops++;
-		return ret;
+	} else {
+		/* 
+		 * Do re-ordering by putting one out of N packets at the front
+		 * of the queue.
+		 */
+		PSCHED_GET_TIME(cb->time_to_send);
+		q->counter = 0;
+		ret = q->qdisc->ops->requeue(skb, q->qdisc);
 	}
-	
-	q->counter = 0;
 
-	return delay_skb(sch, skb);
+	if (likely(ret == NET_XMIT_SUCCESS)) {
+		sch->q.qlen++;
+		sch->stats.bytes += skb->len;
+		sch->stats.packets++;
+	} else
+		sch->stats.drops++;
+
+	pr_debug("netem: enqueue ret %d\n", ret);
+	return ret;
 }
 
 /* Requeue packets but don't change time stamp */
@@ -241,56 +239,46 @@ static unsigned int netem_drop(struct Qd
 	return len;
 }
 
-/* Dequeue packet.
- *  Move all packets that are ready to send from the delay holding
- *  list to the underlying qdisc, then just call dequeue
- */
 static struct sk_buff *netem_dequeue(struct Qdisc *sch)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
 	struct sk_buff *skb;
 
 	skb = q->qdisc->dequeue(q->qdisc);
-	if (skb) 
-		sch->q.qlen--;
-	return skb;
-}
-
-static void netem_watchdog(unsigned long arg)
-{
-	struct Qdisc *sch = (struct Qdisc *)arg;
-	struct netem_sched_data *q = qdisc_priv(sch);
-	struct net_device *dev = sch->dev;
-	struct sk_buff *skb;
-	psched_time_t now;
-
-	pr_debug("netem_watchdog: fired @%lu\n", jiffies);
-
-	spin_lock_bh(&dev->queue_lock);
-	PSCHED_GET_TIME(now);
-
-	while ((skb = skb_peek(&q->delayed)) != NULL) {
+	if (skb) {
 		const struct netem_skb_cb *cb
 			= (const struct netem_skb_cb *)skb->cb;
-		long delay 
-			= PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
-		pr_debug("netem_watchdog: skb %p@%lu %ld\n",
-			 skb, jiffies, delay);
+		psched_time_t now;
+		long delay;
 
 		/* if more time remaining? */
-		if (delay > 0) {
-			mod_timer(&q->timer, jiffies + delay);
-			break;
+		PSCHED_GET_TIME(now);
+		delay = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
+		pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay);
+		if (delay <= 0) {
+			pr_debug("netem_dequeue: return skb=%p\n", skb);
+			sch->q.qlen--;
+			sch->flags &= ~TCQ_F_THROTTLED;
+			return skb;
 		}
-		__skb_unlink(skb, &q->delayed);
 
-		if (q->qdisc->enqueue(skb, q->qdisc))
+		mod_timer(&q->timer, jiffies + delay);
+		sch->flags |= TCQ_F_THROTTLED;
+
+		if (q->qdisc->ops->requeue(skb, q->qdisc) != 0)
 			sch->stats.drops++;
-		else
-			sch->q.qlen++;
 	}
-	qdisc_run(dev);
-	spin_unlock_bh(&dev->queue_lock);
+
+	return NULL;
+}
+
+static void netem_watchdog(unsigned long arg)
+{
+	struct Qdisc *sch = (struct Qdisc *)arg;
+
+	pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen);
+	sch->flags &= ~TCQ_F_THROTTLED;
+	netif_schedule(sch->dev);
 }
 
 static void netem_reset(struct Qdisc *sch)
@@ -298,9 +286,8 @@ static void netem_reset(struct Qdisc *sc
 	struct netem_sched_data *q = qdisc_priv(sch);
 
 	qdisc_reset(q->qdisc);
-	skb_queue_purge(&q->delayed);
-
 	sch->q.qlen = 0;
+	sch->flags &= ~TCQ_F_THROTTLED;
 	del_timer_sync(&q->timer);
 }
 
@@ -366,6 +353,19 @@ static int get_correlation(struct Qdisc 
 	return 0;
 }
 
+static int get_reorder(struct Qdisc *sch, const struct rtattr *attr)
+{
+	struct netem_sched_data *q = qdisc_priv(sch);
+	const struct tc_netem_reorder *r = RTA_DATA(attr);
+
+	if (RTA_PAYLOAD(attr) != sizeof(*r))
+		return -EINVAL;
+
+	q->reorder = r->probability;
+	init_crandom(&q->reorder_cor, r->correlation);
+	return 0;
+}
+
 static int netem_change(struct Qdisc *sch, struct rtattr *opt)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
@@ -386,9 +386,15 @@ static int netem_change(struct Qdisc *sc
 	q->jitter = qopt->jitter;
 	q->limit = qopt->limit;
 	q->gap = qopt->gap;
+	q->counter = 0;
 	q->loss = qopt->loss;
 	q->duplicate = qopt->duplicate;
 
+	/* for compatiablity with earlier versions.
+	 * if gap is set, need to assume 100% probablity
+	 */
+	q->reorder = ~0;
+
 	/* Handle nested options after initial queue options.
 	 * Should have put all options in nested format but too late now.
 	 */ 
@@ -410,6 +416,11 @@ static int netem_change(struct Qdisc *sc
 			if (ret)
 				return ret;
 		}
+		if (tb[TCA_NETEM_REORDER-1]) {
+			ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]);
+			if (ret)
+				return ret;
+		}
 	}
 
 
@@ -425,11 +436,9 @@ static int netem_init(struct Qdisc *sch,
 		return -EINVAL;
 
 	MOD_INC_USE_COUNT;
-	skb_queue_head_init(&q->delayed);
 	init_timer(&q->timer);
 	q->timer.function = netem_watchdog;
 	q->timer.data = (unsigned long) sch;
-	q->counter = 0;
 
 	q->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
 	if (!q->qdisc) {
@@ -463,6 +472,7 @@ static int netem_dump(struct Qdisc *sch,
 	struct rtattr *rta = (struct rtattr *) b;
 	struct tc_netem_qopt qopt;
 	struct tc_netem_corr cor;
+	struct tc_netem_reorder reorder;
 
 	qopt.latency = q->latency;
 	qopt.jitter = q->jitter;
@@ -476,6 +486,11 @@ static int netem_dump(struct Qdisc *sch,
 	cor.loss_corr = q->loss_cor.rho;
 	cor.dup_corr = q->dup_cor.rho;
 	RTA_PUT(skb, TCA_NETEM_CORR, sizeof(cor), &cor);
+
+	reorder.probability = q->reorder;
+	reorder.correlation = q->reorder_cor.rho;
+	RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
+
 	rta->rta_len = skb->tail - b;
 
 	return skb->len;
Index: netem-2.4/include/linux/pkt_sched.h
===================================================================
--- netem-2.4.orig/include/linux/pkt_sched.h
+++ netem-2.4/include/linux/pkt_sched.h
@@ -439,16 +439,17 @@ enum
 	TCA_NETEM_UNSPEC,
 	TCA_NETEM_CORR,
 	TCA_NETEM_DELAY_DIST,
+	TCA_NETEM_REORDER,
 };
 
-#define TCA_NETEM_MAX	TCA_NETEM_DELAY_DIST
+#define TCA_NETEM_MAX	TCA_NETEM_REORDER
 
 struct tc_netem_qopt
 {
 	__u32	latency;	/* added delay (us) */
 	__u32   limit;		/* fifo limit (packets) */
 	__u32	loss;		/* random packet loss (0=none ~0=100%) */
-	__u32	gap;		/* re-ordering gap (0 for delay all) */
+	__u32	gap;		/* re-ordering gap (0 for none) */
 	__u32   duplicate;	/* random packet dup  (0=none ~0=100%) */
 	__u32	jitter;		/* random jitter in latency (us) */
 };
@@ -460,6 +461,12 @@ struct tc_netem_corr
 	__u32	dup_corr;	/* duplicate correlation  */
 };
 
+struct tc_netem_reorder
+{
+	__u32	probability;
+	__u32	correlation;
+};
+
 #define NETEM_DIST_SCALE	8192
 
 #endif

^ permalink raw reply

* Re: [git patches try2] 2.6.x net driver updates
From: Linus Torvalds @ 2005-05-25 20:48 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Andrew Morton, Netdev, Linux Kernel
In-Reply-To: <4294BD9C.2050105@pobox.com>



On Wed, 25 May 2005, Jeff Garzik wrote:
>
> Does this work better?

Looks good.

If this was automated, are your changes to git-pull-script generic enough 
to be useful for others, or did you do a totally specialized one for just 
the "lots of heads in the same directory" case?

		Linus

^ permalink raw reply

* [PATCH] Scalable TCP
From: John Heffner @ 2005-05-25 19:50 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

This patch implements Tom Kelly's Scalable TCP congestion control algorithm 
for the modular framework.

The algorithm has some nice scaling properties, and has been used a fair bit 
in research, though is known to have significant fairness issues, so it's not 
really suitable for general purpose use.

Signed-off-by: John Heffner <jheffner@psc.edu>

Index: net/ipv4/Kconfig
===================================================================
--- ba5d2c7b7d035e88291b9692bd7006907e4c46f5/net/ipv4/Kconfig  (mode:100644)
+++ 4130df8533b79d0ccfd0195e707f4aa60a527e41/net/ipv4/Kconfig  (mode:100644)
@@ -481,6 +481,15 @@
        window. TCP Vegas should provide less packet loss, but it is
        not as aggressive as TCP Reno.
 
+config TCP_CONG_SCALABLE
+       tristate "Scalable TCP"
+       depends on EXPERIMENTAL
+       default n
+       ---help---
+       Scalable TCP is a sender-side only change to TCP which uses a
+       MIMD congestion control algorithm which has some nice scaling
+       properties, though is known to have fairness issues.
+       See http://www-lce.eng.cam.ac.uk/~ctk21/scalable/
 
 endmenu
 
Index: net/ipv4/Makefile
===================================================================
--- ba5d2c7b7d035e88291b9692bd7006907e4c46f5/net/ipv4/Makefile  (mode:100644)
+++ 4130df8533b79d0ccfd0195e707f4aa60a527e41/net/ipv4/Makefile  (mode:100644)
@@ -35,6 +35,7 @@
 obj-$(CONFIG_TCP_CONG_HYBLA) += tcp_hybla.o
 obj-$(CONFIG_TCP_CONG_HTCP) += tcp_htcp.o
 obj-$(CONFIG_TCP_CONG_VEGAS) += tcp_vegas.o
+obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
 
 obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
                      xfrm4_output.o
Index: net/ipv4/tcp_scalable.c
===================================================================
--- /dev/null  (tree:ba5d2c7b7d035e88291b9692bd7006907e4c46f5)
+++ 
4130df8533b79d0ccfd0195e707f4aa60a527e41/net/ipv4/tcp_scalable.c  (mode:100644)
@@ -0,0 +1,71 @@
+/* Tom Kelly's Scalable TCP
+ *
+ * See http://www-lce.eng.cam.ac.uk/~ctk21/scalable/
+ *
+ * John Heffner <jheffner@psc.edu>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+
+/* These factors derived from the recommended values in the paper:
+ * .01 and and 7/8.  We use 50 instead of 100 to account for
+ * delayed ack. */
+#define TCP_SCALABLE_AI_CNT    50U
+#define TCP_SCALABLE_MD_SCALE  3
+
+static void tcp_scalable_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
+                                   u32 in_flight, int flag)
+{
+       if (in_flight < tp->snd_cwnd)
+               return;
+       
+       if (tp->snd_cwnd <= tp->snd_ssthresh) {
+               tp->snd_cwnd++;
+       } else {
+               tp->snd_cwnd_cnt++;
+               if (tp->snd_cwnd_cnt > min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)) 
{
+                       tp->snd_cwnd++;
+                       tp->snd_cwnd_cnt = 0;
+               }
+       }
+       tp->snd_cwnd = min(tp->snd_cwnd, (__u32)tp->snd_cwnd_clamp);
+       tp->snd_cwnd_stamp = tcp_time_stamp;
+}
+
+static u32 tcp_scalable_ssthresh(struct tcp_sock *tp)
+{
+       return max(tp->snd_cwnd - (tp->snd_cwnd>>TCP_SCALABLE_MD_SCALE), 2U);
+}
+
+static u32 tcp_scalable_min_cwnd(struct tcp_sock *tp)
+{
+       return tp->snd_ssthresh / 2;
+}
+
+static struct tcp_congestion_ops tcp_scalable = {
+       .ssthresh       = tcp_scalable_ssthresh,
+       .cong_avoid     = tcp_scalable_cong_avoid,
+       .min_cwnd       = tcp_scalable_min_cwnd,
+       
+       .owner          = THIS_MODULE,
+       .name           = "scalable"
+};
+
+static int __init tcp_scalable_register(void)
+{
+       return tcp_register_congestion_control(&tcp_scalable);
+}
+
+static void __exit tcp_scalable_unregister(void)
+{
+       tcp_unregister_congestion_control(&tcp_scalable);
+}
+
+module_init(tcp_scalable_register);
+module_exit(tcp_scalable_unregister);
+
+MODULE_AUTHOR("John Heffner");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Scalable TCP");

^ permalink raw reply

* 2.6.12-rc5-tcp3
From: Stephen Hemminger @ 2005-05-25 18:32 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20050524163939.0fb86509@dxpl.pdx.osdl.net>

http://developer.osdl.org/shemminger/patches/2.6.12-rc5-tcp3

Keep up with the new 2.6.12-rc5
More minor tweaks:
	- tcp_ack26 is already in rc5
	+ change to min_cwnd to be same (ie ssthresh/2) for all reno like protocols
	  eventually plan to fix the cwnd undershoot bug 
		http://thread.gmane.org/gmane.linux.network/2094 
		http://oss.sgi.com/projects/netdev/archive/2005-04/msg00338.html

^ permalink raw reply

* Re: [PATCH] [BRIDGE]
From: Stephen Hemminger @ 2005-05-25 16:14 UTC (permalink / raw)
  To: Catalin(ux aka Dino) BOIE; +Cc: netdev, davem
In-Reply-To: <Pine.LNX.4.62.0505241024580.19687@webhosting.rdsbv.ro>

On Tue, 24 May 2005 10:29:25 +0300 (EEST)
"Catalin(ux aka Dino) BOIE" <util@deuroconsult.ro> wrote:

> Hello!
> 
> This patch set bridge device features using the common features of all 
> slaves. Also, it reacts to features change using ethtool on the slaves.
> 
> This patch depends on NETDEV_FEAT_CHANGE.patch.
> 

I will add it to the next set of patches for bridging. Hold off until
2.6.13

^ permalink raw reply

* Re: [0/5] Improvements to the ieee80211 layer
From: Jiri Benc @ 2005-05-25 11:20 UTC (permalink / raw)
  To: Zhu Yi; +Cc: NetDev, jbohac
In-Reply-To: <1117004116.3737.30.camel@debian.sh.intel.com>

On Wed, 25 May 2005 14:55:16 +0800, Zhu Yi wrote:
> Do you just clean up current ieee80211 code to still do 802.11 <-> 802.3
> conversion inside the driver or you plan to handle real 802.11 frames in
> the stack like this?
> http://oss.sgi.com/archives/netdev/2005-03/msg01405.html

We are trying to handle real 802.11 frames. Have you made any progress
in your work since posting that patch? If so, could you please post it
to netdev (or to us)?

Thanks.


-- 
Jiri Benc
SUSE Labs

^ permalink raw reply

* Re: [0/5] Improvements to the ieee80211 layer
From: Jiri Benc @ 2005-05-25  9:42 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Jirka Bohac, NetDev
In-Reply-To: <20050525092710.GA1926@elf.ucw.cz>

On Wed, 25 May 2005 11:27:10 +0200, Pavel Machek wrote:
> net/ieee80211/ieee80211_rx.c:281: error: `dev' undeclared (first use
> in this function)

Thanks, we had CONFIG_IEEE80211_CRYPT_TKIP disabled when testing as
there seem to be more important things to deal with. Will be fixed in
the next patch series.


-- 
Jiri Benc
SUSE Labs

^ permalink raw reply

* Re: [0/5] Improvements to the ieee80211 layer
From: Pavel Machek @ 2005-05-25  9:27 UTC (permalink / raw)
  To: Jirka Bohac; +Cc: NetDev
In-Reply-To: <20050525082956.GA20739@dwarf.suse.cz>

Hi!

> > > This is the first series of patches that try to convert it to a generic
> > > IEEE 802.11 layer, usable for most of today's wireless cards.
> > 
> > Are they against -rc4-mm2?
> 
> No, they're against -rc3-mm3. The whole ieee80211 layer has been
> accidentally removed from -rc4-mm3 (see
> http://lkml.org/lkml/2005/5/18/57 )
> 
> > Would it be possible to put agregate patch on the web somewhere (or
> > git tree?). I would certainly be easier to test....
> 
> Hmm, always thought that small patches would be preferred ;-)
> Here you go: http://jikos.cz/~jbohac/tmp/big_80211_patch_01.patch.bz2
> This is combined from all the 11 patches we posted yesterday

Well, they certainly are prefered for review, but applying series of
11 patches, with two that need to be get from the web is not that
easy....

I could not compile it:

  CC      net/ieee80211/ieee80211_rx.o
net/ieee80211/ieee80211_rx.c: In function
`ieee80211_rx_frame_decrypt':
net/ieee80211/ieee80211_rx.c:281: error: `dev' undeclared (first use
in this function)
net/ieee80211/ieee80211_rx.c:281: error: (Each undeclared identifier
is reported only once
net/ieee80211/ieee80211_rx.c:281: error: for each function it appears
in.)
make[2]: *** [net/ieee80211/ieee80211_rx.o] Error 1
make[1]: *** [net/ieee80211] Error 2
make: *** [net] Error 2
468.99user 31.35system 523.98 (8m43.981s) elapsed 95.49%CPU
pavel@amd:/data/l/linux-mm$

After fixing that, ipw2100 seems to work. [Funny, it changed name from
eth1 to wlan0?] Good.

								Pavel

^ permalink raw reply

* Re: [0/5] Improvements to the ieee80211 layer
From: Jirka Bohac @ 2005-05-25  8:29 UTC (permalink / raw)
  To: Pavel Machek; +Cc: NetDev
In-Reply-To: <20050524185241.GB2470@elf.ucw.cz>

On Tue, May 24, 2005 at 08:52:41PM +0200, Pavel Machek wrote:
> > This is the first series of patches that try to convert it to a generic
> > IEEE 802.11 layer, usable for most of today's wireless cards.
> 
> Are they against -rc4-mm2?

No, they're against -rc3-mm3. The whole ieee80211 layer has been
accidentally removed from -rc4-mm3 (see
http://lkml.org/lkml/2005/5/18/57 )

> Would it be possible to put agregate patch on the web somewhere (or
> git tree?). I would certainly be easier to test....

Hmm, always thought that small patches would be preferred ;-)
Here you go: http://jikos.cz/~jbohac/tmp/big_80211_patch_01.patch.bz2
This is combined from all the 11 patches we posted yesterday


regards,

-- 
Jirka Bohac <jbohac@suse.cz>
SUSE Labs, SUSE CR

^ permalink raw reply

* Re: [PATCH] NETDEV: fix receiving multicast frames.
From: Herbert Xu @ 2005-05-25  8:19 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / ????; +Cc: jgarzik, netdev, yoshfuji, usagi-core
In-Reply-To: <20050525.160704.28910448.yoshfuji@linux-ipv6.org>

YOSHIFUJI Hideaki / ???? <yoshfuji@linux-ipv6.org> wrote:
> From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> 
> Some USB ethernet drivers did not accept multicast frames appropriately.
> IPv6 did not work with those drivers without this patch.
> 
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> 
> Index: drivers/usb/net/pegasus.c
> ===================================================================
> --- 5b713315560487f8c288820b17061fe27016c2cc/drivers/usb/net/pegasus.c  (mode:100644)
> +++ uncommitted/drivers/usb/net/pegasus.c  (mode:100644)
> @@ -1166,7 +1166,7 @@
>                pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
>                if (netif_msg_link(pegasus))
>                        pr_info("%s: Promiscuous mode enabled.\n", net->name);
> -       } else if ((net->mc_count > multicast_filter_limit) ||
> +       } else if (net->mc_count ||
>                   (net->flags & IFF_ALLMULTI)) {
>                pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
>                pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
> Index: drivers/usb/net/rtl8150.c
> ===================================================================
> --- 5b713315560487f8c288820b17061fe27016c2cc/drivers/usb/net/rtl8150.c  (mode:100644)
> +++ uncommitted/drivers/usb/net/rtl8150.c  (mode:100644)
> @@ -667,7 +667,7 @@
>        if (netdev->flags & IFF_PROMISC) {
>                dev->rx_creg |= cpu_to_le16(0x0001);
>                info("%s: promiscuous mode", netdev->name);
> -       } else if ((netdev->mc_count > multicast_filter_limit) ||
> +       } else if (netdev->mc_count ||
>                   (netdev->flags & IFF_ALLMULTI)) {
>                dev->rx_creg &= cpu_to_le16(0xfffe);
>                dev->rx_creg |= cpu_to_le16(0x0002);

This patch is correct.  However, I presume these chips do actually have
filter support so it'd be even better if we could utilise that.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ 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