* Re: [PATCH] tcp: Implement a two-level initial RTO as per draft RFC 2988bis-02.
From: Alexander Zimmermann @ 2011-05-19 16:55 UTC (permalink / raw)
To: tsuna
Cc: Hagen Paul Pfeifer, David Miller, kuznet, pekkas, jmorris,
yoshfuji, kaber, eric.dumazet, netdev, linux-kernel
In-Reply-To: <BANLkTimSZEbnNVzi3UvBFndHp25S0ow7YQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1647 bytes --]
Am 19.05.2011 um 18:40 schrieb tsuna:
> On Thu, May 19, 2011 at 1:02 AM, Hagen Paul Pfeifer <hagen@jauu.net> wrote:
>> So yes, it CAN be wise to choose other lower/upper bounds. But keep in
>> mind that we should NOT artificial limit ourself. I can image data center
>> scenarios where a initial RTO of <1 match perfectly.
>
> Yes that's exactly the point I was trying to make when talking to
> Alexander offline. On today's Internet, RTTs are easily in the
> hundreds of ms, and initRTO is 3s, so there's 2 orders of magnitude of
> difference. In my environment,
Exactly. This is the point. It's *your* environment. However, TCP is
general purpose. And for the wider internet 1s is know to be save. See the
measurements in the draft that Mark Allman run.
> if my RTT is ~2µs, an initRTO of 200ms
> means that there's a gap of 6 orders of magnitude (!).
Currently, initRTO is 3s. So you the gap is even larger.
> And yes,
> although I don't work for High Frequency Trading companies in Wall
> Street, I'm already buying switches full of line-rate 10Gb ports with
> a port-to-port latency of 500ns for L2/L3 forwarding/switching. I
> expect this kind of network gear will quickly become prevalent in
> datacenter/backend environments.
>
> --
> Benoit "tsuna" Sigoure
> Software Engineer @ www.StumbleUpon.com
//
// Dipl.-Inform. Alexander Zimmermann
// Department of Computer Science, Informatik 4
// RWTH Aachen University
// Ahornstr. 55, 52056 Aachen, Germany
// phone: (49-241) 80-21422, fax: (49-241) 80-22222
// email: zimmermann@cs.rwth-aachen.de
// web: http://www.umic-mesh.net
//
[-- Attachment #2: Signierter Teil der Nachricht --]
[-- Type: application/pgp-signature, Size: 243 bytes --]
^ permalink raw reply
* Re: [PATCH] tcp: Implement a two-level initial RTO as per draft RFC 2988bis-02.
From: tsuna @ 2011-05-19 16:40 UTC (permalink / raw)
To: Hagen Paul Pfeifer
Cc: Alexander Zimmermann, David Miller, kuznet, pekkas, jmorris,
yoshfuji, kaber, eric.dumazet, netdev, linux-kernel
In-Reply-To: <ef84de89c2597793d4cca5eee446ba90@localhost>
On Thu, May 19, 2011 at 1:02 AM, Hagen Paul Pfeifer <hagen@jauu.net> wrote:
> So yes, it CAN be wise to choose other lower/upper bounds. But keep in
> mind that we should NOT artificial limit ourself. I can image data center
> scenarios where a initial RTO of <1 match perfectly.
Yes that's exactly the point I was trying to make when talking to
Alexander offline. On today's Internet, RTTs are easily in the
hundreds of ms, and initRTO is 3s, so there's 2 orders of magnitude of
difference. In my environment, if my RTT is ~2µs, an initRTO of 200ms
means that there's a gap of 6 orders of magnitude (!). And yes,
although I don't work for High Frequency Trading companies in Wall
Street, I'm already buying switches full of line-rate 10Gb ports with
a port-to-port latency of 500ns for L2/L3 forwarding/switching. I
expect this kind of network gear will quickly become prevalent in
datacenter/backend environments.
--
Benoit "tsuna" Sigoure
Software Engineer @ www.StumbleUpon.com
^ permalink raw reply
* Re: [PATCH 4/4] rps: Inspect GRE encapsulated packets to get flow hash
From: Eric Dumazet @ 2011-05-19 16:16 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
In-Reply-To: <alpine.DEB.2.00.1105190827420.12804@pokey.mtv.corp.google.com>
Le jeudi 19 mai 2011 à 08:39 -0700, Tom Herbert a écrit :
> Crack open GRE packets in __skb_get_rxhash to compute 4-tuple hash on
> in encapsulated packet. Note that this is used only when the
> __skb_get_rxhash is taken, in particular only when the device does
> not compute provide the rxhash (ie. feature is disabled).
>
> This was tested by creating a single GRE tunnel between two 16 core
> AMD machines. 200 netperf TCP_RR streams were ran with 1 byte
> request and response size.
>
> Without patch: 157497 tps, 50/90/99% latencies 1250/1292/1364 usecs
> With patch: 325896 tps, 50/90/99% latencies 603/848/1169
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> net/core/dev.c | 22 ++++++++++++++++++++++
> 1 files changed, 22 insertions(+), 0 deletions(-)
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 0c83494..7799bbd 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2552,6 +2552,28 @@ again:
> }
>
> switch (ip_proto) {
> + case IPPROTO_GRE:
> + if (pskb_may_pull(skb, nhoff + 16)) {
> + u8 *h = skb->data + nhoff;
> + __be16 flags = *(__be16 *)h;
> +
> + /*
> + * Only look inside GRE if version zero and no
> + * routing
> + */
> + if (!(flags & (GRE_VERSION|GRE_ROUTING))) {
> + proto = *(__be16 *)(h + 2);
> + nhoff += 4;
> + if (flags & GRE_CSUM)
> + nhoff += 4;
> + if (flags & GRE_KEY)
> + nhoff += 4;
> + if (flags & GRE_SEQ)
> + nhoff += 4;
> + goto again;
> + }
> + }
> + break;
> default:
> break;
> }
Hi Tom
For sure it helps if this machine is the final host for these packets.
If I am a firewall or router [and not looking into GRE packets], maybe I
dont want to spread all packets received on a tunnel to several cpus and
reorder them when forwarded.
Maybe we need to add a table, so that upper layer (GRE or IPIP tunnels)
can instruct __skb_get_rxhash() that we want to deep inspect packets.
1) Say we keep rxhash first evaluation be the one we have today.
2) Do a hash lookup in a new table to tell if upper layer handled a
previous packet for this first level flow and want more inspection.
3) table could contains 'pointers' to decoding function, that would
recompute a new rxhash function.
4) Find a way to "clean the table", garbage collect or expirations times
can do.
This way we can add stuff in GRE and IPIP modules [and other kind of
tunnels], without layer violations ?
^ permalink raw reply
* Re: [Bridge] [Patch] bridge: call NETDEV_ENSLAVE notifiers when adding a slave
From: Stephen Hemminger @ 2011-05-19 16:04 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Amerigo Wang, Neil Horman, bridge, netdev, Jay Vosburgh,
linux-kernel, akpm, David S. Miller
In-Reply-To: <20110519081213.15c05da2@nehalam>
On Thu, 19 May 2011 08:12:13 -0700
Stephen Hemminger <shemminger@linux-foundation.org> wrote:
> On Thu, 19 May 2011 18:24:17 +0800
> Amerigo Wang <amwang@redhat.com> wrote:
>
> > In the previous patch I added NETDEV_ENSLAVE, now
> > we can notify netconsole when adding a device to a bridge too.
> >
> > By the way, s/netdev_bonding_change/call_netdevice_notifiers/ in
> > bond_main.c, since this is not bonding specific.
> >
> > Signed-off-by: WANG Cong <amwang@redhat.com>
> > Cc: Neil Horman <nhorman@redhat.com>
> >
>
> Is there a usage for this? What listens for this notification?
Never mind it was in the first patch which you did not send.
You should always put a number on group of patches and send
to all parties.
Also, sending networking patches to LKML is a waste of bandwidth
please don't bother.
^ permalink raw reply
* [PATCH 4/4] rps: Inspect GRE encapsulated packets to get flow hash
From: Tom Herbert @ 2011-05-19 15:39 UTC (permalink / raw)
To: davem, netdev
Crack open GRE packets in __skb_get_rxhash to compute 4-tuple hash on
in encapsulated packet. Note that this is used only when the
__skb_get_rxhash is taken, in particular only when the device does
not compute provide the rxhash (ie. feature is disabled).
This was tested by creating a single GRE tunnel between two 16 core
AMD machines. 200 netperf TCP_RR streams were ran with 1 byte
request and response size.
Without patch: 157497 tps, 50/90/99% latencies 1250/1292/1364 usecs
With patch: 325896 tps, 50/90/99% latencies 603/848/1169
Signed-off-by: Tom Herbert <therbert@google.com>
---
net/core/dev.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 0c83494..7799bbd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2552,6 +2552,28 @@ again:
}
switch (ip_proto) {
+ case IPPROTO_GRE:
+ if (pskb_may_pull(skb, nhoff + 16)) {
+ u8 *h = skb->data + nhoff;
+ __be16 flags = *(__be16 *)h;
+
+ /*
+ * Only look inside GRE if version zero and no
+ * routing
+ */
+ if (!(flags & (GRE_VERSION|GRE_ROUTING))) {
+ proto = *(__be16 *)(h + 2);
+ nhoff += 4;
+ if (flags & GRE_CSUM)
+ nhoff += 4;
+ if (flags & GRE_KEY)
+ nhoff += 4;
+ if (flags & GRE_SEQ)
+ nhoff += 4;
+ goto again;
+ }
+ }
+ break;
default:
break;
}
--
1.7.3.1
^ permalink raw reply related
* [PATCH 3/4] rps: Infrastructure in __skb_get_rxhash for deep inspection
From: Tom Herbert @ 2011-05-19 15:39 UTC (permalink / raw)
To: davem, netdev
Basics for looking for ports in encapsulated packets in tunnels.
Signed-off-by: Tom Herbert <therbert@google.com>
---
net/core/dev.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 37ddece..0c83494 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -133,6 +133,7 @@
#include <linux/pci.h>
#include <linux/inetdevice.h>
#include <linux/cpu_rmap.h>
+#include <linux/if_tunnel.h>
#include "net-sysfs.h"
@@ -2521,6 +2522,7 @@ void __skb_get_rxhash(struct sk_buff *skb)
nhoff = skb_network_offset(skb);
proto = skb->protocol;
+again:
switch (proto) {
case __constant_htons(ETH_P_IP):
if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
@@ -2549,6 +2551,11 @@ void __skb_get_rxhash(struct sk_buff *skb)
goto done;
}
+ switch (ip_proto) {
+ default:
+ break;
+ }
+
ports.v32 = 0;
poff = proto_ports_offset(ip_proto);
if (poff >= 0) {
--
1.7.3.1
^ permalink raw reply related
* [PATCH 2/4] rps: Add flag to skb to indicate rxhash is on L4 tuple
From: Tom Herbert @ 2011-05-19 15:39 UTC (permalink / raw)
To: davem, netdev
The l4_rxhash flag was added to the skb structure to indicate
that the rxhash value was computed over the 4 tuple for the
packet which includes the port information in the encapsulated
transport packet. This is used by the stack to preserve the
rxhash value in __skb_rx_tunnel.
Signed-off-by: Tom Herbert <therbert@google.com>
---
include/linux/skbuff.h | 5 +++--
include/net/dst.h | 9 ++++++++-
include/net/sock.h | 14 +++++++++++---
net/core/dev.c | 17 +++++++++++------
net/core/skbuff.c | 1 +
net/ipv4/tcp_ipv4.c | 4 ++--
net/ipv4/udp.c | 4 ++--
7 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 79aafbb..4fab336 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -397,6 +397,7 @@ struct sk_buff {
__u8 ndisc_nodetype:2;
#endif
__u8 ooo_okay:1;
+ __u8 l4_rxhash:1;
kmemcheck_bitfield_end(flags2);
/* 0/13 bit hole */
@@ -555,11 +556,11 @@ extern unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
unsigned int to, struct ts_config *config,
struct ts_state *state);
-extern __u32 __skb_get_rxhash(struct sk_buff *skb);
+extern void __skb_get_rxhash(struct sk_buff *skb);
static inline __u32 skb_get_rxhash(struct sk_buff *skb)
{
if (!skb->rxhash)
- skb->rxhash = __skb_get_rxhash(skb);
+ __skb_get_rxhash(skb);
return skb->rxhash;
}
diff --git a/include/net/dst.h b/include/net/dst.h
index 07a0402..17ff602 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -307,7 +307,14 @@ static inline void skb_dst_force(struct sk_buff *skb)
static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
{
skb->dev = dev;
- skb->rxhash = 0;
+
+ /*
+ * Clear rxhash so that we can reculate the hash for the
+ * encapsulated packet, unless we have already determine the hash
+ * over the L4 4-tuple.
+ */
+ if (!skb->l4_rxhash)
+ skb->rxhash = 0;
skb_set_queue_mapping(skb, 0);
skb_dst_drop(skb);
nf_reset(skb);
diff --git a/include/net/sock.h b/include/net/sock.h
index f2046e4..e670c41 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -685,16 +685,24 @@ static inline void sock_rps_reset_flow(const struct sock *sk)
#endif
}
-static inline void sock_rps_save_rxhash(struct sock *sk, u32 rxhash)
+static inline void sock_rps_save_rxhash(struct sock *sk, struct sk_buff *skb)
{
#ifdef CONFIG_RPS
- if (unlikely(sk->sk_rxhash != rxhash)) {
+ if (unlikely(sk->sk_rxhash != skb->rxhash)) {
sock_rps_reset_flow(sk);
- sk->sk_rxhash = rxhash;
+ sk->sk_rxhash = skb->rxhash;
}
#endif
}
+static inline void sock_rps_reset_rxhash(struct sock *sk)
+{
+#ifdef CONFIG_RPS
+ sock_rps_reset_flow(sk);
+ sk->sk_rxhash = 0;
+#endif
+}
+
#define sk_wait_event(__sk, __timeo, __condition) \
({ int __rc; \
release_sock(__sk); \
diff --git a/net/core/dev.c b/net/core/dev.c
index a40eea9..37ddece 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2014,8 +2014,10 @@ static inline void skb_orphan_try(struct sk_buff *skb)
/* skb_tx_hash() wont be able to get sk.
* We copy sk_hash into skb->rxhash
*/
- if (!skb->rxhash)
+ if (!skb->rxhash) {
skb->rxhash = sk->sk_hash;
+ skb->l4_rxhash = 1;
+ }
skb_orphan(skb);
}
}
@@ -2499,12 +2501,13 @@ static inline void ____napi_schedule(struct softnet_data *sd,
/*
* __skb_get_rxhash: calculate a flow hash based on src/dst addresses
- * and src/dst port numbers. Returns a non-zero hash number on success
- * and 0 on failure.
+ * and src/dst port numbers. Sets rxhash in skb to non-zero hash value
+ * on success, zero indicates no valid hash. Also, sets l4_rxhash in skb
+ * if hash is a canonical 4-tuple hash over transport ports.
*/
-__u32 __skb_get_rxhash(struct sk_buff *skb)
+void __skb_get_rxhash(struct sk_buff *skb)
{
- int nhoff, hash = 0, poff;
+ int nhoff, hash = 0, l4hash = 0, poff;
const struct ipv6hdr *ip6;
const struct iphdr *ip;
u8 ip_proto;
@@ -2554,6 +2557,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
ports.v32 = * (__force u32 *) (skb->data + nhoff);
if (ports.v16[1] < ports.v16[0])
swap(ports.v16[0], ports.v16[1]);
+ l4hash = 1;
}
}
@@ -2566,7 +2570,8 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
hash = 1;
done:
- return hash;
+ skb->rxhash = hash;
+ skb->l4_rxhash = l4hash;
}
EXPORT_SYMBOL(__skb_get_rxhash);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 7ebeed0..cb5c67d 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -513,6 +513,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->mac_header = old->mac_header;
skb_dst_copy(new, old);
new->rxhash = old->rxhash;
+ new->l4_rxhash = old->l4_rxhash;
#ifdef CONFIG_XFRM
new->sp = secpath_get(old->sp);
#endif
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 3c8d9b6..a4b156dc 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1572,7 +1572,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
#endif
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
- sock_rps_save_rxhash(sk, skb->rxhash);
+ sock_rps_save_rxhash(sk, skb);
if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
rsk = sk;
goto reset;
@@ -1596,7 +1596,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
return 0;
}
} else
- sock_rps_save_rxhash(sk, skb->rxhash);
+ sock_rps_save_rxhash(sk, skb);
if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) {
rsk = sk;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 599374f..d2277cf 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1263,7 +1263,7 @@ int udp_disconnect(struct sock *sk, int flags)
sk->sk_state = TCP_CLOSE;
inet->inet_daddr = 0;
inet->inet_dport = 0;
- sock_rps_save_rxhash(sk, 0);
+ sock_rps_reset_rxhash(sk);
sk->sk_bound_dev_if = 0;
if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
inet_reset_saddr(sk);
@@ -1351,7 +1351,7 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
int rc;
if (inet_sk(sk)->inet_daddr)
- sock_rps_save_rxhash(sk, skb->rxhash);
+ sock_rps_save_rxhash(sk, skb);
rc = ip_queue_rcv_skb(sk, skb);
if (rc < 0) {
--
1.7.3.1
^ permalink raw reply related
* [PATCH 1/4] rps: Some minor cleanup in get_rps_cpus
From: Tom Herbert @ 2011-05-19 15:39 UTC (permalink / raw)
To: davem, netdev
Use some variables for clarity and extensibility.
Signed-off-by: Tom Herbert <therbert@google.com>
---
net/core/dev.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 155de20..a40eea9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2508,15 +2508,17 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
const struct ipv6hdr *ip6;
const struct iphdr *ip;
u8 ip_proto;
- u32 addr1, addr2, ihl;
+ u32 addr1, addr2;
+ u16 proto;
union {
u32 v32;
u16 v16[2];
} ports;
nhoff = skb_network_offset(skb);
+ proto = skb->protocol;
- switch (skb->protocol) {
+ switch (proto) {
case __constant_htons(ETH_P_IP):
if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
goto done;
@@ -2528,7 +2530,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
ip_proto = ip->protocol;
addr1 = (__force u32) ip->saddr;
addr2 = (__force u32) ip->daddr;
- ihl = ip->ihl;
+ nhoff += ip->ihl * 4;
break;
case __constant_htons(ETH_P_IPV6):
if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff))
@@ -2538,7 +2540,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
ip_proto = ip6->nexthdr;
addr1 = (__force u32) ip6->saddr.s6_addr32[3];
addr2 = (__force u32) ip6->daddr.s6_addr32[3];
- ihl = (40 >> 2);
+ nhoff += 40;
break;
default:
goto done;
@@ -2547,7 +2549,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
ports.v32 = 0;
poff = proto_ports_offset(ip_proto);
if (poff >= 0) {
- nhoff += ihl * 4 + poff;
+ nhoff += poff;
if (pskb_may_pull(skb, nhoff + 4)) {
ports.v32 = * (__force u32 *) (skb->data + nhoff);
if (ports.v16[1] < ports.v16[0])
--
1.7.3.1
^ permalink raw reply related
* [PATCH 0/4] rps: Look into tunnels to get hash
From: Tom Herbert @ 2011-05-19 15:38 UTC (permalink / raw)
To: davem, netdev
The patches in this series are to look into encapsulated packets
to compute the rx hash for RPS. Before these patches, all packets
received on the same tunnel would wind up on the same RPS CPU-- this
can lead to very poor loading, and make RFS ineffective on these
packets.
This patch supports getting the rxhash out of a GRE encapsulated packet.
A couple of caveats:
- rxhash should be disabled in device to be able to use this. I believe
probably all NICs would just provide rxhash on the outer packet
2-tuple.
- The l4_rxhash flag was added so that the hash is preserved across the
tunnel and can set in flow tables by the transport. It would be nice
it driverswould set this to so to provide more useful information to the
stack (like whether the rxhash hash should be used in the flow table).
Unfortutunately, I don't think all drivers will be able to distinguish
the type of hash (2-tuple, 4-tuple, ...) without looking into the
packet.
^ permalink raw reply
* RE: [RFC V4 PATCH] rtnetlink: Compute and store minimum ifinfo dump size
From: Rose, Gregory V @ 2011-05-19 15:35 UTC (permalink / raw)
To: Rose, Gregory V, David Miller
Cc: netdev@vger.kernel.org, bhutchings@solarflare.com,
eric.dumazet@gmail.com
In-Reply-To: <43F901BD926A4E43B106BF17856F0755018E321C4C@orsmsx508.amr.corp.intel.com>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
> On Behalf Of Rose, Gregory V
> Sent: Wednesday, May 18, 2011 3:49 PM
> To: David Miller
> Cc: netdev@vger.kernel.org; bhutchings@solarflare.com;
> eric.dumazet@gmail.com
> Subject: RE: [RFC V4 PATCH] rtnetlink: Compute and store minimum ifinfo
> dump size
>
> > -----Original Message-----
> > From: David Miller [mailto:davem@davemloft.net]
> > Sent: Wednesday, May 18, 2011 3:48 PM
> > To: Rose, Gregory V
> > Cc: netdev@vger.kernel.org; bhutchings@solarflare.com;
> > eric.dumazet@gmail.com
> > Subject: Re: [RFC V4 PATCH] rtnetlink: Compute and store minimum ifinfo
> > dump size
> >
> > From: "Rose, Gregory V" <gregory.v.rose@intel.com>
> > Date: Wed, 18 May 2011 15:35:58 -0700
> >
> > > It looked to me like rtmsg_ifinfo is called when each device is
> > > registered through register_netdevice() and rtmsg_ifinfo in turn
> > > calls the if_nlmsg_size function returning the ifinfo dump size for
> > > each device. In my testing it looked like the proper maximum size
> > > was being set after I loaded the drivers for the SR-IOV capable
> > > devices.
> >
> > Aha, indeed you're right. I missed this part. Thanks for explaining.
> >
> > So as far as I can tell it should work, I'll let others review it to
> > see if they are ok with this approach.
>
> Ok, sure. We'll see if Eric catches anything, he's got an eagle eye.
Having seen no further comments on this RFC I am going to clean up the patch and submit it to our internal review list for further testing and validation. If/when it passes through that process I'll post it back here.
Thanks to all who commented and made suggestions for improvement.
- Greg
^ permalink raw reply
* Re: [PATCH v3] ipconfig wait for carrier
From: Dan Williams @ 2011-05-19 15:31 UTC (permalink / raw)
To: David Miller; +Cc: micha, netdev
In-Reply-To: <20110518.181427.1228926976939865196.davem@davemloft.net>
On Wed, 2011-05-18 at 18:14 -0400, David Miller wrote:
> From: Micha Nelissen <micha@neli.hopto.org>
> Date: Wed, 18 May 2011 08:59:32 +0200
>
> > Op 2011-05-18 8:37, David Miller schreef:
> >> From: Micha Nelissen<micha@neli.hopto.org>
> >> Date: Wed, 18 May 2011 08:32:35 +0200
> >>
> >>> I'm confused. Against which tree/commit do you want it then?
> >>
> >> Linus's current tree would be fine as would:
> >>
> >> git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
> >
> > Ok I see, thanks. The patch should apply just fine to your tree, there
> > is only a spelling change since 2.6.38 which does not conflict.
>
> Please fix ic_is_init_dev() to return a proper boolean "false" instead
> of "0" when IFF_LOOPBACK is set.
Shouldn't the code still wait at *least* one second? Not all drivers
support carrier detect, and those that don't set the carrier always-on.
Thus older devices that used to have 1s to get carrier in line (even if
they don't report it) now have only 10ms.
I think it should wait at least one second like the code currently does,
and then if the carrier still isn't up, wait longer.
Dan
^ permalink raw reply
* Re: [Patch] bridge: call NETDEV_ENSLAVE notifiers when adding a slave
From: Stephen Hemminger @ 2011-05-19 15:12 UTC (permalink / raw)
To: Amerigo Wang
Cc: linux-kernel, akpm, Neil Horman, Jay Vosburgh, David S. Miller,
netdev, bridge
In-Reply-To: <1305800661-4081-1-git-send-email-amwang@redhat.com>
On Thu, 19 May 2011 18:24:17 +0800
Amerigo Wang <amwang@redhat.com> wrote:
> In the previous patch I added NETDEV_ENSLAVE, now
> we can notify netconsole when adding a device to a bridge too.
>
> By the way, s/netdev_bonding_change/call_netdevice_notifiers/ in
> bond_main.c, since this is not bonding specific.
>
> Signed-off-by: WANG Cong <amwang@redhat.com>
> Cc: Neil Horman <nhorman@redhat.com>
>
Is there a usage for this? What listens for this notification?
^ permalink raw reply
* [PATCH net-next-2.6] macvlan: Forward unicast frames in bridge mode to lowerdev
From: David Ward @ 2011-05-19 12:53 UTC (permalink / raw)
To: netdev; +Cc: David Ward, Patrick McHardy
Unicast frames between macvlan interfaces in bridge mode are not otherwise
sent to network taps on the lowerdev (as all other macvlan frames are), so
forward the frames to the receive queue of the lowerdev first.
Signed-off-by: David Ward <david.ward@ll.mit.edu>
---
drivers/net/macvlan.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index d7c0bc62..e7de3b3 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -237,10 +237,8 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
dest = macvlan_hash_lookup(port, eth->h_dest);
if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
- unsigned int length = skb->len + ETH_HLEN;
- int ret = dest->forward(dest->dev, skb);
- macvlan_count_rx(dest, length,
- ret == NET_RX_SUCCESS, 0);
+ /* send to lowerdev first for its network taps */
+ vlan->forward(vlan->lowerdev, skb);
return NET_XMIT_SUCCESS;
}
--
1.7.4.4
^ permalink raw reply related
* Re: [RFC/PATCH 00/13] wl12xx re-factor
From: Felipe Balbi @ 2011-05-19 14:06 UTC (permalink / raw)
To: Luciano Coelho; +Cc: Felipe Balbi, linux-wireless, netdev, linux-kernel
In-Reply-To: <1305809345.12586.1579.camel@cumari>
[-- Attachment #1: Type: text/plain, Size: 1589 bytes --]
Hi,
On Thu, May 19, 2011 at 03:49:05PM +0300, Luciano Coelho wrote:
> > this is the re-factor I was talking to you
> > about. Please have a look and give your
> > comments.
> >
> > It probably won't work as is, I compile
> > tested only, but it shows the idea.
>
> This looks very good! I think we should do something like this to avoid
> the code that is duplicated in the bus modules.
>
> But, as I already mentioned briefly on IRC, there is a problem with the
> way you changed the platform data structure, because it will break
> compat-wireless. The actual memory and data that is used by the
> platform data is in the board components and not part of the wireless
> subsystem. With compat-wireless, we need to make sure that new stuff
> works with older kernels. In your patches you modify the platform data
> structure, so when we run an old kernel with new compat-wireless, things
> will break.
>
> We already found a similar bug due to a previous change in the platform
> data structure, so I don't want this to happen again. So for now, I'll
> keep these patches aside, but as soon as we find a good solution, I'll
> definitely use your ideas here (or ask you to rebase :P).
>
> I'll probably apply some of the patches that are not related to the
> platform data change. I'll respond to those specific patches
> separately.
ok good. I have stated my POV WRT compatibility layers for in-tree
drivers on a separate thread. In summary, I think those shouldn't exist
at all :-)
Just let me know if you need anything ;-)
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* [PATCH net-next-2.6] netfilter: add more values to enum ip_conntrack_info
From: Eric Dumazet @ 2011-05-19 13:44 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Netfilter Development Mailinglist, netdev, David Miller
Following error is raised (and other similar ones) :
net/ipv4/netfilter/nf_nat_standalone.c: In function ‘nf_nat_fn’:
net/ipv4/netfilter/nf_nat_standalone.c:119:2: warning: case value ‘4’
not in enumerated type ‘enum ip_conntrack_info’
gcc barfs on adding two enum values and getting a not enumerated
result :
case IP_CT_RELATED+IP_CT_IS_REPLY:
Add missing enum values
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: David Miller <davem@davemloft.net>
---
include/linux/netfilter/nf_conntrack_common.h | 3 +++
net/ipv4/netfilter/ipt_CLUSTERIP.c | 6 +++---
net/ipv4/netfilter/ipt_MASQUERADE.c | 2 +-
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 +-
net/ipv4/netfilter/nf_nat_core.c | 2 +-
net/ipv4/netfilter/nf_nat_rule.c | 2 +-
net/ipv4/netfilter/nf_nat_standalone.c | 4 ++--
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 2 +-
net/netfilter/nf_conntrack_core.c | 4 ++--
net/netfilter/nf_conntrack_ftp.c | 2 +-
net/netfilter/nf_conntrack_h323_main.c | 10 ++++------
net/netfilter/nf_conntrack_irc.c | 3 +--
net/netfilter/nf_conntrack_pptp.c | 3 +--
net/netfilter/nf_conntrack_sane.c | 2 +-
net/netfilter/nf_conntrack_sip.c | 2 +-
net/netfilter/xt_socket.c | 4 ++--
16 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
index 50cdc25..0d3dd66 100644
--- a/include/linux/netfilter/nf_conntrack_common.h
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -18,6 +18,9 @@ enum ip_conntrack_info {
/* >= this indicates reply direction */
IP_CT_IS_REPLY,
+ IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY,
+ IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY,
+ IP_CT_NEW_REPLY = IP_CT_NEW + IP_CT_IS_REPLY,
/* Number of distinct IP_CT types (no NEW in reply dirn). */
IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
};
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index d609ac3..5c9e97c 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -307,7 +307,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
* error messages (RELATED) and information requests (see below) */
if (ip_hdr(skb)->protocol == IPPROTO_ICMP &&
(ctinfo == IP_CT_RELATED ||
- ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY))
+ ctinfo == IP_CT_RELATED_REPLY))
return XT_CONTINUE;
/* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO,
@@ -321,12 +321,12 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
ct->mark = hash;
break;
case IP_CT_RELATED:
- case IP_CT_RELATED+IP_CT_IS_REPLY:
+ case IP_CT_RELATED_REPLY:
/* FIXME: we don't handle expectations at the
* moment. they can arrive on a different node than
* the master connection (e.g. FTP passive mode) */
case IP_CT_ESTABLISHED:
- case IP_CT_ESTABLISHED+IP_CT_IS_REPLY:
+ case IP_CT_ESTABLISHED_REPLY:
break;
default:
break;
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index d2ed9dc..9931152 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -60,7 +60,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par)
nat = nfct_nat(ct);
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
- ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
+ ctinfo == IP_CT_RELATED_REPLY));
/* Source address is 0.0.0.0 - locally generated packet that is
* probably not supposed to be masqueraded.
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 5a03c02..db10075 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -101,7 +101,7 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(skb, &ctinfo);
- if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
+ if (!ct || ctinfo == IP_CT_RELATED_REPLY)
goto out;
help = nfct_help(ct);
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 9c71b27..3346de5 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -433,7 +433,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
/* Must be RELATED */
NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED ||
- skb->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
+ skb->nfctinfo == IP_CT_RELATED_REPLY);
/* Redirects on non-null nats must be dropped, else they'll
start talking to each other without our translation, and be
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 21c3042..733c9ab 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -53,7 +53,7 @@ ipt_snat_target(struct sk_buff *skb, const struct xt_action_param *par)
/* Connection must be valid and new. */
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
- ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
+ ctinfo == IP_CT_RELATED_REPLY));
NF_CT_ASSERT(par->out != NULL);
return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 7317bdf..483b76d 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -116,7 +116,7 @@ nf_nat_fn(unsigned int hooknum,
switch (ctinfo) {
case IP_CT_RELATED:
- case IP_CT_RELATED+IP_CT_IS_REPLY:
+ case IP_CT_RELATED_REPLY:
if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
if (!nf_nat_icmp_reply_translation(ct, ctinfo,
hooknum, skb))
@@ -144,7 +144,7 @@ nf_nat_fn(unsigned int hooknum,
default:
/* ESTABLISHED */
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
- ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY));
+ ctinfo == IP_CT_ESTABLISHED_REPLY);
}
return nf_nat_packet(ct, ctinfo, hooknum, skb);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index c8af58b..4111050 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -160,7 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(skb, &ctinfo);
- if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
+ if (!ct || ctinfo == IP_CT_RELATED_REPLY)
goto out;
help = nfct_help(ct);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 2e1c11f..0bd5689 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -850,7 +850,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
/* It exists; we have (non-exclusive) reference. */
if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
- *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
+ *ctinfo = IP_CT_ESTABLISHED_REPLY;
/* Please set reply bit if this packet OK */
*set_reply = 1;
} else {
@@ -1143,7 +1143,7 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
/* This ICMP is in reverse direction to the packet which caused it */
ct = nf_ct_get(skb, &ctinfo);
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
- ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY;
+ ctinfo = IP_CT_RELATED_REPLY;
else
ctinfo = IP_CT_RELATED;
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index e17cb7c..6f5801e 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -368,7 +368,7 @@ static int help(struct sk_buff *skb,
/* Until there's been traffic both ways, don't look in packets. */
if (ctinfo != IP_CT_ESTABLISHED &&
- ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
+ ctinfo != IP_CT_ESTABLISHED_REPLY) {
pr_debug("ftp: Conntrackinfo = %u\n", ctinfo);
return NF_ACCEPT;
}
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 18b2ce5..f03c2d4 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -571,10 +571,9 @@ static int h245_help(struct sk_buff *skb, unsigned int protoff,
int ret;
/* Until there's been traffic both ways, don't look in packets. */
- if (ctinfo != IP_CT_ESTABLISHED &&
- ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
+ if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
return NF_ACCEPT;
- }
+
pr_debug("nf_ct_h245: skblen = %u\n", skb->len);
spin_lock_bh(&nf_h323_lock);
@@ -1125,10 +1124,9 @@ static int q931_help(struct sk_buff *skb, unsigned int protoff,
int ret;
/* Until there's been traffic both ways, don't look in packets. */
- if (ctinfo != IP_CT_ESTABLISHED &&
- ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
+ if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
return NF_ACCEPT;
- }
+
pr_debug("nf_ct_q931: skblen = %u\n", skb->len);
spin_lock_bh(&nf_h323_lock);
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index b394aa3..4f9390b 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -125,8 +125,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
return NF_ACCEPT;
/* Until there's been traffic both ways, don't look in packets. */
- if (ctinfo != IP_CT_ESTABLISHED &&
- ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
+ if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
return NF_ACCEPT;
/* Not a full tcp header? */
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 0889448..2fd4565 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -519,8 +519,7 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff,
u_int16_t msg;
/* don't do any tracking before tcp handshake complete */
- if (ctinfo != IP_CT_ESTABLISHED &&
- ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
+ if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
return NF_ACCEPT;
nexthdr_off = protoff;
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index d9e2773..8501823 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -78,7 +78,7 @@ static int help(struct sk_buff *skb,
ct_sane_info = &nfct_help(ct)->help.ct_sane_info;
/* Until there's been traffic both ways, don't look in packets. */
if (ctinfo != IP_CT_ESTABLISHED &&
- ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY)
+ ctinfo != IP_CT_ESTABLISHED_REPLY)
return NF_ACCEPT;
/* Not a full tcp header? */
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index cb5a285..93faf6a 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1423,7 +1423,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
if (ctinfo != IP_CT_ESTABLISHED &&
- ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
+ ctinfo != IP_CT_ESTABLISHED_REPLY)
return NF_ACCEPT;
/* No Data ? */
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index 9cc4635..fe39f7e 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -143,9 +143,9 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
ct = nf_ct_get(skb, &ctinfo);
if (ct && !nf_ct_is_untracked(ct) &&
((iph->protocol != IPPROTO_ICMP &&
- ctinfo == IP_CT_IS_REPLY + IP_CT_ESTABLISHED) ||
+ ctinfo == IP_CT_ESTABLISHED_REPLY) ||
(iph->protocol == IPPROTO_ICMP &&
- ctinfo == IP_CT_IS_REPLY + IP_CT_RELATED)) &&
+ ctinfo == IP_CT_RELATED_REPLY)) &&
(ct->status & IPS_SRC_NAT_DONE)) {
daddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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 related
* Re: [PATCH v2] CDC NCM: release interfaces fix in unbind()
From: Oliver Neukum @ 2011-05-19 13:40 UTC (permalink / raw)
To: Alexey ORISHKO
Cc: Alan Stern, gregkh-l3A5Bk7waGM@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <2AC7D4AD8BA1C640B4C60C61C8E520153E3ACE0774-8ZTw5gFVCTjVH5byLeRTJxkTb7+GphCuwzqs5ZKRSiY@public.gmane.org>
Am Mittwoch, 18. Mai 2011, 19:11:37 schrieb Alexey ORISHKO:
> I wonder, if Greg or Oliver could provide any comments why master interface
> is not claimed in modem/ether drivers, since they are working with the
> code for quite a while.
Probe is called for the master interface. You claim only _additional_
interfaces. The problem is in disconnect(). You may be called in any order.
HTH
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [RFC PATCH v3 ethtool] ethtool: implement [GS]FEATURES calls
From: Michał Mirosław @ 2011-05-19 13:25 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, David Miller
In-Reply-To: <20110519091833.GA24484@rere.qmqm.pl>
This is all-in-one PoC patch for [GS]FEATURES support and checking of
all feature changes when altering some.
Example result:
icybox:~# ./ethtool -K ge0 tx_checksum-ipv6 on
feature group tx is enabled (expected: disabled)
feature group sg is enabled (expected: disabled)
feature group gso is enabled (expected: disabled)
feature tx-scatter-gather is enabled (expected: disabled, saved: enabled)
feature tx-generic-segmentation is enabled (expected: disabled, saved: enabled)
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
ethtool.c | 583 +++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 494 insertions(+), 89 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 34fe107..40456bb 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -33,6 +33,7 @@
#include <limits.h>
#include <ctype.h>
+#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -83,6 +84,8 @@ static int do_gcoalesce(int fd, struct ifreq *ifr);
static int do_scoalesce(int fd, struct ifreq *ifr);
static int do_goffload(int fd, struct ifreq *ifr);
static int do_soffload(int fd, struct ifreq *ifr);
+static void parse_sfeatures_args(int argc, char **argp, int argi);
+static int do_gfeatures(int fd, struct ifreq *ifr);
static int do_gstats(int fd, struct ifreq *ifr);
static int rxflow_str_to_type(const char *str);
static int parse_rxfhashopts(char *optstr, u32 *data);
@@ -196,7 +199,8 @@ static struct option {
" [ txvlan on|off ]\n"
" [ ntuple on|off ]\n"
" [ rxhash on|off ]\n"
- },
+ " [ feature-name on|off [...] ]\n"
+ " see --show-offload output for feature-name strings\n" },
{ "-i", "--driver", MODE_GDRV, "Show driver information" },
{ "-d", "--register-dump", MODE_GREGS, "Do a register dump",
" [ raw on|off ]\n"
@@ -296,7 +300,6 @@ static void show_usage(void)
static char *devname = NULL;
-static int goffload_changed = 0;
static int off_csum_rx_wanted = -1;
static int off_csum_tx_wanted = -1;
static int off_sg_wanted = -1;
@@ -306,6 +309,9 @@ static int off_gso_wanted = -1;
static u32 off_flags_wanted = 0;
static u32 off_flags_mask = 0;
static int off_gro_wanted = -1;
+static int n_feature_strings;
+static const char **feature_strings;
+static struct ethtool_sfeatures *features_req;
static struct ethtool_pauseparam epause;
static int gpause_changed = 0;
@@ -851,10 +857,7 @@ static void parse_cmdline(int argc, char **argp)
break;
}
if (mode == MODE_SOFFLOAD) {
- parse_generic_cmdline(argc, argp, i,
- &goffload_changed,
- cmdline_offload,
- ARRAY_SIZE(cmdline_offload));
+ parse_sfeatures_args(argc, argp, i);
i = argc;
break;
}
@@ -1788,9 +1791,15 @@ static int dump_coalesce(void)
return 0;
}
-static int dump_offload(int rx, int tx, int sg, int tso, int ufo, int gso,
- int gro, int lro, int rxvlan, int txvlan, int ntuple,
- int rxhash)
+struct offload_state {
+ int rx, tx, sg, tso, ufo, gso, gro, lro, rxvlan, txvlan, ntuple, rxhash;
+};
+
+const char *const old_feature_names[] = {
+ "rx", "tx", "sg", "tso", "ufo", "gso", "gro", "lro", "rxvlan", "txvlan", "ntuple", "rxhash"
+};
+
+static int dump_offload(const struct offload_state *offload)
{
fprintf(stdout,
"rx-checksumming: %s\n"
@@ -1805,18 +1814,18 @@ static int dump_offload(int rx, int tx, int sg, int tso, int ufo, int gso,
"tx-vlan-offload: %s\n"
"ntuple-filters: %s\n"
"receive-hashing: %s\n",
- rx ? "on" : "off",
- tx ? "on" : "off",
- sg ? "on" : "off",
- tso ? "on" : "off",
- ufo ? "on" : "off",
- gso ? "on" : "off",
- gro ? "on" : "off",
- lro ? "on" : "off",
- rxvlan ? "on" : "off",
- txvlan ? "on" : "off",
- ntuple ? "on" : "off",
- rxhash ? "on" : "off");
+ offload->rx ? "on" : "off",
+ offload->tx ? "on" : "off",
+ offload->sg ? "on" : "off",
+ offload->tso ? "on" : "off",
+ offload->ufo ? "on" : "off",
+ offload->gso ? "on" : "off",
+ offload->gro ? "on" : "off",
+ offload->lro ? "on" : "off",
+ offload->rxvlan ? "on" : "off",
+ offload->txvlan ? "on" : "off",
+ offload->ntuple ? "on" : "off",
+ offload->rxhash ? "on" : "off");
return 0;
}
@@ -1867,21 +1876,33 @@ static int dump_rxfhash(int fhash, u64 val)
return 0;
}
-static int doit(void)
-{
- struct ifreq ifr;
- int fd;
+static int control_fd = -1;
+static int get_control_socket(struct ifreq *ifr)
+{
/* Setup our control structures. */
- memset(&ifr, 0, sizeof(ifr));
- strcpy(ifr.ifr_name, devname);
+ memset(ifr, 0, sizeof(*ifr));
+ strcpy(ifr->ifr_name, devname);
+
+ if (control_fd >= 0)
+ return control_fd;
/* Open control socket. */
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
+ control_fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (control_fd < 0)
perror("Cannot get control socket");
+
+ return control_fd;
+}
+
+static int doit(void)
+{
+ struct ifreq ifr;
+ int fd;
+
+ fd = get_control_socket(&ifr);
+ if (fd < 0)
return 70;
- }
/* all of these are expected to populate ifr->ifr_data as needed */
if (mode == MODE_GDRV) {
@@ -2139,14 +2160,13 @@ static int do_scoalesce(int fd, struct ifreq *ifr)
return 0;
}
-static int do_goffload(int fd, struct ifreq *ifr)
+static int send_goffloads(int fd, struct ifreq *ifr,
+ struct offload_state *offload)
{
struct ethtool_value eval;
- int err, allfail = 1, rx = 0, tx = 0, sg = 0;
- int tso = 0, ufo = 0, gso = 0, gro = 0, lro = 0, rxvlan = 0, txvlan = 0,
- ntuple = 0, rxhash = 0;
+ int err, allfail = 1;
- fprintf(stdout, "Offload parameters for %s:\n", devname);
+ memset(offload, 0, sizeof(*offload));
eval.cmd = ETHTOOL_GRXCSUM;
ifr->ifr_data = (caddr_t)&eval;
@@ -2154,7 +2174,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err)
perror("Cannot get device rx csum settings");
else {
- rx = eval.data;
+ offload->rx = eval.data;
allfail = 0;
}
@@ -2164,7 +2184,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err)
perror("Cannot get device tx csum settings");
else {
- tx = eval.data;
+ offload->tx = eval.data;
allfail = 0;
}
@@ -2174,7 +2194,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err)
perror("Cannot get device scatter-gather settings");
else {
- sg = eval.data;
+ offload->sg = eval.data;
allfail = 0;
}
@@ -2184,7 +2204,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err)
perror("Cannot get device tcp segmentation offload settings");
else {
- tso = eval.data;
+ offload->tso = eval.data;
allfail = 0;
}
@@ -2194,7 +2214,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err)
perror("Cannot get device udp large send offload settings");
else {
- ufo = eval.data;
+ offload->ufo = eval.data;
allfail = 0;
}
@@ -2204,7 +2224,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err)
perror("Cannot get device generic segmentation offload settings");
else {
- gso = eval.data;
+ offload->gso = eval.data;
allfail = 0;
}
@@ -2214,11 +2234,11 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err) {
perror("Cannot get device flags");
} else {
- lro = (eval.data & ETH_FLAG_LRO) != 0;
- rxvlan = (eval.data & ETH_FLAG_RXVLAN) != 0;
- txvlan = (eval.data & ETH_FLAG_TXVLAN) != 0;
- ntuple = (eval.data & ETH_FLAG_NTUPLE) != 0;
- rxhash = (eval.data & ETH_FLAG_RXHASH) != 0;
+ offload->lro = (eval.data & ETH_FLAG_LRO) != 0;
+ offload->rxvlan = (eval.data & ETH_FLAG_RXVLAN) != 0;
+ offload->txvlan = (eval.data & ETH_FLAG_TXVLAN) != 0;
+ offload->ntuple = (eval.data & ETH_FLAG_NTUPLE) != 0;
+ offload->rxhash = (eval.data & ETH_FLAG_RXHASH) != 0;
allfail = 0;
}
@@ -2228,130 +2248,515 @@ static int do_goffload(int fd, struct ifreq *ifr)
if (err)
perror("Cannot get device GRO settings");
else {
- gro = eval.data;
+ offload->gro = eval.data;
allfail = 0;
}
+ return -allfail;
+}
+
+static int do_goffload(int fd, struct ifreq *ifr)
+{
+ struct offload_state offload;
+ int err, allfail;
+
+ allfail = send_goffloads(fd, ifr, &offload);
+
+ if (!allfail) {
+ fprintf(stdout, "Offload parameters for %s:\n", devname);
+
+ dump_offload(&offload);
+ }
+
+ err = do_gfeatures(fd, ifr);
+ if (!err)
+ allfail = 0;
+
if (allfail) {
fprintf(stdout, "no offload info available\n");
return 83;
}
- return dump_offload(rx, tx, sg, tso, ufo, gso, gro, lro, rxvlan, txvlan,
- ntuple, rxhash);
+ return 0;
}
-static int do_soffload(int fd, struct ifreq *ifr)
+static int send_soffloads(int fd, struct ifreq *ifr)
{
struct ethtool_value eval;
int err, changed = 0;
if (off_csum_rx_wanted >= 0) {
- changed = 1;
eval.cmd = ETHTOOL_SRXCSUM;
eval.data = (off_csum_rx_wanted == 1);
ifr->ifr_data = (caddr_t)&eval;
err = send_ioctl(fd, ifr);
- if (err) {
+ if (err)
perror("Cannot set device rx csum settings");
- return 84;
- }
+ else
+ changed = 1;
}
if (off_csum_tx_wanted >= 0) {
- changed = 1;
eval.cmd = ETHTOOL_STXCSUM;
eval.data = (off_csum_tx_wanted == 1);
ifr->ifr_data = (caddr_t)&eval;
err = send_ioctl(fd, ifr);
- if (err) {
+ if (err)
perror("Cannot set device tx csum settings");
- return 85;
- }
+ else
+ changed = 1;
}
if (off_sg_wanted >= 0) {
- changed = 1;
eval.cmd = ETHTOOL_SSG;
eval.data = (off_sg_wanted == 1);
ifr->ifr_data = (caddr_t)&eval;
err = send_ioctl(fd, ifr);
- if (err) {
+ if (err)
perror("Cannot set device scatter-gather settings");
- return 86;
- }
+ else
+ changed = 1;
}
if (off_tso_wanted >= 0) {
- changed = 1;
eval.cmd = ETHTOOL_STSO;
eval.data = (off_tso_wanted == 1);
ifr->ifr_data = (caddr_t)&eval;
err = send_ioctl(fd, ifr);
- if (err) {
+ if (err)
perror("Cannot set device tcp segmentation offload settings");
- return 88;
- }
+ else
+ changed = 1;
}
if (off_ufo_wanted >= 0) {
- changed = 1;
eval.cmd = ETHTOOL_SUFO;
eval.data = (off_ufo_wanted == 1);
ifr->ifr_data = (caddr_t)&eval;
err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
+ if (err)
perror("Cannot set device udp large send offload settings");
- return 89;
- }
+ else
+ changed = 1;
}
if (off_gso_wanted >= 0) {
- changed = 1;
eval.cmd = ETHTOOL_SGSO;
eval.data = (off_gso_wanted == 1);
ifr->ifr_data = (caddr_t)&eval;
err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
+ if (err)
perror("Cannot set device generic segmentation offload settings");
- return 90;
- }
+ else
+ changed = 1;
}
if (off_flags_mask) {
- changed = 1;
eval.cmd = ETHTOOL_GFLAGS;
eval.data = 0;
ifr->ifr_data = (caddr_t)&eval;
err = ioctl(fd, SIOCETHTOOL, ifr);
if (err) {
perror("Cannot get device flag settings");
- return 91;
- }
-
- eval.cmd = ETHTOOL_SFLAGS;
- eval.data = ((eval.data & ~off_flags_mask) |
- off_flags_wanted);
-
- err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
- perror("Cannot set device flag settings");
- return 92;
+ } else {
+ eval.cmd = ETHTOOL_SFLAGS;
+ eval.data = ((eval.data & ~off_flags_mask) |
+ off_flags_wanted);
+
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err)
+ perror("Cannot set device flag settings");
+ else
+ changed = 1;
}
}
if (off_gro_wanted >= 0) {
- changed = 1;
eval.cmd = ETHTOOL_SGRO;
eval.data = (off_gro_wanted == 1);
ifr->ifr_data = (caddr_t)&eval;
err = ioctl(fd, SIOCETHTOOL, ifr);
- if (err) {
+ if (err)
perror("Cannot set device GRO settings");
- return 93;
+ else
+ changed = 1;
+ }
+
+ return changed;
+}
+
+static int get_feature_strings(int fd, struct ifreq *ifr,
+ struct ethtool_gstrings **strs)
+{
+ struct ethtool_sset_info *sset_info;
+ struct ethtool_gstrings *strings;
+ int sz_str, n_strings, err;
+
+ sset_info = malloc(sizeof(struct ethtool_sset_info) + sizeof(u32));
+ sset_info->cmd = ETHTOOL_GSSET_INFO;
+ sset_info->sset_mask = (1ULL << ETH_SS_FEATURES);
+ ifr->ifr_data = (caddr_t)sset_info;
+ err = send_ioctl(fd, ifr);
+
+ n_strings = sset_info->data[0];
+ free(sset_info);
+
+ if ((err < 0) ||
+ (!(sset_info->sset_mask & (1ULL << ETH_SS_FEATURES))) ||
+ (n_strings == 0)) {
+ return -100;
+ }
+
+ sz_str = n_strings * ETH_GSTRING_LEN;
+ strings = calloc(1, sz_str + sizeof(struct ethtool_gstrings));
+ if (!strings) {
+ fprintf(stderr, "no memory available\n");
+ exit(95);
+ }
+
+ strings->cmd = ETHTOOL_GSTRINGS;
+ strings->string_set = ETH_SS_FEATURES;
+ strings->len = n_strings;
+ ifr->ifr_data = (caddr_t) strings;
+ err = send_ioctl(fd, ifr);
+ if (err < 0) {
+ perror("Cannot get feature strings information");
+ free(strings);
+ exit(96);
+ }
+
+ *strs = strings;
+ return n_strings;
+}
+
+static int init_feature_strings(void)
+{
+ struct ethtool_gstrings *strings;
+ struct ifreq ifr;
+ int fd, i, n;
+
+ if (feature_strings)
+ return n_feature_strings;
+
+ fd = get_control_socket(&ifr);
+ if (fd < 0)
+ exit(100);
+
+ n = get_feature_strings(fd, &ifr, &strings);
+
+ if (n < 0)
+ return n;
+
+ n_feature_strings = n;
+ feature_strings = calloc(n, sizeof(*feature_strings));
+ if (!feature_strings) {
+ fprintf(stderr, "no memory available for string table [size=%d]\n", n);
+ exit(95);
+ }
+
+ for (i = 0; i < n; ++i) {
+ if (!strings->data[i*ETH_GSTRING_LEN])
+ continue;
+
+ feature_strings[i] = strndup(
+ (const char *)&strings->data[i * ETH_GSTRING_LEN],
+ ETH_GSTRING_LEN);
+
+ if (!feature_strings[i]) {
+ fprintf(stderr, "no memory available for a string\n");
+ exit(95);
}
}
+ free(strings);
+ return n;
+}
+
+static void parse_sfeatures_args(int argc, char **argp, int argi)
+{
+ struct cmdline_info *cmdline_desc, *cp;
+ int sz_features, i;
+ int changed = 0;
+
+ if (init_feature_strings() < 0) {
+ /* ETHTOOL_GFEATURES unavailable */
+ parse_generic_cmdline(argc, argp, argi, &changed,
+ cmdline_offload, ARRAY_SIZE(cmdline_offload));
+ return;
+ }
+
+ sz_features = sizeof(*features_req->features) * ((n_feature_strings + 31) / 32);
+
+ cp = cmdline_desc = calloc(n_feature_strings + ARRAY_SIZE(cmdline_offload),
+ sizeof(*cmdline_desc));
+ memcpy(cp, cmdline_offload, sizeof(cmdline_offload));
+ cp += ARRAY_SIZE(cmdline_offload);
+
+ features_req = calloc(1, sizeof(*features_req) + sz_features);
+ if (!cmdline_desc || !features_req) {
+ fprintf(stderr, "no memory available\n");
+ exit(95);
+ }
+
+ features_req->size = (n_feature_strings + 31) / 32;
+
+ for (i = 0; i < n_feature_strings; ++i) {
+ if (!feature_strings[i])
+ continue;
+
+ cp->name = feature_strings[i];
+ cp->type = CMDL_FLAG;
+ cp->flag_val = 1 << (i % 32);
+ cp->wanted_val = &features_req->features[i / 32].requested;
+ cp->seen_val = &features_req->features[i / 32].valid;
+ ++cp;
+ }
+
+ parse_generic_cmdline(argc, argp, argi, &changed,
+ cmdline_desc, cp - cmdline_desc);
+
+ free(cmdline_desc);
+
+ if (!changed) {
+ free(features_req);
+ features_req = NULL;
+ }
+}
+
+static int send_gfeatures(int fd, struct ifreq *ifr,
+ struct ethtool_gfeatures **features_p)
+{
+ struct ethtool_gfeatures *features;
+ int err, sz_features;
+
+ sz_features = sizeof(*features->features) * ((n_feature_strings + 31) / 32);
+ features = calloc(1, sz_features + sizeof(*features));
+ if (!features) {
+ fprintf(stderr, "no memory available\n");
+ return 95;
+ }
+
+ features->cmd = ETHTOOL_GFEATURES;
+ features->size = (n_feature_strings + 31) / 32;
+ ifr->ifr_data = (caddr_t) features;
+ err = send_ioctl(fd, ifr);
+
+ if (err < 0) {
+ perror("Cannot get feature status");
+ free(features);
+ return 97;
+ }
+
+ *features_p = features;
+ return 0;
+}
+
+static int do_gfeatures(int fd, struct ifreq *ifr)
+{
+ struct ethtool_gfeatures *features;
+ int err, i;
+
+ err = init_feature_strings();
+ if (err < 0)
+ return -err;
+
+ err = send_gfeatures(fd, ifr, &features);
+ if (err)
+ return err;
+
+ fprintf(stdout, "\nFull offload state: (feature-name: active,wanted,changable)\n");
+ for (i = 0; i < n_feature_strings; i++) {
+ if (!feature_strings[i])
+ continue; /* empty */
+#define P_FLAG(f) \
+ (features->features[i / 32].f & (1 << (i % 32))) ? "yes" : " no"
+#define PA_FLAG(f) \
+ (features->features[i / 32].available & (1 << (i % 32))) ? P_FLAG(f) : "---"
+#define PN_FLAG(f) \
+ (features->features[i / 32].never_changed & (1 << (i % 32))) ? "---" : P_FLAG(f)
+ fprintf(stdout, " %-*.*s %s,%s,%s\n",
+ ETH_GSTRING_LEN, ETH_GSTRING_LEN, feature_strings[i],
+ P_FLAG(active), PA_FLAG(requested), PN_FLAG(available));
+#undef P_FLAG
+#undef PA_FLAG
+#undef PN_FLAG
+ }
+ free(features);
+
+ return 0;
+}
+
+static void print_gfeatures_diff(
+ const struct ethtool_get_features_block *expected,
+ const struct ethtool_get_features_block *set,
+ const char **strings, int n_strings)
+{
+ int i;
+
+ if (n_strings > 32)
+ n_strings = 32;
+
+ for (i = 0; i < n_strings; ++i) {
+ u32 mask = 1 << i;
+
+ if (!strings[i])
+ continue;
+
+ if (!((expected->active ^ set->active) & mask))
+ continue;
+
+ fprintf(stderr, "feature %.*s is %s (expected: %s, saved: %s)\n",
+ ETH_GSTRING_LEN, strings[i],
+ set->active & mask ? "enabled" : "disabled",
+ expected->active & mask ? "enabled" : "disabled",
+ !(set->available & mask) ? "not user-changeable" :
+ set->requested & mask ? "enabled" : "disabled"
+ );
+ }
+}
+
+static int get_offload_state(int fd, struct ifreq *ifr,
+ struct ethtool_gfeatures **features,
+ struct offload_state *offload)
+{
+ int err, allfail;
+
+ allfail = send_goffloads(fd, ifr, offload);
+
+ err = init_feature_strings();
+ if (err < 0)
+ return allfail ? err : 0;
+
+ err = send_gfeatures(fd, ifr, features);
+ if (err)
+ perror("Cannot read features");
+
+ return allfail ? -err : 0;
+}
+
+static int send_sfeatures(int fd, struct ifreq *ifr)
+{
+ int err;
+
+ features_req->cmd = ETHTOOL_SFEATURES;
+ ifr->ifr_data = (caddr_t) features_req;
+ err = send_ioctl(fd, ifr);
+ if (err < 0) {
+ perror("Cannot change features");
+ return 97;
+ }
+
+ return 0;
+}
+
+static void compare_offload_state(struct offload_state *offload0,
+ struct offload_state *offload1)
+{
+ int *expected = (int *)offload0, *new = (int *)offload1;
+ int i;
+
+ if (off_csum_rx_wanted >= 0)
+ offload0->rx = off_csum_rx_wanted;
+
+ if (off_csum_tx_wanted >= 0)
+ offload0->tx = off_csum_tx_wanted;
+
+ if (off_sg_wanted >= 0)
+ offload0->sg = off_sg_wanted;
+
+ if (off_tso_wanted >= 0)
+ offload0->tso = off_tso_wanted;
+
+ if (off_ufo_wanted >= 0)
+ offload0->ufo = off_ufo_wanted;
+
+ if (off_gso_wanted >= 0)
+ offload0->gso = off_gso_wanted;
+
+ if (off_gro_wanted >= 0)
+ offload0->gro = off_gro_wanted;
+
+ if (off_flags_mask & ETH_FLAG_LRO)
+ offload0->lro = !!(off_flags_wanted & ETH_FLAG_LRO);
+
+ if (off_flags_mask & ETH_FLAG_RXVLAN)
+ offload0->rxvlan = !!(off_flags_wanted & ETH_FLAG_RXVLAN);
+
+ if (off_flags_mask & ETH_FLAG_TXVLAN)
+ offload0->txvlan = !!(off_flags_wanted & ETH_FLAG_TXVLAN);
+
+ if (off_flags_mask & ETH_FLAG_NTUPLE)
+ offload0->ntuple = !!(off_flags_wanted & ETH_FLAG_NTUPLE);
+
+ if (off_flags_mask & ETH_FLAG_RXHASH)
+ offload0->rxhash = !!(off_flags_wanted & ETH_FLAG_RXHASH);
+
+ for (i = 0; i < ARRAY_SIZE(old_feature_names); i++) {
+ if (expected[i] == new[i])
+ continue;
+
+ fprintf(stderr, "feature group %s is %s (expected: %s)\n",
+ old_feature_names[i],
+ new[i] ? "enabled" : "disabled",
+ expected[i] ? "enabled" : "disabled"
+ );
+ }
+}
+
+static void compare_features(struct ethtool_gfeatures *features0,
+ struct ethtool_gfeatures *features1)
+{
+ int i;
+
+ /* make features0 .active what we expect to be set */
+ i = (n_feature_strings + 31) / 32;
+ while (i--) {
+ features0->features[i].active &= ~features_req->features[i].valid;
+ features0->features[i].active |=
+ features_req->features[i].requested &
+ features_req->features[i].valid;
+ }
+
+ for (i = 0; i < n_feature_strings; i += 32)
+ print_gfeatures_diff(&features0->features[i / 32],
+ &features1->features[i / 32],
+ feature_strings + i,
+ n_feature_strings - i);
+}
+
+static int do_soffload(int fd, struct ifreq *ifr)
+{
+ struct ethtool_gfeatures *features_old, *features_new;
+ struct offload_state offload_old, offload_new;
+ int err, changed;
+
+ err = get_offload_state(fd, ifr, &features_old, &offload_old);
+ if (err)
+ return -err;
+
+ changed = send_soffloads(fd, ifr);
+
+ if (features_req) {
+ err = send_sfeatures(fd, ifr);
+ if (!err)
+ changed = 1;
+ }
+
if (!changed) {
fprintf(stdout, "no offload settings changed\n");
+ return err;
+ }
+
+ err = get_offload_state(fd, ifr, &features_new, &offload_new);
+ if (err) {
+ perror("can't verify offload setting");
+ return 101;
+ }
+ if ((!features_old) ^ (!features_new)) {
+ fprintf(stderr, "can't compare features (one GFEATURES failed)\n");
+ features_old = NULL;
}
+ compare_offload_state(&offload_old, &offload_new);
+ if (features_old)
+ compare_features(features_old, features_new);
+
return 0;
}
^ permalink raw reply related
* Re: [V2 Patch net-next-2.6] netpoll: disable netpoll when enslave a device
From: Neil Horman @ 2011-05-19 13:25 UTC (permalink / raw)
To: Andy Gospodarek
Cc: Amerigo Wang, linux-kernel, akpm, Jay Vosburgh, David S. Miller,
Ian Campbell, Paul E. McKenney, Josh Triplett, netdev
In-Reply-To: <20110519113127.GE21309@gospo.rdu.redhat.com>
On Thu, May 19, 2011 at 07:31:27AM -0400, Andy Gospodarek wrote:
> On Thu, May 19, 2011 at 04:39:53PM +0800, Amerigo Wang wrote:
> [...]
> > diff --git a/include/linux/notifier.h b/include/linux/notifier.h
> > index 621dfa1..3d82867 100644
> > --- a/include/linux/notifier.h
> > +++ b/include/linux/notifier.h
> > @@ -211,6 +211,7 @@ static inline int notifier_to_errno(int ret)
> > #define NETDEV_UNREGISTER_BATCH 0x0011
> > #define NETDEV_BONDING_DESLAVE 0x0012
> > #define NETDEV_NOTIFY_PEERS 0x0013
> > +#define NETDEV_ENSLAVE 0x0014
> >
> > #define SYS_DOWN 0x0001 /* Notify of system down */
> > #define SYS_RESTART SYS_DOWN
>
> Neil just noted the same concern I had -- the asymmetry between
> NETDEV_ENSLAVE and NETDEV_BONDING_DESLAVE bothers me a bit. I also
> don't really like the followup patch that uses 'ENSLAVE' in the bridging
> code when we typically use that language for bonding only.
>
> What about changing NETDEV_BONDING_DESLAVE to NETDEV_RELEASE and create
> NETDEV_JOIN instead of NETDEV_ENSLAVE? I would prefer that or something
> else that might use more generic language that could be applied to all
> for stacked interfaces.
JOIN and RELEASE (or perhaps LEAVE) sounds good to me.
Neil
^ permalink raw reply
* Re: [RFC/PATCH 00/13] wl12xx re-factor
From: Luciano Coelho @ 2011-05-19 12:49 UTC (permalink / raw)
To: Felipe Balbi; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <1305321990-22041-1-git-send-email-balbi@ti.com>
On Sat, 2011-05-14 at 00:26 +0300, Felipe Balbi wrote:
> Hi Luca,
Hi Felipe,
> this is the re-factor I was talking to you
> about. Please have a look and give your
> comments.
>
> It probably won't work as is, I compile
> tested only, but it shows the idea.
This looks very good! I think we should do something like this to avoid
the code that is duplicated in the bus modules.
But, as I already mentioned briefly on IRC, there is a problem with the
way you changed the platform data structure, because it will break
compat-wireless. The actual memory and data that is used by the
platform data is in the board components and not part of the wireless
subsystem. With compat-wireless, we need to make sure that new stuff
works with older kernels. In your patches you modify the platform data
structure, so when we run an old kernel with new compat-wireless, things
will break.
We already found a similar bug due to a previous change in the platform
data structure, so I don't want this to happen again. So for now, I'll
keep these patches aside, but as soon as we find a good solution, I'll
definitely use your ideas here (or ask you to rebase :P).
I'll probably apply some of the patches that are not related to the
platform data change. I'll respond to those specific patches
separately.
--
Cheers,
Luca.
^ permalink raw reply
* [PATCH] IPVS: Free resources on module removal
From: Simon Horman @ 2011-05-19 12:32 UTC (permalink / raw)
To: lvs-devel, netdev, netfilter-devel, netfilter
Cc: Wensong Zhang, Julian Anastasov, Patrick McHardy,
Hans Schillstrom, Dave Jones, Pablo Neira Ayuso, Simon Horman
In-Reply-To: <1305808377-12255-1-git-send-email-horms@verge.net.au>
Reported-by: Dave Jones <davej@redhat.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/netfilter/ipvs/ip_vs_ctl.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 37890f2..9b9039b 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3774,6 +3774,7 @@ err_sock:
void ip_vs_control_cleanup(void)
{
EnterFunction(2);
+ unregister_netdevice_notifier(&ip_vs_dst_notifier);
ip_vs_genl_unregister();
nf_unregister_sockopt(&ip_vs_sockopts);
LeaveFunction(2);
--
1.7.4.4
^ permalink raw reply related
* [GIT PULL nf-2.6] IPVS
From: Simon Horman @ 2011-05-19 12:32 UTC (permalink / raw)
To: lvs-devel, netdev, netfilter-devel, netfilter
Cc: Wensong Zhang, Julian Anastasov, Patrick McHardy,
Hans Schillstrom, Dave Jones, Pablo Neira Ayuso
Hi Pablo, Hi Patrick,
please consider pulling
git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-2.6.git master
to get the following fix for IPVS.
I have based my tree on net-2.6 as it contains all of the IPVS patches -
currently some are in Patrick's tree and one of them is in Pablo's tree but
all of them are in Dave's tree.
Please feel free to apply the patch manually if that suits you better.
Simon Horman (1):
IPVS: Free resources on module removal
net/netfilter/ipvs/ip_vs_ctl.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
^ permalink raw reply
* (unknown)
From: Stella @ 2011-05-19 11:46 UTC (permalink / raw)
Please help me contact my lawyer. I got this
letter from Mrs. Helen saying you should contact
her lawyer for help, so that you can be her
beneficiary.
*************************************
Lawyer Contact Address
Barr. Morgan Owen
Email: bar.morganowen@yahoo.co.uk
*************************************
^ permalink raw reply
* (unknown)
From: Stella @ 2011-05-19 11:46 UTC (permalink / raw)
Please help me contact my lawyer. I got this
letter from Mrs. Helen saying you should contact
her lawyer for help, so that you can be her
beneficiary.
*************************************
Lawyer Contact Address
Barr. Morgan Owen
Email: bar.morganowen@yahoo.co.uk
*************************************
^ permalink raw reply
* (unknown)
From: Stella @ 2011-05-19 11:46 UTC (permalink / raw)
Please help me contact my lawyer. I got this
letter from Mrs. Helen saying you should contact
her lawyer for help, so that you can be her
beneficiary.
*************************************
Lawyer Contact Address
Barr. Morgan Owen
Email: bar.morganowen@yahoo.co.uk
*************************************
^ permalink raw reply
* (unknown)
From: Stella @ 2011-05-19 11:44 UTC (permalink / raw)
Please help me contact my lawyer. I got this
letter from Mrs. Helen saying you should contact
her lawyer for help, so that you can be her
beneficiary.
*************************************
Lawyer Contact Address
Barr. Morgan Owen
Email: bar.morganowen@yahoo.co.uk
*************************************
^ permalink raw reply
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