Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] gre: propagate state of link back go to tunnel
From: David Miller @ 2012-03-22  2:18 UTC (permalink / raw)
  To: shemminger; +Cc: herbert, netdev
In-Reply-To: <20120319165843.7b18412a@nehalam.linuxnetplumber.net>

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Mon, 19 Mar 2012 16:58:43 -0700

> GRE tunnels like other layered devices should propagate
> carrier and RFC2863 state from lower device to tunnel.
> Based on similar code in vlan device driver.
> By using operstate it is possible for user mode to create tunnel
> and use stepped outlined in Documentation/networking/operstate.txt
> to control carrier.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
> Not urgent, can wait if the release window is already over the
> queue limit

Yeah, please resubmit this once net-next opens back up.

And meanwhile you can duplicate this fix to ipip, sit, ip6_tunnel etc.

^ permalink raw reply

* Re: [PATCH net-next] [v2] bonding: remove entries for master_ip and vlan_ip and query devices instead
From: David Miller @ 2012-03-22  2:34 UTC (permalink / raw)
  To: andy; +Cc: netdev, ralf.zeidler
In-Reply-To: <1332365802-21550-1-git-send-email-andy@greyhouse.net>

From: Andy Gospodarek <andy@greyhouse.net>
Date: Wed, 21 Mar 2012 17:36:42 -0400

> As the Subject indicates this patch drops the master_ip and vlan_ip
> elements from the 'bonding' and 'vlan_entry' structs, respectively.
> This can be done because a device's address-list is now traversed to
> determine the optimal source IP address for ARP requests and for checks
> to see if the bonding device has a particular IP address.  This code
> could have all be contained inside the bonding driver, but it made more
> sense to me to EXPORT and call inet_confirm_addr since it did exactly
> what was needed.

I like this patch a lot but you have one little bug that needs to be
fixed:

> +	rcu_read_lock();
> +	in_dev = __in_dev_get_rcu(dev);
> +	rcu_read_unlock();
> +
> +	if (in_dev)
> +		addr = inet_confirm_addr(in_dev, dst, local, RT_SCOPE_HOST);

If you're going to do an RCU ref-less lookup of in_dev and then use
it, you have to include the "use" inside of the RCU protected section
as well.

Otherwise as soon as you rcu_read_unlock() the in_dev could be freed
up on you.

The only exception would be if you know that all callers of
bond_confirm_addr() ran in an RCU protected section, but I do not
think that is universally the case here.

If you think it might be the case that we are RCU protected in all of
these code paths already, you can remove the RCU locking altogether
from bond_confirm_addr() and run with lockdep enabled while exercising
all of the relevant code paths.

^ permalink raw reply

* Re: [PATCH] gianfar: Fix possible overrun and simplify interrupt name field creation
From: David Miller @ 2012-03-22  2:34 UTC (permalink / raw)
  To: joe; +Cc: netdev, linux-kernel, sandeep.kumar
In-Reply-To: <17d93e9eb16cbad75b20cdbcaf38f268260d6fd5.1332010469.git.joe@perches.com>

From: Joe Perches <joe@perches.com>
Date: Sat, 17 Mar 2012 12:05:38 -0700

> Space allocated for int_name_<foo> is unsufficient for
> maximal device name, expand it.
> 
> Code to create int_name_<foo> is obscure, simplify it
> by using sprintf.
> 
> Found by looking for unnecessary \ line continuations.
> Uncompiled, untested.
> 
> Signed-off-by: Joe Perches <joe@perches.com>

Can a gianfar expert please review and test this patch?

Thanks.

^ permalink raw reply

* Re: [PATCH v5] ipv6: Fix problem with expired dst cache
From: David Miller @ 2012-03-22  2:47 UTC (permalink / raw)
  To: gaofeng; +Cc: netdev, eric.dumazet
In-Reply-To: <4F6682AF.6020307@cn.fujitsu.com>

From: Gao feng <gaofeng@cn.fujitsu.com>
Date: Mon, 19 Mar 2012 08:49:51 +0800

> BUT what confuse me is that, in func ip6_rt_copy should we do
> rt6_set_from in any case or only when the ort has flag RTF_ADDRCONF
> and RTF_DEFAULT?

Your guess is as good as mine, unfortunately.  A lot of code in
this area is hard to decipher.

For example, I've spent the past several months trying to figure out
which kinds of ipv6 routes have explicit neighbour entries attached at
route insert time, which do not, etc.

^ permalink raw reply

* Claims Office
From: bmw.claimdpt22 @ 2012-03-22  3:01 UTC (permalink / raw)


You won BMW X6 XDrive Car and a £750,000.00GBP.Send name:tel: country: 
Official E-mail:bmw.claimdpt22@w.cn

^ permalink raw reply

* Query regarding pf_packet sockets
From: Prashant Batra (prbatra) @ 2012-03-22  3:22 UTC (permalink / raw)
  To: netdev

Hi ,

I am trying to use PF_PACKET socket along with filters applied on the socket through setsockopt, SO_ATTACH_FILTER.
Now as I create this socket, any packet coming to the kernel would be copied into the socket buffer for this socket.

So, even if I apply the filter, first few packets would always be those which do not match the filter. 

Is there a way (some socket option),  to make socket passive and active, so that I will set the socket in passive mode after creation, 
and then set it as active, after I apply the filter, so that I only receive the filtered packet in user space.

Thanks,
Prashant

^ permalink raw reply

* Re: Query regarding pf_packet sockets
From: Eric Dumazet @ 2012-03-22  4:28 UTC (permalink / raw)
  To: Prashant Batra (prbatra); +Cc: netdev
In-Reply-To: <B97B134FACB2024DB45F524AB0A7B7F2063EB8C6@XMB-BGL-419.cisco.com>

On Thu, 2012-03-22 at 08:52 +0530, Prashant Batra (prbatra) wrote:
> Hi ,
> 
> I am trying to use PF_PACKET socket along with filters applied on the socket through setsockopt, SO_ATTACH_FILTER.
> Now as I create this socket, any packet coming to the kernel would be copied into the socket buffer for this socket.
> 
> So, even if I apply the filter, first few packets would always be those which do not match the filter. 
> 
> Is there a way (some socket option),  to make socket passive and active, so that I will set the socket in passive mode after creation, 
> and then set it as active, after I apply the filter, so that I only receive the filtered packet in user space.
> 
> Thanks,
> Prashant
> 
1) open PF_PACKET
2)  Install a "deny all packets" filter
3) read all packets that might have been captured right before 2)
4) Install your filter

This is what is done by libpcap

^ permalink raw reply

* Re: tun oops dereferencing garbage nsproxy-> address.
From: Eric W. Biederman @ 2012-03-22  3:58 UTC (permalink / raw)
  To: maciej.rutecki; +Cc: Dave Jones, netdev, Linux Kernel, serue
In-Reply-To: <201203182102.15877.maciej.rutecki@gmail.com>

Maciej Rutecki <maciej.rutecki@gmail.com> writes:

