Netdev List
 help / color / mirror / Atom feed
* Re: second wave of netlink extended ACK reporting
From: David Ahern @ 2017-04-16 14:50 UTC (permalink / raw)
  To: Jamal Hadi Salim, Johannes Berg,
	nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w, Jiri Pirko, Pravin Shelar,
	dev-yBygre7rU0TnMu66kgdUjQ
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA, Jiri Benc,
	pablo-Cap9r6Oaw4JrovVCs/uTlw
In-Reply-To: <280d0c61-4506-f721-1536-4afb2daabef8-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>

On 4/16/17 8:48 AM, Jamal Hadi Salim wrote:
> Excellent. His patches seem to be in. Seems
> commit ce07183282975026716107d36fd3f5f93de76668
> is a good point?

yes. will send later today.

^ permalink raw reply

* Re: [PATCH net-next v2 4/6] vxlan: check valid combinations of address scopes
From: Matthias Schiffer @ 2017-04-16 14:57 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
	roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
	jbenc-H+wXaHxf7aLQT0dZR+AlfA, aduyck-nYU0QVwCCFFWk0Htik3J/w,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <0dd0812f-41d7-f4d8-2b40-0ff5b4553cf5-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>


[-- Attachment #1.1.1: Type: text/plain, Size: 2729 bytes --]

On 04/14/2017 07:27 PM, Sergei Shtylyov wrote:
> On 04/14/2017 07:44 PM, Matthias Schiffer wrote:
> 
>> * Multicast addresses are never valid as local address
>> * Link-local IPv6 unicast addresses may only be used as remote when the
>>   local address is link-local as well
>> * Don't allow link-local IPv6 local/remote addresses without interface
>>
>> We also store in the flags field if link-local addresses are used for the
>> follow-up patches that actually make VXLAN over link-local IPv6 work.
>>
>> Signed-off-by: Matthias Schiffer <mschiffer-Nyw9WiXk/RKXhJHkyCwd5uTW4wlIGRCZ@public.gmane.org>
>> ---
>>
>> v2: was "vxlan: don't allow link-local IPv6 local/remote addresses without
>> interface" before. v2 does a lot more checks and adds the
>> VXLAN_F_IPV6_LINKLOCAL flag.
>>
>>  drivers/net/vxlan.c | 35 +++++++++++++++++++++++++++++++++++
>>  include/net/vxlan.h |  2 ++
>>  2 files changed, 37 insertions(+)
>>
>> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
>> index 07f89b037681..95a71546e8f2 100644
>> --- a/drivers/net/vxlan.c
>> +++ b/drivers/net/vxlan.c
>> @@ -2881,11 +2881,39 @@ static int vxlan_config_validate(struct net
>> *src_net, struct vxlan_config *conf,
>>      if (conf->saddr.sa.sa_family != conf->remote_ip.sa.sa_family)
>>          return -EINVAL;
>>
>> +    if (vxlan_addr_multicast(&conf->saddr))
>> +        return -EINVAL;
>> +
>>      if (conf->saddr.sa.sa_family == AF_INET6) {
>>          if (!IS_ENABLED(CONFIG_IPV6))
>>              return -EPFNOSUPPORT;
>>          use_ipv6 = true;
>>          conf->flags |= VXLAN_F_IPV6;
>> +
>> +        if (!(conf->flags & VXLAN_F_COLLECT_METADATA)) {
>> +            int local_type =
>> +                ipv6_addr_type(&conf->saddr.sin6.sin6_addr);
>> +            int remote_type =
>> +                ipv6_addr_type(&conf->remote_ip.sin6.sin6_addr);
>> +
>> +            if (local_type & IPV6_ADDR_LINKLOCAL) {
>> +                if (!(remote_type & IPV6_ADDR_LINKLOCAL) &&
>> +                    (remote_type != IPV6_ADDR_ANY)) {
>> +                    pr_info("invalid combination of address scopes\n");
> 
>    Maybe pr_err()?

Hmm, I mostly followed the style of the existing code, which uses pr_info
for such messages. Also, these messages can be triggered by userspace, as
they're diagnostics for the newlink/changelink operations; I'm not
convinced that their importance justifies pr_err().

Generally, it seems unusual to me to use the kernel log for configuration
diagnostics at all; just removing the messages would be another option.
Stephen also mentioned "extended netlink error reporting", but I guess that
can be done in another patchset.

Matthias


[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: [PATCH net-next v2 4/6] vxlan: check valid combinations of address scopes
From: Matthias Schiffer @ 2017-04-16 15:03 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
	roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
	jbenc-H+wXaHxf7aLQT0dZR+AlfA, aduyck-nYU0QVwCCFFWk0Htik3J/w,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170414103604.61ecffa9@xeon-e3>


[-- Attachment #1.1.1: Type: text/plain, Size: 1697 bytes --]

On 04/14/2017 07:36 PM, Stephen Hemminger wrote:
> On Fri, 14 Apr 2017 18:44:44 +0200
> Matthias Schiffer <mschiffer-Nyw9WiXk/RKXhJHkyCwd5uTW4wlIGRCZ@public.gmane.org> wrote:
> 
>> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
>> index 07f89b037681..95a71546e8f2 100644
>> --- a/drivers/net/vxlan.c
>> +++ b/drivers/net/vxlan.c
>> @@ -2881,11 +2881,39 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
>>  	if (conf->saddr.sa.sa_family != conf->remote_ip.sa.sa_family)
>>  		return -EINVAL;
>>  
>> +	if (vxlan_addr_multicast(&conf->saddr))
>> +		return -EINVAL;
>> +
>>  	if (conf->saddr.sa.sa_family == AF_INET6) {
>>  		if (!IS_ENABLED(CONFIG_IPV6))
>>  			return -EPFNOSUPPORT;
>>  		use_ipv6 = true;
>>  		conf->flags |= VXLAN_F_IPV6;
>> +
>> +		if (!(conf->flags & VXLAN_F_COLLECT_METADATA)) {
>> +			int local_type =
>> +				ipv6_addr_type(&conf->saddr.sin6.sin6_addr);
>> +			int remote_type =
>> +				ipv6_addr_type(&conf->remote_ip.sin6.sin6_addr);
>> +
>> +			if (local_type & IPV6_ADDR_LINKLOCAL) {
>> +				if (!(remote_type & IPV6_ADDR_LINKLOCAL) &&
>> +				    (remote_type != IPV6_ADDR_ANY)) {
>> +					pr_info("invalid combination of address scopes\n");
> 
> It is always helpful to include device if possible in error message.
> 					netdev_notice(old->dev, " invalid combination of address scopes\n");

That makes sense, I'll change it in v3.

> Also vxlan is good candidate for extended netlink error reporting.

Can you point me to a piece of code that does this? Unless you insist, I
wouldn't do it in this patchset, but I might implement the extended error
reporting later.

Matthias



[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: [PATCH net-next v2 6/6] vxlan: allow multiple VXLANs with same VNI for IPv6 link-local addresses
From: Matthias Schiffer @ 2017-04-16 15:15 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
	roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
	jbenc-H+wXaHxf7aLQT0dZR+AlfA, aduyck-nYU0QVwCCFFWk0Htik3J/w,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170414103830.111a24a8@xeon-e3>


[-- Attachment #1.1.1: Type: text/plain, Size: 1390 bytes --]

On 04/14/2017 07:38 PM, Stephen Hemminger wrote:
> On Fri, 14 Apr 2017 18:44:46 +0200
> Matthias Schiffer <mschiffer-Nyw9WiXk/RKXhJHkyCwd5uTW4wlIGRCZ@public.gmane.org> wrote:
> 
>> As link-local addresses are only valid for a single interface, we can allow
>> to use the same VNI for multiple independent VXLANs, as long as the used
>> interfaces are distinct. This way, VXLANs can always be used as a drop-in
>> replacement for VLANs with greater ID space.
>>
>> This also extends VNI lookup to respect the ifindex when link-local IPv6
>> addresses are used, so using the same VNI on multiple interfaces can
>> actually work.
>>
>> Signed-off-by: Matthias Schiffer <mschiffer-Nyw9WiXk/RKXhJHkyCwd5uTW4wlIGRCZ@public.gmane.org>
> 
> Why does this have to be IPv6 specific?

I'm not familar with IPv4 link-local addresses and how route lookup works
for them. vxlan_get_route() sets flowi4_oif to the outgoing interface; does
__ip_route_output_key_hash() do the right thing for link-local addresses
when such addresses are used on multiple interfaces? I see some special
casing for multicast destinations, but none for link-local ones.

> 
> What about the case where VXLAN is not bound to an interface?
> If that is used then that could be a problem.
> 

With patch 4/6, link-local IPv6 addresses can't be configured without an
interface anymore.

Matthias


[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: 4.10.9 nok with realtek wlan, atom
From: Larry Finger @ 2017-04-16 16:02 UTC (permalink / raw)
  To: rupert THURNER
  Cc: Bjorn Helgaas, linux-pci, Chaoming Li, Kalle Valo, linux-wireless,
	netdev, linux-kernel
In-Reply-To: <CAJs9aZ9Hwnjb60mCycR3T2TWH75ZTdtEeWQ1iHRN+6NkkD+pZA@mail.gmail.com>

On 04/16/2017 05:23 AM, rupert THURNER wrote:
> On Sat, Apr 15, 2017 at 10:40 PM, Larry Finger
> <Larry.Finger@lwfinger.net> wrote:
>> On 04/14/2017 03:26 PM, rupert THURNER wrote:
>>>
>>> On Thu, Feb 9, 2017 at 9:09 PM, Larry Finger <Larry.Finger@lwfinger.net>
>>> wrote:
>>>>
>>>> On 02/09/2017 01:43 PM, Bjorn Helgaas wrote:
>>>>>
>>>>>
>>>>> [+cc rtl8192ce folks in case they've seen this]
>>>>>
>>>>> On Thu, Feb 09, 2017 at 03:45:01PM +0100, rupert THURNER wrote:
>>>>>>
>>>>>>
>>>>>> hi,
>>>>>>
>>>>>> not technical expert enough, i just wanted to give a short user
>>>>>> feedback. for realtek wlan on atom, kernels up to 4.9.5 are ok, and
>>>>>> kernel 4.10.0-rc7-g926af6273fc6 (arch linux-git version numbering) as
>>>>>> well. kernels 4.9.6, 4.9.7, and 4.9.8 fail, i.e. connection to a WLAN
>>>>>> hotspot is possible then drops, or connecting to wlan fails
>>>>>> alltogether.
>>>>>
>>>>>
>>>>>
>>>>> Thanks very much for your report, and sorry for the inconvenience.
>>>>>
>>>>> v4.10-rc7 works, so I guess we don't need to worry about fixing v4.10.
>>>>>
>>>>> But the stable kernels v4.9.6, v4.9.7, and v4.9.8 are broken, so we
>>>>> need to figure out why and make sure we fix the v4.9 stable series.
>>>>>
>>>>> I can't tell yet whether this is PCI-related or not.  If it is,
>>>>> 4922a6a5cfa7 ("PCI: Enumerate switches below PCI-to-PCIe bridges")
>>>>> appeared in v4.9.6, and there is a known issue with that.  The issue
>>>>> should be fixed by 610c2b7ff8f6 ("PCI/ASPM: Handle PCI-to-PCIe bridges
>>>>> as roots of PCIe hierarchies"), which appeared in v4.9.9, so I guess
>>>>> the first thing to do would be to test v4.9.9.
>>>>>
>>>>> If it's not fixed in v4.9.9, can you share the complete dmesg log
>>>>> (output of "dmesg" command) and "lspci -vv" output for v4.9.5 (last
>>>>> known working version) and v4.9.6 (first known broken version)?  On
>>>>> v4.9.6, collect the dmesg output after the failure occurs.
>>>>>
>>>>>> 24: PCI 300.0: 0282 WLAN controller
>>>>>>   [Created at pci.366]
>>>>>>   Model: "Realtek RTL8188CE 802.11b/g/n WiFi Adapter"
>>>>>>   Device: pci 0x8176 "RTL8188CE 802.11b/g/n WiFi Adapter"
>>>>>>   Revision: 0x01
>>>>>>   Driver: "rtl8192ce"
>>>>>>   Driver Modules: "rtl8192ce"
>>>>>>   Device File: wlp3s0
>>>>>>   Features: WLAN
>>>>
>>>>
>>>>
>>>> It would be helpful if someone were to bisect this issue. The only issue
>>>> that comes to mind was fixed in commit 52f5631a4c05 ("rtlwifi: rtl8192ce:
>>>> Fix loading of incorrect firmware") which is in 4.10-rc7 and will be
>>>> backported to 4.9.
>>>>
>>>> The above issue is one that could not be reproduced on my hardware, thus
>>>> it
>>>> took Jurij Smakov to find the fix. Without his bisection of the problem,
>>>> who
>>>> knows how long it would have taken to find my edit mistake.
>>>
>>>
>>> larry, using the newest kernel 4.10.8 the network connection dropps
>>> again irregular.
>>>
>>> # dmesg
>>> [    0.000000] Linux version 4.10.9-1-ARCH (builduser@tobias) (gcc
>>> version 6.3.1 20170306 (GCC) ) #1 SMP PREEMPT Sat Apr 8 12:39:59 CEST
>>> 2017
>>> [   11.933373] rtl8192ce: rtl8192ce: Power Save off (module option)
>>> [   11.933396] rtl8192ce: Using firmware rtlwifi/rtl8192cfw.bin
>>> [   11.978307] ieee80211 phy0: Selected rate control algorithm 'rtl_rc'
>>> [   11.978945] rtlwifi: rtlwifi: wireless switch is on
>>>
>>> # lspci -vv
>>> Subsystem: Realtek Semiconductor Co., Ltd. RTL8188CE 802.11b/g/n WiFi
>>> Adapter
>>> Kernel driver in use: rtl8192ce
>>
>>
>> Is firmware rtlwifi/rtl8192cfw.bin also used on kernels that work?
>
> 4.10.x used to work. 4.10.6 or 4.10.7 it started failing? i am not too
> sure about it.
>
> # ls -l /usr/lib/firmware/rtlwifi/rtl8192cfw.bin
> -rw-r--r-- 1 root root 16192 Mar 10 12:15
> /usr/lib/firmware/rtlwifi/rtl8192cfw.bin

That does not answer my question.

Larry

^ permalink raw reply

* Re: [RFC patch 1/1] large netlink dumps
From: Stephen Hemminger @ 2017-04-16 16:37 UTC (permalink / raw)
  To: Jamal Hadi Salim
  Cc: Eric Dumazet, Johannes Berg, Pablo Neira Ayuso, David Miller,
	netdev@vger.kernel.org
In-Reply-To: <ae839ce5-351b-f351-3852-2d9f78669efb@mojatatu.com>

On Sun, 16 Apr 2017 09:03:08 -0400
Jamal Hadi Salim <jhs@mojatatu.com> wrote:

> On 17-04-15 11:08 PM, Eric Dumazet wrote:
> > On Sat, 2017-04-15 at 13:07 -0400, Jamal Hadi Salim wrote:  
> >> Eric,
> >>
> >> How does attached look instead of the 32K?
> >> I found it helps to let user space suggest something
> >> larger.
> >>
> >> cheers,
> >> jamal  
> >
> > Looks dangerous to me, for various reasons.
> >
> > 1) Memory allocations might not like it
> >
> > Have you tried your change after user does a
> > setsockopt(    SO_RCVBUFFORCE,  256 Mbytes), and a
> > recvmsg ( .. 64 Mbytes) ?
> >
> > Presumably, we could replace 32768 by (PAGE_SIZE <<
> > PAGE_ALLOC_COSTLY_ORDER), but this will not matter on x86.
> >  
> 
> For my use case I dont need to go that high, but i can see
> plausibility that someone else will. Is there a reasonable
> large number other than 32K? 128K-512K would be way sufficient.

It was common with routing daemons to set SO_RCVBUF to very large values
to avoid losing notifications.

> > 2) We might have paths in the kernel filling a potential big skb without
> > yielding cpu or a spinlock or a mutex. -> latency source.
> >
> >
> > What perf numbers do you have, using 1MB buffers instead of 32KB ?
> >
> > The syscall overhead seems tiny compared to the actual cost of filling
> > the netlink message, accessing thousands of cache lines all over the
> > places.
> >  
> 
> sycall is affecting me - but I have only compared with limited
> traffic running at the same time as dumping. The more i can batch
> the sooner i can stop polluting the cache.
> 
> The tests I have done are with a default socket buffer of 4M
> and say recvmsg(... 128K). I dont need to go higher
> that 256-512K to achieve my goals.
> With default of 32K I can fit about 250-60 actions in one batch.
> With 128K I can fit 4x that.
> It takes about 1.5 minutes for one process to dump 1M actions
> on my laptop (Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz) with
> 32K; 25% of that time with 128K. tc is single threaded, so i can
> keep one cpu busy 100% while I dump which means latency fear
> is lowered.
> 
> My eventual need: To dump all relevant stats every 5 seconds.
> I will send the other patch I talked about which filters based
> on time which helps in most cases but not always.
> 
> I am also now thinking of adding "a range index filter" and then
> multi-threading several parrallel requests, one for each range of
> indices.
> 
> cheers,
> jamal

^ permalink raw reply

* [PATCH net-next] net: rtnetlink: plumb extended ack to doit function
From: David Ahern @ 2017-04-16 16:48 UTC (permalink / raw)
  To: netdev; +Cc: jhs, David Ahern

Add netlink_ext_ack arg to rtnl_doit_func. Pass extack arg to nlmsg_parse
for doit functions that call it directly.

This is the first step to using extended error reporting in rtnetlink.
>From here individual subsystems can be updated to set netlink_ext_ack as
needed.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 drivers/net/vrf.c        |  4 ++--
 include/net/fib_rules.h  |  6 ++++--
 include/net/rtnetlink.h  |  3 ++-
 net/bridge/br_mdb.c      |  6 ++++--
 net/can/gw.c             |  6 ++++--
 net/core/fib_rules.c     | 10 ++++++----
 net/core/neighbour.c     | 15 +++++++++------
 net/core/net_namespace.c | 10 ++++++----
 net/core/rtnetlink.c     | 42 ++++++++++++++++++++++++++----------------
 net/dcb/dcbnl.c          |  5 +++--
 net/decnet/dn_dev.c      | 12 ++++++++----
 net/decnet/dn_fib.c      | 10 ++++++----
 net/decnet/dn_route.c    |  6 ++++--
 net/ipv4/devinet.c       | 13 ++++++++-----
 net/ipv4/fib_frontend.c  |  6 ++++--
 net/ipv4/ipmr.c          | 10 ++++++----
 net/ipv4/route.c         |  5 +++--
 net/ipv6/addrconf.c      | 20 ++++++++++++--------
 net/ipv6/addrlabel.c     | 12 ++++++++----
 net/ipv6/route.c         | 11 +++++++----
 net/mpls/af_mpls.c       |  9 ++++++---
 net/phonet/pn_netlink.c  | 10 ++++++----
 net/qrtr/qrtr.c          |  5 +++--
 net/sched/act_api.c      |  5 +++--
 net/sched/cls_api.c      |  5 +++--
 net/sched/sch_api.c      | 15 +++++++++------
 26 files changed, 162 insertions(+), 99 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index eb5493e83556..a84dcad2ee91 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1282,11 +1282,11 @@ static int vrf_fib_rule(const struct net_device *dev, __u8 family, bool add_it)
 	/* fib_nl_{new,del}rule handling looks for net from skb->sk */
 	skb->sk = dev_net(dev)->rtnl;
 	if (add_it) {
-		err = fib_nl_newrule(skb, nlh);
+		err = fib_nl_newrule(skb, nlh, NULL);
 		if (err == -EEXIST)
 			err = 0;
 	} else {
-		err = fib_nl_delrule(skb, nlh);
+		err = fib_nl_delrule(skb, nlh, NULL);
 		if (err == -ENOENT)
 			err = 0;
 	}
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 1243b9c7694e..76c7300626d6 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -143,6 +143,8 @@ int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table,
 			 u32 flags);
 bool fib_rule_matchall(const struct fib_rule *rule);
 
-int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh);
-int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh);
+int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
+		   struct netlink_ext_ack *extack);
+int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
+		   struct netlink_ext_ack *extack);
 #endif
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index c07b941fce89..78fa5fe32947 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -4,7 +4,8 @@
 #include <linux/rtnetlink.h>
 #include <net/netlink.h>
 
-typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *);
+typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *,
+			      struct netlink_ext_ack *);
 typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *);
 typedef u16 (*rtnl_calcit_func)(struct sk_buff *, struct nlmsghdr *);
 
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 993626a7fc3b..b0845480a3ae 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -569,7 +569,8 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
 	return ret;
 }
 
-static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh,
+		      struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct net_bridge_vlan_group *vg;
@@ -663,7 +664,8 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
 	return err;
 }
 
-static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
+		      struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct net_bridge_vlan_group *vg;
diff --git a/net/can/gw.c b/net/can/gw.c
index 3b84fb7d98aa..ad5bf5d508d3 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -809,7 +809,8 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
 	return 0;
 }
 
-static int cgw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh)
+static int cgw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh,
+			  struct netlink_ext_ack *extack)
 {
 	struct rtcanmsg *r;
 	struct cgw_job *gwj;
@@ -921,7 +922,8 @@ static void cgw_remove_all_jobs(void)
 	}
 }
 
-static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh,
+			  struct netlink_ext_ack *extack)
 {
 	struct cgw_job *gwj = NULL;
 	struct hlist_node *nx;
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index df03110ca3c8..c58c1df6f92b 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -368,7 +368,8 @@ static int rule_exists(struct fib_rules_ops *ops, struct fib_rule_hdr *frh,
 	return 0;
 }
 
-int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh)
+int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
+		   struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct fib_rule_hdr *frh = nlmsg_data(nlh);
@@ -386,7 +387,7 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh)
 		goto errout;
 	}
 
