Re: [PATCH] net:ppp: replace too strict capability restriction on opening /dev/ppp

2016-06-18 Thread Shanker Wang

> 在 2016年6月19日,07:24,David Miller  写道:
> 
> From: Shanker Wang 
> Date: Sun, 19 Jun 2016 07:21:27 +0200
> 
>> This patch removes the check for CAP_NET_ADMIN in the initial namespace
>> when opening /dev/open. Instead, CAP_NET_ADMIN is checked in the user
>> namespace the net namespace was created so that /dev/ppp cat get opened
>> in a unprivileged container.
>> 
>> Cc: Hannes Frederic Sowa 
>> Cc: Richard Weinberger 
>> Cc: Guillaume Nault 
>> Cc: Miao Wang 
>> Signed-off-by: Miao Wang 
> 
> Why are you posting this again?

Sorry for re-sending this e-mail. But the e-mail address of mine has been 
changed. And I haven’t seen this e-mail in several kernel mail list 
archives after a night of sleep. I’m wondering if the e-mail is sent
correctly. So I finally decide to re-send this e-mail. Again, I feel
sorry for sending the same thing for two times.

BTW, how can i judge if my e-mail is correctly sent to the mail list?



Re: [PATCH] net:ppp: replace too strict capability restriction on opening /dev/ppp

2016-06-18 Thread David Miller
From: Shanker Wang 
Date: Sun, 19 Jun 2016 07:21:27 +0200

> This patch removes the check for CAP_NET_ADMIN in the initial namespace
> when opening /dev/open. Instead, CAP_NET_ADMIN is checked in the user
> namespace the net namespace was created so that /dev/ppp cat get opened
> in a unprivileged container.
> 
> Cc: Hannes Frederic Sowa 
> Cc: Richard Weinberger 
> Cc: Guillaume Nault 
> Cc: Miao Wang 
> Signed-off-by: Miao Wang 

Why are you posting this again?


[PATCH] net:ppp: replace too strict capability restriction on opening /dev/ppp

2016-06-18 Thread Shanker Wang
This patch removes the check for CAP_NET_ADMIN in the initial namespace
when opening /dev/open. Instead, CAP_NET_ADMIN is checked in the user
namespace the net namespace was created so that /dev/ppp cat get opened
in a unprivileged container.

Cc: Hannes Frederic Sowa 
Cc: Richard Weinberger 
Cc: Guillaume Nault 
Cc: Miao Wang 
Signed-off-by: Miao Wang 
---
drivers/net/ppp/ppp_generic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index f572b31..4b3b2b5 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -380,7 +380,7 @@ static int ppp_open(struct inode *inode, struct file *file)
/*
 * This could (should?) be enforced by the permissions on /dev/ppp.
 */
-   if (!capable(CAP_NET_ADMIN))
+   if (!ns_capable(current->nsproxy->net_ns->user_ns, CAP_NET_ADMIN))
return -EPERM;
return 0;
}
-- 
2.5.2




Re: [PATCH v2 net-next 0/5] ipv6: better traceroute support in sit and gre

2016-06-18 Thread David Miller
From: Eric Dumazet 
Date: Sat, 18 Jun 2016 21:52:01 -0700

> In commit ca15a078bd90 ("sit: generate icmpv6 error when receiving icmpv4
> error"), Oussama Ghorbel added minimal support for SIT tunnels to
> generate ICMPv6 messages when receiving ICMPv4 messages.
> 
> This patch series extends this to GRE tunnels.
> 
> It also adds support for ICMPV6_TIME_EXCEED.
> 
> Partial support for RFC 4884 is added, to forward ICMP Multi-part
> extensions eventually found in the ICMPv4 message.
> 
> v2: replaced an overlapping memcpy() by memmove()

Series applied, thanks Eric.


[PATCH v2 net-next 1/5] ipv6: icmp: add a force_saddr param to icmp6_send()

2016-06-18 Thread Eric Dumazet
SIT or GRE tunnels might want to translate an IPV4 address
into a v4mapped one when translating ICMP to ICMPv6.

This patch adds the parameter to icmp6_send() but
does not change icmpv6_send() signature.

Signed-off-by: Eric Dumazet 
---
 include/linux/icmpv6.h | 3 ++-
 net/ipv6/icmp.c| 7 +--
 net/ipv6/ip6_icmp.c| 2 +-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 630f45335c73..432611a297fb 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -14,7 +14,8 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff 
*skb)
 #if IS_ENABLED(CONFIG_IPV6)
 extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
 
-typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 
info);
+typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index e32a72fb9982..6c57e6e90301 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -388,7 +388,8 @@ relookup_failed:
 /*
  * Send an ICMP message in response to a packet in error
  */
-static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
+static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+  const struct in6_addr *force_saddr)
 {
struct net *net = dev_net(skb->dev);
struct inet6_dev *idev = NULL;
@@ -475,6 +476,8 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 
code, __u32 info)
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_ICMPV6;
fl6.daddr = hdr->saddr;
+   if (force_saddr)
+   saddr = force_saddr;
if (saddr)
fl6.saddr = *saddr;
fl6.flowi6_mark = mark;
@@ -551,7 +554,7 @@ out:
  */
 void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
 {
-   icmp6_send(skb, ICMPV6_PARAMPROB, code, pos);
+   icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL);
kfree_skb(skb);
 }
 
diff --git a/net/ipv6/ip6_icmp.c b/net/ipv6/ip6_icmp.c
index 14dacc544c3e..713676f14a0e 100644
--- a/net/ipv6/ip6_icmp.c
+++ b/net/ipv6/ip6_icmp.c
@@ -39,7 +39,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 
info)
 
if (!send)
goto out;
-   send(skb, type, code, info);
+   send(skb, type, code, info, NULL);
 out:
rcu_read_unlock();
 }
-- 
2.8.0.rc3.226.g39d4020



[PATCH v2 net-next 4/5] gre: better support for ICMP messages for gre+ipv6

2016-06-18 Thread Eric Dumazet
ipgre_err() can call ip6_err_gen_icmpv6_unreach() for proper
support of ipv4+gre+icmp+ipv6+... frames, used for example
by traceroute/mtr.

Signed-off-by: Eric Dumazet 
---
 include/net/ip_tunnels.h | 1 +
 net/ipv4/gre_demux.c | 1 +
 net/ipv4/ip_gre.c| 6 ++
 3 files changed, 8 insertions(+)

diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 9222678426a1..a5e7035fb93f 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -157,6 +157,7 @@ struct tnl_ptk_info {
__be16 proto;
__be32 key;
__be32 seq;
+   int hdr_len;
 };
 
 #define PACKET_RCVD0
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c
index de1d119a4497..b798862b6be5 100644
--- a/net/ipv4/gre_demux.c
+++ b/net/ipv4/gre_demux.c
@@ -117,6 +117,7 @@ int gre_parse_header(struct sk_buff *skb, struct 
tnl_ptk_info *tpi,
if ((*(u8 *)options & 0xF0) != 0x40)
hdr_len += 4;
}
+   tpi->hdr_len = hdr_len;
return hdr_len;
 }
 EXPORT_SYMBOL(gre_parse_header);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 48eccc4e4cc5..b199a3c85dfc 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -181,6 +181,12 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
if (!t)
return;
 
+#if IS_ENABLED(CONFIG_IPV6)
+   if (tpi->proto == htons(ETH_P_IPV6) &&
+   !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len, type))
+   return;
+#endif
+
if (t->parms.iph.daddr == 0 ||
ipv4_is_multicast(t->parms.iph.daddr))
return;
-- 
2.8.0.rc3.226.g39d4020



[PATCH v2 net-next 3/5] ipv6: translate ICMP_TIME_EXCEEDED to ICMPV6_TIME_EXCEED

2016-06-18 Thread Eric Dumazet
For better traceroute/mtr support for SIT and GRE tunnels,
we translate IPV4 ICMP ICMP_TIME_EXCEEDED to ICMPV6_TIME_EXCEED

We also have to translate the IPv4 source IP address of ICMP
message to IPv6 v4mapped.

Signed-off-by: Eric Dumazet 
---
 include/linux/icmpv6.h |  2 +-
 net/ipv6/icmp.c| 12 +---
 net/ipv6/sit.c |  6 +++---
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 9796481edbdb..97ae98071a03 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -18,7 +18,7 @@ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 
code, __u32 info,
 const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
-int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs);
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type);
 
 #else
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 07bc63c23712..867aebc34248 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -564,8 +564,9 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int 
pos)
  *  Either an IPv4 header for SIT encap
  * an IPv4 header + GRE header for GRE encap
  */
-int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs)
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type)
 {
+   struct in6_addr temp_saddr;
struct rt6_info *rt;
struct sk_buff *skb2;
 
@@ -586,8 +587,13 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int 
nhs)
if (rt && rt->dst.dev)
skb2->dev = rt->dst.dev;
 
-   icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
-
+   ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
+   if (type == ICMP_TIME_EXCEEDED)
+   icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
+  0, &temp_saddr);
+   else
+   icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH,
+  0, &temp_saddr);
if (rt)
ip6_rt_put(rt);
 
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 78e84d6793ee..d7a36114eb50 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -535,11 +535,11 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
goto out;
}
 
-   if (t->parms.iph.daddr == 0)
+   err = 0;
+   if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type))
goto out;
 
-   err = 0;
-   if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4))
+   if (t->parms.iph.daddr == 0)
goto out;
 
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
-- 
2.8.0.rc3.226.g39d4020



[PATCH v2 net-next 5/5] ipv6: RFC 4884 partial support for SIT/GRE tunnels

2016-06-18 Thread Eric Dumazet
When receiving an ICMPv4 message containing extensions as
defined in RFC 4884, and translating it to ICMPv6 at SIT
or GRE tunnel, we need some extra manipulation in order
to properly forward the extensions.

This patch only takes care of Time Exceeded messages as they
are the ones that typically carry information from various
routers in a fabric during a traceroute session.

It also avoids complex skb logic if the data_len is not
a multiple of 8.

RFC states :

   The "original datagram" field MUST contain at least 128 octets.
   If the original datagram did not contain 128 octets, the
   "original datagram" field MUST be zero padded to 128 octets.

In practice routers use 128 bytes of original datagram, not more.

Initial translation was added in commit ca15a078bd90
("sit: generate icmpv6 error when receiving icmpv4 error")

Signed-off-by: Eric Dumazet 
Cc: Oussama Ghorbel 
---
 include/linux/icmpv6.h|  3 ++-
 include/uapi/linux/icmp.h |  1 +
 net/ipv4/ip_gre.c |  5 -
 net/ipv6/icmp.c   | 28 
 net/ipv6/sit.c|  4 +++-
 5 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 97ae98071a03..57086e9fc64c 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -18,7 +18,8 @@ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 
code, __u32 info,
 const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
-int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type);
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
+  unsigned int data_len);
 
 #else
 
diff --git a/include/uapi/linux/icmp.h b/include/uapi/linux/icmp.h
index 16fff055f734..fddd9d736284 100644
--- a/include/uapi/linux/icmp.h
+++ b/include/uapi/linux/icmp.h
@@ -79,6 +79,7 @@ struct icmphdr {
__be16  __unused;
__be16  mtu;
} frag;
+   __u8reserved[4];
   } un;
 };
 
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index b199a3c85dfc..24d1516ff6c5 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -138,6 +138,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
const struct iphdr *iph;
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
+   unsigned int data_len = 0;
struct ip_tunnel *t;
 
switch (type) {
@@ -163,6 +164,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
case ICMP_TIME_EXCEEDED:
if (code != ICMP_EXC_TTL)
return;
+   data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
break;
 
case ICMP_REDIRECT:
@@ -183,7 +185,8 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
 
 #if IS_ENABLED(CONFIG_IPV6)
if (tpi->proto == htons(ETH_P_IPV6) &&
-   !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len, type))
+   !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
+  type, data_len))
return;
 #endif
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 867aebc34248..d2b157659e11 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -564,16 +564,22 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int 
pos)
  *  Either an IPv4 header for SIT encap
  * an IPv4 header + GRE header for GRE encap
  */
-int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type)
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
+  unsigned int data_len)
 {
struct in6_addr temp_saddr;
struct rt6_info *rt;
struct sk_buff *skb2;
+   u32 info = 0;
 
if (!pskb_may_pull(skb, nhs + sizeof(struct ipv6hdr) + 8))
return 1;
 
-   skb2 = skb_clone(skb, GFP_ATOMIC);
+   /* RFC 4884 (partial) support for ICMP extensions */
+   if (data_len < 128 || (data_len & 7) || skb->len < data_len)
+   data_len = 0;
+
+   skb2 = data_len ? skb_copy(skb, GFP_ATOMIC) : skb_clone(skb, 
GFP_ATOMIC);
 
if (!skb2)
return 1;
@@ -588,12 +594,26 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int 
nhs, int type)
skb2->dev = rt->dst.dev;
 
ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
+
+   if (data_len) {
+   /* RFC 4884 (partial) support :
+* insert 0 padding at the end, before the extensions
+*/
+   __skb_push(skb2, nhs);
+   skb_reset_network_header(skb2);
+   memmove(skb2->data, skb2->data + nhs, data_len - nhs);
+   memset(skb2->data + data_len - nhs, 0, nhs);
+   /* RFC 4884 4.5 : Length is measured in 64-bit words,
+  

[PATCH v2 net-next 0/5] ipv6: better traceroute support in sit and gre

2016-06-18 Thread Eric Dumazet
In commit ca15a078bd90 ("sit: generate icmpv6 error when receiving icmpv4
error"), Oussama Ghorbel added minimal support for SIT tunnels to
generate ICMPv6 messages when receiving ICMPv4 messages.

This patch series extends this to GRE tunnels.

It also adds support for ICMPV6_TIME_EXCEED.

Partial support for RFC 4884 is added, to forward ICMP Multi-part
extensions eventually found in the ICMPv4 message.

v2: replaced an overlapping memcpy() by memmove()

Eric Dumazet (5):
  ipv6: icmp: add a force_saddr param to icmp6_send()
  ip6: move ipip6_err_gen_icmpv6_unreach()
  ipv6: translate ICMP_TIME_EXCEEDED to ICMPV6_TIME_EXCEED
  gre: better support for ICMP messages for gre+ipv6
  ipv6: RFC 4884 partial support for SIT/GRE tunnels

 include/linux/icmpv6.h|  5 +++-
 include/net/ip_tunnels.h  |  1 +
 include/uapi/linux/icmp.h |  1 +
 net/ipv4/gre_demux.c  |  1 +
 net/ipv4/ip_gre.c |  9 ++
 net/ipv6/icmp.c   | 72 +--
 net/ipv6/ip6_icmp.c   |  2 +-
 net/ipv6/sit.c| 44 -
 8 files changed, 92 insertions(+), 43 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



[PATCH v2 net-next 2/5] ip6: move ipip6_err_gen_icmpv6_unreach()

2016-06-18 Thread Eric Dumazet
We want to use this helper from GRE as well, so this is
the time to move it in net/ipv6/icmp.c

Also add a @nhs parameter, since SIT and GRE have different
values for the header(s) to skip.

Signed-off-by: Eric Dumazet 
---
 include/linux/icmpv6.h |  1 +
 net/ipv6/icmp.c| 39 +++
 net/ipv6/sit.c | 38 +-
 3 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 432611a297fb..9796481edbdb 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -18,6 +18,7 @@ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 
code, __u32 info,
 const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs);
 
 #else
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 6c57e6e90301..07bc63c23712 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -558,6 +558,45 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int 
pos)
kfree_skb(skb);
 }
 
+/* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
+ * if sufficient data bytes are available
+ * @nhs is the size of the tunnel header(s) :
+ *  Either an IPv4 header for SIT encap
+ * an IPv4 header + GRE header for GRE encap
+ */
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs)
+{
+   struct rt6_info *rt;
+   struct sk_buff *skb2;
+
+   if (!pskb_may_pull(skb, nhs + sizeof(struct ipv6hdr) + 8))
+   return 1;
+
+   skb2 = skb_clone(skb, GFP_ATOMIC);
+
+   if (!skb2)
+   return 1;
+
+   skb_dst_drop(skb2);
+   skb_pull(skb2, nhs);
+   skb_reset_network_header(skb2);
+
+   rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
+
+   if (rt && rt->dst.dev)
+   skb2->dev = rt->dst.dev;
+
+   icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
+
+   if (rt)
+   ip6_rt_put(rt);
+
+   kfree_skb(skb2);
+
+   return 0;
+}
+EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach);
+
 static void icmpv6_echo_reply(struct sk_buff *skb)
 {
struct net *net = dev_net(skb->dev);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index d9f2bd6ef72d..78e84d6793ee 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -479,42 +479,6 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
dev_put(dev);
 }
 