> On wtorek, 13 marca 2012 o 04:42:02 Dave Jones wrote:
>> BUG: unable to handle kernel paging request at 0000000100000029
>> IP: [<ffffffffa06ec54f>] tun_chr_open+0x4f/0x80 [tun]
>> PGD 5ae4f067 PUD 0
>> Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
>> CPU 1
>> Modules linked in: tun binfmt_misc can_bcm cmtp kernelcapi nfnetlink bnep
>> can_raw af_802154 phonet bluetooth can pppoe pppox ppp_generic slhc irda
>> crc_ccitt rds af_key rose ax25 appletalk atm ipx p8022 psnap llc p8023
>> tcp_lp iwlwifi mac80211 cfg80211 nfs fscache auth_rpcgss nfs_acl fuse
>> lockd ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter
>> ip6_tables nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack xts
>> gf128mul dm_crypt dm_mirror dm_region_hash dm_log arc4 snd_hda_codec_hdmi
>> uvcvideo snd_hda_codec_idt videobuf2_core snd_usb_audio snd_hda_intel
>> videodev snd_hda_codec dell_wmi sparse_keymap media snd_usbmidi_lib
>> snd_hwdep v4l2_compat_ioctl32 snd_rawmidi cdc_ether videobuf2_vmalloc
>> videobuf2_memops snd_seq usbnet cdc_wdm mii cdc_acm snd_seq_device snd_pcm
>> dell_laptop dcdbas joydev microcode snd_timer tg3 snd pcspkr i2c_i801
>> iTCO_wdt iTCO_vendor_support soundcore snd_page_alloc rfkill wmi sunrpc
>> i915 drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded:
>> cfg80211]
>> 
>> Pid: 15413, comm: trinity Not tainted 3.3.0-rc7+ #54 Dell Inc. Adamo 13  
>> /0N70T0 RIP: 0010:[<ffffffffa06ec54f>]  [<ffffffffa06ec54f>]
>> tun_chr_open+0x4f/0x80 [tun] RSP: 0018:ffff8800a5e29bc8  EFLAGS: 00010286
>> RAX: ffff88012036fd88 RBX: ffff8801084c4dc0 RCX: 0000000000000006
>> RDX: 0000000100000001 RSI: ffff88000fd9abc8 RDI: 0000000000000292
>> RBP: ffff8800a5e29bd8 R08: 0000000000000000 R09: 0000000000000001
>> R10: 0000000000000000 R11: 0000000000000000 R12: ffff8801084c4dc0
>> R13: ffff88012eb10d20 R14: ffffffffa06f0000 R15: ffffffff81856ae0
>> FS:  00007f3ebcb1a700(0000) GS:ffff88013b400000(0000)
>> knlGS:0000000000000000 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> CR2: 0000000100000029 CR3: 00000000032bb000 CR4: 00000000000406e0
>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
>> Process trinity (pid: 15413, threadinfo ffff8800a5e28000, task
>> ffff88000fd9a4a0) Stack:
>>  00000000000000c8 0000000000000000 ffff8800a5e29c38 ffffffff813fcf38
>>  ffffffff81c54838 0000000000000001 ffff8800a5e29c18 ffffffff816a1afd
>>  ffff8801084c4dc0 ffff8801396bbab8 ffff88012eb10d20 0000000000000000
>> Call Trace:
>>  [<ffffffff813fcf38>] misc_open+0x1d8/0x670
>>  [<ffffffff816a1afd>] ? sub_preempt_count+0x9d/0xd0
>>  [<ffffffff811c2978>] chrdev_open+0x258/0x350
>>  [<ffffffff811baa04>] __dentry_open+0x384/0x550
>>  [<ffffffff816a1afd>] ? sub_preempt_count+0x9d/0xd0
>>  [<ffffffff811c2720>] ? cdev_put+0x30/0x30
>>  [<ffffffff811bc224>] nameidata_to_filp+0x74/0x80
>>  [<ffffffff811ce59c>] do_last+0x26c/0x930
>>  [<ffffffff811ced76>] path_openat+0xd6/0x3e0
>>  [<ffffffff810a6298>] ? sched_clock_cpu+0xb8/0x130
>>  [<ffffffff811cf1a2>] do_filp_open+0x42/0xa0
>>  [<ffffffff8169d845>] ? _raw_spin_unlock+0x35/0x60
>>  [<ffffffff811dd7cd>] ? alloc_fd+0x18d/0x210
>>  [<ffffffff811bc328>] do_sys_open+0xf8/0x1d0
>>  [<ffffffff810faadc>] ? __audit_syscall_entry+0xcc/0x310
>>  [<ffffffff811bc421>] sys_open+0x21/0x30
>>  [<ffffffff816a5a69>] system_call_fastpath+0x16/0x1b
>> Code: 00 00 00 e8 64 8d ab e0 48 85 c0 74 46 c7 00 00 00 00 00 48 c7 40 08
>> 00 00 00 00 65 48 8b 14 25 00 c9 00 00 48 8b 92 50 05 00 00 <48> 8b 52 28
>> f0 ff 42 04 48 89 50 10 48 89 83 28 01 00 00 31 c0 RIP 
>> [<ffffffffa06ec54f>] tun_chr_open+0x4f/0x80 [tun]
>>  RSP <ffff8800a5e29bc8>
>> CR2: 0000000100000029
>> Disabling lock debugging due to kernel taint
>> ---[ end trace 9e00e91b0629ad80 ]---
>> 
>> 
>> oops happened here..
>> 
>>         tfile->net = get_net(current->nsproxy->net_ns);
>>      548:       48 8b 92 50 05 00 00    mov    0x550(%rdx),%rdx
>>      54f:       48 8b 52 28             mov    0x28(%rdx),%rdx
>> 
>> My guess is the fuzzer called some syscall that set current->nsproxy
>> to garbage (0x0000000100000001), which later got dereferenced when it
>> subsequently randomly did an open() on tun.
>> 
>> Any thoughts ?
>> 
>> 	Dave
>> 
>
> I created a Bugzilla entry at 
> https://bugzilla.kernel.org/show_bug.cgi?id=42960
> for your bug/regression report, please add your address to the CC list in 
> there, thanks!

There is not enough information here to track this as any kind of bug to
be fixed.   This problem can be neither reproduced nor is it a
direct consequence of anything obvious in the code.  The bug should
simply be closed with "can not reproduce".  There is no evidence
that this is any kind of regression.

If there is a system to track weird failures and note strange
occurrences and to start looking for patterns this might be interesting,
but I don't believe that system is the kernel bugzilla system.

This was all covered in the discussion of this issue before you put it
in the kernel bugzilla so I don't understand why you bothered.  There is
simply too little information to do anything interesting with this
failure.  Most likely this is the result of a kernel memory stomp
triggered by an unprivileged process.

I think such memory stomps suck but there is not enough information in
this thread to really even start looking and there is a lot of kernel
code to look through.  You don't seem to be interested in digging into
this yourself so adding this to bugzilla simply appears to be a waste
of time.

Eric

^ permalink raw reply

* Re: e1000e: Avoid wrong check on TX hang
From: Jeff Kirsher @ 2012-03-22  5:11 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: netdev
In-Reply-To: <OF66508452.5C6F589E-ONC12579C8.005ECBB5-C12579C8.005F4640@transmode.se>

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

On Wed, 2012-03-21 at 18:20 +0100, Joakim Tjernlund wrote:
> I think commit 09357b00255c233705b1cf6d76a8d147340545b8(e1000e: Avoid wrong check on TX hang)
> needs to be applied in 3.2.x (and 3.0.x) too.
> 
> We have seen this on routers(we got 3):
> e1000e 0000:11:00.0: eth9: Detected Hardware Unit Hang:
>   TDH                  <a4>
>   TDT                  <a7>
>   next_to_use          <a7>
>   next_to_clean        <a4>
> buffer_info[next_to_clean]:
>   time_stamp           <1008e849f>
>   next_to_watch        <a4>
>   jiffies              <1008e85d8>
>   next_to_watch.status <0>
> MAC Status             <80387>
> PHY Status             <792d>
> PHY 1000BASE-T Status  <3800>
> PHY Extended Status    <3000>
> PCI Status             <10>
> 
> Applying the above patch on 3.2.12 makes the error go away.
> 
>    Jocke
> 

Thanks Joakim, I am aware of the issue/fix.  I will submit the fix to
all stable tree's back to 2.6.32.  Look for me posting the patch this
weekend.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* RE: Query regarding pf_packet sockets
From: Prashant Batra (prbatra) @ 2012-03-22  5:16 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1332390522.9433.17.camel@edumazet-glaptop>

That’s look good

Thanks.

-----Original Message-----
From: Eric Dumazet [mailto:eric.dumazet@gmail.com] 
Sent: Thursday, March 22, 2012 9:59 AM
To: Prashant Batra (prbatra)
Cc: netdev@vger.kernel.org
Subject: Re: Query regarding pf_packet sockets

On Thu, 2012-03-22 at 08:52 +0530, Prashant Batra (prbatra) wrote:
> Hi ,
> 
> I am trying to use PF_PACKET socket along with filters applied on the socket through setsockopt, SO_ATTACH_FILTER.
> Now as I create this socket, any packet coming to the kernel would be copied into the socket buffer for this socket.
> 
> So, even if I apply the filter, first few packets would always be those which do not match the filter. 
> 
> Is there a way (some socket option),  to make socket passive and active, so that I will set the socket in passive mode after creation, 
> and then set it as active, after I apply the filter, so that I only receive the filtered packet in user space.
> 
> Thanks,
> Prashant
> 
1) open PF_PACKET
2)  Install a "deny all packets" filter
3) read all packets that might have been captured right before 2)
4) Install your filter