-	err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, extack);
 	if (err < 0)
 		goto errout;
 
@@ -561,7 +562,8 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh)
 }
 EXPORT_SYMBOL_GPL(fib_nl_newrule);
 
-int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh)
+int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
+		   struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct fib_rule_hdr *frh = nlmsg_data(nlh);
@@ -580,7 +582,7 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh)
 		goto errout;
 	}
 
-	err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, extack);
 	if (err < 0)
 		goto errout;
 
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 31f37b264710..58b0bcc125b5 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1590,7 +1590,8 @@ static struct neigh_table *neigh_find_table(int family)
 	return tbl;
 }
 
-static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ndmsg *ndm;
@@ -1648,7 +1649,8 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
 	return err;
 }
 
-static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
+		     struct netlink_ext_ack *extack)
 {
 	int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE;
 	struct net *net = sock_net(skb->sk);
@@ -1661,7 +1663,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh)
 	int err;
 
 	ASSERT_RTNL();
-	err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, extack);
 	if (err < 0)
 		goto out;
 
@@ -1936,7 +1938,8 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
 	[NDTPA_LOCKTIME]		= { .type = NLA_U64 },
 };
 
-static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct neigh_table *tbl;
@@ -1946,7 +1949,7 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
 	int err, tidx;
 
 	err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX,