-/* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
- * if sufficient data bytes are available
- */
-static int ipip6_err_gen_icmpv6_unreach(struct sk_buff *skb)
-{
-   int ihl = ((const struct iphdr *)skb->data)->ihl*4;
-   struct rt6_info *rt;
-   struct sk_buff *skb2;
-
-   if (!pskb_may_pull(skb, ihl + sizeof(struct ipv6hdr) + 8))
-   return 1;
-
-   skb2 = skb_clone(skb, GFP_ATOMIC);
-
-   if (!skb2)
-   return 1;
-
-   skb_dst_drop(skb2);
-   skb_pull(skb2, ihl);
-   skb_reset_network_header(skb2);
-
-   rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
-
-   if (rt && rt->dst.dev)
-   skb2->dev = rt->dst.dev;
-
-   icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
-
-   if (rt)
-   ip6_rt_put(rt);
-
-   kfree_skb(skb2);
-
-   return 0;
-}
-
 static int ipip6_err(struct sk_buff *skb, u32 info)
 {
const struct iphdr *iph = (const struct iphdr *)skb->data;
@@ -575,7 +539,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
goto out;
 
err = 0;
-   if (!ipip6_err_gen_icmpv6_unreach(skb))
+   if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4))
goto out;
 
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
-- 
2.8.0.rc3.226.g39d4020



Re: [PATCH net-next 5/5] ipv6: RFC 4884 partial support for SIT/GRE tunnels

2016-06-18 Thread Eric Dumazet
On Sat, 2016-06-18 at 21:26 -0700, David Miller wrote:

> The golden rule is: "the memory areas must not overlap"
> 
> If it can be optimized into calling a memcpy, the memmove
> implementation will do so.

Of course, I guess I have been working on x86 for too long ;)






Re: [PATCH] net: rds: fix coding style issues

2016-06-18 Thread David Miller
From: Joshua Houghton 
Date: Sat, 18 Jun 2016 15:46:31 +

> Fix coding style issues in the following files:
> 
> ib_cm.c:  add space
> loop.c:   convert spaces to tabs
> sysctl.c: add space
> tcp.h:convert spaces to tabs
> tcp_connect.c:remove extra indentation in switch statement
> tcp_recv.c:   convert spaces to tabs
> tcp_send.c:   convert spaces to tabs
> transport.c:  move brace up one line on for statement
> 
> Signed-off-by: Joshua Houghton 

Applied.


Re: [PATCH net-next 5/5] ipv6: RFC 4884 partial support for SIT/GRE tunnels

2016-06-18 Thread David Miller
From: Eric Dumazet 
Date: Sat, 18 Jun 2016 21:03:29 -0700

> On Sat, 2016-06-18 at 20:54 -0700, David Miller wrote:
>> From: Eric Dumazet 
>> Date: Sat, 18 Jun 2016 16:26:40 -0700
>> 
>> > @@ -588,12 +594,26 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, 
>> > int nhs, int type)
>> >skb2->dev = rt->dst.dev;
>> >  
>> >ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
>> > +
>> > +  if (data_len) {
>> > +  /* RFC 4884 (partial) support :
>> > +   * insert 0 padding at the end, before the extensions
>> > +   */
>> > +  __skb_push(skb2, nhs);
>> > +  skb_reset_network_header(skb2);
>> > +  memcpy(skb2->data, skb2->data + nhs, data_len - nhs);
>> 
>> Since this is overlapping, it really need to use memmove() instead of
>> memcpy().
> 
> 
> Interesting, I always thought memcpy(dest, src, xxx) was ok if src >
> dest

The golden rule is: "the memory areas must not overlap"

If it can be optimized into calling a memcpy, the memmove
implementation will do so.


Re: [PATCH net-next 5/5] ipv6: RFC 4884 partial support for SIT/GRE tunnels

2016-06-18 Thread Eric Dumazet
On Sat, 2016-06-18 at 20:54 -0700, David Miller wrote:
> From: Eric Dumazet 
> Date: Sat, 18 Jun 2016 16:26:40 -0700
> 
> > @@ -588,12 +594,26 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, 
> > int nhs, int type)
> > skb2->dev = rt->dst.dev;
> >  
> > ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
> > +
> > +   if (data_len) {
> > +   /* RFC 4884 (partial) support :
> > +* insert 0 padding at the end, before the extensions
> > +*/
> > +   __skb_push(skb2, nhs);
> > +   skb_reset_network_header(skb2);
> > +   memcpy(skb2->data, skb2->data + nhs, data_len - nhs);
> 
> Since this is overlapping, it really need to use memmove() instead of
> memcpy().


Interesting, I always thought memcpy(dest, src, xxx) was ok if src >
dest







Re: PATCH 1/1] AX.25: Close socket connection on session completion

2016-06-18 Thread David Miller
From: Basil Gunn 
Date: Thu, 16 Jun 2016 09:42:30 -0700

> A socket connection made in ax.25 is not closed when session is
> completed.  The heartbeat timer is stopped prematurely and this is
> where the socket gets closed. Allow heatbeat timer to run to close
> socket. Symptom occurs in kernels >= 4.2.0
> 
> Originally sent 6/15/2016. Resend with distribution list matching
> scripts/maintainer.pl output.
> 
> Signed-off-by: Basil Gunn 

Applied.


Re: [PATCH net-next 5/5] ipv6: RFC 4884 partial support for SIT/GRE tunnels

2016-06-18 Thread David Miller
From: Eric Dumazet 
Date: Sat, 18 Jun 2016 16:26:40 -0700

> @@ -588,12 +594,26 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int 
> nhs, int type)
>   skb2->dev = rt->dst.dev;
>  
>   ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
> +
> + if (data_len) {
> + /* RFC 4884 (partial) support :
> +  * insert 0 padding at the end, before the extensions
> +  */
> + __skb_push(skb2, nhs);
> + skb_reset_network_header(skb2);
> + memcpy(skb2->data, skb2->data + nhs, data_len - nhs);

Since this is overlapping, it really need to use memmove() instead of
memcpy().


Re: [PATCH net-next v10 2/5] openvswitch: set skb protocol and mac_len when receiving on internal device

2016-06-18 Thread pravin shelar
On Thu, Jun 16, 2016 at 10:53 PM, Simon Horman
 wrote:
> On Tue, Jun 07, 2016 at 03:45:27PM -0700, pravin shelar wrote:
>> On Mon, Jun 6, 2016 at 8:08 PM, Simon Horman  
>> wrote:
>> > On Thu, Jun 02, 2016 at 03:01:47PM -0700, pravin shelar wrote:
>> >> On Wed, Jun 1, 2016 at 11:24 PM, Simon Horman
>> >>  wrote:
>> >> > * Set skb protocol based on contents of packet. I have observed this is
>> >> >   necessary to get actual protocol of a packet when it is injected into 
>> >> > an
>> >> >   internal device e.g. by libnet in which case skb protocol will be set 
>> >> > to
>> >> >   ETH_ALL.


>> > eth_type = eth_type_trans(skb, skb->dev);
>> > skb->mac_len = skb->data - skb_mac_header(skb);
>> > __skb_push(skb, skb->mac_len);
>> >
>> > if (eth_type == htons(ETH_P_8021Q))
>> > skb->mac_len += VLAN_HLEN;
>> >
>> > Perhaps that logic ought to be in a helper used by both internal_dev_xmit()
>> > and netdev_port_receive(). Or somehow centralised in ovs_vport_receive().
>>
>> This does looks bit complex. Can we use other skb metadata like
>> skb_mac_header_was_set()?
>
> Yes, I think that can be made to work if skb->mac_header is unset
> for l3 packets in netdev_port_receive(). The following is an incremental
> patch on the entire series. Is this the kind of thing you had in mind?
>
> diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
> index 86f2cfb19de3..42587d5bf894 100644
> --- a/net/openvswitch/flow.c
> +++ b/net/openvswitch/flow.c
> @@ -729,7 +729,7 @@ int ovs_flow_key_extract(const struct ip_tunnel_info 
> *tun_info,
> key->phy.skb_mark = skb->mark;
> ovs_ct_fill_key(skb, key);
> key->ovs_flow_hash = 0;
> -   key->phy.is_layer3 = skb->mac_len == 0;
> +   key->phy.is_layer3 = skb_mac_header_was_set(skb) == 0;
> key->recirc_id = 0;
>
> err = key_extract(skb, key);
> diff --git a/net/openvswitch/vport-internal_dev.c 
> b/net/openvswitch/vport-internal_dev.c
> index 484ba529c682..8973d4db509b 100644
> --- a/net/openvswitch/vport-internal_dev.c
> +++ b/net/openvswitch/vport-internal_dev.c
> @@ -50,7 +50,6 @@ static int internal_dev_xmit(struct sk_buff *skb, struct 
> net_device *netdev)
>
> skb->protocol = eth_type_trans(skb, netdev);
> skb_push(skb, ETH_HLEN);
> -   skb_reset_mac_len(skb);
>
> len = skb->len;
> rcu_read_lock();
> diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
> index 3df36df62ee9..4cf3f12ffc99 100644
> --- a/net/openvswitch/vport-netdev.c
> +++ b/net/openvswitch/vport-netdev.c
> @@ -60,22 +60,9 @@ static void netdev_port_receive(struct sk_buff *skb)
> if (vport->dev->type == ARPHRD_ETHER) {
> skb_push(skb, ETH_HLEN);
> skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
> -   } else if (vport->dev->type == ARPHRD_NONE) {
> -   if (skb->protocol == htons(ETH_P_TEB)) {
> -   __be16 eth_type;
> -
> -   if (unlikely(skb->len < ETH_HLEN))
> -   goto error;
> -
> -   eth_type = eth_type_trans(skb, skb->dev);
> -   skb->mac_len = skb->data - skb_mac_header(skb);
> -   __skb_push(skb, skb->mac_len);
> -
> -   if (eth_type == htons(ETH_P_8021Q))
> -   skb->mac_len += VLAN_HLEN;
> -   } else {
> -   skb->mac_len = 0;
> -   }
> +   } else if (vport->dev->type == ARPHRD_NONE &&
> +  skb->protocol != htons(ETH_P_TEB)) {
> +   skb->mac_header = (typeof(skb->mac_header))~0U;
> }
>
> ovs_vport_receive(vport, skb, skb_tunnel_info(skb));

This certainly looks better. I was wondering if we can unset the mac
header offset in L3 tunnel devices itself. So there is no need to have
this check here.


Re: PATCH 1/1] AX.25: Close socket connection on session completion

2016-06-18 Thread David Ranch
Hello David,

I don't have a specific commit # for you at the moment but there have been a 
few serious regressions since 4.1.x.  When new code gets commited, are there 
any systems to run regession tests on?  I'd be willing to build up a pair of 
VMs that can be run with scripts to verify say basic sanity for kissattach, 
ax.25, netrom, rose, etc.

Btw, once I get back, I hope to pursue some additional negative case fixes:  
(pulling a usb-to-serial adapter when used with kiss-attach will panic the 
kernel, ifconfig rose0 down will take the kernel to 100%, and a data corruption 
issue for large transfers (2MB+).

Thanks for your help!

--David
KI6ZHD
--David

On June 17, 2016 12:33:19 PM CST, David Miller  wrote:
>From: Basil Gunn 
>Date: Thu, 16 Jun 2016 09:42:30 -0700
>
>> A socket connection made in ax.25 is not closed when session is
>> completed.  The heartbeat timer is stopped prematurely and this is
>> where the socket gets closed. Allow heatbeat timer to run to close
>> socket. Symptom occurs in kernels >= 4.2.0
>> 
>> Originally sent 6/15/2016. Resend with distribution list matching
>> scripts/maintainer.pl output.
>> 
>> Signed-off-by: Basil Gunn 
>
>What changed in 4.2.x that broke this?
>--
>To unsubscribe from this list: send the line "unsubscribe linux-hams"
>in
>the body of a message to majord...@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html



[PATCH] ixgbe: Fix minor typo while freeing irq

2016-06-18 Thread Babu Moger
The array subscript increments after the execution of the statement.
So there is no issue here. However it helps to read the code better.

Signed-off-by: Babu Moger 
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 569cb07..6f4fe66 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3016,7 +3016,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
free_irq(entry->vector, q_vector);
}
 
-   free_irq(adapter->msix_entries[vector++].vector, adapter);
+   free_irq(adapter->msix_entries[vector].vector, adapter);
 }
 
 /**
-- 
1.7.1



[PATCH] brcmfmac: add missing break when deleting P2P_DEVICE

2016-06-18 Thread Rafał Miłecki
We obviously don't want to fall through in that switch. With this change
1) We wait for event (triggered by p2p_disc) as expected
2) We remove interface manually on timeout
3) We return 0 on success instead of -ENOTSUPP

Signed-off-by: Rafał Miłecki 
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 426ff05..f6241fd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -2261,6 +2261,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct 
wireless_dev *wdev)
return 0;
brcmf_p2p_cancel_remain_on_channel(vif->ifp);
brcmf_p2p_deinit_discovery(p2p);
+   break;
+
default:
return -ENOTSUPP;
}
-- 
1.8.4.5



[PATCH] net:ppp: replace too strict capability restriction on opening /dev/ppp

2016-06-18 Thread Shanker Wang
This patch removes the check for CAP_NET_ADMIN in the initial namespace
when opening /dev/open. Instead, CAP_NET_ADMIN is checked in the user
namespace the net namespace was created so that /dev/ppp cat get opened
in a unprivileged container.

Cc: Hannes Frederic Sowa 
Cc: Richard Weinberger 
Cc: Guillaume Nault 
Cc: Miao Wang 
Signed-off-by: Miao Wang 
---
 drivers/net/ppp/ppp_generic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index f572b31..4b3b2b5 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -380,7 +380,7 @@ static int ppp_open(struct inode *inode, struct file *file)
/*
 * This could (should?) be enforced by the permissions on /dev/ppp.
 */
-   if (!capable(CAP_NET_ADMIN))
+   if (!ns_capable(current->nsproxy->net_ns->user_ns, CAP_NET_ADMIN))
return -EPERM;
return 0;
 }
-- 
2.5.2




[PATCH net-next 2/5] ip6: move ipip6_err_gen_icmpv6_unreach()

2016-06-18 Thread Eric Dumazet
We want to use this helper from GRE as well, so this is
the time to move it in net/ipv6/icmp.c

Also add a @nhs parameter, since SIT and GRE have different
values for the header(s) to skip.

