Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 13/13] net: ipv6: address selection should only consider devices in L3 domain
From: David Ahern @ 2016-05-05  3:33 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern
In-Reply-To: <1462419210-10463-1-git-send-email-dsa@cumulusnetworks.com>

IPv6 version of 3f2fb9a834cb ("net: l3mdev: address selection should only
consider devices in L3 domain"). IPv4's follow up commit, a17b693cdd876
("net: l3mdev: prefer VRF master for source address selection"), is not
relevant. For IPv6 the VRF device should not be preferred over the dst_dev
as it leads to unnecessary forwarding versus a direct hop.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 net/ipv6/addrconf.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b12553905e42..d13813867460 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1577,7 +1577,14 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
 		if (idev)
 			hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
 	} else {
+		int master_idx = l3mdev_master_ifindex_rcu(dst_dev);
+
 		for_each_netdev_rcu(net, dev) {
+			/* only consider addresses on devices in the
+			 * same L3 domain
+			 */
+			if (l3mdev_master_ifindex_rcu(dev) != master_idx)
+				continue;
 			idev = __in6_dev_get(dev);
 			if (!idev)
 				continue;
-- 
2.1.4

^ permalink raw reply related

* Re: task_diag: add a new interface to get information about processes
From: Andy Lutomirski @ 2016-05-05  3:39 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Eric W. Biederman, David S. Miller, Network Development,
	Andrey Vagin, Linus Torvalds
In-Reply-To: <20160504191436.7dfa3a55@xeon-e3>

On May 4, 2016 7:14 PM, "Stephen Hemminger" <stephen@networkplumber.org> wrote:
>
> On Wed, 4 May 2016 15:34:21 -0700
> Andrey Vagin <avagin@openvz.org> wrote:
>
> > Hi Stephen,
> >
> > On Wed, May 4, 2016 at 1:22 PM, Stephen Hemminger
> > <stephen@networkplumber.org> wrote:
> > > I understand how reading /proc or /sys can be a bottleneck, but this
> > > proposed method using a system call is the wrong way to do this.
> > >
> > > Why not use netlink like other systems do which allows a message
> > > based response which allows for future changes (no fixed datastructures),
> > > and is message based.
> > >
> > > Generic netlink has already been used by several other subsystems.
> >
> > I used netlink in two first versions of task_diag, but then Andy
> > convinced me that netlink interfaces are not ideal for this case. I
> > added him into Cс.
> >
> > Here is a thread with our discussion about using netlink for
> > task_diag: https://lkml.org/lkml/2015/12/15/520
> > Can I ask you to read it and give your comments? It would be nice to
> > find a way how to use netlink sockets instead of creating a new
> > interface.
> >
> > Thanks,
> > Andrew
>
> LKML is too busy, no one reads it anymore :-)
> Since this is netlink related you need to discuss it on netdev.
>
> The objection seems to be time or creation versus time of use and permissions.
> Netlink internally is not really message based all responses are generated
> in the context of the send().  You need credentials to create
> the socket, but the actual response will occur in the context of the calling
> process. I don't see how that is substantially different than a system call.
>
>

Linus, this is Yet Another Credential Fuckup, except that it hasn't
happened yet, so it's okay.  The tl;dr is that Andrey wants to add an
interface to ask a pidns some questions, and netlink looks natural,
except that using netlink sockets to interrogate a pidns seems rather
problematic.  I would also love to see a decent interface for
interrogating user namespaces, and again, netlink would be great,
except that it's a socket and makes no sense in this context.

Netlink had, and possibly still has, tons of serious security bugs
involving code checking send() callers' creds.  I found and fixed a
few a couple years ago.  To reiterate once again, send() CANNOT use
caller creds safely.  (I feel like I say this once every few weeks.
It's getting old.)

I realize that it's convenient to use a socket as a context to keep
state between syscalls, but it has some annoying side effects:

 - It makes people want to rely on send()'s caller's creds.

 - It's miserable in combination with seccomp.

 - It doesn't play nicely with namespaces.

 - It makes me wonder why things like task_diag, which have nothing to
do with networking, seem to get tangled up with networking.


Would it be worth considering adding a parallel interface, using it
for new things, and slowly migrating old use cases over?

int issue_kernel_command(int ns, int command, const struct iovec *iov,
int iovcnt, int flags);

ns is an actual namespace fd or:

KERNEL_COMMAND_CURRENT_NETNS
KERNEL_COMMAND_CURRENT_PIDNS
etc, or a special one:
KERNEL_COMMAND_GLOBAL.  KERNEL_COMMAND_GLOBAL can't be used in a
non-root namespace.

KERNEL_COMMAND_GLOBAL works even for namespaced things, if the
relevant current ns is the init namespace.  (This feature is optional,
but it would allow gradually namespacing global things.)

command is an enumerated command.  Each command implies a namespace
type, and, if you feed this thing the wrong namespace type, you get
EINVAL.  The high bit of command indicates whether it's read-only
command.

iov gives a command in the format expected, which, for the most part,
would be a netlink message.

The return value is an fd that you can call read/readv on to read the
response.  It's not a socket (or at least you can't do normal socket
operations on it if it is a socket behind the scenes).  The
implementation of read() promises *not* to look at caller creds.  The
returned fd is unconditionally cloexec -- it's 2016 already.  Sheesh.

When you've read all the data, all you can do is close the fd.  You
can't issue another command on the same fd.  You also can't call
write() or send() on the fd unless someone has a good reason why you
should be able to and why it's safe.  You can't issue another command
on the same fd.


I imagine that the implementation could re-use a bunch of netlink code
under the hood.


--Andy

^ permalink raw reply

* Re: [net-next 08/15] i40e: Allow user to change input set mask for flow director
From: Alexander Duyck @ 2016-05-05  3:52 UTC (permalink / raw)
  To: Jeff Kirsher
  Cc: David Miller, Kiran Patil, Netdev, Neil Horman, sassmann,
	John Greene
In-Reply-To: <1461704148-114349-9-git-send-email-jeffrey.t.kirsher@intel.com>

On Tue, Apr 26, 2016 at 1:55 PM, Jeff Kirsher
<jeffrey.t.kirsher@intel.com> wrote:
> From: Kiran Patil <kiran.patil@intel.com>
>
> This patch implements feature, which allows user to change
> input set mask for flow director using side-band channel.
> This patch adds definition of FLOW_TYPE_MASK into the header file.
> With this patch, user can now specify less than 4 tuple(src ip, dsp ip,
> src port, dst port) for flow type TCP4/UDP4.

Isn't that what the mask field in the flow specifier is for?  It seems
like you guys are trying to come up with your own alternative to how
this has been done in the past.  It looks like this driver is badly
broken and it isn't implementing flow director.  It is implementing a
bad hack that is trying to pass itself off as flow director.

I don't know who thought it was okay to come up with your own
interpretation on how the fields are supposed to be used but whoever
did it made a real mess of things.  I am pretty sure the ixgbe driver
and the i40e driver are playing by two completely different rule
books.  If you printed an i40e rule and tried to apply it to ixgbe it
just wouldn't work because you guys didn't do basic things like
actually use the mask fields, in the other direction you guys totally
ignored the mask fields which really isn't okay because you should
throw an error if someone tries to get the driver to do something it
cannot support.

I'd say you are better off scrapping this whole patch and fixing flow
director so that you actually use the mask fields correctly because
the current implementation is badly broken and breaking it further
isn't going to help.  You need to add support for validating the mask
fields to the driver and that will solve the original problem that
this patch is attempting to work around.

- Alex

^ permalink raw reply

* Re: [PATCH net-next v2] macvtap: add namespace support to the sysfs device class
From: David Miller @ 2016-05-05  3:53 UTC (permalink / raw)
  To: marc; +Cc: netdev, ebiederm
In-Reply-To: <CAPSAET_zPYBvMdTQ5m1O9xO178Jk0b93rC1cy0CNY2yinUbnXw@mail.gmail.com>

From: Marc Angel <marc@arista.com>
Date: Thu, 5 May 2016 01:33:09 +0100

> On Wed, May 4, 2016 at 9:04 PM, David Miller <davem@davemloft.net> wrote:
>> From: Marc Angel <marc@arista.com>
>> Date: Tue,  3 May 2016 20:30:54 +0200
>>
>>> @@ -1274,6 +1285,7 @@ static int macvtap_device_event(struct notifier_block *unused,
>>>                               unsigned long event, void *ptr)
>>>  {
>>>       struct net_device *dev = netdev_notifier_info_to_dev(ptr);
>>> +     const char *tap_name = kasprintf(GFP_KERNEL, "tap%d", dev->ifindex);
>>>       struct macvlan_dev *vlan;
>>>       struct device *classdev;
>>>       dev_t devt;
>>
>> This 'tap_name' buffer seems to be leaked in several code paths.
> 
> Sorry about that... V3 should be better.

V3 doesn't apply cleanly to net-next, please respin your patch against
the current tree.

Thanks.

^ permalink raw reply

* Re: [net-next 08/15] i40e: Allow user to change input set mask for flow director
From: David Miller @ 2016-05-05  3:57 UTC (permalink / raw)
  To: kiran.patil; +Cc: jeffrey.t.kirsher, netdev, nhorman, sassmann, jogreene
In-Reply-To: <572AB43E.2020007@intel.com>

From: "Patil, Kiran" <kiran.patil@intel.com>
Date: Wed, 4 May 2016 19:47:26 -0700

> This is not new feature implemented in i40e driver. This is the
> original feature of ethtool which allows user to specify subset of
> tuple for setting up flow director.

Where is the interpretation of this special value defined in the
ethtool headers?

If it doesn't even have a macro for that magic constant value, it's
not part of the interface at all.

If the only other example of doing this trick is another Intel driver,
that lends even less credence to your arguments that this is a defined
interface.  Rather, it makes it look even more like an Intel specific
behavior.  Vendor specific behaviors of interfaces is exactly what we
are trying to avoid.

^ permalink raw reply

* Re: [PATCH net-next 00/13] net: Various VRF patches
From: David Miller @ 2016-05-05  3:59 UTC (permalink / raw)
  To: dsa; +Cc: netdev
In-Reply-To: <1462419210-10463-1-git-send-email-dsa@cumulusnetworks.com>

From: David Ahern <dsa@cumulusnetworks.com>
Date: Wed,  4 May 2016 20:33:17 -0700

> Various fixes and features for VRF over the past few months.

I really dislike a patch series that is simply a hodge podge of
unrelated things.

Please group your changes into logical bunches, and submit them as
groups one at a time.

Thank you.

^ permalink raw reply

* Re: [PATCH net-next 00/13] net: Various VRF patches
From: David Ahern @ 2016-05-05  4:13 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20160504.235932.203671415532849729.davem@davemloft.net>

On 5/4/16 9:59 PM, David Miller wrote:
> From: David Ahern <dsa@cumulusnetworks.com>
> Date: Wed,  4 May 2016 20:33:17 -0700
>
>> Various fixes and features for VRF over the past few months.
>
> I really dislike a patch series that is simply a hodge podge of
> unrelated things.
>
> Please group your changes into logical bunches, and submit them as
> groups one at a time.

I can send them out based on the grouping mentioned in the cover letter, 
but they apply in order. I believe patch 4 is the only one that is not 
order dependent.

After several days of wrestling with the order of patches 7-13 they are 
all inherently dependent on patch 5. If you look at the diff summary 
most of the code changes are to l3mdev.{c,h} and vrf.c.

I will break out the first 4 as separate patches and re-send.

^ permalink raw reply

* [PATCH net-next] net: vrf: Create FIB tables on link create
From: David Ahern @ 2016-05-05  4:18 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Tables have to exist for VRFs to function. Ensure they exist
when VRF device is created.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 drivers/net/vrf.c       | 11 +++++++++--
 net/ipv4/fib_frontend.c |  1 +
 net/ipv6/ip6_fib.c      |  1 +
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 8a8f1e58b415..2f2aac1b598f 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -372,9 +372,13 @@ static int vrf_rt6_create(struct net_device *dev)
 	if (!rt6)
 		goto out;
 
-	rt6->dst.output	= vrf_output6;
-	rt6->rt6i_table = fib6_get_table(net, vrf->tb_id);
 	dst_hold(&rt6->dst);
+
+	rt6->rt6i_table = fib6_new_table(net, vrf->tb_id);
+	if (!rt6->rt6i_table)
+		goto out;
+
+	rt6->dst.output	= vrf_output6;
 	vrf->rt6 = rt6;
 	rc = 0;
 out:
@@ -462,6 +466,9 @@ static struct rtable *vrf_rtable_create(struct net_device *dev)
 	struct net_vrf *vrf = netdev_priv(dev);
 	struct rtable *rth;
 
+	if (!fib_new_table(dev_net(dev), vrf->tb_id))
+		return NULL;
+
 	rth = rt_dst_alloc(dev, 0, RTN_UNICAST, 1, 1, 0);
 	if (rth) {
 		rth->dst.output	= vrf_output;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 63566ec54794..ef2ebeb89d0f 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -110,6 +110,7 @@ struct fib_table *fib_new_table(struct net *net, u32 id)
 	hlist_add_head_rcu(&tb->tb_hlist, &net->ipv4.fib_table_hash[h]);
 	return tb;
 }
+EXPORT_SYMBOL_GPL(fib_new_table);
 
 /* caller must hold either rtnl or rcu read lock */
 struct fib_table *fib_get_table(struct net *net, u32 id)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index ea071fad67a0..1bcef2369d64 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -240,6 +240,7 @@ struct fib6_table *fib6_new_table(struct net *net, u32 id)
 
 	return tb;
 }
+EXPORT_SYMBOL_GPL(fib6_new_table);
 
 struct fib6_table *fib6_get_table(struct net *net, u32 id)
 {
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH net-next] tcp: two more missing bh disable
From: David Miller @ 2016-05-05  4:25 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1462400849.13075.8.camel@edumazet-glaptop3.roam.corp.google.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 04 May 2016 15:27:29 -0700

> From: Eric Dumazet <edumazet@google.com>
> 
> percpu_counter only have protection against preemption.
> 
> TCP stack uses them possibly from BH, so we need BH protection
> in contexts that could be run in process context
> 
> Fixes: c10d9310edf5 ("tcp: do not assume TCP code is non preemptible")
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied.

^ permalink raw reply

* Re: [net-next] MAINTAINERS: Cleanup Intel Wired LAN maintainers list
From: David Miller @ 2016-05-05  4:25 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, nhorman, sassmann, jogreene
In-Reply-To: <1462402179-125720-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed,  4 May 2016 15:49:39 -0700

> With the recent "retirements" and other changes, make the maintainers
> list a lot less confusing and a bit more straight forward.
> 
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
> Acked-by: Shannon Nelson <sln@onemain.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next] net: vrf: Create FIB tables on link create
From: David Miller @ 2016-05-05  4:24 UTC (permalink / raw)
  To: dsa; +Cc: netdev