This is what is done by libpcap





^ permalink raw reply

* Re: [PATCH net V4 2/2] igb: offer a PTP Hardware Clock instead of the timecompare method
From: Richard Cochran @ 2012-03-22  6:41 UTC (permalink / raw)
  To: chetan loke
  Cc: e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org,
	Ronciak, John, john.stultz@linaro.org, Keller, Jacob E,
	tglx@linutronix.de
In-Reply-To: <CAAsGZS6QuMJoXz8mmqZsgfTF2ykRz6KG_nCoPBBkTA4z3idoGA@mail.gmail.com>

On Wed, Mar 21, 2012 at 05:50:34PM -0400, chetan loke wrote:
> 
> Richard - Intent is to make the readers(get_time) wait (or return last
> read value if the seq_counter tripped because you know that this value
> was recent) and let the tx/rx path continue. I haven't looked in more
> details but as Jake mentioned you will also need to change the way you
> read the values(by not using timecounter_read in get_time).

I don't get what you guys are saying. How can you avoid the spin lock
around the two time register reads? How about a patch or some pseudo
code?

Thanks,
Richard

------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here 
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply

* [patch] netlabel: use GFP flags from caller instead of GFP_ATOMIC
From: Dan Carpenter @ 2012-03-22  6:41 UTC (permalink / raw)
  To: Paul Moore; +Cc: David S. Miller, netdev, kernel-janitors

This function takes a GFP flags as a parameter, but they are never used.
We don't take a lock in this function so there is no reason to prefer
GFP_ATOMIC over the caller's GFP flags.

There is only one caller, cipso_v4_map_cat_rng_ntoh(), and it passes
GFP_ATOMIC as the GFP flags so this doesn't change how the code works.
It's just a cleanup.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 2560e7b..7c94aed 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -597,7 +597,7 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
 			iter = iter->next;
 			iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
 		}
-		ret_val = netlbl_secattr_catmap_setbit(iter, spot, GFP_ATOMIC);
+		ret_val = netlbl_secattr_catmap_setbit(iter, spot, flags);
 	}
 
 	return ret_val;

^ permalink raw reply related

* [patch] RDS: use gfp flags from caller in conn_alloc()
From: Dan Carpenter @ 2012-03-22  6:44 UTC (permalink / raw)
  To: Venkat Venkatsubra; +Cc: David S. Miller, rds-devel, netdev, kernel-janitors

We should be using the gfp flags the caller specified here, instead of
GFP_KERNEL.  I think this might be a bugfix, depending on the value of
"sock->sk->sk_allocation" when we call rds_conn_create_outgoing() in
rds_sendmsg().  Otherwise, it's just a cleanup.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/net/rds/loop.c b/net/rds/loop.c
index 87ff2a8..6b12b68 100644
--- a/net/rds/loop.c
+++ b/net/rds/loop.c
@@ -121,7 +121,7 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 	struct rds_loop_connection *lc;
 	unsigned long flags;
 
-	lc = kzalloc(sizeof(struct rds_loop_connection), GFP_KERNEL);
+	lc = kzalloc(sizeof(struct rds_loop_connection), gfp);
 	if (!lc)
 		return -ENOMEM;
 
diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c
index 9556d28..a91e1db 100644
--- a/net/rds/iw_cm.c
+++ b/net/rds/iw_cm.c
@@ -694,7 +694,7 @@ int rds_iw_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 	unsigned long flags;
 
 	/* XXX too lazy? */
-	ic = kzalloc(sizeof(struct rds_iw_connection), GFP_KERNEL);
+	ic = kzalloc(sizeof(struct rds_iw_connection), gfp);
 	if (!ic)
 		return -ENOMEM;
 
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index 51c8689..a1e1162 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -749,7 +749,7 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 	int ret;
 
 	/* XXX too lazy? */
-	ic = kzalloc(sizeof(struct rds_ib_connection), GFP_KERNEL);
+	ic = kzalloc(sizeof(struct rds_ib_connection), gfp);
 	if (!ic)
 		return -ENOMEM;
 

^ permalink raw reply related

* Re: [PATCH v2] ethernet driver for the WIZnet W5300 chip
From: Mike Sinkovsky @ 2012-03-22  6:58 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: netdev, linux-kernel, msink
In-Reply-To: <4F69EA7E.4030606@openwrt.org>

21.03.2012 20:49, Florian Fainelli wrote:
>> +#if defined(CONFIG_WIZNET_BUS_DIRECT)
>> +#define detect_bus_mode(priv, mem_size) do {} while(0)
>> +#define read_reg_u16    read_u16_direct
>> +#define write_reg_u16    write_u16_direct
>> +
>> +#elif defined(CONFIG_WIZNET_BUS_INDIRECT)
>> +#define detect_bus_mode(priv, mem_size) do {} while(0)
>> +#define read_reg_u16    read_u16_indirect
>> +#define write_reg_u16    write_u16_indirect
> Looks like you don't have to make such decisions at compile-time. 
> Since it is a platform driver, better supply this through 
> platform_data instead.
Interface bus mode can be selected in .config (make menuconfig etc.)
If don't selected explicitly in .config, platform_device.resource[] is 
used in runtime to setup callbacks.
This hack was done for performance reasons, but may be not necessary, 
I'm not sure.


> Please implement phylib to properly report the link state to the 
> networking stack and ethtool.
This chip don't allow any access to phy interface, it completely hidden 
for host processor.
The only way I found - to wire pin LINK from W5300 to some GPIO, then 
ise RIGING/FALLING interrupt for tthat GPIO:
> +static irqreturn_t w5300_detect_link(int irq, void *ndev_instance)
> +{
> +        struct net_device *ndev = ndev_instance;
> +        struct w5300_private *priv = netdev_priv(ndev);
> +
> +        if (netif_running(ndev)) {
> +                if (gpio_get_value(priv->link) == 0)
> +                        netif_carrier_off(ndev);
> +                else
> +                        netif_carrier_on(ndev);
> +        }
> +
> +        return IRQ_HANDLED;
> +}
Isn't it enough for networking stack?


> Allow platform_data to pass a valid MAC address to this driver instead 
> of defaulting to random unconditionnaly.
>
Do you mean - create .h file in /include/linux/platform_data/ ?
Ok, will do in next version.

Thanks.

---
Mike

^ permalink raw reply

* Re: [PATCH net V4 2/2] igb: offer a PTP Hardware Clock instead of the timecompare method
From: Richard Cochran @ 2012-03-22  7:00 UTC (permalink / raw)
  To: chetan loke
  Cc: netdev, e1000-devel, jacob.e.keller, jeffrey.t.kirsher,
	john.ronciak, john.stultz, tglx
In-Reply-To: <CAAsGZS4xU6Uqu59r6donnVmvi-NdxhQRi-7FEEHwg0mFcmKhxA@mail.gmail.com>

On Wed, Mar 21, 2012 at 01:02:38PM -0400, chetan loke wrote:
> > Well, if people want to write programs that make no sense at all,
> > then I can cannot stop them. There really isn't any point in general
> > applications using the PHC directly. You can easily synchronize the
> 
> I thought the core patches enables using PHC as a reference time, no?
> So that seems to be contradicting the PHC API. If there's no point
> then why are we exporting PHC->get_time as a generic interface? May be
> just limit get_time interface to something like ethtool?

There was a long discussion on this list and the lkml about the API,
and I think what we came up is a good solution. There is nothing to
prevent you from rewriting all of user space to use a dynamic clock ID
instead of CLOCK_REALTIME, but I seriously doubt anyone is going to do
this.

It does make sense for the time synchronization services to use
the clock_gettime calls to do their work.

Calls to read the system clock are highly optimized (at least on x86),
and thus applications wanting quick time stamps are wise to use that
clock. Calling clock_gettime on another clock, a PHY based clock for
example, might block for a long, long time. There is no way to
optimize around that, since it is a MDIO bus transaction.