Signed-off-by: Eric Dumazet 
---
 include/linux/icmpv6.h |  1 +
 net/ipv6/icmp.c| 39 +++
 net/ipv6/sit.c | 38 +-
 3 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 432611a297fb..9796481edbdb 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -18,6 +18,7 @@ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 
code, __u32 info,
 const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs);
 
 #else
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 6c57e6e90301..07bc63c23712 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -558,6 +558,45 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int 
pos)
kfree_skb(skb);
 }
 
+/* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
+ * if sufficient data bytes are available
+ * @nhs is the size of the tunnel header(s) :
+ *  Either an IPv4 header for SIT encap
+ * an IPv4 header + GRE header for GRE encap
+ */
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs)
+{
+   struct rt6_info *rt;
+   struct sk_buff *skb2;
+
+   if (!pskb_may_pull(skb, nhs + sizeof(struct ipv6hdr) + 8))
+   return 1;
+
+   skb2 = skb_clone(skb, GFP_ATOMIC);
+
+   if (!skb2)
+   return 1;
+
+   skb_dst_drop(skb2);
+   skb_pull(skb2, nhs);
+   skb_reset_network_header(skb2);
+
+   rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
+
+   if (rt && rt->dst.dev)
+   skb2->dev = rt->dst.dev;
+
+   icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
+
+   if (rt)
+   ip6_rt_put(rt);
+
+   kfree_skb(skb2);
+
+   return 0;
+}
+EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach);
+
 static void icmpv6_echo_reply(struct sk_buff *skb)
 {
struct net *net = dev_net(skb->dev);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index d9f2bd6ef72d..78e84d6793ee 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -479,42 +479,6 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
dev_put(dev);
 }
 
-/* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
- * if sufficient data bytes are available
- */
-static int ipip6_err_gen_icmpv6_unreach(struct sk_buff *skb)
-{
-   int ihl = ((const struct iphdr *)skb->data)->ihl*4;
-   struct rt6_info *rt;
-   struct sk_buff *skb2;
-
-   if (!pskb_may_pull(skb, ihl + sizeof(struct ipv6hdr) + 8))
-   return 1;
-
-   skb2 = skb_clone(skb, GFP_ATOMIC);
-
-   if (!skb2)
-   return 1;
-
-   skb_dst_drop(skb2);
-   skb_pull(skb2, ihl);
-   skb_reset_network_header(skb2);
-
-   rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
-
-   if (rt && rt->dst.dev)
-   skb2->dev = rt->dst.dev;
-
-   icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
-
-   if (rt)
-   ip6_rt_put(rt);
-
-   kfree_skb(skb2);
-
-   return 0;
-}
-
 static int ipip6_err(struct sk_buff *skb, u32 info)
 {
const struct iphdr *iph = (const struct iphdr *)skb->data;
@@ -575,7 +539,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
goto out;
 
err = 0;
-   if (!ipip6_err_gen_icmpv6_unreach(skb))
+   if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4))
goto out;
 
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
-- 
2.8.0.rc3.226.g39d4020



[PATCH net-next 5/5] ipv6: RFC 4884 partial support for SIT/GRE tunnels

2016-06-18 Thread Eric Dumazet
When receiving an ICMPv4 message containing extensions as
defined in RFC 4884, and translating it to ICMPv6 at SIT
or GRE tunnel, we need some extra manipulation in order
to properly forward the extensions.

This patch only takes care of Time Exceeded messages as they
are the ones that typically carry information from various
routers in a fabric during a traceroute session.

It also avoids complex skb logic if the data_len is not
a multiple of 8.

RFC states :

   The "original datagram" field MUST contain at least 128 octets.
   If the original datagram did not contain 128 octets, the
   "original datagram" field MUST be zero padded to 128 octets.

In practice routers use 128 bytes of original datagram, not more.

Initial translation was added in commit ca15a078bd90
("sit: generate icmpv6 error when receiving icmpv4 error")

Signed-off-by: Eric Dumazet 
Cc: Oussama Ghorbel 
---
 include/linux/icmpv6.h|  3 ++-
 include/uapi/linux/icmp.h |  1 +
 net/ipv4/ip_gre.c |  5 -
 net/ipv6/icmp.c   | 28 
 net/ipv6/sit.c|  4 +++-
 5 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 97ae98071a03..57086e9fc64c 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -18,7 +18,8 @@ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 
code, __u32 info,
 const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
-int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type);
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
+  unsigned int data_len);
 
 #else
 
diff --git a/include/uapi/linux/icmp.h b/include/uapi/linux/icmp.h
index 16fff055f734..fddd9d736284 100644
--- a/include/uapi/linux/icmp.h
+++ b/include/uapi/linux/icmp.h
@@ -79,6 +79,7 @@ struct icmphdr {
__be16  __unused;
__be16  mtu;
} frag;
+   __u8reserved[4];
   } un;
 };
 
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index b199a3c85dfc..24d1516ff6c5 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -138,6 +138,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
const struct iphdr *iph;
const int type = icmp_hdr(skb)->type;
const int code = icmp_hdr(skb)->code;
+   unsigned int data_len = 0;
struct ip_tunnel *t;
 
switch (type) {
@@ -163,6 +164,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
case ICMP_TIME_EXCEEDED:
if (code != ICMP_EXC_TTL)
return;
+   data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
break;
 
case ICMP_REDIRECT:
@@ -183,7 +185,8 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
 
 #if IS_ENABLED(CONFIG_IPV6)
if (tpi->proto == htons(ETH_P_IPV6) &&
-   !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len, type))
+   !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
+  type, data_len))
return;
 #endif
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 867aebc34248..d2b157659e11 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -564,16 +564,22 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int 
pos)
  *  Either an IPv4 header for SIT encap
  * an IPv4 header + GRE header for GRE encap
  */
-int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type)
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
+  unsigned int data_len)
 {
struct in6_addr temp_saddr;
struct rt6_info *rt;
struct sk_buff *skb2;
+   u32 info = 0;
 
if (!pskb_may_pull(skb, nhs + sizeof(struct ipv6hdr) + 8))
return 1;
 
-   skb2 = skb_clone(skb, GFP_ATOMIC);
+   /* RFC 4884 (partial) support for ICMP extensions */
+   if (data_len < 128 || (data_len & 7) || skb->len < data_len)
+   data_len = 0;
+
+   skb2 = data_len ? skb_copy(skb, GFP_ATOMIC) : skb_clone(skb, 
GFP_ATOMIC);
 
if (!skb2)
return 1;
@@ -588,12 +594,26 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int 
nhs, int type)
skb2->dev = rt->dst.dev;
 
ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
+
+   if (data_len) {
+   /* RFC 4884 (partial) support :
+* insert 0 padding at the end, before the extensions
+*/
+   __skb_push(skb2, nhs);
+   skb_reset_network_header(skb2);
+   memcpy(skb2->data, skb2->data + nhs, data_len - nhs);
+   memset(skb2->data + data_len - nhs, 0, nhs);
+   /* RFC 4884 4.5 : Length is measured in 64-bit words,
+   

[PATCH net-next 4/5] gre: better support for ICMP messages for gre+ipv6

2016-06-18 Thread Eric Dumazet
ipgre_err() can call ip6_err_gen_icmpv6_unreach() for proper
support of ipv4+gre+icmp+ipv6+... frames, used for example
by traceroute/mtr.

Signed-off-by: Eric Dumazet 
---
 include/net/ip_tunnels.h | 1 +
 net/ipv4/gre_demux.c | 1 +
 net/ipv4/ip_gre.c| 6 ++
 3 files changed, 8 insertions(+)

diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 9222678426a1..a5e7035fb93f 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -157,6 +157,7 @@ struct tnl_ptk_info {
__be16 proto;
__be32 key;
__be32 seq;
+   int hdr_len;
 };
 
 #define PACKET_RCVD0
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c
index de1d119a4497..b798862b6be5 100644
--- a/net/ipv4/gre_demux.c
+++ b/net/ipv4/gre_demux.c
@@ -117,6 +117,7 @@ int gre_parse_header(struct sk_buff *skb, struct 
tnl_ptk_info *tpi,
if ((*(u8 *)options & 0xF0) != 0x40)
hdr_len += 4;
}
+   tpi->hdr_len = hdr_len;
return hdr_len;
 }
 EXPORT_SYMBOL(gre_parse_header);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 48eccc4e4cc5..b199a3c85dfc 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -181,6 +181,12 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
if (!t)
return;
 
+#if IS_ENABLED(CONFIG_IPV6)
+   if (tpi->proto == htons(ETH_P_IPV6) &&
+   !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len, type))
+   return;
+#endif
+
if (t->parms.iph.daddr == 0 ||
ipv4_is_multicast(t->parms.iph.daddr))
return;
-- 
2.8.0.rc3.226.g39d4020



[PATCH net-next 3/5] ipv6: translate ICMP_TIME_EXCEEDED to ICMPV6_TIME_EXCEED

2016-06-18 Thread Eric Dumazet
For better traceroute/mtr support for SIT and GRE tunnels,
we translate IPV4 ICMP ICMP_TIME_EXCEEDED to ICMPV6_TIME_EXCEED

We also have to translate the IPv4 source IP address of ICMP
message to IPv6 v4mapped.

Signed-off-by: Eric Dumazet 
---
 include/linux/icmpv6.h |  2 +-
 net/ipv6/icmp.c| 12 +---
 net/ipv6/sit.c |  6 +++---
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 9796481edbdb..97ae98071a03 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -18,7 +18,7 @@ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 
code, __u32 info,
 const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
-int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs);
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type);
 
 #else
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 07bc63c23712..867aebc34248 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -564,8 +564,9 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int 
pos)
  *  Either an IPv4 header for SIT encap
  * an IPv4 header + GRE header for GRE encap
  */
-int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs)
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type)
 {
+   struct in6_addr temp_saddr;
struct rt6_info *rt;
struct sk_buff *skb2;
 
@@ -586,8 +587,13 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int 
nhs)
if (rt && rt->dst.dev)
skb2->dev = rt->dst.dev;
 
-   icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
-
+   ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
+   if (type == ICMP_TIME_EXCEEDED)
+   icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
+  0, &temp_saddr);
+   else
+   icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH,
+  0, &temp_saddr);
if (rt)
ip6_rt_put(rt);
 
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 78e84d6793ee..d7a36114eb50 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -535,11 +535,11 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
goto out;
}
 
-   if (t->parms.iph.daddr == 0)
+   err = 0;
+   if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type))
goto out;
 
-   err = 0;
-   if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4))
+   if (t->parms.iph.daddr == 0)
goto out;
 
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
-- 
2.8.0.rc3.226.g39d4020



[PATCH net-next 1/5] ipv6: icmp: add a force_saddr param to icmp6_send()

2016-06-18 Thread Eric Dumazet
SIT or GRE tunnels might want to translate an IPV4 address
into a v4mapped one when translating ICMP to ICMPv6.

This patch adds the parameter to icmp6_send() but
does not change icmpv6_send() signature.

Signed-off-by: Eric Dumazet 
---
 include/linux/icmpv6.h | 3 ++-
 net/ipv6/icmp.c| 7 +--
 net/ipv6/ip6_icmp.c| 2 +-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 630f45335c73..432611a297fb 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -14,7 +14,8 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff 
*skb)
 #if IS_ENABLED(CONFIG_IPV6)
 extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
 
-typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 
info);
+typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index e32a72fb9982..6c57e6e90301 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -388,7 +388,8 @@ relookup_failed:
 /*
  * Send an ICMP message in response to a packet in error
  */
-static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
+static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+  const struct in6_addr *force_saddr)
 {
struct net *net = dev_net(skb->dev);
struct inet6_dev *idev = NULL;
@@ -475,6 +476,8 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 
code, __u32 info)
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_ICMPV6;
fl6.daddr = hdr->saddr;
+   if (force_saddr)
+   saddr = force_saddr;
if (saddr)
fl6.saddr = *saddr;
fl6.flowi6_mark = mark;
@@ -551,7 +554,7 @@ out:
  */
 void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
 {
-   icmp6_send(skb, ICMPV6_PARAMPROB, code, pos);
+   icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL);
kfree_skb(skb);
 }
 
diff --git a/net/ipv6/ip6_icmp.c b/net/ipv6/ip6_icmp.c
index 14dacc544c3e..713676f14a0e 100644
--- a/net/ipv6/ip6_icmp.c
+++ b/net/ipv6/ip6_icmp.c
@@ -39,7 +39,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 
info)
 
if (!send)
goto out;
-   send(skb, type, code, info);
+   send(skb, type, code, info, NULL);
 out:
rcu_read_unlock();
 }
-- 
2.8.0.rc3.226.g39d4020



[PATCH net-next 0/5] ipv6: better traceroute support in sit and gre