In-Reply-To: <1462421887-10712-1-git-send-email-dsa@cumulusnetworks.com>

From: David Ahern <dsa@cumulusnetworks.com>
Date: Wed,  4 May 2016 21:18:07 -0700

> @@ -372,9 +372,13 @@ static int vrf_rt6_create(struct net_device *dev)
>  	if (!rt6)
>  		goto out;
>  
> -	rt6->dst.output	= vrf_output6;
> -	rt6->rt6i_table = fib6_get_table(net, vrf->tb_id);
>  	dst_hold(&rt6->dst);
> +
> +	rt6->rt6i_table = fib6_new_table(net, vrf->tb_id);
> +	if (!rt6->rt6i_table)
> +		goto out;
> +
> +	rt6->dst.output	= vrf_output6;
>  	vrf->rt6 = rt6;
>  	rc = 0;
>  out:

This leaks rt6.

^ permalink raw reply

* [PATCH] net: ipv6: tcp reset, icmp need to consider L3 domain
From: David Ahern @ 2016-05-05  4:26 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Responses for packets to unused ports are getting lost with L3 domains.

IPv4 has ip_send_unicast_reply for sending TCP responses which accounts
for L3 domains; update the IPv6 counterpart tcp_v6_send_response.
For icmp the L3 master check needs to be moved up in icmp6_send
to properly respond to UDP packets to a port with no listener.