> Once, the clocks are in-sync, it's not an error - but  *somewhat
> fixed* latency. There are users who don't want to spend extra money
> for expensive GPS time-sync stuff but yet have enough CPUs such that
> they can dedicate 1 CPU for book-keeping. For such users, this
> *somewhat fixed* latency should be constant over a period of time even
> when other CPUs are processing traffic at line rate.

Consider the following program:

	if (interesting_event()) {
		/* what happens in this empty space? preemption? interrupt? */
		clock_gettime();
	}

Run cyclictest on your system, and let's then talk about your 'fixed'
latency numbers.

> Sounds good on the tools part. But if applications should stick to
> reading sys-time then either we shouldn't export the API or export it
> selectively.If there's an API then user-space guys will use it. For
> this discussion, lets focus on PCI cards because that is what this
> patch talks about. Also the majority of the deployment will be LOM or
> PCI cards.

Like I said, I personally don't see much utility in optimizing igb. I
only have so much time to spend, but I am not against you or Jacob or
anyone else doing that work.

Thanks,
Richard

^ permalink raw reply

* Re: [PATCH net V4 2/2] igb: offer a PTP Hardware Clock instead of the timecompare method
From: Richard Cochran @ 2012-03-22  7:09 UTC (permalink / raw)
  To: Keller, Jacob E
  Cc: e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org,
	Ronciak, John, john.stultz@linaro.org, tglx@linutronix.de,
	chetan loke
In-Reply-To: <02874ECE860811409154E81DA85FBB580DA6CC@ORSMSX105.amr.corp.intel.com>

On Wed, Mar 21, 2012 at 05:06:09PM +0000, Keller, Jacob E wrote:
> 
> I agree with Chetan. I think it would be best to make sure the
> correct form of locking is done, as we are providing an interface to
> the user. Using a seqlock would allow for preventing the ioctls from
> blocking the hardware timestamp code.

Okay, you can improve the time stamping path in the driver to avoid
contending with callers to clock_gettime. But that will not help the
hundreds of clock_gettime callers from contending with each other.

> It's a fairly simple change for the gettime function (the most
> likely culprit to be hammered) by changing it to use
> timecounter_cyc2time function instead of timecounter_read. (as long
> as timecounter_read is called at least every 1/2 the system time
> overflow, which it should be due to the work task.)
>
> With that change, then the section use a seqlock (along with the
> section for checking hardware timestamps). Other places would do the
> full write lock.

So, you think that clock_gettime should not read the card's time
registers?

Richard



------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here 
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply

* [PATCH 3/3] net: orinoco: add error handling for failed kmalloc().
From: santosh nayak @ 2012-03-22  7:12 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ
  Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	kernel-janitors-u79uwXL29TY76Z2rM5mHXA, Santosh Nayak

From: Santosh Nayak <santoshprasadnayak-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

With flag 'GFP_ATOMIC', probability of allocation failure is more.
Add error handling after kmalloc() call to avoid null dereference.

Signed-off-by: Santosh Nayak <santoshprasadnayak-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/net/wireless/orinoco/main.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index dd6c64a..24a768b 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -1336,6 +1336,10 @@ static void qbuf_scan(struct orinoco_private *priv, void *buf,
 	unsigned long flags;
 
 	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+	if (!sd) {
+		printk(KERN_ERR "%s: failed to alloc memory\n", __func__);
+		return;
+	}
 	sd->buf = buf;
 	sd->len = len;
 	sd->type = type;
@@ -1353,6 +1357,10 @@ static void qabort_scan(struct orinoco_private *priv)
 	unsigned long flags;
 
 	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+	if (!sd) {
+		printk(KERN_ERR "%s: failed to alloc memory\n", __func__);
+		return;
+	}
 	sd->len = -1; /* Abort */
 
 	spin_lock_irqsave(&priv->scan_lock, flags);
-- 
1.7.4.4

--
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 related

* IPv6 flapping with kernel 3.3 (regression from 3.2.9)
From: Marc Haber @ 2012-03-22  7:34 UTC (permalink / raw)
  To: linux-kernel, netdev

Hi,

I have a host which has IPv6 misbehaving when running with Linux 3.3.
It is flawlessly working with Linux 3.2.9.

The host
- is running Debian stable (x64_64) with a few locally built and/or
  backported packages, including the kernel.
- has native IPv6 connectivity on eth0
- is not doing SLAAC on eth0, both IP address (from 2a01/16) and
  default gateway (fe80::1) are statically configured
- is running a handful of VMs using KVM/libvirt
- has IPv6 forwarding enabled
- does IPv4 NAT
- has a handful of iptables rules, both for v4 and v6. ICMP and ICMPv6
  are fully open

- the gateway is not under my control
- the VMs are either bridged to br0 or to br1
- both br0 and br1 have an IPv6 /64 and radvd running to provide IPv6
  to the VMs

This setup is unique in my machine list, my other machines either are
no KVM hosts or do only have IPv6 tunneled.

When I run the box with kernel 3.3, it drops off the IPv6 network
every few minutes and is not responding to pings any more. This state
stays like 30 seconds to a minute and then IPv6 resumes. It looks to
me that the box does not lose its default route though. Once in a
while, I see "fe80::1 dev eth0  router FAILED" in the ip neigh output.

Running a continuous ping in either direction doesn't seem to help.

Booting the box back to 3.2.9 immediately fixes the issue.

I have not yet re-tried going back to 3.3 since a few of the VMs are
too important to reboot again today. I tried running tcpdump on eth0
over night but hit br1 instead, so I don't have any packet dumps to
show.

I guess that something goes wrong with neighbor detection regarding
the IPv6 gateway.

Was there a relevant change between 3.2.9 and 3.3? Where do I look for
the issue?

Greetings
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 31958061
Nordisch by Nature |  How to make an American Quilt | Fax: *49 621 31958062

^ permalink raw reply

* [PATCH net 1/2] bonding:delete rlb entry if bond's ip is deleted
From: Weiping Pan @ 2012-03-22  8:18 UTC (permalink / raw)
  Cc: Weiping Pan, Jay Vosburgh, Andy Gospodarek,
	open list:BONDING DRIVER, open list
In-Reply-To: <cover.1332386801.git.panweiping3@gmail.com>

When the ip of bonding is deleted, its rlb table still contains old invalid
mappings, just delete them to avoid poisoning other clients arp cache.

Signed-off-by: Weiping Pan <panweiping3@gmail.com>
---
 drivers/net/bonding/bond_alb.c  |   35 +++++++++++++++++++++++++++++++++++
 drivers/net/bonding/bond_alb.h  |    2 ++
 drivers/net/bonding/bond_main.c |    1 +
 3 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index f820b26..bca1039 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -853,6 +853,41 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
 	_unlock_rx_hashtbl_bh(bond);
 }
 
+/* delete all rlb entries whose ip_src equals ip */
+void bond_alb_delete_entry(struct bonding *bond, __be32 ip)
+{
+	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+	u32 curr_index;
+
+	_lock_rx_hashtbl_bh(bond);
+
+	curr_index = bond_info->rx_hashtbl_head;
+	while (curr_index != RLB_NULL_INDEX) {
+		struct rlb_client_info *curr = &(bond_info->rx_hashtbl[curr_index]);
+		u32 next_index = bond_info->rx_hashtbl[curr_index].next;
+		u32 prev_index = bond_info->rx_hashtbl[curr_index].prev;
+		if (curr->assigned && (curr->ip_src == ip)) {
+			if (curr_index == bond_info->rx_hashtbl_head) {
+				bond_info->rx_hashtbl_head = next_index;
+			}
+
+			if (prev_index != RLB_NULL_INDEX) {
+				bond_info->rx_hashtbl[prev_index].next = next_index;
+			}
+
+			if (next_index != RLB_NULL_INDEX) {
+				bond_info->rx_hashtbl[next_index].prev = prev_index;
+			}
+
+			rlb_init_table_entry(curr);
+		}
+
+		curr_index = next_index;
+	}
+
+	_unlock_rx_hashtbl_bh(bond);
+}
+
 /*********************** tlb/rlb shared functions *********************/
 
 static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 90f140a..38863fc 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -163,5 +163,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
 void bond_alb_monitor(struct work_struct *);
 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
 void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