2016-06-18 Thread Eric Dumazet
In commit ca15a078bd90 ("sit: generate icmpv6 error when receiving icmpv4
error"), Oussama Ghorbel added minimal support for SIT tunnels to
generate ICMPv6 messages when receiving ICMPv4 messages.

This patch series extends this to GRE tunnels.

It also adds support for ICMPV6_TIME_EXCEED.

Partial support for RFC 4884 is added, to forward ICMP Multi-part
extensions eventually found in the ICMPv4 message.

Eric Dumazet (5):
  ipv6: icmp: add a force_saddr param to icmp6_send()
  ip6: move ipip6_err_gen_icmpv6_unreach()
  ipv6: translate ICMP_TIME_EXCEEDED to ICMPV6_TIME_EXCEED
  gre: better support for ICMP messages for gre+ipv6
  ipv6: RFC 4884 partial support for SIT/GRE tunnels

 include/linux/icmpv6.h|  5 +++-
 include/net/ip_tunnels.h  |  1 +
 include/uapi/linux/icmp.h |  1 +
 net/ipv4/gre_demux.c  |  1 +
 net/ipv4/ip_gre.c |  9 ++
 net/ipv6/icmp.c   | 72 +--
 net/ipv6/ip6_icmp.c   |  2 +-
 net/ipv6/sit.c| 44 -
 8 files changed, 92 insertions(+), 43 deletions(-)

-- 
2.8.0.rc3.226.g39d4020



Re: [very-RFC 0/8] TSN driver for the kernel

2016-06-18 Thread Henrik Austad
On Sat, Jun 18, 2016 at 02:22:13PM +0900, Takashi Sakamoto wrote:
> Hi,

Hi Takashi,

You raise a lot of valid points and questions, I'll try to answer them.

edit: this turned out to be a somewhat lengthy answer. I have tried to 
shorten it down somewhere. it is getting late and I'm getting increasingly 
incoherent (Richard probably knows what I'm talking about ;) so I'll stop 
for now.

Plase post a follow-up with everything that's not clear!
Thanks!

> Sorry to be late. In this weekday, I have little time for this thread
> because working for alsa-lib[1]. Besides, I'm not full-time developer
> for this kind of work. In short, I use my limited private time for this
> discussion.

Thank you for taking the time to reply to this thread then, it is much 
appreciated

> On Jun 15 2016 17:06, Richard Cochran wrote:
> > On Wed, Jun 15, 2016 at 12:15:24PM +0900, Takashi Sakamoto wrote:
> >>> On Mon, Jun 13, 2016 at 01:47:13PM +0200, Richard Cochran wrote:
>  I have seen audio PLL/multiplier chips that will take, for example, a
>  10 kHz input and produce your 48 kHz media clock.  With the right HW
>  design, you can tell your PTP Hardware Clock to produce a 1 PPS,
>  and you will have a synchronized AVB endpoint.  The software is all
>  there already.  Somebody should tell the ALSA guys about it.
> >>
> >> Just from my curiosity, could I ask you more explanation for it in ALSA
> >> side?
> > 
> > (Disclaimer: I really don't know too much about ALSA, expect that is
> > fairly big and complex ;)
> 
> In this morning, I read IEEE 1722:2011 and realized that it quite
> roughly refers to IEC 61883-1/6 and includes much ambiguities to end
> applications.

As far as I know, 1722 aims to describe how the data is wrapped in AVTPDU 
(and likewise for control-data), not how the end-station should implement 
it.

If there are ambiguities, would you mind listing a few? It would serve as a 
useful guide as to look for other pitfalls as well (thanks!)

> (In my opinion, the author just focuses on packet with timestamps,
> without enough considering about how to implement endpoint applications
> which perform semi-real sampling, fetching and queueing and so on, so as
> you. They're satisfied just by handling packet with timestamp, without
> enough consideration about actual hardware/software applications.)

You are correct, none of the standards explain exactly how it should be 
implemented, only what the end result should look like. One target of this 
collection of standards are embedded, dedicated AV equipment and the 
authors have no way of knowing (nor should they care I think) the 
underlying architecture of these.

> > Here is what I think ALSA should provide:
> > 
> > - The DA and AD clocks should appear as attributes of the HW device.

This would be very useful and helpful when determining if the clock of the 
HW time is falling behind or racing ahead of the gPTP time domain. It will 
also help finding the capture time or calculating when a sample in the 
buffer will be played back by the device.

> > - There should be a method for measuring the DA/AD clock rate with
> >   respect to both the system time and the PTP Hardware Clock (PHC)
> >   time.

as above.

> > - There should be a method for adjusting the DA/AD clock rate if
> >   possible.  If not, then ALSA should fall back to sample rate
> >   conversion.

This is not a requirement from the standard, but will help avoid costly 
resampling. At least it should be possible to detect the *need* for 
resampling so that we can try to avoid underruns.

> > - There should be a method to determine the time delay from the point
> >   when the audio data are enqueued into ALSA until they pass through
> >   the D/A converter.  If this cannot be known precisely, then the
> >   library should provide an estimate with an error bound.
> > 
> > - I think some AVB use cases will need to know the time delay from A/D
> >   until the data are available to the local application.  (Distributed
> >   microphones?  I'm not too sure about that.)

yes, if you have multiple microphones that you want to combine into a 
stream and do signal processing, some cases require sample-sync (so within 
1 us accuracy for 48kHz).

> > - If the DA/AD clocks are connected to other clock devices in HW,
> >   there should be a way to find this out in SW.  For example, if SW
> >   can see the PTP-PHC-PLL-DA relationship from the above example, then
> >   it knows how to synchronize the DA clock using the network.
> > 
> >   [ Implementing this point involves other subsystems beyond ALSA.  It
> > isn't really necessary for people designing AVB systems, since
> > they know their designs, but it would be nice to have for writing
> > generic applications that can deal with any kind of HW setup. ]
> 
> Depends on which subsystem decides "AVTP presentation time"[3]. 

Presentation time is either set by
a) Local sound card performing capture (in which case it will be 'capture 
 

Re: [PATCH RFC 1/2] brcmfmac: remove interface before notifying listener

2016-06-18 Thread Rafał Miłecki
On 18 June 2016 at 23:58, Rafał Miłecki  wrote:
> On 18 June 2016 at 21:26, Arend van Spriel  
> wrote:
>> On 18-06-16 20:18, Rafał Miłecki wrote:
>>> So far when receiving event about in-firmware-interface removal we were
>>> notifying our listener and afterwards we were removing Linux interface.
>>>
>>
>> [snip]
>>
>>>
>>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c 
>>> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
>>> index 9da7a4c..5fd1886 100644
>>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
>>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
>>> @@ -18,6 +18,7 @@
>>>  #include "brcmu_wifi.h"
>>>  #include "brcmu_utils.h"
>>>
>>> +#include "cfg80211.h"
>>>  #include "core.h"
>>>  #include "debug.h"
>>>  #include "tracepoint.h"
>>> @@ -180,10 +181,16 @@ static void brcmf_fweh_handle_if_event(struct 
>>> brcmf_pub *drvr,
>>>   if (ifp && ifevent->action == BRCMF_E_IF_CHANGE)
>>>   brcmf_fws_reset_interface(ifp);
>>>
>>> - err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, 
>>> data);
>>
>> The reason for doing this first is because we are passing the ifp, which
>> is netdev_priv(ifp->ndev). In brcmf_remove_interface() we only
>> unregister the netdev, which will end up (after scheduling) in
>> brcmf_free_netdev() thus freeing the ifp. By moving the event handler
>> function ifp may be stale already.
>
> Good catch. What about making brcmf_fweh_call_event_handler work
> without ifp? Would that be OK then?

Maybe I have even better idea. What about handling Linux interface
removal in the code waiting for BRCMF_E_IF_DEL? We already do
something like that in case of BRCMF_E_IF_ADD (it is brcmf_ap_add_vif
that calls brcmf_net_attach).


Re: [PATCHv2 2/2] mt7601u: use linux/bitfield.h

2016-06-18 Thread kbuild test robot
Hi,

[auto build test ERROR on wireless-drivers-next/master]
[also build test ERROR on v4.7-rc3 next-20160617]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Jakub-Kicinski/register-field-manipulation-macros/20160614-195149
base:   
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git 
master
config: x86_64-randconfig-s4-06190511 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   In file included from include/asm-generic/bug.h:4:0,
from arch/x86/include/asm/bug.h:35,
from include/linux/bug.h:4,
from include/linux/bitfield.h:19,
from drivers/net/wireless/mediatek/mt7601u/mt7601u.h:18,
from drivers/net/wireless/mediatek/mt7601u/init.c:16:
   In function 'mt7601u_init_usb_dma',
   inlined from 'mt7601u_init_hardware' at 
drivers/net/wireless/mediatek/mt7601u/init.c:359:2:
>> include/linux/compiler.h:510:38: error: call to '__compiletime_assert_111' 
>> declared with attribute error: BUILD_BUG_ON failed: 
>> __builtin_constant_p(0x80) ? ~(~0UL) << (0)) & (~0UL >> (64 - 1 - 
>> (7) >> _bf_shf~0UL) << (0)) & (~0UL >> (64 - 1 - (7)) & (0x80) : >> 0
 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
 ^
   include/linux/compiler.h:493:4: note: in definition of macro 
'__compiletime_assert'
   prefix ## suffix();\
   ^~
   include/linux/compiler.h:510:2: note: in expansion of macro 
'_compiletime_assert'
 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
 ^~~
   include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~
   include/linux/bug.h:75:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
 BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
 ^~~~
>> include/linux/bitfield.h:28:3: note: in expansion of macro 'BUILD_BUG_ON'
  BUILD_BUG_ON(!(_mask) || (hi && !is_power_of_2_u64(hi))); \
  ^~~~
>> include/linux/bitfield.h:36:3: note: in expansion of macro '_BF_FIELD_CHECK'
  _BF_FIELD_CHECK(_mask, _val);   \
  ^~~
>> drivers/net/wireless/mediatek/mt7601u/mt7601u.h:285:18: note: in expansion 
>> of macro 'FIELD_PUT'
#define MT76_SET FIELD_PUT
 ^
>> drivers/net/wireless/mediatek/mt7601u/init.c:111:8: note: in expansion of 
>> macro 'MT76_SET'
 val = MT76_SET(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, MT_USB_AGGR_TIMEOUT) |
   ^~~~
   include/linux/compiler.h:510:38: error: call to '__compiletime_assert_112' 
declared with attribute error: BUILD_BUG_ON failed: __builtin_constant_p(28) ? 
~(~0UL) << (8)) & (~0UL >> (64 - 1 - (15) >> _bf_shf~0UL) << (8)) & 
(~0UL >> (64 - 1 - (15)) & (28) : 0
 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
 ^
   include/linux/compiler.h:493:4: note: in definition of macro 
'__compiletime_assert'
   prefix ## suffix();\
   ^~
   include/linux/compiler.h:510:2: note: in expansion of macro 
'_compiletime_assert'
 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
 ^~~
   include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~
   include/linux/bug.h:75:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
 BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
 ^~~~
>> include/linux/bitfield.h:28:3: note: in expansion of macro 'BUILD_BUG_ON'
  BUILD_BUG_ON(!(_mask) || (hi && !is_power_of_2_u64(hi))); \
  ^~~~
>> include/linux/bitfield.h:36:3: note: in expansion of macro '_BF_FIELD_CHECK'
  _BF_FIELD_CHECK(_mask, _val);   \
  ^~~
>> drivers/net/wireless/mediatek/mt7601u/mt7601u.h:285:18: note: in expansion 
>> of macro 'FIELD_PUT'
#define MT76_SET FIELD_PUT
 ^
   drivers/net/wireless/mediatek/mt7601u/init.c:112:8: note: in expansion of 
macro 'MT76_SET'
   MT76_SET(MT_USB_DMA_CFG_RX_BULK_AGG_LMT, MT_USB_AGGR_SIZE_LIMIT) |
   ^~~~
   drivers/net/wireless/mediatek/mt7601u/init.c: In function 
'mt7601u_init_hardware':
   include/linux/compiler.h:510:38: error: call to '__compiletime_assert_399' 
declared with attribute error: BUILD_BUG_ON failed: __builtin_constant_p(0x3f) 
? ~(~0UL) << (0)) & (~0UL >> (64 - 1 - (5)))

Re: [PATCH RFC 1/2] brcmfmac: remove interface before notifying listener

2016-06-18 Thread Rafał Miłecki
On 18 June 2016 at 21:26, Arend van Spriel  wrote:
> On 18-06-16 20:18, Rafał Miłecki wrote:
>> So far when receiving event about in-firmware-interface removal we were
>> notifying our listener and afterwards we were removing Linux interface.
>>
>
> [snip]
>
>>
>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c 
>> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
>> index 9da7a4c..5fd1886 100644
>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
>> @@ -18,6 +18,7 @@
>>  #include "brcmu_wifi.h"
>>  #include "brcmu_utils.h"
>>
>> +#include "cfg80211.h"
>>  #include "core.h"
>>  #include "debug.h"
>>  #include "tracepoint.h"
>> @@ -180,10 +181,16 @@ static void brcmf_fweh_handle_if_event(struct 
>> brcmf_pub *drvr,
>>   if (ifp && ifevent->action == BRCMF_E_IF_CHANGE)
>>   brcmf_fws_reset_interface(ifp);
>>
>> - err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
>
> The reason for doing this first is because we are passing the ifp, which
> is netdev_priv(ifp->ndev). In brcmf_remove_interface() we only
> unregister the netdev, which will end up (after scheduling) in
> brcmf_free_netdev() thus freeing the ifp. By moving the event handler
> function ifp may be stale already.

Good catch. What about making brcmf_fweh_call_event_handler work
without ifp? Would that be OK then?


>> + if (ifp && ifevent->action == BRCMF_E_IF_DEL) {
>> + bool rtnl_locked = 
>> brcmf_cfg80211_vif_event_armed(drvr->config);
>> +
>> + brcmf_remove_interface(ifp, rtnl_locked);
>
> I guess rtnl_locked here means "rtnl_is_locked() by brcmfmac". It
> actually does not matter who is holding the rtnl_lock. At least when it
> is brcmfmac it is still a different task, ie. hostapd, iw, etc. Also
> when brcmf_cfg80211_vif_event_armed() return false there may still be
> some task holding the rtnl_lock.

It does matter who holds the lock.

If it's e.g. some other driver (ath, intel, ralink, whatever) we still
should call unregister_netdevice. It'll just wait until rtnl lock gets
released.

If it's brcmfmac holding the lock, we can't expect it to be released
as brcmfmac waits for completion event.

-- 
Rafał


Re: [PATCH v3 net-next v3 13/14] net: dsa: mv88e6xxx: add addressing mode to info

2016-06-18 Thread Vivien Didelot
Hi Andrew,

Andrew Lunn  writes:

>> +struct mv88e6xxx_smi_ops {
>> +int (*read)(struct mii_bus *bus, int sw_addr,
>> +int addr, int reg, u16 *val);
>> +int (*write)(struct mii_bus *bus, int sw_addr,
>> + int addr, int reg, u16 val);
>> +};
>
> Hi Vivien
>
> I still think this API should be based on ps.
>
> With the way you have restructured probe, this now also works, there
> is no longer a read without PS in order to get the device ID.
>
> Also, think about the case of reading/writing registers via Ethernet
> frames. Such functions would need ps, bus and sw_addr is not useful.

Yes, I do RMU in mind, that was one motivation behind isolating
SMI-specific pieces of code.

I considered mv88e6xxx_smi_ops private to the SMI (MDIO) access, needing
an additional abstraction for regs access operations.

But I can indeed rename mv88e6xxx_smi_ops to mv88e6xxx_ops and make them
use a ps before one day, implementing an optional ps->rmu_ops.

Thanks,

Vivien


[PATCH 2/2] net: ethernet: nb8800: use phy_ethtool_{get|set}_link_ksettings

2016-06-18 Thread Philippe Reynes
There are two generics functions phy_ethtool_{get|set}_link_ksettings,
so we can use them instead of defining the same code in the driver.

Signed-off-by: Philippe Reynes 
---
 drivers/net/ethernet/aurora/nb8800.c |   24 ++--
 1 files changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/aurora/nb8800.c 
b/drivers/net/ethernet/aurora/nb8800.c
index 4989d31..dc2c35d 100644
--- a/drivers/net/ethernet/aurora/nb8800.c
+++ b/drivers/net/ethernet/aurora/nb8800.c
@@ -1035,26 +1035,6 @@ static const struct net_device_ops nb8800_netdev_ops = {
.ndo_validate_addr  = eth_validate_addr,
 };
 
-static int nb8800_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-   struct phy_device *phydev = dev->phydev;
-
-   if (!phydev)
-   return -ENODEV;
-
-   return phy_ethtool_gset(phydev, cmd);
-}
-
-static int nb8800_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-   struct phy_device *phydev = dev->phydev;
-
-   if (!phydev)
-   return -ENODEV;
-
-   return phy_ethtool_sset(phydev, cmd);
-}
-
 static int nb8800_nway_reset(struct net_device *dev)
 {
struct phy_device *phydev = dev->phydev;
@@ -1183,8 +1163,6 @@ static void nb8800_get_ethtool_stats(struct net_device 
*dev,
 }
 
 static const struct ethtool_ops nb8800_ethtool_ops = {
-   .get_settings   = nb8800_get_settings,
-   .set_settings   = nb8800_set_settings,
.nway_reset = nb8800_nway_reset,
.get_link   = ethtool_op_get_link,
.get_pauseparam = nb8800_get_pauseparam,
@@ -1192,6 +1170,8 @@ static const struct ethtool_ops nb8800_ethtool_ops = {
.get_sset_count = nb8800_get_sset_count,
.get_strings= nb8800_get_strings,
.get_ethtool_stats  = nb8800_get_ethtool_stats,
+   .get_link_ksettings = phy_ethtool_get_link_ksettings,
+   .set_link_ksettings = phy_ethtool_set_link_ksettings,
 };
 
 static int nb8800_hw_init(struct net_device *dev)
-- 
1.7.4.4



[PATCH 1/2] net: ethernet: nb8800: use phydev from struct net_device

2016-06-18 Thread Philippe Reynes
The private structure contain a pointer to phydev, but the structure
net_device already contain such pointer. So we can remove the pointer
phydev in the private structure, and update the driver to use the
one contained in struct net_device.

Signed-off-by: Philippe Reynes 
---
 drivers/net/ethernet/aurora/nb8800.c |   57 +
 drivers/net/ethernet/aurora/nb8800.h |1 -
 2 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/aurora/nb8800.c 
b/drivers/net/ethernet/aurora/nb8800.c
index 08a23e6..4989d31 100644
--- a/drivers/net/ethernet/aurora/nb8800.c
+++ b/drivers/net/ethernet/aurora/nb8800.c
@@ -631,7 +631,7 @@ static void nb8800_mac_config(struct net_device *dev)
 static void nb8800_pause_config(struct net_device *dev)
 {
struct nb8800_priv *priv = netdev_priv(dev);
-   struct phy_device *phydev = priv->phydev;
+   struct phy_device *phydev = dev->phydev;
u32 rxcr;
 
if (priv->pause_aneg) {
@@ -664,7 +664,7 @@ static void nb8800_pause_config(struct net_device *dev)
 static void nb8800_link_reconfigure(struct net_device *dev)
 {
struct nb8800_priv *priv = netdev_priv(dev);
-   struct phy_device *phydev = priv->phydev;
+   struct phy_device *phydev = dev->phydev;
int change = 0;
 
if (phydev->link) {
@@ -690,7 +690,7 @@ static void nb8800_link_reconfigure(struct net_device *dev)
}
 
if (change)
-   phy_print_status(priv->phydev);
+   phy_print_status(phydev);
 }
 
 static void nb8800_update_mac_addr(struct net_device *dev)
@@ -935,9 +935,10 @@ static int nb8800_dma_stop(struct net_device *dev)
 static void nb8800_pause_adv(struct net_device *dev)
 {
struct nb8800_priv *priv = netdev_priv(dev);
+   struct phy_device *phydev = dev->phydev;
u32 adv = 0;
 
-   if (!priv->phydev)
+   if (!phydev)
return;
 
if (priv->pause_rx)
@@ -945,13 +946,14 @@ static void nb8800_pause_adv(struct net_device *dev)
if (priv->pause_tx)
adv ^= ADVERTISED_Asym_Pause;
 
-   priv->phydev->supported |= adv;
-   priv->phydev->advertising |= adv;
+   phydev->supported |= adv;
+   phydev->advertising |= adv;
 }
 
 static int nb8800_open(struct net_device *dev)
 {
struct nb8800_priv *priv = netdev_priv(dev);
+   struct phy_device *phydev;
int err;
 
/* clear any pending interrupts */
@@ -969,10 +971,10 @@ static int nb8800_open(struct net_device *dev)
nb8800_mac_rx(dev, true);
nb8800_mac_tx(dev, true);
 
-   priv->phydev = of_phy_connect(dev, priv->phy_node,
- nb8800_link_reconfigure, 0,
- priv->phy_mode);
-   if (!priv->phydev)
+   phydev = of_phy_connect(dev, priv->phy_node,
+   nb8800_link_reconfigure, 0,
+   priv->phy_mode);
+   if (!phydev)
goto err_free_irq;
 
nb8800_pause_adv(dev);
@@ -982,7 +984,7 @@ static int nb8800_open(struct net_device *dev)
netif_start_queue(dev);
 
nb8800_start_rx(dev);
-   phy_start(priv->phydev);
+   phy_start(phydev);
 
return 0;
 
@@ -997,8 +999,9 @@ err_free_dma:
 static int nb8800_stop(struct net_device *dev)
 {
struct nb8800_priv *priv = netdev_priv(dev);
+   struct phy_device *phydev = dev->phydev;
 
-   phy_stop(priv->phydev);
+   phy_stop(phydev);
 
netif_stop_queue(dev);
napi_disable(&priv->napi);
@@ -1007,8 +1010,7 @@ static int nb8800_stop(struct net_device *dev)
nb8800_mac_rx(dev, false);
nb8800_mac_tx(dev, false);
 
-   phy_disconnect(priv->phydev);
-   priv->phydev = NULL;
+   phy_disconnect(phydev);
 
free_irq(dev->irq, dev);
 
@@ -1019,9 +1021,7 @@ static int nb8800_stop(struct net_device *dev)
 
 static int nb8800_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-   struct nb8800_priv *priv = netdev_priv(dev);
-
-   return phy_mii_ioctl(priv->phydev, rq, cmd);
+   return phy_mii_ioctl(dev->phydev, rq, cmd);
 }
 
 static const struct net_device_ops nb8800_netdev_ops = {
@@ -1037,32 +1037,32 @@ static const struct net_device_ops nb8800_netdev_ops = {
 
 static int nb8800_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-   struct nb8800_priv *priv = netdev_priv(dev);
+   struct phy_device *phydev = dev->phydev;
 
-   if (!priv->phydev)
+   if (!phydev)
return -ENODEV;
 
-   return phy_ethtool_gset(priv->phydev, cmd);
+   return phy_ethtool_gset(phydev, cmd);
 }
 
 static int nb8800_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-   struct nb8800_priv *priv = netdev_priv(dev);
+   struct phy_device *phydev = dev->phydev;
 
-   if (!priv->phydev)
+   if (!phydev)
return -ENODEV;
 
-   return phy_

Re: [PATCH v3 net-next v3 14/14] net: dsa: mv88e6xxx: add port base address to info

2016-06-18 Thread Andrew Lunn
On Fri, Jun 17, 2016 at 08:07:36PM -0400, Vivien Didelot wrote:
> The switch ID is located at address 0x3 of every Port Registers bank.
> 
> But not all Marvell switches have their Port Registers SMI Addresses
> starting at 0x10. 88E6060 starts at 0x8 and 88E6390 starts at 0x0.
> 
> Add this data in the info structure and use it in the detection code.

Reviewed-by: Andrew Lunn 

Andrew


Re: [PATCH v3 net-next v3 13/14] net: dsa: mv88e6xxx: add addressing mode to info

2016-06-18 Thread Andrew Lunn
> +struct mv88e6xxx_smi_ops {
> + int (*read)(struct mii_bus *bus, int sw_addr,
> + int addr, int reg, u16 *val);
> + int (*write)(struct mii_bus *bus, int sw_addr,
> +  int addr, int reg, u16 val);
> +};

Hi Vivien

I still think this API should be based on ps.

With the way you have restructured probe, this now also works, there
is no longer a read without PS in order to get the device ID.

Also, think about the case of reading/writing registers via Ethernet
frames. Such functions would need ps, bus and sw_addr is not useful.

Andrew


Re: [PATCH v3 net-next v3 12/14] net: dsa: mv88e6xxx: pass compatible info

2016-06-18 Thread Andrew Lunn
On Fri, Jun 17, 2016 at 08:07:34PM -0400, Vivien Didelot wrote:
> After allocating the chip structure, pass it a compatible info pointer.
> 
> The compatible info structure will be used later to describe how to
> access the switch registers and where to read the switch ID.
> 
> For the standard MDIO probe, get it from the device node data. For the
> legacy DSA driver probing, pass it the 88E6085 info.
> 
> Signed-off-by: Vivien Didelot 

Reviewed-by: Andrew Lunn 

Andrew


Re: [PATCH v3 net-next v3 11/14] net: dsa: mv88e6xxx: add detection helper

2016-06-18 Thread Andrew Lunn
On Fri, Jun 17, 2016 at 08:07:33PM -0400, Vivien Didelot wrote:
> Extract the common detection code which assigns the info structure to
> the chip given the read switch ID.
> 
> Signed-off-by: Vivien Didelot 

Reviewed-by: Andrew Lunn 

Andrew


Re: [PATCH v3 net-next v3 10/14] net: dsa: mv88e6xxx: add SMI init helper

2016-06-18 Thread Andrew Lunn
On Fri, Jun 17, 2016 at 08:07:32PM -0400, Vivien Didelot wrote:
> Add an helper function to isolate SMI specific assignations and checks.

I don't think you meant assignations. Assignments?

Otherwise

Reviewed-by: Andrew Lunn 

Andrew


Re: [PATCH v3 net-next v3 09/14] net: dsa: mv88e6xxx: add chip allocation helper

2016-06-18 Thread Andrew Lunn
On Fri, Jun 17, 2016 at 08:07:31PM -0400, Vivien Didelot wrote:
> Add an helper function to allocate the chip structure at the beginning
> of the probe functions. It will be used to initialize the SMI access.
> 
> Signed-off-by: Vivien Didelot 

Reviewed-by: Andrew Lunn 

Andrew


Re: [PATCH v3 net-next v3 08/14] net: dsa: mv88e6xxx: rename smi_mutex to reg_lock

2016-06-18 Thread Andrew Lunn
On Fri, Jun 17, 2016 at 08:07:30PM -0400, Vivien Didelot wrote:
> The chip smi_mutex mutex is used to protect the access to the internal
> switch registers, not only the Multi-chip Addressing Mode, as commented.
> 
> Other registers access (like management frames) may use this mutex.
> 
> Since we will isolate SMI-specific pieces of code, avoid the confusion
> now by renaming smi_mutex to reg_lock. No functional changes here.
> 
> Signed-off-by: Vivien Didelot 

Reviewed-by: Andrew Lunn 

Andrew


Re: [PATCH v3 net-next v3 07/14] net: dsa: mv88e6xxx: remove table args in info lookup

2016-06-18 Thread Andrew Lunn
On Fri, Jun 17, 2016 at 08:07:29PM -0400, Vivien Didelot wrote:
> The mv88e6xxx_table array and the mv88e6xxx_lookup_info function are
> static, so remove the table and size arguments from the lookup function.
> 
> Signed-off-by: Vivien Didelot 

Reviewed-by: Andrew Lunn 

Andrew


Re: [PATCH v3 net-next v3 06/14] net: dsa: mv88e6xxx: use gpio get optional variant

2016-06-18 Thread Andrew Lunn
On Fri, Jun 17, 2016 at 08:07:28PM -0400, Vivien Didelot wrote:
> Use the optional variant to get the reset GPIO line, instead of checking
> for the -ENOENT error.
> 
> Signed-off-by: Vivien Didelot 

Reviewed-by: Andrew Lunn 

Andrew


Re: [PATCH RFC 2/2] brcmfmac: support removing AP interfaces with "interface_remove"

2016-06-18 Thread Arend van Spriel
On 18-06-16 20:18, Rafał Miłecki wrote:
> New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove"
> for removing interfaces. Try to use this method on cfg80211 request. In
> case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this
> will just result in firmware rejecting command and this won't change any
> behavior.
> 
> Signed-off-by: Rafał Miłecki 
> ---
>  .../broadcom/brcm80211/brcmfmac/cfg80211.c | 37 
> +-
>  1 file changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> index 502b0a0..aff76c2 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> @@ -785,12 +785,46 @@ s32 brcmf_notify_escan_complete(struct 
> brcmf_cfg80211_info *cfg,
>   return err;
>  }
>  
> +static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
> +struct wireless_dev *wdev)
> +{
> + struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
> + struct net_device *ndev = wdev->netdev;
> + struct brcmf_if *ifp = netdev_priv(ndev);
> + int ret;
> + int err;
> +
> + brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
> +
> + err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
> + if (err) {
> + brcmf_err("interface_remove failed %d\n", err);
> + goto err_unarm;
> + }
> +
> + /* wait for firmware event */
> + ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
> + BRCMF_VIF_EVENT_TIMEOUT);
> + if (!ret) {
> + brcmf_err("timeout occurred\n");
> + err = -EIO;
> + goto err_unarm;
> + }
> +
> +err_unarm:
> + brcmf_cfg80211_arm_vif_event(cfg, NULL);
> + return err;
> +}
> +
>  static
>  int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
>  {
>   struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
>   struct net_device *ndev = wdev->netdev;
>  
> + if (ndev == cfg_to_ndev(cfg))

ndev can be NULL, ie. for IFTYPE_P2P_DEVICE.

Regards,
Arend

> + return -ENOTSUPP;
> +
>   /* vif event pending in firmware */
>   if (brcmf_cfg80211_vif_event_armed(cfg))
>   return -EBUSY;
> @@ -807,12 +841,13 @@ int brcmf_cfg80211_del_iface(struct wiphy *wiphy, 
> struct wireless_dev *wdev)
>   switch (wdev->iftype) {
>   case NL80211_IFTYPE_ADHOC:
>   case NL80211_IFTYPE_STATION:
> - case NL80211_IFTYPE_AP:
>   case NL80211_IFTYPE_AP_VLAN:
>   case NL80211_IFTYPE_WDS:
>   case NL80211_IFTYPE_MONITOR:
>   case NL80211_IFTYPE_MESH_POINT:
>   return -EOPNOTSUPP;
> + case NL80211_IFTYPE_AP:
> + return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
>   case NL80211_IFTYPE_P2P_CLIENT:
>   case NL80211_IFTYPE_P2P_GO:
>   case NL80211_IFTYPE_P2P_DEVICE:
> 


Re: [PATCH RFC 1/2] brcmfmac: remove interface before notifying listener

2016-06-18 Thread Arend van Spriel
On 18-06-16 20:18, Rafał Miłecki wrote:
> So far when receiving event about in-firmware-interface removal we were
> notifying our listener and afterwards we were removing Linux interface.
> 

[snip]

> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c 
> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
> index 9da7a4c..5fd1886 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
> @@ -18,6 +18,7 @@
>  #include "brcmu_wifi.h"
>  #include "brcmu_utils.h"
>  
> +#include "cfg80211.h"
>  #include "core.h"
>  #include "debug.h"
>  #include "tracepoint.h"
> @@ -180,10 +181,16 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub 
> *drvr,
>   if (ifp && ifevent->action == BRCMF_E_IF_CHANGE)
>   brcmf_fws_reset_interface(ifp);
>  
> - err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);

The reason for doing this first is because we are passing the ifp, which
is netdev_priv(ifp->ndev). In brcmf_remove_interface() we only
unregister the netdev, which will end up (after scheduling) in
brcmf_free_netdev() thus freeing the ifp. By moving the event handler
function ifp may be stale already.

> + if (ifp && ifevent->action == BRCMF_E_IF_DEL) {
> + bool rtnl_locked = brcmf_cfg80211_vif_event_armed(drvr->config);
> +
> + brcmf_remove_interface(ifp, rtnl_locked);

I guess rtnl_locked here means "rtnl_is_locked() by brcmfmac". It
actually does not matter who is holding the rtnl_lock. At least when it
is brcmfmac it is still a different task, ie. hostapd, iw, etc. Also
when brcmf_cfg80211_vif_event_armed() return false there may still be
some task holding the rtnl_lock.

Regards,
Arend


[PATCH RFC 1/2] brcmfmac: remove interface before notifying listener

2016-06-18 Thread Rafał Miłecki
So far when receiving event about in-firmware-interface removal we were
notifying our listener and afterwards we were removing Linux interface.

This order was most likely a try to avoid a lockup. Removing in-firmware
interface could be requested by a driver code holding rtnl lock. Such
code waits for a corresponding event (still holding rtnl lock) which
prevents us from calling unregister_netdev. Notifying listener first
allowed it to release rtnl lock and removing interface succesfully.

Please note we couldn't switch to unregister_netdevice as interface
removal event could also occur in other (unpredictable) moments.

Unfortunately above workaround doesn't work in some corner cases. Focus
on the time slot between calling event handler and removing Linux
interface. During that time original caller may leave (unlocking rtnl
semaphore) *and* another call to the same code may be done (locking it
again). If that happens our event handler will stuck at removing Linux
interface, it won't handle another event and will block process holding
rtnl lock.

So the real solution is to remove interface before notifying listener.
We just need to know if rtnl is hold by a caller that triggered our
event.

Moreover this changes makes sure we call unregister_netdevice before
del_virtual_intf leaves which isn't critical but it makes a bit more of
sense to handle it this way.

Signed-off-by: Rafał Miłecki 
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
index 9da7a4c..5fd1886 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
@@ -18,6 +18,7 @@
 #include "brcmu_wifi.h"
 #include "brcmu_utils.h"
 
+#include "cfg80211.h"
 #include "core.h"
 #include "debug.h"
 #include "tracepoint.h"
@@ -180,10 +181,16 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub 
*drvr,
if (ifp && ifevent->action == BRCMF_E_IF_CHANGE)
brcmf_fws_reset_interface(ifp);
 
-   err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
+   if (ifp && ifevent->action == BRCMF_E_IF_DEL) {
+   bool rtnl_locked = brcmf_cfg80211_vif_event_armed(drvr->config);
+
+   brcmf_remove_interface(ifp, rtnl_locked);
+   }
 
-   if (ifp && ifevent->action == BRCMF_E_IF_DEL)
-   brcmf_remove_interface(ifp, false);
+   err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
+   if (err)
+   brcmf_err("event %d handler failed (%d)\n", emsg->event_code,
+ err);
 }
 
 /**
-- 
1.8.4.5



[PATCH RFC 2/2] brcmfmac: support removing AP interfaces with "interface_remove"

2016-06-18 Thread Rafał Miłecki
New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove"
for removing interfaces. Try to use this method on cfg80211 request. In
case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this
will just result in firmware rejecting command and this won't change any
behavior.

Signed-off-by: Rafał Miłecki 
---
 .../broadcom/brcm80211/brcmfmac/cfg80211.c | 37 +-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 502b0a0..aff76c2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -785,12 +785,46 @@ s32 brcmf_notify_escan_complete(struct 
brcmf_cfg80211_info *cfg,
return err;
 }
 
+static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
+  struct wireless_dev *wdev)
+{
+   struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
+   struct net_device *ndev = wdev->netdev;
+   struct brcmf_if *ifp = netdev_priv(ndev);
+   int ret;
+   int err;
+
+   brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
+
+   err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
+   if (err) {
+   brcmf_err("interface_remove failed %d\n", err);
+   goto err_unarm;
+   }
+
+   /* wait for firmware event */
+   ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
+   BRCMF_VIF_EVENT_TIMEOUT);
+   if (!ret) {
+   brcmf_err("timeout occurred\n");
+   err = -EIO;
+   goto err_unarm;
+   }
+
+err_unarm:
+   brcmf_cfg80211_arm_vif_event(cfg, NULL);
+   return err;
+}
+
 static
 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
 {
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
struct net_device *ndev = wdev->netdev;
 
+   if (ndev == cfg_to_ndev(cfg))
+   return -ENOTSUPP;
+
/* vif event pending in firmware */
if (brcmf_cfg80211_vif_event_armed(cfg))
return -EBUSY;
@@ -807,12 +841,13 @@ int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct 
wireless_dev *wdev)
switch (wdev->iftype) {
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_STATION:
-   case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_MESH_POINT:
return -EOPNOTSUPP;
+   case NL80211_IFTYPE_AP:
+   return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_P2P_DEVICE:
-- 
1.8.4.5



Re: [PATCH] net: rds: fix coding style issues

2016-06-18 Thread Joshua Houghton
On Saturday, 18 June 2016 09:22:49 UTC santosh.shilim...@oracle.com wrote:
> On 6/18/16 8:46 AM, Joshua Houghton wrote:
> > Fix coding style issues in the following files:
> > 
> > ib_cm.c:  add space
> > loop.c:   convert spaces to tabs
> > sysctl.c: add space
> > tcp.h:convert spaces to tabs
> > tcp_connect.c:remove extra indentation in switch statement
> > tcp_recv.c:   convert spaces to tabs
> > tcp_send.c:   convert spaces to tabs
> > transport.c:  move brace up one line on for statement
> > 
> > Signed-off-by: Joshua Houghton 
> > ---
> 
> Thanks for doing it.
> Acked-by: Santosh Shilimkar 

Your welcome. :)


[PATCH] brcmfmac: include also core.h header in cfg80211.h

2016-06-18 Thread Rafał Miłecki
This header provides two inline functions using struct brcmf_if so we
need core.h to avoid:

drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function 
‘ndev_to_prof’:
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:368:13: error: 
dereferencing pointer to incomplete type
  return &ifp->vif->profile;
 ^
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function 
‘ndev_to_vif’:
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:374:12: error: 
dereferencing pointer to incomplete type
  return ifp->vif;
^

Signed-off-by: Rafał Miłecki 
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 04bfc7e..7d77f86 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -20,6 +20,7 @@
 /* for brcmu_d11inf */
 #include 
 
+#include "core.h"
 #include "fwil_types.h"
 #include "p2p.h"
 
-- 
1.8.4.5



Re: [PATCH] net: rds: fix coding style issues

2016-06-18 Thread santosh.shilim...@oracle.com

On 6/18/16 8:46 AM, Joshua Houghton wrote:

Fix coding style issues in the following files:

ib_cm.c:  add space
loop.c:   convert spaces to tabs
sysctl.c: add space
tcp.h:convert spaces to tabs
tcp_connect.c:remove extra indentation in switch statement
tcp_recv.c:   convert spaces to tabs
tcp_send.c:   convert spaces to tabs
transport.c:  move brace up one line on for statement

Signed-off-by: Joshua Houghton 
---

Thanks for doing it.
Acked-by: Santosh Shilimkar 


Re: act_mirred: remove spinlock in fast path

2016-06-18 Thread Eric Dumazet
On Sat, 2016-06-18 at 11:24 -0400, Jamal Hadi Salim wrote:
> On 16-06-18 11:16 AM, Eric Dumazet wrote:
> 
> >> Given an update/replace of an action is such a rare occassion, what
> >> is wrong with init doing a spin lock on existing action?
> >> Sure, there is performance impact on fast path at that point - but:
> >> as established update/replace is _a rare occassion_ ;->
> >
> > The potential 'problem' is not the write side, but the read side.
> >
> > If you read say 3 values   you might want to read them in a
> > consistent way, instead of 
> >
> 
> That part i get.
> What i meant is: while the fast path is doing rcu_read_lock()
> of   and on the rare occassion that _init() is doing a
> write to  then if it should spin lock it would not corrupt
> what fast path sees as  during the transition.
> Am i misunderstanding?

Yes, I do not see how a change in the write side can help.

You probably need a bit of coffee ;)





Re: act_mirred: remove spinlock in fast path

2016-06-18 Thread Jamal Hadi Salim

On 16-06-18 11:16 AM, Eric Dumazet wrote:


Given an update/replace of an action is such a rare occassion, what
is wrong with init doing a spin lock on existing action?
Sure, there is performance impact on fast path at that point - but:
as established update/replace is _a rare occassion_ ;->


The potential 'problem' is not the write side, but the read side.

If you read say 3 values   you might want to read them in a
consistent way, instead of 



That part i get.
What i meant is: while the fast path is doing rcu_read_lock()
of   and on the rare occassion that _init() is doing a
write to  then if it should spin lock it would not corrupt
what fast path sees as  during the transition.
Am i misunderstanding?

cheers,
jamal


Re: act_mirred: remove spinlock in fast path

2016-06-18 Thread Eric Dumazet
On Sat, 2016-06-18 at 09:45 -0400, Jamal Hadi Salim wrote:
> On 16-06-17 06:03 PM, Eric Dumazet wrote:
> > On Fri, Jun 17, 2016 at 2:59 PM, Cong Wang  wrote:
> >
> >> Generally speaking I worry about we change multiple fields in a struct
> >> meanwhile we could still read them any time in the middle, we may
> >> get them correct for some easy case, but it is hard to insure the
> >> correctness when the struct becomes large.
> >>
> >> I am thinking to make more tc actions lockless, so this problem
> >> comes up immediately for other complex cases than mirred.
> >
> > I certainly wont object to a patch.
> >
> > Also note that instead of RCU with a pointer and the usual kfree_rcu() 
> > stuff,
> > we now can use seqcount_latch infra which might allow to not increase
> > memory foot print.
> >
> 
> Given an update/replace of an action is such a rare occassion, what
> is wrong with init doing a spin lock on existing action?
> Sure, there is performance impact on fast path at that point - but:
> as established update/replace is _a rare occassion_ ;->

The potential 'problem' is not the write side, but the read side.

If you read say 3 values   you might want to read them in a
consistent way, instead of 









[PATCH net-next 1/2] net: simplify and make pkt_type_ok() available for other users

2016-06-18 Thread Jamal Hadi Salim
From: Jamal Hadi Salim 

Suggested-by: Daniel Borkmann 
Signed-off-by: Jamal Hadi Salim 
---
 include/linux/skbuff.h   | 11 +++
 net/netfilter/nft_meta.c |  9 +
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index dc0fca7..0b794de 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* The interface for checksum offload between the stack and networking drivers
@@ -797,6 +798,7 @@ struct sk_buff {
atomic_tusers;
 };
 
+
 #ifdef __KERNEL__
 /*
  * Handling routines are only of interest to the kernel
@@ -881,6 +883,15 @@ static inline struct rtable *skb_rtable(const struct 
sk_buff *skb)
return (struct rtable *)skb_dst(skb);
 }
 
+/* For mangling skb->pkt_type from user space side from applications
+ * such as nft, tc, etc, we only allow a conservative subset of
+ * possible pkt_types to be set.
+*/
+static inline bool skb_pkt_type_ok(u32 p)
+{
+   return p <= PACKET_OTHERHOST;
+}
+
 void kfree_skb(struct sk_buff *skb);
 void kfree_skb_list(struct sk_buff *segs);
 void skb_tx_error(struct sk_buff *skb);
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 16c50b0..03e5e33 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -199,13 +199,6 @@ err:
 }
 EXPORT_SYMBOL_GPL(nft_meta_get_eval);
 
-/* don't change or set _LOOPBACK, _USER, etc. */
-static bool pkt_type_ok(u32 p)
-{
-   return p == PACKET_HOST || p == PACKET_BROADCAST ||
-  p == PACKET_MULTICAST || p == PACKET_OTHERHOST;
-}
-
 void nft_meta_set_eval(const struct nft_expr *expr,
   struct nft_regs *regs,
   const struct nft_pktinfo *pkt)
@@ -223,7 +216,7 @@ void nft_meta_set_eval(const struct nft_expr *expr,
break;
case NFT_META_PKTTYPE:
if (skb->pkt_type != value &&
-   pkt_type_ok(value) && pkt_type_ok(skb->pkt_type))
+   skb_pkt_type_ok(value) && skb_pkt_type_ok(skb->pkt_type))
skb->pkt_type = value;
break;
case NFT_META_NFTRACE:
-- 
1.9.1



[PATCH net-next 2/2] net sched actions: skbedit add support for mod-ing skb pkt_type

2016-06-18 Thread Jamal Hadi Salim
From: Jamal Hadi Salim 

Extremely useful for setting packet type to host so i dont
have to modify the dst mac address using pedit (which requires
that i know the mac address)

Example usage:
tc filter add dev eth0 parent : protocol ip pref 9 u32 \
match ip src 5.5.5.5/32 \
flowid 1:5 action skbedit ptype host

This will tag all packets incoming from 5.5.5.5 with type
PACKET_HOST

Signed-off-by: Jamal Hadi Salim 
---
 include/net/tc_act/tc_skbedit.h| 10 +-
 include/uapi/linux/tc_act/tc_skbedit.h |  2 ++
 net/sched/act_skbedit.c| 18 +-
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h
index b496d5a..d01a5d4 100644
--- a/include/net/tc_act/tc_skbedit.h
+++ b/include/net/tc_act/tc_skbedit.h
@@ -24,11 +24,11 @@
 
 struct tcf_skbedit {
struct tcf_common   common;
-   u32 flags;
-   u32 priority;
-   u32 mark;
-   u16 queue_mapping;
-   /* XXX: 16-bit pad here? */
+   u32 flags;
+   u32 priority;
+   u32 mark;
+   u16 queue_mapping;
+   u16 ptype;
 };
 #define to_skbedit(a) \
container_of(a->priv, struct tcf_skbedit, common)
diff --git a/include/uapi/linux/tc_act/tc_skbedit.h 
b/include/uapi/linux/tc_act/tc_skbedit.h
index fecb5cc..a4d00c6 100644
--- a/include/uapi/linux/tc_act/tc_skbedit.h
+++ b/include/uapi/linux/tc_act/tc_skbedit.h
@@ -27,6 +27,7 @@
 #define SKBEDIT_F_PRIORITY 0x1
 #define SKBEDIT_F_QUEUE_MAPPING0x2
 #define SKBEDIT_F_MARK 0x4
+#define SKBEDIT_F_PTYPE0x8
 
 struct tc_skbedit {
tc_gen;
@@ -40,6 +41,7 @@ enum {
TCA_SKBEDIT_QUEUE_MAPPING,
TCA_SKBEDIT_MARK,
TCA_SKBEDIT_PAD,
+   TCA_SKBEDIT_PTYPE,
__TCA_SKBEDIT_MAX
 };
 #define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index 53d1486..1c4c924 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -47,6 +47,8 @@ static int tcf_skbedit(struct sk_buff *skb, const struct 
tc_action *a,
skb_set_queue_mapping(skb, d->queue_mapping);
if (d->flags & SKBEDIT_F_MARK)
skb->mark = d->mark;
+   if (d->flags & SKBEDIT_F_PTYPE)
+   skb->pkt_type = d->ptype;
 
spin_unlock(&d->tcf_lock);
return d->tcf_action;
@@ -57,6 +59,7 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX 
+ 1] = {
[TCA_SKBEDIT_PRIORITY]  = { .len = sizeof(u32) },
[TCA_SKBEDIT_QUEUE_MAPPING] = { .len = sizeof(u16) },
[TCA_SKBEDIT_MARK]  = { .len = sizeof(u32) },
+   [TCA_SKBEDIT_PTYPE] = { .len = sizeof(u16) },
 };
 
 static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
@@ -68,7 +71,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr 
*nla,
struct tc_skbedit *parm;
struct tcf_skbedit *d;
u32 flags = 0, *priority = NULL, *mark = NULL;
-   u16 *queue_mapping = NULL;
+   u16 *queue_mapping = NULL, *ptype = NULL;
bool exists = false;
int ret = 0, err;
 
@@ -92,6 +95,13 @@ static int tcf_skbedit_init(struct net *net, struct nlattr 
*nla,
queue_mapping = nla_data(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
}
 
+   if (tb[TCA_SKBEDIT_PTYPE] != NULL) {
+   ptype = nla_data(tb[TCA_SKBEDIT_PTYPE]);
+   if (!skb_pkt_type_ok(*ptype))
+   return -EINVAL;
+   flags |= SKBEDIT_F_PTYPE;
+   }
+
if (tb[TCA_SKBEDIT_MARK] != NULL) {
flags |= SKBEDIT_F_MARK;
mark = nla_data(tb[TCA_SKBEDIT_MARK]);
@@ -132,6 +142,8 @@ static int tcf_skbedit_init(struct net *net, struct nlattr 
*nla,
d->queue_mapping = *queue_mapping;
if (flags & SKBEDIT_F_MARK)
d->mark = *mark;
+   if (flags & SKBEDIT_F_PTYPE)
+   d->ptype = *ptype;
 
d->tcf_action = parm->action;
 
@@ -169,6 +181,10 @@ static int tcf_skbedit_dump(struct sk_buff *skb, struct 
tc_action *a,
nla_put(skb, TCA_SKBEDIT_MARK, sizeof(d->mark),
&d->mark))
goto nla_put_failure;
+   if ((d->flags & SKBEDIT_F_PTYPE) &&
+   nla_put(skb, TCA_SKBEDIT_PTYPE, sizeof(d->ptype),
+   &d->ptype))
+   goto nla_put_failure;
 
tcf_tm_dump(&t, &d->tcf_tm);
if (nla_put_64bit(skb, TCA_SKBEDIT_TM, sizeof(t), &t, TCA_SKBEDIT_PAD))
-- 
1.9.1



[PATCH] net: rds: fix coding style issues

2016-06-18 Thread Joshua Houghton
Fix coding style issues in the following files:

ib_cm.c:  add space
loop.c:   convert spaces to tabs
sysctl.c: add space
tcp.h:convert spaces to tabs
tcp_connect.c:remove extra indentation in switch statement
tcp_recv.c:   convert spaces to tabs
tcp_send.c:   convert spaces to tabs
transport.c:  move brace up one line on for statement

Signed-off-by: Joshua Houghton 
---
 net/rds/ib_cm.c   |  2 +-
 net/rds/loop.c|  5 +++--
 net/rds/sysctl.c  |  3 ++-
 net/rds/tcp.h |  2 +-
 net/rds/tcp_connect.c | 26 +-
 net/rds/tcp_recv.c|  2 +-
 net/rds/tcp_send.c| 14 +++---
 net/rds/transport.c   |  3 +--
 8 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index 310cabc..7c2a65a 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -111,7 +111,7 @@ void rds_ib_cm_connect_complete(struct rds_connection 
*conn, struct rdma_cm_even
}
}
 
-   if (conn->c_version < RDS_PROTOCOL(3,1)) {
+   if (conn->c_version < RDS_PROTOCOL(3, 1)) {
printk(KERN_NOTICE "RDS/IB: Connection to %pI4 version %u.%u 
failed,"
   " no longer supported\n",
   &conn->c_faddr,
diff --git a/net/rds/loop.c b/net/rds/loop.c
index 6b12b68..814173b 100644
--- a/net/rds/loop.c
+++ b/net/rds/loop.c
@@ -95,8 +95,9 @@ out:
  */
 static void rds_loop_inc_free(struct rds_incoming *inc)
 {
-struct rds_message *rm = container_of(inc, struct rds_message, m_inc);
-rds_message_put(rm);
+   struct rds_message *rm = container_of(inc, struct rds_message, m_inc);
+
+   rds_message_put(rm);
 }
 
 /* we need to at least give the thread something to succeed */
diff --git a/net/rds/sysctl.c b/net/rds/sysctl.c
index c173f69..e381bbc 100644
--- a/net/rds/sysctl.c
+++ b/net/rds/sysctl.c
@@ -102,7 +102,8 @@ int rds_sysctl_init(void)
rds_sysctl_reconnect_min = msecs_to_jiffies(1);
rds_sysctl_reconnect_min_jiffies = rds_sysctl_reconnect_min;
 
-   rds_sysctl_reg_table = register_net_sysctl(&init_net,"net/rds", 
rds_sysctl_rds_table);
+   rds_sysctl_reg_table =
+   register_net_sysctl(&init_net, "net/rds", rds_sysctl_rds_table);
if (!rds_sysctl_reg_table)
return -ENOMEM;
return 0;
diff --git a/net/rds/tcp.h b/net/rds/tcp.h
index ec0602b..7940bab 100644
--- a/net/rds/tcp.h
+++ b/net/rds/tcp.h
@@ -83,7 +83,7 @@ int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct 
iov_iter *to);
 void rds_tcp_xmit_prepare(struct rds_connection *conn);
 void rds_tcp_xmit_complete(struct rds_connection *conn);
 int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm,
-unsigned int hdr_off, unsigned int sg, unsigned int off);
+unsigned int hdr_off, unsigned int sg, unsigned int off);
 void rds_tcp_write_space(struct sock *sk);
 
 /* tcp_stats.c */
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index fba13d0..f6e95d6 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -54,19 +54,19 @@ void rds_tcp_state_change(struct sock *sk)
 
rdsdebug("sock %p state_change to %d\n", tc->t_sock, sk->sk_state);
 
-   switch(sk->sk_state) {
-   /* ignore connecting sockets as they make progress */
-   case TCP_SYN_SENT:
-   case TCP_SYN_RECV:
-   break;
-   case TCP_ESTABLISHED:
-   rds_connect_path_complete(conn, RDS_CONN_CONNECTING);
-   break;
-   case TCP_CLOSE_WAIT:
-   case TCP_CLOSE:
-   rds_conn_drop(conn);
-   default:
-   break;
+   switch (sk->sk_state) {
+   /* ignore connecting sockets as they make progress */
+   case TCP_SYN_SENT:
+   case TCP_SYN_RECV:
+   break;
+   case TCP_ESTABLISHED:
+   rds_connect_path_complete(conn, RDS_CONN_CONNECTING);
+   break;
+   case TCP_CLOSE_WAIT:
+   case TCP_CLOSE:
+   rds_conn_drop(conn);
+   default:
+   break;
}
 out:
read_unlock_bh(&sk->sk_callback_lock);
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index c3196f9..6e6a711 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -171,7 +171,7 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, 
struct sk_buff *skb,
while (left) {
if (!tinc) {
tinc = kmem_cache_alloc(rds_tcp_incoming_slab,
-   arg->gfp);
+   arg->gfp);
if (!tinc) {
desc->error = -ENOMEM;
goto out;
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c
index 22d0f20..618be69 100644
--- a/net/rds/tcp_send.c
+++ b/net/rds/tcp_send.c
@@ -6

Re: [BUG] act_ife: sleeping functions called in atomic context

2016-06-18 Thread Jamal Hadi Salim

On 16-06-17 01:31 PM, Cong Wang wrote:


My patch is against -net. (I see you already figured out your patch is
missing in -net-next.)



Ok, should have re-read this email before working on the patch;->


Or are you suggesting to rebase it for -net-next? I think it fixes some real
bug so -net is better, although it is slightly large as a bug fix.



I am conflicted. There are a lot of changes in net-next at the moment;
adding this to -net seems like will definetely cause merge issues for
Dave.

Ok, Cong - patch attached and tested. Let me know what you think.

cheers,
jamal


diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index b7fa969..b52deb4 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -239,8 +239,7 @@ static int ife_validate_metatype(struct tcf_meta_ops *ops, 
void *val, int len)
return ret;
 }
 
-/* called when adding new meta information
- * under ife->tcf_lock
+/* called to find new metadata ops. Possibly load it as a module.
 */
 static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid,
void *val, int len)
@@ -251,11 +250,9 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, 
u32 metaid,
if (!ops) {
ret = -ENOENT;
 #ifdef CONFIG_MODULES
-   spin_unlock_bh(&ife->tcf_lock);
rtnl_unlock();
request_module("ifemeta%u", metaid);
rtnl_lock();
-   spin_lock_bh(&ife->tcf_lock);
ops = find_ife_oplist(metaid);
 #endif
}
@@ -272,7 +269,6 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, 
u32 metaid,
 }
 
 /* called when adding new meta information
- * under ife->tcf_lock
 */
 static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
int len)
@@ -302,7 +298,9 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 
metaid, void *metaval,
}
}
 
+   spin_lock_bh(&ife->tcf_lock);
list_add_tail(&mi->metalist, &ife->metalist);
+   spin_unlock_bh(&ife->tcf_lock);
 
return ret;
 }
@@ -357,7 +355,6 @@ out_nlmsg_trim:
return -1;
 }
 