-			  nl_neightbl_policy, NULL);
+			  nl_neightbl_policy, extack);
 	if (err < 0)
 		goto errout;
 
@@ -1984,7 +1987,7 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
 		int i, ifindex = 0;
 
 		err = nla_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS],
-				       nl_ntbl_parm_policy, NULL);
+				       nl_ntbl_parm_policy, extack);
 		if (err < 0)
 			goto errout_tbl_lock;
 
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index ec18cbc756d2..c1d8aed8e5a8 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -571,7 +571,8 @@ static const struct nla_policy rtnl_net_policy[NETNSA_MAX + 1] = {
 	[NETNSA_FD]		= { .type = NLA_U32 },
 };
 
-static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
+			  struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tb[NETNSA_MAX + 1];
@@ -579,7 +580,7 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh)
 	int nsid, err;
 
 	err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
-			  rtnl_net_policy, NULL);
+			  rtnl_net_policy, extack);
 	if (err < 0)
 		return err;
 	if (!tb[NETNSA_NSID])
@@ -644,7 +645,8 @@ static int rtnl_net_fill(struct sk_buff *skb, u32 portid, u32 seq, int flags,
 	return -EMSGSIZE;
 }
 
-static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
+			  struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tb[NETNSA_MAX + 1];
@@ -653,7 +655,7 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh)
 	int err, id;
 
 	err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
-			  rtnl_net_policy, NULL);
+			  rtnl_net_policy, extack);
 	if (err < 0)
 		return err;
 	if (tb[NETNSA_PID])
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 0ee5479528b5..088f9c8b4196 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2213,7 +2213,8 @@ static int do_setlink(const struct sk_buff *skb,
 	return err;
 }
 
-static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ifinfomsg *ifm;
@@ -2222,7 +2223,8 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh)
 	struct nlattr *tb[IFLA_MAX+1];
 	char ifname[IFNAMSIZ];
 
-	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy,
+			  extack);
 	if (err < 0)
 		goto errout;
 
@@ -2306,7 +2308,8 @@ int rtnl_delete_link(struct net_device *dev)
 }
 EXPORT_SYMBOL_GPL(rtnl_delete_link);
 
-static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct net_device *dev;
@@ -2315,7 +2318,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)
 	struct nlattr *tb[IFLA_MAX+1];
 	int err;
 
-	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack);
 	if (err < 0)
 		return err;
 
@@ -2426,7 +2429,8 @@ static int rtnl_group_changelink(const struct sk_buff *skb,
 	return 0;
 }
 
-static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	const struct rtnl_link_ops *ops;
@@ -2444,7 +2448,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
 #ifdef CONFIG_MODULES
 replay:
 #endif
-	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack);
 	if (err < 0)
 		return err;
 
@@ -2678,7 +2682,8 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
 	}
 }
 
-static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh)
+static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ifinfomsg *ifm;
@@ -2689,7 +2694,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh)
 	int err;
 	u32 ext_filter_mask = 0;
 
-	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack);
 	if (err < 0)
 		return err;
 
@@ -2960,7 +2965,8 @@ static int fdb_vid_parse(struct nlattr *vlan_attr, u16 *p_vid)
 	return 0;
 }
 
-static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ndmsg *ndm;
@@ -2970,7 +2976,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
 	u16 vid;
 	int err;
 
-	err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, extack);
 	if (err < 0)
 		return err;
 
@@ -3060,7 +3066,8 @@ int ndo_dflt_fdb_del(struct ndmsg *ndm,
 }
 EXPORT_SYMBOL(ndo_dflt_fdb_del);
 
-static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ndmsg *ndm;
@@ -3073,7 +3080,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
 	if (!netlink_capable(skb, CAP_NET_ADMIN))
 		return -EPERM;
 
-	err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, extack);
 	if (err < 0)
 		return err;
 
@@ -3503,7 +3510,8 @@ static int rtnl_bridge_notify(struct net_device *dev)
 	return err;
 }
 
-static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
+			       struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ifinfomsg *ifm;
@@ -3577,7 +3585,8 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh)
 	return err;
 }
 
-static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
+			       struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ifinfomsg *ifm;
@@ -3945,7 +3954,8 @@ static size_t if_nlmsg_stats_size(const struct net_device *dev,
 	return size;
 }
 
-static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
+			  struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct net_device *dev = NULL;
@@ -4107,7 +4117,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (doit == NULL)
 		return -EOPNOTSUPP;
 
-	return doit(skb, nlh);
+	return doit(skb, nlh, extack);
 }
 
 static void rtnetlink_rcv(struct sk_buff *skb)
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 3f5a5f710576..93106120f987 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -1696,7 +1696,8 @@ static const struct reply_func reply_funcs[DCB_CMD_MAX+1] = {
 	[DCB_CMD_CEE_GET]	= { RTM_GETDCB, dcbnl_cee_get },
 };
 
-static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
+		    struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct net_device *netdev;
@@ -1712,7 +1713,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
 		return -EPERM;
 
 	ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX,
-			  dcbnl_rtnl_policy, NULL);
+			  dcbnl_rtnl_policy, extack);
 	if (ret < 0)
 		return ret;
 
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index e65f1be44e8e..9017a9a73ab5 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -565,7 +565,8 @@ static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = {
 	[IFA_FLAGS]		= { .type = NLA_U32 },
 };
 
-static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
+			 struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tb[IFA_MAX+1];
@@ -581,7 +582,8 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	if (!net_eq(net, &init_net))
 		goto errout;
 
-	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy,
+			  extack);
 	if (err < 0)
 		goto errout;
 
@@ -609,7 +611,8 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	return err;
 }
 
-static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
+			 struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tb[IFA_MAX+1];
@@ -625,7 +628,8 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	if (!net_eq(net, &init_net))
 		return -EINVAL;
 
-	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy,
+			  extack);
 	if (err < 0)
 		return err;
 
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 34663bf8aa6d..f9058ebeb635 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -501,7 +501,8 @@ static inline u32 rtm_get_table(struct nlattr *attrs[], u8 table)
 	return table;
 }
 
-static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh,
+			       struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct dn_fib_table *tb;
@@ -516,7 +517,7 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
 		return -EINVAL;
 
 	err = nlmsg_parse(nlh, sizeof(*r), attrs, RTA_MAX, rtm_dn_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		return err;
 
@@ -527,7 +528,8 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
 	return tb->delete(tb, r, attrs, nlh, &NETLINK_CB(skb));
 }
 
-static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
+			       struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct dn_fib_table *tb;
@@ -542,7 +544,7 @@ static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
 		return -EINVAL;
 
 	err = nlmsg_parse(nlh, sizeof(*r), attrs, RTA_MAX, rtm_dn_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		return err;
 
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 2d7097bbc666..4b9518a0d248 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1640,7 +1640,8 @@ const struct nla_policy rtm_dn_policy[RTA_MAX + 1] = {
 /*
  * This is called by both endnodes and routers now.
  */
-static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
+static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+			     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
 	struct rtmsg *rtm = nlmsg_data(nlh);
@@ -1654,7 +1655,8 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
 	if (!net_eq(net, &init_net))
 		return -EINVAL;
 
-	err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_dn_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_dn_policy,
+			  extack);
 	if (err < 0)
 		return err;
 
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index f33f53791f50..df14815a3b8c 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -571,7 +571,8 @@ static int ip_mc_config(struct sock *sk, bool join, const struct in_ifaddr *ifa)
 	return ret;
 }
 
-static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
+			    struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tb[IFA_MAX+1];
@@ -583,7 +584,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	ASSERT_RTNL();
 
 	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		goto errout;
 
@@ -845,7 +846,8 @@ static struct in_ifaddr *find_matching_ifa(struct in_ifaddr *ifa)
 	return NULL;
 }
 
-static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
+			    struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct in_ifaddr *ifa;
@@ -1871,7 +1873,8 @@ static const struct nla_policy devconf_ipv4_policy[NETCONFA_MAX+1] = {
 };
 
 static int inet_netconf_get_devconf(struct sk_buff *in_skb,
-				    struct nlmsghdr *nlh)
+				    struct nlmsghdr *nlh,
+				    struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
 	struct nlattr *tb[NETCONFA_MAX+1];
@@ -1884,7 +1887,7 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb,
 	int err;
 
 	err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
-			  devconf_ipv4_policy, NULL);
+			  devconf_ipv4_policy, extack);
 	if (err < 0)
 		goto errout;
 
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 434dd2538716..5a0e456b5d58 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -710,7 +710,8 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
 	return err;
 }
 
-static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh,
+			     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct fib_config cfg;
@@ -732,7 +733,8 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
 	return err;
 }
 
-static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
+			     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct fib_config cfg;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index d7be21f2174a..95ea3585a223 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2430,7 +2430,8 @@ static int ipmr_nla_get_ttls(const struct nlattr *nla, struct mfcctl *mfcc)
 /* returns < 0 on error, 0 for ADD_MFC and 1 for ADD_MFC_PROXY */
 static int rtm_to_ipmr_mfcc(struct net *net, struct nlmsghdr *nlh,
 			    struct mfcctl *mfcc, int *mrtsock,
-			    struct mr_table **mrtret)
+			    struct mr_table **mrtret,
+			    struct netlink_ext_ack *extack)
 {
 	struct net_device *dev = NULL;
 	u32 tblid = RT_TABLE_DEFAULT;
@@ -2440,7 +2441,7 @@ static int rtm_to_ipmr_mfcc(struct net *net, struct nlmsghdr *nlh,
 	int ret, rem;
 
 	ret = nlmsg_validate(nlh, sizeof(*rtm), RTA_MAX, rtm_ipmr_policy,
-			     NULL);
+			     extack);
 	if (ret < 0)
 		goto out;
 	rtm = nlmsg_data(nlh);
@@ -2499,7 +2500,8 @@ static int rtm_to_ipmr_mfcc(struct net *net, struct nlmsghdr *nlh,
 }
 
 /* takes care of both newroute and delroute */
-static int ipmr_rtm_route(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int ipmr_rtm_route(struct sk_buff *skb, struct nlmsghdr *nlh,
+			  struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	int ret, mrtsock, parent;
@@ -2508,7 +2510,7 @@ static int ipmr_rtm_route(struct sk_buff *skb, struct nlmsghdr *nlh)
 
 	mrtsock = 0;
 	tbl = NULL;
-	ret = rtm_to_ipmr_mfcc(net, nlh, &mfcc, &mrtsock, &tbl);
+	ret = rtm_to_ipmr_mfcc(net, nlh, &mfcc, &mrtsock, &tbl, extack);
 	if (ret < 0)
 		return ret;
 
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 7a4f2c38c3c4..a4443748cc1e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2629,7 +2629,8 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
 	return -EMSGSIZE;
 }
 
-static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
+static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+			     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
 	struct rtmsg *rtm;
@@ -2646,7 +2647,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
 	kuid_t uid;
 
 	err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		goto errout;
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d6da0fe5acca..1b34d66b9bf5 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -611,7 +611,8 @@ static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
 };
 
 static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
-				     struct nlmsghdr *nlh)
+				     struct nlmsghdr *nlh,
+				     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
 	struct nlattr *tb[NETCONFA_MAX+1];