Fixes: ca254490c8df ("net: Add VRF support to IPv6 stack")
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 net/ipv6/icmp.c     | 5 ++---
 net/ipv6/tcp_ipv6.c | 7 ++++++-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 9554b99a8508..4527285fcaa2 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -446,6 +446,8 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 
 	if (__ipv6_addr_needs_scope_id(addr_type))
 		iif = skb->dev->ifindex;
+	else
+		iif = l3mdev_master_ifindex(skb->dev);
 
 	/*
 	 *	Must not send error if the source does not uniquely
@@ -500,9 +502,6 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 	else if (!fl6.flowi6_oif)
 		fl6.flowi6_oif = np->ucast_oif;
 
-	if (!fl6.flowi6_oif)
-		fl6.flowi6_oif = l3mdev_master_ifindex(skb->dev);
-
 	dst = icmpv6_route_lookup(net, skb, sk, &fl6);
 	if (IS_ERR(dst))
 		goto out;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7bdc9c9c231b..c4efaa97280c 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -810,8 +810,13 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
 	fl6.flowi6_proto = IPPROTO_TCP;
 	if (rt6_need_strict(&fl6.daddr) && !oif)
 		fl6.flowi6_oif = tcp_v6_iif(skb);
-	else
+	else {
+		if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
+			oif = skb->skb_iif;
+
 		fl6.flowi6_oif = oif;
+	}
+
 	fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark);
 	fl6.fl6_dport = t1->dest;
 	fl6.fl6_sport = t1->source;
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH net-next] net: vrf: Create FIB tables on link create
From: David Ahern @ 2016-05-05  4:29 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20160505.002448.1005276153595006235.davem@davemloft.net>

On 5/4/16 10:24 PM, David Miller wrote:
> From: David Ahern <dsa@cumulusnetworks.com>
> Date: Wed,  4 May 2016 21:18:07 -0700
>
>> @@ -372,9 +372,13 @@ static int vrf_rt6_create(struct net_device *dev)
>>   	if (!rt6)
>>   		goto out;
>>
>> -	rt6->dst.output	= vrf_output6;
>> -	rt6->rt6i_table = fib6_get_table(net, vrf->tb_id);
>>   	dst_hold(&rt6->dst);
>> +
>> +	rt6->rt6i_table = fib6_new_table(net, vrf->tb_id);
>> +	if (!rt6->rt6i_table)
>> +		goto out;
>> +
>> +	rt6->dst.output	= vrf_output6;
>>   	vrf->rt6 = rt6;
>>   	rc = 0;
>>   out:
>
> This leaks rt6.
>

Indeed. That fact was lost by follow on patches which fix the ordering.

^ permalink raw reply

* [PATCH net-next v2] net: vrf: Create FIB tables on link create
From: David Ahern @ 2016-05-05  4:46 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

Tables have to exist for VRFs to function. Ensure they exist
when VRF device is created.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
v2
- create table before rt6 allocation per comment from DaveM

 drivers/net/vrf.c       | 13 +++++++++++--
 net/ipv4/fib_frontend.c |  1 +
 net/ipv6/ip6_fib.c      |  1 +
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 8a8f1e58b415..4b2461ae5d3b 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -364,17 +364,23 @@ static int vrf_rt6_create(struct net_device *dev)
 {
 	struct net_vrf *vrf = netdev_priv(dev);
 	struct net *net = dev_net(dev);
+	struct fib6_table *rt6i_table;
 	struct rt6_info *rt6;
 	int rc = -ENOMEM;
 
+	rt6i_table = fib6_new_table(net, vrf->tb_id);
+	if (!rt6i_table)
+		goto out;
+
 	rt6 = ip6_dst_alloc(net, dev,
 			    DST_HOST | DST_NOPOLICY | DST_NOXFRM | DST_NOCACHE);
 	if (!rt6)
 		goto out;
 
-	rt6->dst.output	= vrf_output6;
-	rt6->rt6i_table = fib6_get_table(net, vrf->tb_id);
 	dst_hold(&rt6->dst);
+
+	rt6->rt6i_table = rt6i_table;
+	rt6->dst.output	= vrf_output6;
 	vrf->rt6 = rt6;
 	rc = 0;
 out:
@@ -462,6 +468,9 @@ static struct rtable *vrf_rtable_create(struct net_device *dev)
 	struct net_vrf *vrf = netdev_priv(dev);
 	struct rtable *rth;
 
+	if (!fib_new_table(dev_net(dev), vrf->tb_id))
+		return NULL;
+
 	rth = rt_dst_alloc(dev, 0, RTN_UNICAST, 1, 1, 0);
 	if (rth) {
 		rth->dst.output	= vrf_output;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 63566ec54794..ef2ebeb89d0f 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -110,6 +110,7 @@ struct fib_table *fib_new_table(struct net *net, u32 id)
 	hlist_add_head_rcu(&tb->tb_hlist, &net->ipv4.fib_table_hash[h]);
 	return tb;
 }
+EXPORT_SYMBOL_GPL(fib_new_table);
 
 /* caller must hold either rtnl or rcu read lock */
 struct fib_table *fib_get_table(struct net *net, u32 id)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index ea071fad67a0..1bcef2369d64 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -240,6 +240,7 @@ struct fib6_table *fib6_new_table(struct net *net, u32 id)
 
 	return tb;
 }