+
+void bond_alb_delete_entry(struct bonding *bond, __be32 ip);
 #endif /* __BOND_ALB_H__ */
 
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 435984a..ec071b9 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3315,6 +3315,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
 				return NOTIFY_OK;
 			case NETDEV_DOWN:
 				bond->master_ip = 0;
+				bond_alb_delete_entry(bond, ifa->ifa_local);
 				return NOTIFY_OK;
 			default:
 				return NOTIFY_DONE;
-- 
1.7.4

^ permalink raw reply related

* [PATCH net 2/2] bonding:delete rlb entry at regular intervals
From: Weiping Pan @ 2012-03-22  8:18 UTC (permalink / raw)
  Cc: Weiping Pan, Jay Vosburgh, Andy Gospodarek,
	open list:BONDING DRIVER, open list
In-Reply-To: <cover.1332386801.git.panweiping3@gmail.com>

Jiri Bohac(jbohac@suse.cz) found that once an IP address is recorded in the
rlb hash table, it stays there indefinitely. If this IP address is migrated
to a different host in the network, bonding still sends out ARP packets
that poison other systems' ARP caches with invalid information.

Assume the rlb entry is like <source ip, dest ip, dest mac>.

There are some kinds of migration.

1 delete ip address from bond device
If one ip address is deleted from bond device, the rlb table still contains
the old mapping.

2 swap ip address between bond0 and HostB
before the change:
                            ---- HostC(ipC)--
HostA(ipA) ----- switch ---|-- eth0 - bond0  |
HostB(ipB) -----/       \--|-- eth1 -/       |
                            -----------------

Like this topo, HostC and HostB can swap their ip addresses.
after the change:
                            ---- HostC(ipB)--
HostA(ipA) ----- switch ---|-- eth0 - bond0  |
HostB(ipC) -----/       \--|-- eth1 -/       |
                            -----------------
Then bonding will still send arp replies to HostA with the source ip  is ipC,
and it will poison arp cache of HostA, so HostA can not ping HostB now.

3 clients change their ip address, even swap them
before the change:
                           ----- HostC(ipC)--
HostA(ipA) ----- switch ---|-- eth0 - bond0  |
HostB(ipB) -----/       \--|-- eth1 -/       |
                            -----------------

after the change:
                            ---- HostC(ipC)--
HostA(ipB) ----- switch ---|-- eth0 - bond0  |
HostB(ipA) -----/       \--|-- eth1 -/       |
                            -----------------

Then rlb table still contains old mapping, that is <ipC, ipA, macA> and
<ipC, ipB, macB>, and continues to send arp replies to them.

4 bond can be enslave to a bridge
before the change:
                                 br0
                                  |
                                bond0
                               ___|___
                              |       |
HostA(ipA) --- NetworkA --- eth0     eth1 --- NetworkB --- hostB(ipB)

after the change:
                                 br0
                                  |
                                bond0
                               ___|___
                              |       |
HostA(ipB) --- NetworkA --- eth0     eth1 --- NetworkB --- hostB(ipA)

Then rlb table still contains old mapping, that is <ipA, ipB, macB>,
and continues to send arp replies to HostB, it will poison arp cache of HostB.

There are some attempts to fix this problem, 
http://marc.info/?l=linux-netdev&m=133036407906892&w=4
http://marc.info/?l=linux-netdev&m=133057427414043&w=4

But they did not fix the root cause of the problem, that rlb table does not
have a aging mechanism, the entry is valid for ever unless it is replaced.

In this patchset I want to add aging mechanism to rlb table.

Assume RLB_MONITOR_DELAY is 2 seconds and RLB_WORK_COUNTER_TIMES is 3.
Every 6 seconds bonding will make all entries invalid.
Every 2 seconds, bonding will send arp requests to its all
clients, then if it receives corresponding arp reply, bonding will deem that
this entry is valid.
And we give a entry 3 opportunities to survive in 6 seconds.

TODO:
The ntt (need to transmit) mechanism of rlb has duplicate functions with this
patch, if this patch is accepted, ntt mechanism can be deleted.

Signed-off-by: Weiping Pan <panweiping3@gmail.com>
---
 drivers/net/bonding/bond_alb.c  |   95 ++++++++++++++++++++++++++++++++++----
 drivers/net/bonding/bond_alb.h  |    7 +++
 drivers/net/bonding/bond_main.c |   10 +++-
 3 files changed, 100 insertions(+), 12 deletions(-)

diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index bca1039..4be5bf1 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -333,12 +333,15 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
 
 	if ((client_info->assigned) &&
 	    (client_info->ip_src == arp->ip_dst) &&
-	    (client_info->ip_dst == arp->ip_src) &&
-	    (compare_ether_addr_64bits(client_info->mac_dst, arp->mac_src))) {
-		/* update the clients MAC address */
-		memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
-		client_info->ntt = 1;
-		bond_info->rx_ntt = 1;
+	    (client_info->ip_dst == arp->ip_src)) {
+		if (compare_ether_addr_64bits(client_info->mac_dst,
+						arp->mac_src)) {
+			/* update the clients MAC address */
+			memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
+			client_info->ntt = 1;
+			bond_info->rx_ntt = 1;
+		} else
+			client_info->used = 1;
 	}
 
 	_unlock_rx_hashtbl_bh(bond);