@@ -624,7 +625,7 @@ static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
 	int err;
 
 	err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
-			  devconf_ipv6_policy, NULL);
+			  devconf_ipv6_policy, extack);
 	if (err < 0)
 		goto errout;
 
@@ -4402,7 +4403,8 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
 };
 
 static int
-inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
+inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
+		  struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ifaddrmsg *ifm;
@@ -4412,7 +4414,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	int err;
 
 	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		return err;
 
@@ -4512,7 +4514,8 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
 }
 
 static int
-inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
+inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
+		  struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ifaddrmsg *ifm;
@@ -4525,7 +4528,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 	int err;
 
 	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		return err;
 
@@ -4875,7 +4878,8 @@ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
 	return inet6_dump_addr(skb, cb, type);
 }
 
-static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh)
+static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+			     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
 	struct ifaddrmsg *ifm;
@@ -4887,7 +4891,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh)
 	int err;
 
 	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		goto errout;
 
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 6cb4ed91722a..07cd7d248bb6 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -404,7 +404,8 @@ static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
 	[IFAL_LABEL]		= { .len = sizeof(u32), },
 };
 
-static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
+			     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct ifaddrlblmsg *ifal;
@@ -413,7 +414,8 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh)
 	u32 label;
 	int err = 0;
 
-	err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy,
+			  extack);
 	if (err < 0)
 		return err;
 
@@ -521,7 +523,8 @@ static inline int ip6addrlbl_msgsize(void)
 		+ nla_total_size(4);	/* IFAL_LABEL */
 }
 
-static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh)
+static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+			  struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
 	struct ifaddrlblmsg *ifal;
@@ -532,7 +535,8 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh)
 	struct ip6addrlbl_entry *p;
 	struct sk_buff *skb;
 
-	err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy, NULL);
+	err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy,
+			  extack);
 	if (err < 0)
 		return err;
 
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ccde23eba702..4ba7c49872ff 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3260,7 +3260,8 @@ static int ip6_route_multipath_del(struct fib6_config *cfg)
 	return last_err;
 }
 
-static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh,
+			      struct netlink_ext_ack *extack)
 {
 	struct fib6_config cfg;
 	int err;
@@ -3277,7 +3278,8 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
 	}
 }
 
-static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
+			      struct netlink_ext_ack *extack)
 {
 	struct fib6_config cfg;
 	int err;
@@ -3565,7 +3567,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
 		     NLM_F_MULTI);
 }
 
-static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
+static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+			      struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
 	struct nlattr *tb[RTA_MAX+1];
@@ -3576,7 +3579,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)
 	int err, iif = 0, oif = 0;
 
 	err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		goto errout;
 
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 07181d2273e1..088e2b459d0f 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1110,7 +1110,8 @@ static const struct nla_policy devconf_mpls_policy[NETCONFA_MAX + 1] = {
 };
 
 static int mpls_netconf_get_devconf(struct sk_buff *in_skb,
-				    struct nlmsghdr *nlh)
+				    struct nlmsghdr *nlh,
+				    struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
 	struct nlattr *tb[NETCONFA_MAX + 1];
@@ -1746,7 +1747,8 @@ static int rtm_to_route_config(struct sk_buff *skb,  struct nlmsghdr *nlh,
 	return err;
 }
 
-static int mpls_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int mpls_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh,
+			     struct netlink_ext_ack *extack)
 {
 	struct mpls_route_config *cfg;
 	int err;
@@ -1767,7 +1769,8 @@ static int mpls_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
 }
 
 
-static int mpls_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int mpls_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
+			     struct netlink_ext_ack *extack)
 {
 	struct mpls_route_config *cfg;
 	int err;
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index 363799bf97f6..45b3af3080d8 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -61,7 +61,8 @@ static const struct nla_policy ifa_phonet_policy[IFA_MAX+1] = {
 	[IFA_LOCAL] = { .type = NLA_U8 },
 };
 
-static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
+		     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tb[IFA_MAX+1];
@@ -79,7 +80,7 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
 	ASSERT_RTNL();
 
 	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_phonet_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		return err;
 
@@ -227,7 +228,8 @@ static const struct nla_policy rtm_phonet_policy[RTA_MAX+1] = {
 	[RTA_OIF] = { .type = NLA_U32 },
 };
 
-static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
+		      struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tb[RTA_MAX+1];
@@ -245,7 +247,7 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
 	ASSERT_RTNL();
 
 	err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_phonet_policy,
-			  NULL);
+			  extack);
 	if (err < 0)
 		return err;
 
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 7fdbb34002f5..c36b0ec364a4 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -943,7 +943,8 @@ static const struct nla_policy qrtr_policy[IFA_MAX + 1] = {
 	[IFA_LOCAL] = { .type = NLA_U32 },
 };
 
-static int qrtr_addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int qrtr_addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
+			  struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[IFA_MAX + 1];
 	struct ifaddrmsg *ifm;
@@ -957,7 +958,7 @@ static int qrtr_addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh)
 
 	ASSERT_RTNL();
 
-	rc = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, qrtr_policy, NULL);
+	rc = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, qrtr_policy, extack);
 	if (rc < 0)
 		return rc;
 
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 79d875c6e8a0..82b1d48d91cc 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -993,7 +993,8 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
 	return tcf_add_notify(net, n, &actions, portid);
 }
 
-static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n)
+static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
+			 struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tca[TCA_ACT_MAX + 1];
@@ -1005,7 +1006,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n)
 		return -EPERM;
 
 	ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL,
-			  NULL);
+			  extack);
 	if (ret < 0)
 		return ret;
 
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index e2c68c30f97d..a8da383b681a 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -201,7 +201,8 @@ EXPORT_SYMBOL(tcf_destroy_chain);
 
 /* Add/change/delete/get a filter node */
 
-static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
+static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
+			  struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tca[TCA_MAX + 1];
@@ -229,7 +230,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
 replay:
 	tp_created = 0;
 
-	err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL, NULL);
+	err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL, extack);
 	if (err < 0)
 		return err;
 
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index fcb5ae581c04..2fa163a095cf 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1116,7 +1116,8 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w)
  * Delete/get qdisc.
  */
 
-static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
+static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
+			struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct tcmsg *tcm = nlmsg_data(n);
@@ -1131,7 +1132,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
 	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
 		return -EPERM;
 
-	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL, NULL);
+	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL, extack);
 	if (err < 0)
 		return err;
 
@@ -1185,7 +1186,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
  * Create/change qdisc.
  */
 
-static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
+static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
+			   struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct tcmsg *tcm;
@@ -1200,7 +1202,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
 
 replay:
 	/* Reinit, just in case something touches this. */
-	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL, NULL);
+	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL, extack);
 	if (err < 0)
 		return err;
 
@@ -1558,7 +1560,8 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
 
 
 
-static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n)
+static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
+			 struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(skb->sk);
 	struct tcmsg *tcm = nlmsg_data(n);
@@ -1577,7 +1580,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n)
 	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
 		return -EPERM;
 
-	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL, NULL);
+	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL, extack);
 	if (err < 0)
 		return err;
 
-- 
2.1.4

^ permalink raw reply related

* Re: second wave of netlink extended ACK reporting
From: David Ahern @ 2017-04-16 16:55 UTC (permalink / raw)
  To: Jamal Hadi Salim, Johannes Berg,
	nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w, Jiri Pirko, Pravin Shelar,
	dev-yBygre7rU0TnMu66kgdUjQ
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA, Jiri Benc,
	pablo-Cap9r6Oaw4JrovVCs/uTlw
In-Reply-To: <826de765-dd18-f6a3-8e37-7b55398ad99b-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>

On 4/16/17 8:40 AM, Jamal Hadi Salim wrote:
> 
> Johannes or anybody else working on it?
> i.e one which sends the extack to the bowels of callees
> so we can return meaningful messages
> example: rtnetlink::doit() or equivalent seems to be a candidate for
> taking it as a param
> For things that call netlink_ack it may be easier if they create
> the extack.
> For dumps it makes it tricky since their lifetime is much
> longer..


I have a start to a patch for iproute2 as well. It needs some
improvements before I can send it. Should be able to get to it Monday or
Tuesday.

^ permalink raw reply

* Re: [PATCH iproute2 v2] ip vrf: Add command name next to pid
From: Stephen Hemminger @ 2017-04-16 17:07 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev
In-Reply-To: <1492211396-18494-1-git-send-email-dsa@cumulusnetworks.com>

On Fri, 14 Apr 2017 16:09:56 -0700
David Ahern <dsa@cumulusnetworks.com> wrote:

> 'ip vrf pids' is used to list processes bound to a vrf, but it only
> shows the pid leaving a lot of work for the user. Add the command
> name to the output. With this patch you get the more user friendly:
> 
>     $ ip vrf pids mgmt
>      1121  ntpd
>      1418  gdm-session-wor
>      1488  gnome-session
>      1491  dbus-launch
>      1492  dbus-daemon
>      1565  sshd
>      ...
> 
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>

Looks good, applied.

^ permalink raw reply

* Re: [PATCH net-next v2 4/6] vxlan: check valid combinations of address scopes
From: Roopa Prabhu @ 2017-04-16 17:15 UTC (permalink / raw)
  To: Matthias Schiffer
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
	jbenc-H+wXaHxf7aLQT0dZR+AlfA, Stephen Hemminger,
	aduyck-nYU0QVwCCFFWk0Htik3J/w, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <d401b6c7-357a-1e1c-13bd-64e9af951971-Nyw9WiXk/RKXhJHkyCwd5uTW4wlIGRCZ@public.gmane.org>