+EXPORT_SYMBOL_GPL(fib6_new_table);
 
 struct fib6_table *fib6_get_table(struct net *net, u32 id)
 {
-- 
2.1.4

^ permalink raw reply related

* [PATCH net-next 0/2] net: l3mdev: Allow send on enslaved interface
From: David Ahern @ 2016-05-05  4:54 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern

First patch preps for the second. The second is required for several use
cases such as ping on an interface and BFD that need to send packets on
a specific interface, including ones enslaved to a VRF device.

David Ahern (2):
  net: l3mdev: Move get_saddr and rt6_dst
  net: l3mdev: Allow send on enslaved interface

 drivers/net/vrf.c    |  2 ++
 include/net/l3mdev.h | 56 +++-----------------------------------------
 net/ipv4/route.c     |  4 ++++
 net/ipv6/route.c     |  2 +-
 net/l3mdev/l3mdev.c  | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 75 insertions(+), 54 deletions(-)

-- 
2.1.4

^ permalink raw reply

* [PATCH net-next 1/2] net: l3mdev: Move get_saddr and rt6_dst
From: David Ahern @ 2016-05-05  4:54 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern
In-Reply-To: <1462424050-16084-1-git-send-email-dsa@cumulusnetworks.com>

Move l3mdev_rt6_dst_by_oif and l3mdev_get_saddr to l3mdev.c. Collapse
l3mdev_get_rt6_dst into l3mdev_rt6_dst_by_oif since it is the only
user and keep the l3mdev_get_rt6_dst name for consistency with other
hooks.

A follow-on patch adds more code to these functions making them long
for inlined functions.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 include/net/l3mdev.h | 56 +++-------------------------------------------------
 net/ipv6/route.c     |  2 +-
 net/l3mdev/l3mdev.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 54 deletions(-)

diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h
index c43a9c73de5e..78872bd1dc2c 100644
--- a/include/net/l3mdev.h
+++ b/include/net/l3mdev.h
@@ -130,52 +130,9 @@ static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
 	return rc;
 }
 
-static inline int l3mdev_get_saddr(struct net *net, int ifindex,
-				   struct flowi4 *fl4)
-{
-	struct net_device *dev;
-	int rc = 0;
-
-	if (ifindex) {
-
-		rcu_read_lock();
-
-		dev = dev_get_by_index_rcu(net, ifindex);
-		if (dev && netif_is_l3_master(dev) &&
-		    dev->l3mdev_ops->l3mdev_get_saddr) {
-			rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
-		}
-
-		rcu_read_unlock();
-	}
-
-	return rc;
-}
+int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4);
 
-static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
-						   const struct flowi6 *fl6)
-{
-	if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rt6_dst)
-		return dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
-
-	return NULL;
-}
-
-static inline
-struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
-					const struct flowi6 *fl6)
-{
-	struct dst_entry *dst = NULL;
-	struct net_device *dev;
-
-	dev = dev_get_by_index(net, fl6->flowi6_oif);
-	if (dev) {
-		dst = l3mdev_get_rt6_dst(dev, fl6);
-		dev_put(dev);
-	}
-
-	return dst;
-}
+struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6);
 
 #else
 
@@ -233,14 +190,7 @@ static inline int l3mdev_get_saddr(struct net *net, int ifindex,
 }
 
 static inline
-struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
-				     const struct flowi6 *fl6)
-{
-	return NULL;
-}
-static inline
-struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
-					const struct flowi6 *fl6)
+struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6)
 {
 	return NULL;
 }
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index af46e19205f5..c42fa1deb152 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1190,7 +1190,7 @@ struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
 	struct dst_entry *dst;
 	bool any_src;
 
-	dst = l3mdev_rt6_dst_by_oif(net, fl6);
+	dst = l3mdev_get_rt6_dst(net, fl6);
 	if (dst)
 		return dst;
 
diff --git a/net/l3mdev/l3mdev.c b/net/l3mdev/l3mdev.c
index e925037fa0df..0fe4211e646f 100644
--- a/net/l3mdev/l3mdev.c
+++ b/net/l3mdev/l3mdev.c
@@ -97,3 +97,58 @@ u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
 	return tb_id;
 }
 EXPORT_SYMBOL_GPL(l3mdev_fib_table_by_index);