-/* under ife->tcf_lock */
 static void _tcf_ife_cleanup(struct tc_action *a, int bind)
 {
struct tcf_ife_info *ife = a->priv;
@@ -385,7 +382,6 @@ static void tcf_ife_cleanup(struct tc_action *a, int bind)
spin_unlock_bh(&ife->tcf_lock);
 }
 
-/* under ife->tcf_lock */
 static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb)
 {
int len = 0;
@@ -465,6 +461,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
}
 
ife = to_ife(a);
+   if (exists)
+   spin_lock_bh(&ife->tcf_lock);
ife->flags = parm->flags;
 
if (parm->flags & IFE_ENCODE) {
@@ -475,10 +473,9 @@ static int tcf_ife_init(struct net *net, struct nlattr 
*nla,
saddr = nla_data(tb[TCA_IFE_SMAC]);
}
 
-   spin_lock_bh(&ife->tcf_lock);
ife->tcf_action = parm->action;
-
if (parm->flags & IFE_ENCODE) {
+
if (daddr)
ether_addr_copy(ife->eth_dst, daddr);
else
@@ -492,6 +489,9 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
ife->eth_type = ife_type;
}
 
+   if (exists)
+   spin_unlock_bh(&ife->tcf_lock);
+
if (ret == ACT_P_CREATED)
INIT_LIST_HEAD(&ife->metalist);
 
@@ -505,7 +505,6 @@ metadata_parse_err:
if (ret == ACT_P_CREATED)
_tcf_ife_cleanup(a, bind);
 
-   spin_unlock_bh(&ife->tcf_lock);
return err;
}
 