On 4/16/17, 8:03 AM, Matthias Schiffer wrote:
> On 04/14/2017 07:36 PM, Stephen Hemminger wrote:
>> On Fri, 14 Apr 2017 18:44:44 +0200
>> Matthias Schiffer <mschiffer-Nyw9WiXk/RKXhJHkyCwd5uTW4wlIGRCZ@public.gmane.org> wrote:
>>
>>> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
>>> index 07f89b037681..95a71546e8f2 100644
>>> --- a/drivers/net/vxlan.c
>>> +++ b/drivers/net/vxlan.c
>>> @@ -2881,11 +2881,39 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
>>>  	if (conf->saddr.sa.sa_family != conf->remote_ip.sa.sa_family)
>>>  		return -EINVAL;
>>>  
>>> +	if (vxlan_addr_multicast(&conf->saddr))
>>> +		return -EINVAL;
>>> +
>>>  	if (conf->saddr.sa.sa_family == AF_INET6) {
>>>  		if (!IS_ENABLED(CONFIG_IPV6))
>>>  			return -EPFNOSUPPORT;
>>>  		use_ipv6 = true;
>>>  		conf->flags |= VXLAN_F_IPV6;
>>> +
>>> +		if (!(conf->flags & VXLAN_F_COLLECT_METADATA)) {
>>> +			int local_type =
>>> +				ipv6_addr_type(&conf->saddr.sin6.sin6_addr);
>>> +			int remote_type =
>>> +				ipv6_addr_type(&conf->remote_ip.sin6.sin6_addr);
>>> +
>>> +			if (local_type & IPV6_ADDR_LINKLOCAL) {
>>> +				if (!(remote_type & IPV6_ADDR_LINKLOCAL) &&
>>> +				    (remote_type != IPV6_ADDR_ANY)) {
>>> +					pr_info("invalid combination of address scopes\n");
>> It is always helpful to include device if possible in error message.
>> 					netdev_notice(old->dev, " invalid combination of address scopes\n");
> That makes sense, I'll change it in v3.

I think it should just return -EINVAL here since this is in response to a netlink call from user-space.
I dont think we should print anything but like stephen says use the extended ack mechanism to propagate more information
about the error.


>
>> Also vxlan is good candidate for extended netlink error reporting.
> Can you point me to a piece of code that does this? Unless you insist, I
> wouldn't do it in this patchset, but I might implement the extended error
> reporting later.
>
For rtnetlink users (vxlan is one of them) this is still in the works... see patch "net: rtnetlink: plumb extended ack to doit function"

^ permalink raw reply

* Re: [PATCH iproute2 net-next v2 1/3] ip: add ip sr command to control SR-IPv6 internal structures
From: Stephen Hemminger @ 2017-04-16 17:22 UTC (permalink / raw)
  To: David Lebrun; +Cc: netdev
In-Reply-To: <20170415101717.18730-2-david.lebrun@uclouvain.be>

Overall, this looks fine and applied.
I had to add seg6.h to include/linux since it was not there.

> +		switch (alg_id) {
> +		case SEG6_HMAC_ALGO_SHA1:
> +			algstr = "sha1";
> +			break;
> +		case SEG6_HMAC_ALGO_SHA256:
> +			algstr = "sha256";
> +			break;
> +		default:
> +			algstr = "<unknown>";
> +		}

You might want to consider having a table of HMAC algorithms so that get and set match. 
It seems likely that new  values will come.

^ permalink raw reply

* Re: 4.10.9 nok with realtek wlan, atom
From: rupert THURNER @ 2017-04-16 18:09 UTC (permalink / raw)
  To: Larry Finger
  Cc: Bjorn Helgaas, linux-pci, Chaoming Li, Kalle Valo, linux-wireless,
	netdev, linux-kernel
In-Reply-To: <40bc6004-519c-7bf1-874b-3ae169140637@lwfinger.net>

On Sun, Apr 16, 2017 at 6:02 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote:
> On 04/16/2017 05:23 AM, rupert THURNER wrote:
>>
>> On Sat, Apr 15, 2017 at 10:40 PM, Larry Finger
>> <Larry.Finger@lwfinger.net> wrote:
>>>
>>> On 04/14/2017 03:26 PM, rupert THURNER wrote:
>>>>
>>>>
>>>> On Thu, Feb 9, 2017 at 9:09 PM, Larry Finger <Larry.Finger@lwfinger.net>
>>>> wrote:
>>>>>
>>>>>
>>>>> On 02/09/2017 01:43 PM, Bjorn Helgaas wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> [+cc rtl8192ce folks in case they've seen this]
>>>>>>
>>>>>> On Thu, Feb 09, 2017 at 03:45:01PM +0100, rupert THURNER wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> hi,
>>>>>>>
>>>>>>> not technical expert enough, i just wanted to give a short user
>>>>>>> feedback. for realtek wlan on atom, kernels up to 4.9.5 are ok, and
>>>>>>> kernel 4.10.0-rc7-g926af6273fc6 (arch linux-git version numbering) as
>>>>>>> well. kernels 4.9.6, 4.9.7, and 4.9.8 fail, i.e. connection to a WLAN
>>>>>>> hotspot is possible then drops, or connecting to wlan fails
>>>>>>> alltogether.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks very much for your report, and sorry for the inconvenience.
>>>>>>
>>>>>> v4.10-rc7 works, so I guess we don't need to worry about fixing v4.10.
>>>>>>
>>>>>> But the stable kernels v4.9.6, v4.9.7, and v4.9.8 are broken, so we
>>>>>> need to figure out why and make sure we fix the v4.9 stable series.
>>>>>>
>>>>>> I can't tell yet whether this is PCI-related or not.  If it is,
>>>>>> 4922a6a5cfa7 ("PCI: Enumerate switches below PCI-to-PCIe bridges")
>>>>>> appeared in v4.9.6, and there is a known issue with that.  The issue
>>>>>> should be fixed by 610c2b7ff8f6 ("PCI/ASPM: Handle PCI-to-PCIe bridges
>>>>>> as roots of PCIe hierarchies"), which appeared in v4.9.9, so I guess
>>>>>> the first thing to do would be to test v4.9.9.
>>>>>>
>>>>>> If it's not fixed in v4.9.9, can you share the complete dmesg log
>>>>>> (output of "dmesg" command) and "lspci -vv" output for v4.9.5 (last
>>>>>> known working version) and v4.9.6 (first known broken version)?  On
>>>>>> v4.9.6, collect the dmesg output after the failure occurs.
>>>>>>
>>>>>>> 24: PCI 300.0: 0282 WLAN controller
>>>>>>>   [Created at pci.366]
>>>>>>>   Model: "Realtek RTL8188CE 802.11b/g/n WiFi Adapter"
>>>>>>>   Device: pci 0x8176 "RTL8188CE 802.11b/g/n WiFi Adapter"
>>>>>>>   Revision: 0x01
>>>>>>>   Driver: "rtl8192ce"
>>>>>>>   Driver Modules: "rtl8192ce"
>>>>>>>   Device File: wlp3s0
>>>>>>>   Features: WLAN
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> It would be helpful if someone were to bisect this issue. The only
>>>>> issue
>>>>> that comes to mind was fixed in commit 52f5631a4c05 ("rtlwifi:
>>>>> rtl8192ce:
>>>>> Fix loading of incorrect firmware") which is in 4.10-rc7 and will be
>>>>> backported to 4.9.
>>>>>
>>>>> The above issue is one that could not be reproduced on my hardware,
>>>>> thus
>>>>> it
>>>>> took Jurij Smakov to find the fix. Without his bisection of the
>>>>> problem,
>>>>> who
>>>>> knows how long it would have taken to find my edit mistake.
>>>>
>>>>
>>>>
>>>> larry, using the newest kernel 4.10.8 the network connection dropps
>>>> again irregular.
>>>>
>>>> # dmesg
>>>> [    0.000000] Linux version 4.10.9-1-ARCH (builduser@tobias) (gcc
>>>> version 6.3.1 20170306 (GCC) ) #1 SMP PREEMPT Sat Apr 8 12:39:59 CEST
>>>> 2017
>>>> [   11.933373] rtl8192ce: rtl8192ce: Power Save off (module option)
>>>> [   11.933396] rtl8192ce: Using firmware rtlwifi/rtl8192cfw.bin
>>>> [   11.978307] ieee80211 phy0: Selected rate control algorithm 'rtl_rc'
>>>> [   11.978945] rtlwifi: rtlwifi: wireless switch is on
>>>>
>>>> # lspci -vv
>>>> Subsystem: Realtek Semiconductor Co., Ltd. RTL8188CE 802.11b/g/n WiFi
>>>> Adapter
>>>> Kernel driver in use: rtl8192ce
>>>
>>>
>>>
>>> Is firmware rtlwifi/rtl8192cfw.bin also used on kernels that work?
>>
>>
>> 4.10.x used to work. 4.10.6 or 4.10.7 it started failing? i am not too
>> sure about it.
>>
>> # ls -l /usr/lib/firmware/rtlwifi/rtl8192cfw.bin
>> -rw-r--r-- 1 root root 16192 Mar 10 12:15
>> /usr/lib/firmware/rtlwifi/rtl8192cfw.bin
>
>
> That does not answer my question.
4.10, 4.10.2, 4.10.3, 4.10.5 worked. as far as i can tell
rtl8192cfw.bin did not change and was used. with kernels 4.9 there was
a phase where rtl8192cfwU.bin was loaded which did not work. or i do
not understand your question correctly?

^ permalink raw reply

* (unknown), 
From: cbordinaro @ 2017-04-16 18:50 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: EMAIL_165222_netdev.zip --]
[-- Type: application/zip, Size: 1999 bytes --]

^ permalink raw reply

* [PATCH net-next v2] bonding: deliver link-local packets with skb->dev set to link that packets arrived on
From: Chonggang Li @ 2017-04-16 19:02 UTC (permalink / raw)
  To: j.vosburgh, andy, vfalico, nikolay, edumazet, davem
  Cc: netdev, Chonggang Li, Mahesh Bandewar, Maciej Żenczykowski

Bonding driver changes the skb->dev to the bonding-master before
passing the packet to stack for further processing. This, however
does not make sense for the link-local packets and it looses "the
link info" once its skb->dev is changed to bonding-master.  This
patch changes this behavior for link-local packets by not changing
the skb->dev to the bonding-master and maintaining it as it is,
i.e. the link on which the packet arrived.

Signed-off-by: Chonggang Li <chonggangli@google.com>
Signed-off-by: Mahesh Bandewar <maheshb@google.com>
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
Changes in v2:
  - Make the commit message more clearer.

 drivers/net/bonding/bond_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 01e4a69af421..6bd3b50faf48 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1176,6 +1176,9 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
 		}
 	}
 
+	/* don't change skb->dev for link-local packets */
+	if (is_link_local_ether_addr(eth_hdr(skb)->h_dest))
+		return RX_HANDLER_PASS;
 	if (bond_should_deliver_exact_match(skb, slave, bond))
 		return RX_HANDLER_EXACT;
 
-- 
2.12.2.762.g0e3151a226-goog

^ permalink raw reply related

* Re: 4.10.9 nok with realtek wlan, atom
From: Larry Finger @ 2017-04-16 19:30 UTC (permalink / raw)
  To: rupert THURNER
  Cc: Bjorn Helgaas, linux-pci-u79uwXL29TY76Z2rM5mHXA, Chaoming Li,
	Kalle Valo, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAJs9aZ_QRgqAjt+6FV=ZkPvYvkDedwtegMKC4Dk-uT8KtrE-mA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On 04/16/2017 01:09 PM, rupert THURNER wrote:
> On Sun, Apr 16, 2017 at 6:02 PM, Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org> wrote:
>> On 04/16/2017 05:23 AM, rupert THURNER wrote:
>>>
>>> On Sat, Apr 15, 2017 at 10:40 PM, Larry Finger
>>> <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org> wrote:
>>>>
>>>> On 04/14/2017 03:26 PM, rupert THURNER wrote:
>>>>>
>>>>>
>>>>> On Thu, Feb 9, 2017 at 9:09 PM, Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>> On 02/09/2017 01:43 PM, Bjorn Helgaas wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> [+cc rtl8192ce folks in case they've seen this]
>>>>>>>
>>>>>>> On Thu, Feb 09, 2017 at 03:45:01PM +0100, rupert THURNER wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> hi,
>>>>>>>>
>>>>>>>> not technical expert enough, i just wanted to give a short user
>>>>>>>> feedback. for realtek wlan on atom, kernels up to 4.9.5 are ok, and
>>>>>>>> kernel 4.10.0-rc7-g926af6273fc6 (arch linux-git version numbering) as
>>>>>>>> well. kernels 4.9.6, 4.9.7, and 4.9.8 fail, i.e. connection to a WLAN
>>>>>>>> hotspot is possible then drops, or connecting to wlan fails
>>>>>>>> alltogether.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Thanks very much for your report, and sorry for the inconvenience.
>>>>>>>
>>>>>>> v4.10-rc7 works, so I guess we don't need to worry about fixing v4.10.
>>>>>>>
>>>>>>> But the stable kernels v4.9.6, v4.9.7, and v4.9.8 are broken, so we
>>>>>>> need to figure out why and make sure we fix the v4.9 stable series.
>>>>>>>
>>>>>>> I can't tell yet whether this is PCI-related or not.  If it is,
>>>>>>> 4922a6a5cfa7 ("PCI: Enumerate switches below PCI-to-PCIe bridges")
>>>>>>> appeared in v4.9.6, and there is a known issue with that.  The issue
>>>>>>> should be fixed by 610c2b7ff8f6 ("PCI/ASPM: Handle PCI-to-PCIe bridges
>>>>>>> as roots of PCIe hierarchies"), which appeared in v4.9.9, so I guess
>>>>>>> the first thing to do would be to test v4.9.9.
>>>>>>>
>>>>>>> If it's not fixed in v4.9.9, can you share the complete dmesg log
>>>>>>> (output of "dmesg" command) and "lspci -vv" output for v4.9.5 (last
>>>>>>> known working version) and v4.9.6 (first known broken version)?  On
>>>>>>> v4.9.6, collect the dmesg output after the failure occurs.
>>>>>>>
>>>>>>>> 24: PCI 300.0: 0282 WLAN controller
>>>>>>>>   [Created at pci.366]
>>>>>>>>   Model: "Realtek RTL8188CE 802.11b/g/n WiFi Adapter"
>>>>>>>>   Device: pci 0x8176 "RTL8188CE 802.11b/g/n WiFi Adapter"
>>>>>>>>   Revision: 0x01
>>>>>>>>   Driver: "rtl8192ce"
>>>>>>>>   Driver Modules: "rtl8192ce"
>>>>>>>>   Device File: wlp3s0
>>>>>>>>   Features: WLAN
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> It would be helpful if someone were to bisect this issue. The only
>>>>>> issue
>>>>>> that comes to mind was fixed in commit 52f5631a4c05 ("rtlwifi:
>>>>>> rtl8192ce:
>>>>>> Fix loading of incorrect firmware") which is in 4.10-rc7 and will be
>>>>>> backported to 4.9.
>>>>>>
>>>>>> The above issue is one that could not be reproduced on my hardware,
>>>>>> thus
>>>>>> it
>>>>>> took Jurij Smakov to find the fix. Without his bisection of the
>>>>>> problem,
>>>>>> who
>>>>>> knows how long it would have taken to find my edit mistake.
>>>>>
>>>>>
>>>>>
>>>>> larry, using the newest kernel 4.10.8 the network connection dropps
>>>>> again irregular.
>>>>>
>>>>> # dmesg
>>>>> [    0.000000] Linux version 4.10.9-1-ARCH (builduser@tobias) (gcc
>>>>> version 6.3.1 20170306 (GCC) ) #1 SMP PREEMPT Sat Apr 8 12:39:59 CEST
>>>>> 2017
>>>>> [   11.933373] rtl8192ce: rtl8192ce: Power Save off (module option)
>>>>> [   11.933396] rtl8192ce: Using firmware rtlwifi/rtl8192cfw.bin
>>>>> [   11.978307] ieee80211 phy0: Selected rate control algorithm 'rtl_rc'
>>>>> [   11.978945] rtlwifi: rtlwifi: wireless switch is on
>>>>>
>>>>> # lspci -vv
>>>>> Subsystem: Realtek Semiconductor Co., Ltd. RTL8188CE 802.11b/g/n WiFi
>>>>> Adapter
>>>>> Kernel driver in use: rtl8192ce
>>>>
>>>>
>>>>
>>>> Is firmware rtlwifi/rtl8192cfw.bin also used on kernels that work?
>>>
>>>
>>> 4.10.x used to work. 4.10.6 or 4.10.7 it started failing? i am not too
>>> sure about it.
>>>
>>> # ls -l /usr/lib/firmware/rtlwifi/rtl8192cfw.bin
>>> -rw-r--r-- 1 root root 16192 Mar 10 12:15
>>> /usr/lib/firmware/rtlwifi/rtl8192cfw.bin
>>
>>
>> That does not answer my question.
> 4.10, 4.10.2, 4.10.3, 4.10.5 worked. as far as i can tell
> rtl8192cfw.bin did not change and was used. with kernels 4.9 there was
> a phase where rtl8192cfwU.bin was loaded which did not work. or i do
> not understand your question correctly?

I think you mean that rtl8192cfw.bin was the firmware used for both a good and a 
bad kernel.

My problem is that there are at least 6 varieties of chips that use the 
rtl8192ce driver. I do not have all of them, but so far it is impossible for me 
to tell if yours is the same as one of mine. If you post the output of 'lspci 
-nn', then I might be able to answer that question.

A second problem is that there are no fixes in any 4.10.x kernel where x >= 1 
that can cause a problem in rtl8192ce, thus it is hard to know how 4.10.5 can 
work and 4.10.6 or 7 can fail! That is the reason that a bisection would be useful.

At this point, and with the information you have provided, I'm not sure if the 
problem is even in rtl8192ce, or how I can help.

Larry

^ permalink raw reply

* [PATCH] sh_eth: unmap DMA buffers when freeing rings
From: Sergei Shtylyov @ 2017-04-16 20:01 UTC (permalink / raw)
  To: netdev; +Cc: linux-renesas-soc, Sergei Shtylyov

[-- Attachment #1: sh_eth-unmap-DMA-buffers-when-freeing-rings.patch --]
[-- Type: text/plain, Size: 6255 bytes --]

The DMA API debugging (when enabled) causes:

WARNING: CPU: 0 PID: 1445 at lib/dma-debug.c:519 add_dma_entry+0xe0/0x12c
DMA-API: exceeded 7 overlapping mappings of cacheline 0x01b2974d

to be  printed after repeated initialization of the Ether device, e.g.
suspend/resume or 'ifconfig' up/down. This is because DMA buffers mapped
using dma_map_single() in sh_eth_ring_format() and sh_eth_start_xmit() are
never unmapped. Resolve this problem by unmapping the buffers when freeing
the descriptor  rings;  in order  to do it right, we'd have to add an extra
parameter to sh_eth_txfree() (we rename this function to sh_eth_tx_free(),
while at it).

Based on the commit a47b70ea86bd ("ravb: unmap descriptors when freeing
rings").

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
 drivers/net/ethernet/renesas/sh_eth.c |  122 ++++++++++++++++++----------------
 1 file changed, 67 insertions(+), 55 deletions(-)

Index: net/drivers/net/ethernet/renesas/sh_eth.c
===================================================================
--- net.orig/drivers/net/ethernet/renesas/sh_eth.c
+++ net/drivers/net/ethernet/renesas/sh_eth.c
@@ -1127,12 +1127,70 @@ static struct mdiobb_ops bb_ops = {
 	.get_mdio_data = sh_get_mdio,
 };
 
+/* free Tx skb function */
+static int sh_eth_tx_free(struct net_device *ndev, bool sent_only)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	struct sh_eth_txdesc *txdesc;
+	int free_num = 0;
+	int entry;
+	bool sent;
+
+	for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
+		entry = mdp->dirty_tx % mdp->num_tx_ring;
+		txdesc = &mdp->tx_ring[entry];
+		sent = txdesc->status & cpu_to_le32(TD_TACT);
+		if (sent_only && !sent)
+			break;
+		/* TACT bit must be checked before all the following reads */
+		dma_rmb();
+		netif_info(mdp, tx_done, ndev,
+			   "tx entry %d status 0x%08x\n",
+			   entry, le32_to_cpu(txdesc->status));
+		/* Free the original skb. */
+		if (mdp->tx_skbuff[entry]) {
+			dma_unmap_single(&ndev->dev, le32_to_cpu(txdesc->addr),
+					 le32_to_cpu(txdesc->len) >> 16,
+					 DMA_TO_DEVICE);
+			dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
+			mdp->tx_skbuff[entry] = NULL;
+			free_num++;
+		}
+		txdesc->status = cpu_to_le32(TD_TFP);
+		if (entry >= mdp->num_tx_ring - 1)
+			txdesc->status |= cpu_to_le32(TD_TDLE);
+
+		if (sent) {
+			ndev->stats.tx_packets++;
+			ndev->stats.tx_bytes += le32_to_cpu(txdesc->len) >> 16;
+		}
+	}
+	return free_num;
+}
+
 /* free skb and descriptor buffer */
 static void sh_eth_ring_free(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	int ringsize, i;
 
+	if (mdp->rx_ring) {
+		for (i = 0; i < mdp->num_rx_ring; i++) {
+			if (mdp->rx_skbuff[i]) {
+				struct sh_eth_rxdesc *rxdesc = &mdp->rx_ring[i];
+
+				dma_unmap_single(&ndev->dev,
+						 le32_to_cpu(rxdesc->addr),
+						 ALIGN(mdp->rx_buf_sz, 32),
+						 DMA_FROM_DEVICE);
+			}
+		}
+		ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
+		dma_free_coherent(NULL, ringsize, mdp->rx_ring,
+				  mdp->rx_desc_dma);
+		mdp->rx_ring = NULL;
+	}
+
 	/* Free Rx skb ringbuffer */
 	if (mdp->rx_skbuff) {
 		for (i = 0; i < mdp->num_rx_ring; i++)
@@ -1141,27 +1199,18 @@ static void sh_eth_ring_free(struct net_
 	kfree(mdp->rx_skbuff);
 	mdp->rx_skbuff = NULL;
 
-	/* Free Tx skb ringbuffer */
-	if (mdp->tx_skbuff) {
-		for (i = 0; i < mdp->num_tx_ring; i++)
-			dev_kfree_skb(mdp->tx_skbuff[i]);
-	}
-	kfree(mdp->tx_skbuff);
-	mdp->tx_skbuff = NULL;
-
-	if (mdp->rx_ring) {
-		ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
-		dma_free_coherent(NULL, ringsize, mdp->rx_ring,
-				  mdp->rx_desc_dma);
-		mdp->rx_ring = NULL;
-	}
-
 	if (mdp->tx_ring) {
+		sh_eth_tx_free(ndev, false);
+
 		ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
 		dma_free_coherent(NULL, ringsize, mdp->tx_ring,
 				  mdp->tx_desc_dma);
 		mdp->tx_ring = NULL;
 	}
+
+	/* Free Tx skb ringbuffer */
+	kfree(mdp->tx_skbuff);
+	mdp->tx_skbuff = NULL;
 }
 
 /* format skb and descriptor buffer */
@@ -1409,43 +1458,6 @@ static void sh_eth_dev_exit(struct net_d
 	update_mac_address(ndev);
 }
 
-/* free Tx skb function */
-static int sh_eth_txfree(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-	struct sh_eth_txdesc *txdesc;
-	int free_num = 0;
-	int entry;
-
-	for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
-		entry = mdp->dirty_tx % mdp->num_tx_ring;
-		txdesc = &mdp->tx_ring[entry];
-		if (txdesc->status & cpu_to_le32(TD_TACT))
-			break;
-		/* TACT bit must be checked before all the following reads */
-		dma_rmb();
-		netif_info(mdp, tx_done, ndev,
-			   "tx entry %d status 0x%08x\n",
-			   entry, le32_to_cpu(txdesc->status));
-		/* Free the original skb. */
-		if (mdp->tx_skbuff[entry]) {
-			dma_unmap_single(&ndev->dev, le32_to_cpu(txdesc->addr),
-					 le32_to_cpu(txdesc->len) >> 16,
-					 DMA_TO_DEVICE);
-			dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
-			mdp->tx_skbuff[entry] = NULL;
-			free_num++;
-		}
-		txdesc->status = cpu_to_le32(TD_TFP);
-		if (entry >= mdp->num_tx_ring - 1)
-			txdesc->status |= cpu_to_le32(TD_TDLE);
-
-		ndev->stats.tx_packets++;
-		ndev->stats.tx_bytes += le32_to_cpu(txdesc->len) >> 16;
-	}
-	return free_num;
-}
-
 /* Packet receive function */
 static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
 {
@@ -1690,7 +1702,7 @@ static void sh_eth_error(struct net_devi
 			   intr_status, mdp->cur_tx, mdp->dirty_tx,
 			   (u32)ndev->state, edtrr);
 		/* dirty buffer free */
-		sh_eth_txfree(ndev);
+		sh_eth_tx_free(ndev, true);
 
 		/* SH7712 BUG */
 		if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
@@ -1751,7 +1763,7 @@ static irqreturn_t sh_eth_interrupt(int
 		/* Clear Tx interrupts */
 		sh_eth_write(ndev, intr_status & cd->tx_check, EESR);
 
-		sh_eth_txfree(ndev);
+		sh_eth_tx_free(ndev, true);
 		netif_wake_queue(ndev);
 	}
 
@@ -2412,7 +2424,7 @@ static int sh_eth_start_xmit(struct sk_b
 
 	spin_lock_irqsave(&mdp->lock, flags);
 	if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
-		if (!sh_eth_txfree(ndev)) {
+		if (!sh_eth_tx_free(ndev, true)) {
 			netif_warn(mdp, tx_queued, ndev, "TxFD exhausted.\n");
 			netif_stop_queue(ndev);
 			spin_unlock_irqrestore(&mdp->lock, flags);

^ permalink raw reply

* Re: [PATCH v3 net-next RFC] Generic XDP
From: Jesper Dangaard Brouer @ 2017-04-16 20:26 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Jakub Kicinski, David Miller, netdev, xdp-newbies, brouer
In-Reply-To: <20170415004642.GA73685@ast-mbp.thefacebook.com>

On Fri, 14 Apr 2017 17:46:44 -0700
Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:

> But that's probably bad idea, since I was assuming that such ring
> reconfiguration can be made fast, which is unlikely.
> If it takes seconds to setup a ring, then drivers should just
> assume XDP_PACKET_HEADROOM, since at that time the program
> properties are unknown and in the future other programs will be loaded.
>
> Take a look at our current setup with slots for xdp_dump, ddos, lb
> programs. Only root program is attached at the begining.
> If the driver configures the ring for such empty program that would break
> dynamic addition of lb prog.
> The driver must not interrupt the traffic when user adds another
> prog to prog array. In such case XDP side doesn't even know that
> prog array is used. It's all happening purely on bpf side.

The bpf tail-call use-case is a very good example of why the verifier
cannot deduct the needed HEADROOM upfront.

Could we still make the verifier reject a program getting attached as a
tail-call when a too "low"/small HEADROOM have been setup? (to satisfy
programs needs)

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* Re: [PATCH net-next v6 02/11] bpf,landlock: Define an eBPF program type for Landlock
From: Mickaël Salaün @ 2017-04-16 21:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Alexei Starovoitov, Andy Lutomirski, Arnaldo Carvalho de Melo,
	Casey Schaufler, Daniel Borkmann, David Drysdale,
	David S . Miller, Eric W . Biederman, James Morris, Jann Horn,
	Jonathan Corbet, Matthew Garrett, Michael Kerrisk, Kees Cook,
	Paul Moore, Sargun Dhillon, Serge E . Hallyn, Shuah Khan,
	Tejun Heo, Thomas Graf, Will Drewry
In-Reply-To: <20170328234650.19695-3-mic@digikod.net>


[-- Attachment #1.1: Type: text/plain, Size: 6593 bytes --]


On 29/03/2017 01:46, Mickaël Salaün wrote:
> Add a new type of eBPF program used by Landlock rules.
> 
> This new BPF program type will be registered with the Landlock LSM
> initialization.
> 
> Add an initial Landlock Kconfig.
> 
> Changes since v5:
> * rename file hooks.c to init.c
> * fix spelling
> 
> Changes since v4:
> * merge a minimal (not enabled) LSM code and Kconfig in this commit
> 
> Changes since v3:
> * split commit
> * revamp the landlock_context:
>   * add arch, syscall_nr and syscall_cmd (ioctl, fcntl…) to be able to
>     cross-check action with the event type
>   * replace args array with dedicated fields to ease the addition of new
>     fields
> 
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Andy Lutomirski <luto@amacapital.net>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: James Morris <james.l.morris@oracle.com>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Serge E. Hallyn <serge@hallyn.com>
> ---
>  include/linux/landlock.h       |  23 ++++++++
>  include/uapi/linux/bpf.h       | 105 +++++++++++++++++++++++++++++++++++
>  security/Kconfig               |   1 +
>  security/Makefile              |   2 +
>  security/landlock/Kconfig      |  18 ++++++
>  security/landlock/Makefile     |   3 +
>  security/landlock/common.h     |  25 +++++++++
>  security/landlock/init.c       | 123 +++++++++++++++++++++++++++++++++++++++++
>  tools/include/uapi/linux/bpf.h | 105 +++++++++++++++++++++++++++++++++++
>  9 files changed, 405 insertions(+)
>  create mode 100644 include/linux/landlock.h
>  create mode 100644 security/landlock/Kconfig
>  create mode 100644 security/landlock/Makefile
>  create mode 100644 security/landlock/common.h
>  create mode 100644 security/landlock/init.c
>
[...]
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 0eb71ab9b4fd..619b1f8707cc 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -114,6 +114,7 @@ enum bpf_prog_type {
>  	BPF_PROG_TYPE_LWT_IN,
>  	BPF_PROG_TYPE_LWT_OUT,
>  	BPF_PROG_TYPE_LWT_XMIT,
> +	BPF_PROG_TYPE_LANDLOCK,
>  };
>  
>  enum bpf_attach_type {
> @@ -661,4 +662,108 @@ struct xdp_md {
>  	__u32 data_end;
>  };
>  
> +/**
> + * enum landlock_subtype_event - event occurring when an action is performed on
> + * a particular kernel object
> + *
> + * An event is a policy decision point which exposes the same context type
> + * (especially the same arg[0-9] field types) for each rule execution.
> + *
> + * @LANDLOCK_SUBTYPE_EVENT_UNSPEC: invalid value
> + * @LANDLOCK_SUBTYPE_EVENT_FS: generic filesystem event
> + */
> +enum landlock_subtype_event {
> +	LANDLOCK_SUBTYPE_EVENT_UNSPEC,
> +	LANDLOCK_SUBTYPE_EVENT_FS,
> +};
> +#define _LANDLOCK_SUBTYPE_EVENT_LAST LANDLOCK_SUBTYPE_EVENT_FS
[...]
> +/**
> + * DOC: landlock_action_fs
> + *
> + * - %LANDLOCK_ACTION_FS_EXEC: execute a file or walk through a directory
> + * - %LANDLOCK_ACTION_FS_WRITE: modify a file or a directory view (which
> + *   include mount actions)
> + * - %LANDLOCK_ACTION_FS_READ: read a file or a directory
> + * - %LANDLOCK_ACTION_FS_NEW: create a file or a directory
> + * - %LANDLOCK_ACTION_FS_GET: open or receive a file
> + * - %LANDLOCK_ACTION_FS_REMOVE: unlink a file or remove a directory
> + *
> + * Each of the following actions are specific to syscall multiplexers. They
> + * fill the syscall_cmd field from &struct landlock_context with their custom
> + * command.
> + *
> + * - %LANDLOCK_ACTION_FS_IOCTL: ioctl command
> + * - %LANDLOCK_ACTION_FS_LOCK: flock or fcntl lock command
> + * - %LANDLOCK_ACTION_FS_FCNTL: fcntl command
> + */
> +#define LANDLOCK_ACTION_FS_EXEC			(1ULL << 0)
> +#define LANDLOCK_ACTION_FS_WRITE		(1ULL << 1)
> +#define LANDLOCK_ACTION_FS_READ			(1ULL << 2)
> +#define LANDLOCK_ACTION_FS_NEW			(1ULL << 3)
> +#define LANDLOCK_ACTION_FS_GET			(1ULL << 4)
> +#define LANDLOCK_ACTION_FS_REMOVE		(1ULL << 5)
> +#define LANDLOCK_ACTION_FS_IOCTL		(1ULL << 6)
> +#define LANDLOCK_ACTION_FS_LOCK			(1ULL << 7)
> +#define LANDLOCK_ACTION_FS_FCNTL		(1ULL << 8)
> +#define _LANDLOCK_ACTION_FS_NB			9
> +#define _LANDLOCK_ACTION_FS_MASK		((1ULL << _LANDLOCK_ACTION_FS_NB) - 1)
> +
> +
> +/**
> + * struct landlock_context - context accessible to a Landlock rule
> + *
> + * @status: bitfield for future use (LANDLOCK_SUBTYPE_STATUS_*)
> + * @arch: indicates system call convention as an AUDIT_ARCH_* value
> + *        as defined in <linux/audit.h>
> + * @syscall_nr: the system call number called by the current process (may be
> + *              useful to debug: find out from which syscall this request came
> + *              from)
> + * @syscall_cmd: contains the command used by a multiplexer syscall (e.g.
> + *               ioctl, fcntl, flock)
> + * @event: event type (&enum landlock_subtype_event)
> + * @arg1: event's first optional argument
> + * @arg2: event's second optional argument
> + */
> +struct landlock_context {
> +	__u64 status;
> +	__u32 arch;
> +	__u32 syscall_nr;
> +	__u32 syscall_cmd;
> +	__u32 event;
> +	__u64 arg1;
> +	__u64 arg2;
> +};

I plan to simplify and make the FS event more generic for the IOCTL,
LOCK or FCNTL actions. The action flags for the
LANDLOCK_SUBTYPE_EVENT_FS event will remain the same but the syscall_cmd
field will be removed from struct landlock_context. Instead, one of
three dedicated events will be triggered in addition to one of this
three multiplexed actions.

The aim is to trigger the LANDLOCK_SUBTYPE_EVENT_FS for all file system
events (still including IOCTL/LOCK/FCNTL actions). This should avoid a
developer/user to forget such actions. However, when this kind of action
is triggered, a LANDLOCK_SUBTYPE_EVENT_FS_{IOCTL,LOCK,FCNTL} event will
follow. This enable to simplify the struct landlock_context while still
having it as generic as possible. The difference will be that the arg2
field for one of the LANDLOCK_SUBTYPE_EVENT_FS_{IOCTL,LOCK,FCNTL} events
will contain a custom IOCTL, LOCK or FCNTL command (currently in the
syscall_cmd field) instead of a LANDLOCK_ACTION_FS_* value. The same
logic could be used to tighten other actions in the future.

The HOOK_NEW_FS_CMD(...) from [04/11]:security/landlock/hooks_fs.c will
be replaced with dedicated calls.


I also plan to remove the arch and syscall_nr fields. This will make
struct landlock_context even more simple and arch-independent.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH nf-next] ipvs: remove unused function ip_vs_set_state_timeout
From: Simon Horman @ 2017-04-16 22:34 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Aaron Conole, netfilter-devel, Wensong Zhang, Julian Anastasov,
	netdev, lvs-devel, linux-kernel
In-Reply-To: <20170414001309.GA28870@salvia>

On vr, apr 14, 2017 at 02:13:09 +0200, Pablo Neira Ayuso wrote:
> On Mon, Apr 10, 2017 at 03:50:44PM -0400, Aaron Conole wrote:
> > There are no in-tree callers of this function and it isn't exported.
> 
> Simon, let me know if you want to take this, or just add your
> Signed-off-by.

Hi Pablo,

I will take this.

^ permalink raw reply

* [PATCH RFC] ptr_ring: add ptr_ring_unconsume
From: Michael S. Tsirkin @ 2017-04-16 23:19 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Jason Wang

Applications that consume a batch of entries in one go
can benefit from ability to return some of them back
into the ring.

Add an API for that - assuming there's space. If there's no space
naturally we can't do this and have to drop entries, but this implies
ring is full so we'd likely drop some anyway.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

Jason, in my mind the biggest issue with your batching patchset is the
backet drops on disconnect.  This API will help avoid that in the common
case.

I would still prefer that we understand what's going on, and I would
like to know what's the smallest batch size that's still helpful, but
I'm not going to block the patch on these grounds assuming packet drops
are fixed.

Lightly tested - this is on top of consumer batching patches.

Thanks!

 include/linux/ptr_ring.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h
index 783e7f5..5fbeab4 100644
--- a/include/linux/ptr_ring.h
+++ b/include/linux/ptr_ring.h
@@ -457,6 +457,63 @@ static inline int ptr_ring_init(struct ptr_ring *r, int size, gfp_t gfp)
 	return 0;
 }
 
+/*
+ * Return entries into ring. Destroy entries that don't fit.
+ *
+ * Note: this is expected to be a rare slow path operation.
+ *
+ * Note: producer lock is nested within consumer lock, so if you
+ * resize you must make sure all uses nest correctly.
+ * In particular if you consume ring in interrupt or BH context, you must
+ * disable interrupts/BH when doing so.
+ */
+static inline void ptr_ring_unconsume(struct ptr_ring *r, void **batch, int n,
+				      void (*destroy)(void *))
+{
+	unsigned long flags;
+	int head;
+
+	spin_lock_irqsave(&(r)->consumer_lock, flags);
+	spin_lock(&(r)->producer_lock);
+
+	if (!r->size)
+		goto done;
+
+	/* 
+	 * Clean out buffered entries (for simplicity). This way following code
+	 * can test entries for NULL and if not assume they are valid.
+	 */
+	head = r->consumer_head - 1;
+	while (likely(head >= r->consumer_tail))
+		r->queue[head--] = NULL;
+	r->consumer_tail = r->consumer_head;
+
+	/*
+	 * Go over entries in batch, start moving head back and copy entries.
+	 * Stop when we run into previously unconsumed entries.
+	 */
+	while (n--) {
+		head = r->consumer_head - 1;
+		if (head < 0)
+			head = r->size - 1;
+		if (r->queue[head]) {
+			/* This batch entry will have to be destroyed. */
+			++n;
+			goto done;
+		}
+		r->queue[head] = batch[n];
+		r->consumer_tail = r->consumer_head = head;
+	}
+
+done:
+	/* Destroy all entries left in the batch. */
+	while (n--) {
+		destroy(batch[n]);
+	}
+	spin_unlock(&(r)->producer_lock);
+	spin_unlock_irqrestore(&(r)->consumer_lock, flags);
+}
+
 static inline void **__ptr_ring_swap_queue(struct ptr_ring *r, void **queue,
 					   int size, gfp_t gfp,
 					   void (*destroy)(void *))
-- 
MST

^ permalink raw reply related

* Re: ipv6 udp early demux breaks udp_l3mdev_accept=0
From: David Ahern @ 2017-04-16 23:26 UTC (permalink / raw)
  To: Subash Abhinov Kasiviswanathan; +Cc: David Miller, netdev, rshearma
In-Reply-To: <2b582c01f3d2e265cf94bc89d0346a5b@codeaurora.org>

On 4/15/17 8:23 PM, Subash Abhinov Kasiviswanathan wrote:
>>> It should be fixed for 4.12. Basically, __udp6_lib_demux_lookup needs to
>>> be more like __udp4_lib_demux_lookup
> 
> Hi David
> 
> Would it be possible for you to test this with udp_l3mdev_accept=0

formatting was botched so it does not apply cleanly. please send a patch
file

^ permalink raw reply

* Re: ipv6 udp early demux breaks udp_l3mdev_accept=0
From: Subash Abhinov Kasiviswanathan @ 2017-04-17  0:44 UTC (permalink / raw)
  To: dsa, davem, netdev, rshearma; +Cc: Subash Abhinov Kasiviswanathan
In-Reply-To: <3639a683-2839-4363-2cd2-c2a040402c93@cumulusnetworks.com>

Can you try this

---
 net/ipv6/udp.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b793ed1..0e307e5 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -46,6 +46,7 @@
 #include <net/tcp_states.h>
 #include <net/ip6_checksum.h>
 #include <net/xfrm.h>
+#include <net/inet_hashtables.h>
 #include <net/inet6_hashtables.h>
 #include <net/busy_poll.h>
 #include <net/sock_reuseport.h>
@@ -864,21 +865,25 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	return 0;
 }
 
+
 static struct sock *__udp6_lib_demux_lookup(struct net *net,
 			__be16 loc_port, const struct in6_addr *loc_addr,
 			__be16 rmt_port, const struct in6_addr *rmt_addr,
 			int dif)
 {
+	unsigned short hnum = ntohs(loc_port);
+	unsigned int hash2 = udp6_portaddr_hash(net, loc_addr, hnum);
+	unsigned int slot2 = hash2 & udp_table.mask;
+	struct udp_hslot *hslot2 = &udp_table.hash2[slot2];
+	const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
 	struct sock *sk;
 
-	rcu_read_lock();
-	sk = __udp6_lib_lookup(net, rmt_addr, rmt_port, loc_addr, loc_port,
-			       dif, &udp_table, NULL);
-	if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
-		sk = NULL;
-	rcu_read_unlock();
-
-	return sk;
+	udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+		if (INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif))
+			return sk;
+		break;
+	}
+	return NULL;
 }
 
 static void udp_v6_early_demux(struct sk_buff *skb)
-- 
1.9.1

^ permalink raw reply related

* [PATCH net 2/2] bpf: fix checking xdp_adjust_head on tail calls
From: Daniel Borkmann @ 2017-04-17  1:12 UTC (permalink / raw)
  To: davem
  Cc: alexei.starovoitov, kubakici, netdev, Daniel Borkmann,
	Martin KaFai Lau
In-Reply-To: <cover.1492390940.git.daniel@iogearbox.net>

Commit 17bedab27231 ("bpf: xdp: Allow head adjustment in XDP prog")
added the xdp_adjust_head bit to the BPF prog in order to tell drivers
that the program that is to be attached requires support for the XDP
bpf_xdp_adjust_head() helper such that drivers not supporting this
helper can reject the program. There are also drivers that do support
the helper, but need to check for xdp_adjust_head bit in order to move
packet metadata prepended by the firmware away for making headroom.

For these cases, the current check for xdp_adjust_head bit is insufficient
since there can be cases where the program itself does not use the
bpf_xdp_adjust_head() helper, but tail calls into another program that
uses bpf_xdp_adjust_head(). As such, the xdp_adjust_head bit is still
set to 0. Since the first program has no control over which program it
calls into, we need to assume that bpf_xdp_adjust_head() helper is used
upon tail calls. Thus, for the very same reasons in cb_access, set the
xdp_adjust_head bit to 1 when the main program uses tail calls.

Fixes: 17bedab27231 ("bpf: xdp: Allow head adjustment in XDP prog")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Cc: Martin KaFai Lau <kafai@fb.com>
---
 kernel/bpf/syscall.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index ee5c969..821f9e8 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -623,6 +623,7 @@ static void fixup_bpf_calls(struct bpf_prog *prog)
 				 * in the program array.
 				 */
 				prog->cb_access = 1;
+				prog->xdp_adjust_head = 1;
 
 				/* mark bpf_tail_call as different opcode
 				 * to avoid conditional branch in
-- 
1.9.3

^ permalink raw reply related

* [PATCH net 0/2] Two BPF fixes
From: Daniel Borkmann @ 2017-04-17  1:12 UTC (permalink / raw)
  To: davem; +Cc: alexei.starovoitov, kubakici, netdev, Daniel Borkmann

The set fixes cb_access and xdp_adjust_head bits in struct bpf_prog,
that are used for requirement checks on the program rather than f.e.
heuristics. Thus, for tail calls, we cannot make any assumptions and
are forced to set them.

Thanks!

Daniel Borkmann (2):
  bpf: fix cb access in socket filter programs on tail calls
  bpf: fix checking xdp_adjust_head on tail calls

 kernel/bpf/syscall.c | 8 ++++++++
 1 file changed, 8 insertions(+)

-- 
1.9.3

^ permalink raw reply

* [PATCH net 1/2] bpf: fix cb access in socket filter programs on tail calls
From: Daniel Borkmann @ 2017-04-17  1:12 UTC (permalink / raw)
  To: davem; +Cc: alexei.starovoitov, kubakici, netdev, Daniel Borkmann
In-Reply-To: <cover.1492390940.git.daniel@iogearbox.net>

Commit ff936a04e5f2 ("bpf: fix cb access in socket filter programs")
added a fix for socket filter programs such that in i) AF_PACKET the
20 bytes of skb->cb[] area gets zeroed before use in order to not leak
data, and ii) socket filter programs attached to TCP/UDP sockets need
to save/restore these 20 bytes since they are also used by protocol
layers at that time.

The problem is that bpf_prog_run_save_cb() and bpf_prog_run_clear_cb()
only look at the actual attached program to determine whether to zero
or save/restore the skb->cb[] parts. There can be cases where the
actual attached program does not access the skb->cb[], but the program
tail calls into another program which does access this area. In such
a case, the zero or save/restore is currently not performed.

Since the programs we tail call into are unknown at verification time
and can dynamically change, we need to assume that whenever the attached
program performs a tail call, that later programs could access the
skb->cb[], and therefore we need to always set cb_access to 1.

Fixes: ff936a04e5f2 ("bpf: fix cb access in socket filter programs")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
---
 kernel/bpf/syscall.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 7af0dcc..ee5c969 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -617,6 +617,13 @@ static void fixup_bpf_calls(struct bpf_prog *prog)
 			if (insn->imm == BPF_FUNC_xdp_adjust_head)
 				prog->xdp_adjust_head = 1;
 			if (insn->imm == BPF_FUNC_tail_call) {
+				/* If we tail call into other programs, we
+				 * cannot make any assumptions since they
+				 * can be replaced dynamically during runtime
+				 * in the program array.
+				 */
+				prog->cb_access = 1;
+
 				/* mark bpf_tail_call as different opcode
 				 * to avoid conditional branch in
 				 * interpeter for every normal call
-- 
1.9.3

^ permalink raw reply related


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