+
+/**
+ *	l3mdev_get_rt6_dst - IPv6 route lookup based on flow. Returns
+ *			     cached route for L3 master device if relevant
+ *			     to flow
+ *	@net: network namespace for device index lookup
+ *	@fl6: IPv6 flow struct for lookup
+ */
+
+struct dst_entry *l3mdev_get_rt6_dst(struct net *net,
+				     const struct flowi6 *fl6)
+{
+	struct dst_entry *dst = NULL;
+	struct net_device *dev;
+
+	dev = dev_get_by_index(net, fl6->flowi6_oif);
+	if (dev) {
+		if (netif_is_l3_master(dev) &&
+		    dev->l3mdev_ops->l3mdev_get_rt6_dst)
+			dst = dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
+		dev_put(dev);
+	}
+
+	return dst;
+}
+EXPORT_SYMBOL_GPL(l3mdev_get_rt6_dst);
+
+/**
+ *	l3mdev_get_saddr - get source address for a flow based on an interface
+ *			   enslaved to an L3 master device
+ *	@net: network namespace for device index lookup
+ *	@ifindex: Interface index
+ *	@fl4: IPv4 flow struct
+ */
+
+int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4)
+{
+	struct net_device *dev;
+	int rc = 0;
+
+	if (ifindex) {
+		rcu_read_lock();
+
+		dev = dev_get_by_index_rcu(net, ifindex);
+		if (dev && netif_is_l3_master(dev) &&
+		    dev->l3mdev_ops->l3mdev_get_saddr) {
+			rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
+		}
+
+		rcu_read_unlock();
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(l3mdev_get_saddr);
-- 
2.1.4

^ permalink raw reply related

* [PATCH net-next 2/2] net: l3mdev: Allow send on enslaved interface
From: David Ahern @ 2016-05-05  4:54 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern
In-Reply-To: <1462424050-16084-1-git-send-email-dsa@cumulusnetworks.com>

Allow udp and raw sockets to send by oif that is an enslaved interface
versus the l3mdev/VRF device. For example, this allows BFD to use ifindex
from IP_PKTINFO on a receive to send a response without the need to
convert to the VRF index. It also allows ping and ping6 to work when
specifying an enslaved interface (e.g., ping -I swp1 <ip>) which is
a natural use case.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 drivers/net/vrf.c   |  2 ++
 net/ipv4/route.c    |  4 ++++
 net/l3mdev/l3mdev.c | 20 +++++++++++++++-----
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 4b2461ae5d3b..c8db55aa8280 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -648,6 +648,8 @@ static int vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
 
 	fl4->flowi4_flags |= FLOWI_FLAG_SKIP_NH_OIF;
 	fl4->flowi4_iif = LOOPBACK_IFINDEX;
+	/* make sure oif is set to VRF device for lookup */
+	fl4->flowi4_oif = dev->ifindex;
 	fl4->flowi4_tos = tos & IPTOS_RT_MASK;
 	fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
 			     RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8c8c655bb2c4..a1f2830d8110 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2146,6 +2146,7 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
 	unsigned int flags = 0;
 	struct fib_result res;
 	struct rtable *rth;
+	int master_idx;
 	int orig_oif;
 	int err = -ENETUNREACH;
 
@@ -2155,6 +2156,9 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
 
 	orig_oif = fl4->flowi4_oif;
 
+	master_idx = l3mdev_master_ifindex_by_index(net, fl4->flowi4_oif);
+	if (master_idx)
+		fl4->flowi4_oif = master_idx;
 	fl4->flowi4_iif = LOOPBACK_IFINDEX;
 	fl4->flowi4_tos = tos & IPTOS_RT_MASK;
 	fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
diff --git a/net/l3mdev/l3mdev.c b/net/l3mdev/l3mdev.c
index 0fe4211e646f..0fd8cc1417cd 100644
--- a/net/l3mdev/l3mdev.c
+++ b/net/l3mdev/l3mdev.c
@@ -112,12 +112,19 @@ struct dst_entry *l3mdev_get_rt6_dst(struct net *net,
 	struct dst_entry *dst = NULL;
 	struct net_device *dev;
 
-	dev = dev_get_by_index(net, fl6->flowi6_oif);
-	if (dev) {
-		if (netif_is_l3_master(dev) &&
-		    dev->l3mdev_ops->l3mdev_get_rt6_dst)
+	if (fl6->flowi6_oif) {
+		rcu_read_lock();
+
+		dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
+		if (dev && netif_is_l3_slave(dev))
+			dev = netdev_master_upper_dev_get_rcu(dev);
+
+		if (dev && netif_is_l3_master(dev) &&
+		    dev->l3mdev_ops->l3mdev_get_rt6_dst) {
 			dst = dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
-		dev_put(dev);
+		}
+
+		rcu_read_unlock();
 	}
 
 	return dst;
@@ -141,6 +148,9 @@ int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4)
 		rcu_read_lock();
 
 		dev = dev_get_by_index_rcu(net, ifindex);
+		if (dev && netif_is_l3_slave(dev))
+			dev = netdev_master_upper_dev_get_rcu(dev);
+
 		if (dev && netif_is_l3_master(dev) &&
 		    dev->l3mdev_ops->l3mdev_get_saddr) {
 			rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
-- 
2.1.4

^ permalink raw reply related

* [PATCH net 1/1] qede: prevent chip hang when increasing channels
From: Sudarsana Reddy Kalluru @ 2016-05-05  4:35 UTC (permalink / raw)
  To: davem; +Cc: netdev, Yuval.Mintz, sudarsana.kalluru

qede requires qed to provide enough resources to accommodate 16 combined
channels, but that upper-bound isn't actually being enforced by it.
Instead, qed inform back to qede how many channels can be opened based on
available resources - but that calculation doesn't really take into account
the resources requested by qede; Instead it considers other FW/HW available
resources.

As a result, if a user would increase the number of channels to more than
16 [e.g., using ethtool] the chip would hang.

This change increments the resources requested by qede to 64 combined
channels instead of 16; This value is an upper bound on the possible
available channels [due to other FW/HW resources].

Signed-off-by: Sudarsana Reddy Kalluru <sudarsana.kalluru@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
---
 drivers/net/ethernet/qlogic/qede/qede_main.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 7869465..8d5248c 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1938,8 +1938,6 @@ static struct qede_dev *qede_alloc_etherdev(struct qed_dev *cdev,
 	edev->q_num_rx_buffers = NUM_RX_BDS_DEF;
 	edev->q_num_tx_buffers = NUM_TX_BDS_DEF;
 
-	DP_INFO(edev, "Allocated netdev with 64 tx queues and 64 rx queues\n");
-
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 
 	memset(&edev->stats, 0, sizeof(edev->stats));
@@ -2090,9 +2088,9 @@ static void qede_update_pf_params(struct qed_dev *cdev)
 {
 	struct qed_pf_params pf_params;
 
-	/* 16 rx + 16 tx */
+	/* 64 rx + 64 tx */
 	memset(&pf_params, 0, sizeof(struct qed_pf_params));
-	pf_params.eth_pf_params.num_cons = 32;
+	pf_params.eth_pf_params.num_cons = 128;
 	qed_ops->common->update_pf_params(cdev, &pf_params);
 }
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next] cxgb4: Reset dcb state machine and tx queue prio only if dcb is enabled
From: Hariprasad Shenai @ 2016-05-05  5:35 UTC (permalink / raw)
  To: davem; +Cc: netdev, leedom, nirranjan, Hariprasad Shenai

When cxgb4 is enabled with CONFIG_CHELSIO_T4_DCB set, VI enable command
gets called with DCB enabled. But when we have a back to back setup with
DCB enabled on one side and non-DCB on the Peer side. Firmware doesn't
send any DCB_L2_CFG, and DCB priority is never set for Tx queue.
But driver resets the queue priority and state machine whenever there
is a link down, this patch fixes it by adding a check to reset only if
cxgb4_dcb_enabled() returns true.

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 38 +++++++++++++------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index d7f40436f319..477db477b133 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -304,6 +304,22 @@ static void dcb_tx_queue_prio_enable(struct net_device *dev, int enable)
 }
 #endif /* CONFIG_CHELSIO_T4_DCB */
 
+int cxgb4_dcb_enabled(const struct net_device *dev)
+{
+#ifdef CONFIG_CHELSIO_T4_DCB
+	struct port_info *pi = netdev_priv(dev);
+
+	if (!pi->dcb.enabled)
+		return 0;
+
+	return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) ||
+		(pi->dcb.state == CXGB4_DCB_STATE_HOST));
+#else
+	return 0;
+#endif
+}
+EXPORT_SYMBOL(cxgb4_dcb_enabled);
+
 void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
 {
 	struct net_device *dev = adapter->port[port_id];
@@ -314,8 +330,10 @@ void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
 			netif_carrier_on(dev);
 		else {
 #ifdef CONFIG_CHELSIO_T4_DCB
-			cxgb4_dcb_state_init(dev);
-			dcb_tx_queue_prio_enable(dev, false);
+			if (cxgb4_dcb_enabled(dev)) {
+				cxgb4_dcb_state_init(dev);
+				dcb_tx_queue_prio_enable(dev, false);
+			}
 #endif /* CONFIG_CHELSIO_T4_DCB */
 			netif_carrier_off(dev);
 		}
@@ -494,22 +512,6 @@ static int link_start(struct net_device *dev)
 	return ret;
 }
 
-int cxgb4_dcb_enabled(const struct net_device *dev)
-{
-#ifdef CONFIG_CHELSIO_T4_DCB
-	struct port_info *pi = netdev_priv(dev);
-
-	if (!pi->dcb.enabled)
-		return 0;
-
-	return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) ||
-		(pi->dcb.state == CXGB4_DCB_STATE_HOST));
-#else
-	return 0;
-#endif
-}
-EXPORT_SYMBOL(cxgb4_dcb_enabled);
-
 #ifdef CONFIG_CHELSIO_T4_DCB
 /* Handle a Data Center Bridging update message from the firmware. */
 static void dcb_rpl(struct adapter *adap, const struct fw_port_cmd *pcmd)