@@ -524,13 +523,10 @@ metadata_parse_err:
if (ret == ACT_P_CREATED)
_tcf_ife_cleanup(a, bind);
 
-   spin_unlock_bh(&ife->tcf_lock);
return err;
}
}
 
-   spin_unlock_bh(&ife->tcf_lock);
-
if (ret == ACT_P_CREATED)
tcf_hash_insert(tn, a);
 


[PATCH 2/2] net: ethernet: altera_tse: use phy_ethtool_{get|set}_link_ksettings

2016-06-18 Thread Philippe Reynes
There are two generics functions phy_ethtool_{get|set}_link_ksettings,
so we can use them instead of defining the same code in the driver.

Signed-off-by: Philippe Reynes 
---
 drivers/net/ethernet/altera/altera_tse_ethtool.c |   24 +
 1 files changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c 
b/drivers/net/ethernet/altera/altera_tse_ethtool.c
index c1b5608..7c36771 100644
--- a/drivers/net/ethernet/altera/altera_tse_ethtool.c
+++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c
@@ -233,38 +233,18 @@ static void tse_get_regs(struct net_device *dev, struct 
ethtool_regs *regs,
buf[i] = csrrd32(priv->mac_dev, i * 4);
 }
 
-static int tse_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-   struct phy_device *phydev = dev->phydev;
-
-   if (phydev == NULL)
-   return -ENODEV;
-
-   return phy_ethtool_gset(phydev, cmd);
-}
-
-static int tse_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-   struct phy_device *phydev = dev->phydev;
-
-   if (phydev == NULL)
-   return -ENODEV;
-
-   return phy_ethtool_sset(phydev, cmd);
-}
-
 static const struct ethtool_ops tse_ethtool_ops = {
.get_drvinfo = tse_get_drvinfo,
.get_regs_len = tse_reglen,
.get_regs = tse_get_regs,
.get_link = ethtool_op_get_link,
-   .get_settings = tse_get_settings,
-   .set_settings = tse_set_settings,
.get_strings = tse_gstrings,
.get_sset_count = tse_sset_count,
.get_ethtool_stats = tse_fill_stats,
.get_msglevel = tse_get_msglevel,
.set_msglevel = tse_set_msglevel,
+   .get_link_ksettings = phy_ethtool_get_link_ksettings,
+   .set_link_ksettings = phy_ethtool_set_link_ksettings,
 };
 
 void altera_tse_set_ethtool_ops(struct net_device *netdev)