@@ -485,14 +488,20 @@ static void rlb_update_client(struct rlb_client_info *client_info)
 {
 	int i;
 
+	if (client_info->used)
+		return;
+
 	if (!client_info->slave) {
 		return;
 	}
 
+	if (is_zero_ether_addr(client_info->mac_dst))
+		return;
+
 	for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
 		struct sk_buff *skb;
 
-		skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
+		skb = arp_create(ARPOP_REQUEST, ETH_P_ARP,
 				 client_info->ip_dst,
 				 client_info->slave->dev,
 				 client_info->ip_src,
@@ -521,7 +530,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
 }
 
 /* sends ARP REPLIES that update the clients that need updating */
-static void rlb_update_rx_clients(struct bonding *bond)
+static void rlb_update_rx_clients(struct bonding *bond, bool force)
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	struct rlb_client_info *client_info;
@@ -532,7 +541,7 @@ static void rlb_update_rx_clients(struct bonding *bond)
 	hash_index = bond_info->rx_hashtbl_head;
 	for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
 		client_info = &(bond_info->rx_hashtbl[hash_index]);
-		if (client_info->ntt) {
+		if (client_info->ntt || force) {
 			rlb_update_client(client_info);
 			if (bond_info->rlb_update_retry_counter == 0) {
 				client_info->ntt = 0;
@@ -776,6 +785,67 @@ static void rlb_init_table_entry(struct rlb_client_info *entry)
 	entry->prev = RLB_NULL_INDEX;
 }
 
+/*
+ * bond_rlb_monitor
+ *
+ * Every RLB_MONITOR_DELAY seconds, send arp requests for all clients.
+ * And if bond receives corresponding arp reply from client,
+ * rlb_client_info->used will be set to 1.
+ * If rlb_client_info->used is not set to 1 during
+ * RLB_WORK_COUNTER_TIMES * RLB_MONITOR_DELAY seconds,
+ * then delete the rlb entry.
+ */
+void bond_rlb_monitor(struct work_struct *work)
+{
+	struct alb_bond_info *bond_info = container_of(work, struct alb_bond_info,
+					    rlb_work.work);
+
+	struct bonding *bond = container_of(bond_info, struct bonding,
+					    alb_info);
+	struct rlb_client_info *client_info;
+	u32 curr_index;
+
+	_lock_rx_hashtbl_bh(bond);
+	if (bond_info->rlb_work_counter++ < RLB_WORK_COUNTER_TIMES) {
+		_lock_rx_hashtbl_bh(bond);
+		rlb_update_rx_clients(bond, true);
+		queue_delayed_work(bond->wq, &bond_info->rlb_work, RLB_MONITOR_DELAY);
+		return;
+	}
+
+	bond_info->rlb_work_counter = 0;
+
+	curr_index = bond_info->rx_hashtbl_head;
+	for (; curr_index != RLB_NULL_INDEX;) {
+		u32 next_index;
+		u32 prev_index;
+		client_info = &(bond_info->rx_hashtbl[curr_index]);
+		next_index = client_info->next;
+		prev_index = client_info->prev;
+		if (client_info->used != 1) {
+			/* delete this rlb entry */
+			if (curr_index == bond_info->rx_hashtbl_head) {
+				bond_info->rx_hashtbl_head = next_index;
+			}
+			if (prev_index != RLB_NULL_INDEX) {
+				bond_info->rx_hashtbl[prev_index].next = next_index;
+			}
+			if (next_index != RLB_NULL_INDEX) {
+				bond_info->rx_hashtbl[next_index].prev = prev_index;
+			}
+
+			rlb_init_table_entry(client_info);
+		} else
+			client_info->used = 0;
+
+		curr_index = next_index;
+	}
+
+	_unlock_rx_hashtbl_bh(bond);
+
+	queue_delayed_work(bond->wq, &bond_info->rlb_work, RLB_MONITOR_DELAY);
+}
+
 static int rlb_initialize(struct bonding *bond)
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
@@ -804,6 +874,9 @@ static int rlb_initialize(struct bonding *bond)
 	/* register to receive ARPs */
 	bond->recv_probe = rlb_arp_recv;
 
+	INIT_DELAYED_WORK(&bond_info->rlb_work, bond_rlb_monitor);
+	queue_delayed_work(bond->wq, &bond_info->rlb_work, 0);
+
 	return 0;
 }
 
@@ -818,6 +891,8 @@ static void rlb_deinitialize(struct bonding *bond)
 	bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
 
 	_unlock_rx_hashtbl_bh(bond);
+
+	cancel_delayed_work_sync(&bond_info->rlb_work);
 }
 
 static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
@@ -1497,7 +1572,7 @@ void bond_alb_monitor(struct work_struct *work)
 			if (bond_info->rlb_update_delay_counter) {
 				--bond_info->rlb_update_delay_counter;
 			} else {
-				rlb_update_rx_clients(bond);
+				rlb_update_rx_clients(bond, false);
 				if (bond_info->rlb_update_retry_counter) {
 					--bond_info->rlb_update_retry_counter;
 				} else {
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 38863fc..5b7c433 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -68,6 +68,9 @@ struct slave;
  */
 #define RLB_PROMISC_TIMEOUT	(10*ALB_TIMER_TICKS_PER_SEC)
 
+#define RLB_MONITOR_DELAY 2 * HZ
+#define RLB_WORK_COUNTER_TIMES 3
+
 
 struct tlb_client_info {
 	struct slave *tx_slave;	/* A pointer to slave used for transmiting
@@ -104,6 +107,8 @@ struct rlb_client_info {
 	u32 next;		/* The next Hash table entry index */
 	u32 prev;		/* The previous Hash table entry index */
 	u8  assigned;		/* checking whether this entry is assigned */
+	u8  used;		/* checking whether this entry is used during
+				   RLB_MONITOR_DELAY seconds*/
 	u8  ntt;		/* flag - need to transmit client info */
 	struct slave *slave;	/* the slave assigned to this client */
 	u8 tag;			/* flag - need to tag skb */
@@ -135,6 +140,8 @@ struct alb_bond_info {
 	u8			rx_ntt;	/* flag - need to transmit
 					 * to all rx clients
 					 */
+	struct delayed_work 	rlb_work;
+	int 			rlb_work_counter;
 	struct slave		*next_rx_slave;/* next slave to be assigned
 						* to a new rx client for
 						*/
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ec071b9..b2bd96f 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4351,16 +4351,22 @@ static void bond_setup(struct net_device *bond_dev)
 
 static void bond_work_cancel_all(struct bonding *bond)
 {
+	struct alb_bond_info *bond_info = &BOND_ALB_INFO(bond);
+
 	if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
 		cancel_delayed_work_sync(&bond->mii_work);
 
 	if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
 		cancel_delayed_work_sync(&bond->arp_work);
 
-	if (bond->params.mode == BOND_MODE_ALB &&
-	    delayed_work_pending(&bond->alb_work))
+	if (bond->params.mode == BOND_MODE_ALB) {
+	    if (delayed_work_pending(&bond->alb_work))
 		cancel_delayed_work_sync(&bond->alb_work);
 
+	    if (delayed_work_pending(&bond_info->rlb_work))
+		cancel_delayed_work_sync(&bond_info->rlb_work);
+	}
+
 	if (bond->params.mode == BOND_MODE_8023AD &&
 	    delayed_work_pending(&bond->ad_work))
 		cancel_delayed_work_sync(&bond->ad_work);
-- 
1.7.4

^ permalink raw reply related

* Re: [PULL] vhost-net/virtio: fixes for 3.4
From: Michael S. Tsirkin @ 2012-03-22  8:27 UTC (permalink / raw)
  To: David Miller
  Cc: kvm, virtualization, netdev, linux-kernel, levinsasha928, nyh,
	nyh
In-Reply-To: <20120320145010.GA31570@redhat.com>

On Tue, Mar 20, 2012 at 04:50:41PM +0200, Michael S. Tsirkin wrote:
> The following changes since commit 5ffca28a4ac7abb8a254fafe6bd03b2f83667df7:
> 
>   Merge git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs (2012-02-27 07:59:33 -0800)
> 
> are available in the git repository at:
> 
>   ra.kernel.org:/pub/scm/linux/kernel/git/mst/vhost.git for_davem
> 
>   (ssh url as git.kernel.org seems down at the moment, when it comes up
>    git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git for_davem
>    should be the equivalent).
> 
> for you to fetch changes up to ea5d404655ba3b356d0c06d6a3c4f24112124522:
> 
>   vhost: fix release path lockdep checks (2012-02-28 09:13:22 +0200)
> 
> ----------------------------------------------------------------
> vhost/virtio: fixes for 3.4
> 
> This includes a couple of vhost-net bugfixes,
> and fixes tools/virtio making it useful again.
> 
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> 
> ----------------------------------------------------------------

Dave, just checking - not sure I made it clear that this pull request
is intended to go in through your tree.
If you see any issues pls let me know so I can fix them.
Thanks!

> Michael S. Tsirkin (4):
>       tools/virtio: add linux/module.h stub
>       tools/virtio: add linux/hrtimer.h stub
>       tools/virtio: stub out strong barriers
>       vhost: fix release path lockdep checks
> 
> Nadav Har'El (1):
>       vhost: don't forget to schedule()
> 
>  drivers/vhost/net.c         |    2 +-
>  drivers/vhost/vhost.c       |   11 +++++++----
>  drivers/vhost/vhost.h       |    2 +-
>  tools/virtio/linux/virtio.h |    3 +++
>  4 files changed, 12 insertions(+), 6 deletions(-)
>  create mode 100644 tools/virtio/linux/hrtimer.h
>  create mode 100644 tools/virtio/linux/module.h

^ permalink raw reply

* [PATCH net V2 1/2] bonding:delete rlb entry if bond's ip is deleted
From: Weiping Pan @ 2012-03-22  8:37 UTC (permalink / raw)
  To: netdev; +Cc: fubar, andy, linux-kernel, Weiping Pan
In-Reply-To: <cover.1332405098.git.panweiping3@gmail.com>

When the ip of bonding is deleted, its rlb table still contains old invalid
mappings, just delete them to avoid poisoning other clients arp cache.

Signed-off-by: Weiping Pan <panweiping3@gmail.com>
---
 drivers/net/bonding/bond_alb.c  |   35 +++++++++++++++++++++++++++++++++++
 drivers/net/bonding/bond_alb.h  |    2 ++
 drivers/net/bonding/bond_main.c |    1 +
 3 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index f820b26..bca1039 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -853,6 +853,41 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
 	_unlock_rx_hashtbl_bh(bond);
 }
 
+/* delete all rlb entries whose ip_src equals ip */
+void bond_alb_delete_entry(struct bonding *bond, __be32 ip)
+{
+	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+	u32 curr_index;
+
+	_lock_rx_hashtbl_bh(bond);
+
+	curr_index = bond_info->rx_hashtbl_head;
+	while (curr_index != RLB_NULL_INDEX) {
+		struct rlb_client_info *curr = &(bond_info->rx_hashtbl[curr_index]);
+		u32 next_index = bond_info->rx_hashtbl[curr_index].next;
+		u32 prev_index = bond_info->rx_hashtbl[curr_index].prev;
+		if (curr->assigned && (curr->ip_src == ip)) {
+			if (curr_index == bond_info->rx_hashtbl_head) {
+				bond_info->rx_hashtbl_head = next_index;
+			}
+
+			if (prev_index != RLB_NULL_INDEX) {
+				bond_info->rx_hashtbl[prev_index].next = next_index;
+			}
+
+			if (next_index != RLB_NULL_INDEX) {
+				bond_info->rx_hashtbl[next_index].prev = prev_index;
+			}
+
+			rlb_init_table_entry(curr);
+		}
+
+		curr_index = next_index;
+	}
+
+	_unlock_rx_hashtbl_bh(bond);
+}
+
 /*********************** tlb/rlb shared functions *********************/
 
 static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 90f140a..38863fc 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -163,5 +163,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
 void bond_alb_monitor(struct work_struct *);
 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
 void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
+
+void bond_alb_delete_entry(struct bonding *bond, __be32 ip);
 #endif /* __BOND_ALB_H__ */
 
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 435984a..ec071b9 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3315,6 +3315,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
 				return NOTIFY_OK;
 			case NETDEV_DOWN:
 				bond->master_ip = 0;
+				bond_alb_delete_entry(bond, ifa->ifa_local);
 				return NOTIFY_OK;
 			default:
 				return NOTIFY_DONE;
-- 
1.7.4

^ permalink raw reply related

* [PATCH net V2 2/2] bonding:delete rlb entry at regular intervals
From: Weiping Pan @ 2012-03-22  8:37 UTC (permalink / raw)
  To: netdev; +Cc: fubar, andy, linux-kernel, Weiping Pan
In-Reply-To: <cover.1332405098.git.panweiping3@gmail.com>

Jiri Bohac(jbohac@suse.cz) found that once an IP address is recorded in the
rlb hash table, it stays there indefinitely. If this IP address is migrated
to a different host in the network, bonding still sends out ARP packets
that poison other systems' ARP caches with invalid information.

Assume the rlb entry is like <source ip, dest ip, dest mac>.

There are some kinds of migration.

1 delete ip address from bond device
If one ip address is deleted from bond device, the rlb table still contains
the old mapping.

2 swap ip address between bond0 and HostB
before the change:
                            ---- HostC(ipC)--
HostA(ipA) ----- switch ---|-- eth0 - bond0  |
HostB(ipB) -----/       \--|-- eth1 -/       |
                            -----------------

Like this topo, HostC and HostB can swap their ip addresses.
after the change:
                            ---- HostC(ipB)--
HostA(ipA) ----- switch ---|-- eth0 - bond0  |
HostB(ipC) -----/       \--|-- eth1 -/       |
                            -----------------
Then bonding will still send arp replies to HostA with the source ip  is ipC,
and it will poison arp cache of HostA, so HostA can not ping HostB now.

3 clients change their ip address, even swap them
before the change:
                           ----- HostC(ipC)--
HostA(ipA) ----- switch ---|-- eth0 - bond0  |
HostB(ipB) -----/       \--|-- eth1 -/       |
                            -----------------

after the change:
                            ---- HostC(ipC)--
HostA(ipB) ----- switch ---|-- eth0 - bond0  |
HostB(ipA) -----/       \--|-- eth1 -/       |
                            -----------------

Then rlb table still contains old mapping, that is <ipC, ipA, macA> and
<ipC, ipB, macB>, and continues to send arp replies to them.

4 bond can be enslave to a bridge
before the change:
                                 br0
                                  |
                                bond0
                               ___|___
                              |       |
HostA(ipA) --- NetworkA --- eth0     eth1 --- NetworkB --- hostB(ipB)

after the change:
                                 br0
                                  |
                                bond0
                               ___|___
                              |       |
HostA(ipB) --- NetworkA --- eth0     eth1 --- NetworkB --- hostB(ipA)

Then rlb table still contains old mapping, that is <ipA, ipB, macB>,
and continues to send arp replies to HostB, it will poison arp cache of HostB.

There are some attempts to fix this problem, 
http://marc.info/?l=linux-netdev&m=133036407906892&w=4
http://marc.info/?l=linux-netdev&m=133057427414043&w=4

But they did not fix the root cause of the problem, that rlb table does not
have a aging mechanism, the entry is valid for ever unless it is replaced.

In this patchset I want to add aging mechanism to rlb table.

Assume RLB_MONITOR_DELAY is 2 seconds and RLB_WORK_COUNTER_TIMES is 3.
Every 6 seconds bonding will make all entries invalid.
Every 2 seconds, bonding will send arp requests to its all
clients, then if it receives corresponding arp reply, bonding will deem that
this entry is valid.
And we give a entry 3 opportunities to survive in 6 seconds.

TODO:
The ntt (need to transmit) mechanism of rlb has duplicate functions with this
patch, if this patch is accepted, ntt mechanism can be deleted.

Signed-off-by: Weiping Pan <panweiping3@gmail.com>
---
 drivers/net/bonding/bond_alb.c  |   95 ++++++++++++++++++++++++++++++++++----
 drivers/net/bonding/bond_alb.h  |    7 +++
 drivers/net/bonding/bond_main.c |   10 +++-
 3 files changed, 100 insertions(+), 12 deletions(-)

diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index bca1039..4be5bf1 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -333,12 +333,15 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
 
 	if ((client_info->assigned) &&
 	    (client_info->ip_src == arp->ip_dst) &&
-	    (client_info->ip_dst == arp->ip_src) &&
-	    (compare_ether_addr_64bits(client_info->mac_dst, arp->mac_src))) {
-		/* update the clients MAC address */
-		memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
-		client_info->ntt = 1;
-		bond_info->rx_ntt = 1;
+	    (client_info->ip_dst == arp->ip_src)) {
+		if (compare_ether_addr_64bits(client_info->mac_dst,
+						arp->mac_src)) {
+			/* update the clients MAC address */
+			memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
+			client_info->ntt = 1;
+			bond_info->rx_ntt = 1;
+		} else
+			client_info->used = 1;
 	}
 
 	_unlock_rx_hashtbl_bh(bond);
@@ -485,14 +488,20 @@ static void rlb_update_client(struct rlb_client_info *client_info)
 {
 	int i;
 
+	if (client_info->used)
+		return;
+
 	if (!client_info->slave) {
 		return;
 	}
 
+	if (is_zero_ether_addr(client_info->mac_dst))
+		return;
+
 	for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
 		struct sk_buff *skb;
 
-		skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
+		skb = arp_create(ARPOP_REQUEST, ETH_P_ARP,
 				 client_info->ip_dst,
 				 client_info->slave->dev,
 				 client_info->ip_src,
@@ -521,7 +530,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
 }
 
 /* sends ARP REPLIES that update the clients that need updating */
-static void rlb_update_rx_clients(struct bonding *bond)
+static void rlb_update_rx_clients(struct bonding *bond, bool force)
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	struct rlb_client_info *client_info;
@@ -532,7 +541,7 @@ static void rlb_update_rx_clients(struct bonding *bond)
 	hash_index = bond_info->rx_hashtbl_head;
 	for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
 		client_info = &(bond_info->rx_hashtbl[hash_index]);
-		if (client_info->ntt) {
+		if (client_info->ntt || force) {
 			rlb_update_client(client_info);
 			if (bond_info->rlb_update_retry_counter == 0) {
 				client_info->ntt = 0;
@@ -776,6 +785,67 @@ static void rlb_init_table_entry(struct rlb_client_info *entry)
 	entry->prev = RLB_NULL_INDEX;
 }
 
+/*
+ * bond_rlb_monitor
+ *
+ * Every RLB_MONITOR_DELAY seconds, send arp requests for all clients.
+ * And if bond receives corresponding arp reply from client,
+ * rlb_client_info->used will be set to 1.
+ * If rlb_client_info->used is not set to 1 during
+ * RLB_WORK_COUNTER_TIMES * RLB_MONITOR_DELAY seconds,
+ * then delete the rlb entry.
+ */
+void bond_rlb_monitor(struct work_struct *work)
+{
+	struct alb_bond_info *bond_info = container_of(work, struct alb_bond_info,
+					    rlb_work.work);
+
+	struct bonding *bond = container_of(bond_info, struct bonding,
+					    alb_info);
+	struct rlb_client_info *client_info;
+	u32 curr_index;
+
+	_lock_rx_hashtbl_bh(bond);
+	if (bond_info->rlb_work_counter++ < RLB_WORK_COUNTER_TIMES) {
+		_lock_rx_hashtbl_bh(bond);
+		rlb_update_rx_clients(bond, true);
+		queue_delayed_work(bond->wq, &bond_info->rlb_work, RLB_MONITOR_DELAY);
+		return;
+	}
+
+	bond_info->rlb_work_counter = 0;
+
+	curr_index = bond_info->rx_hashtbl_head;
+	for (; curr_index != RLB_NULL_INDEX;) {
+		u32 next_index;
+		u32 prev_index;
+		client_info = &(bond_info->rx_hashtbl[curr_index]);
+		next_index = client_info->next;
+		prev_index = client_info->prev;
+		if (client_info->used != 1) {
+			/* delete this rlb entry */
+			if (curr_index == bond_info->rx_hashtbl_head) {
+				bond_info->rx_hashtbl_head = next_index;
+			}
+			if (prev_index != RLB_NULL_INDEX) {
+				bond_info->rx_hashtbl[prev_index].next = next_index;
+			}
+			if (next_index != RLB_NULL_INDEX) {
+				bond_info->rx_hashtbl[next_index].prev = prev_index;
+			}
+
+			rlb_init_table_entry(client_info);
+		} else
+			client_info->used = 0;
+
+		curr_index = next_index;
+	}
+
+	_unlock_rx_hashtbl_bh(bond);
+
+	queue_delayed_work(bond->wq, &bond_info->rlb_work, RLB_MONITOR_DELAY);
+}
+
 static int rlb_initialize(struct bonding *bond)
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
@@ -804,6 +874,9 @@ static int rlb_initialize(struct bonding *bond)
 	/* register to receive ARPs */
 	bond->recv_probe = rlb_arp_recv;
 
+	INIT_DELAYED_WORK(&bond_info->rlb_work, bond_rlb_monitor);
+	queue_delayed_work(bond->wq, &bond_info->rlb_work, 0);
+
 	return 0;
 }
 
@@ -818,6 +891,8 @@ static void rlb_deinitialize(struct bonding *bond)
 	bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
 
 	_unlock_rx_hashtbl_bh(bond);
+
+	cancel_delayed_work_sync(&bond_info->rlb_work);
 }
 
 static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
@@ -1497,7 +1572,7 @@ void bond_alb_monitor(struct work_struct *work)
 			if (bond_info->rlb_update_delay_counter) {
 				--bond_info->rlb_update_delay_counter;
 			} else {
-				rlb_update_rx_clients(bond);
+				rlb_update_rx_clients(bond, false);
 				if (bond_info->rlb_update_retry_counter) {
 					--bond_info->rlb_update_retry_counter;
 				} else {
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 38863fc..5b7c433 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -68,6 +68,9 @@ struct slave;
  */
 #define RLB_PROMISC_TIMEOUT	(10*ALB_TIMER_TICKS_PER_SEC)
 
+#define RLB_MONITOR_DELAY 2 * HZ
+#define RLB_WORK_COUNTER_TIMES 3
+
 
 struct tlb_client_info {
 	struct slave *tx_slave;	/* A pointer to slave used for transmiting
@@ -104,6 +107,8 @@ struct rlb_client_info {
 	u32 next;		/* The next Hash table entry index */
 	u32 prev;		/* The previous Hash table entry index */
 	u8  assigned;		/* checking whether this entry is assigned */
+	u8  used;		/* checking whether this entry is used during
+				   RLB_MONITOR_DELAY seconds*/
 	u8  ntt;		/* flag - need to transmit client info */
 	struct slave *slave;	/* the slave assigned to this client */
 	u8 tag;			/* flag - need to tag skb */
@@ -135,6 +140,8 @@ struct alb_bond_info {
 	u8			rx_ntt;	/* flag - need to transmit
 					 * to all rx clients
 					 */
+	struct delayed_work 	rlb_work;
+	int 			rlb_work_counter;
 	struct slave		*next_rx_slave;/* next slave to be assigned
 						* to a new rx client for
 						*/
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ec071b9..b2bd96f 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4351,16 +4351,22 @@ static void bond_setup(struct net_device *bond_dev)
 
 static void bond_work_cancel_all(struct bonding *bond)
 {
+	struct alb_bond_info *bond_info = &BOND_ALB_INFO(bond);
+
 	if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
 		cancel_delayed_work_sync(&bond->mii_work);
 
 	if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
 		cancel_delayed_work_sync(&bond->arp_work);
 
-	if (bond->params.mode == BOND_MODE_ALB &&
-	    delayed_work_pending(&bond->alb_work))
+	if (bond->params.mode == BOND_MODE_ALB) {
+	    if (delayed_work_pending(&bond->alb_work))
 		cancel_delayed_work_sync(&bond->alb_work);
 
+	    if (delayed_work_pending(&bond_info->rlb_work))
+		cancel_delayed_work_sync(&bond_info->rlb_work);
+	}
+
 	if (bond->params.mode == BOND_MODE_8023AD &&
 	    delayed_work_pending(&bond->ad_work))
 		cancel_delayed_work_sync(&bond->ad_work);
-- 
1.7.4

^ permalink raw reply related

* [PATCH net V2 0/2] bonding:add aging mechanism to rlb table
From: Weiping Pan @ 2012-03-22  8:37 UTC (permalink / raw)
  To: netdev; +Cc: fubar, andy, linux-kernel, Weiping Pan

Jiri Bohac(jbohac@suse.cz) found that once an IP address is recorded in the
rlb hash table, it stays there indefinitely. If this IP address is migrated
to a different host in the network, bonding still sends out ARP packets
that poison other systems' ARP caches with invalid information.

There are some attempts to fix this problem,
http://marc.info/?l=linux-netdev&m=133036407906892&w=4
http://marc.info/?l=linux-netdev&m=133057427414043&w=4

But they did not fix the root cause of the problem, that rlb table does not
have a aging mechanism, the entry is deemed valid for ever unless it is
replaced.

In this patchset I want to add aging mechanism to rlb table.

Assume RLB_MONITOR_DELAY is 2 seconds and RLB_WORK_COUNTER_TIMES is 3,
and we can tune them.

Every 6 seconds bonding will make all entries invalid.
Every 2 seconds, bonding will send arp requests to its all
clients, then if it receives corresponding arp reply, bonding will deem that
this entry is valid.
And we give a entry 3 opportunities to survive in 6 seconds.

V2:
add cover letter

Weiping Pan (2):
  bonding:delete rlb entry if bond's ip is deleted
  bonding:delete rlb entry at regular intervals

 drivers/net/bonding/bond_alb.c  |  130 ++++++++++++++++++++++++++++++++++++---
 drivers/net/bonding/bond_alb.h  |    9 +++
 drivers/net/bonding/bond_main.c |   11 +++-
 3 files changed, 138 insertions(+), 12 deletions(-)

-- 
1.7.4

^ permalink raw reply

* Re: [PULL] vhost-net/virtio: fixes for 3.4
From: David Miller @ 2012-03-22  8:57 UTC (permalink / raw)
  To: mst; +Cc: kvm, virtualization, netdev, linux-kernel, levinsasha928, nyh,
	nyh
In-Reply-To: <20120322082718.GA11258@redhat.com>

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Thu, 22 Mar 2012 10:27:19 +0200

> Dave, just checking - not sure I made it clear that this pull request
> is intended to go in through your tree.
> If you see any issues pls let me know so I can fix them.

I missed it, sorry.

For some reason patchwork didn't pick it up, because if it did
then it wouldn't have mattered that I lost it in my huge inbox.
Oh well :-/

But I've got it now, thanks.  I'll work on it tomorrow.

^ 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