* Re: [PATCH net-next v6 1/1] ipv6: add support of equal cost multipath (ECMP)
From: Eric Dumazet @ 2012-10-02 16:14 UTC (permalink / raw)
To: nicolas.dichtel; +Cc: joe, bernat, netdev, yoshfuji, davem
In-Reply-To: <506B1104.7030908@6wind.com>
On Tue, 2012-10-02 at 18:06 +0200, Nicolas Dichtel wrote:
> I forget to run checkpatch.pl, some lines are over 80 columns. I will fix it in
> the v7 with other comments (if any).
> --
Yep, please reorder :
@@ -98,6 +100,15 @@ struct rt6_info {
struct fib6_node *rt6i_node;
struct in6_addr rt6i_gateway;
+#ifdef CONFIG_IPV6_MULTIPATH
+ /*
+ * siblings is a list of rt6_info that have the the same metric/weight,
+ * destination, but not the same gateway. nsiblings is just a cache
+ * to speed up lookup.
+ */
+ unsigned int rt6i_nsiblings;
+ struct list_head rt6i_siblings;
+#endif
atomic_t rt6i_ref;
@@ -318,4 +329,43 @@ static inline void fib6_rules_cleanup(void)
return ;
}
to :
@@ -98,6 +100,15 @@ struct rt6_info {
struct fib6_node *rt6i_node;
struct in6_addr rt6i_gateway;
+#ifdef CONFIG_IPV6_MULTIPATH
+ /*
+ * siblings is a list of rt6_info that have the the same metric/weight,
+ * destination, but not the same gateway. nsiblings is just a cache
+ * to speed up lookup.
+ */
+ struct list_head rt6i_siblings;
+ unsigned int rt6i_nsiblings;
+#endif
atomic_t rt6i_ref;
@@ -318,4 +329,43 @@ static inline void fib6_rules_cleanup(void)
return ;
}
^ permalink raw reply
* Re: [PATCH net-next v6 1/1] ipv6: add support of equal cost multipath (ECMP)
From: Nicolas Dichtel @ 2012-10-02 16:06 UTC (permalink / raw)
To: Nicolas Dichtel; +Cc: joe, bernat, netdev, yoshfuji, davem
In-Reply-To: <1349193767-3992-2-git-send-email-nicolas.dichtel@6wind.com>
Le 02/10/2012 18:02, Nicolas Dichtel a écrit :
> Each nexthop is added like a single route in the routing table. All routes
> that have the same metric/weight and destination but not the same gateway
> are considering as ECMP routes. They are linked together, through a list called
> rt6i_siblings.
>
> ECMP routes can be added in one shot, with RTA_MULTIPATH attribute or one after
> the other (in both case, the flag NLM_F_EXCL should not be set).
>
> The patch is based on a previous work from
> Luc Saillard <luc.saillard@6wind.com>.
>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
I forget to run checkpatch.pl, some lines are over 80 columns. I will fix it in
the v7 with other comments (if any).
^ permalink raw reply
* Re: Possible networking regression in 3.6.0
From: Eric Dumazet @ 2012-10-02 16:06 UTC (permalink / raw)
To: Dave Jones; +Cc: David Miller, chris2553, netdev, gpiez
In-Reply-To: <20121002155738.GA20331@redhat.com>
On Tue, 2012-10-02 at 11:57 -0400, Dave Jones wrote:
>
> Good work! Any idea why it didn't happen on every build for me ?
>
> From your description, this should have failed every time ?
Well, it seems that as long as you had forwarded packets and a route not
yet cached in nh_rth_input, we were using a brand new route (and correct
one)
But as soon as a locally generated traffic did cache a route in
nh_rth_input, forwarded packets immediately were using this cache and
were delivered (and dropped) to local host.
Maybe my patch is not the good fix, but at least its a step in
understanding the problem.
Thanks
^ permalink raw reply
* [PATCH net-next v6 1/1] ipv6: add support of equal cost multipath (ECMP)
From: Nicolas Dichtel @ 2012-10-02 16:02 UTC (permalink / raw)
To: joe; +Cc: bernat, netdev, yoshfuji, davem, Nicolas Dichtel
In-Reply-To: <1349193767-3992-1-git-send-email-nicolas.dichtel@6wind.com>
Each nexthop is added like a single route in the routing table. All routes
that have the same metric/weight and destination but not the same gateway
are considering as ECMP routes. They are linked together, through a list called
rt6i_siblings.
ECMP routes can be added in one shot, with RTA_MULTIPATH attribute or one after
the other (in both case, the flag NLM_F_EXCL should not be set).
The patch is based on a previous work from
Luc Saillard <luc.saillard@6wind.com>.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
include/net/ip6_fib.h | 50 +++++++++++++++
net/ipv6/Kconfig | 10 +++
net/ipv6/ip6_fib.c | 71 +++++++++++++++++++++
net/ipv6/route.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 297 insertions(+), 3 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 8a2a203..2712572 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -47,6 +47,8 @@ struct fib6_config {
unsigned long fc_expires;
struct nlattr *fc_mx;
int fc_mx_len;
+ int fc_mp_len;
+ struct nlattr *fc_mp;
struct nl_info fc_nlinfo;
};
@@ -98,6 +100,15 @@ struct rt6_info {
struct fib6_node *rt6i_node;
struct in6_addr rt6i_gateway;
+#ifdef CONFIG_IPV6_MULTIPATH
+ /*
+ * siblings is a list of rt6_info that have the the same metric/weight,
+ * destination, but not the same gateway. nsiblings is just a cache
+ * to speed up lookup.
+ */
+ unsigned int rt6i_nsiblings;
+ struct list_head rt6i_siblings;
+#endif
atomic_t rt6i_ref;
@@ -318,4 +329,43 @@ static inline void fib6_rules_cleanup(void)
return ;
}
#endif
+
+#ifdef CONFIG_IPV6_MULTIPATH
+static inline unsigned int ipv6_multipath_get_nsiblings(const struct rt6_info *rt)
+{
+ return rt->rt6i_nsiblings;
+}
+static inline void ipv6_multipath_reset_nsiblings(struct rt6_info *rt)
+{
+ rt->rt6i_nsiblings = 0;
+}
+static inline void ipv6_multipath_inc_nsiblings(struct rt6_info *rt)
+{
+ rt->rt6i_nsiblings++;
+}
+static inline void ipv6_multipath_dec_nsiblings(struct rt6_info *rt)
+{
+ rt->rt6i_nsiblings--;
+}
+#else
+static inline unsigned int ipv6_multipath_get_nsiblings(const struct rt6_info *rt)
+{
+ return 0;
+}
+static inline void ipv6_multipath_reset_nsiblings(struct rt6_info *rt)
+{
+}
+static inline void ipv6_multipath_inc_nsiblings(struct rt6_info *rt)
+{
+}
+static inline void ipv6_multipath_dec_nsiblings(struct rt6_info *rt)
+{
+}
+static inline struct rt6_info *rt6_multipath_select(struct net *net,
+ struct rt6_info *rt,
+ struct flowi6 *fl6)
+{
+ return rt;
+}
+#endif
#endif
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 4f7fe72..fc2f3cb 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -266,4 +266,14 @@ config IPV6_PIMSM_V2
Support for IPv6 PIM multicast routing protocol PIM-SMv2.
If unsure, say N.
+config IPV6_MULTIPATH
+ bool "IPv6: equal cost multipath for IPv6 routing"
+ depends on IPV6
+ default y
+ ---help---
+ Enable this option to support ECMP for IPv6.
+
+ The algorithm used for route selection is based on a hash of packet
+ header (recommanded by RFC4311) and flowlabel (RFC6438).
+
endif # IPV6
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 24995a9..ef4faf8 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -672,6 +672,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
iter->rt6i_idev == rt->rt6i_idev &&
ipv6_addr_equal(&iter->rt6i_gateway,
&rt->rt6i_gateway)) {
+ if (ipv6_multipath_get_nsiblings(rt))
+ ipv6_multipath_reset_nsiblings(rt);
if (!(iter->rt6i_flags & RTF_EXPIRES))
return -EEXIST;
if (!(rt->rt6i_flags & RTF_EXPIRES))
@@ -680,6 +682,21 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
rt6_set_expires(iter, rt->dst.expires);
return -EEXIST;
}
+ /* If we have the same destination and the same metric,
+ * but not the same gateway, then the route we try to
+ * add is sibling to this route, increment our counter
+ * of siblings, and later we will add our route to the
+ * list.
+ * Only static routes (which don't have flag
+ * RTF_EXPIRES) are used for ECMPv6.
+ *
+ * To avoid long list, we only had siblings if the
+ * route have a gateway.
+ */
+ if (rt->rt6i_flags & RTF_GATEWAY &&
+ !(rt->rt6i_flags & RTF_EXPIRES) &&
+ !(iter->rt6i_flags & RTF_EXPIRES))
+ ipv6_multipath_inc_nsiblings(rt);
}
if (iter->rt6i_metric > rt->rt6i_metric)
@@ -692,6 +709,45 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
if (ins == &fn->leaf)
fn->rr_ptr = NULL;
+#ifdef CONFIG_IPV6_MULTIPATH
+ /* Link this route to others same route. */
+ if (ipv6_multipath_get_nsiblings(rt)) {
+ unsigned int rt6i_nsiblings;
+ struct rt6_info *sibling, *temp_sibling;
+
+ /* Find the first route that have the same metric */
+ sibling = fn->leaf;
+ while (sibling) {
+ if (sibling->rt6i_metric == rt->rt6i_metric) {
+ list_add_tail(&rt->rt6i_siblings,
+ &sibling->rt6i_siblings);
+ break;
+ }
+ sibling = sibling->dst.rt6_next;
+ }
+ /* For each sibling in the list, increment the counter of
+ * siblings. We can check if all the counter are equal.
+ */
+ rt6i_nsiblings = 0;
+ list_for_each_entry_safe(sibling, temp_sibling,
+ &rt->rt6i_siblings,
+ rt6i_siblings) {
+ ipv6_multipath_inc_nsiblings(sibling);
+ if (unlikely(ipv6_multipath_get_nsiblings(sibling) !=
+ ipv6_multipath_get_nsiblings(rt))) {
+ pr_err("Wrong number of siblings for route %p (%d)\n",
+ sibling, ipv6_multipath_get_nsiblings(sibling));
+ }
+ rt6i_nsiblings++;
+ }
+ if (unlikely(rt6i_nsiblings !=
+ ipv6_multipath_get_nsiblings(rt))) {
+ pr_err("Wrong number of siblings for route %p. I have %d routes, but count %d siblings\n",
+ rt, rt6i_nsiblings,
+ ipv6_multipath_get_nsiblings(rt));
+ }
+ }
+#endif
/*
* insert node
*/
@@ -1193,6 +1249,21 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
if (fn->rr_ptr == rt)
fn->rr_ptr = NULL;
+#ifdef CONFIG_IPV6_MULTIPATH
+ /* Remove this entry from other siblings */
+ if (ipv6_multipath_get_nsiblings(rt)) {
+ struct rt6_info *sibling, *next_sibling;
+
+ /* For each siblings, decrement the counter of siblings */
+ list_for_each_entry_safe(sibling, next_sibling,
+ &rt->rt6i_siblings, rt6i_siblings) {
+ ipv6_multipath_dec_nsiblings(sibling);
+ }
+ ipv6_multipath_reset_nsiblings(rt);
+ list_del_init(&rt->rt6i_siblings);
+ }
+#endif
+
/* Adjust walkers */
read_lock(&fib6_walker_lock);
FOR_WALKERS(w) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d1ddbc6..4c42b9e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -57,6 +57,9 @@
#include <net/xfrm.h>
#include <net/netevent.h>
#include <net/netlink.h>
+#ifdef CONFIG_IPV6_MULTIPATH
+#include <net/nexthop.h>
+#endif
#include <asm/uaccess.h>
@@ -289,6 +292,10 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
rt->rt6i_genid = rt_genid(net);
+#ifdef CONFIG_IPV6_MULTIPATH
+ INIT_LIST_HEAD(&rt->rt6i_siblings);
+#endif
+ ipv6_multipath_reset_nsiblings(rt);
}
return rt;
}
@@ -385,6 +392,92 @@ static bool rt6_need_strict(const struct in6_addr *daddr)
(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
}
+#ifdef CONFIG_IPV6_MULTIPATH
+/*
+ * Multipath route selection.
+ */
+
+/*
+ * Hash based function using packet header and flowlabel.
+ * Adapted from fib_info_hashfn()
+ */
+static int rt6_info_hash_nhsfn(unsigned int candidate_count,
+ const struct flowi6 *fl6)
+{
+ unsigned int val = fl6->flowi6_proto;
+
+ val ^= fl6->daddr.s6_addr32[0];
+ val ^= fl6->daddr.s6_addr32[1];
+ val ^= fl6->daddr.s6_addr32[2];
+ val ^= fl6->daddr.s6_addr32[3];
+
+ val ^= fl6->saddr.s6_addr32[0];
+ val ^= fl6->saddr.s6_addr32[1];
+ val ^= fl6->saddr.s6_addr32[2];
+ val ^= fl6->saddr.s6_addr32[3];
+
+ /* Work only if this not encapsulated */
+ switch (fl6->flowi6_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ val ^= fl6->fl6_sport;
+ val ^= fl6->fl6_dport;
+ break;
+
+ case IPPROTO_ICMPV6:
+ val ^= fl6->fl6_icmp_type;
+ val ^= fl6->fl6_icmp_code;
+ break;
+ }
+ /* RFC6438 recommands to use flowlabel */
+ val ^= fl6->flowlabel;
+
+ /* Perhaps, we need to tune, this function? */
+ val = val ^ (val >> 7) ^ (val >> 12);
+ return val % candidate_count;
+}
+
+/*
+ * This function returns an index used to select a route between any siblings.
+ *
+ * Note: fl6 can be NULL
+ */
+static unsigned int rt6_info_hashfn(struct net *net,
+ const struct rt6_info *rt,
+ const struct flowi6 *fl6)
+{
+ int candidate_count = ipv6_multipath_get_nsiblings(rt) + 1;
+
+ if (fl6 == NULL)
+ return 0;
+ return rt6_info_hash_nhsfn(candidate_count, fl6);
+}
+
+static struct rt6_info *rt6_multipath_select(struct net *net,
+ struct rt6_info *match,
+ struct flowi6 *fl6)
+{
+ struct rt6_info *sibling, *next_sibling;
+ int route_choosen;
+
+ route_choosen = rt6_info_hashfn(net, match, fl6);
+ /* Don't change the route, if route_choosen == 0
+ * (siblings does not include ourself)
+ */
+ if (route_choosen)
+ list_for_each_entry_safe(sibling, next_sibling,
+ &match->rt6i_siblings, rt6i_siblings) {
+ route_choosen--;
+ if (route_choosen == 0) {
+ match = sibling;
+ break;
+ }
+ }
+ return match;
+}
+#endif /* CONFIG_IPV6_MULTIPATH */
+
/*
* Route lookup. Any table->tb6_lock is implied.
*/
@@ -702,6 +795,8 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
restart:
rt = fn->leaf;
rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags);
+ if (ipv6_multipath_get_nsiblings(rt) && fl6->flowi6_oif == 0)
+ rt = rt6_multipath_select(net, rt, fl6);
BACKTRACK(net, &fl6->saddr);
out:
dst_use(&rt->dst, jiffies);
@@ -863,7 +958,8 @@ restart_2:
restart:
rt = rt6_select(fn, oif, strict | reachable);
-
+ if (ipv6_multipath_get_nsiblings(rt) && oif == 0)
+ rt = rt6_multipath_select(net, rt, fl6);
BACKTRACK(net, &fl6->saddr);
if (rt == net->ipv6.ip6_null_entry ||
rt->rt6i_flags & RTF_CACHE)
@@ -2248,6 +2344,9 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
[RTA_IIF] = { .type = NLA_U32 },
[RTA_PRIORITY] = { .type = NLA_U32 },
[RTA_METRICS] = { .type = NLA_NESTED },
+#ifdef CONFIG_IPV6_MULTIPATH
+ [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
+#endif
};
static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -2325,11 +2424,69 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
if (tb[RTA_TABLE])
cfg->fc_table = nla_get_u32(tb[RTA_TABLE]);
+ if (tb[RTA_MULTIPATH]) {
+ cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]);
+ cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]);
+ }
+
err = 0;
errout:
return err;
}
+static int ip6_route_multipath(struct fib6_config *cfg, int add)
+{
+#ifdef CONFIG_IPV6_MULTIPATH
+ struct fib6_config r_cfg;
+ struct rtnexthop *rtnh;
+ int remaining;
+ int attrlen;
+ int err = 0, last_err = 0;
+
+beginning:
+ rtnh = (struct rtnexthop *)cfg->fc_mp;
+ remaining = cfg->fc_mp_len;
+
+ /* Parse a Multipath Entry */
+ while (rtnh_ok(rtnh, remaining)) {
+ memcpy(&r_cfg, cfg, sizeof(*cfg));
+ if (rtnh->rtnh_ifindex)
+ r_cfg.fc_ifindex = rtnh->rtnh_ifindex;
+
+ attrlen = rtnh_attrlen(rtnh);
+ if (attrlen > 0) {
+ struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
+
+ nla = nla_find(attrs, attrlen, RTA_GATEWAY);
+ if (nla) {
+ nla_memcpy(&r_cfg.fc_gateway, nla, 16);
+ r_cfg.fc_flags |= RTF_GATEWAY;
+ }
+ }
+ err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg);
+ if (err) {
+ last_err = err;
+ /* If we are trying to remove a route, do not stop the
+ * loop when ip6_route_del() fails (because next hop is
+ * already gone), we should try to remove all next hops.
+ */
+ if (add) {
+ /* If add fails, we should try to delete all
+ * next hops that have been already added.
+ */
+ add = 0;
+ goto beginning;
+ }
+ }
+ rtnh = rtnh_next(rtnh, &remaining);
+ }
+
+ return last_err;
+#else
+ return -ENOSYS;
+#endif /* CONFIG_IPV6_MULTIPATH */
+}
+
static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
{
struct fib6_config cfg;
@@ -2339,7 +2496,10 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
if (err < 0)
return err;
- return ip6_route_del(&cfg);
+ if (cfg.fc_mp)
+ return ip6_route_multipath(&cfg, 0);
+ else
+ return ip6_route_del(&cfg);
}
static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
@@ -2351,7 +2511,10 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
if (err < 0)
return err;
- return ip6_route_add(&cfg);
+ if (cfg.fc_mp)
+ return ip6_route_multipath(&cfg, 1);
+ else
+ return ip6_route_add(&cfg);
}
static inline size_t rt6_nlmsg_size(void)
--
1.7.12
^ permalink raw reply related
* [PATCH net-next v6 0/1] Add support of ECMPv6
From: Nicolas Dichtel @ 2012-10-02 16:02 UTC (permalink / raw)
To: joe; +Cc: bernat, netdev, yoshfuji, davem
In-Reply-To: <1349110077.7740.23.camel@joe-AO722>
Here is a proposal to add the support of ECMPv6. The previous patch
from Vincent against iproute2 can be used, but a little other patch is needed
too, see http://patchwork.ozlabs.org/patch/183277/
If the kernel patch is approved, I can submit formally the patch for
iproute2.
Here is an example of a command to add an ECMP route:
$ ip -6 route add 3ffe:304:124:2306::/64 \
nexthop via fe80::230:1bff:feb4:e05c dev eth0 \
nexthop via fe80::230:1bff:feb4:dd4f dev eth0
But note that this command is a shortcut and previous patches are not
mandatory to set ECMP routes. The following commands can be used too:
$ ip -6 route add 3ffe:304:124:2306::/64 via fe80::230:1bff:feb4:dd4f dev
eth0
$ ip -6 route append 3ffe:304:124:2306::/64 via fe80::230:1bff:feb4:e05c dev
eth0
Here is an example of a dump:
$ ip -6 route | grep 3ffe:304:124:2306::/64
3ffe:304:124:2306::/64 via fe80::230:1bff:feb4:dd4f dev eth0 metric 1024
3ffe:304:124:2306::/64 via fe80::230:1bff:feb4:e05c dev eth0 metric 1024
v6: be more verbose in commitlog
add some helpers in ip6_fib.h to avoid to have too many ifdef block in the
code
invert fc_mp_len and fc_mp in struct fib6_config to avoid a hole on 64bits
arch
v5: to minimize the patch and ease its integration, remove roundrobin and random
algorithms for route selection. It will be possible to add new algorithms
through rt6_info_hashfn() when the basic support of ECMP is integrated.
v4: remove compilation options to choose multipath algorithm for next hop
selection. Now the choice can be done at run time via
/proc/sys/net/ipv6/route/multipath_algorithm
v3: rebase after updating net-next
v2: rename CONFIG_IPV6_MULTIPATH_ROUTE to CONFIG_IPV6_MULTIPATH_HASH
use flowlabel in the hash function
add reference to RFC
fix a small identation issue
remove "If unsure, say N." from the help of CONFIG_IPV6_MULTIPATH
Comments are welcome.
Regards,
Nicolas
^ permalink raw reply
* Re: Possible networking regression in 3.6.0
From: Dave Jones @ 2012-10-02 15:57 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, chris2553, netdev, gpiez
In-Reply-To: <1349192919.12401.778.camel@edumazet-glaptop>
On Tue, Oct 02, 2012 at 05:48:39PM +0200, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> On Tue, 2012-10-02 at 17:35 +0200, Eric Dumazet wrote:
> > On Mon, 2012-10-01 at 22:04 +0200, Eric Dumazet wrote:
> > > On Mon, 2012-10-01 at 16:01 -0400, David Miller wrote:
> >
> > > > If you can find a way to more reliably trigger the case, that would
> > > > help us immensely.
> > >
> > > I am building a KMEMCHECK kernel, as a last try before my night ;)
> >
> > This was a total disaster. KMEMCHECK dies horribly on my machine
> >
> > David, shouldnt we use a nh_rth_forward instead of a nh_rth_input in
> > __mkroute_input() ?
> >
> > (And change rt_cache_route() as well ?)
> >
> > I am testing a patch right now.
>
> Yeah, this patch seems to fix the bug for me.
Good work! Any idea why it didn't happen on every build for me ?
>From your description, this should have failed every time ?
Dave
^ permalink raw reply
* Re: network namespace and kernel bind issue
From: Stephen Hemminger @ 2012-10-02 15:51 UTC (permalink / raw)
To: Julian Anastasov, James Chapman; +Cc: Eric W. Biederman, netdev
In-Reply-To: <alpine.LFD.2.00.1210020910010.1642@ja.ssi.bg>
On Tue, 2 Oct 2012 09:15:46 +0300 (EEST)
Julian Anastasov <ja@ssi.bg> wrote:
>
> Hello,
>
> On Mon, 1 Oct 2012, Stephen Hemminger wrote:
>
> > The problem was vxlan wasn't doing sk_change_net on the created socket.
> >
> > I'm testing that fix.
> >
> > The long term fix is to change sock_create_kern() to take a 'struct net'
> > argument. This would avoid the trap of having to change the namespace.
> > Also several places using __sock_create() could use it.
> >
> > L2TP still looks to have several namespace related issues.
>
> There should be also .netnsok = true in l2tp_nl_family
> as final step.
>
> Regards
>
> --
> Julian Anastasov <ja@ssi.bg>
There are actually lots more net namespace issues in L2TP.
For example session and tunnel counts are global, not per namespace.
^ permalink raw reply
* Re: Possible networking regression in 3.6.0
From: Eric Dumazet @ 2012-10-02 15:48 UTC (permalink / raw)
To: David Miller; +Cc: chris2553, netdev, gpiez, Dave Jones
In-Reply-To: <1349192133.12401.768.camel@edumazet-glaptop>
From: Eric Dumazet <edumazet@google.com>
On Tue, 2012-10-02 at 17:35 +0200, Eric Dumazet wrote:
> On Mon, 2012-10-01 at 22:04 +0200, Eric Dumazet wrote:
> > On Mon, 2012-10-01 at 16:01 -0400, David Miller wrote:
>
> > > If you can find a way to more reliably trigger the case, that would
> > > help us immensely.
> >
> > I am building a KMEMCHECK kernel, as a last try before my night ;)
>
> This was a total disaster. KMEMCHECK dies horribly on my machine
>
> David, shouldnt we use a nh_rth_forward instead of a nh_rth_input in
> __mkroute_input() ?
>
> (And change rt_cache_route() as well ?)
>
> I am testing a patch right now.
Yeah, this patch seems to fix the bug for me.
[PATCH] ipv4: properly cache forward routes
commit d2d68ba9fe8 (ipv4: Cache input routes in fib_info nexthops.)
introduced a regression for forwarding.
This was hard to reproduce but the symptom was that packets were
delivered to local host instead of being forwarded.
Add a separate cache (nh_rth_forward) to solve the problem.
Many thanks to Chris Clayton for his patience and help.
Reported-by: Chris Clayton <chris2553@googlemail.com>
Bisected-by: Chris Clayton <chris2553@googlemail.com>
Reported-by: Dave Jones <davej@redhat.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/ip_fib.h | 1 +
net/ipv4/fib_semantics.c | 1 +
net/ipv4/route.c | 16 ++++++++--------
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 926142e..ce7ffe9 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -85,6 +85,7 @@ struct fib_nh {
int nh_saddr_genid;
struct rtable __rcu * __percpu *nh_pcpu_rth_output;
struct rtable __rcu *nh_rth_input;
+ struct rtable __rcu *nh_rth_forward;
struct fnhe_hash_bucket *nh_exceptions;
};
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 3509065..45b5d1d 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -208,6 +208,7 @@ static void free_fib_info_rcu(struct rcu_head *head)
free_nh_exceptions(nexthop_nh);
rt_fibinfo_free_cpus(nexthop_nh->nh_pcpu_rth_output);
rt_fibinfo_free(&nexthop_nh->nh_rth_input);
+ rt_fibinfo_free(&nexthop_nh->nh_rth_forward);
} endfor_nexthops(fi);
release_net(fi->fib_net);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ff62206..50898d6 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1193,14 +1193,12 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
return ret;
}
-static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt)
+static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt, struct rtable **p)
{
- struct rtable *orig, *prev, **p;
+ struct rtable *orig, *prev;
bool ret = true;
- if (rt_is_input_route(rt)) {
- p = (struct rtable **)&nh->nh_rth_input;
- } else {
+ if (!p) {
if (!nh->nh_pcpu_rth_output)
goto nocache;
p = (struct rtable **)__this_cpu_ptr(nh->nh_pcpu_rth_output);
@@ -1290,7 +1288,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
if (unlikely(fnhe))
cached = rt_bind_exception(rt, fnhe, daddr);
else if (!(rt->dst.flags & DST_NOCACHE))
- cached = rt_cache_route(nh, rt);
+ cached = rt_cache_route(nh, rt, NULL);
}
if (unlikely(!cached))
rt_add_uncached_list(rt);
@@ -1462,7 +1460,7 @@ static int __mkroute_input(struct sk_buff *skb,
do_cache = false;
if (res->fi) {
if (!itag) {
- rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
+ rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_forward);
if (rt_cache_valid(rth)) {
skb_dst_set_noref(skb, &rth->dst);
goto out;
@@ -1493,6 +1491,8 @@ static int __mkroute_input(struct sk_buff *skb,
rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag);
skb_dst_set(skb, &rth->dst);
+ if (do_cache)
+ rt_cache_route(&FIB_RES_NH(*res), rth, &FIB_RES_NH(*res).nh_rth_forward);
out:
err = 0;
cleanup:
@@ -1663,7 +1663,7 @@ local_input:
rth->rt_flags &= ~RTCF_LOCAL;
}
if (do_cache)
- rt_cache_route(&FIB_RES_NH(res), rth);
+ rt_cache_route(&FIB_RES_NH(res), rth, &FIB_RES_NH(res).nh_rth_input);
skb_dst_set(skb, &rth->dst);
err = 0;
goto out;
^ permalink raw reply related
* Re: Possible networking regression in 3.6.0
From: Eric Dumazet @ 2012-10-02 15:35 UTC (permalink / raw)
To: David Miller; +Cc: davej, chris2553, netdev, gpiez
In-Reply-To: <1349121884.12401.721.camel@edumazet-glaptop>
On Mon, 2012-10-01 at 22:04 +0200, Eric Dumazet wrote:
> On Mon, 2012-10-01 at 16:01 -0400, David Miller wrote:
> > If you can find a way to more reliably trigger the case, that would
> > help us immensely.
>
> I am building a KMEMCHECK kernel, as a last try before my night ;)
This was a total disaster. KMEMCHECK dies horribly on my machine
David, shouldnt we use a nh_rth_forward instead of a nh_rth_input in
__mkroute_input() ?
(And change rt_cache_route() as well ?)
I am testing a patch right now.
^ permalink raw reply
* [PATCH net-next,5/6] hyperv: Report actual status in receive completion packet
From: Haiyang Zhang @ 2012-10-02 15:30 UTC (permalink / raw)
To: davem, netdev; +Cc: haiyangz, kys, olaf, jasowang, linux-kernel, devel
In-Reply-To: <1349191824-14001-1-git-send-email-haiyangz@microsoft.com>
The existing code always reports NVSP_STAT_SUCCESS. This patch adds the
mechanism to report failure when it happens.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/net/hyperv/hyperv_net.h | 2 ++
drivers/net/hyperv/netvsc.c | 18 ++++++++++++------
drivers/net/hyperv/netvsc_drv.c | 2 ++
drivers/net/hyperv/rndis_filter.c | 19 ++++++++++++++-----
4 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index d58f28c..5fd6f46 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -35,6 +35,7 @@ struct hv_netvsc_packet;
/* Represent the xfer page packet which contains 1 or more netvsc packet */
struct xferpage_packet {
struct list_head list_ent;
+ u32 status;
/* # of netvsc packets this xfer packet contains */
u32 count;
@@ -47,6 +48,7 @@ struct xferpage_packet {
struct hv_netvsc_packet {
/* Bookkeeping stuff */
struct list_head list_ent;
+ u32 status;
struct hv_device *device;
bool is_data_pkt;
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index d9c4c03..1cd7748 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -558,7 +558,7 @@ int netvsc_send(struct hv_device *device,
}
static void netvsc_send_recv_completion(struct hv_device *device,
- u64 transaction_id)
+ u64 transaction_id, u32 status)
{
struct nvsp_message recvcompMessage;
int retries = 0;
@@ -571,9 +571,7 @@ static void netvsc_send_recv_completion(struct hv_device *device,
recvcompMessage.hdr.msg_type =
NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
- /* FIXME: Pass in the status */
- recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status =
- NVSP_STAT_SUCCESS;
+ recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status = status;
retry_send_cmplt:
/* Send the completion */
@@ -613,6 +611,7 @@ static void netvsc_receive_completion(void *context)
bool fsend_receive_comp = false;
unsigned long flags;
struct net_device *ndev;
+ u32 status = NVSP_STAT_NONE;
/*
* Even though it seems logical to do a GetOutboundNetDevice() here to
@@ -627,6 +626,9 @@ static void netvsc_receive_completion(void *context)
/* Overloading use of the lock. */
spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
+ if (packet->status != NVSP_STAT_SUCCESS)
+ packet->xfer_page_pkt->status = NVSP_STAT_FAIL;
+
packet->xfer_page_pkt->count--;
/*
@@ -636,6 +638,7 @@ static void netvsc_receive_completion(void *context)
if (packet->xfer_page_pkt->count == 0) {
fsend_receive_comp = true;
transaction_id = packet->completion.recv.recv_completion_tid;
+ status = packet->xfer_page_pkt->status;
list_add_tail(&packet->xfer_page_pkt->list_ent,
&net_device->recv_pkt_list);
@@ -647,7 +650,7 @@ static void netvsc_receive_completion(void *context)
/* Send a receive completion for the xfer page packet */
if (fsend_receive_comp)
- netvsc_send_recv_completion(device, transaction_id);
+ netvsc_send_recv_completion(device, transaction_id, status);
}
@@ -736,7 +739,8 @@ static void netvsc_receive(struct hv_device *device,
flags);
netvsc_send_recv_completion(device,
- vmxferpage_packet->d.trans_id);
+ vmxferpage_packet->d.trans_id,
+ NVSP_STAT_FAIL);
return;
}
@@ -744,6 +748,7 @@ static void netvsc_receive(struct hv_device *device,
/* Remove the 1st packet to represent the xfer page packet itself */
xferpage_packet = (struct xferpage_packet *)listHead.next;
list_del(&xferpage_packet->list_ent);
+ xferpage_packet->status = NVSP_STAT_SUCCESS;
/* This is how much we can satisfy */
xferpage_packet->count = count - 1;
@@ -760,6 +765,7 @@ static void netvsc_receive(struct hv_device *device,
list_del(&netvsc_packet->list_ent);
/* Initialize the netvsc packet */
+ netvsc_packet->status = NVSP_STAT_SUCCESS;
netvsc_packet->xfer_page_pkt = xferpage_packet;
netvsc_packet->completion.recv.recv_completion =
netvsc_receive_completion;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index e91111a..f825a62 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -265,6 +265,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
if (!net) {
netdev_err(net, "got receive callback but net device"
" not initialized yet\n");
+ packet->status = NVSP_STAT_FAIL;
return 0;
}
@@ -272,6 +273,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
skb = netdev_alloc_skb_ip_align(net, packet->total_data_buflen);
if (unlikely(!skb)) {
++net->stats.rx_dropped;
+ packet->status = NVSP_STAT_FAIL;
return 0;
}
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index f25f41e..e7e12cf 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -411,9 +411,12 @@ int rndis_filter_receive(struct hv_device *dev,
struct rndis_device *rndis_dev;
struct rndis_message *rndis_msg;
struct net_device *ndev;
+ int ret = 0;
- if (!net_dev)
- return -EINVAL;
+ if (!net_dev) {
+ ret = -EINVAL;
+ goto exit;
+ }
ndev = net_dev->ndev;
@@ -421,14 +424,16 @@ int rndis_filter_receive(struct hv_device *dev,
if (!net_dev->extension) {
netdev_err(ndev, "got rndis message but no rndis device - "
"dropping this message!\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto exit;
}
rndis_dev = (struct rndis_device *)net_dev->extension;
if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
netdev_err(ndev, "got rndis message but rndis device "
"uninitialized...dropping this message!\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto exit;
}
rndis_msg = pkt->data;
@@ -460,7 +465,11 @@ int rndis_filter_receive(struct hv_device *dev,
break;
}
- return 0;
+exit:
+ if (ret != 0)
+ pkt->status = NVSP_STAT_FAIL;
+
+ return ret;
}
static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next, 3/6] hyperv: Fix page buffer handling in rndis_filter_send_request()
From: Haiyang Zhang @ 2012-10-02 15:30 UTC (permalink / raw)
To: davem, netdev; +Cc: olaf, jasowang, linux-kernel, devel, haiyangz
In-Reply-To: <1349191824-14001-1-git-send-email-haiyangz@microsoft.com>
To prevent possible data corruption in RNDIS requests, add another
page buffer if the request message crossed page boundary.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/net/hyperv/rndis_filter.c | 15 ++++++++++++++-
1 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 617eb2e..f25f41e 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -45,7 +45,8 @@ struct rndis_request {
/* Simplify allocation by having a netvsc packet inline */
struct hv_netvsc_packet pkt;
- struct hv_page_buffer buf;
+ /* Set 2 pages for rndis requests crossing page boundary */
+ struct hv_page_buffer buf[2];
struct rndis_message request_msg;
/*
@@ -227,6 +228,18 @@ static int rndis_filter_send_request(struct rndis_device *dev,
packet->page_buf[0].offset =
(unsigned long)&req->request_msg & (PAGE_SIZE - 1);
+ /* Add one page_buf when request_msg crossing page boundary */
+ if (packet->page_buf[0].offset + packet->page_buf[0].len > PAGE_SIZE) {
+ packet->page_buf_cnt++;
+ packet->page_buf[0].len = PAGE_SIZE -
+ packet->page_buf[0].offset;
+ packet->page_buf[1].pfn = virt_to_phys((void *)&req->request_msg
+ + packet->page_buf[0].len) >> PAGE_SHIFT;
+ packet->page_buf[1].offset = 0;
+ packet->page_buf[1].len = req->request_msg.msg_len -
+ packet->page_buf[0].len;
+ }
+
packet->completion.send.send_completion_ctx = req;/* packet; */
packet->completion.send.send_completion =
rndis_filter_send_request_completion;
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next,2/6] hyperv: Fix the missing return value in rndis_filter_set_packet_filter()
From: Haiyang Zhang @ 2012-10-02 15:30 UTC (permalink / raw)
To: davem, netdev; +Cc: haiyangz, kys, olaf, jasowang, linux-kernel, devel
In-Reply-To: <1349191824-14001-1-git-send-email-haiyangz@microsoft.com>
Return ETIMEDOUT when the reply message is not received in time.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/net/hyperv/rndis_filter.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 1337b64..617eb2e 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -647,6 +647,7 @@ int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
if (t == 0) {
netdev_err(ndev,
"timeout before we got a set response...\n");
+ ret = -ETIMEDOUT;
/*
* We can't deallocate the request since we may still receive a
* send completion for it.
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next,1/6] hyperv: Fix the max_xfer_size in RNDIS initialization
From: Haiyang Zhang @ 2012-10-02 15:30 UTC (permalink / raw)
To: davem, netdev; +Cc: haiyangz, kys, olaf, jasowang, linux-kernel, devel
According to RNDIS specs, Windows sets this size to
0x4000. I use the same value here.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/net/hyperv/rndis_filter.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 06f8601..1337b64 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -684,8 +684,7 @@ static int rndis_filter_init_device(struct rndis_device *dev)
init = &request->request_msg.msg.init_req;
init->major_ver = RNDIS_MAJOR_VERSION;
init->minor_ver = RNDIS_MINOR_VERSION;
- /* FIXME: Use 1536 - rounded ethernet frame size */
- init->max_xfer_size = 2048;
+ init->max_xfer_size = 0x4000;
dev->state = RNDIS_DEV_INITIALIZING;
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCHv2 net-next] vxlan: put UDP socket in correct namespace
From: Eric W. Biederman @ 2012-10-02 15:18 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20121001214921.78d9ed72@nehalam.linuxnetplumber.net>
Stephen Hemminger <shemminger@vyatta.com> writes:
> Move vxlan UDP socket to correct network namespace
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Looks good from here.
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
> v2 need to change sock_release to sk_release_kernel
>
> --- a/drivers/net/vxlan.c 2012-10-01 17:18:30.776513263 -0700
> +++ b/drivers/net/vxlan.c 2012-10-01 21:47:40.435979178 -0700
> @@ -1136,6 +1136,9 @@ static __net_init int vxlan_init_net(str
> pr_debug("UDP socket create failed\n");
> return rc;
> }
> + /* Put in proper namespace */
> + sk = vn->sock->sk;
> + sk_change_net(sk, net);
>
> vxlan_addr.sin_port = htons(vxlan_port);
>
> @@ -1144,13 +1147,12 @@ static __net_init int vxlan_init_net(str
> if (rc < 0) {
> pr_debug("bind for UDP socket %pI4:%u (%d)\n",
> &vxlan_addr.sin_addr, ntohs(vxlan_addr.sin_port), rc);
> - sock_release(vn->sock);
> + sk_release_kernel(sk);
> vn->sock = NULL;
> return rc;
> }
>
> /* Disable multicast loopback */
> - sk = vn->sock->sk;
> inet_sk(sk)->mc_loop = 0;
>
> /* Mark socket as an encapsulation socket. */
> @@ -1169,7 +1171,7 @@ static __net_exit void vxlan_exit_net(st
> struct vxlan_net *vn = net_generic(net, vxlan_net_id);
>
> if (vn->sock) {
> - sock_release(vn->sock);
> + sk_release_kernel(vn->sock->sk);
> vn->sock = NULL;
> }
> }
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next,6/6] hyperv: Add buffer for extended info after the RNDIS response message.
From: Haiyang Zhang @ 2012-10-02 15:30 UTC (permalink / raw)
To: davem, netdev; +Cc: haiyangz, kys, olaf, jasowang, linux-kernel, devel
In-Reply-To: <1349191824-14001-1-git-send-email-haiyangz@microsoft.com>
In some response messages, there may be some extended info after the
message.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/net/hyperv/rndis_filter.c | 22 ++++++++++++----------
1 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index e7e12cf..928148c 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -32,16 +32,19 @@
#include "hyperv_net.h"
+#define RNDIS_EXT_LEN 100
struct rndis_request {
struct list_head list_ent;
struct completion wait_event;
+ struct rndis_message response_msg;
/*
- * FIXME: We assumed a fixed size response here. If we do ever need to
- * handle a bigger response, we can either define a max response
- * message or add a response buffer variable above this field
+ * The buffer for extended info after the RNDIS response message. It's
+ * referenced based on the data offset in the RNDIS message. Its size
+ * is enough for current needs, and should be sufficient for the near
+ * future.
*/
- struct rndis_message response_msg;
+ u8 response_ext[RNDIS_EXT_LEN];
/* Simplify allocation by having a netvsc packet inline */
struct hv_netvsc_packet pkt;
@@ -50,12 +53,10 @@ struct rndis_request {
struct rndis_message request_msg;
/*
- * The buffer for the extended info after the RNDIS message. It's
- * referenced based on the data offset in the RNDIS message. Its size
- * is enough for current needs, and should be sufficient for the near
- * future.
+ * The buffer for the extended info after the RNDIS request message.
+ * It is referenced and sized in a similar way as response_ext.
*/
- u8 ext[100];
+ u8 request_ext[RNDIS_EXT_LEN];
};
static void rndis_filter_send_completion(void *ctx);
@@ -274,7 +275,8 @@ static void rndis_filter_receive_response(struct rndis_device *dev,
spin_unlock_irqrestore(&dev->request_lock, flags);
if (found) {
- if (resp->msg_len <= sizeof(struct rndis_message)) {
+ if (resp->msg_len <=
+ sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
memcpy(&request->response_msg, resp,
resp->msg_len);
} else {
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next,4/6] hyperv: Remove extra allocated space for recv_pkt_list elements
From: Haiyang Zhang @ 2012-10-02 15:30 UTC (permalink / raw)
To: davem, netdev; +Cc: haiyangz, kys, olaf, jasowang, linux-kernel, devel
In-Reply-To: <1349191824-14001-1-git-send-email-haiyangz@microsoft.com>
The receive code path doesn't use the page buffer, so remove the
extra allocated space here.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/net/hyperv/hyperv_net.h | 2 --
drivers/net/hyperv/netvsc.c | 4 +---
2 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 95ceb35..d58f28c 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -465,8 +465,6 @@ struct nvsp_message {
#define NETVSC_RECEIVE_BUFFER_ID 0xcafe
-#define NETVSC_RECEIVE_SG_COUNT 1
-
/* Preallocated receive packets */
#define NETVSC_RECEIVE_PACKETLIST_COUNT 256
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 4a1a5f5..d9c4c03 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -904,9 +904,7 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
INIT_LIST_HEAD(&net_device->recv_pkt_list);
for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
- packet = kzalloc(sizeof(struct hv_netvsc_packet) +
- (NETVSC_RECEIVE_SG_COUNT *
- sizeof(struct hv_page_buffer)), GFP_KERNEL);
+ packet = kzalloc(sizeof(struct hv_netvsc_packet), GFP_KERNEL);
if (!packet)
break;
--
1.7.4.1
^ permalink raw reply related
* Re: tg3 driver upgrade (Linux 2.6.32 -> 3.2) breaks IBM Bladecenter SoL
From: Michael Chan @ 2012-10-02 15:03 UTC (permalink / raw)
To: Ferenc Wagner
Cc: netdev, Matt Carlson, Grant Likely, Rob Herring, linux-kernel
In-Reply-To: <87a9w5dqle.fsf@lant.ki.iif.hu>
On Tue, 2012-10-02 at 14:07 +0200, Ferenc Wagner wrote:
> I'm done with bisecting it: the first bad commit is:
>
> commit dabc5c670d3f86d15ee4f42ab38ec5bd2682487d
> Author: Matt Carlson <mcarlson@broadcom.com>
> Date: Thu May 19 12:12:52 2011 +0000
>
> tg3: Move TSO_CAPABLE assignment
>
> This patch moves the code that asserts the TSO_CAPABLE flag closer
> to
> where the TSO capabilities flags are set. There isn't a good
> enough
> reason for the code to be separated.
>
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Reviewed-by: Michael Chan <mchan@broadcom.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
Thanks, I'll look into this.
>
> On the other hand, losing the SoL console even temporarily during boot
> (as it happens with a minimal kernel before this commit) isn't nice
> either. I'll try to look after that, too, just mentioning it here...
This is expected as the driver has to reset the link and you'll lose SoL
for a few seconds until link comes back up. We can look into an
enhancement to not touch the link if it is already in a good state when
the driver comes up.
^ permalink raw reply
* RE: [PATCH net, 3/3] hyperv: Fix page buffer handling in rndis_filter_send_request()
From: Haiyang Zhang @ 2012-10-02 14:28 UTC (permalink / raw)
To: Dan Carpenter
Cc: olaf@aepfle.de, netdev@vger.kernel.org, jasowang@redhat.com,
linux-kernel@vger.kernel.org, devel@linuxdriverproject.org,
davem@davemloft.net
In-Reply-To: <20121002083847.GR4587@mwanda>
> -----Original Message-----
> From: Dan Carpenter [mailto:dan.carpenter@oracle.com]
> Sent: Tuesday, October 02, 2012 4:39 AM
> To: Haiyang Zhang
> Cc: davem@davemloft.net; netdev@vger.kernel.org; olaf@aepfle.de;
> jasowang@redhat.com; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org
> Subject: Re: [PATCH net, 3/3] hyperv: Fix page buffer handling in
> rndis_filter_send_request()
>
> On Mon, Oct 01, 2012 at 03:30:57PM -0700, Haiyang Zhang wrote:
> > Add another page buffer if the request message crossed page boundary.
> >
>
> What are the user visible effects of this bug fix? Please put that
> in the commit message.
Will do.
Thanks,
- Haiyang
^ permalink raw reply
* [PATCHv4] rtlwifi: rtl8192ce: rtl8192cu: use %*phC to dump small buffers
From: Andy Shevchenko @ 2012-10-02 14:19 UTC (permalink / raw)
To: Larry Finger, Chaoming Li, David S . Miller,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Joe Perches
Cc: Andy Shevchenko
The patch changes a bit trace output format in the rtl_cam_program_entry() to
print prefix and the actual data on the same line. Moreover the %*phC outputs
each byte as 2 hex digits, which is slightly different to the original %x.
Signed-off-by: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
ACKed-by: Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
---
drivers/net/wireless/rtlwifi/cam.c | 7 ++-----
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 6 ++----
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 6 ++----
3 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
index 5b4b4d4..ca69e35 100644
--- a/drivers/net/wireless/rtlwifi/cam.c
+++ b/drivers/net/wireless/rtlwifi/cam.c
@@ -52,11 +52,8 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
u32 target_content = 0;
u8 entry_i;
- RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
- "key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
- key_cont_128[0], key_cont_128[1],
- key_cont_128[2], key_cont_128[3],
- key_cont_128[4], key_cont_128[5]);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "key_cont_128: %6phC\n",
+ key_cont_128);
for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index 86d73b3..038c02c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -1918,10 +1918,8 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
(ratr_index << 28);
rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
- "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
- ratr_index, ratr_bitmap,
- rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
- rate_mask[4]);
+ "Rate_index:%x, ratr_val:%x, %5phC\n",
+ ratr_index, ratr_bitmap, rate_mask);
rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
if (macid != 0)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 4bbb711..7d36a94 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -2169,10 +2169,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
ratr_index << 28);
rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
- "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
- ratr_index, ratr_bitmap,
- rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
- rate_mask[4]);
+ "Rate_index:%x, ratr_val:%x, %5phC\n",
+ ratr_index, ratr_bitmap, rate_mask);
rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
}
--
1.7.10.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
* Re: GPF in ip6_dst_lookup_tail
From: Dave Jones @ 2012-10-02 13:59 UTC (permalink / raw)
To: netdev
In-Reply-To: <20120927140323.GA1459@redhat.com>
On Thu, Sep 27, 2012 at 10:03:23AM -0400, Dave Jones wrote:
> general protection fault: 0000 [#1] SMP
> Modules linked in: ipt_ULOG tun fuse binfmt_misc nfnetlink nfc caif_socket caif phonet can llc2 pppoe pppox ppp_generic slhc irda crc_ccitt rds af_key decnet rose x25 atm netrom appletalk ipx p8023 psnap p8022 llc ax25 lockd sunrpc bluetooth rfkill ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack kvm_intel kvm usb_debug crc32c_intel ghash_clmulni_intel microcode pcspkr i2c_i801 e1000e uinput i915 video i2c_algo_bit drm_kms_helper drm i2c_core
> CPU 4
> Pid: 21651, comm: trinity-child4 Not tainted 3.6.0-rc7+ #55
> RIP: 0010:[<ffffffff81628797>] [<ffffffff81628797>] ip6_dst_lookup_tail+0x147/0x380
> RSP: 0018:ffff8800144c3a48 EFLAGS: 00010286
> RAX: 8000000000000011 RBX: ffff8800144c3b00 RCX: 0000000000000001
> RDX: ffff8800144c2000 RSI: 0000000000000000 RDI: 0000000000000282
> RBP: ffff8800144c3ae8 R08: 0000000000000014 R09: ffff8800034708c0
> R10: ffffffff81c34a60 R11: 0000000000000000 R12: 0000000000000000
> R13: ffff8800144c3bf0 R14: ffffffff81cd9580 R15: ffff8801052e4200
> FS: 00007f74949af740(0000) GS:ffff880148400000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00000000051f7000 CR3: 00000000a8f72000 CR4: 00000000001407e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process trinity-child4 (pid: 21651, threadinfo ffff8800144c2000, task ffff880003470000)
> Stack:
> ffffffff81628730 ffffffff810dafbf ffff880003470000 0000000000000000
> ffff8800144c3aa8 0000000000000282 ffff8800144c3aa8 ffff88013d79dd40
> ffff8801052e4200 0000000000000003 0000000000000001 0000000000000000
> Call Trace:
> [<ffffffff81628730>] ? ip6_dst_lookup_tail+0xe0/0x380
> [<ffffffff810dafbf>] ? lock_release_holdtime.part.26+0xf/0x180
> [<ffffffff81556b20>] ? sock_def_wakeup+0x1b0/0x1b0
> [<ffffffff81628a9b>] ip6_sk_dst_lookup_flow+0xcb/0x1b0
> [<ffffffff81649d8d>] udpv6_sendmsg+0x6ad/0xc40
> [<ffffffff81023af9>] ? native_sched_clock+0x19/0x80
> [<ffffffff810db438>] ? trace_hardirqs_off_caller+0x28/0xd0
> [<ffffffff810db4ed>] ? trace_hardirqs_off+0xd/0x10
> [<ffffffff815e613a>] inet_sendmsg+0x12a/0x240
> [<ffffffff815e6010>] ? inet_create+0x6f0/0x6f0
> [<ffffffff815562a1>] ? sock_update_classid+0xb1/0x390
> [<ffffffff81556340>] ? sock_update_classid+0x150/0x390
> [<ffffffff8155115c>] sock_sendmsg+0xbc/0xf0
> [<ffffffff810b46c9>] ? local_clock+0x99/0xc0
> [<ffffffff810dff4f>] ? lock_release_non_nested+0x2df/0x320
> [<ffffffff810dafbf>] ? lock_release_holdtime.part.26+0xf/0x180
> [<ffffffff81553740>] sys_sendto+0x130/0x180
> [<ffffffff816af8ad>] system_call_fastpath+0x1a/0x1f
> Code: c0 74 19 80 3d 0e 4d 6d 00 00 75 10 e8 73 cb af ff 85 c0 0f 85 e3 01 00 00 0f 1f 00 48 8b 03 48 8b 80 98 00 00 00 48 85 c0 74 09 <f6> 80 6d 01 00 00 de 74 48 e8 3b db a6 ff 85 c0 74 0d 80 3d d5
>
> The disassembly points here..
>
> 983 rcu_read_lock();
> 984 rt = (struct rt6_info *) *dst;
> 985 n = rt->n;
> 986 if (n && !(n->nud_state & NUD_VALID)) {
> db2: 48 85 c0 test %rax,%rax
> db5: 74 09 je dc0 <ip6_dst_lookup_tail+0x150>
> db7: f6 80 6d 01 00 00 de testb $0xde,0x16d(%rax)
> dbe: 74 48 je e08 <ip6_dst_lookup_tail+0x198>
>
> 'rt->n' is 0x8000000000000011, which looks like one of the garbage values trinity generates
I hit this a few more times last night. I'm starting to doubt my theory of where
that value came from, as every instance is always 0x8000000000000011, which seems
a little too lucky. Anyone have any idea what that number resembles ?
Working on some code to make this (and other bugs) more reproducable today..
Dave
^ permalink raw reply
* Re: [RFC PATCH net-next] tcp: introduce tcp_tw_interval to specifiy the time of TIME-WAIT
From: Neil Horman @ 2012-10-02 12:09 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, David S. Miller, Alexey Kuznetsov, Patrick McHardy,
Eric Dumazet
In-Reply-To: <1349161479.22107.17.camel@cr0>
On Tue, Oct 02, 2012 at 03:04:39PM +0800, Cong Wang wrote:
> On Fri, 2012-09-28 at 09:16 -0400, Neil Horman wrote:
> > On Fri, Sep 28, 2012 at 02:33:07PM +0800, Cong Wang wrote:
> > > On Thu, 2012-09-27 at 10:23 -0400, Neil Horman wrote:
> > > > On Thu, Sep 27, 2012 at 04:41:01PM +0800, Cong Wang wrote:
> > > > > Some customer requests this feature, as they stated:
> > > > >
> > > > > "This parameter is necessary, especially for software that continually
> > > > > creates many ephemeral processes which open sockets, to avoid socket
> > > > > exhaustion. In many cases, the risk of the exhaustion can be reduced by
> > > > > tuning reuse interval to allow sockets to be reusable earlier.
> > > > >
> > > > > In commercial Unix systems, this kind of parameters, such as
> > > > > tcp_timewait in AIX and tcp_time_wait_interval in HP-UX, have
> > > > > already been available. Their implementations allow users to tune
> > > > > how long they keep TCP connection as TIME-WAIT state on the
> > > > > millisecond time scale."
> > > > >
> > > > > We indeed have "tcp_tw_reuse" and "tcp_tw_recycle", but these tunings
> > > > > are not equivalent in that they cannot be tuned directly on the time
> > > > > scale nor in a safe way, as some combinations of tunings could still
> > > > > cause some problem in NAT. And, I think second scale is enough, we don't
> > > > > have to make it in millisecond time scale.
> > > > >
> > > > I think I have a little difficultly seeing how this does anything other than
> > > > pay lip service to actually having sockets spend time in TIME_WAIT state. That
> > > > is to say, while I see users using this to just make the pain stop. If we wait
> > > > less time than it takes to be sure that a connection isn't being reused (either
> > > > by waiting two segment lifetimes, or by checking timestamps), then you might as
> > > > well not wait at all. I see how its tempting to be able to say "Just don't wait
> > > > as long", but it seems that theres no difference between waiting half as long as
> > > > the RFC mandates, and waiting no time at all. Neither is a good idea.
> > >
> > > I don't think reducing TIME_WAIT is a good idea either, but there must
> > > be some reason behind as several UNIX provides a microsecond-scale
> > > tuning interface, or maybe in non-recycle mode, their RTO is much less
> > > than 2*MSL?
> > >
> > My guess? Cash was the reason. I certainly wasn't there for any of those
> > developments, but a setting like this just smells to me like some customer waved
> > some cash under IBM's/HP's/Sun's nose and said, "We'd like to get our tcp
> > sockets back to CLOSED state faster, what can you do for us?"
>
> Yeah, maybe. But it still doesn't make sense even if they are sure their
> packets are impossible to linger in their high-speed LAN for 2*MSL?
>
No it doesn't make sense, but the universal rule is that the business people
will focus more on revenue recognition than on sound design pracice.
> >
> > > >
> > > > Given the problem you're trying to solve here, I'll ask the standard question in
> > > > response: How does using SO_REUSEADDR not solve the problem? Alternatively, in
> > > > a pinch, why not reduce the tcp_max_tw_buckets sufficiently to start forcing
> > > > TIME_WAIT sockets back into CLOSED state?
> > > >
> > > > The code looks fine, but the idea really doesn't seem like a good plan to me.
> > > > I'm sure HPUX/Solaris/AIX/etc have done this in response to customer demand, but
> > > > that doesn't make it the right solution.
> > > >
> > >
> > > *I think* the customer doesn't want to modify their applications, so
> > > that is why they don't use SO_REUSERADDR.
> > >
> > Well, ok, thats a legitimate distro problem. What its not is an upstream
> > problem. Fixing the appilcation is the right thing to do, wether or not they
> > want to.
> >
> > > I didn't know tcp_max_tw_buckets can do the trick, nor the customer, so
> > > this is a side effect of tcp_max_tw_buckets? Is it documented?
> > man 7 tcp:
> > tcp_max_tw_buckets (integer; default: see below; since Linux 2.4)
> > The maximum number of sockets in TIME_WAIT state allowed in the
> > system. This limit exists only to prevent simple
> > denial-of-service attacks. The default value of NR_FILE*2 is
> > adjusted depending on the memory in the system. If this number
> > is exceeded, the socket is closed and a warning is printed.
> >
>
> Hey, "a warning is printed" seems not very friendly. ;)
>
No, its not very friendly, but the people using this are violating the RFC,
which isn't very friendly. :)
> Thanks!
>
>
^ permalink raw reply
* Re: tg3 driver upgrade (Linux 2.6.32 -> 3.2) breaks IBM Bladecenter SoL
From: Ferenc Wagner @ 2012-10-02 12:07 UTC (permalink / raw)
To: Michael Chan
Cc: netdev, Matt Carlson, Grant Likely, Rob Herring, linux-kernel,
wferi
In-Reply-To: <1349083982.5420.16.camel@LTIRV-MCHAN1.corp.ad.broadcom.com>
"Michael Chan" <mchan@broadcom.com> writes:
> On Fri, 2012-09-28 at 22:45 +0200, Ferenc Wagner wrote:
>
>> Upgrading the kernel on our HS20 blades resulted in their SoL (serial
>> over LAN) connection being broken. The disconnection happens when eth0
>> (the interface involved in SoL) is brought up during the boot sequence.
>> If I later "ip link set eth0 down", then the connection is restored, but
>> "ip link set eth0 up" breaks it again on 3.2. ethtool -a, -c, -g, -k
>> and -u show no difference; ethtool -i on the 2.6.32 kernel reports:
>>
>> driver: tg3
>> version: 3.116
>> firmware-version: 5704s-v3.38, ASFIPMIs v2.47
>> bus-info: 0000:05:01.0
>>
>> In the 3.2 kernel the driver version is 3.121.
>
> 2.6.32 to 3.2 is a big jump. Can you narrow this down further? It will
> be hard for us to find a HS20 with 5704 to test this. Thanks.
I'm done with bisecting it: the first bad commit is:
commit dabc5c670d3f86d15ee4f42ab38ec5bd2682487d
Author: Matt Carlson <mcarlson@broadcom.com>
Date: Thu May 19 12:12:52 2011 +0000
tg3: Move TSO_CAPABLE assignment
This patch moves the code that asserts the TSO_CAPABLE flag closer to
where the TSO capabilities flags are set. There isn't a good enough
reason for the code to be separated.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
On the other hand, losing the SoL console even temporarily during boot
(as it happens with a minimal kernel before this commit) isn't nice
either. I'll try to look after that, too, just mentioning it here...
--
Regards,
Feri.
^ permalink raw reply
* [patch] bnx2x: use strlcpy() to copy a string
From: Dan Carpenter @ 2012-10-02 11:47 UTC (permalink / raw)
To: Eilon Greenstein; +Cc: netdev, kernel-janitors
DRV_MODULE_VERSION is smaller than the ->version buffer so the memcpy()
copies 1 byte past the end of the string. It's not super harmful, but
it makes the static checkers complain.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index f7ed122..d5648fc 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -3052,9 +3052,8 @@ static void bnx2x_drv_info_ether_stat(struct bnx2x *bp)
struct eth_stats_info *ether_stat =
&bp->slowpath->drv_info_to_mcp.ether_stat;
- /* leave last char as NULL */
- memcpy(ether_stat->version, DRV_MODULE_VERSION,
- ETH_STAT_INFO_VERSION_LEN - 1);
+ strlcpy(ether_stat->version, DRV_MODULE_VERSION,
+ ETH_STAT_INFO_VERSION_LEN);
bp->sp_objs[0].mac_obj.get_n_elements(bp, &bp->sp_objs[0].mac_obj,
DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED,
^ permalink raw reply related
* [PATCH 2/2] net: ethernet: Remove obsolete comment
From: matthew @ 2012-10-02 11:41 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev, davem, Matthew Walster
In-Reply-To: <1349178105-28269-1-git-send-email-matthew@walster.org>
From: Matthew Walster <matthew@walster.org>
The deleted comment was related to code I've just removed in the previous patch.
---
net/ethernet/eth.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index a9f8531..7d72108 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -170,14 +170,6 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
skb->pkt_type = PACKET_MULTICAST;
}
- /*
- * This ALLMULTI check should be redundant by 1.4
- * so don't forget to remove it.
- *
- * Seems, you forgot to remove it. All silly devices
- * seems to set IFF_PROMISC.
- */
-
else if (unlikely(!ether_addr_equal_64bits(eth->h_dest, dev->dev_addr)))
skb->pkt_type = PACKET_OTHERHOST;
--
1.7.10.4
^ permalink raw reply related
* checkpatch run on net/ethernet
From: matthew @ 2012-10-02 11:41 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev, davem
This is my first patch, it's just a checkpatch run. I figured I would also clean up the code as there appears to be long-since-obsoleted comments and code in there.
A fairly trivial change, but worthy of inclusion IMO all the same!
Matthew Walster
^ 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