-- 
1.7.4.4



[PATCH 1/2] net: ethernet: altera_tse: use phydev from struct net_device

2016-06-18 Thread Philippe Reynes
The private structure contain a pointer to phydev, but the structure
net_device already contain such pointer. So we can remove the pointer
phydev in the private structure, and update the driver to use the
one contained in struct net_device.

Signed-off-by: Philippe Reynes 
---
 drivers/net/ethernet/altera/altera_tse.h |1 -
 drivers/net/ethernet/altera/altera_tse_ethtool.c |6 ++
 drivers/net/ethernet/altera/altera_tse_main.c|   16 +++-
 3 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_tse.h 
b/drivers/net/ethernet/altera/altera_tse.h
index 103c30d..e005200 100644
--- a/drivers/net/ethernet/altera/altera_tse.h
+++ b/drivers/net/ethernet/altera/altera_tse.h
@@ -473,7 +473,6 @@ struct altera_tse_private {
int phy_addr;   /* PHY's MDIO address, -1 for autodetection */
phy_interface_t phy_iface;
struct mii_bus *mdio;
-   struct phy_device *phydev;
int oldspeed;
int oldduplex;
int oldlink;
diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c 
b/drivers/net/ethernet/altera/altera_tse_ethtool.c
index be72e1e..c1b5608 100644
--- a/drivers/net/ethernet/altera/altera_tse_ethtool.c
+++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c
@@ -235,8 +235,7 @@ static void tse_get_regs(struct net_device *dev, struct 
ethtool_regs *regs,
 
 static int tse_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-   struct altera_tse_private *priv = netdev_priv(dev);
-   struct phy_device *phydev = priv->phydev;
+   struct phy_device *phydev = dev->phydev;
 
if (phydev == NULL)
return -ENODEV;
@@ -246,8 +245,7 @@ static int tse_get_settings(struct net_device *dev, struct 
ethtool_cmd *cmd)
 
 static int tse_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-   struct altera_tse_private *priv = netdev_priv(dev);
-   struct phy_device *phydev = priv->phydev;
+   struct phy_device *phydev = dev->phydev;
 
if (phydev == NULL)
return -ENODEV;
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c 
b/drivers/net/ethernet/altera/altera_tse_main.c
index f749e4d..49025e9 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -625,7 +625,7 @@ out:
 static void altera_tse_adjust_link(struct net_device *dev)
 {
struct altera_tse_private *priv = netdev_priv(dev);
-   struct phy_device *phydev = priv->phydev;
+   struct phy_device *phydev = dev->phydev;
int new_state = 0;
 
/* only change config if there is a link */
@@ -845,7 +845,6 @@ static int init_phy(struct net_device *dev)
netdev_dbg(dev, "attached to PHY %d UID 0x%08x Link = %d\n",
   phydev->mdio.addr, phydev->phy_id, phydev->link);
 
-   priv->phydev = phydev;
return 0;
 }
 
@@ -1172,8 +1171,8 @@ static int tse_open(struct net_device *dev)
 
spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags);
 
-   if (priv->phydev)
-   phy_start(priv->phydev);
+   if (dev->phydev)
+   phy_start(dev->phydev);
 
napi_enable(&priv->napi);
netif_start_queue(dev);
@@ -1205,8 +1204,8 @@ static int tse_shutdown(struct net_device *dev)
unsigned long int flags;
 
/* Stop the PHY */
-   if (priv->phydev)
-   phy_stop(priv->phydev);
+   if (dev->phydev)
+   phy_stop(dev->phydev);
 
netif_stop_queue(dev);
napi_disable(&priv->napi);
@@ -1545,10 +1544,9 @@ err_free_netdev:
 static int altera_tse_remove(struct platform_device *pdev)
 {
struct net_device *ndev = platform_get_drvdata(pdev);
-   struct altera_tse_private *priv = netdev_priv(ndev);
 
-   if (priv->phydev)
-   phy_disconnect(priv->phydev);
+   if (ndev->phydev)
+   phy_disconnect(ndev->phydev);
 
platform_set_drvdata(pdev, NULL);
altera_tse_mdio_destroy(ndev);
-- 
1.7.4.4



Re: [patch net-next v4 0/4] return offloaded stats as default and expose original sw stats

2016-06-18 Thread Jamal Hadi Salim

On 16-06-18 04:00 AM, Jiri Pirko wrote:

Fri, Jun 17, 2016 at 07:12:22PM CEST, f.faine...@gmail.com wrote:



Yep. And I believe that for offloaded forwarding, this tools should see
hw counters, as they show what is going on in real.


If your NIC is offloading packets today, these tools typically won't see
these stats, but ethtool -S likely will report what is going on under
the hood.

Do we actually need to tell apart SW maintained from HW maintained
stats, or at the end all that matters is just, as DaveM pointed out,
getting the information, and in the case of an Ethernet switch, return
HW stats by default and supplement with SW stats whenever we have them,
all in the same namespace?




In general it is extremely useful for debugging to be able to see them
separately. One API to unify them (and that API being netlink) is
the way to go. I dont know if you can ever obsolete ethtool if lots
of other utils are using it - but would be nice.
It is also useful to just get the sum of them - but user space can
take care of that. David A., whatever user space tools that depended
on ethtool should now be able to retrieve them via netlink, no?


I believe it is valuable for user to know stats for slow path
(non-forwarded by ASIC). Also, it's just another rtnl attr. Easy.



So Jiri, I see:
IFLA_SW_STATS64 should that be: IFLA_HW_STATS_LINK_64?
I think IFLA_STATS_LINK_64 should continue to send s/ware stats.

cheers,
jamal


Re: [PATCH v2 net-next 0/3] net sched action timestamp improvements

2016-06-18 Thread Jamal Hadi Salim

On 16-06-18 12:31 AM, David Miller wrote:

From: Jamal Hadi Salim 
Date: Fri, 17 Jun 2016 07:15:27 -0400


Ok, mystery solved. Dave, this patch series is missing from current
net-next.


Then what is:

commit 53eb440f4ada034ea43b295891feec3df0fa7a29


/blink, blink
sorry ;-> I should have pulled before yelling.

So Cong what tree are you using? ;->

cheers,
jamal


Re: act_mirred: remove spinlock in fast path

2016-06-18 Thread Jamal Hadi Salim

On 16-06-17 06:03 PM, Eric Dumazet wrote:

On Fri, Jun 17, 2016 at 2:59 PM, Cong Wang  wrote:


Generally speaking I worry about we change multiple fields in a struct
meanwhile we could still read them any time in the middle, we may
get them correct for some easy case, but it is hard to insure the
correctness when the struct becomes large.

I am thinking to make more tc actions lockless, so this problem
comes up immediately for other complex cases than mirred.


I certainly wont object to a patch.

Also note that instead of RCU with a pointer and the usual kfree_rcu() stuff,
we now can use seqcount_latch infra which might allow to not increase
memory foot print.



Given an update/replace of an action is such a rare occassion, what
is wrong with init doing a spin lock on existing action?
Sure, there is performance impact on fast path at that point - but:
as established update/replace is _a rare occassion_ ;->

cheers,
jamal


Re: mwifiex: fix link error against sdio

2016-06-18 Thread Kalle Valo
Arnd Bergmann  wrote:
> Calling sdio_claim_host() from the interface independent part of
> the mwifiex driver is not only a layering violation, but also causes
> a link error if MMC support is disabled, or if CONFIG_MMC=m
> and CONFIG_MWIFIEX=y:
> 
> drivers/net/built-in.o: In function `mwifiex_fw_dpc':
> :(.text+0xff138): undefined reference to `sdio_claim_host'
> :(.text+0xff158): undefined reference to `sdio_release_host'
> 
> The right way to do this is to have the sdio specific code in the
> sdio driver front-end, and we already have a callback pointer that
> we can use for this after exporting the generic fw download
> function from the core driver.
> 
> Signed-off-by: Arnd Bergmann 
> Fixes: 65c71efe1c59 ("mwifiex: fix racing condition when downloading 
> firmware")

Thanks, 1 patch applied to wireless-drivers-next.git:

2095b1426c9c mwifiex: fix link error against sdio

-- 
Sent by pwcli
https://patchwork.kernel.org/patch/9180095/



[PATCH 2/2] net: ethernet: sun4i-emac: use phy_ethtool_{get|set}_link_ksettings

2016-06-18 Thread Philippe Reynes
There are two generics functions phy_ethtool_{get|set}_link_ksettings,
so we can use them instead of defining the same code in the driver.

Signed-off-by: Philippe Reynes 
---
 drivers/net/ethernet/allwinner/sun4i-emac.c |   24 ++--
 1 files changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c 
b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 6e31cb6..6ffdff6 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -225,31 +225,11 @@ static void emac_get_drvinfo(struct net_device *dev,
strlcpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info));
 }
 
-static int emac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-   struct phy_device *phydev = dev->phydev;
-
-   if (!phydev)
-   return -ENODEV;
-
-   return phy_ethtool_gset(phydev, cmd);
-}
-
-static int emac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-   struct phy_device *phydev = dev->phydev;
-
-   if (!phydev)
-   return -ENODEV;
-
-   return phy_ethtool_sset(phydev, cmd);
-}
-
 static const struct ethtool_ops emac_ethtool_ops = {
.get_drvinfo= emac_get_drvinfo,
-   .get_settings   = emac_get_settings,
-   .set_settings   = emac_set_settings,
.get_link   = ethtool_op_get_link,
+   .get_link_ksettings = phy_ethtool_get_link_ksettings,
+   .set_link_ksettings = phy_ethtool_set_link_ksettings,
 };
 
 static unsigned int emac_setup(struct net_device *ndev)
-- 
1.7.4.4



[PATCH 1/2] net: ethernet: sun4i-emac: use phydev from struct net_device

2016-06-18 Thread Philippe Reynes
The private structure contain a pointer to phydev, but the structure
net_device already contain such pointer. So we can remove the pointer
phydev in the private structure, and update the driver to use the
one contained in struct net_device.

Signed-off-by: Philippe Reynes 
---
 drivers/net/ethernet/allwinner/sun4i-emac.c |   34 +++---
 1 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c 
b/drivers/net/ethernet/allwinner/sun4i-emac.c
index de2c4bf..6e31cb6 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -77,7 +77,6 @@ struct emac_board_info {
 
int emacrx_completed_flag;
 
-   struct phy_device   *phy_dev;
struct device_node  *phy_node;
unsigned intlink;
unsigned intspeed;
@@ -115,7 +114,7 @@ static void emac_update_duplex(struct net_device *dev)
 static void emac_handle_link_change(struct net_device *dev)
 {
struct emac_board_info *db = netdev_priv(dev);
-   struct phy_device *phydev = db->phy_dev;
+   struct phy_device *phydev = dev->phydev;
unsigned long flags;
int status_change = 0;
 
@@ -154,21 +153,22 @@ static void emac_handle_link_change(struct net_device 
*dev)
 static int emac_mdio_probe(struct net_device *dev)
 {
struct emac_board_info *db = netdev_priv(dev);
+   struct phy_device *phydev;
 
/* to-do: PHY interrupts are currently not supported */
 
/* attach the mac to the phy */
-   db->phy_dev = of_phy_connect(db->ndev, db->phy_node,
-&emac_handle_link_change, 0,
-db->phy_interface);
-   if (!db->phy_dev) {
+   phydev = of_phy_connect(db->ndev, db->phy_node,
+   &emac_handle_link_change, 0,
+   db->phy_interface);
+   if (!phydev) {
netdev_err(db->ndev, "could not find the PHY\n");
return -ENODEV;
}
 
/* mask with MAC supported features */
-   db->phy_dev->supported &= PHY_BASIC_FEATURES;
-   db->phy_dev->advertising = db->phy_dev->supported;
+   phydev->supported &= PHY_BASIC_FEATURES;
+   phydev->advertising = phydev->supported;
 
db->link = 0;
db->speed = 0;
@@ -179,10 +179,7 @@ static int emac_mdio_probe(struct net_device *dev)
 
 static void emac_mdio_remove(struct net_device *dev)
 {
-   struct emac_board_info *db = netdev_priv(dev);
-
-   phy_disconnect(db->phy_dev);
-   db->phy_dev = NULL;
+   phy_disconnect(dev->phydev);
 }
 
 static void emac_reset(struct emac_board_info *db)
@@ -208,8 +205,7 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, 
int count)
 
 static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-   struct emac_board_info *dm = netdev_priv(dev);
-   struct phy_device *phydev = dm->phy_dev;
+   struct phy_device *phydev = dev->phydev;
 
if (!netif_running(dev))
return -EINVAL;
@@ -231,8 +227,7 @@ static void emac_get_drvinfo(struct net_device *dev,
 
 static int emac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-   struct emac_board_info *dm = netdev_priv(dev);
-   struct phy_device *phydev = dm->phy_dev;
+   struct phy_device *phydev = dev->phydev;
 
if (!phydev)
return -ENODEV;
@@ -242,8 +237,7 @@ static int emac_get_settings(struct net_device *dev, struct 
ethtool_cmd *cmd)
 
 static int emac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-   struct emac_board_info *dm = netdev_priv(dev);
-   struct phy_device *phydev = dm->phy_dev;
+   struct phy_device *phydev = dev->phydev;
 
if (!phydev)
return -ENODEV;
@@ -744,7 +738,7 @@ static int emac_open(struct net_device *dev)
return ret;
}
 
-   phy_start(db->phy_dev);
+   phy_start(dev->phydev);
netif_start_queue(dev);
 
return 0;
@@ -781,7 +775,7 @@ static int emac_stop(struct net_device *ndev)
netif_stop_queue(ndev);
netif_carrier_off(ndev);
 
-   phy_stop(db->phy_dev);
+   phy_stop(ndev->phydev);
 
emac_mdio_remove(ndev);
 
-- 
1.7.4.4



[patch 3/3 -mainline] liquidio: off by one in liquidio_set_mcast_list()

2016-06-18 Thread Dan Carpenter
The nctrl.udd[] array has 32 elements of size u64.

Imagine that netdev_mc_count() returns more than 32.  That means
"mc_count" is 32.  On the last iteration through the loop we have
mc == &nctrl.udd[32] so we're writing one element beyond the end
of the array.

Fixes: f21fb3ed364b ('Add support of Cavium Liquidio ethernet adapters')
Signed-off-by: Dan Carpenter 

diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c 
b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 1126422..41ee8bd 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -2376,7 +2376,7 @@ static void liquidio_set_mcast_list(struct net_device 
*netdev)
memcpy(((u8 *)mc) + 2, ha->addr, ETH_ALEN);
/* no need to swap bytes */
 
-   if (++mc > &nctrl.udd[mc_count])
+   if (++mc >= &nctrl.udd[mc_count])
break;
}
 


[patch 2/3] liquidio: remove an unused variable

2016-06-18 Thread Dan Carpenter
We don't use "i" in this function.

Signed-off-by: Dan Carpenter 

diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c 
b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 715ddfa..1126422 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -2354,7 +2354,7 @@ static void liquidio_set_mcast_list(struct net_device 
*netdev)
struct octnic_ctrl_pkt nctrl;
struct netdev_hw_addr *ha;
u64 *mc;
-   int ret, i;
+   int ret;
int mc_count = min(netdev_mc_count(netdev), MAX_OCTEON_MULTICAST_ADDR);
 
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
@@ -2370,7 +2370,6 @@ static void liquidio_set_mcast_list(struct net_device 
*netdev)
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
/* copy all the addresses into the udd */
-   i = 0;
mc = &nctrl.udd[0];
netdev_for_each_mc_addr(ha, netdev) {
*mc = 0;


[patch 1/3 -next] liquidio: a couple indenting tweaks

2016-06-18 Thread Dan Carpenter
Remove a stray space character and fix an if statement that wasn't
indented.

Signed-off-by: Dan Carpenter 
---
Speaking of style issues, this whole file follows return 1 on error
and 0 on success.  It was confusing for me.  It's not too late to change
it to use correct error codes.  ;)

diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c 
b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index d0ab97c..715ddfa 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -365,7 +365,7 @@ static int wait_for_pending_requests(struct octeon_device 
*oct)
[OCTEON_ORDERED_SC_LIST].pending_req_count);
if (pcount)
schedule_timeout_uninterruptible(HZ / 10);
-else
+   else
break;
}
 
@@ -3351,8 +3351,8 @@ static int setup_nic_devices(struct octeon_device 
*octeon_dev)
liquidio_set_ethtool_ops(netdev);
 
if (netdev->features & NETIF_F_LRO)
-   liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE,
-OCTNIC_LROIPV4 | OCTNIC_LROIPV6);
+   liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE,
+OCTNIC_LROIPV4 | OCTNIC_LROIPV6);
 
if ((debug != -1) && (debug & NETIF_MSG_HW))
liquidio_set_feature(netdev, OCTNET_CMD_VERBOSE_ENABLE,


[patch net-next] rxrpc: checking for IS_ERR() instead of NULL

2016-06-18 Thread Dan Carpenter
rxrpc_lookup_peer_rcu() returns NULL on error, it never returns error
pointers.

Fixes: be6e6707f6ee ('rxrpc: Rework peer object handling to use hash table and 
RCU')
Signed-off-by: Dan Carpenter 

diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index 47fb167..e11e4d7 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -639,7 +639,7 @@ static struct rxrpc_connection 
*rxrpc_conn_from_local(struct rxrpc_local *local,
rxrpc_get_addr_from_skb(local, skb, &srx);
rcu_read_lock();
peer = rxrpc_lookup_peer_rcu(local, &srx);
-   if (IS_ERR(peer))
+   if (!peer)
goto cant_find_peer;
 
trans = rxrpc_find_transport(local, peer);


Re: [patch net-next v4 0/4] return offloaded stats as default and expose original sw stats

2016-06-18 Thread Jiri Pirko
Fri, Jun 17, 2016 at 07:12:22PM CEST, f.faine...@gmail.com wrote:
>On 06/17/2016 08:42 AM, Jiri Pirko wrote:
>> Fri, Jun 17, 2016 at 05:35:53PM CEST, d...@cumulusnetworks.com wrote:
>>> On 6/17/16 8:54 AM, Jamal Hadi Salim wrote:
 On 16-06-17 10:05 AM, Jiri Pirko wrote:
> Fri, Jun 17, 2016 at 03:48:35PM CEST, d...@cumulusnetworks.com wrote:
>> On 6/17/16 2:24 AM, Jiri Pirko wrote:
>>>

>
> That is problematic. Existing apps depend on rtnetlink stats. But if we
> don't count offloaded forwarded packets, the apps don't see anything.
> Therefore I believe that this patchset approach is better. The existing
> apps continue to work and future apps can use newly introduces sw_stats
> to query slowpath traffic. Makes sense to me.
>

 I agree with Jiri. It is a bad idea to depend on ethtool for any of
 this stuff. Is there a way we can tag netlink stats instead
 to indicate they are hardware or software?
>>>
>>> Right, old API but the key here is that low level h/w stats are returned by 
>>> a
>>> different API.
>>>
>>> By default ip, ifconfig, snmpd, etc all continue to get traditional S/W 
>>> stats
>>> - counters as seen by the CPU.
>> 
>> Yep. And I believe that for offloaded forwarding, this tools should see
>> hw counters, as they show what is going on in real.
>
>If your NIC is offloading packets today, these tools typically won't see
>these stats, but ethtool -S likely will report what is going on under
>the hood.
>
>Do we actually need to tell apart SW maintained from HW maintained
>stats, or at the end all that matters is just, as DaveM pointed out,
>getting the information, and in the case of an Ethernet switch, return
>HW stats by default and supplement with SW stats whenever we have them,
>all in the same namespace?

I believe it is valuable for user to know stats for slow path
(non-forwarded by ASIC). Also, it's just another rtnl attr. Easy.