* Re: [PATCH 2/2 v7] xps: Transmit Packet Steering
From: David Miller @ 2010-11-24 19:45 UTC (permalink / raw)
To: therbert; +Cc: netdev, eric.dumazet
In-Reply-To: <alpine.DEB.2.00.1011211501430.14906@pokey.mtv.corp.google.com>
From: Tom Herbert <therbert@google.com>
Date: Sun, 21 Nov 2010 15:17:27 -0800 (PST)
> This patch implements transmit packet steering (XPS) for multiqueue
> devices. XPS selects a transmit queue during packet transmission based
> on configuration. This is done by mapping the CPU transmitting the
> packet to a queue. This is the transmit side analogue to RPS-- where
> RPS is selecting a CPU based on receive queue, XPS selects a queue
> based on the CPU (previously there was an XPS patch from Eric
> Dumazet, but that might more appropriately be called transmit completion
> steering).
>
> Each transmit queue can be associated with a number of CPUs which will
> use the queue to send packets. This is configured as a CPU mask on a
> per queue basis in:
>
> /sys/class/net/eth<n>/queues/tx-<n>/xps_cpus
>
> The mappings are stored per device in an inverted data structure that
> maps CPUs to queues. In the netdevice structure this is an array of
> num_possible_cpu structures where each structure holds and array of
> queue_indexes for queues which that CPU can use.
>
> The benefits of XPS are improved locality in the per queue data
> structures. Also, transmit completions are more likely to be done
> nearer to the sending thread, so this should promote locality back
> to the socket on free (e.g. UDP). The benefits of XPS are dependent on
> cache hierarchy, application load, and other factors. XPS would
> nominally be configured so that a queue would only be shared by CPUs
> which are sharing a cache, the degenerative configuration woud be that
> each CPU has it's own queue.
>
> Below are some benchmark results which show the potential benfit of
> this patch. The netperf test has 500 instances of netperf TCP_RR test
> with 1 byte req. and resp.
>
> bnx2x on 16 core AMD
> XPS (16 queues, 1 TX queue per CPU) 1234K at 100% CPU
> No XPS (16 queues) 996K at 100% CPU
>
> Signed-off-by: Tom Herbert <therbert@google.com>
Applied, please consider Eric's feedback about map NUMA node placement.
^ permalink raw reply
* Re: possible kernel oops from user MSS
From: David Miller @ 2010-11-24 19:47 UTC (permalink / raw)
To: mzhang; +Cc: netdev
In-Reply-To: <4CDDC6EE.2010005@mvista.com>
From: Min Zhang <mzhang@mvista.com>
Date: Fri, 12 Nov 2010 14:59:58 -0800
> Regarding commit 7a1abd08d52fdeddb3e9a5a33f2f15cc6a5674d2 ("tcp:
> Increase TCP_MAXSEG socket option minimum"). What is the reason
> TCP_MAXSEG minimum be 64? Isn't the exact be 40 which is
> TCPOLEN_MD5SIG_ALIGNED(20) + TCPOLEN_TSTAMP_ALIGNED(12) + 8?
>
> Or is it better to use TCP_MIN_MSS from tcp.h:
>
> /* Minimal accepted MSS. It is (60+60+8) - (20+20). */
> #define TCP_MIN_MSS 88U
Committed to net-2.6:
--------------------
>From c39508d6f118308355468314ff414644115a07f3 Mon Sep 17 00:00:00 2001
From: David S. Miller <davem@davemloft.net>
Date: Wed, 24 Nov 2010 11:47:22 -0800
Subject: [PATCH] tcp: Make TCP_MAXSEG minimum more correct.
Use TCP_MIN_MSS instead of constant 64.
Reported-by: Min Zhang <mzhang@mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/tcp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0814199..f15c36a 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
/* Values greater than interface MTU won't take effect. However
* at the point when this call is done we typically don't yet
* know which interface is going to be used */
- if (val < 64 || val > MAX_TCP_WINDOW) {
+ if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) {
err = -EINVAL;
break;
}
--
1.7.3.2
^ permalink raw reply related
* Unplug ethernet cable, the route persists. Why?
From: Mike Caoco @ 2010-11-24 19:48 UTC (permalink / raw)
To: Netdev, LKML; +Cc: caoco2002
Hello,
This may have been discussed, but all search engines couldn't give me a good answer...
I notice that when an interface is up/running, a local route is in the routing table:
$ ifconfig eth1
eth1 Link encap:Ethernet HWaddr 00:13:20:0e:2f:ed
inet addr:192.168.1.125 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::213:20ff:fe0e:2fed/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:35984995 errors:0 dropped:0 overruns:0 frame:0
TX packets:7409151 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3252413825 (3.2 GB) TX bytes:1340077250 (1.3 GB)
$ ip route
192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.120
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.125
default via 192.168.20.254 dev eth1 metric 100
After I unplug the cable from eth1, the RUNNING flag disappears, but the route is still there:
$ ifconfig eth1
eth1 Link encap:Ethernet HWaddr 00:13:20:0e:2f:ed
inet addr:192.168.1.125 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::213:20ff:fe0e:2fed/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:35985023 errors:0 dropped:0 overruns:0 frame:0
TX packets:7409151 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3252415633 (3.2 GB) TX bytes:1340077250 (1.3 GB)
$ ip route
192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.120
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.125
default via 192.168.20.254 dev eth1 metric 100
And that *prevents* from using the default route to reach 192.168.1/24 subnet after eth1 is out.
I looked at the code, it seems the IFF_RUNNING flag change is ignored in dev_change_flags():
void __dev_notify_flags(struct net_device *dev, unsigned int old_flags)
{
.....
if (dev->flags & IFF_UP &&
(changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE)))
call_netdevice_notifiers(NETDEV_CHANGE, dev);
}
I searched in the Internet, and saw some people suggest using an application listener (eg, netplug) to remove the route.
My question is why cannot the kernel remove the route automatically when the link becomes down? Why should this complexity be pushed to the user to find a program to do that?
Thanks,
Joe
^ permalink raw reply
* Re: Generalizing mmap'ed sockets
From: Michael S. Tsirkin @ 2010-11-24 19:57 UTC (permalink / raw)
To: Tom Herbert; +Cc: David Miller, rick.jones2, netdev
In-Reply-To: <AANLkTik7HU0wyub3krZb_aABsHp-_LvNLtAr5CaAo4_A@mail.gmail.com>
On Fri, Nov 19, 2010 at 02:49:46PM -0800, Tom Herbert wrote:
> > I think the ACK (or for UDP, the kfree_skb() after TX completes) should
> > move the consumer pointer. Otherwise you have to copy, and the ACKs
> > do not clock the sender process properly.
> >
> Right, with the caveats that even ACK'ed data might still go out on
> the with that was discussed in the vmsplice() related patches. I
> don't think this should make the problem any worse.
Or any better. Sigh. Any idea how to actually track pages
in question so we can either really know when the stack is no longer
referencing them, or force a copy if they hang around after ack?
--
MST
^ permalink raw reply
* Re: Unplug ethernet cable, the route persists. Why?
From: Stephen Hemminger @ 2010-11-24 20:18 UTC (permalink / raw)
To: Mike Caoco; +Cc: Netdev, LKML
In-Reply-To: <242082.99180.qm@web63407.mail.re1.yahoo.com>
On Wed, 24 Nov 2010 11:48:03 -0800 (PST)
Mike Caoco <caoco2002@yahoo.com> wrote:
> Hello,
>
> This may have been discussed, but all search engines couldn't give me a good answer...
>
> I notice that when an interface is up/running, a local route is in the routing table:
>
> $ ifconfig eth1
> eth1 Link encap:Ethernet HWaddr 00:13:20:0e:2f:ed
> inet addr:192.168.1.125 Bcast:192.168.1.255 Mask:255.255.255.0
> inet6 addr: fe80::213:20ff:fe0e:2fed/64 Scope:Link
> UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
> RX packets:35984995 errors:0 dropped:0 overruns:0 frame:0
> TX packets:7409151 errors:0 dropped:0 overruns:0 carrier:0
> collisions:0 txqueuelen:1000
> RX bytes:3252413825 (3.2 GB) TX bytes:1340077250 (1.3 GB)
>
> $ ip route
> 192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.120
> 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.125
> default via 192.168.20.254 dev eth1 metric 100
>
> After I unplug the cable from eth1, the RUNNING flag disappears, but the route is still there:
>
> $ ifconfig eth1
> eth1 Link encap:Ethernet HWaddr 00:13:20:0e:2f:ed
> inet addr:192.168.1.125 Bcast:192.168.1.255 Mask:255.255.255.0
> inet6 addr: fe80::213:20ff:fe0e:2fed/64 Scope:Link
> UP BROADCAST MULTICAST MTU:1500 Metric:1
> RX packets:35985023 errors:0 dropped:0 overruns:0 frame:0
> TX packets:7409151 errors:0 dropped:0 overruns:0 carrier:0
> collisions:0 txqueuelen:1000
> RX bytes:3252415633 (3.2 GB) TX bytes:1340077250 (1.3 GB)
>
> $ ip route
> 192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.120
> 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.125
> default via 192.168.20.254 dev eth1 metric 100
>
> And that *prevents* from using the default route to reach 192.168.1/24 subnet after eth1 is out.
>
> I looked at the code, it seems the IFF_RUNNING flag change is ignored in dev_change_flags():
>
> void __dev_notify_flags(struct net_device *dev, unsigned int old_flags)
> {
> .....
> if (dev->flags & IFF_UP &&
> (changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE)))
> call_netdevice_notifiers(NETDEV_CHANGE, dev);
> }
>
> I searched in the Internet, and saw some people suggest using an application listener (eg, netplug) to remove the route.
>
> My question is why cannot the kernel remove the route automatically when the link becomes down? Why should this complexity be pushed to the user to find a program to do that?
>
Because there is no reason for the kernel to not expect the link to come back.
It is up to user space to do routing policy. For desktop/laptop users this is
done typically with NetworkManager or Connman; for routers this is done with
Quagga; and for servers use other tools.
If the kernel automatically removed the route, it would cause routing daemons
to recompute the route table (and propagate the change) every time a cable
got pulled or NIC needed to be reset.
--
^ permalink raw reply
* Re: bonding: propagation of offload settings
From: David Miller @ 2010-11-24 20:27 UTC (permalink / raw)
To: horms; +Cc: netdev, fubar
In-Reply-To: <20101030025435.GF12842@verge.net.au>
From: Simon Horman <horms@verge.net.au>
Date: Sat, 30 Oct 2010 11:54:35 +0900
> It seems to me that from a user point of view it may make more sense to:
>
> a) propagate settings from the master to the slaves and;
> b) possibly disallow setting the slaves directly
Yeah, good question.
Propagation from master to slave(s) would have difficult semantics.
If any of the slave changes fail (f.e. unsupported feature or memory
allocation failure) we'd have to unwind all of the slaves which did
accept the change without error.
What if the unwind operation fails, due to lack of resources? A lot
of state would thus need to be tracked to support this reasonably.
However we pretty much have to respect whatever changes get made
directly to the slaves, since the master must at all times claim
support for only the lowest common denominator, feature wise, amongst
that master's slaves.
^ permalink raw reply
* Re: tg3 driver not advertising 1000mbit
From: Krzysztof Olędzki @ 2010-11-24 20:09 UTC (permalink / raw)
To: Matt Carlson
Cc: Jean-Louis Dupond, Michael Chan, netdev@vger.kernel.org,
David Christensen
In-Reply-To: <20090702164212.GA8430@xw6200.broadcom.net>
On 2009-07-02 18:42, Matt Carlson wrote:
> On Tue, Jun 30, 2009 at 02:20:45AM -0700, Jean-Louis Dupond wrote:
>> # ethtool -i eth0
>> driver: tg3
>> version: 3.97
>> firmware-version: 5722-v3.08, ASFIPMI v6.02
>> bus-info: 0000:01:00.0
>>
>> Kernel version 2.6.29.4
>
> Rats. I mirrored your setup here, but I still can't reproduce the
> problem. I still suspect this is a bad driver<=> firmware interaction.
>
> Can you apply the following patch and show me the resulting syslog
> entries? The patch is just making sure the firmware request to shutdown
> really goes through.
>
>
> diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
> index 46a3f86..900e28b 100644
> --- a/drivers/net/tg3.c
> +++ b/drivers/net/tg3.c
> @@ -1124,6 +1124,9 @@ static void tg3_wait_for_event_ack(struct tg3 *tp)
> break;
> udelay(8);
> }
> +
> + if (i == delay_cnt)
> + printk( KERN_WARNING "Firmware didn't ack driver event!\n" );
> }
>
> /* tp->lock is held. */
> @@ -6330,12 +6333,16 @@ static void tg3_stop_fw(struct tg3 *tp)
> /* Wait for RX cpu to ACK the previous event. */
> tg3_wait_for_event_ack(tp);
>
> + printk( KERN_NOTICE "%s: Stopping firmware.\n", tp->dev->name );
> +
> tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
>
> tg3_generate_fw_event(tp);
>
> /* Wait for RX cpu to ACK this event. */
> tg3_wait_for_event_ack(tp);
> +
> + printk( KERN_NOTICE "%s: Operation completed.\n", tp->dev->name );
> }
> }
>
> @@ -7537,6 +7544,8 @@ static void tg3_timer(unsigned long __opaque)
> !(tp->tg3_flags3& TG3_FLG3_ENABLE_APE)) {
> tg3_wait_for_event_ack(tp);
>
> + printk( KERN_NOTICE "%s: Sending keepalive event.\n", tp->dev->name );
> +
> tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
> FWCMD_NICDRV_ALIVE3);
> tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
Hello,
Have you been able to solve this issue? I have a similar problem with
Dell PowerEdge R300 servers connected to HP2610 100Mbps switches. The
servers contain two BCM5722 NICs and after a reboot, with probability
about 70%, I end up with 10Mbps HD mainly on the first NIC.
I discovered that it is enough to run:
/sbin/mii-tool -R eth0
/sbin/mii-tool -R eth1
to trigger renegotiation that brings expected 100Mbps FD. For now, I
added this to my startups scripts as a workaround.
This problem exists in 2.6.30-stable, 2.6.31-stable and 2.6.34-stable
which I'm currently running.
Best regards,
Krzysztof Olędzki
^ permalink raw reply
* Re: Unplug ethernet cable, the route persists. Why?
From: Mike Caoco @ 2010-11-24 20:29 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Netdev, LKML
In-Reply-To: <20101124121826.39dd6ed1@nehalam>
--- On Wed, 11/24/10, Stephen Hemminger <shemminger@vyatta.com> wrote:
> From: Stephen Hemminger <shemminger@vyatta.com>
> Subject: Re: Unplug ethernet cable, the route persists. Why?
> To: "Mike Caoco" <caoco2002@yahoo.com>
> Cc: "Netdev" <netdev@vger.kernel.org>, "LKML" <linux-kernel@vger.kernel.org>
> Date: Wednesday, November 24, 2010, 12:18 PM
> On Wed, 24 Nov 2010 11:48:03 -0800
> (PST)
> Mike Caoco <caoco2002@yahoo.com>
> wrote:
>
> > Hello,
> >
> > This may have been discussed, but all search engines
> couldn't give me a good answer...
> >
> > I notice that when an interface is up/running, a local
> route is in the routing table:
> >
> > $ ifconfig eth1
> > eth1 Link encap:Ethernet
> HWaddr 00:13:20:0e:2f:ed
> > inet
> addr:192.168.1.125 Bcast:192.168.1.255
> Mask:255.255.255.0
> > inet6
> addr: fe80::213:20ff:fe0e:2fed/64 Scope:Link
> > UP
> BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
> > RX
> packets:35984995 errors:0 dropped:0 overruns:0 frame:0
> > TX
> packets:7409151 errors:0 dropped:0 overruns:0 carrier:0
> >
> collisions:0 txqueuelen:1000
> > RX
> bytes:3252413825 (3.2 GB) TX bytes:1340077250 (1.3
> GB)
> >
> > $ ip route
> > 192.168.20.0/24 dev eth0 proto kernel
> scope link src 192.168.20.120
> > 192.168.1.0/24 dev eth1 proto kernel scope
> link src 192.168.1.125
> > default via 192.168.20.254 dev eth1 metric 100
> >
> > After I unplug the cable from eth1, the RUNNING flag
> disappears, but the route is still there:
> >
> > $ ifconfig eth1
> > eth1 Link encap:Ethernet
> HWaddr 00:13:20:0e:2f:ed
> > inet
> addr:192.168.1.125 Bcast:192.168.1.255
> Mask:255.255.255.0
> > inet6
> addr: fe80::213:20ff:fe0e:2fed/64 Scope:Link
> > UP
> BROADCAST MULTICAST MTU:1500 Metric:1
> > RX
> packets:35985023 errors:0 dropped:0 overruns:0 frame:0
> > TX
> packets:7409151 errors:0 dropped:0 overruns:0 carrier:0
> >
> collisions:0 txqueuelen:1000
> > RX
> bytes:3252415633 (3.2 GB) TX bytes:1340077250 (1.3
> GB)
> >
> > $ ip route
> > 192.168.20.0/24 dev eth0 proto kernel
> scope link src 192.168.20.120
> > 192.168.1.0/24 dev eth1 proto kernel scope
> link src 192.168.1.125
> > default via 192.168.20.254 dev eth1 metric 100
> >
> > And that *prevents* from using the default route to
> reach 192.168.1/24 subnet after eth1 is out.
> >
> > I looked at the code, it seems the IFF_RUNNING flag
> change is ignored in dev_change_flags():
> >
> > void __dev_notify_flags(struct net_device *dev,
> unsigned int old_flags)
> > {
> > .....
> > if
> (dev->flags & IFF_UP &&
> >
> (changes & ~(IFF_UP | IFF_PROMISC |
> IFF_ALLMULTI | IFF_VOLATILE)))
> >
> call_netdevice_notifiers(NETDEV_CHANGE,
> dev);
> > }
> >
> > I searched in the Internet, and saw some people
> suggest using an application listener (eg, netplug) to
> remove the route.
> >
> > My question is why cannot the kernel remove the route
> automatically when the link becomes down? Why should
> this complexity be pushed to the user to find a program to
> do that?
> >
>
> Because there is no reason for the kernel to not expect the
> link to come back.
> It is up to user space to do routing policy. For
> desktop/laptop users this is
> done typically with NetworkManager or Connman; for routers
> this is done with
> Quagga; and for servers use other tools.
>
> If the kernel automatically removed the route, it would
> cause routing daemons
> to recompute the route table (and propagate the change)
> every time a cable
> got pulled or NIC needed to be reset.
>
So if you rely on NetworkManager or Connman or Quagga to remove the route, the routing daemons will recompute the route table anyway. So why cannot this be done in the kernel?
Even when no NetworkManager/Quagga is present, I think it is a legitimate reason to recompute the route when a cable is unplugged, which should not be a frequent event unless when under error conditions.
Thanks,
^ permalink raw reply
* Re: Unplug ethernet cable, the route persists. Why?
From: David Miller @ 2010-11-24 20:44 UTC (permalink / raw)
To: caoco2002; +Cc: shemminger, netdev, linux-kernel
In-Reply-To: <144174.46619.qm@web63401.mail.re1.yahoo.com>
From: Mike Caoco <caoco2002@yahoo.com>
Date: Wed, 24 Nov 2010 12:29:43 -0800 (PST)
> Even when no NetworkManager/Quagga is present, I think it is a
> legitimate reason to recompute the route when a cable is unplugged,
> which should not be a frequent event unless when under error
> conditions.
Cards periodically reset themselves, faulty switchs flap occaisionally,
this is life and it shouldn't cause route table recomputations across
your entire region.
Also Stephen listed places where such policy should be employed in
userspace, he absolutely did not say they should act that way by
default.
^ permalink raw reply
* RE: [PATCH 1/1] UDEV - Add 'udevlom' command line param to start_udev
From: Loke, Chetan @ 2010-11-24 20:57 UTC (permalink / raw)
To: Rick Jones, Ben Hutchings
Cc: Matt Domsch, Greg KH, K, Narendra, linux-hotplug, netdev,
Hargrave, Jordan, Rose, Charles
In-Reply-To: <4CE18ACC.3020508@hp.com>
>
> > - "mbe" = MotherBoard Ethernet. Looks a bit like "GbE" as some OEMs
put
> > on the port labels.
>
> Collides with Multi-Bit Error.
>
> > - "eom" = Ethernet On Motherboard
>
> Collides with End of Message.
>
On board ethernet(obe)?
On board nic(obn)?
^ permalink raw reply
* RE: [PATCH 1/1] UDEV - Add 'udevlom' command line param to start_udev
From: Loke, Chetan @ 2010-11-24 21:13 UTC (permalink / raw)
To: Rick Jones, Ben Hutchings
Cc: Matt Domsch, Greg KH, K, Narendra, linux-hotplug, netdev,
Hargrave, Jordan, Rose, Charles
In-Reply-To: <4CE18ACC.3020508@hp.com>
>
> Are folks sufficently confident that using anything other than "eth"
> won't cause some unpleasant "our app always ass-u-me-d interfaces
started with
> 'eth'" situations?
>
Good point. I'm sure folks use 'eth' in their regex filters. Please
ignore my obe/obn email.
> rick jones
Chetan Loke
^ permalink raw reply
* [PATCH net-26] cxgb4vf: fix setting unicast/multicast addresses ...
From: Casey Leedom @ 2010-11-24 22:23 UTC (permalink / raw)
To: netdev; +Cc: davem, Casey Leedom
We were truncating the number of unicast and multicast MAC addresses
supported. Additionally, we were incorrectly computing the MAC Address
hash (a "1 << N" where we needed a "1ULL << N").
Signed-off-by: Casey Leedom <leedom@chelsio.com>
---
drivers/net/cxgb4vf/cxgb4vf_main.c | 73 +++++++++++++++++----------
drivers/net/cxgb4vf/t4vf_hw.c | 96 ++++++++++++++++++++++-------------
2 files changed, 105 insertions(+), 64 deletions(-)
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index 9246d2f..f54af48 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -814,40 +814,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev)
}
/*
- * Collect up to maxaddrs worth of a netdevice's unicast addresses into an
- * array of addrss pointers and return the number collected.
+ * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting
+ * at a specified offset within the list, into an array of addrss pointers and
+ * return the number collected.
*/
-static inline int collect_netdev_uc_list_addrs(const struct net_device *dev,
- const u8 **addr,
- unsigned int maxaddrs)
+static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev,
+ const u8 **addr,
+ unsigned int offset,
+ unsigned int maxaddrs)
{
+ unsigned int index = 0;
unsigned int naddr = 0;
const struct netdev_hw_addr *ha;
- for_each_dev_addr(dev, ha) {
- addr[naddr++] = ha->addr;
- if (naddr >= maxaddrs)
- break;
- }
+ for_each_dev_addr(dev, ha)
+ if (index++ >= offset) {
+ addr[naddr++] = ha->addr;
+ if (naddr >= maxaddrs)
+ break;
+ }
return naddr;
}
/*
- * Collect up to maxaddrs worth of a netdevice's multicast addresses into an
- * array of addrss pointers and return the number collected.
+ * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting
+ * at a specified offset within the list, into an array of addrss pointers and
+ * return the number collected.
*/
-static inline int collect_netdev_mc_list_addrs(const struct net_device *dev,
- const u8 **addr,
- unsigned int maxaddrs)
+static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev,
+ const u8 **addr,
+ unsigned int offset,
+ unsigned int maxaddrs)
{
+ unsigned int index = 0;
unsigned int naddr = 0;
const struct netdev_hw_addr *ha;
- netdev_for_each_mc_addr(ha, dev) {
- addr[naddr++] = ha->addr;
- if (naddr >= maxaddrs)
- break;
- }
+ netdev_for_each_mc_addr(ha, dev)
+ if (index++ >= offset) {
+ addr[naddr++] = ha->addr;
+ if (naddr >= maxaddrs)
+ break;
+ }
return naddr;
}
@@ -860,16 +868,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
u64 mhash = 0;
u64 uhash = 0;
bool free = true;
- u16 filt_idx[7];
+ unsigned int offset, naddr;
const u8 *addr[7];
- int ret, naddr = 0;
+ int ret;
const struct port_info *pi = netdev_priv(dev);
/* first do the secondary unicast addresses */
- naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr));
- if (naddr > 0) {
+ for (offset = 0; ; offset += naddr) {
+ naddr = collect_netdev_uc_list_addrs(dev, addr, offset,
+ ARRAY_SIZE(addr));
+ if (naddr == 0)
+ break;
+
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
- naddr, addr, filt_idx, &uhash, sleep);
+ naddr, addr, NULL, &uhash, sleep);
if (ret < 0)
return ret;
@@ -877,12 +889,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
}
/* next set up the multicast addresses */
- naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr));
- if (naddr > 0) {
+ for (offset = 0; ; offset += naddr) {
+ naddr = collect_netdev_mc_list_addrs(dev, addr, offset,
+ ARRAY_SIZE(addr));
+ if (naddr == 0)
+ break;
+
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
- naddr, addr, filt_idx, &mhash, sleep);
+ naddr, addr, NULL, &mhash, sleep);
if (ret < 0)
return ret;
+ free = false;
}
return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0,
diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c
index f7d7f97..35fc803 100644
--- a/drivers/net/cxgb4vf/t4vf_hw.c
+++ b/drivers/net/cxgb4vf/t4vf_hw.c
@@ -1014,48 +1014,72 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
unsigned int naddr, const u8 **addr, u16 *idx,
u64 *hash, bool sleep_ok)
{
- int i, ret;
+ int offset, ret = 0;
+ unsigned nfilters = 0;
+ unsigned int rem = naddr;
struct fw_vi_mac_cmd cmd, rpl;
- struct fw_vi_mac_exact *p;
- size_t len16;
- if (naddr > ARRAY_SIZE(cmd.u.exact))
+ if (naddr > FW_CLS_TCAM_NUM_ENTRIES)
return -EINVAL;
- len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
- u.exact[naddr]), 16);
- memset(&cmd, 0, sizeof(cmd));
- cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
- FW_CMD_REQUEST |
- FW_CMD_WRITE |
- (free ? FW_CMD_EXEC : 0) |
- FW_VI_MAC_CMD_VIID(viid));
- cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
- FW_CMD_LEN16(len16));
+ for (offset = 0; offset < naddr; /**/) {
+ unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
+ ? rem
+ : ARRAY_SIZE(cmd.u.exact));
+ size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
+ u.exact[fw_naddr]), 16);
+ struct fw_vi_mac_exact *p;
+ int i;
- for (i = 0, p = cmd.u.exact; i < naddr; i++, p++) {
- p->valid_to_idx =
- cpu_to_be16(FW_VI_MAC_CMD_VALID |
- FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
- memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
- }
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
+ FW_CMD_REQUEST |
+ FW_CMD_WRITE |
+ (free ? FW_CMD_EXEC : 0) |
+ FW_VI_MAC_CMD_VIID(viid));
+ cmd.freemacs_to_len16 =
+ cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
+ FW_CMD_LEN16(len16));
+
+ for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
+ p->valid_to_idx = cpu_to_be16(
+ FW_VI_MAC_CMD_VALID |
+ FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
+ memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
+ }
+
+
+ ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
+ sleep_ok);
+ if (ret && ret != -ENOMEM)
+ break;
- ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl, sleep_ok);
- if (ret)
- return ret;
-
- for (i = 0, p = rpl.u.exact; i < naddr; i++, p++) {
- u16 index = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx));
-
- if (idx)
- idx[i] = (index >= FW_CLS_TCAM_NUM_ENTRIES
- ? 0xffff
- : index);
- if (index < FW_CLS_TCAM_NUM_ENTRIES)
- ret++;
- else if (hash)
- *hash |= (1 << hash_mac_addr(addr[i]));
+ for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
+ u16 index = FW_VI_MAC_CMD_IDX_GET(
+ be16_to_cpu(p->valid_to_idx));
+
+ if (idx)
+ idx[offset+i] =
+ (index >= FW_CLS_TCAM_NUM_ENTRIES
+ ? 0xffff
+ : index);
+ if (index < FW_CLS_TCAM_NUM_ENTRIES)
+ nfilters++;
+ else if (hash)
+ *hash |= (1ULL << hash_mac_addr(addr[offset+i]));
+ }
+
+ free = false;
+ offset += fw_naddr;
+ rem -= fw_naddr;
}
+
+ /*
+ * If there were no errors or we merely ran out of room in our MAC
+ * address arena, return the number of filters actually written.
+ */
+ if (ret == 0 || ret == -ENOMEM)
+ ret = nfilters;
return ret;
}
--
1.7.0.4
^ permalink raw reply related
* Re: tg3 driver not advertising 1000mbit
From: Jean-Louis Dupond @ 2010-11-24 22:27 UTC (permalink / raw)
To: Krzysztof Olędzki
Cc: Matt Carlson, Michael Chan, netdev@vger.kernel.org,
David Christensen
In-Reply-To: <4CED7110.9030801@ans.pl>
I didn't do more research on the issue.
The guys @ broadcom advised me to do BIOS update, so the firmware of the
NIC is updated.
Maby you can try that also?
Sincerely,
Jean-Louis Dupond
Op 24-11-10 21:09, Krzysztof Olędzki schreef:
> On 2009-07-02 18:42, Matt Carlson wrote:
>> On Tue, Jun 30, 2009 at 02:20:45AM -0700, Jean-Louis Dupond wrote:
>>> # ethtool -i eth0
>>> driver: tg3
>>> version: 3.97
>>> firmware-version: 5722-v3.08, ASFIPMI v6.02
>>> bus-info: 0000:01:00.0
>>>
>>> Kernel version 2.6.29.4
>>
>> Rats. I mirrored your setup here, but I still can't reproduce the
>> problem. I still suspect this is a bad driver<=> firmware interaction.
>>
>> Can you apply the following patch and show me the resulting syslog
>> entries? The patch is just making sure the firmware request to shutdown
>> really goes through.
>>
>>
>> diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
>> index 46a3f86..900e28b 100644
>> --- a/drivers/net/tg3.c
>> +++ b/drivers/net/tg3.c
>> @@ -1124,6 +1124,9 @@ static void tg3_wait_for_event_ack(struct tg3 *tp)
>> break;
>> udelay(8);
>> }
>> +
>> + if (i == delay_cnt)
>> + printk( KERN_WARNING "Firmware didn't ack driver event!\n" );
>> }
>>
>> /* tp->lock is held. */
>> @@ -6330,12 +6333,16 @@ static void tg3_stop_fw(struct tg3 *tp)
>> /* Wait for RX cpu to ACK the previous event. */
>> tg3_wait_for_event_ack(tp);
>>
>> + printk( KERN_NOTICE "%s: Stopping firmware.\n", tp->dev->name );
>> +
>> tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
>>
>> tg3_generate_fw_event(tp);
>>
>> /* Wait for RX cpu to ACK this event. */
>> tg3_wait_for_event_ack(tp);
>> +
>> + printk( KERN_NOTICE "%s: Operation completed.\n", tp->dev->name );
>> }
>> }
>>
>> @@ -7537,6 +7544,8 @@ static void tg3_timer(unsigned long __opaque)
>> !(tp->tg3_flags3& TG3_FLG3_ENABLE_APE)) {
>> tg3_wait_for_event_ack(tp);
>>
>> + printk( KERN_NOTICE "%s: Sending keepalive event.\n", tp->dev->name );
>> +
>> tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
>> FWCMD_NICDRV_ALIVE3);
>> tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
>
> Hello,
>
> Have you been able to solve this issue? I have a similar problem with
> Dell PowerEdge R300 servers connected to HP2610 100Mbps switches. The
> servers contain two BCM5722 NICs and after a reboot, with probability
> about 70%, I end up with 10Mbps HD mainly on the first NIC.
>
> I discovered that it is enough to run:
> /sbin/mii-tool -R eth0
> /sbin/mii-tool -R eth1
> to trigger renegotiation that brings expected 100Mbps FD. For now, I
> added this to my startups scripts as a workaround.
>
> This problem exists in 2.6.30-stable, 2.6.31-stable and 2.6.34-stable
> which I'm currently running.
>
> Best regards,
>
> Krzysztof Olędzki
^ permalink raw reply
* [PATCH] bonding: check for assigned mac before adopting the slaves mac address
From: David Strand @ 2010-11-24 23:12 UTC (permalink / raw)
To: netdev; +Cc: Jay Vosburgh, linux-kernel
Restore the check for a missing mac address before adopting the first
slaves as it's own. This regression was introduced in:
http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.36.y.git;a=commit;h=c20811a79e671a6a1fe86a8c1afe04aca8a7f085
Signed-off-by: David Strand dpstrand@gmail.com
---
diff -uprN a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c 2010-11-24 11:36:58.125640000 -0800
+++ b/drivers/net/bonding/bond_main.c 2010-11-24 11:40:58.175640000 -0800
@@ -1577,8 +1577,9 @@ int bond_enslave(struct net_device *bond
/* If this is the first slave, then we need to set the master's hardware
* address to be the same as the slave's. */
if (bond->slave_cnt == 0)
- memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
- slave_dev->addr_len);
+ if (is_zero_ether_addr(bond->dev->dev_addr))
+ memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
+ slave_dev->addr_len);
new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
^ permalink raw reply
* [net-next-2.6 PATCH] 8021q: vlan device is lockless do not transfer real_num_{tx|rx}_queues
From: John Fastabend @ 2010-11-24 23:14 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet
Now that the vlan device is lockless and single queue do not
transfer the real num queues. This is causing a BUG_ON to occur.
kernel BUG at net/8021q/vlan.c:345!
Call Trace:
[<ffffffff813fd6e8>] ? fib_rules_event+0x28/0x1b0
[<ffffffff814ad2b5>] notifier_call_chain+0x55/0x80
[<ffffffff81089156>] raw_notifier_call_chain+0x16/0x20
[<ffffffff813e5af7>] call_netdevice_notifiers+0x37/0x70
[<ffffffff813e6756>] netdev_features_change+0x16/0x20
[<ffffffffa02995be>] ixgbe_fcoe_enable+0xae/0x100 [ixgbe]
[<ffffffffa01da06a>] vlan_dev_fcoe_enable+0x2a/0x30 [8021q]
[<ffffffffa02d08c3>] fcoe_create+0x163/0x630 [fcoe]
[<ffffffff811244d5>] ? mmap_region+0x255/0x5a0
[<ffffffff81080ef0>] param_attr_store+0x50/0x80
[<ffffffff810809b6>] module_attr_store+0x26/0x30
[<ffffffff811b9db2>] sysfs_write_file+0xf2/0x180
[<ffffffff8114fc88>] vfs_write+0xc8/0x190
[<ffffffff81150621>] sys_write+0x51/0x90
[<ffffffff8100c0b2>] system_call_fastpath+0x16/0x1b
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
net/8021q/vlan.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index dc10713..6e64f7c 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -341,9 +341,6 @@ static void vlan_transfer_features(struct net_device *dev,
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
#endif
- vlandev->real_num_tx_queues = dev->real_num_tx_queues;
- BUG_ON(vlandev->real_num_tx_queues > vlandev->num_tx_queues);
-
if (old_features != vlandev->features)
netdev_features_change(vlandev);
}
^ permalink raw reply related
* Re: [PATCH] bonding: check for assigned mac before adopting the slaves mac address
From: Jay Vosburgh @ 2010-11-24 23:33 UTC (permalink / raw)
To: David Strand; +Cc: netdev, linux-kernel
In-Reply-To: <AANLkTinpO=FmoecfV8epubXU4OrhFsXJ7-Kc68yNhMEs@mail.gmail.com>
David Strand <dpstrand@gmail.com> wrote:
>Restore the check for a missing mac address before adopting the first
>slaves as it's own. This regression was introduced in:
>http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.36.y.git;a=commit;h=c20811a79e671a6a1fe86a8c1afe04aca8a7f085
How exactly is this a regression? The above referenced patch
changes the method used to decide if the bonding master needs to have
it's MAC address set. The original way was "bonding master's MAC is
zero," after the above, it's "adding first slave."
Do you have some use case that manually sets the master's MAC
address prior to adding any slaves?
-J
>Signed-off-by: David Strand dpstrand@gmail.com
>---
>diff -uprN a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>--- a/drivers/net/bonding/bond_main.c 2010-11-24 11:36:58.125640000 -0800
>+++ b/drivers/net/bonding/bond_main.c 2010-11-24 11:40:58.175640000 -0800
>@@ -1577,8 +1577,9 @@ int bond_enslave(struct net_device *bond
> /* If this is the first slave, then we need to set the master's hardware
> * address to be the same as the slave's. */
> if (bond->slave_cnt == 0)
>- memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
>- slave_dev->addr_len);
>+ if (is_zero_ether_addr(bond->dev->dev_addr))
>+ memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
>+ slave_dev->addr_len);
>
>
> new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* [PATCH 1/1] NET: wan/x25_asy, move lapb_unregister to x25_asy_close_tty
From: Jiri Slaby @ 2010-11-24 23:54 UTC (permalink / raw)
To: davem; +Cc: netdev, slapin, linux-kernel, jirislaby, Andrew Hendry
We register lapb when tty is created, but unregister it only when the
device is UP. So move the lapb_unregister to x25_asy_close_tty after
the device is down.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Reported-by: Sergey Lapin <slapin@ossfans.org>
Cc: Andrew Hendry <andrew.hendry@gmail.com>
---
drivers/net/wan/x25_asy.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 66cda25..24297b2 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -498,7 +498,6 @@ norbuff:
static int x25_asy_close(struct net_device *dev)
{
struct x25_asy *sl = netdev_priv(dev);
- int err;
spin_lock(&sl->lock);
if (sl->tty)
@@ -507,10 +506,6 @@ static int x25_asy_close(struct net_device *dev)
netif_stop_queue(dev);
sl->rcount = 0;
sl->xleft = 0;
- err = lapb_unregister(dev);
- if (err != LAPB_OK)
- printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
- err);
spin_unlock(&sl->lock);
return 0;
}
@@ -595,6 +590,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
static void x25_asy_close_tty(struct tty_struct *tty)
{
struct x25_asy *sl = tty->disc_data;
+ int err;
/* First make sure we're connected. */
if (!sl || sl->magic != X25_ASY_MAGIC)
@@ -605,6 +601,11 @@ static void x25_asy_close_tty(struct tty_struct *tty)
dev_close(sl->dev);
rtnl_unlock();
+ err = lapb_unregister(sl->dev);
+ if (err != LAPB_OK)
+ printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
+ err);
+
tty->disc_data = NULL;
sl->tty = NULL;
x25_asy_free(sl);
--
1.7.3.1
^ permalink raw reply related
* Re: [PATCH] bonding: check for assigned mac before adopting the slaves mac address
From: Laurent Chavey @ 2010-11-25 0:44 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: David Strand, netdev, linux-kernel
In-Reply-To: <31169.1290641617@death>
based on the new code, the behavior of ifenslave works the same.
>- if (bond->slave_cnt == 0)
>+ if (is_zero_ether_addr(bond->dev->dev_addr))
>- memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
>- slave_dev->addr_len);
> + bond_sethwaddr(bond, slave_dev);
On Wed, Nov 24, 2010 at 3:33 PM, Jay Vosburgh <fubar@us.ibm.com> wrote:
> David Strand <dpstrand@gmail.com> wrote:
>
>>Restore the check for a missing mac address before adopting the first
>>slaves as it's own. This regression was introduced in:
>>http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.36.y.git;a=commit;h=c20811a79e671a6a1fe86a8c1afe04aca8a7f085
>
> How exactly is this a regression? The above referenced patch
> changes the method used to decide if the bonding master needs to have
> it's MAC address set. The original way was "bonding master's MAC is
> zero," after the above, it's "adding first slave."
>
> Do you have some use case that manually sets the master's MAC
> address prior to adding any slaves?
>
> -J
>
>>Signed-off-by: David Strand dpstrand@gmail.com
>>---
>>diff -uprN a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>>--- a/drivers/net/bonding/bond_main.c 2010-11-24 11:36:58.125640000 -0800
>>+++ b/drivers/net/bonding/bond_main.c 2010-11-24 11:40:58.175640000 -0800
>>@@ -1577,8 +1577,9 @@ int bond_enslave(struct net_device *bond
>> /* If this is the first slave, then we need to set the master's hardware
>> * address to be the same as the slave's. */
>> if (bond->slave_cnt == 0)
>>- memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
>>- slave_dev->addr_len);
>>+ if (is_zero_ether_addr(bond->dev->dev_addr))
>>+ memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
>>+ slave_dev->addr_len);
>>
>>
>> new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
>
> ---
> -Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
--------------------------------------------------------------------------------
^ permalink raw reply
* [PATCH net-next 1/2] bnx2: Fix reset bug on 5709
From: Michael Chan @ 2010-11-24 23:48 UTC (permalink / raw)
To: davem; +Cc: netdev
From: Eddie Wai <waie@broadcom.com>
The 5709 chip requires the BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE bit to be
cleared and polling for pending DMAs to complete before chip reset.
Without this step, we've seen NMIs during repeated resets of the chip.
Signed-off-by: Eddie Wai <waie@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/bnx2.c | 29 ++++++++++++++++++++++-------
drivers/net/bnx2.h | 2 ++
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 062600b..83af01d 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -4645,13 +4645,28 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
/* Wait for the current PCI transaction to complete before
* issuing a reset. */
- REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
- BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
- val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
- udelay(5);
+ if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
+ (CHIP_NUM(bp) == CHIP_NUM_5708)) {
+ REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
+ BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
+ val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
+ udelay(5);
+ } else { /* 5709 */
+ val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+ val &= ~BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
+ REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
+ val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+
+ for (i = 0; i < 100; i++) {
+ msleep(1);
+ val = REG_RD(bp, BNX2_PCICFG_DEVICE_CONTROL);
+ if (!(val & BNX2_PCICFG_DEVICE_STATUS_NO_PEND))
+ break;
+ }
+ }
/* Wait for the firmware to tell us it is ok to issue a reset. */
bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index bf4c342..5488a2e 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -461,6 +461,8 @@ struct l2_fhdr {
#define BNX2_PCICFG_MAILBOX_QUEUE_ADDR 0x00000090
#define BNX2_PCICFG_MAILBOX_QUEUE_DATA 0x00000094
+#define BNX2_PCICFG_DEVICE_CONTROL 0x000000b4
+#define BNX2_PCICFG_DEVICE_STATUS_NO_PEND ((1L<<5)<<16)
/*
* pci_reg definition
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH net-next 2/2] bnx2: Remove config access to non-standard registers
From: Michael Chan @ 2010-11-24 23:48 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1290642535-20293-1-git-send-email-mchan@broadcom.com>
In KVM passthrough mode, the driver may not have config access to
non-standard registers. The BNX2_PCICFG_MISC_CONFIG config register
access to setup mailbox swapping can be done using MMIO.
Update version to 2.0.20.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/bnx2.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 83af01d..4c0106f 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -56,8 +56,8 @@
#include "bnx2_fw.h"
#define DRV_MODULE_NAME "bnx2"
-#define DRV_MODULE_VERSION "2.0.18"
-#define DRV_MODULE_RELDATE "Oct 7, 2010"
+#define DRV_MODULE_VERSION "2.0.20"
+#define DRV_MODULE_RELDATE "Nov 24, 2010"
#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw"
#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw"
#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw"
@@ -4688,7 +4688,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
- pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val);
+ REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
} else {
val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
@@ -7929,15 +7929,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
goto err_out_release;
}
+ bnx2_set_power_state(bp, PCI_D0);
+
/* Configure byte swap and enable write to the reg_window registers.
* Rely on CPU to do target byte swapping on big endian systems
* The chip's target access swapping will not swap all accesses
*/
- pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG,
- BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
- BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
-
- bnx2_set_power_state(bp, PCI_D0);
+ REG_WR(bp, BNX2_PCICFG_MISC_CONFIG,
+ BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+ BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
--
1.6.4.GIT
^ permalink raw reply related
* Re: [PATCH] bonding: check for assigned mac before adopting the slaves mac address
From: David Strand @ 2010-11-25 1:45 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: netdev, linux-kernel
In-Reply-To: <31169.1290641617@death>
We have a use case where we assign a mac to the bond device, because
the slave device configuration may change periodically. With older
kernels, it honored the assigned mac and everything was fine, with
2.6.36 it now uses the mac of whatever slave device is first instead
of our assigned one.
ifenslave code and documentation appears to still support the old way,
where a bond assigned mac will reign supreme, so this patch restores
that behavior.
On Wed, Nov 24, 2010 at 3:33 PM, Jay Vosburgh <fubar@us.ibm.com> wrote:
> How exactly is this a regression? The above referenced patch
> changes the method used to decide if the bonding master needs to have
> it's MAC address set. The original way was "bonding master's MAC is
> zero," after the above, it's "adding first slave."
>
> Do you have some use case that manually sets the master's MAC
> address prior to adding any slaves?
>
> -J
^ permalink raw reply
* [PATCH 0/8] ipvs: ipvs update for nf-next-2.6
From: Simon Horman @ 2010-11-25 1:46 UTC (permalink / raw)
To: lvs-devel, netdev, netfilter, netfilter-devel
Cc: Hans Schillstrom, Julian Anastasov, Patrick McHardy
Hi Patrick,
please consider pulling in the new sync protocol for ipvs
by Hans Schillstrom from
git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-test-2.6.git master
After this series I now have no outstanding IPVS patches for nf-next-2.6
in my queue.
^ permalink raw reply
* [PATCH 1/8] IPVS: Backup, Prepare for transferring firewall marks (fwmark) to the backup daemon.
From: Simon Horman @ 2010-11-25 1:46 UTC (permalink / raw)
To: lvs-devel, netdev, netfilter, netfilter-devel
Cc: Hans Schillstrom, Julian Anastasov, Patrick McHardy, Simon Horman
In-Reply-To: <1290649618-18955-1-git-send-email-horms@verge.net.au>
From: Hans Schillstrom <hans.schillstrom@ericsson.com>
One struct will have fwmark added:
* ip_vs_conn
ip_vs_conn_new() and ip_vs_find_dest()
will have an extra param - fwmark
The effects of that, is in this patch.
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
include/net/ip_vs.h | 6 ++++--
net/netfilter/ipvs/ip_vs_conn.c | 5 +++--
net/netfilter/ipvs/ip_vs_core.c | 8 ++++----
net/netfilter/ipvs/ip_vs_ctl.c | 4 ++--
net/netfilter/ipvs/ip_vs_ftp.c | 5 +++--
net/netfilter/ipvs/ip_vs_sync.c | 4 ++--
6 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index d5a32e4..890f01c 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -382,6 +382,7 @@ struct ip_vs_conn {
union nf_inet_addr vaddr; /* virtual address */
union nf_inet_addr daddr; /* destination address */
volatile __u32 flags; /* status flags */
+ __u32 fwmark; /* Fire wall mark from skb */
__be16 cport;
__be16 vport;
__be16 dport;
@@ -720,7 +721,7 @@ extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);
struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p,
const union nf_inet_addr *daddr,
__be16 dport, unsigned flags,
- struct ip_vs_dest *dest);
+ struct ip_vs_dest *dest, __u32 fwmark);
extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp);
extern const char * ip_vs_state_name(__u16 proto, int state);
@@ -901,7 +902,8 @@ extern int ip_vs_control_init(void);
extern void ip_vs_control_cleanup(void);
extern struct ip_vs_dest *
ip_vs_find_dest(int af, const union nf_inet_addr *daddr, __be16 dport,
- const union nf_inet_addr *vaddr, __be16 vport, __u16 protocol);
+ const union nf_inet_addr *vaddr, __be16 vport, __u16 protocol,
+ __u32 fwmark);
extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp);
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 7615f9e..66e4662 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -613,7 +613,7 @@ struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp)
if ((cp) && (!cp->dest)) {
dest = ip_vs_find_dest(cp->af, &cp->daddr, cp->dport,
&cp->vaddr, cp->vport,
- cp->protocol);
+ cp->protocol, cp->fwmark);
ip_vs_bind_dest(cp, dest);
return dest;
} else
@@ -803,7 +803,7 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
struct ip_vs_conn *
ip_vs_conn_new(const struct ip_vs_conn_param *p,
const union nf_inet_addr *daddr, __be16 dport, unsigned flags,
- struct ip_vs_dest *dest)
+ struct ip_vs_dest *dest, __u32 fwmark)
{
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp = ip_vs_proto_get(p->protocol);
@@ -827,6 +827,7 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p,
&cp->daddr, daddr);
cp->dport = dport;
cp->flags = flags;
+ cp->fwmark = fwmark;
if (flags & IP_VS_CONN_F_TEMPLATE && p->pe) {
ip_vs_pe_get(p->pe);
cp->pe = p->pe;
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index b4e51e9..e2bb3cd 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -293,7 +293,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
* and thus param.pe_data will be destroyed
* when the template expires */
ct = ip_vs_conn_new(¶m, &dest->addr, dport,
- IP_VS_CONN_F_TEMPLATE, dest);
+ IP_VS_CONN_F_TEMPLATE, dest, skb->mark);
if (ct == NULL) {
kfree(param.pe_data);
return NULL;
@@ -319,7 +319,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
*/
ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, ports[0],
&iph.daddr, ports[1], ¶m);
- cp = ip_vs_conn_new(¶m, &dest->addr, dport, flags, dest);
+ cp = ip_vs_conn_new(¶m, &dest->addr, dport, flags, dest, skb->mark);
if (cp == NULL) {
ip_vs_conn_put(ct);
return NULL;
@@ -423,7 +423,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
pptr[0], &iph.daddr, pptr[1], &p);
cp = ip_vs_conn_new(&p, &dest->addr,
dest->port ? dest->port : pptr[1],
- flags, dest);
+ flags, dest, skb->mark);
if (!cp)
return NULL;
}
@@ -489,7 +489,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
&iph.daddr, pptr[1], &p);
cp = ip_vs_conn_new(&p, &daddr, 0,
IP_VS_CONN_F_BYPASS | flags,
- NULL);
+ NULL, skb->mark);
if (!cp)
return NF_DROP;
}
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 3e92558..a5bd002 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -657,12 +657,12 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr,
struct ip_vs_dest *ip_vs_find_dest(int af, const union nf_inet_addr *daddr,
__be16 dport,
const union nf_inet_addr *vaddr,
- __be16 vport, __u16 protocol)
+ __be16 vport, __u16 protocol, __u32 fwmark)
{
struct ip_vs_dest *dest;
struct ip_vs_service *svc;
- svc = ip_vs_service_get(af, 0, protocol, vaddr, vport);
+ svc = ip_vs_service_get(af, fwmark, protocol, vaddr, vport);
if (!svc)
return NULL;
dest = ip_vs_lookup_dest(svc, daddr, dport);
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index 7545500..84aef65 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -208,7 +208,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
n_cp = ip_vs_conn_new(&p, &from, port,
IP_VS_CONN_F_NO_CPORT |
IP_VS_CONN_F_NFCT,
- cp->dest);
+ cp->dest, skb->mark);
if (!n_cp)
return 0;
@@ -365,7 +365,8 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
if (!n_cp) {
n_cp = ip_vs_conn_new(&p, &cp->daddr,
htons(ntohs(cp->dport)-1),
- IP_VS_CONN_F_NFCT, cp->dest);
+ IP_VS_CONN_F_NFCT, cp->dest,
+ skb->mark);
if (!n_cp)
return 0;
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 3897d6b..47eed67 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -404,7 +404,7 @@ static void ip_vs_process_message(char *buffer, const size_t buflen)
s->dport,
(union nf_inet_addr *)&s->vaddr,
s->vport,
- s->protocol);
+ s->protocol, 0);
/* Set the approprite ativity flag */
if (s->protocol == IPPROTO_TCP) {
if (state != IP_VS_TCP_S_ESTABLISHED)
@@ -419,7 +419,7 @@ static void ip_vs_process_message(char *buffer, const size_t buflen)
}
cp = ip_vs_conn_new(¶m,
(union nf_inet_addr *)&s->daddr,
- s->dport, flags, dest);
+ s->dport, flags, dest, 0);
if (dest)
atomic_dec(&dest->refcnt);
if (!cp) {
--
1.7.2.3
^ permalink raw reply related
* [PATCH 4/8] IPVS: Handle Scheduling errors.
From: Simon Horman @ 2010-11-25 1:46 UTC (permalink / raw)
To: lvs-devel, netdev, netfilter, netfilter-devel
Cc: Hans Schillstrom, Julian Anastasov, Patrick McHardy, Simon Horman
In-Reply-To: <1290649618-18955-1-git-send-email-horms@verge.net.au>
From: Hans Schillstrom <hans.schillstrom@ericsson.com>
If ip_vs_conn_fill_param_persist return an error to ip_vs_sched_persist,
this error must propagate as ignored=-1 to ip_vs_schedule().
Errors from ip_vs_conn_new() in ip_vs_sched_persist() and ip_vs_schedule()
should also return *ignored=-1;
This patch just relies on the fact that ignored is 1 before calling
ip_vs_sched_persist().
Sent from Julian:
"The new case when ip_vs_conn_fill_param_persist fails
should set *ignored = -1, so that we can use NF_DROP,
see below. *ignored = -1 should be also used for ip_vs_conn_new
failure in ip_vs_sched_persist() and ip_vs_schedule().
The new negative value should be handled in tcp,udp,sctp"
"To summarize:
- *ignored = 1:
protocol tried to schedule (eg. on SYN), found svc but the
svc/scheduler decides that this packet should be accepted with
NF_ACCEPT because it must not be scheduled.
- *ignored = 0:
scheduler can not find destination, so try bypass or
return ICMP and then NF_DROP (ip_vs_leave).
- *ignored = -1:
scheduler tried to schedule but fatal error occurred, eg.
ip_vs_conn_new failure (ENOMEM) or ip_vs_sip_fill_param
failure such as missing Call-ID, ENOMEM on skb_linearize
or pe_data. In this case we should return NF_DROP without
any attempts to send ICMP with ip_vs_leave."
More or less all ideas and input to this patch is work from
Julian Anastasov
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/netfilter/ipvs/ip_vs_core.c | 56 +++++++++++++++++++++++---------
net/netfilter/ipvs/ip_vs_proto_sctp.c | 11 +++++--
net/netfilter/ipvs/ip_vs_proto_tcp.c | 10 +++++-
net/netfilter/ipvs/ip_vs_proto_udp.c | 10 +++++-
4 files changed, 64 insertions(+), 23 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 9acdd79..3445da6 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -177,7 +177,7 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction,
return pp->state_transition(cp, direction, skb, pp);
}
-static inline void
+static inline int
ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc,
struct sk_buff *skb, int protocol,
const union nf_inet_addr *caddr, __be16 cport,
@@ -187,7 +187,9 @@ ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc,
ip_vs_conn_fill_param(svc->af, protocol, caddr, cport, vaddr, vport, p);
p->pe = svc->pe;
if (p->pe && p->pe->fill_param)
- p->pe->fill_param(p, skb);
+ return p->pe->fill_param(p, skb);
+
+ return 0;
}
/*
@@ -200,7 +202,7 @@ ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc,
static struct ip_vs_conn *
ip_vs_sched_persist(struct ip_vs_service *svc,
struct sk_buff *skb,
- __be16 src_port, __be16 dst_port)
+ __be16 src_port, __be16 dst_port, int *ignored)
{
struct ip_vs_conn *cp = NULL;
struct ip_vs_iphdr iph;
@@ -268,20 +270,27 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
vaddr = &fwmark;
}
}
- ip_vs_conn_fill_param_persist(svc, skb, protocol, &snet, 0,
- vaddr, vport, ¶m);
+ /* return *ignored = -1 so NF_DROP can be used */
+ if (ip_vs_conn_fill_param_persist(svc, skb, protocol, &snet, 0,
+ vaddr, vport, ¶m) < 0) {
+ *ignored = -1;
+ return NULL;
+ }
}
/* Check if a template already exists */
ct = ip_vs_ct_in_get(¶m);
if (!ct || !ip_vs_check_template(ct)) {
- /* No template found or the dest of the connection
+ /*
+ * No template found or the dest of the connection
* template is not available.
+ * return *ignored=0 i.e. ICMP and NF_DROP
*/
dest = svc->scheduler->schedule(svc, skb);
if (!dest) {
IP_VS_DBG(1, "p-schedule: no dest found.\n");
kfree(param.pe_data);
+ *ignored = 0;
return NULL;
}
@@ -296,6 +305,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
IP_VS_CONN_F_TEMPLATE, dest, skb->mark);
if (ct == NULL) {
kfree(param.pe_data);
+ *ignored = -1;
return NULL;
}
@@ -323,6 +333,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
cp = ip_vs_conn_new(¶m, &dest->addr, dport, flags, dest, skb->mark);
if (cp == NULL) {
ip_vs_conn_put(ct);
+ *ignored = -1;
return NULL;
}
@@ -342,6 +353,21 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
* It selects a server according to the virtual service, and
* creates a connection entry.
* Protocols supported: TCP, UDP
+ *
+ * Usage of *ignored
+ *
+ * 1 : protocol tried to schedule (eg. on SYN), found svc but the
+ * svc/scheduler decides that this packet should be accepted with
+ * NF_ACCEPT because it must not be scheduled.
+ *
+ * 0 : scheduler can not find destination, so try bypass or
+ * return ICMP and then NF_DROP (ip_vs_leave).
+ *
+ * -1 : scheduler tried to schedule but fatal error occurred, eg.
+ * ip_vs_conn_new failure (ENOMEM) or ip_vs_sip_fill_param
+ * failure such as missing Call-ID, ENOMEM on skb_linearize
+ * or pe_data. In this case we should return NF_DROP without
+ * any attempts to send ICMP with ip_vs_leave.
*/
struct ip_vs_conn *
ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
@@ -372,11 +398,9 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
}
/*
- * Do not schedule replies from local real server. It is risky
- * for fwmark services but mostly for persistent services.
+ * Do not schedule replies from local real server.
*/
if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) &&
- (svc->flags & IP_VS_SVC_F_PERSISTENT || svc->fwmark) &&
(cp = pp->conn_in_get(svc->af, skb, pp, &iph, iph.len, 1))) {
IP_VS_DBG_PKT(12, svc->af, pp, skb, 0,
"Not scheduling reply for existing connection");
@@ -387,10 +411,10 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
/*
* Persistent service
*/
- if (svc->flags & IP_VS_SVC_F_PERSISTENT) {
- *ignored = 0;
- return ip_vs_sched_persist(svc, skb, pptr[0], pptr[1]);
- }
+ if (svc->flags & IP_VS_SVC_F_PERSISTENT)
+ return ip_vs_sched_persist(svc, skb, pptr[0], pptr[1], ignored);
+
+ *ignored = 0;
/*
* Non-persistent service
@@ -403,8 +427,6 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
return NULL;
}
- *ignored = 0;
-
dest = svc->scheduler->schedule(svc, skb);
if (dest == NULL) {
IP_VS_DBG(1, "Schedule: no dest found.\n");
@@ -425,8 +447,10 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
cp = ip_vs_conn_new(&p, &dest->addr,
dest->port ? dest->port : pptr[1],
flags, dest, skb->mark);
- if (!cp)
+ if (!cp) {
+ *ignored = -1;
return NULL;
+ }
}
IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u "
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index 1ea96bc..a315159 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -47,13 +47,18 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
* incoming connection, and create a connection entry.
*/
*cpp = ip_vs_schedule(svc, skb, pp, &ignored);
- if (!*cpp && !ignored) {
- *verdict = ip_vs_leave(svc, skb, pp);
+ if (!*cpp && ignored <= 0) {
+ if (!ignored)
+ *verdict = ip_vs_leave(svc, skb, pp);
+ else {
+ ip_vs_service_put(svc);
+ *verdict = NF_DROP;
+ }
return 0;
}
ip_vs_service_put(svc);
}
-
+ /* NF_ACCEPT */
return 1;
}
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index f6c5200..1cdab12 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -64,12 +64,18 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
* incoming connection, and create a connection entry.
*/
*cpp = ip_vs_schedule(svc, skb, pp, &ignored);
- if (!*cpp && !ignored) {
- *verdict = ip_vs_leave(svc, skb, pp);
+ if (!*cpp && ignored <= 0) {
+ if (!ignored)
+ *verdict = ip_vs_leave(svc, skb, pp);
+ else {
+ ip_vs_service_put(svc);
+ *verdict = NF_DROP;
+ }
return 0;
}
ip_vs_service_put(svc);
}
+ /* NF_ACCEPT */
return 1;
}
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index 9d106a0..cd398de 100644
--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -63,12 +63,18 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
* incoming connection, and create a connection entry.
*/
*cpp = ip_vs_schedule(svc, skb, pp, &ignored);
- if (!*cpp && !ignored) {
- *verdict = ip_vs_leave(svc, skb, pp);
+ if (!*cpp && ignored <= 0) {
+ if (!ignored)
+ *verdict = ip_vs_leave(svc, skb, pp);
+ else {
+ ip_vs_service_put(svc);
+ *verdict = NF_DROP;
+ }
return 0;
}
ip_vs_service_put(svc);
}
+ /* NF_ACCEPT */
return 1;
}
--
1.7.2.3
^ permalink raw reply related
* [PATCH 5/8] IPVS: Backup, Adding structs for new sync format
From: Simon Horman @ 2010-11-25 1:46 UTC (permalink / raw)
To: lvs-devel, netdev, netfilter, netfilter-devel
Cc: Hans Schillstrom, Julian Anastasov, Patrick McHardy, Simon Horman
In-Reply-To: <1290649618-18955-1-git-send-email-horms@verge.net.au>
From: Hans Schillstrom <hans.schillstrom@ericsson.com>
New structs defined for version 1 of sync.
* ip_vs_sync_v4 Ipv4 base format struct
* ip_vs_sync_v6 Ipv6 base format struct
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/netfilter/ipvs/ip_vs_sync.c | 154 ++++++++++++++++++++++++++++++++++++---
1 files changed, 142 insertions(+), 12 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 47eed67..566482f 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -43,11 +43,13 @@
#define IP_VS_SYNC_GROUP 0xe0000051 /* multicast addr - 224.0.0.81 */
#define IP_VS_SYNC_PORT 8848 /* multicast port */
+#define SYNC_PROTO_VER 1 /* Protocol version in header */
/*
* IPVS sync connection entry
+ * Version 0, i.e. original version.
*/
-struct ip_vs_sync_conn {
+struct ip_vs_sync_conn_v0 {
__u8 reserved;
/* Protocol, addresses and port numbers */
@@ -71,40 +73,157 @@ struct ip_vs_sync_conn_options {
struct ip_vs_seq out_seq; /* outgoing seq. struct */
};
+/*
+ Sync Connection format (sync_conn)
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Protocol | Ver. | Size |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Flags |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | State | cport |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | vport | dport |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | fwmark |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | timeout (in sec.) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ... |
+ | IP-Addresses (v4 or v6) |
+ | ... |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ Optional Parameters.
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Param. Type | Param. Length | Param. data |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ | ... |
+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | | Param Type | Param. Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Param data |
+ | Last Param data should be padded for 32 bit alignment |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+/*
+ * Type 0, IPv4 sync connection format
+ */
+struct ip_vs_sync_v4 {
+ __u8 type;
+ __u8 protocol; /* Which protocol (TCP/UDP) */
+ __be16 ver_size; /* Version msb 4 bits */
+ /* Flags and state transition */
+ __be32 flags; /* status flags */
+ __be16 state; /* state info */
+ /* Protocol, addresses and port numbers */
+ __be16 cport;
+ __be16 vport;
+ __be16 dport;
+ __be32 fwmark; /* Firewall mark from skb */
+ __be32 timeout; /* cp timeout */
+ __be32 caddr; /* client address */
+ __be32 vaddr; /* virtual address */
+ __be32 daddr; /* destination address */
+ /* The sequence options start here */
+ /* PE data padded to 32bit alignment after seq. options */
+};
+/*
+ * Type 2 messages IPv6
+ */
+struct ip_vs_sync_v6 {
+ __u8 type;
+ __u8 protocol; /* Which protocol (TCP/UDP) */
+ __be16 ver_size; /* Version msb 4 bits */
+ /* Flags and state transition */
+ __be32 flags; /* status flags */
+ __be16 state; /* state info */
+ /* Protocol, addresses and port numbers */
+ __be16 cport;
+ __be16 vport;
+ __be16 dport;
+ __be32 fwmark; /* Firewall mark from skb */
+ __be32 timeout; /* cp timeout */
+ struct in6_addr caddr; /* client address */
+ struct in6_addr vaddr; /* virtual address */
+ struct in6_addr daddr; /* destination address */
+ /* The sequence options start here */
+ /* PE data padded to 32bit alignment after seq. options */
+};
+
+union ip_vs_sync_conn {
+ struct ip_vs_sync_v4 v4;
+ struct ip_vs_sync_v6 v6;
+};
+
+/* Bits in Type field in above */
+#define STYPE_INET6 0
+#define STYPE_F_INET6 (1 << STYPE_INET6)
+
+#define SVER_SHIFT 12 /* Shift to get version */
+#define SVER_MASK 0x0fff /* Mask to strip version */
+
+#define IPVS_OPT_SEQ_DATA 1
+#define IPVS_OPT_PE_DATA 2
+#define IPVS_OPT_PE_NAME 3
+#define IPVS_OPT_PARAM 7
+
+#define IPVS_OPT_F_SEQ_DATA (1 << (IPVS_OPT_SEQ_DATA-1))
+#define IPVS_OPT_F_PE_DATA (1 << (IPVS_OPT_PE_DATA-1))
+#define IPVS_OPT_F_PE_NAME (1 << (IPVS_OPT_PE_NAME-1))
+#define IPVS_OPT_F_PARAM (1 << (IPVS_OPT_PARAM-1))
+
struct ip_vs_sync_thread_data {
struct socket *sock;
char *buf;
};
-#define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn))
+/* Version 0 definition of packet sizes */
+#define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn_v0))
#define FULL_CONN_SIZE \
-(sizeof(struct ip_vs_sync_conn) + sizeof(struct ip_vs_sync_conn_options))
+(sizeof(struct ip_vs_sync_conn_v0) + sizeof(struct ip_vs_sync_conn_options))
/*
- The master mulitcasts messages to the backup load balancers in the
- following format.
+ The master mulitcasts messages (Datagrams) to the backup load balancers
+ in the following format.
+
+ Version 1:
+ Note, first byte should be Zero, so ver 0 receivers will drop the packet.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Count Conns | SyncID | Size |
+ | 0 | SyncID | Size |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Count Conns | Version | Reserved, set to Zero |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| IPVS Sync Connection (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| . |
- | . |
+ ~ . ~
| . |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| IPVS Sync Connection (n) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Version 0 Header
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Count Conns | SyncID | Size |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | IPVS Sync Connection (1) |
*/
#define SYNC_MESG_HEADER_LEN 4
#define MAX_CONNS_PER_SYNCBUFF 255 /* nr_conns in ip_vs_sync_mesg is 8 bit */
+/* Version 0 header */
struct ip_vs_sync_mesg {
__u8 nr_conns;
__u8 syncid;
@@ -113,6 +232,17 @@ struct ip_vs_sync_mesg {
/* ip_vs_sync_conn entries start here */
};
+/* Version 1 header */
+struct ip_vs_sync_mesg_v2 {
+ __u8 reserved; /* must be zero */
+ __u8 syncid;
+ __u16 size;
+ __u8 nr_conns;
+ __s8 version; /* SYNC_PROTO_VER */
+ __u16 spare;
+ /* ip_vs_sync_conn entries start here */
+};
+
/* the maximum length of sync (sending/receiving) message */
static int sync_send_mesg_maxlen;
static int sync_recv_mesg_maxlen;
@@ -239,7 +369,7 @@ get_curr_sync_buff(unsigned long time)
void ip_vs_sync_conn(const struct ip_vs_conn *cp)
{
struct ip_vs_sync_mesg *m;
- struct ip_vs_sync_conn *s;
+ struct ip_vs_sync_conn_v0 *s;
int len;
spin_lock(&curr_sb_lock);
@@ -254,7 +384,7 @@ void ip_vs_sync_conn(const struct ip_vs_conn *cp)
len = (cp->flags & IP_VS_CONN_F_SEQ_MASK) ? FULL_CONN_SIZE :
SIMPLE_CONN_SIZE;
m = curr_sb->mesg;
- s = (struct ip_vs_sync_conn *)curr_sb->head;
+ s = (struct ip_vs_sync_conn_v0 *)curr_sb->head;
/* copy members */
s->protocol = cp->protocol;
@@ -306,7 +436,7 @@ ip_vs_conn_fill_param_sync(int af, int protocol,
static void ip_vs_process_message(char *buffer, const size_t buflen)
{
struct ip_vs_sync_mesg *m = (struct ip_vs_sync_mesg *)buffer;
- struct ip_vs_sync_conn *s;
+ struct ip_vs_sync_conn_v0 *s;
struct ip_vs_sync_conn_options *opt;
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp;
@@ -343,7 +473,7 @@ static void ip_vs_process_message(char *buffer, const size_t buflen)
IP_VS_ERR_RL("bogus conn in sync message\n");
return;
}
- s = (struct ip_vs_sync_conn *) p;
+ s = (struct ip_vs_sync_conn_v0 *) p;
flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
flags &= ~IP_VS_CONN_F_HASHED;
if (flags & IP_VS_CONN_F_SEQ_MASK) {
@@ -849,7 +979,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
IP_VS_DBG(7, "%s(): pid %d\n", __func__, task_pid_nr(current));
IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n",
- sizeof(struct ip_vs_sync_conn));
+ sizeof(struct ip_vs_sync_conn_v0));
if (state == IP_VS_STATE_MASTER) {
if (sync_master_thread)
--
1.7.2.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox