* Re: [PATCH]
From: Eric Dumazet @ 2013-09-26 15:53 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: Daniel Borkmann, netdev, davem, andy, fubar, vfalico
In-Reply-To: <52445553.1030308@redhat.com>
On Thu, 2013-09-26 at 17:40 +0200, Nikolay Aleksandrov wrote:
> >
> 1 question, I might be missing something but proto_ports_offset() gets the SPI
> with that 4 byte offset as is written in the comments, in every other case
> proto_ports_offset() is 0, so why would we want the SPI in the ->ports field ?
> And even then isn't it supposed to be 16 bits (2 bytes) and not 4, since we need
> to pass over "next header" (8 bits) and length (8 bits) ?
struct ip_auth_hdr {
__u8 nexthdr;
__u8 hdrlen; /* This one is measured in 32 bit units! */
__be16 reserved;
__be32 spi;
__be32 seq_no; /* Sequence number */
__u8 auth_data[0]; /* Variable len but >=4. Mind the 64 bit alignment! */
};
offsetof(spi, struct ...) = 4
^ permalink raw reply
* Re: [PATCH net-next v3 2/3] bonding: modify the old and add new xmit hash policies
From: Eric Dumazet @ 2013-09-26 16:02 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, davem, andy, fubar, vfalico
In-Reply-To: <1380204582-27144-3-git-send-email-nikolay@redhat.com>
On Thu, 2013-09-26 at 16:09 +0200, Nikolay Aleksandrov wrote:
> This patch adds two new hash policy modes which use skb_flow_dissect:
> 3 - Encapsulated layer 2+3
> 4 - Encapsulated layer 3+4
> There should be a good improvement for tunnel users in those modes.
> It also changes the old hash functions to:
> hash ^= (__force u32)flow.dst ^ (__force u32)flow.src;
> hash ^= (hash >> 16);
> hash ^= (hash >> 8);
>
> Where hash will be initialized either to L2 hash, that is
> SRCMAC[5] XOR DSTMAC[5], or to flow->ports which should be extracted
> from the upper layer. Flow's dst and src are also extracted based on the
> xmit policy either directly from the buffer or by using skb_flow_dissect,
> but in both cases if the protocol is IPv6 then dst and src are obtained by
> ipv6_addr_hash() on the real addresses. In case of a non-dissectable
> packet, the algorithms fall back to L2 hashing.
> The bond_set_mode_ops() function is now obsolete and thus deleted
> because it was used only to set the proper hash policy. Also we trim a
> pointer from struct bonding because we no longer need to keep the hash
> function, now there's only a single hash function - bond_xmit_hash that
> works based on bond->params.xmit_policy.
>
> The hash function and skb_flow_dissect were suggested by Eric Dumazet.
> The layer names were suggested by Andy Gospodarek, because I suck at
> semantics.
>
> Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
> ---
> v2: fix a bug in bond_flow_dissect which might've caused the use of
> uninitalized flow_keys and make use of skb_flow_get_ports
> v3: no change
> One line is intentionally left at 82 chars since it's the whole function
> and IMO looks better that way.
>
> drivers/net/bonding/bond_3ad.c | 2 +-
> drivers/net/bonding/bond_main.c | 197 ++++++++++++++-------------------------
> drivers/net/bonding/bond_sysfs.c | 2 -
> drivers/net/bonding/bonding.h | 3 +-
> include/uapi/linux/if_bonding.h | 2 +
> 5 files changed, 72 insertions(+), 134 deletions(-)
I love this patch, thanks for following up on this one.
Reviewed-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* Re: [PATCH] net: flow_dissector: fix thoff for IPPROTO_AH
From: Daniel Borkmann @ 2013-09-26 16:03 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Nikolay Aleksandrov, netdev, davem, andy, fubar, vfalico
In-Reply-To: <1380210246.3165.184.camel@edumazet-glaptop>
On 09/26/2013 05:44 PM, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> In commit 8ed781668dd49 ("flow_keys: include thoff into flow_keys for
> later usage"), we missed that existing code was using nhoff as a
> temporary variable that could not always contain transport header
> offset.
>
> This is not a problem for TCP/UDP because port offset (@poff)
> is 0 for these protocols.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Daniel Borkmann <dborkman@redhat.com>
> Cc: Nikolay Aleksandrov <nikolay@redhat.com>
Acked-by: Daniel Borkmann <dborkman@redhat.com>
Thanks !
> ---
> net/core/flow_dissector.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> index 1929af8..8d7d0dd 100644
> --- a/net/core/flow_dissector.c
> +++ b/net/core/flow_dissector.c
> @@ -154,8 +154,8 @@ ipv6:
> if (poff >= 0) {
> __be32 *ports, _ports;
>
> - nhoff += poff;
> - ports = skb_header_pointer(skb, nhoff, sizeof(_ports), &_ports);
> + ports = skb_header_pointer(skb, nhoff + poff,
> + sizeof(_ports), &_ports);
> if (ports)
> flow->ports = *ports;
> }
>
>
^ permalink raw reply
* Re: [PATCH] net: flow_dissector: fix thoff for IPPROTO_AH
From: Eric Dumazet @ 2013-09-26 16:05 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: Daniel Borkmann, netdev, davem, andy, fubar, vfalico
In-Reply-To: <5244575B.8060309@redhat.com>
On Thu, 2013-09-26 at 17:48 +0200, Nikolay Aleksandrov wrote:
>
> 1 question about my current patchset, can I leave it to get reviewed and if
> applied to post a follow-up for net-next that fixes the issue, or would you
> prefer a v4 that integrates the fix ?
I think your 1/3 patch only has to pass nhoff as value instead of
reference.
+__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto)
+{
+ int poff = proto_ports_offset(ip_proto);
+
+ if (poff >= 0) {
+ __be32 *ports, _ports;
+
+ ports = skb_header_pointer(skb, thoff + poff,
+ sizeof(_ports), &_ports);
+ if (ports)
+ return *ports;
+ }
+
+ return 0;
+}
^ permalink raw reply
* Re: [PATCH] net: flow_dissector: fix thoff for IPPROTO_AH
From: Nikolay Aleksandrov @ 2013-09-26 16:03 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Daniel Borkmann, netdev, davem, andy, fubar, vfalico
In-Reply-To: <1380211524.3165.192.camel@edumazet-glaptop>
On 09/26/2013 06:05 PM, Eric Dumazet wrote:
> On Thu, 2013-09-26 at 17:48 +0200, Nikolay Aleksandrov wrote:
>
>>
>> 1 question about my current patchset, can I leave it to get reviewed and if
>> applied to post a follow-up for net-next that fixes the issue, or would you
>> prefer a v4 that integrates the fix ?
>
> I think your 1/3 patch only has to pass nhoff as value instead of
> reference.
>
> +__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto)
> +{
> + int poff = proto_ports_offset(ip_proto);
> +
> + if (poff >= 0) {
> + __be32 *ports, _ports;
> +
> + ports = skb_header_pointer(skb, thoff + poff,
> + sizeof(_ports), &_ports);
> + if (ports)
> + return *ports;
> + }
> +
> + return 0;
> +}
>
>
Yeah, exactly but 2/3 will need a change as well because it uses the function.
I'll just re-post a v4 with the change in a bit.
Thanks
^ permalink raw reply
* Re: [PATCH] sh_eth: NAPI requires netif_receive_skb()
From: Guennadi Liakhovetski @ 2013-09-26 16:12 UTC (permalink / raw)
To: David Miller; +Cc: sergei.shtylyov, netdev, nobuhiro.iwamatsu.yj, linux-sh
In-Reply-To: <20130904.141252.532474080722830977.davem@davemloft.net>
Hi
On Wed, 4 Sep 2013, David Miller wrote:
> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Date: Tue, 3 Sep 2013 03:03:10 +0400
>
> > Driver supporting NAPI should use NAPI-specific function for receiving packets,
> > so netif_rx() should be changed to netif_receive_skb().
> >
> > Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
This patch breaks NFS boot on Armadillo800eva for me. Network
communication slows down to a crawl with
net eth0: Receive FIFO Overflow
nfs: server 192.168.x.y not responding, still trying
With this patch reverted (e.g. in today's Linus tree snapshot) boot is
restored.
Thanks
Guennadi
> Applied.
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* [PATCH net-next v4 0/3] bonding: modify the current and add new hash functions
From: Nikolay Aleksandrov @ 2013-09-26 16:13 UTC (permalink / raw)
To: netdev; +Cc: davem, andy, fubar, eric.dumazet, vfalico
Hi all,
This is a complete remake of my old patch that modified the bonding hash
functions to use skb_flow_dissect which was suggested by Eric Dumazet.
This time around I've left the old modes although using a new hash function
again suggested by Eric, which is the same for all modes. The only
difference is the way the headers are obtained. The old modes obtain them
as before in order to address concerns about speed, but the 2 new ones use
skb_flow_dissect. The unification of the hash function allows to remove a
pointer from struct bonding and also a few extra functions that dealt with
it. Two new functions are added which take care of the hashing based on
bond->params.xmit_policy only:
bond_xmit_hash() - global function, used by XOR and 3ad modes
bond_flow_dissect() - used by bond_xmit_hash() to obtain the necessary
headers and combine them according to bond->params.xmit_policy.
Also factor out the ports extraction from skb_flow_dissect and add a new
function - skb_flow_get_ports() which can be re-used.
v2: add the flow_dissector patch and use skb_flow_get_ports in patch 02
v3: fix a bug in the flow_dissector patch that caused a different thoff
by modifying the thoff argument in skb_flow_get_ports directly, most
of the users already do it anyway.
Also add the necessary export symbol for skb_flow_get_ports.
v4: integrate the thoff bug fix in patch 01
Best regards,
Nikolay Aleksandrov
Nikolay Aleksandrov (3):
flow_dissector: factor out the ports extraction in skb_flow_get_ports
bonding: modify the old and add new xmit hash policies
bonding: document the new xmit policy modes and update the changed
ones
Documentation/networking/bonding.txt | 66 ++++++------
drivers/net/bonding/bond_3ad.c | 2 +-
drivers/net/bonding/bond_main.c | 197 ++++++++++++-----------------------
drivers/net/bonding/bond_sysfs.c | 2 -
drivers/net/bonding/bonding.h | 3 +-
include/net/flow_keys.h | 1 +
include/uapi/linux/if_bonding.h | 2 +
net/core/flow_dissector.c | 39 +++++--
8 files changed, 137 insertions(+), 175 deletions(-)
--
1.8.1.4
^ permalink raw reply
* [PATCH net-next v4 2/3] bonding: modify the old and add new xmit hash policies
From: Nikolay Aleksandrov @ 2013-09-26 16:13 UTC (permalink / raw)
To: netdev; +Cc: davem, andy, fubar, eric.dumazet, vfalico
In-Reply-To: <1380212024-3417-1-git-send-email-nikolay@redhat.com>
This patch adds two new hash policy modes which use skb_flow_dissect:
3 - Encapsulated layer 2+3
4 - Encapsulated layer 3+4
There should be a good improvement for tunnel users in those modes.
It also changes the old hash functions to:
hash ^= (__force u32)flow.dst ^ (__force u32)flow.src;
hash ^= (hash >> 16);
hash ^= (hash >> 8);
Where hash will be initialized either to L2 hash, that is
SRCMAC[5] XOR DSTMAC[5], or to flow->ports which should be extracted
from the upper layer. Flow's dst and src are also extracted based on the
xmit policy either directly from the buffer or by using skb_flow_dissect,
but in both cases if the protocol is IPv6 then dst and src are obtained by
ipv6_addr_hash() on the real addresses. In case of a non-dissectable
packet, the algorithms fall back to L2 hashing.
The bond_set_mode_ops() function is now obsolete and thus deleted
because it was used only to set the proper hash policy. Also we trim a
pointer from struct bonding because we no longer need to keep the hash
function, now there's only a single hash function - bond_xmit_hash that
works based on bond->params.xmit_policy.
The hash function and skb_flow_dissect were suggested by Eric Dumazet.
The layer names were suggested by Andy Gospodarek, because I suck at
semantics.
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
---
v2: fix a bug in bond_flow_dissect which might've caused the use of
uninitalized flow_keys and make use of skb_flow_get_ports
v3, v4: no change
One line is intentionally left at 82 chars since it's the whole function
and IMO looks better that way.
drivers/net/bonding/bond_3ad.c | 2 +-
drivers/net/bonding/bond_main.c | 197 ++++++++++++++-------------------------
drivers/net/bonding/bond_sysfs.c | 2 -
drivers/net/bonding/bonding.h | 3 +-
include/uapi/linux/if_bonding.h | 2 +
5 files changed, 72 insertions(+), 134 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 0d8f427..b3ab703 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2442,7 +2442,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
goto out;
}
- slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg);
+ slave_agg_no = bond_xmit_hash(bond, skb, slaves_in_agg);
bond_for_each_slave(bond, slave) {
struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 55bbb8b..ef6d2f7 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -78,6 +78,7 @@
#include <net/netns/generic.h>
#include <net/pkt_sched.h>
#include <linux/rculist.h>
+#include <net/flow_keys.h>
#include "bonding.h"
#include "bond_3ad.h"
#include "bond_alb.h"
@@ -159,7 +160,8 @@ MODULE_PARM_DESC(min_links, "Minimum number of available links before turning on
module_param(xmit_hash_policy, charp, 0);
MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; "
"0 for layer 2 (default), 1 for layer 3+4, "
- "2 for layer 2+3");
+ "2 for layer 2+3, 3 for encap layer 2+3, "
+ "4 for encap layer 3+4");
module_param(arp_interval, int, 0);
MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
module_param_array(arp_ip_target, charp, NULL, 0);
@@ -217,6 +219,8 @@ const struct bond_parm_tbl xmit_hashtype_tbl[] = {
{ "layer2", BOND_XMIT_POLICY_LAYER2},
{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
+{ "encap2+3", BOND_XMIT_POLICY_ENCAP23},
+{ "encap3+4", BOND_XMIT_POLICY_ENCAP34},
{ NULL, -1},
};
@@ -3026,99 +3030,85 @@ static struct notifier_block bond_netdev_notifier = {
/*---------------------------- Hashing Policies -----------------------------*/
-/*
- * Hash for the output device based upon layer 2 data
- */
-static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)
+/* L2 hash helper */
+static inline u32 bond_eth_hash(struct sk_buff *skb)
{
struct ethhdr *data = (struct ethhdr *)skb->data;
if (skb_headlen(skb) >= offsetof(struct ethhdr, h_proto))
- return (data->h_dest[5] ^ data->h_source[5]) % count;
+ return data->h_dest[5] ^ data->h_source[5];
return 0;
}
-/*
- * Hash for the output device based upon layer 2 and layer 3 data. If
- * the packet is not IP, fall back on bond_xmit_hash_policy_l2()
- */
-static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
+/* Extract the appropriate headers based on bond's xmit policy */
+static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb,
+ struct flow_keys *fk)
{
- const struct ethhdr *data;
+ const struct ipv6hdr *iph6;
const struct iphdr *iph;
- const struct ipv6hdr *ipv6h;
- u32 v6hash;
- const __be32 *s, *d;
+ int noff, proto = -1;
- if (skb->protocol == htons(ETH_P_IP) &&
- pskb_network_may_pull(skb, sizeof(*iph))) {
+ if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23)
+ return skb_flow_dissect(skb, fk);
+
+ fk->ports = 0;
+ noff = skb_network_offset(skb);
+ if (skb->protocol == htons(ETH_P_IP)) {
+ if (!pskb_may_pull(skb, noff + sizeof(*iph)))
+ return false;
iph = ip_hdr(skb);
- data = (struct ethhdr *)skb->data;
- return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
- (data->h_dest[5] ^ data->h_source[5])) % count;
- } else if (skb->protocol == htons(ETH_P_IPV6) &&
- pskb_network_may_pull(skb, sizeof(*ipv6h))) {
- ipv6h = ipv6_hdr(skb);
- data = (struct ethhdr *)skb->data;
- s = &ipv6h->saddr.s6_addr32[0];
- d = &ipv6h->daddr.s6_addr32[0];
- v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]);
- v6hash ^= (v6hash >> 24) ^ (v6hash >> 16) ^ (v6hash >> 8);
- return (v6hash ^ data->h_dest[5] ^ data->h_source[5]) % count;
- }
-
- return bond_xmit_hash_policy_l2(skb, count);
+ fk->src = iph->saddr;
+ fk->dst = iph->daddr;
+ noff += iph->ihl << 2;
+ if (!ip_is_fragment(iph))
+ proto = iph->protocol;
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ if (!pskb_may_pull(skb, noff + sizeof(*iph6)))
+ return false;
+ iph6 = ipv6_hdr(skb);
+ fk->src = (__force __be32)ipv6_addr_hash(&iph6->saddr);
+ fk->dst = (__force __be32)ipv6_addr_hash(&iph6->daddr);
+ noff += sizeof(*iph6);
+ proto = iph6->nexthdr;
+ } else {
+ return false;
+ }
+ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34 && proto >= 0)
+ fk->ports = skb_flow_get_ports(skb, noff, proto);
+
+ return true;
}
-/*
- * Hash for the output device based upon layer 3 and layer 4 data. If
- * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
- * altogether not IP, fall back on bond_xmit_hash_policy_l2()
+/**
+ * bond_xmit_hash - generate a hash value based on the xmit policy
+ * @bond: bonding device
+ * @skb: buffer to use for headers
+ * @count: modulo value
+ *
+ * This function will extract the necessary headers from the skb buffer and use
+ * them to generate a hash based on the xmit_policy set in the bonding device
+ * which will be reduced modulo count before returning.
*/
-static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
+int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count)
{
- u32 layer4_xor = 0;
- const struct iphdr *iph;
- const struct ipv6hdr *ipv6h;
- const __be32 *s, *d;
- const __be16 *l4 = NULL;
- __be16 _l4[2];
- int noff = skb_network_offset(skb);
- int poff;
-
- if (skb->protocol == htons(ETH_P_IP) &&
- pskb_may_pull(skb, noff + sizeof(*iph))) {
- iph = ip_hdr(skb);
- poff = proto_ports_offset(iph->protocol);
+ struct flow_keys flow;
+ u32 hash;
- if (!ip_is_fragment(iph) && poff >= 0) {
- l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff,
- sizeof(_l4), &_l4);
- if (l4)
- layer4_xor = ntohs(l4[0] ^ l4[1]);
- }
- return (layer4_xor ^
- ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
- } else if (skb->protocol == htons(ETH_P_IPV6) &&
- pskb_may_pull(skb, noff + sizeof(*ipv6h))) {
- ipv6h = ipv6_hdr(skb);
- poff = proto_ports_offset(ipv6h->nexthdr);
- if (poff >= 0) {
- l4 = skb_header_pointer(skb, noff + sizeof(*ipv6h) + poff,
- sizeof(_l4), &_l4);
- if (l4)
- layer4_xor = ntohs(l4[0] ^ l4[1]);
- }
- s = &ipv6h->saddr.s6_addr32[0];
- d = &ipv6h->daddr.s6_addr32[0];
- layer4_xor ^= (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]);
- layer4_xor ^= (layer4_xor >> 24) ^ (layer4_xor >> 16) ^
- (layer4_xor >> 8);
- return layer4_xor % count;
- }
+ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 ||
+ !bond_flow_dissect(bond, skb, &flow))
+ return bond_eth_hash(skb) % count;
+
+ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23 ||
+ bond->params.xmit_policy == BOND_XMIT_POLICY_ENCAP23)
+ hash = bond_eth_hash(skb);
+ else
+ hash = (__force u32)flow.ports;
+ hash ^= (__force u32)flow.dst ^ (__force u32)flow.src;
+ hash ^= (hash >> 16);
+ hash ^= (hash >> 8);
- return bond_xmit_hash_policy_l2(skb, count);
+ return hash % count;
}
/*-------------------------- Device entry points ----------------------------*/
@@ -3700,8 +3690,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
return NETDEV_TX_OK;
}
-/*
- * In bond_xmit_xor() , we determine the output device by using a pre-
+/* In bond_xmit_xor() , we determine the output device by using a pre-
* determined xmit_hash_policy(), If the selected device is not enabled,
* find the next active slave.
*/
@@ -3709,8 +3698,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
- bond_xmit_slave_id(bond, skb,
- bond->xmit_hash_policy(skb, bond->slave_cnt));
+ bond_xmit_slave_id(bond, skb, bond_xmit_hash(bond, skb, bond->slave_cnt));
return NETDEV_TX_OK;
}
@@ -3746,22 +3734,6 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
/*------------------------- Device initialization ---------------------------*/
-static void bond_set_xmit_hash_policy(struct bonding *bond)
-{
- switch (bond->params.xmit_policy) {
- case BOND_XMIT_POLICY_LAYER23:
- bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
- break;
- case BOND_XMIT_POLICY_LAYER34:
- bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
- break;
- case BOND_XMIT_POLICY_LAYER2:
- default:
- bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
- break;
- }
-}
-
/*
* Lookup the slave that corresponds to a qid
*/
@@ -3871,38 +3843,6 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
return ret;
}
-/*
- * set bond mode specific net device operations
- */
-void bond_set_mode_ops(struct bonding *bond, int mode)
-{
- struct net_device *bond_dev = bond->dev;
-
- switch (mode) {
- case BOND_MODE_ROUNDROBIN:
- break;
- case BOND_MODE_ACTIVEBACKUP:
- break;
- case BOND_MODE_XOR:
- bond_set_xmit_hash_policy(bond);
- break;
- case BOND_MODE_BROADCAST:
- break;
- case BOND_MODE_8023AD:
- bond_set_xmit_hash_policy(bond);
- break;
- case BOND_MODE_ALB:
- /* FALLTHRU */
- case BOND_MODE_TLB:
- break;
- default:
- /* Should never happen, mode already checked */
- pr_err("%s: Error: Unknown bonding mode %d\n",
- bond_dev->name, mode);
- break;
- }
-}
-
static int bond_ethtool_get_settings(struct net_device *bond_dev,
struct ethtool_cmd *ecmd)
{
@@ -4004,7 +3944,6 @@ static void bond_setup(struct net_device *bond_dev)
ether_setup(bond_dev);
bond_dev->netdev_ops = &bond_netdev_ops;
bond_dev->ethtool_ops = &bond_ethtool_ops;
- bond_set_mode_ops(bond, bond->params.mode);
bond_dev->destructor = bond_destructor;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index c29b836..dba3b9b 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -352,7 +352,6 @@ static ssize_t bonding_store_mode(struct device *d,
/* don't cache arp_validate between modes */
bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
bond->params.mode = new_value;
- bond_set_mode_ops(bond, bond->params.mode);
pr_info("%s: setting mode to %s (%d).\n",
bond->dev->name, bond_mode_tbl[new_value].modename,
new_value);
@@ -392,7 +391,6 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
ret = -EINVAL;
} else {
bond->params.xmit_policy = new_value;
- bond_set_mode_ops(bond, bond->params.mode);
pr_info("%s: setting xmit hash policy to %s (%d).\n",
bond->dev->name,
xmit_hashtype_tbl[new_value].modename, new_value);
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 03cf3fd..4db9ec4 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -245,7 +245,6 @@ struct bonding {
char proc_file_name[IFNAMSIZ];
#endif /* CONFIG_PROC_FS */
struct list_head bond_list;
- int (*xmit_hash_policy)(struct sk_buff *, int);
u16 rr_tx_counter;
struct ad_bond_info ad_info;
struct alb_bond_info alb_info;
@@ -446,7 +445,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
void bond_mii_monitor(struct work_struct *);
void bond_loadbalance_arp_mon(struct work_struct *);
void bond_activebackup_arp_mon(struct work_struct *);
-void bond_set_mode_ops(struct bonding *bond, int mode);
+int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count);
int bond_parse_parm(const char *mode_arg, const struct bond_parm_tbl *tbl);
void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
diff --git a/include/uapi/linux/if_bonding.h b/include/uapi/linux/if_bonding.h
index a17edda..9635a62 100644
--- a/include/uapi/linux/if_bonding.h
+++ b/include/uapi/linux/if_bonding.h
@@ -91,6 +91,8 @@
#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */
#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */
#define BOND_XMIT_POLICY_LAYER23 2 /* layer 2+3 (IP ^ MAC) */
+#define BOND_XMIT_POLICY_ENCAP23 3 /* encapsulated layer 2+3 */
+#define BOND_XMIT_POLICY_ENCAP34 4 /* encapsulated layer 3+4 */
typedef struct ifbond {
__s32 bond_mode;
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next v4 3/3] bonding: document the new xmit policy modes and update the changed ones
From: Nikolay Aleksandrov @ 2013-09-26 16:13 UTC (permalink / raw)
To: netdev; +Cc: davem, andy, fubar, eric.dumazet, vfalico
In-Reply-To: <1380212024-3417-1-git-send-email-nikolay@redhat.com>
Add new documentation for encap2+3 and encap3+4, also update the formula
for the old modes due to the changes.
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
---
v2, v3, v4: no change
Documentation/networking/bonding.txt | 66 ++++++++++++++++++++----------------
1 file changed, 36 insertions(+), 30 deletions(-)
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 9b28e71..3856ed2 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -743,21 +743,16 @@ xmit_hash_policy
protocol information to generate the hash.
Uses XOR of hardware MAC addresses and IP addresses to
- generate the hash. The IPv4 formula is
+ generate the hash. The formula is
- (((source IP XOR dest IP) AND 0xffff) XOR
- ( source MAC XOR destination MAC ))
- modulo slave count
+ hash = source MAC XOR destination MAC
+ hash = hash XOR source IP XOR destination IP
+ hash = hash XOR (hash RSHIFT 16)
+ hash = hash XOR (hash RSHIFT 8)
+ And then hash is reduced modulo slave count.
- The IPv6 formula is
-
- hash = (source ip quad 2 XOR dest IP quad 2) XOR
- (source ip quad 3 XOR dest IP quad 3) XOR
- (source ip quad 4 XOR dest IP quad 4)
-
- (((hash >> 24) XOR (hash >> 16) XOR (hash >> 8) XOR hash)
- XOR (source MAC XOR destination MAC))
- modulo slave count
+ If the protocol is IPv6 then the source and destination
+ addresses are first hashed using ipv6_addr_hash.
This algorithm will place all traffic to a particular
network peer on the same slave. For non-IP traffic,
@@ -779,21 +774,16 @@ xmit_hash_policy
slaves, although a single connection will not span
multiple slaves.
- The formula for unfragmented IPv4 TCP and UDP packets is
-
- ((source port XOR dest port) XOR
- ((source IP XOR dest IP) AND 0xffff)
- modulo slave count
+ The formula for unfragmented TCP and UDP packets is
- The formula for unfragmented IPv6 TCP and UDP packets is
+ hash = source port, destination port (as in the header)
+ hash = hash XOR source IP XOR destination IP
+ hash = hash XOR (hash RSHIFT 16)
+ hash = hash XOR (hash RSHIFT 8)
+ And then hash is reduced modulo slave count.
- hash = (source port XOR dest port) XOR
- ((source ip quad 2 XOR dest IP quad 2) XOR
- (source ip quad 3 XOR dest IP quad 3) XOR
- (source ip quad 4 XOR dest IP quad 4))
-
- ((hash >> 24) XOR (hash >> 16) XOR (hash >> 8) XOR hash)
- modulo slave count
+ If the protocol is IPv6 then the source and destination
+ addresses are first hashed using ipv6_addr_hash.
For fragmented TCP or UDP packets and all other IPv4 and
IPv6 protocol traffic, the source and destination port
@@ -801,10 +791,6 @@ xmit_hash_policy
formula is the same as for the layer2 transmit hash
policy.
- The IPv4 policy is intended to mimic the behavior of
- certain switches, notably Cisco switches with PFC2 as
- well as some Foundry and IBM products.
-
This algorithm is not fully 802.3ad compliant. A
single TCP or UDP conversation containing both
fragmented and unfragmented packets will see packets
@@ -815,6 +801,26 @@ xmit_hash_policy
conversations. Other implementations of 802.3ad may
or may not tolerate this noncompliance.
+ encap2+3
+
+ This policy uses the same formula as layer2+3 but it
+ relies on skb_flow_dissect to obtain the header fields
+ which might result in the use of inner headers if an
+ encapsulation protocol is used. For example this will
+ improve the performance for tunnel users because the
+ packets will be distributed according to the encapsulated
+ flows.
+
+ encap3+4
+
+ This policy uses the same formula as layer3+4 but it
+ relies on skb_flow_dissect to obtain the header fields
+ which might result in the use of inner headers if an
+ encapsulation protocol is used. For example this will
+ improve the performance for tunnel users because the
+ packets will be distributed according to the encapsulated
+ flows.
+
The default value is layer2. This option was added in bonding
version 2.6.3. In earlier versions of bonding, this parameter
does not exist, and the layer2 policy is the only policy. The
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next v4 1/3] flow_dissector: factor out the ports extraction in skb_flow_get_ports
From: Nikolay Aleksandrov @ 2013-09-26 16:13 UTC (permalink / raw)
To: netdev; +Cc: davem, andy, fubar, eric.dumazet, vfalico
In-Reply-To: <1380212024-3417-1-git-send-email-nikolay@redhat.com>
Factor out the code that extracts the ports from skb_flow_dissect and
add a new function skb_flow_get_ports which can be re-used.
Also fix a bug that caused thoff to be wrong in the AH case, spotted
by Eric Dumazet.
Suggested-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
---
v2: new patch
v3: fix a bug in skb_flow_dissect where thoff didn't have poff added by
modifying thoff directly in skb_flow_get_ports as it's done anyway.
Also add the necessary export symbol for skb_flow_get_ports.
v4: integrate the thoff fix in skb_flow_get_ports
This seems like a good idea because there're other users that can re-use
it later as well.
include/net/flow_keys.h | 1 +
net/core/flow_dissector.c | 39 ++++++++++++++++++++++++++++-----------
2 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/include/net/flow_keys.h b/include/net/flow_keys.h
index ac2439d..7e64bd8 100644
--- a/include/net/flow_keys.h
+++ b/include/net/flow_keys.h
@@ -14,4 +14,5 @@ struct flow_keys {
};
bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow);
+__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto);
#endif
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 1929af8..ec9919b 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -25,9 +25,35 @@ static void iph_to_flow_copy_addrs(struct flow_keys *flow, const struct iphdr *i
memcpy(&flow->src, &iph->saddr, sizeof(flow->src) + sizeof(flow->dst));
}
+/**
+ * skb_flow_get_ports - extract the upper layer ports and return them
+ * @skb: buffer to extract the ports from
+ * @thoff: transport header offset
+ * @ip_proto: protocol for which to get port offset
+ *
+ * The function will try to retrieve the ports at offset thoff + poff where poff
+ * is the protocol port offset returned from proto_ports_offset
+ */
+__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto)
+{
+ int poff = proto_ports_offset(ip_proto);
+
+ if (poff >= 0) {
+ __be32 *ports, _ports;
+
+ ports = skb_header_pointer(skb, thoff + poff, sizeof(_ports),
+ &_ports);
+ if (ports)
+ return *ports;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(skb_flow_get_ports);
+
bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow)
{
- int poff, nhoff = skb_network_offset(skb);
+ int nhoff = skb_network_offset(skb);
u8 ip_proto;
__be16 proto = skb->protocol;
@@ -150,16 +176,7 @@ ipv6:
}
flow->ip_proto = ip_proto;
- poff = proto_ports_offset(ip_proto);
- if (poff >= 0) {
- __be32 *ports, _ports;
-
- nhoff += poff;
- ports = skb_header_pointer(skb, nhoff, sizeof(_ports), &_ports);
- if (ports)
- flow->ports = *ports;
- }
-
+ flow->ports = skb_flow_get_ports(skb, nhoff, ip_proto);
flow->thoff = (u16) nhoff;
return true;
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH net-next v4 1/3] flow_dissector: factor out the ports extraction in skb_flow_get_ports
From: Eric Dumazet @ 2013-09-26 16:33 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, davem, andy, fubar, vfalico
In-Reply-To: <1380212024-3417-2-git-send-email-nikolay@redhat.com>
On Thu, 2013-09-26 at 18:13 +0200, Nikolay Aleksandrov wrote:
> flow->ip_proto = ip_proto;
> - poff = proto_ports_offset(ip_proto);
> - if (poff >= 0) {
> - __be32 *ports, _ports;
> -
> - nhoff += poff;
> - ports = skb_header_pointer(skb, nhoff, sizeof(_ports), &_ports);
> - if (ports)
> - flow->ports = *ports;
> - }
> -
> + flow->ports = skb_flow_get_ports(skb, nhoff, ip_proto);
> flow->thoff = (u16) nhoff;
>
> return true;
The best way is to ask David to apply my fix in net tree, then your
patch will be on top of it.
Mixing a fix and a factoring seems not right.
^ permalink raw reply
* Re: [PATCH net-next v4 1/3] flow_dissector: factor out the ports extraction in skb_flow_get_ports
From: Nikolay Aleksandrov @ 2013-09-26 16:35 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, davem, andy, fubar, vfalico
In-Reply-To: <1380213202.3165.195.camel@edumazet-glaptop>
On 09/26/2013 06:33 PM, Eric Dumazet wrote:
> On Thu, 2013-09-26 at 18:13 +0200, Nikolay Aleksandrov wrote:
>
>> flow->ip_proto = ip_proto;
>> - poff = proto_ports_offset(ip_proto);
>> - if (poff >= 0) {
>> - __be32 *ports, _ports;
>> -
>> - nhoff += poff;
>> - ports = skb_header_pointer(skb, nhoff, sizeof(_ports), &_ports);
>> - if (ports)
>> - flow->ports = *ports;
>> - }
>> -
>> + flow->ports = skb_flow_get_ports(skb, nhoff, ip_proto);
>> flow->thoff = (u16) nhoff;
>>
>> return true;
>
>
>
> The best way is to ask David to apply my fix in net tree, then your
> patch will be on top of it.
>
> Mixing a fix and a factoring seems not right.
>
>
Ah, okay, sorry about that, I'm hurrying again :-)
Dave would you apply Eric's fix in the net-next tree ?
I'll then re-base on it.
Thanks,
Nik
^ permalink raw reply
* Re: [PATCH] sh_eth: NAPI requires netif_receive_skb()
From: Eric Dumazet @ 2013-09-26 16:59 UTC (permalink / raw)
To: Guennadi Liakhovetski
Cc: David Miller, sergei.shtylyov, netdev, nobuhiro.iwamatsu.yj,
linux-sh
In-Reply-To: <Pine.LNX.4.64.1309261751200.11968@axis700.grange>
On Thu, 2013-09-26 at 18:12 +0200, Guennadi Liakhovetski wrote:
> Hi
>
> On Wed, 4 Sep 2013, David Miller wrote:
>
> > From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> > Date: Tue, 3 Sep 2013 03:03:10 +0400
> >
> > > Driver supporting NAPI should use NAPI-specific function for receiving packets,
> > > so netif_rx() should be changed to netif_receive_skb().
> > >
> > > Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>
> This patch breaks NFS boot on Armadillo800eva for me. Network
> communication slows down to a crawl with
>
> net eth0: Receive FIFO Overflow
> nfs: server 192.168.x.y not responding, still trying
>
> With this patch reverted (e.g. in today's Linus tree snapshot) boot is
> restored.
RX_RING_SIZE is 64
This driver refills the Rx ring buffers only _after_ the loop to drain
ready buffers. This was OK with the previous behavior (netif_rx() is
damn fast)
With this low amount of buffers, underrun can happen with the new code,
as netif_receive_skb() adds delay during the drain.
Most likely driver needs to refill buffers one by one (or small batches)
instead of in one go after the drain.
^ permalink raw reply
* Re: rx_dropped count for USB ethernet interfaces
From: David Miller @ 2013-09-26 17:21 UTC (permalink / raw)
To: David.Laight; +Cc: netdev
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B735E@saturn3.aculab.com>
From: "David Laight" <David.Laight@ACULAB.COM>
Date: Thu, 26 Sep 2013 10:32:24 +0100
> It isn't exactly useful behaviour though.
In your opinion.
We have tracepoints for people who want more fine grained drops
in these kinds of situations.
Also, the behavior of this statistic has existed for more than a
decade so changing it is really not in the cards. Therefore any
discussion about what would have been the best samentic to choose from
the beginning is moot.
^ permalink raw reply
* Re: [PATCH 00/11 - GIT PULL] drivers: net: Last block of Remove extern from function prototypes
From: David Miller @ 2013-09-26 17:44 UTC (permalink / raw)
To: joe
Cc: netdev, linux-kernel, wimax, ath10k, linux-wireless, ath9k-devel,
brcm80211-dev-list
In-Reply-To: <cover.1380137609.git.joe@perches.com>
From: Joe Perches <joe@perches.com>
Date: Wed, 25 Sep 2013 12:37:18 -0700
> The following changes since commit 294da3abaa73a0b69fd54e442b0b5bd9455b7be6:
>
> irda: Remove extern from function prototypes (2013-09-24 12:54:17 -0700)
>
> are available in the git repository at:
>
> git://repo.or.cz/linux-2.6/trivial-mods.git 20130925_dn_externs_3
>
> for you to fetch changes up to a958df5dc3065ce517726dc54087639e13ffee8f:
>
> rtlwifi: Remove extern from function prototypes (2013-09-24 18:06:51 -0700)
Pulled, thanks Joe.
That should be about it for networking right?
^ permalink raw reply
* Re: [PATCH net-next] net: neighbour: use source address of last enqueued packet for solicitation
From: David Miller @ 2013-09-26 17:46 UTC (permalink / raw)
To: hannes; +Cc: netdev, ja
In-Reply-To: <20130921043234.GA13307@order.stressinduktion.org>
From: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date: Sat, 21 Sep 2013 06:32:34 +0200
> Currently we always use the first member of the arp_queue to determine
> the sender ip address of the arp packet (or in case of IPv6 - source
> address of the ndisc packet). This skb is fixed as long as the queue is
> not drained by a complete purge because of a timeout or by a successful
> response.
>
> If the first packet enqueued on the arp_queue is from a local application
> with a manually set source address and the to be discovered system
> does some kind of uRPF checks on the source address in the arp packet
> the resolving process hangs until a timeout and restarts. This hurts
> communication with the participating network node.
>
> This could be mitigated a bit if we use the latest enqueued skb's
> source address for the resolving process, which is not as static as
> the arp_queue's head. This change of the source address could result in
> better recovery of a failed solicitation.
>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Julian Anastasov <ja@ssi.bg>
> Reviewed-by: Julian Anastasov <ja@ssi.bg>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Applied, but honestly I think the tail packet has just as much chance
to come from an application with a manually set source address as
the head one.
^ permalink raw reply
* Re: [PATCH 00/11 - GIT PULL] drivers: net: Last block of Remove extern from function prototypes
From: Joe Perches @ 2013-09-26 18:02 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, wimax-BPSAo7wm5JOHVYUYWc+uSQ,
ath10k-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
ath9k-devel-juf53994utBLZpfksSYvnA,
brcm80211-dev-list-dY08KVG/lbpWk0Htik3J/w
In-Reply-To: <20130926.134408.91633054642517467.davem-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Thu, 2013-09-26 at 13:44 -0400, David Miller wrote:
> From: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
> Date: Wed, 25 Sep 2013 12:37:18 -0700
[]
> Pulled, thanks Joe.
> That should be about it for networking right?
Yes for drivers/net/...
There are some more files like:
include/linux/etherdevice.h
include/linux/inetdevice.h
include/linux/net.h
include/linux/netdevice.h
include/linux/skbuff.h
and some netfilter ones:
include/linux/netfilter*.h
include/linux/netfilter/...
and maybe a few others like:
include/linux/atmdev.h
include/linux/fddidevice.h
that I was planning on converting then submitting.
Want those in one more pull request or
maybe individually?
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net 2/2] ip_tunnel: Add fallback tunnels to the hash lists
From: Pravin Shelar @ 2013-09-26 18:24 UTC (permalink / raw)
To: Steffen Klassert; +Cc: David Miller, netdev
In-Reply-To: <20130926081344.GA7660@secunet.com>
On Thu, Sep 26, 2013 at 1:13 AM, Steffen Klassert
<steffen.klassert@secunet.com> wrote:
> On Wed, Sep 25, 2013 at 09:03:11AM -0700, Pravin Shelar wrote:
>> On Tue, Sep 24, 2013 at 10:55 PM, Steffen Klassert
>> <steffen.klassert@secunet.com> wrote:
>> > Currently we can not update the tunnel parameters of
>> > the fallback tunnels because we don't find them in the
>> > hash lists. Fix this by adding them on initialization.
>> >
>> > Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
>> > ---
>> > net/ipv4/ip_tunnel.c | 4 +++-
>> > 1 file changed, 3 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
>> > index b8ce640..f2348f2 100644
>> > --- a/net/ipv4/ip_tunnel.c
>> > +++ b/net/ipv4/ip_tunnel.c
>> > @@ -853,8 +853,10 @@ int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
>> > /* FB netdevice is special: we have one, and only one per netns.
>> > * Allowing to move it to another netns is clearly unsafe.
>> > */
>> > - if (!IS_ERR(itn->fb_tunnel_dev))
>> > + if (!IS_ERR(itn->fb_tunnel_dev)) {
>> > itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
>> > + ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
>> > + }
>> > rtnl_unlock();
>> >
>> fallback tunnel s not required to be in hash table, Its is returned if
>> none of hashed tunnels are matched, ref ip_tunnel_lookup().
>> Can you post command to reproduce this issue?
>>
>
> Something like
>
> ip tunnel change tunl0 mode ipip remote 0.0.0.0 local 0.0.0.0 ttl 0 tos 1
>
> worked until v3.9 and stopped working with v3.10.
OK, I see the bug, tunnel exact match lookup does not check fb tunnel.
There are two options.
1. Fix ip_tunnel_find() to check for fb tunnel.
2. Add fb tunnel to hash table, which is what ur patch does.
I think your patch is better solution as it get rid of special case.
But patch is not complete. It needs to remove fb tunnel checks on
netdev unregister.
^ permalink raw reply
* Re: [PATCH net 1/2] ip_tunnel: Fix a memory corruption in ip_tunnel_xmit
From: Pravin Shelar @ 2013-09-26 18:25 UTC (permalink / raw)
To: Steffen Klassert; +Cc: David Miller, netdev
In-Reply-To: <20130926082552.GB7660@secunet.com>
On Thu, Sep 26, 2013 at 1:25 AM, Steffen Klassert
<steffen.klassert@secunet.com> wrote:
> On Wed, Sep 25, 2013 at 09:55:50AM -0700, Pravin Shelar wrote:
>> On Tue, Sep 24, 2013 at 10:54 PM, Steffen Klassert
>> <steffen.klassert@secunet.com> wrote:
>> > We might extend the used aera of a skb beyond the total
>> > headroom when we install the ipip header. Fix this by
>> > calling skb_cow_head() unconditionally.
>> >
>> It is better to call skb_cow_head() from ipip_tunnel_xmit() as it is
>> consistent with gre.
>
> I think this would just move the bug from ipip to gre. ipgre_xmit()
> uses dev->needed_headroom which is based on the guessed output device
> in ip_tunnel_bind_dev(). If the device we get from the route lookup
> in ip_tunnel_xmit() is different from the guessed one and the resulting
> max_headroom is bigger than dev->needed_headroom, we run into that bug
> because skb_cow_head() will not be called with the updated
> dev->needed_headroom.
>
Thats why ip_tunnel_xmit() update dev->needed_headroom.
Just to be clear I was talking abt calling skb_cow_head with
dev->needed_headroom in ipip_xmit and leave ip_tunnel_xmit as it is.
So that most of cases we will not need to adjust headroom in ip_tunnel
xmit.
^ permalink raw reply
* [PATCH 3/7] rtlwifi: rtl8192ce: Convert driver to use new rtl_phy_scan_operation_backup() routine
From: Larry Finger @ 2013-09-26 18:25 UTC (permalink / raw)
To: linville-2XuSBdqkA4R54TAoqtyWWQ
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, Larry Finger,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1380219933-16784-1-git-send-email-Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
Now that rtl_phy_scan_operation_backup() exists, convert rtl8192ce to use it.
Signed-off-by: Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
---
drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 1 -
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 3 ++-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
index bb319b0..ff32b5b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
@@ -202,7 +202,6 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel);
void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm);
-void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 1420356..b790320 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -30,6 +30,7 @@
#include "../wifi.h"
#include "../core.h"
#include "../pci.h"
+#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
@@ -219,7 +220,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
.set_bw_mode = rtl92c_phy_set_bw_mode,
.switch_channel = rtl92c_phy_sw_chnl,
.dm_watchdog = rtl92c_dm_watchdog,
- .scan_operation_backup = rtl92c_phy_scan_operation_backup,
+ .scan_operation_backup = rtl_phy_scan_operation_backup,
.set_rf_power_state = rtl92c_phy_set_rf_power_state,
.led_control = rtl92ce_led_control,
.set_desc = rtl92ce_set_desc,
--
1.8.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/7] rtlwifi: Implement a common rtl_phy_scan_operation_backup() routine
From: Larry Finger @ 2013-09-26 18:25 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Larry Finger, netdev
In-Reply-To: <1380219933-16784-1-git-send-email-Larry.Finger@lwfinger.net>
Several of the drivers supported by rtlwifi individually implement the same
routine that supports scans. As a first step, create this routine in
driver rtlwifi.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/net/wireless/rtlwifi/base.c | 29 +++++++++++++++++++++++++++++
drivers/net/wireless/rtlwifi/base.h | 1 +
2 files changed, 30 insertions(+)
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 8bb4a9a..9a78e3d 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -1613,6 +1613,35 @@ err_free:
}
EXPORT_SYMBOL(rtl_send_smps_action);
+void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ enum io_type iotype;
+
+ if (!is_hal_stop(rtlhal)) {
+ switch (operation) {
+ case SCAN_OPT_BACKUP:
+ iotype = IO_CMD_PAUSE_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+ break;
+ case SCAN_OPT_RESTORE:
+ iotype = IO_CMD_RESUME_DM_BY_SCAN;
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_IO_CMD,
+ (u8 *)&iotype);
+ break;
+ default:
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ "Unknown Scan Backup operation.\n");
+ break;
+ }
+ }
+}
+EXPORT_SYMBOL(rtl_phy_scan_operation_backup);
+
/* There seem to be issues in mac80211 regarding when del ba frames can be
* received. As a work around, we make a fake del_ba if we receive a ba_req;
* however, rx_agg was opened to let mac80211 release some ba related
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index c07f114..0cd0742 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -152,5 +152,6 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw,
u8 *sa, u8 *bssid, u16 tid);
+void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
#endif
--
1.8.1.4
^ permalink raw reply related
* [PATCH 2/7] rtlwifi: rtl8192cu: Convert to use new rtl_phy_scan_operation_backup() routine
From: Larry Finger @ 2013-09-26 18:25 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Larry Finger, netdev
In-Reply-To: <1380219933-16784-1-git-send-email-Larry.Finger@lwfinger.net>
Now that the routine exists in driver rtlwifi, convert rtl8192cu to use it.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 2bd5985..9936de7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -31,6 +31,7 @@
#include "../core.h"
#include "../usb.h"
#include "../efuse.h"
+#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
@@ -117,7 +118,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
.set_bw_mode = rtl92c_phy_set_bw_mode,
.switch_channel = rtl92c_phy_sw_chnl,
.dm_watchdog = rtl92c_dm_watchdog,
- .scan_operation_backup = rtl92c_phy_scan_operation_backup,
+ .scan_operation_backup = rtl_phy_scan_operation_backup,
.set_rf_power_state = rtl92cu_phy_set_rf_power_state,
.led_control = rtl92cu_led_control,
.enable_hw_sec = rtl92cu_enable_hw_security_config,
--
1.8.1.4
^ permalink raw reply related
* [PATCH 0/7] Convert drivers to a common rtl_phy_scan_operation_backup() routine
From: Larry Finger @ 2013-09-26 18:25 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Larry Finger, netdev
Several of the driver implement this routine using the same code. This set
of patches creates a common routine in driver rtlwifi, converts each of the
drivers to use the new routine, and then deletes the now unused old code.
These patches rely on two prerequisite patches:
[PATCH 11/11] rtlwifi: Remove extern from function prototypes by Joe Perches
TCH] rtlwifi: remove duplicate declarations and macros in headers by Catalin Iacob
None of these patches fix any bugs. They merely reduce the size of the source code,
thus they need no particular priority.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
Larry Finger (7):
rtlwifi: Implement a common rtl_phy_scan_operation_backup() routine
rtlwifi: rtl8192cu: Convert to use new rtl_phy_scan_operation_backup()
routine
rtlwifi: rtl8192ce: Convert driver to use new
rtl_phy_scan_operation_backup() routine
rtlwifi: rtl8192c: Remove rtl8192c_phy_scan_operation_backup()
rtlwifi: rtl8192ce: Convert driver to use new
rtl_phy_scan_operation_backup() routine
rtlwifi: rtl8723ae: Convert driver to use new
rtl_phy_scan_operation_backup() routine
rtlwifi: rtl8188ee: Convert driver to use new
rtl_phy_scan_operation_backup() routine
drivers/net/wireless/rtlwifi/base.c | 29 +++++++++++++++++++++
drivers/net/wireless/rtlwifi/base.h | 1 +
drivers/net/wireless/rtlwifi/rtl8188ee/phy.c | 28 --------------------
drivers/net/wireless/rtlwifi/rtl8188ee/phy.h | 1 -
drivers/net/wireless/rtlwifi/rtl8188ee/sw.c | 3 ++-
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 30 ----------------------
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | 2 --
drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 1 -
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 3 ++-
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 3 ++-
drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 28 --------------------
drivers/net/wireless/rtlwifi/rtl8192de/phy.h | 1 -
drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 3 ++-
drivers/net/wireless/rtlwifi/rtl8723ae/phy.c | 29 ---------------------
drivers/net/wireless/rtlwifi/rtl8723ae/phy.h | 1 -
drivers/net/wireless/rtlwifi/rtl8723ae/sw.c | 3 ++-
16 files changed, 40 insertions(+), 126 deletions(-)
--
1.8.1.4
^ permalink raw reply
* [PATCH 4/7] rtlwifi: rtl8192c: Remove rtl8192c_phy_scan_operation_backup()
From: Larry Finger @ 2013-09-26 18:25 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Larry Finger, netdev
In-Reply-To: <1380219933-16784-1-git-send-email-Larry.Finger@lwfinger.net>
Drivers rtl8192ce and rtl8192cu no longer rely on this routine. It is removed.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 30 ----------------------
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | 2 --
2 files changed, 32 deletions(-)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
index 246e535..0c0e782 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
@@ -592,36 +592,6 @@ long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm);
-void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- enum io_type iotype;
-
- if (!is_hal_stop(rtlhal)) {
- switch (operation) {
- case SCAN_OPT_BACKUP:
- iotype = IO_CMD_PAUSE_DM_BY_SCAN;
- rtlpriv->cfg->ops->set_hw_reg(hw,
- HW_VAR_IO_CMD,
- (u8 *)&iotype);
-
- break;
- case SCAN_OPT_RESTORE:
- iotype = IO_CMD_RESUME_DM_BY_SCAN;
- rtlpriv->cfg->ops->set_hw_reg(hw,
- HW_VAR_IO_CMD,
- (u8 *)&iotype);
- break;
- default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- "Unknown Scan Backup operation\n");
- break;
- }
- }
-}
-EXPORT_SYMBOL(rtl92c_phy_scan_operation_backup);
-
void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type)
{
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
index 24957e2..e79dabe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
@@ -203,8 +203,6 @@ void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
long power_indbm);
-void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
- u8 operation);
void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
--
1.8.1.4
^ permalink raw reply related
* [PATCH 5/7] rtlwifi: rtl8192ce: Convert driver to use new rtl_phy_scan_operation_backup() routine
From: Larry Finger @ 2013-09-26 18:25 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Larry Finger, netdev
In-Reply-To: <1380219933-16784-1-git-send-email-Larry.Finger@lwfinger.net>
Now that rtl_phy_scan_operation_backup() exists, convert rtl8192de to use it.
Routine rtl92d_phy_scan_operation_backup() is no longer used and is removed.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 28 ----------------------------
drivers/net/wireless/rtlwifi/rtl8192de/phy.h | 1 -
drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 3 ++-
3 files changed, 2 insertions(+), 30 deletions(-)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
index 840bac5..13196cc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
@@ -1022,34 +1022,6 @@ void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
}
-void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
- enum io_type iotype;
-
- if (!is_hal_stop(rtlhal)) {
- switch (operation) {
- case SCAN_OPT_BACKUP:
- rtlhal->current_bandtypebackup =
- rtlhal->current_bandtype;
- iotype = IO_CMD_PAUSE_DM_BY_SCAN;
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
- (u8 *)&iotype);
- break;
- case SCAN_OPT_RESTORE:
- iotype = IO_CMD_RESUME_DM_BY_SCAN;
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
- (u8 *)&iotype);
- break;
- default:
- RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
- "Unknown Scan Backup operation\n");
- break;
- }
- }
-}
-
void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type)
{
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
index 8f07606..33df0d1c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
@@ -139,7 +139,6 @@ bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
enum radio_path rfpath);
void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
-void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
enum nl80211_channel_type ch_type);
u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index c18c04b..edab5a5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -30,6 +30,7 @@
#include "../wifi.h"
#include "../core.h"
#include "../pci.h"
+#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
@@ -236,7 +237,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = {
.set_bw_mode = rtl92d_phy_set_bw_mode,
.switch_channel = rtl92d_phy_sw_chnl,
.dm_watchdog = rtl92d_dm_watchdog,
- .scan_operation_backup = rtl92d_phy_scan_operation_backup,
+ .scan_operation_backup = rtl_phy_scan_operation_backup,
.set_rf_power_state = rtl92d_phy_set_rf_power_state,
.led_control = rtl92de_led_control,
.set_desc = rtl92de_set_desc,
--
1.8.1.4
^ 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