-- 
2.3.4

^ permalink raw reply related

* [PATCH] cfg80211/nl80211: add wifi tx power mode switching support
From: Wei-Ning Huang @ 2016-05-05  6:44 UTC (permalink / raw)
  To: Linux-Wireless
  Cc: LKML, Johannes Berg, Sameer Nanda, Todd Broch, Wei-Ning Huang,
	davem, netdev

Recent new hardware has the ability to switch between tablet mode and
clamshell mode. To optimize WiFi performance, we want to be able to use
different power table between modes. This patch adds a new netlink
message type and cfg80211_ops function to allow userspace to trigger a
power mode switch for a given wireless interface.

Signed-off-by: Wei-Ning Huang <wnhuang@chromium.org>
---
 include/net/cfg80211.h       | 11 +++++++++++
 include/uapi/linux/nl80211.h | 21 +++++++++++++++++++++
 net/wireless/nl80211.c       | 16 ++++++++++++++++
 net/wireless/rdev-ops.h      | 22 ++++++++++++++++++++++
 net/wireless/trace.h         | 20 ++++++++++++++++++++
 5 files changed, 90 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9e1b24c..aa77fa0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2370,6 +2370,12 @@ struct cfg80211_qos_map {
  * @get_tx_power: store the current TX power into the dbm variable;
  *	return 0 if successful
  *
+ * @set_tx_power_mode: set the transmit power mode. Some device have the ability
+ *	to transform between different mode such as clamshell and tablet mode.
+ *	set_tx_power_mode allows setting of different TX power mode at runtime.
+ * @get_tx_power_mode: store the current TX power mode into the mode variable;
+ *	return 0 if successful
+ *
  * @set_wds_peer: set the WDS peer for a WDS interface
  *
  * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
@@ -2631,6 +2637,11 @@ struct cfg80211_ops {
 	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
 				int *dbm);
 
+	int	(*set_tx_power_mode)(struct wiphy *wiphy,
+				     enum nl80211_tx_power_mode mode);
+	int	(*get_tx_power_mode)(struct wiphy *wiphy,
+				     enum nl80211_tx_power_mode *mode);
+
 	int	(*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
 				const u8 *addr);
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 5a30a75..9b1888a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1796,6 +1796,9 @@ enum nl80211_commands {
  *	connecting to a PCP, and in %NL80211_CMD_START_AP to start
  *	a PCP instead of AP. Relevant for DMG networks only.
  *
+ * @NL80211_ATTR_WIPHY_TX_POWER_MODE: Transmit power mode. See
+ *      &enum nl80211_tx_power_mode for possible values.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2172,6 +2175,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_PBSS,
 
+	NL80211_ATTR_WIPHY_TX_POWER_MODE,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -3703,6 +3708,22 @@ enum nl80211_tx_power_setting {
 };
 
 /**
+ * enum nl80211_tx_power_mode - TX power mode setting
+ * @NL80211_TX_POWER_LOW: general low TX power mode
+ * @NL80211_TX_POWER_MEDIUM: general medium TX power mode
+ * @NL80211_TX_POWER_HIGH: general high TX power mode
+ * @NL80211_TX_POWER_CLAMSHELL: clamshell mode TX power mode
+ * @NL80211_TX_POWER_TABLET: tablet mode TX power mode
+ */
+enum nl80211_tx_power_mode {
+	NL80211_TX_POWER_LOW,
+	NL80211_TX_POWER_MEDIUM,
+	NL80211_TX_POWER_HIGH,
+	NL80211_TX_POWER_CLAMSHELL,
+	NL80211_TX_POWER_TABLET,
+};
+
+/**
  * enum nl80211_packet_pattern_attr - packet pattern attribute
  * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
  * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 056a730..61b474d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -402,6 +402,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
 	[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
 	[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
+	[NL80211_ATTR_WIPHY_TX_POWER_MODE] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -2218,6 +2219,21 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 			return result;
 	}
 
+	if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_MODE]) {
+		enum nl80211_tx_power_mode mode;
+		int idx = 0;
+
+		if (!rdev->ops->set_tx_power_mode)
+			return -EOPNOTSUPP;
+
+		idx = NL80211_ATTR_WIPHY_TX_POWER_MODE;
+		mode = nla_get_u32(info->attrs[idx]);
+
+		result = rdev_set_tx_power_mode(rdev, mode);
+		if (result)
+			return result;
+	}
+
 	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
 	    info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
 		u32 tx_ant, rx_ant;
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 8ae0c04..c3a1035 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -552,6 +552,28 @@ static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev,
 	return ret;
 }
 
+static inline int
+rdev_set_tx_power_mode(struct cfg80211_registered_device *rdev,
+		       enum nl80211_tx_power_mode mode)
+{
+	int ret;
+	trace_rdev_set_tx_power_mode(&rdev->wiphy, mode);
+	ret = rdev->ops->set_tx_power_mode(&rdev->wiphy, mode);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
+static inline int
+rdev_get_tx_power_mode(struct cfg80211_registered_device *rdev,
+		       enum nl80211_tx_power_mode *mode)
+{
+	int ret;
+	trace_rdev_get_tx_power_mode(&rdev->wiphy);
+	ret = rdev->ops->get_tx_power_mode(&rdev->wiphy, mode);
+	trace_rdev_return_int_int(&rdev->wiphy, ret, *mode);
+	return ret;
+}
+
 static inline int rdev_set_wds_peer(struct cfg80211_registered_device *rdev,
 				    struct net_device *dev, const u8 *addr)
 {
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 09b242b..132c8c2 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1420,6 +1420,26 @@ TRACE_EVENT(rdev_set_tx_power,
 		  WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm)
 );
 
+DEFINE_EVENT(wiphy_only_evt, rdev_get_tx_power_mode,
+	TP_PROTO(struct wiphy *wiphy),
+	TP_ARGS(wiphy)
+);
+
+TRACE_EVENT(rdev_set_tx_power_mode,
+	TP_PROTO(struct wiphy *wiphy, enum nl80211_tx_power_mode mode),
+	TP_ARGS(wiphy, mode),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		__field(enum nl80211_tx_power_mode, mode)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		__entry->mode = mode;
+	),
+	TP_printk(WIPHY_PR_FMT ", mode: %d",
+		  WIPHY_PR_ARG, __entry->mode)
+);
+
 TRACE_EVENT(rdev_return_int_int,
 	TP_PROTO(struct wiphy *wiphy, int func_ret, int func_fill),
 	TP_ARGS(wiphy, func_ret, func_fill),
-- 
2.1.2

^ permalink raw reply related

* A couple of questions about the SKB fragments
From: Ilya Matveychikov @ 2016-05-05  7:40 UTC (permalink / raw)
  To: netdev; +Cc: Aleksey.Baulin

Hello folks,

While working with fragmented SKBs we've got stuck with the following:
- is it possible for an SKB fragment in skb_shinfo(skb)->frag_list to
be fragmented too (i.e. to have SKBs in frag_list)?
- do skb->len and skb->data_len contain the whole SKB length,
including the length of all fragments (not only the paged parts)?

Is there any docs except the kernel sources itself to refer to?

Thanks.

^ permalink raw reply

* Re: [PATCH net-next 03/13] net: l3mdev: Allow send on enslaved interface
From: Julian Anastasov @ 2016-05-05  7:40 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev
In-Reply-To: <1462419210-10463-4-git-send-email-dsa@cumulusnetworks.com>


	Hello,

On Wed, 4 May 2016, David Ahern wrote:

> Allow udp and raw sockets to send by oif that is an enslaved interface
> versus the l3mdev/VRF device. For example, this allows BFD to use ifindex
> from IP_PKTINFO on a receive to send a response without the need to
> convert to the VRF index. It also allows ping and ping6 to work when
> specifying an enslaved interface (e.g., ping -I swp1 <ip>) which is
> a natural use case.
> 
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
> ---
>  drivers/net/vrf.c   |  2 ++
>  net/ipv4/route.c    |  4 ++++
>  net/l3mdev/l3mdev.c | 20 +++++++++++++++-----
>  3 files changed, 21 insertions(+), 5 deletions(-)
> 

> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 8c8c655bb2c4..a1f2830d8110 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -2146,6 +2146,7 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
>  	unsigned int flags = 0;
>  	struct fib_result res;
>  	struct rtable *rth;
> +	int master_idx;
>  	int orig_oif;
>  	int err = -ENETUNREACH;
>  
> @@ -2155,6 +2156,9 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
>  
>  	orig_oif = fl4->flowi4_oif;
>  
> +	master_idx = l3mdev_master_ifindex_by_index(net, fl4->flowi4_oif);
> +	if (master_idx)
> +		fl4->flowi4_oif = master_idx;

	Changing the flowi4_oif at this point can have
bad effects. I remember for recent commit for  __mkroute_output
where the route caching is disabled if traffic is redirected
to loopback. I think, such change can affect the route
caching, for example, now we use nexthop on master_idx to
cache routes for orig_oif. Such problems with the caching
in the past always caused lookups to return wrong cached result
for other users. But this is only my fears, I don't know
the actual result of this change. May be you are trying to
change flowi4_oif at one place instead of every caller.

Regards

^ permalink raw reply

* Re: [REGRESSION] asix: Lots of asix_rx_fixup() errors and slow transmissions
From: Dean Jenkins @ 2016-05-05  8:11 UTC (permalink / raw)
  To: John Stultz
  Cc: Guodong Xu, lkml, Mark Craske, David S. Miller, YongQin Liu,
	linux-usb, netdev, Ivan Vecera, David B. Robins
In-Reply-To: <CALAqxLXbMuK3Sj45vbf_r4GYQR=8bGUrhDz9-7+S2pbO_dJZ4A@mail.gmail.com>

On 05/05/16 00:45, John Stultz wrote:
> On Tue, May 3, 2016 at 3:54 AM, Dean Jenkins <Dean_Jenkins@mentor.com> wrote:
>> On 03/05/16 11:04, Guodong Xu wrote:
>>> did you test on ARM 64-bit system or ARM 32-bit? I ask because HiKey
>>> is an ARM 64-bit system. I suggest we should be careful on that. I saw
>>> similar issues when transferring to a 64-bit system in other net
>>> drivers.
>> We used 32-bit ARM and never tested on 64-bit ARM so I suggest that the
>> commits need to be reviewed with 64-bit OS in mind.
>>>
>>> Do you have any suggestion on this regard?
>> Try testing on a Linux PC x86 32-bit OS which has has a kernel containing my
>> ASIX commits. This will help to confirm whether the failure is related to
>> 32-bit or 64-bit OS. Then try with Linux PC x86 64-bit OS, this should fail
>> otherwise it points to something specific in your ARM 64-bit platform.
> Just as a sample point, I have managed to reproduce exactly this issue
> on an x86_64 system by simply scp'ing a large file.
Please tell us the x86_64 kernel version number that you used and which 
Linux Distribution it was ? This allows other people a chance to 
reproduce your observations.

>
> [  417.819276] asix 1-5:1.0 eth1: asix_rx_fixup() Data Header
> synchronisation was lost, remaining 988
It is interesting that the reported "remaining" value is 988. Is 988 
always shown ? I mean that do you see any other "remaining" values for 
the "Data Header synchronisation was lost" error message ?

> [  417.823415] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0xef830347, offset 4
The gap in the timestamps shows 417.823415 - 417.819276 = 0.004139 = 4ms 
which is a large gap in terms of USB 2.0 high speed communications. This 
gap is expected to be in the 100us range for consecutive URBs. So 4ms is 
strange.

The expectation is that the "Data Header synchronisation was lost" error 
message resets the 32-bit header word synchronisation to the start of 
the next URB buffer. The "Bad Header Length, offset 4" is the expected 
outcome for the next URB because it is unlikely the 32-bit header word 
is at the start of URB buffer due to Ethernet frames spanning across URBs.
> [  417.827502] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x31e2b348, offset 4
Timestamps show the gap to be 4ms which is strange for USB 2.0 high 
speed, are you sure high speed mode is being used ?
> [  417.843779] asix 1-5:1.0 eth1: asix_rx_fixup() Data Header
> synchronisation was lost, remaining 988
> [  417.847921] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x8af91035, offset 4
> [  417.852004] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x8521fa03, offset 4
> [  418.273394] asix 1-5:1.0 eth1: asix_rx_fixup() Data Header
> synchronisation was lost, remaining 988
> [  418.277532] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x33cd9c7c, offset 4
> [  418.281683] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x3d850896, offset 4
> [  418.286227] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0x86443357, offset 4
> [  418.290319] asix 1-5:1.0 eth1: asix_rx_fixup() Bad Header Length
> 0xee6c81d1, offset 4
>
> I don't have any 32bit x86 installs around so I'm not sure I can easly
> test there, but its clear its not arm64 specific.
I agree the issue is not specific to your ARM 64 bit platform.

Please can you supply the output of ifconfig for the USB to Ethernet 
adaptor, your example above shows eth1 as the device.

Please show the output of ifconfig eth1 before and after the issue is 
seen. This will show us whether the kernel logs any network errors and 
how many bytes have been transferred.

After the issue is seen, please can you show us the output of "dmesg | 
grep asix" so that we can see status messages from the ASIX driver that 
the USB to Ethernet adaptor is using. In particular we need to check 
that USB high speed operation (480Mbps) is being used and not full speed 
operation (12Mbps).

Thanks,

Regards,
Dean

>
> thanks
> -john


-- 
Dean Jenkins
Embedded Software Engineer
Linux Transportation Solutions
Mentor Embedded Software Division
Mentor Graphics (UK) Ltd.

^ permalink raw reply

* Re: [v10, 7/7] mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
From: Arnd Bergmann @ 2016-05-05  8:31 UTC (permalink / raw)
  To: linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ
  Cc: Mark Rutland, ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
	xiaobo.xie-3arQi8VN3Tc, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, Qiang Zhao, Russell King,
	Bhupesh Sharma, Claudiu Manoil, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Kumar Gala, Scott Wood, Rob Herring, Santosh Shilimkar,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	netdev-u79uwXL29TY76Z2rM5mHXA, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, leoyang.li-3arQi8VN3Tc,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Yangbo Lu
In-Reply-To: <1462417950-46796-8-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>

On Thursday 05 May 2016 11:12:30 Yangbo Lu wrote:
> 
> +       fsl_guts_init();
> +       svr = fsl_guts_get_svr();
> +       if (svr) {
> +               esdhc->soc_ver = SVR_SOC_VER(svr);
> +               esdhc->soc_rev = SVR_REV(svr);
> +       } else {
> +               dev_err(&pdev->dev, "Failed to get SVR value!\n");
> +       }
> +
> 


Sorry for jumping in again after not participating in the discussion for the
past few versions.

What happened to my suggestion of making this a platform-independent interface
to avoid the link time dependency?

Specifically, why not add an exported function to drivers/base/soc.c that
uses glob_match() for comparing a string in the device driver to the ID
of the SoC that is set by whatever SoC identifying driver the platform
has?

	Arnd

^ permalink raw reply

* Re: [PATCH net-next 06/13] net: original ingress device index in PKTINFO
From: Julian Anastasov @ 2016-05-05  8:41 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev
In-Reply-To: <1462419210-10463-7-git-send-email-dsa@cumulusnetworks.com>


	Hello,

On Wed, 4 May 2016, David Ahern wrote:

> Applications such as OSPF and BFD need the original ingress device not
> the VRF device; the latter can be derived from the former. To that end
> add the skb_iif to inet_skb_parm and set it in ipv4 code after clearing
> the skb control buffer similar to IPv6. From there the pktinfo can just
> pull it from cb with the PKTINFO_SKB_CB cast.
> 
> The previous patch moving the skb->dev change to L3 means nothing else
> is needed for IPv6; it just works.
> 
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
> ---
>  include/net/ip.h       | 1 +
>  net/ipv4/ip_input.c    | 1 +
>  net/ipv4/ip_sockglue.c | 9 +++++++--
>  3 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/include/net/ip.h b/include/net/ip.h
> index 247ac82e9cf2..37165fba3741 100644
> --- a/include/net/ip.h
> +++ b/include/net/ip.h
> @@ -36,6 +36,7 @@
>  struct sock;
>  
>  struct inet_skb_parm {
> +	int			iif;
>  	struct ip_options	opt;		/* Compiled IP options		*/
>  	unsigned char		flags;
>  
> diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
> index 37375eedeef9..4b351af3e67b 100644
> --- a/net/ipv4/ip_input.c
> +++ b/net/ipv4/ip_input.c
> @@ -478,6 +478,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
>  
>  	/* Remove any debris in the socket control block */
>  	memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
> +	IPCB(skb)->iif = skb->skb_iif;

	For loopback traffic (including looped back multicast)
this is now a zero :( Can inet_iif be moved to ip_rcv_finish
instead? Still, we spend cycles in fast path in case nobody
listens for such info.

>  	/* Must drop socket now because of tproxy. */
>  	skb_orphan(skb);
> diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
> index bdb222c0c6a2..dbcd027c38e7 100644
> --- a/net/ipv4/ip_sockglue.c
> +++ b/net/ipv4/ip_sockglue.c
> @@ -476,9 +476,9 @@ static bool ipv4_datagram_support_cmsg(const struct sock *sk,
>  	    (!skb->dev))
>  		return false;
>  
> +	/* see comment in ipv4_pktinfo_prepare about CB re-use */
>  	info = PKTINFO_SKB_CB(skb);
>  	info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr;
> -	info->ipi_ifindex = skb->dev->ifindex;

	This code is only for SOF_TIMESTAMPING_OPT_CMSG.
I'm not sure skb passes ip_rcv in all cases. So, we can not
easily remove it.

Regards

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox