Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next 1/3] devlink: Introduce PCI PF port flavour and port attribute
From: Andrew Lunn @ 2019-07-03 14:09 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Parav Pandit, Jakub Kicinski, Jiri Pirko, netdev@vger.kernel.org,
	Saeed Mahameed, vivien.didelot, f.fainelli
In-Reply-To: <20190703103720.GU2250@nanopsycho>

> However, we expose it for DEVLINK_PORT_FLAVOUR_CPU and
> DEVLINK_PORT_FLAVOUR_DSA. Not sure if it makes sense there either.
> Ccing Florian, Andrew and Vivien.
> What do you guys think?

Hi Jiri

DSA and CPU ports are physical ports of the switch. And there can be
multiple DSA ports, and maybe sometime real soon now, multiple CPU
ports. So having a number associated with them is useful.

       Andrew

^ permalink raw reply

* Re: [PATCH net-next v6 07/15] ethtool: support for netlink notifications
From: Michal Kubecek @ 2019-07-03 14:16 UTC (permalink / raw)
  To: netdev
  Cc: Jiri Pirko, David Miller, Jakub Kicinski, Andrew Lunn,
	Florian Fainelli, John Linville, Stephen Hemminger, Johannes Berg,
	linux-kernel
In-Reply-To: <20190703133352.GY2250@nanopsycho>

On Wed, Jul 03, 2019 at 03:33:52PM +0200, Jiri Pirko wrote:
> >+/* notifications */
> >+
> >+typedef void (*ethnl_notify_handler_t)(struct net_device *dev,
> >+				       struct netlink_ext_ack *extack,
> >+				       unsigned int cmd, u32 req_mask,
> >+				       const void *data);
> >+
> >+static const ethnl_notify_handler_t ethnl_notify_handlers[] = {
> >+};
> >+
> >+void ethtool_notify(struct net_device *dev, struct netlink_ext_ack *extack,
> >+		    unsigned int cmd, u32 req_mask, const void *data)
> 
> What's "req_mask" ?

It's infomask to interpret the same way as if it came from request
header (the notification triggered by a SET request or its ioctl
equivalent uses the same format as corresponding GET_REPLY message and
is created by the same code). But it could be called infomask, I have no
strong opinion about that.

> >+{
> >+	if (unlikely(!ethnl_ok))
> >+		return;
> >+	ASSERT_RTNL();
> >+
> >+	if (likely(cmd < ARRAY_SIZE(ethnl_notify_handlers) &&
> >+		   ethnl_notify_handlers[cmd]))
> 
> How it could be null?

Notification message types share the enum with other kernel messages:

/* message types - kernel to userspace */
enum {
	ETHTOOL_MSG_KERNEL_NONE,
	ETHTOOL_MSG_STRSET_GET_REPLY,
	ETHTOOL_MSG_SETTINGS_GET_REPLY,
	ETHTOOL_MSG_SETTINGS_NTF,
	ETHTOOL_MSG_SETTINGS_SET_REPLY,
	ETHTOOL_MSG_INFO_GET_REPLY,
	ETHTOOL_MSG_PARAMS_GET_REPLY,
	ETHTOOL_MSG_PARAMS_NTF,
	ETHTOOL_MSG_NWAYRST_NTF,
	ETHTOOL_MSG_PHYSID_NTF,
	ETHTOOL_MSG_RESET_NTF,
	ETHTOOL_MSG_RESET_ACT_REPLY,
	ETHTOOL_MSG_RXFLOW_GET_REPLY,
	ETHTOOL_MSG_RXFLOW_NTF,
	ETHTOOL_MSG_RXFLOW_SET_REPLY,

	/* add new constants above here */
	__ETHTOOL_MSG_KERNEL_CNT,
	ETHTOOL_MSG_KERNEL_MAX = (__ETHTOOL_MSG_KERNEL_CNT - 1)
};

Only entries for *_NTF types are non-null in ethnl_notify_handlers[]:

static const ethnl_notify_handler_t ethnl_notify_handlers[] = {
	[ETHTOOL_MSG_SETTINGS_NTF]	= ethnl_std_notify,
	[ETHTOOL_MSG_PARAMS_NTF]	= ethnl_std_notify,
	[ETHTOOL_MSG_NWAYRST_NTF]	= ethnl_nwayrst_notify,
	[ETHTOOL_MSG_PHYSID_NTF]	= ethnl_physid_notify,
	[ETHTOOL_MSG_RESET_NTF]		= ethnl_reset_notify,
	[ETHTOOL_MSG_RXFLOW_NTF]	= ethnl_rxflow_notify,
};

If the check above fails, it means that kernel code tried to send
a notification with type which does not exist or is not a notification,
i.e. a bug in kernel; that's why the WARN_ONCE.

Michal

> >+		ethnl_notify_handlers[cmd](dev, extack, cmd, req_mask, data);
> >+	else
> >+		WARN_ONCE(1, "notification %u not implemented (dev=%s, req_mask=0x%x)\n",
> >+			  cmd, netdev_name(dev), req_mask);
> >+}
> >+EXPORT_SYMBOL(ethtool_notify);

^ permalink raw reply

* Re: [PATCH net-next v6 07/15] ethtool: support for netlink notifications
From: Michal Kubecek @ 2019-07-03 14:18 UTC (permalink / raw)
  To: netdev
  Cc: Johannes Berg, David Miller, Jakub Kicinski, Jiri Pirko,
	Andrew Lunn, Florian Fainelli, John Linville, Stephen Hemminger,
	linux-kernel
In-Reply-To: <ea84d738346b96b81550e0fd0a6c715faa323061.camel@sipsolutions.net>

On Wed, Jul 03, 2019 at 03:39:54PM +0200, Johannes Berg wrote:
> On Tue, 2019-07-02 at 13:50 +0200, Michal Kubecek wrote:
> > 
> > +static bool ethnl_ok __read_mostly;
> 
> Not sure it makes a big difference, but it could probably be
> __ro_after_init instead?

Yes, that's more fitting; the flag is initialized to false, changes to
true once ethtool netlink is ready and never changes back. I wasn't
aware of __ro_after_init annotation.

Michal

^ permalink raw reply

* Re: [PATCH net-next v6 09/15] ethtool: generic handlers for GET requests
From: Jiri Pirko @ 2019-07-03 14:25 UTC (permalink / raw)
  To: Michal Kubecek
  Cc: David Miller, netdev, Jakub Kicinski, Andrew Lunn,
	Florian Fainelli, John Linville, Stephen Hemminger, Johannes Berg,
	linux-kernel
In-Reply-To: <4faa0ce52dfe02c9cde5a46012b16c9af6764c5e.1562067622.git.mkubecek@suse.cz>

Tue, Jul 02, 2019 at 01:50:24PM CEST, mkubecek@suse.cz wrote:

[...]	
	
>+/* generic ->doit() handler for GET type requests */
>+static int ethnl_get_doit(struct sk_buff *skb, struct genl_info *info)

It is very unfortunate for review to introduce function in a patch and
don't use it. In general, this approach is frowned upon. You should use
whatever you introduce in the same patch. I understand it is sometimes
hard.

IIUC, you have one ethnl_get_doit for all possible commands, and you
have this ops to do cmd-specific tasks. That is quite unusual. Plus if
you consider the complicated datastructures connected with this, 
I'm lost from the beginning :( Any particular reason form this indirection?
I don't think any other generic netlink code does that (correct me if
I'm wrong). The nice thing about generic netlink is the fact that
you have separate handlers per cmd.

I don't think you need these ops and indirections. For the common parts,
just have a set of common helpers, as the other generic netlink users
are doing. The code would be much easier to read and follow then.


>+{
>+	const u8 cmd = info->genlhdr->cmd;
>+	const struct get_request_ops *ops;
>+	struct ethnl_req_info *req_info;
>+	struct sk_buff *rskb;
>+	void *reply_payload;
>+	int reply_len;
>+	int ret;
>+
>+	ops = get_requests[cmd];
>+	if (WARN_ONCE(!ops, "cmd %u has no get_request_ops\n", cmd))
>+		return -EOPNOTSUPP;
>+	req_info = ethnl_alloc_get_data(ops);
>+	if (!req_info)
>+		return -ENOMEM;
>+	ret = ethnl_std_parse(req_info, info->nlhdr, genl_info_net(info), ops,
>+			      info->extack, !ops->allow_nodev_do);
>+	if (ret < 0)
>+		goto err_dev;
>+	req_info->privileged = ethnl_is_privileged(skb);
>+	ethnl_init_reply_data(req_info, ops, req_info->dev);
>+
>+	rtnl_lock();
>+	ret = ops->prepare_data(req_info, info);
>+	if (ret < 0)
>+		goto err_rtnl;
>+	reply_len = ops->reply_size(req_info);
>+	if (ret < 0)
>+		goto err_cleanup;
>+	ret = -ENOMEM;
>+	rskb = ethnl_reply_init(reply_len, req_info->dev, ops->reply_cmd,
>+				ops->hdr_attr, info, &reply_payload);
>+	if (!rskb)
>+		goto err_cleanup;
>+	ret = ops->fill_reply(rskb, req_info);
>+	if (ret < 0)
>+		goto err_msg;
>+	rtnl_unlock();
>+
>+	genlmsg_end(rskb, reply_payload);
>+	if (req_info->dev)
>+		dev_put(req_info->dev);
>+	ethnl_free_get_data(ops, req_info);
>+	return genlmsg_reply(rskb, info);
>+
>+err_msg:
>+	WARN_ONCE(ret == -EMSGSIZE,
>+		  "calculated message payload length (%d) not sufficient\n",
>+		  reply_len);
>+	nlmsg_free(rskb);
>+err_cleanup:
>+	ethnl_free_get_data(ops, req_info);
>+err_rtnl:
>+	rtnl_unlock();
>+err_dev:
>+	if (req_info->dev)
>+		dev_put(req_info->dev);
>+	return ret;
>+}

[...]

^ permalink raw reply

* Re: [PATCH net-next 1/3] devlink: Introduce PCI PF port flavour and port attribute
From: Jiri Pirko @ 2019-07-03 14:33 UTC (permalink / raw)
  To: Parav Pandit
  Cc: Jakub Kicinski, Jiri Pirko, netdev@vger.kernel.org,
	Saeed Mahameed, vivien.didelot@gmail.com, andrew@lunn.ch,
	f.fainelli@gmail.com
In-Reply-To: <AM0PR05MB4866675A8CB5BDB2890E14BBD1FB0@AM0PR05MB4866.eurprd05.prod.outlook.com>

Wed, Jul 03, 2019 at 03:49:51PM CEST, parav@mellanox.com wrote:
>
>
>> -----Original Message-----
>> From: Jiri Pirko <jiri@resnulli.us>
>> Sent: Wednesday, July 3, 2019 4:07 PM
>> To: Parav Pandit <parav@mellanox.com>
>> Cc: Jakub Kicinski <jakub.kicinski@netronome.com>; Jiri Pirko
>> <jiri@mellanox.com>; netdev@vger.kernel.org; Saeed Mahameed
>> <saeedm@mellanox.com>; vivien.didelot@gmail.com; andrew@lunn.ch;
>> f.fainelli@gmail.com
>> Subject: Re: [PATCH net-next 1/3] devlink: Introduce PCI PF port flavour and
>> port attribute
>> 
>> Wed, Jul 03, 2019 at 06:46:13AM CEST, parav@mellanox.com wrote:
>> >
>> >
>> >> -----Original Message-----
>> >> From: Jakub Kicinski <jakub.kicinski@netronome.com>
>> >> Sent: Wednesday, July 3, 2019 7:46 AM
>> >> To: Parav Pandit <parav@mellanox.com>
>> >> Cc: Jiri Pirko <jiri@mellanox.com>; netdev@vger.kernel.org; Saeed
>> >> Mahameed <saeedm@mellanox.com>
>> >> Subject: Re: [PATCH net-next 1/3] devlink: Introduce PCI PF port
>> >> flavour and port attribute
>> >>
>> >> On Wed, 3 Jul 2019 02:08:39 +0000, Parav Pandit wrote:
>> >> > > If you want to expose some device specific eswitch port ID please
>> >> > > add a new attribute for that.
>> >> > > The fact that that ID may match port_number for your device today
>> >> > > is coincidental.  port_number, and split attributes should not be
>> >> > > exposed for PCI ports.
>> >> >
>> >> > So your concern is non mellanox hw has eswitch but there may not be
>> >> > a unique handle to identify a eswitch port?
>> >>
>> >> That's not a concern, no.  Like any debug attribute it should be optional.
>> >>
>> >> > Or that handle may be wider than 32-bit?
>> >>
>> >> 64 bit would probably be better, yes, although that wasn't my initial
>> >> concern.
>> >>
>> >Why 32-bit is not enough?
>> >
>> >> > And instead of treating port_number as handle, there should be
>> >> > different attribute, is that the ask?
>> >>
>> >> Yes, the ask, as always, is to not abuse existing attributes to carry
>> >> tangentially related information.
>> >
>> >Why it is tangential?
>> >Devlink_port has got a port_number. Depending on flavour this port_number
>> represents a port.
>> >If it is floavour=PHYSICAL, its physical port number.
>> >If it is eswitch pf/vf ports, it represents eswitch port.
>> >
>> >Why you see it only as physical_port_number?
>> 
>> The original intention was like that. See the desc of
>> devlink_port_attrs_set():
>> 
>>  *      @port_number: number of the port that is facing user, for example
>>  *                    the front panel port number
>> 
>> For vf/pf representors, this is not applicable and should be indeed avoided.
>> 
>Physical port number is not applicable but this is useful information that completes the eswitch picture.
>Because eswitch has this termination end point anyway.

Use port_index. That is up to the driver to put whatever value there.


>Instead of inventing some new vendor specific field, I see value in using existing port_number field.
>Will wait for others inputs.
>
>> However, we expose it for DEVLINK_PORT_FLAVOUR_CPU and
>> DEVLINK_PORT_FLAVOUR_DSA. Not sure if it makes sense there either.
>> Ccing Florian, Andrew and Vivien.
>> What do you guys think?
>> 
>> Perhaps we should have:
>> 	if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PHYSICAL &&
>> 	    nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, attrs-
>> >port_number))
>>                 return -EMSGSIZE;
>> in devlink_nl_port_attrs_put()
>

^ permalink raw reply

* Re: [PATCH net-next 1/3] devlink: Introduce PCI PF port flavour and port attribute
From: Jiri Pirko @ 2019-07-03 14:34 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parav Pandit, Jakub Kicinski, Jiri Pirko, netdev@vger.kernel.org,
	Saeed Mahameed, vivien.didelot, f.fainelli
In-Reply-To: <20190703140958.GB18473@lunn.ch>

Wed, Jul 03, 2019 at 04:09:58PM CEST, andrew@lunn.ch wrote:
>> However, we expose it for DEVLINK_PORT_FLAVOUR_CPU and
>> DEVLINK_PORT_FLAVOUR_DSA. Not sure if it makes sense there either.
>> Ccing Florian, Andrew and Vivien.
>> What do you guys think?
>
>Hi Jiri
>
>DSA and CPU ports are physical ports of the switch. And there can be
>multiple DSA ports, and maybe sometime real soon now, multiple CPU
>ports. So having a number associated with them is useful.

Okay. Makes sense.

>
>       Andrew

^ permalink raw reply

* Re: [PATCH net-next v6 08/15] ethtool: move string arrays into common file
From: Michal Kubecek @ 2019-07-03 14:37 UTC (permalink / raw)
  To: netdev
  Cc: Jiri Pirko, David Miller, Jakub Kicinski, Andrew Lunn,
	Florian Fainelli, John Linville, Stephen Hemminger, Johannes Berg,
	linux-kernel
In-Reply-To: <20190703134452.GZ2250@nanopsycho>

On Wed, Jul 03, 2019 at 03:44:52PM +0200, Jiri Pirko wrote:
> Tue, Jul 02, 2019 at 01:50:19PM CEST, mkubecek@suse.cz wrote:
> >Introduce file net/ethtool/common.c for code shared by ioctl and netlink
> >ethtool interface. Move name tables of features, RSS hash functions,
> >tunables and PHY tunables into this file.
> >
> >Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
> >---
> > net/ethtool/Makefile |  2 +-
> > net/ethtool/common.c | 84 ++++++++++++++++++++++++++++++++++++++++++++
> > net/ethtool/common.h | 17 +++++++++
> > net/ethtool/ioctl.c  | 83 ++-----------------------------------------
> > 4 files changed, 104 insertions(+), 82 deletions(-)
> > create mode 100644 net/ethtool/common.c
> > create mode 100644 net/ethtool/common.h
> >
> >diff --git a/net/ethtool/Makefile b/net/ethtool/Makefile
> >index 482fdb9380fa..11782306593b 100644
> >--- a/net/ethtool/Makefile
> >+++ b/net/ethtool/Makefile
> >@@ -1,6 +1,6 @@
> > # SPDX-License-Identifier: GPL-2.0
> > 
> >-obj-y				+= ioctl.o
> >+obj-y				+= ioctl.o common.o
> > 
> > obj-$(CONFIG_ETHTOOL_NETLINK)	+= ethtool_nl.o
> > 
> >diff --git a/net/ethtool/common.c b/net/ethtool/common.c
> >new file mode 100644
> >index 000000000000..b0ce420e994e
> >--- /dev/null
> >+++ b/net/ethtool/common.c
> >@@ -0,0 +1,84 @@
> >+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
> >+
> >+#include "common.h"
> >+
> >+const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
> 
> const char *netdev_features_strings[NETDEV_FEATURE_COUNT] = {
> ?
> 
> Same with the other arrays.

These are not new tables, this patch only moves existing tables from
ioctl.c (originally net/core/ethtool.c) into common.c so that they can
be used by both ioctl and netlink code.

This fixed size string array format is used by ETHTOOL_GSTRINGS ioctl
command. So if we switch these into simple const char *table[], we can
get rid of some complexity in strset.c and bitset.c (the "simple" vs.
"legacy" string set mess) but we would have to convert them into the
fixed size string array in ioctl ETHTOOL_GSTRINGS handler. And then we
would also have to convert (or rather "index") string sets retrieved
from NIC driver (e.g. private flags, stats, tests) - which also means an
extra kmalloc() (or rather kmalloc_array()).

It an option I'm certainly open to if we agree on it but it's not for
free.

Michal

^ permalink raw reply

* Re: [PATCH net-next v6 06/15] ethtool: netlink bitset handling
From: Jiri Pirko @ 2019-07-03 14:37 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Michal Kubecek, David Miller, netdev, Jakub Kicinski, Andrew Lunn,
	Florian Fainelli, John Linville, Stephen Hemminger, linux-kernel
In-Reply-To: <b3cd61506080143f571d6286223ae33c8bd02c3a.camel@sipsolutions.net>

Wed, Jul 03, 2019 at 03:44:57PM CEST, johannes@sipsolutions.net wrote:
>On Wed, 2019-07-03 at 13:49 +0200, Jiri Pirko wrote:
>> 
>> > +Value and mask must have length at least ETHTOOL_A_BITSET_SIZE bits rounded up
>> > +to a multiple of 32 bits. They consist of 32-bit words in host byte order,
>> 
>> Looks like the blocks are similar to NLA_BITFIELD32. Why don't you user
>> nested array of NLA_BITFIELD32 instead?
>
>That would seem kind of awkward to use, IMHO.
>
>Perhaps better to make some kind of generic "arbitrary size bitfield"
>attribute type?

Yep, I believe I was trying to make this point during bitfield32
discussion, failed apparently. So if we have "NLA_BITFIELD" with
arbitrary size, that sounds good to me.


>
>Not really sure we want the complexity with _LIST and _SIZE, since you
>should always be able to express it as _VALUE and _MASK, right?
>
>Trying to think how we should express this best - bitfield32 is just a
>mask/value struct, for arbitrary size I guess we *could* just make it
>kind of a binary with arbitrary length that must be a multiple of 2
>bytes (or 2 u32-bit-words?) and then the first half is the value and the
>second half is the mask? Some more validation would be nicer, but having
>a generic attribute that actually is nested is awkward too.
>
>johannes
>
>

^ permalink raw reply

* Re: [PATCH net] sctp: count data bundling sack chunk for outctrlchunks
From: Neil Horman @ 2019-07-03 14:38 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner
In-Reply-To: <62e917e312bc582e96fa19b502561e37ca7f91a6.1562149220.git.lucien.xin@gmail.com>

On Wed, Jul 03, 2019 at 06:20:20PM +0800, Xin Long wrote:
> Now all ctrl chunks are counted for asoc stats.octrlchunks and net
> SCTP_MIB_OUTCTRLCHUNKS either after queuing up or bundling, other
> than the chunk maked and bundled in sctp_packet_bundle_sack, which
> caused 'outctrlchunks' not consistent with 'inctrlchunks' in peer.
> 
> This issue exists since very beginning, here to fix it by increasing
> both net SCTP_MIB_OUTCTRLCHUNKS and asoc stats.octrlchunks when sack
> chunk is maked and bundled in sctp_packet_bundle_sack.
> 
> Reported-by: Ja Ram Jeon <jajeon@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  net/sctp/output.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/net/sctp/output.c b/net/sctp/output.c
> index e0c2747..dbda7e7 100644
> --- a/net/sctp/output.c
> +++ b/net/sctp/output.c
> @@ -282,6 +282,9 @@ static enum sctp_xmit sctp_packet_bundle_sack(struct sctp_packet *pkt,
>  					sctp_chunk_free(sack);
>  					goto out;
>  				}
> +				SCTP_INC_STATS(sock_net(asoc->base.sk),
> +					       SCTP_MIB_OUTCTRLCHUNKS);
> +				asoc->stats.octrlchunks++;
>  				asoc->peer.sack_needed = 0;
>  				if (del_timer(timer))
>  					sctp_association_put(asoc);
> -- 
> 2.1.0
> 
> 
Acked-by: Neil Horman <nhorman@tuxdriver.com>


^ permalink raw reply

* Re: kernel panic: corrupted stack end in dput
From: Al Viro @ 2019-07-03 14:40 UTC (permalink / raw)
  To: Hillf Danton
  Cc: syzbot, linux-fsdevel@vger.kernel.org,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	syzkaller-bugs@googlegroups.com
In-Reply-To: <20190703064307.13740-1-hdanton@sina.com>

On Wed, Jul 03, 2019 at 02:43:07PM +0800, Hillf Danton wrote:

> > This is very much *NOT* fine.
> > 	1) trylock can fail from any number of reasons, starting
> > with "somebody is going through the hash chain doing a lookup on
> > something completely unrelated"
> 
> They are also a red light that we need to bail out of spiraling up
> the directory hierarchy imho.

Translation: "let's leak the reference to parent, shall we?"

> > 	2) whoever had been holding the lock and whatever they'd
> > been doing might be over right after we get the return value from
> > spin_trylock().
> 
> Or after we send a mail using git. I don't know.
> 
> > 	3) even had that been really somebody adding children in
> > the same parent *AND* even if they really kept doing that, rather
> > than unlocking and buggering off, would you care to explain why
> > dentry_unlist() called by __dentry_kill() and removing the victim
> > from the list of children would be safe to do in parallel with that?
> >
> My bad. I have to walk around that unsafety.

WHAT unsafety?  Can you explain what are you seeing and how to
reproduce it, whatever it is?

^ permalink raw reply

* Re: [PATCH net-next v2 0/5] net: use ICW for sk_proto->{send,recv}msg
From: Willem de Bruijn @ 2019-07-03 14:45 UTC (permalink / raw)
  To: Paolo Abeni; +Cc: Network Development, David S. Miller
In-Reply-To: <cover.1562162469.git.pabeni@redhat.com>

On Wed, Jul 3, 2019 at 10:07 AM Paolo Abeni <pabeni@redhat.com> wrote:
>
> This series extends ICW usage to one of the few remaining spots in fast-path
> still hitting per packet retpoline overhead, namely the sk_proto->{send,recv}msg
> calls.
>
> The first 3 patches in this series refactor the existing code so that applying
> the ICW macros is straight-forward: we demux inet_{recv,send}msg in ipv4 and
> ipv6 variants so that each of them can easily select the appropriate TCP or UDP
> direct call. While at it, a new helper is created to avoid excessive code
> duplication, and the current ICWs for inet_{recv,send}msg are adjusted
> accordingly.
>
> The last 2 patches really introduce the new ICW use-case, respectively for the
> ipv6 and the ipv4 code path.
>
> This gives up to 5% performance improvement under UDP flood, and smaller but
> measurable gains for TCP RR workloads.
>
> v1 -> v2:
>  - drop inet6_{recv,send}msg declaration from header file,
>    prefer ICW macro instead
>  - avoid unneeded reclaration for udp_sendmsg, as suggested by Willem
>
> Paolo Abeni (5):
>   inet: factor out inet_send_prepare()
>   ipv6: provide and use ipv6 specific version for {recv,send}msg
>   net: adjust socket level ICW to cope with ipv6 variant of
>     {recv,send}msg
>   ipv6: use indirect call wrappers for {tcp,udpv6}_{recv,send}msg()
>   ipv4: use indirect call wrappers for {tcp,udp}_{recv,send}msg()

Acked-by: Willem de Bruijn <willemb@google.com>

^ permalink raw reply

* Re: [PATCH v2 bpf-next] bpf: cgroup: Fix build error without CONFIG_NET
From: Yonghong Song @ 2019-07-03 14:45 UTC (permalink / raw)
  To: YueHaibing, ast@kernel.org, daniel@iogearbox.net, Martin Lau,
	Song Liu, sdf@google.com
  Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	bpf@vger.kernel.org
In-Reply-To: <20190703082630.51104-1-yuehaibing@huawei.com>



On 7/3/19 1:26 AM, YueHaibing wrote:
> If CONFIG_NET is not set and CONFIG_CGROUP_BPF=y,
> gcc building fails:
> 
> kernel/bpf/cgroup.o: In function `cg_sockopt_func_proto':
> cgroup.c:(.text+0x237e): undefined reference to `bpf_sk_storage_get_proto'
> cgroup.c:(.text+0x2394): undefined reference to `bpf_sk_storage_delete_proto'
> kernel/bpf/cgroup.o: In function `__cgroup_bpf_run_filter_getsockopt':
> (.text+0x2a1f): undefined reference to `lock_sock_nested'
> (.text+0x2ca2): undefined reference to `release_sock'
> kernel/bpf/cgroup.o: In function `__cgroup_bpf_run_filter_setsockopt':
> (.text+0x3006): undefined reference to `lock_sock_nested'
> (.text+0x32bb): undefined reference to `release_sock'
> 
> Reported-by: Hulk Robot <hulkci@huawei.com>
> Suggested-by: Stanislav Fomichev <sdf@fomichev.me>
> Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks")
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>

Acked-by: Yonghong Song <yhs@fb.com>

> ---
> v2: use ifdef macro
> ---
>   kernel/bpf/cgroup.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> index 76fa007..0a00eac 100644
> --- a/kernel/bpf/cgroup.c
> +++ b/kernel/bpf/cgroup.c
> @@ -939,6 +939,7 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
>   }
>   EXPORT_SYMBOL(__cgroup_bpf_run_filter_sysctl);
>   
> +#ifdef CONFIG_NET
>   static bool __cgroup_bpf_prog_array_is_empty(struct cgroup *cgrp,
>   					     enum bpf_attach_type attach_type)
>   {
> @@ -1120,6 +1121,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
>   	return ret;
>   }
>   EXPORT_SYMBOL(__cgroup_bpf_run_filter_getsockopt);
> +#endif
>   
>   static ssize_t sysctl_cpy_dir(const struct ctl_dir *dir, char **bufp,
>   			      size_t *lenp)
> @@ -1386,10 +1388,12 @@ static const struct bpf_func_proto *
>   cg_sockopt_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
>   {
>   	switch (func_id) {
> +#ifdef CONFIG_NET
>   	case BPF_FUNC_sk_storage_get:
>   		return &bpf_sk_storage_get_proto;
>   	case BPF_FUNC_sk_storage_delete:
>   		return &bpf_sk_storage_delete_proto;
> +#endif
>   #ifdef CONFIG_INET
>   	case BPF_FUNC_tcp_sock:
>   		return &bpf_tcp_sock_proto;
> 

^ permalink raw reply

* Re: [PATCH net-next] skbuff: increase verbosity when dumping skb data
From: Willem de Bruijn @ 2019-07-03 14:55 UTC (permalink / raw)
  To: Yunsheng Lin
  Cc: Network Development, David Miller, Cong Wang, Herbert Xu,
	Eric Dumazet, Saeed Mahameed, Willem de Bruijn
In-Reply-To: <254abb52-e201-eb12-d6c2-6bd96e505871@huawei.com>

On Tue, Jul 2, 2019 at 11:28 PM Yunsheng Lin <linyunsheng@huawei.com> wrote:
>
> On 2019/7/3 3:39, Willem de Bruijn wrote:
> > From: Willem de Bruijn <willemb@google.com>
> >
> > skb_warn_bad_offload and netdev_rx_csum_fault trigger on hard to debug
> > issues. Dump more state and the header.
> >
> > Optionally dump the entire packet and linear segment. This is required
> > to debug checksum bugs that may include bytes past skb_tail_pointer().
> >
> > Both call sites call this function inside a net_ratelimit() block.
> > Limit full packet log further to a hard limit of can_dump_full (5).
> >
> > Based on an earlier patch by Cong Wang, see link below.
> >
> > Link: https://patchwork.ozlabs.org/patch/1000841/
> > Signed-off-by: Willem de Bruijn <willemb@google.com>
> > ---

> > +void skb_dump(const char *level, const struct sk_buff *skb, bool full_pkt)
> > +{
> > +     static atomic_t can_dump_full = ATOMIC_INIT(5);
> > +     struct skb_shared_info *sh = skb_shinfo(skb);
> > +     struct net_device *dev = skb->dev;
> > +     struct sock *sk = skb->sk;
> > +     struct sk_buff *list_skb;
> > +     bool has_mac, has_trans;
> > +     int headroom, tailroom;
> > +     int i, len, seg_len;
> > +
> > +     if (full_pkt)
> > +             full_pkt = atomic_dec_if_positive(&can_dump_full) >= 0;
> > +
> > +     if (full_pkt)
> > +             len = skb->len;
>
> Minor question:
> Here we set the len to skb->len if full_pkt is true when skb_dump is
> called with frag_list skb and full_pkt being true below, which may
> cause some problem?

Good catch, thanks!

That recursive call to skb_dump on the frag_list below was not updated
from a previous revision that passed an explicit length.

> Maybe change the definition to:
> void skb_dump(const char *level, const struct sk_buff *skb, int len, bool full_pkt)

Indeed. It is less important when full_pkt, as then the entire
frag_list will be printed.

But if len is truncated, but somehow len != 0 when reaching the
frag_list, it might overshoot the limit. Will fix for v2.

> skb_dump(KERN_ERR, skb, skb->len, true);
>
> > +     else
> > +             len = min_t(int, skb->len, MAX_HEADER + 128);
> > +
> > +     headroom = skb_headroom(skb);
> > +     tailroom = skb_tailroom(skb);
> > +
> > +     has_mac = skb_mac_header_was_set(skb);
> > +     has_trans = skb_transport_header_was_set(skb);
> > +
> > +     printk("%sskb len=%u headroom=%u headlen=%u tailroom=%u\n"
> > +            "mac=(%d,%d) net=(%d,%d) trans=%d\n"
> > +            "shinfo(txflags=%u nr_frags=%u gso(size=%hu type=%u segs=%hu))\n"
> > +            "csum(0x%x ip_summed=%u complete_sw=%u valid=%u level=%u)\n"
> > +            "hash(0x%x sw=%u l4=%u) proto=0x%04x pkttype=%u iif=%d\n",
> > +            level, skb->len, headroom, skb_headlen(skb), tailroom,
> > +            has_mac ? skb->mac_header : -1,
> > +            has_mac ? skb_mac_header_len(skb) : -1,
> > +            skb->network_header,
> > +            has_trans ? skb_network_header_len(skb) : -1,
> > +            has_trans ? skb->transport_header : -1,
> > +            sh->tx_flags, sh->nr_frags,
> > +            sh->gso_size, sh->gso_type, sh->gso_segs,
> > +            skb->csum, skb->ip_summed, skb->csum_complete_sw,
> > +            skb->csum_valid, skb->csum_level,
> > +            skb->hash, skb->sw_hash, skb->l4_hash,
> > +            ntohs(skb->protocol), skb->pkt_type, skb->skb_iif);
> > +
> > +     if (dev)
> > +             printk("%sdev name=%s feat=0x%pNF\n",
> > +                    level, dev->name, &dev->features);
> > +     if (sk)
> > +             printk("%ssk family=%hu type=%hu proto=%hu\n",
> > +                    level, sk->sk_family, sk->sk_type, sk->sk_protocol);
> > +
> > +     if (full_pkt && headroom)
> > +             print_hex_dump(level, "skb headroom: ", DUMP_PREFIX_OFFSET,
> > +                            16, 1, skb->head, headroom, false);
> > +
> > +     seg_len = min_t(int, skb_headlen(skb), len);
> > +     if (seg_len)
> > +             print_hex_dump(level, "skb linear:   ", DUMP_PREFIX_OFFSET,
> > +                            16, 1, skb->data, seg_len, false);
> > +     len -= seg_len;
> > +
> > +     if (full_pkt && tailroom)
> > +             print_hex_dump(level, "skb tailroom: ", DUMP_PREFIX_OFFSET,
> > +                            16, 1, skb_tail_pointer(skb), tailroom, false);
> > +
> > +     for (i = 0; len && i < skb_shinfo(skb)->nr_frags; i++) {
> > +             skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
> > +             u32 p_off, p_len, copied;
> > +             struct page *p;
> > +             u8 *vaddr;
> > +
> > +             skb_frag_foreach_page(frag, frag->page_offset,
> > +                                   skb_frag_size(frag), p, p_off, p_len,
> > +                                   copied) {
> > +                     seg_len = min_t(int, p_len, len);
> > +                     vaddr = kmap_atomic(p);
> > +                     print_hex_dump(level, "skb frag:     ",
> > +                                    DUMP_PREFIX_OFFSET,
> > +                                    16, 1, vaddr + p_off, seg_len, false);
> > +                     kunmap_atomic(vaddr);
> > +                     len -= seg_len;
> > +                     if (!len)
> > +                             break;
> > +             }
> > +     }
> > +
> > +     if (len && skb_has_frag_list(skb)) {
> > +             printk("skb fraglist:\n");
> > +             skb_walk_frags(skb, list_skb) {
> > +                     if (len <= 0)
> > +                             break;
> > +                     skb_dump(level, list_skb, len);
>
> Here we call skb_dump passing len as full_pkt.
>
> Maybe call it with skb_dump(level, list_skb, len, full_pkt);
>
> > +                     len -= list_skb->len;
> > +             }
> > +     }
> > +}
> > +EXPORT_SYMBOL(skb_dump);

^ permalink raw reply

* Re: [PATCH v4 bpf-next] bpf: Add support for fq's EDT to HBM
From: Daniel Borkmann @ 2019-07-03 15:03 UTC (permalink / raw)
  To: brakmo, netdev
  Cc: Alexei Starovoitov, Yonghong Song, Eric Dumazet, Kernel Team
In-Reply-To: <20190702220952.3929270-1-brakmo@fb.com>

On 07/03/2019 12:09 AM, brakmo wrote:
> Adds support for fq's Earliest Departure Time to HBM (Host Bandwidth
> Manager). Includes a new BPF program supporting EDT, and also updates
> corresponding programs.
> 
> It will drop packets with an EDT of more than 500us in the future
> unless the packet belongs to a flow with less than 2 packets in flight.
> This is done so each flow has at least 2 packets in flight, so they
> will not starve, and also to help prevent delayed ACK timeouts.
> 
> It will also work with ECN enabled traffic, where the packets will be
> CE marked if their EDT is more than 50us in the future.
> 
> The table below shows some performance numbers. The flows are back to
> back RPCS. One server sending to another, either 2 or 4 flows.
> One flow is a 10KB RPC, the rest are 1MB RPCs. When there are more
> than one flow of a given RPC size, the numbers represent averages.
> 
> The rate limit applies to all flows (they are in the same cgroup).
> Tests ending with "-edt" ran with the new BPF program supporting EDT.
> Tests ending with "-hbt" ran on top HBT qdisc with the specified rate
> (i.e. no HBM). The other tests ran with the HBM BPF program included
> in the HBM patch-set.
> 
> EDT has limited value when using DCTCP, but it helps in many cases when
> using Cubic. It usually achieves larger link utilization and lower
> 99% latencies for the 1MB RPCs.
> HBM ends up queueing a lot of packets with its default parameter values,
> reducing the goodput of the 10KB RPCs and increasing their latency. Also,
> the RTTs seen by the flows are quite large.
> 
>                          Aggr              10K  10K  10K   1MB  1MB  1MB
>          Limit           rate drops  RTT  rate  P90  P99  rate  P90  P99
> Test      rate  Flows    Mbps   %     us  Mbps   us   us  Mbps   ms   ms
> --------  ----  -----    ---- -----  ---  ---- ---- ----  ---- ---- ----
> cubic       1G    2       904  0.02  108   257  511  539   647 13.4 24.5
> cubic-edt   1G    2       982  0.01  156   239  656  967   743 14.0 17.2
> dctcp       1G    2       977  0.00  105   324  408  744   653 14.5 15.9
> dctcp-edt   1G    2       981  0.01  142   321  417  811   660 15.7 17.0
> cubic-htb   1G    2       919  0.00 1825    40 2822 4140   879  9.7  9.9
> 
> cubic     200M    2       155  0.30  220    81  532  655    74  283  450
> cubic-edt 200M    2       188  0.02  222    87 1035 1095   101   84   85
> dctcp     200M    2       188  0.03  111    77  912  939   111   76  325
> dctcp-edt 200M    2       188  0.03  217    74 1416 1738   114   76   79
> cubic-htb 200M    2       188  0.00 5015     8 14ms 15ms   180   48   50
> 
> cubic       1G    4       952  0.03  110   165  516  546   262   38  154
> cubic-edt   1G    4       973  0.01  190   111 1034 1314   287   65   79
> dctcp       1G    4       951  0.00  103   180  617  905   257   37   38
> dctcp-edt   1G    4       967  0.00  163   151  732 1126   272   43   55
> cubic-htb   1G    4       914  0.00 3249    13  7ms  8ms   300   29   34
> 
> cubic       5G    4      4236  0.00  134   305  490  624  1310   10   17
> cubic-edt   5G    4      4865  0.00  156   306  425  759  1520   10   16
> dctcp       5G    4      4936  0.00  128   485  221  409  1484    7    9
> dctcp-edt   5G    4      4924  0.00  148   390  392  623  1508   11   26
> 
> v1 -> v2: Incorporated Andrii's suggestions
> v2 -> v3: Incorporated Yonghong's suggestions
> v3 -> v4: Removed credit update that is not needed
> 
> Signed-off-by: Lawrence Brakmo <brakmo@fb.com>

Applied, thanks!

^ permalink raw reply

* Re: [PATCH bpf-next] selftests: bpf: standardize to static __always_inline
From: Daniel Borkmann @ 2019-07-03 15:03 UTC (permalink / raw)
  To: Jiri Benc, netdev, bpf; +Cc: Alexei Starovoitov, Song Liu, Y Song
In-Reply-To: <b62ef44131bbe3b905fc42990d16b667a65c820c.1562091849.git.jbenc@redhat.com>

On 07/02/2019 08:26 PM, Jiri Benc wrote:
> The progs for bpf selftests use several different notations to force
> function inlining. Standardize to what most of them use,
> static __always_inline.
> 
> Suggested-by: Song Liu <liu.song.a23@gmail.com>
> Signed-off-by: Jiri Benc <jbenc@redhat.com>

Applied, thanks!

^ permalink raw reply

* Re: [PATCH bpf-next v2 0/8] bpf: TCP RTT sock_ops bpf callback
From: Daniel Borkmann @ 2019-07-03 15:04 UTC (permalink / raw)
  To: Stanislav Fomichev, netdev, bpf
  Cc: davem, ast, Eric Dumazet, Priyaranjan Jha, Yuchung Cheng,
	Soheil Hassas Yeganeh
In-Reply-To: <20190702161403.191066-1-sdf@google.com>

On 07/02/2019 06:13 PM, Stanislav Fomichev wrote:
> Congestion control team would like to have a periodic callback to
> track some TCP statistics. Let's add a sock_ops callback that can be
> selectively enabled on a socket by socket basis and is executed for
> every RTT. BPF program frequency can be further controlled by calling
> bpf_ktime_get_ns and bailing out early.
> 
> I run neper tcp_stream and tcp_rr tests with the sample program
> from the last patch and didn't observe any noticeable performance
> difference.
> 
> v2:
> * add a comment about second accept() in selftest (Yonghong Song)
> * refer to tcp_bpf.readme in sample program (Yonghong Song)
> 
> Suggested-by: Eric Dumazet <edumazet@google.com>
> Cc: Eric Dumazet <edumazet@google.com>
> Cc: Priyaranjan Jha <priyarjha@google.com>
> Cc: Yuchung Cheng <ycheng@google.com>
> Cc: Soheil Hassas Yeganeh <soheil@google.com>
> Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
> Acked-by: Yuchung Cheng <ycheng@google.com>
> 
> Stanislav Fomichev (8):
>   bpf: add BPF_CGROUP_SOCK_OPS callback that is executed on every RTT
>   bpf: split shared bpf_tcp_sock and bpf_sock_ops implementation
>   bpf: add dsack_dups/delivered{,_ce} to bpf_tcp_sock
>   bpf: add icsk_retransmits to bpf_tcp_sock
>   bpf/tools: sync bpf.h
>   selftests/bpf: test BPF_SOCK_OPS_RTT_CB
>   samples/bpf: add sample program that periodically dumps TCP stats
>   samples/bpf: fix tcp_bpf.readme detach command
> 
>  include/net/tcp.h                           |   8 +
>  include/uapi/linux/bpf.h                    |  12 +-
>  net/core/filter.c                           | 207 +++++++++++-----
>  net/ipv4/tcp_input.c                        |   4 +
>  samples/bpf/Makefile                        |   1 +
>  samples/bpf/tcp_bpf.readme                  |   2 +-
>  samples/bpf/tcp_dumpstats_kern.c            |  68 ++++++
>  tools/include/uapi/linux/bpf.h              |  12 +-
>  tools/testing/selftests/bpf/Makefile        |   3 +-
>  tools/testing/selftests/bpf/progs/tcp_rtt.c |  61 +++++
>  tools/testing/selftests/bpf/test_tcp_rtt.c  | 254 ++++++++++++++++++++
>  11 files changed, 574 insertions(+), 58 deletions(-)
>  create mode 100644 samples/bpf/tcp_dumpstats_kern.c
>  create mode 100644 tools/testing/selftests/bpf/progs/tcp_rtt.c
>  create mode 100644 tools/testing/selftests/bpf/test_tcp_rtt.c
> 

Applied, thanks!

^ permalink raw reply

* Re: [PATCH bpf v2] selftests: bpf: fix inlines in test_lwt_seg6local
From: Daniel Borkmann @ 2019-07-03 15:04 UTC (permalink / raw)
  To: Jiri Benc, netdev, bpf
  Cc: Alexei Starovoitov, Mathieu Xhonneux, Song Liu, Y Song
In-Reply-To: <bf60860191c7d4ab0f50fe3143f3d175bd6ee112.1562089104.git.jbenc@redhat.com>

On 07/02/2019 07:40 PM, Jiri Benc wrote:
> Selftests are reporting this failure in test_lwt_seg6local.sh:
> 
> + ip netns exec ns2 ip -6 route add fb00::6 encap bpf in obj test_lwt_seg6local.o sec encap_srh dev veth2
> Error fetching program/map!
> Failed to parse eBPF program: Operation not permitted
> 
> The problem is __attribute__((always_inline)) alone is not enough to prevent
> clang from inserting those functions in .text. In that case, .text is not
> marked as relocateable.
> 
> See the output of objdump -h test_lwt_seg6local.o:
> 
> Idx Name          Size      VMA               LMA               File off  Algn
>   0 .text         00003530  0000000000000000  0000000000000000  00000040  2**3
>                   CONTENTS, ALLOC, LOAD, READONLY, CODE
> 
> This causes the iproute bpf loader to fail in bpf_fetch_prog_sec:
> bpf_has_call_data returns true but bpf_fetch_prog_relo fails as there's no
> relocateable .text section in the file.
> 
> To fix this, convert to 'static __always_inline'.
> 
> v2: Use 'static __always_inline' instead of 'static inline
>     __attribute__((always_inline))'
> 
> Fixes: c99a84eac026 ("selftests/bpf: test for seg6local End.BPF action")
> Signed-off-by: Jiri Benc <jbenc@redhat.com>

Applied, thanks!

^ permalink raw reply

* Re: [PATCH bpf v6 0/2] xdp: fix hang while unregistering device bound to xdp socket
From: Daniel Borkmann @ 2019-07-03 15:05 UTC (permalink / raw)
  To: Ilya Maximets, netdev
  Cc: linux-kernel, bpf, xdp-newbies, David S. Miller,
	Björn Töpel, Magnus Karlsson, Jonathan Lemon,
	Jakub Kicinski
In-Reply-To: <20190628080407.30354-1-i.maximets@samsung.com>

On 06/28/2019 10:04 AM, Ilya Maximets wrote:
> Version 6:
> 
>     * Better names for socket state.
> 
> Version 5:
> 
>     * Fixed incorrect handling of rtnl_lock.
> 
> Version 4:
> 
>     * 'xdp_umem_clear_dev' exposed to be used while unregistering.
>     * Added XDP socket state to track if resources already unbinded.
>     * Splitted in two fixes.
> 
> Version 3:
> 
>     * Declaration lines ordered from longest to shortest.
>     * Checking of event type moved to the top to avoid unnecessary
>       locking.
> 
> Version 2:
> 
>     * Completely re-implemented using netdev event handler.
> 
> Ilya Maximets (2):
>   xdp: hold device for umem regardless of zero-copy mode
>   xdp: fix hang while unregistering device bound to xdp socket
> 
>  include/net/xdp_sock.h |  5 +++
>  net/xdp/xdp_umem.c     | 21 +++++-----
>  net/xdp/xdp_umem.h     |  1 +
>  net/xdp/xsk.c          | 87 ++++++++++++++++++++++++++++++++++++------
>  4 files changed, 93 insertions(+), 21 deletions(-)
> 

Applied, thanks!

^ permalink raw reply

* Re: [PATCH v2 02/17] dt-bindings: soc: qcom: add IPA bindings
From: Alex Elder @ 2019-07-03 15:09 UTC (permalink / raw)
  To: Alex Elder, Rob Herring
  Cc: David Miller, Arnd Bergmann, Bjorn Andersson, Ilias Apalodimas,
	Mark Rutland, devicetree, Evan Green, Ben Chan, Eric Caruso,
	cpratapa, syadagir, subashab, abhishek.esse, netdev,
	linux-kernel@vger.kernel.org, open list:ARM/QUALCOMM SUPPORT,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	linux-arm-msm
In-Reply-To: <bcb7f599-3c22-da27-c92b-4c1903a5ea06@ieee.org>

On 6/10/19 9:11 PM, Alex Elder wrote:
> On 6/10/19 5:08 PM, Rob Herring wrote:
>> On Thu, May 30, 2019 at 9:53 PM Alex Elder <elder@linaro.org> wrote:
>>>
>>> Add the binding definitions for the "qcom,ipa" device tree node.
>>>
>>> Signed-off-by: Alex Elder <elder@linaro.org>
>>> ---
>>>  .../devicetree/bindings/net/qcom,ipa.yaml     | 180 ++++++++++++++++++
>>>  1 file changed, 180 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/net/qcom,ipa.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/qcom,ipa.yaml b/Documentation/devicetree/bindings/net/qcom,ipa.yaml
>>> new file mode 100644
>>> index 000000000000..0037fc278a61
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/net/qcom,ipa.yaml
>>> @@ -0,0 +1,180 @@
>>> +# SPDX-License-Identifier: GPL-2.0
>>
>> New bindings are preferred to be dual GPL-2.0 and BSD-2-Clause. But
>> that's really a decision for the submitter.
> 
> Thanks Rob.  I'll ask Qualcomm if there's any problem
> with doing that; I presume not.  If I re-submit this
> with dual copyright, I will include your Reviewed-by
> despite the change, OK?

FYI I have the go-ahead to use dual GPL-2.0 and BSD-2-Clause
bindings on this, and will mark it that way whenever I next
post this code for review.

I will also be updating other Qualcomm bindings to have a
dual copyright (in a separate series).  We'll want to
get an ack from appropriate Code Aurora developers on
those (I'll provide more detail at the time those get
posted).

					-Alex

> 					-Alex
> 
>>
>> Reviewed-by: Rob Herring <robh@kernel.org>
>>
> 


^ permalink raw reply

* [PATCH net-next 0/3] net: Multipath hashing on inner L3
From: Stephen Suryaputra @ 2019-07-03 15:19 UTC (permalink / raw)
  To: netdev; +Cc: idosch, nikolay, dsahern, Stephen Suryaputra

This series extends commit 363887a2cdfe ("ipv4: Support multipath
hashing on inner IP pkts for GRE tunnel") to include support when the
outer L3 is IPv6 and to consider the case where the inner L3 is
different version from the outer L3, such as IPv6 over GRE over IPv4 or
vice versa. It also includes kselftest scripts to test the use cases.

Stephen Suryaputra (3):
  ipv4: Multipath hashing on inner L3 needs to consider inner IPv6 pkts
  ipv6: Support multipath hashing on inner IP pkts
  selftests: forwarding: Test multipath hashing on inner IP pkts for GRE
    tunnel

 Documentation/networking/ip-sysctl.txt        |   1 +
 net/ipv4/route.c                              |  21 +-
 net/ipv6/route.c                              |  36 +++
 .../net/forwarding/gre_inner_v4_multipath.sh  | 305 +++++++++++++++++
 .../net/forwarding/gre_inner_v6_multipath.sh  | 306 ++++++++++++++++++
 .../forwarding/ip6gre_inner_v4_multipath.sh   | 304 +++++++++++++++++
 .../forwarding/ip6gre_inner_v6_multipath.sh   | 305 +++++++++++++++++
 7 files changed, 1274 insertions(+), 4 deletions(-)
 create mode 100755 tools/testing/selftests/net/forwarding/gre_inner_v4_multipath.sh
 create mode 100755 tools/testing/selftests/net/forwarding/gre_inner_v6_multipath.sh
 create mode 100755 tools/testing/selftests/net/forwarding/ip6gre_inner_v4_multipath.sh
 create mode 100755 tools/testing/selftests/net/forwarding/ip6gre_inner_v6_multipath.sh

-- 
2.17.1


^ permalink raw reply

* [PATCH net-next 1/3] ipv4: Multipath hashing on inner L3 needs to consider inner IPv6 pkts
From: Stephen Suryaputra @ 2019-07-03 15:19 UTC (permalink / raw)
  To: netdev; +Cc: idosch, nikolay, dsahern, Stephen Suryaputra
In-Reply-To: <20190703151934.9567-1-ssuryaextr@gmail.com>

Commit 363887a2cdfe ("ipv4: Support multipath hashing on inner IP pkts
for GRE tunnel") supports multipath policy value of 2, Layer 3 or inner
Layer 3 if present, but it only considers inner IPv4. There is a use
case of IPv6 over GRE over IPv4, thus add the ability to hash on inner
IPv6 addresses.

Fixes: 363887a2cdfe ("ipv4: Support multipath hashing on inner IP pkts for GRE tunnel")
Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
---
 net/ipv4/route.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index dc1f510a7c81..abaa7f9371e5 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1964,17 +1964,30 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
 		break;
 	case 2:
 		memset(&hash_keys, 0, sizeof(hash_keys));
-		hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
 		/* skb is currently provided only when forwarding */
 		if (skb) {
 			struct flow_keys keys;
 
 			skb_flow_dissect_flow_keys(skb, &keys, 0);
-
-			hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src;
-			hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst;
+			/* Inner can be v4 or v6 */
+			if (keys.control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
+				hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+				hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src;
+				hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst;
+			} else if (keys.control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
+				hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+				hash_keys.addrs.v6addrs.src = keys.addrs.v6addrs.src;
+				hash_keys.addrs.v6addrs.dst = keys.addrs.v6addrs.dst;
+				hash_keys.tags.flow_label = keys.tags.flow_label;
+				hash_keys.basic.ip_proto = keys.basic.ip_proto;
+			} else {
+				/* Same as case 0 */
+				hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+				ip_multipath_l3_keys(skb, &hash_keys);
+			}
 		} else {
 			/* Same as case 0 */
+			hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
 			hash_keys.addrs.v4addrs.src = fl4->saddr;
 			hash_keys.addrs.v4addrs.dst = fl4->daddr;
 		}
-- 
2.17.1


^ permalink raw reply related

* [PATCH net-next 2/3] ipv6: Support multipath hashing on inner IP pkts
From: Stephen Suryaputra @ 2019-07-03 15:19 UTC (permalink / raw)
  To: netdev; +Cc: idosch, nikolay, dsahern, Stephen Suryaputra
In-Reply-To: <20190703151934.9567-1-ssuryaextr@gmail.com>

Make the same support as commit 363887a2cdfe ("ipv4: Support multipath
hashing on inner IP pkts for GRE tunnel") for outer IPv6. The hashing
considers both IPv4 and IPv6 inner pkts.

Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
---
 Documentation/networking/ip-sysctl.txt |  1 +
 net/ipv6/route.c                       | 36 ++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index f0e6d1f53485..48c79e78817b 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1473,6 +1473,7 @@ fib_multipath_hash_policy - INTEGER
 	Possible values:
 	0 - Layer 3 (source and destination addresses plus flow label)
 	1 - Layer 4 (standard 5-tuple)
+	2 - Layer 3 or inner Layer 3 if present
 
 anycast_src_echo_reply - BOOLEAN
 	Controls the use of anycast addresses as source addresses for ICMPv6
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 39361f57351a..4d2e6b31a8d6 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2370,6 +2370,42 @@ u32 rt6_multipath_hash(const struct net *net, const struct flowi6 *fl6,
 			hash_keys.basic.ip_proto = fl6->flowi6_proto;
 		}
 		break;
+	case 2:
+		memset(&hash_keys, 0, sizeof(hash_keys));
+		hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+		if (skb) {
+			struct flow_keys keys;
+
+			if (!flkeys) {
+				skb_flow_dissect_flow_keys(skb, &keys, 0);
+				flkeys = &keys;
+			}
+
+			/* Inner can be v4 or v6 */
+			if (flkeys->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
+				hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+				hash_keys.addrs.v4addrs.src = flkeys->addrs.v4addrs.src;
+				hash_keys.addrs.v4addrs.dst = flkeys->addrs.v4addrs.dst;
+			} else if (flkeys->control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
+				hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+				hash_keys.addrs.v6addrs.src = flkeys->addrs.v6addrs.src;
+				hash_keys.addrs.v6addrs.dst = flkeys->addrs.v6addrs.dst;
+				hash_keys.tags.flow_label = flkeys->tags.flow_label;
+				hash_keys.basic.ip_proto = flkeys->basic.ip_proto;
+			} else {
+				/* Same as case 0 */
+				hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+				ip6_multipath_l3_keys(skb, &hash_keys, flkeys);
+			}
+		} else {
+			/* Same as case 0 */
+			hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+			hash_keys.addrs.v6addrs.src = fl6->saddr;
+			hash_keys.addrs.v6addrs.dst = fl6->daddr;
+			hash_keys.tags.flow_label = (__force u32)flowi6_get_flowlabel(fl6);
+			hash_keys.basic.ip_proto = fl6->flowi6_proto;
+		}
+		break;
 	}
 	mhash = flow_hash_from_keys(&hash_keys);
 
-- 
2.17.1


^ permalink raw reply related

* [PATCH net-next 3/3] selftests: forwarding: Test multipath hashing on inner IP pkts for GRE tunnel
From: Stephen Suryaputra @ 2019-07-03 15:19 UTC (permalink / raw)
  To: netdev; +Cc: idosch, nikolay, dsahern, Stephen Suryaputra
In-Reply-To: <20190703151934.9567-1-ssuryaextr@gmail.com>

Add selftest scripts for multipath hashing on inner IP pkts when there
is a single GRE tunnel but there are multiple underlay routes to reach
the other end of the tunnel.

Four cases are covered in these scripts:
    - IPv4 over GRE over IPv4
    - IPv6 over GRE over IPv4
    - IPv4 over GRE over IPv6
    - IPv6 over GRE over IPv6

Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
---
 .../net/forwarding/gre_inner_v4_multipath.sh  | 305 +++++++++++++++++
 .../net/forwarding/gre_inner_v6_multipath.sh  | 306 ++++++++++++++++++
 .../forwarding/ip6gre_inner_v4_multipath.sh   | 304 +++++++++++++++++
 .../forwarding/ip6gre_inner_v6_multipath.sh   | 305 +++++++++++++++++
 4 files changed, 1220 insertions(+)
 create mode 100755 tools/testing/selftests/net/forwarding/gre_inner_v4_multipath.sh
 create mode 100755 tools/testing/selftests/net/forwarding/gre_inner_v6_multipath.sh
 create mode 100755 tools/testing/selftests/net/forwarding/ip6gre_inner_v4_multipath.sh
 create mode 100755 tools/testing/selftests/net/forwarding/ip6gre_inner_v6_multipath.sh

diff --git a/tools/testing/selftests/net/forwarding/gre_inner_v4_multipath.sh b/tools/testing/selftests/net/forwarding/gre_inner_v4_multipath.sh
new file mode 100755
index 000000000000..4b2ef8a5715f
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/gre_inner_v4_multipath.sh
@@ -0,0 +1,305 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# Test traffic distribution when there are multiple routes between a GRE over
+# IPv4 tunnel. The tunnel carries IPv4 traffic between multiple hosts.
+# Multiple routes are in the underlay network. With the default multipath
+# policy, SW2 will only look at the outer IP addresses, hence only a single
+# route would be used.
+#
+# +-------------------------+
+# | H1                      |
+# |               $h1 +     |
+# | 192.0.3.{2-62}/24 |     |
+# +-------------------|-----+
+#                     |
+# +-------------------|------------------------+
+# | SW1               |                        |
+# |              $ol1 +                        |
+# |      192.0.3.1/24                          |
+# |                                            |
+# |  + g1 (gre)                                |
+# |    loc=192.0.2.65                          |
+# |    rem=192.0.2.66 --.                      |
+# |    tos=inherit      |                      |
+# |                     v                      |
+# |                     + $ul1                 |
+# |                     | 192.0.2.129/28       |
+# +---------------------|----------------------+
+#                       |
+# +---------------------|----------------------+
+# | SW2                 |                      |
+# |               $ul21 +                      |
+# |      192.0.2.130/28                        |
+# |                   |                        |
+# !   ________________|_____                   |
+# |  /                      \                  |
+# |  |                      |                  |
+# |  + $ul22.111 (vlan)     + $ul22.222 (vlan) |
+# |  | 192.0.2.145/28       | 192.0.2.161/28   |
+# |  |                      |                  |
+# +--|----------------------|------------------+
+#    |                      |
+# +--|----------------------|------------------+
+# |  |                      |                  |
+# |  + $ul32.111 (vlan)     + $ul32.222 (vlan) |
+# |  | 192.0.2.146/28       | 192.0.2.162/28   |
+# |  |                      |                  |
+# |  \______________________/                  |
+# |                   |                        |
+# |                   |                        |
+# |               $ul31 +                      |
+# |      192.0.2.177/28 |                  SW3 |
+# +---------------------|----------------------+
+#                       |
+# +---------------------|----------------------+
+# |                     + $ul4                 |
+# |                     ^ 192.0.2.178/28       |
+# |                     |                      |
+# |  + g2 (gre)         |                      |
+# |    loc=192.0.2.66   |                      |
+# |    rem=192.0.2.65 --'                      |
+# |    tos=inherit                             |
+# |                                            |
+# |               $ol4 +                       |
+# |       192.0.4.1/24 |                   SW4 |
+# +--------------------|-----------------------+
+#                      |
+# +--------------------|---------+
+# |                    |         |
+# |                $h2 +         |
+# |  192.0.4.{2-62}/24        H2 |
+# +------------------------------+
+
+ALL_TESTS="
+	ping_ipv4
+	multipath_ipv4
+"
+
+NUM_NETIFS=10
+source lib.sh
+
+h1_create()
+{
+	simple_if_init $h1 192.0.3.2/24
+	ip route add vrf v$h1 192.0.4.0/24 via 192.0.3.1
+}
+
+h1_destroy()
+{
+	ip route del vrf v$h1 192.0.4.0/24 via 192.0.3.1
+	simple_if_fini $h1 192.0.3.2/24
+}
+
+sw1_create()
+{
+	simple_if_init $ol1 192.0.3.1/24
+	__simple_if_init $ul1 v$ol1 192.0.2.129/28
+
+	tunnel_create g1 gre 192.0.2.65 192.0.2.66 tos inherit dev v$ol1
+	__simple_if_init g1 v$ol1 192.0.2.65/32
+	ip route add vrf v$ol1 192.0.2.66/32 via 192.0.2.130
+
+	ip route add vrf v$ol1 192.0.4.0/24 nexthop dev g1
+}
+
+sw1_destroy()
+{
+	ip route del vrf v$ol1 192.0.4.0/24
+
+	ip route del vrf v$ol1 192.0.2.66/32
+	__simple_if_fini g1 192.0.2.65/32
+	tunnel_destroy g1
+
+	__simple_if_fini $ul1 192.0.2.129/28
+	simple_if_fini $ol1 192.0.3.1/24
+}
+
+sw2_create()
+{
+	simple_if_init $ul21 192.0.2.130/28
+	__simple_if_init $ul22 v$ul21
+	vlan_create $ul22 111 v$ul21 192.0.2.145/28
+	vlan_create $ul22 222 v$ul21 192.0.2.161/28
+
+	ip route add vrf v$ul21 192.0.2.65/32 via 192.0.2.129
+	ip route add vrf v$ul21 192.0.2.66/32 \
+	   nexthop via 192.0.2.146 \
+	   nexthop via 192.0.2.162
+}
+
+sw2_destroy()
+{
+	ip route del vrf v$ul21 192.0.2.66/32
+	ip route del vrf v$ul21 192.0.2.65/32
+
+	vlan_destroy $ul22 222
+	vlan_destroy $ul22 111
+	__simple_if_fini $ul22
+	simple_if_fini $ul21 192.0.2.130/28
+}
+
+sw3_create()
+{
+	simple_if_init $ul31 192.0.2.177/28
+	__simple_if_init $ul32 v$ul31
+	vlan_create $ul32 111 v$ul31 192.0.2.146/28
+	vlan_create $ul32 222 v$ul31 192.0.2.162/28
+
+	ip route add vrf v$ul31 192.0.2.66/32 via 192.0.2.178
+	ip route add vrf v$ul31 192.0.2.65/32 \
+	   nexthop via 192.0.2.145 \
+	   nexthop via 192.0.2.161
+
+	tc qdisc add dev $ul32 clsact
+	tc filter add dev $ul32 ingress pref 111 prot 802.1Q \
+	   flower vlan_id 111 action pass
+	tc filter add dev $ul32 ingress pref 222 prot 802.1Q \
+	   flower vlan_id 222 action pass
+}
+
+sw3_destroy()
+{
+	tc qdisc del dev $ul32 clsact
+
+	ip route del vrf v$ul31 192.0.2.65/32
+	ip route del vrf v$ul31 192.0.2.66/32
+
+	vlan_destroy $ul32 222
+	vlan_destroy $ul32 111
+	__simple_if_fini $ul32
+	simple_if_fini $ul31 192.0.2.177/28
+}
+
+sw4_create()
+{
+	simple_if_init $ol4 192.0.4.1/24
+	__simple_if_init $ul4 v$ol4 192.0.2.178/28
+
+	tunnel_create g2 gre 192.0.2.66 192.0.2.65 tos inherit dev v$ol4
+	__simple_if_init g2 v$ol4 192.0.2.66/32
+	ip route add vrf v$ol4 192.0.2.65/32 via 192.0.2.177
+
+	ip route add vrf v$ol4 192.0.3.0/24 nexthop dev g2
+}
+
+sw4_destroy()
+{
+	ip route del vrf v$ol4 192.0.3.0/24
+
+	ip route del vrf v$ol4 192.0.2.65/32
+	__simple_if_fini g2 192.0.2.66/32
+	tunnel_destroy g2
+
+	__simple_if_fini $ul4 192.0.2.178/28
+	simple_if_fini $ol4 192.0.4.1/24
+}
+
+h2_create()
+{
+	simple_if_init $h2 192.0.4.2/24
+	ip route add vrf v$h2 192.0.3.0/24 via 192.0.4.1
+}
+
+h2_destroy()
+{
+	ip route del vrf v$h2 192.0.3.0/24 via 192.0.4.1
+	simple_if_fini $h2 192.0.4.2/24
+}
+
+setup_prepare()
+{
+	h1=${NETIFS[p1]}
+
+	ol1=${NETIFS[p2]}
+	ul1=${NETIFS[p3]}
+
+	ul21=${NETIFS[p4]}
+	ul22=${NETIFS[p5]}
+
+	ul32=${NETIFS[p6]}
+	ul31=${NETIFS[p7]}
+
+	ul4=${NETIFS[p8]}
+	ol4=${NETIFS[p9]}
+
+	h2=${NETIFS[p10]}
+
+	vrf_prepare
+	h1_create
+	sw1_create
+	sw2_create
+	sw3_create
+	sw4_create
+	h2_create
+
+	forwarding_enable
+}
+
+cleanup()
+{
+	pre_cleanup
+
+	forwarding_restore
+
+	h2_destroy
+	sw4_destroy
+	sw3_destroy
+	sw2_destroy
+	sw1_destroy
+	h1_destroy
+	vrf_cleanup
+}
+
+multipath4_test()
+{
+	local what=$1; shift
+	local weight1=$1; shift
+	local weight2=$1; shift
+
+	sysctl_set net.ipv4.fib_multipath_hash_policy 2
+	ip route replace vrf v$ul21 192.0.2.66/32 \
+	   nexthop via 192.0.2.146 weight $weight1 \
+	   nexthop via 192.0.2.162 weight $weight2
+
+	local t0_111=$(tc_rule_stats_get $ul32 111 ingress)
+	local t0_222=$(tc_rule_stats_get $ul32 222 ingress)
+
+	ip vrf exec v$h1 \
+	   $MZ $h1 -q -p 64 -A "192.0.3.2-192.0.3.62" -B "192.0.4.2-192.0.4.62" \
+	       -d 1msec -c 50 -t udp "sp=1024,dp=1024"
+	sleep 1
+
+	local t1_111=$(tc_rule_stats_get $ul32 111 ingress)
+	local t1_222=$(tc_rule_stats_get $ul32 222 ingress)
+
+	local d111=$((t1_111 - t0_111))
+	local d222=$((t1_222 - t0_222))
+	multipath_eval "$what" $weight1 $weight2 $d111 $d222
+
+	ip route replace vrf v$ul21 192.0.2.66/32 \
+	   nexthop via 192.0.2.146 \
+	   nexthop via 192.0.2.162
+	sysctl_restore net.ipv4.fib_multipath_hash_policy
+}
+
+ping_ipv4()
+{
+	ping_test $h1 192.0.4.2
+}
+
+multipath_ipv4()
+{
+	log_info "Running IPv4 over GRE over IPv4 multipath tests"
+	multipath4_test "ECMP" 1 1
+	multipath4_test "Weighted MP 2:1" 2 1
+	multipath4_test "Weighted MP 11:45" 11 45
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+tests_run
+
+exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/gre_inner_v6_multipath.sh b/tools/testing/selftests/net/forwarding/gre_inner_v6_multipath.sh
new file mode 100755
index 000000000000..4557a4c6edac
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/gre_inner_v6_multipath.sh
@@ -0,0 +1,306 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# Test traffic distribution when there are multiple routes between a GRE over
+# IPv4 tunnel. The tunnel carries IPv6 traffic between multiple hosts.
+# Multiple routes are in the underlay network. With the default multipath
+# policy, SW2 will only look at the outer IP addresses, hence only a single
+# route would be used.
+#
+# +-------------------------+
+# | H1                      |
+# |               $h1 +     |
+# |  2001:db8:1::2/64 |     |
+# +-------------------|-----+
+#                     |
+# +-------------------|------------------------+
+# | SW1               |                        |
+# |              $ol1 +                        |
+# |  2001:db8:1::1/64                          |
+# |                                            |
+# |  + g1 (gre)                                |
+# |    loc=192.0.2.65                          |
+# |    rem=192.0.2.66 --.                      |
+# |    tos=inherit      |                      |
+# |                     v                      |
+# |                     + $ul1                 |
+# |                     | 192.0.2.129/28       |
+# +---------------------|----------------------+
+#                       |
+# +---------------------|----------------------+
+# | SW2                 |                      |
+# |               $ul21 +                      |
+# |      192.0.2.130/28                        |
+# |                   |                        |
+# !   ________________|_____                   |
+# |  /                      \                  |
+# |  |                      |                  |
+# |  + $ul22.111 (vlan)     + $ul22.222 (vlan) |
+# |  | 192.0.2.145/28       | 192.0.2.161/28   |
+# |  |                      |                  |
+# +--|----------------------|------------------+
+#    |                      |
+# +--|----------------------|------------------+
+# |  |                      |                  |
+# |  + $ul32.111 (vlan)     + $ul32.222 (vlan) |
+# |  | 192.0.2.146/28       | 192.0.2.162/28   |
+# |  |                      |                  |
+# |  \______________________/                  |
+# |                   |                        |
+# |                   |                        |
+# |               $ul31 +                      |
+# |      192.0.2.177/28 |                  SW3 |
+# +---------------------|----------------------+
+#                       |
+# +---------------------|----------------------+
+# |                     + $ul4                 |
+# |                     ^ 192.0.2.178/28       |
+# |                     |                      |
+# |  + g2 (gre)         |                      |
+# |    loc=192.0.2.66   |                      |
+# |    rem=192.0.2.65 --'                      |
+# |    tos=inherit                             |
+# |                                            |
+# |               $ol4 +                       |
+# |   2001:db8:2::1/64 |                   SW4 |
+# +--------------------|-----------------------+
+#                      |
+# +--------------------|---------+
+# |                    |         |
+# |                $h2 +         |
+# |   2001:db8:2::2/64        H2 |
+# +------------------------------+
+
+ALL_TESTS="
+	ping_ipv6
+	multipath_ipv6
+"
+
+NUM_NETIFS=10
+source lib.sh
+
+h1_create()
+{
+	simple_if_init $h1 2001:db8:1::2/64
+	ip -6 route add vrf v$h1 2001:db8:2::/64 via 2001:db8:1::1
+}
+
+h1_destroy()
+{
+	ip -6 route del vrf v$h1 2001:db8:2::/64 via 2001:db8:1::1
+	simple_if_fini $h1 2001:db8:1::2/64
+}
+
+sw1_create()
+{
+	simple_if_init $ol1 2001:db8:1::1/64
+	__simple_if_init $ul1 v$ol1 192.0.2.129/28
+
+	tunnel_create g1 gre 192.0.2.65 192.0.2.66 tos inherit dev v$ol1
+	__simple_if_init g1 v$ol1 192.0.2.65/32
+	ip route add vrf v$ol1 192.0.2.66/32 via 192.0.2.130
+
+	ip -6 route add vrf v$ol1 2001:db8:2::/64 dev g1
+}
+
+sw1_destroy()
+{
+	ip -6 route del vrf v$ol1 2001:db8:2::/64
+
+	ip route del vrf v$ol1 192.0.2.66/32
+	__simple_if_fini g1 192.0.2.65/32
+	tunnel_destroy g1
+
+	__simple_if_fini $ul1 192.0.2.129/28
+	simple_if_fini $ol1 2001:db8:1::1/64
+}
+
+sw2_create()
+{
+	simple_if_init $ul21 192.0.2.130/28
+	__simple_if_init $ul22 v$ul21
+	vlan_create $ul22 111 v$ul21 192.0.2.145/28
+	vlan_create $ul22 222 v$ul21 192.0.2.161/28
+
+	ip route add vrf v$ul21 192.0.2.65/32 via 192.0.2.129
+	ip route add vrf v$ul21 192.0.2.66/32 \
+	   nexthop via 192.0.2.146 \
+	   nexthop via 192.0.2.162
+}
+
+sw2_destroy()
+{
+	ip route del vrf v$ul21 192.0.2.66/32
+	ip route del vrf v$ul21 192.0.2.65/32
+
+	vlan_destroy $ul22 222
+	vlan_destroy $ul22 111
+	__simple_if_fini $ul22
+	simple_if_fini $ul21 192.0.2.130/28
+}
+
+sw3_create()
+{
+	simple_if_init $ul31 192.0.2.177/28
+	__simple_if_init $ul32 v$ul31
+	vlan_create $ul32 111 v$ul31 192.0.2.146/28
+	vlan_create $ul32 222 v$ul31 192.0.2.162/28
+
+	ip route add vrf v$ul31 192.0.2.66/32 via 192.0.2.178
+	ip route add vrf v$ul31 192.0.2.65/32 \
+	   nexthop via 192.0.2.145 \
+	   nexthop via 192.0.2.161
+
+	tc qdisc add dev $ul32 clsact
+	tc filter add dev $ul32 ingress pref 111 prot 802.1Q \
+	   flower vlan_id 111 action pass
+	tc filter add dev $ul32 ingress pref 222 prot 802.1Q \
+	   flower vlan_id 222 action pass
+}
+
+sw3_destroy()
+{
+	tc qdisc del dev $ul32 clsact
+
+	ip route del vrf v$ul31 192.0.2.65/32
+	ip route del vrf v$ul31 192.0.2.66/32
+
+	vlan_destroy $ul32 222
+	vlan_destroy $ul32 111
+	__simple_if_fini $ul32
+	simple_if_fini $ul31 192.0.2.177/28
+}
+
+sw4_create()
+{
+	simple_if_init $ol4 2001:db8:2::1/64
+	__simple_if_init $ul4 v$ol4 192.0.2.178/28
+
+	tunnel_create g2 gre 192.0.2.66 192.0.2.65 tos inherit dev v$ol4
+	__simple_if_init g2 v$ol4 192.0.2.66/32
+	ip route add vrf v$ol4 192.0.2.65/32 via 192.0.2.177
+
+	ip -6 route add vrf v$ol4 2001:db8:1::/64 dev g2
+}
+
+sw4_destroy()
+{
+	ip -6 route del vrf v$ol4 2001:db8:1::/64
+
+	ip route del vrf v$ol4 192.0.2.65/32
+	__simple_if_fini g2 192.0.2.66/32
+	tunnel_destroy g2
+
+	__simple_if_fini $ul4 192.0.2.178/28
+	simple_if_fini $ol4 2001:db8:2::1/64
+}
+
+h2_create()
+{
+	simple_if_init $h2 2001:db8:2::2/64
+	ip -6 route add vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1
+}
+
+h2_destroy()
+{
+	ip -6 route del vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1
+	simple_if_fini $h2 2001:db8:2::2/64
+}
+
+setup_prepare()
+{
+	h1=${NETIFS[p1]}
+
+	ol1=${NETIFS[p2]}
+	ul1=${NETIFS[p3]}
+
+	ul21=${NETIFS[p4]}
+	ul22=${NETIFS[p5]}
+
+	ul32=${NETIFS[p6]}
+	ul31=${NETIFS[p7]}
+
+	ul4=${NETIFS[p8]}
+	ol4=${NETIFS[p9]}
+
+	h2=${NETIFS[p10]}
+
+	vrf_prepare
+	h1_create
+	sw1_create
+	sw2_create
+	sw3_create
+	sw4_create
+	h2_create
+
+	forwarding_enable
+}
+
+cleanup()
+{
+	pre_cleanup
+
+	forwarding_restore
+
+	h2_destroy
+	sw4_destroy
+	sw3_destroy
+	sw2_destroy
+	sw1_destroy
+	h1_destroy
+	vrf_cleanup
+}
+
+multipath6_test()
+{
+	local what=$1; shift
+	local weight1=$1; shift
+	local weight2=$1; shift
+
+	sysctl_set net.ipv4.fib_multipath_hash_policy 2
+	ip route replace vrf v$ul21 192.0.2.66/32 \
+	   nexthop via 192.0.2.146 weight $weight1 \
+	   nexthop via 192.0.2.162 weight $weight2
+
+	local t0_111=$(tc_rule_stats_get $ul32 111 ingress)
+	local t0_222=$(tc_rule_stats_get $ul32 222 ingress)
+
+	ip vrf exec v$h1 \
+	   $MZ $h1 -6 -q -p 64 -A "2001:db8:1::2-2001:db8:1::1e" \
+	       -B "2001:db8:2::2-2001:db8:2::1e" \
+	       -d 1msec -c 50 -t udp "sp=1024,dp=1024"
+	sleep 1
+
+	local t1_111=$(tc_rule_stats_get $ul32 111 ingress)
+	local t1_222=$(tc_rule_stats_get $ul32 222 ingress)
+
+	local d111=$((t1_111 - t0_111))
+	local d222=$((t1_222 - t0_222))
+	multipath_eval "$what" $weight1 $weight2 $d111 $d222
+
+	ip route replace vrf v$ul21 192.0.2.66/32 \
+	   nexthop via 192.0.2.146 \
+	   nexthop via 192.0.2.162
+	sysctl_restore net.ipv4.fib_multipath_hash_policy
+}
+
+ping_ipv6()
+{
+	ping_test $h1 2001:db8:2::2
+}
+
+multipath_ipv6()
+{
+	log_info "Running IPv6 over GRE over IPv4 multipath tests"
+	multipath6_test "ECMP" 1 1
+	multipath6_test "Weighted MP 2:1" 2 1
+	multipath6_test "Weighted MP 11:45" 11 45
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+tests_run
+
+exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/ip6gre_inner_v4_multipath.sh b/tools/testing/selftests/net/forwarding/ip6gre_inner_v4_multipath.sh
new file mode 100755
index 000000000000..ca4f383d6492
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/ip6gre_inner_v4_multipath.sh
@@ -0,0 +1,304 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# Test traffic distribution when there are multiple routes between a GRE over
+# IPv6 tunnel. The tunnel carries IPv4 traffic between multiple hosts.
+# Multiple routes are in the underlay network. With the default multipath
+# policy, SW2 will only look at the outer IP addresses, hence only a single
+# route would be used.
+#
+# +-------------------------+
+# | H1                      |
+# |               $h1 +     |
+# | 192.0.3.{2-62}/24 |     |
+# +-------------------|-----+
+#                     |
+# +-------------------|-------------------------+
+# | SW1               |                         |
+# |              $ol1 +                         |
+# |      192.0.3.1/24                           |
+# |                                             |
+# |  + g1 (gre)                                 |
+# |    loc=2001:db8:40::1                       |
+# |    rem=2001:db8:40::2 --.                   |
+# |    tos=inherit          |                   |
+# |                         v                   |
+# |                         + $ul1              |
+# |                         | 2001:db8:80::1/64 |
+# +-------------------------|-------------------+
+#                           |
+# +-------------------------|-------------------+
+# | SW2                     |                   |
+# |                   $ul21 +                   |
+# |       2001:db8:80::2/64                     |
+# |                   |                         |
+# !   ________________|_____                    |
+# |  /                      \                   |
+# |  |                      |                   |
+# |  + $ul22.111 (vlan)     + $ul22.222 (vlan)  |
+# |  | 2001:db8:81::1/64    | 2001:db8:82::1/64 |
+# |  |                      |                   |
+# +--|----------------------|-------------------+
+#    |                      |
+# +--|----------------------|-------------------+
+# |  |                      |                   |
+# |  + $ul32.111 (vlan)     + $ul32.222 (vlan)  |
+# |  | 2001:db8:81::2/64    | 2001:db8:82::2/64 |
+# |  |                      |                   |
+# |  \______________________/                   |
+# |                   |                         |
+# |                   |                         |
+# |                   $ul31 +                   |
+# |       2001:db8:83::2/64 |               SW3 |
+# +-------------------------|-------------------+
+#                           |
+# +-------------------------|-------------------+
+# |                         + $ul4              |
+# |                         ^ 2001:db8:83::1/64 |
+# |  + g2 (gre)             |                   |
+# |    loc=2001:db8:40::2   |                   |
+# |    rem=2001:db8:40::1 --'                   |
+# |    tos=inherit                              |
+# |                                             |
+# |               $ol4 +                        |
+# |       192.0.4.1/24 |                    SW4 |
+# +--------------------|------------------------+
+#                      |
+# +--------------------|---------+
+# |                    |         |
+# |                $h2 +         |
+# |  192.0.4.{2-62}/24        H2 |
+# +------------------------------+
+
+ALL_TESTS="
+	ping_ipv4
+	multipath_ipv4
+"
+
+NUM_NETIFS=10
+source lib.sh
+
+h1_create()
+{
+	simple_if_init $h1 192.0.3.2/24
+	ip route add vrf v$h1 192.0.4.0/24 via 192.0.3.1
+}
+
+h1_destroy()
+{
+	ip route del vrf v$h1 192.0.4.0/24 via 192.0.3.1
+	simple_if_fini $h1 192.0.3.2/24
+}
+
+sw1_create()
+{
+	simple_if_init $ol1 192.0.3.1/24
+	__simple_if_init $ul1 v$ol1 2001:db8:80::1/64
+
+	tunnel_create g1 ip6gre 2001:db8:40::1 2001:db8:40::2 tos inherit dev v$ol1
+	__simple_if_init g1 v$ol1 2001:db8:40::1/128
+	ip -6 route add vrf v$ol1 2001:db8:40::2/128 via 2001:db8:80::2
+
+	ip route add vrf v$ol1 192.0.4.0/24 nexthop dev g1
+}
+
+sw1_destroy()
+{
+	ip route del vrf v$ol1 192.0.4.0/24
+
+	ip -6 route del vrf v$ol1 2001:db8:40::2/128
+	__simple_if_fini g1 2001:db8:40::1/128
+	tunnel_destroy g1
+
+	__simple_if_fini $ul1 2001:db8:80::1/64
+	simple_if_fini $ol1 192.0.3.1/24
+}
+
+sw2_create()
+{
+	simple_if_init $ul21 2001:db8:80::2/64
+	__simple_if_init $ul22 v$ul21
+	vlan_create $ul22 111 v$ul21 2001:db8:81::1/64
+	vlan_create $ul22 222 v$ul21 2001:db8:82::1/64
+
+	ip -6 route add vrf v$ul21 2001:db8:40::1/128 via 2001:db8:80::1
+	ip -6 route add vrf v$ul21 2001:db8:40::2/128 \
+	   nexthop via 2001:db8:81::2 \
+	   nexthop via 2001:db8:82::2
+}
+
+sw2_destroy()
+{
+	ip -6 route del vrf v$ul21 2001:db8:40::2/128
+	ip -6 route del vrf v$ul21 2001:db8:40::1/128
+
+	vlan_destroy $ul22 222
+	vlan_destroy $ul22 111
+	__simple_if_fini $ul22
+	simple_if_fini $ul21 2001:db8:80::2/64
+}
+
+sw3_create()
+{
+	simple_if_init $ul31 2001:db8:83::2/64
+	__simple_if_init $ul32 v$ul31
+	vlan_create $ul32 111 v$ul31 2001:db8:81::2/64
+	vlan_create $ul32 222 v$ul31 2001:db8:82::2/64
+
+	ip -6 route add vrf v$ul31 2001:db8:40::2/128 via 2001:db8:83::1
+	ip -6 route add vrf v$ul31 2001:db8:40::1/128 \
+	   nexthop via 2001:db8:81::1 \
+	   nexthop via 2001:db8:82::1
+
+	tc qdisc add dev $ul32 clsact
+	tc filter add dev $ul32 ingress pref 111 prot 802.1Q \
+	   flower vlan_id 111 action pass
+	tc filter add dev $ul32 ingress pref 222 prot 802.1Q \
+	   flower vlan_id 222 action pass
+}
+
+sw3_destroy()
+{
+	tc qdisc del dev $ul32 clsact
+
+	ip -6 route del vrf v$ul31 2001:db8:40::1/128
+	ip -6 route del vrf v$ul31 2001:db8:40::2/128
+
+	vlan_destroy $ul32 222
+	vlan_destroy $ul32 111
+	__simple_if_fini $ul32
+	simple_if_fini $ul31 2001:Db8:83::2/64
+}
+
+sw4_create()
+{
+	simple_if_init $ol4 192.0.4.1/24
+	__simple_if_init $ul4 v$ol4 2001:db8:83::1/64
+
+	tunnel_create g2 ip6gre 2001:db8:40::2 2001:db8:40::1 tos inherit dev v$ol4
+	__simple_if_init g2 v$ol4 2001:db8:40::2/128
+	ip -6 route add vrf v$ol4 2001:db8:40::1/128 via 2001:db8:83::2
+
+	ip route add vrf v$ol4 192.0.3.0/24 nexthop dev g2
+}
+
+sw4_destroy()
+{
+	ip route del vrf v$ol4 192.0.3.0/24
+
+	ip -6 route del vrf v$ol4 2001:db8:40::1/128
+	__simple_if_fini g2 2001:db8:40::2/128
+	tunnel_destroy g2
+
+	__simple_if_fini $ul4 2001:db8:83::1/64
+	simple_if_fini $ol4 192.0.4.1/24
+}
+
+h2_create()
+{
+	simple_if_init $h2 192.0.4.2/24
+	ip route add vrf v$h2 192.0.3.0/24 via 192.0.4.1
+}
+
+h2_destroy()
+{
+	ip route del vrf v$h2 192.0.3.0/24 via 192.0.4.1
+	simple_if_fini $h2 192.0.4.2/24
+}
+
+setup_prepare()
+{
+	h1=${NETIFS[p1]}
+
+	ol1=${NETIFS[p2]}
+	ul1=${NETIFS[p3]}
+
+	ul21=${NETIFS[p4]}
+	ul22=${NETIFS[p5]}
+
+	ul32=${NETIFS[p6]}
+	ul31=${NETIFS[p7]}
+
+	ul4=${NETIFS[p8]}
+	ol4=${NETIFS[p9]}
+
+	h2=${NETIFS[p10]}
+
+	vrf_prepare
+	h1_create
+	sw1_create
+	sw2_create
+	sw3_create
+	sw4_create
+	h2_create
+
+	forwarding_enable
+}
+
+cleanup()
+{
+	pre_cleanup
+
+	forwarding_restore
+
+	h2_destroy
+	sw4_destroy
+	sw3_destroy
+	sw2_destroy
+	sw1_destroy
+	h1_destroy
+	vrf_cleanup
+}
+
+multipath4_test()
+{
+	local what=$1; shift
+	local weight1=$1; shift
+	local weight2=$1; shift
+
+	sysctl_set net.ipv6.fib_multipath_hash_policy 2
+	ip route replace vrf v$ul21 2001:db8:40::2/128 \
+	   nexthop via 2001:db8:81::2 weight $weight1 \
+	   nexthop via 2001:db8:82::2 weight $weight2
+
+	local t0_111=$(tc_rule_stats_get $ul32 111 ingress)
+	local t0_222=$(tc_rule_stats_get $ul32 222 ingress)
+
+	ip vrf exec v$h1 \
+	   $MZ $h1 -q -p 64 -A "192.0.3.2-192.0.3.62" -B "192.0.4.2-192.0.4.62" \
+	       -d 1msec -c 50 -t udp "sp=1024,dp=1024"
+	sleep 1
+
+	local t1_111=$(tc_rule_stats_get $ul32 111 ingress)
+	local t1_222=$(tc_rule_stats_get $ul32 222 ingress)
+
+	local d111=$((t1_111 - t0_111))
+	local d222=$((t1_222 - t0_222))
+	multipath_eval "$what" $weight1 $weight2 $d111 $d222
+
+	ip route replace vrf v$ul21 2001:db8:40::2/128 \
+	   nexthop via 2001:db8:81::2 \
+	   nexthop via 2001:db8:82::2
+	sysctl_restore net.ipv6.fib_multipath_hash_policy
+}
+
+ping_ipv4()
+{
+	ping_test $h1 192.0.4.2
+}
+
+multipath_ipv4()
+{
+	log_info "Running IPv4 over GRE over IPv6 multipath tests"
+	multipath4_test "ECMP" 1 1
+	multipath4_test "Weighted MP 2:1" 2 1
+	multipath4_test "Weighted MP 11:45" 11 45
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+tests_run
+
+exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/ip6gre_inner_v6_multipath.sh b/tools/testing/selftests/net/forwarding/ip6gre_inner_v6_multipath.sh
new file mode 100755
index 000000000000..c167acd33cb5
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/ip6gre_inner_v6_multipath.sh
@@ -0,0 +1,305 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# Test traffic distribution when there are multiple routes between a GRE over
+# IPv6 tunnel. The tunnel carries IPv6 traffic between multiple hosts.
+# Multiple routes are in the underlay network. With the default multipath
+# policy, SW2 will only look at the outer IP addresses, hence only a single
+# route would be used.
+#
+# +-------------------------+
+# | H1                      |
+# |               $h1 +     |
+# |  2001:db8:1::2/64 |     |
+# +-------------------|-----+
+#                     |
+# +-------------------|-------------------------+
+# | SW1               |                         |
+# |              $ol1 +                         |
+# |  2001:db8:1::1/64                           |
+# |                                             |
+# |  + g1 (gre)                                 |
+# |    loc=2001:db8:40::1                       |
+# |    rem=2001:db8:40::2 --.                   |
+# |    tos=inherit          |                   |
+# |                         v                   |
+# |                         + $ul1              |
+# |                         | 2001:db8:80::1/64 |
+# +-------------------------|-------------------+
+#                           |
+# +-------------------------|-------------------+
+# | SW2                     |                   |
+# |                   $ul21 +                   |
+# |       2001:db8:80::2/64                     |
+# |                   |                         |
+# !   ________________|_____                    |
+# |  /                      \                   |
+# |  |                      |                   |
+# |  + $ul22.111 (vlan)     + $ul22.222 (vlan)  |
+# |  | 2001:db8:81::1/64    | 2001:db8:82::1/64 |
+# |  |                      |                   |
+# +--|----------------------|-------------------+
+#    |                      |
+# +--|----------------------|-------------------+
+# |  |                      |                   |
+# |  + $ul32.111 (vlan)     + $ul32.222 (vlan)  |
+# |  | 2001:db8:81::2/64    | 2001:db8:82::2/64 |
+# |  |                      |                   |
+# |  \______________________/                   |
+# |                   |                         |
+# |                   |                         |
+# |                   $ul31 +                   |
+# |       2001:db8:83::2/64 |               SW3 |
+# +-------------------------|-------------------+
+#                           |
+# +-------------------------|-------------------+
+# |                         + $ul4              |
+# |                         ^ 2001:db8:83::1/64 |
+# |  + g2 (gre)             |                   |
+# |    loc=2001:db8:40::2   |                   |
+# |    rem=2001:db8:40::1 --'                   |
+# |    tos=inherit                              |
+# |                                             |
+# |               $ol4 +                        |
+# |   2001:db8:2::1/64 |                    SW4 |
+# +--------------------|------------------------+
+#                      |
+# +--------------------|---------+
+# |                    |         |
+# |                $h2 +         |
+# |   2001:db8:2::2/64        H2 |
+# +------------------------------+
+
+ALL_TESTS="
+	ping_ipv6
+	multipath_ipv6
+"
+
+NUM_NETIFS=10
+source lib.sh
+
+h1_create()
+{
+	simple_if_init $h1 2001:db8:1::2/64
+	ip -6 route add vrf v$h1 2001:db8:2::/64 via 2001:db8:1::1
+}
+
+h1_destroy()
+{
+	ip -6 route del vrf v$h1 2001:db8:2::/64 via 2001:db8:1::1
+	simple_if_fini $h1 2001:db8:1::2/64
+}
+
+sw1_create()
+{
+	simple_if_init $ol1 2001:db8:1::1/64
+	__simple_if_init $ul1 v$ol1 2001:db8:80::1/64
+
+	tunnel_create g1 ip6gre 2001:db8:40::1 2001:db8:40::2 tos inherit dev v$ol1
+	__simple_if_init g1 v$ol1 2001:db8:40::1/128
+	ip -6 route add vrf v$ol1 2001:db8:40::2/128 via 2001:db8:80::2
+
+	ip -6 route add vrf v$ol1 2001:db8:2::/64 dev g1
+}
+
+sw1_destroy()
+{
+	ip -6 route del vrf v$ol1 2001:db8:2::/64
+
+	ip -6 route del vrf v$ol1 2001:db8:40::2/128
+	__simple_if_fini g1 2001:db8:40::1/128
+	tunnel_destroy g1
+
+	__simple_if_fini $ul1 2001:db8:80::1/64
+	simple_if_fini $ol1 2001:db8:1::1/64
+}
+
+sw2_create()
+{
+	simple_if_init $ul21 2001:db8:80::2/64
+	__simple_if_init $ul22 v$ul21
+	vlan_create $ul22 111 v$ul21 2001:db8:81::1/64
+	vlan_create $ul22 222 v$ul21 2001:db8:82::1/64
+
+	ip -6 route add vrf v$ul21 2001:db8:40::1/128 via 2001:db8:80::1
+	ip -6 route add vrf v$ul21 2001:db8:40::2/128 \
+	   nexthop via 2001:db8:81::2 \
+	   nexthop via 2001:db8:82::2
+}
+
+sw2_destroy()
+{
+	ip -6 route del vrf v$ul21 2001:db8:40::2/128
+	ip -6 route del vrf v$ul21 2001:db8:40::1/128
+
+	vlan_destroy $ul22 222
+	vlan_destroy $ul22 111
+	__simple_if_fini $ul22
+	simple_if_fini $ul21 2001:db8:80::2/64
+}
+
+sw3_create()
+{
+	simple_if_init $ul31 2001:db8:83::2/64
+	__simple_if_init $ul32 v$ul31
+	vlan_create $ul32 111 v$ul31 2001:db8:81::2/64
+	vlan_create $ul32 222 v$ul31 2001:db8:82::2/64
+
+	ip -6 route add vrf v$ul31 2001:db8:40::2/128 via 2001:db8:83::1
+	ip -6 route add vrf v$ul31 2001:db8:40::1/128 \
+	   nexthop via 2001:db8:81::1 \
+	   nexthop via 2001:db8:82::1
+
+	tc qdisc add dev $ul32 clsact
+	tc filter add dev $ul32 ingress pref 111 prot 802.1Q \
+	   flower vlan_id 111 action pass
+	tc filter add dev $ul32 ingress pref 222 prot 802.1Q \
+	   flower vlan_id 222 action pass
+}
+
+sw3_destroy()
+{
+	tc qdisc del dev $ul32 clsact
+
+	ip -6 route del vrf v$ul31 2001:db8:40::1/128
+	ip -6 route del vrf v$ul31 2001:db8:40::2/128
+
+	vlan_destroy $ul32 222
+	vlan_destroy $ul32 111
+	__simple_if_fini $ul32
+	simple_if_fini $ul31 2001:Db8:83::2/64
+}
+
+sw4_create()
+{
+	simple_if_init $ol4 2001:db8:2::1/64
+	__simple_if_init $ul4 v$ol4 2001:db8:83::1/64
+
+	tunnel_create g2 ip6gre 2001:db8:40::2 2001:db8:40::1 tos inherit dev v$ol4
+	__simple_if_init g2 v$ol4 2001:db8:40::2/128
+	ip -6 route add vrf v$ol4 2001:db8:40::1/128 via 2001:db8:83::2
+
+	ip -6 route add vrf v$ol4 2001:db8:1::/64 dev g2
+}
+
+sw4_destroy()
+{
+	ip -6 route del vrf v$ol4 2001:db8:1::/64
+
+	ip -6 route del vrf v$ol4 2001:db8:40::1/128
+	__simple_if_fini g2 2001:db8:40::2/128
+	tunnel_destroy g2
+
+	__simple_if_fini $ul4 2001:db8:83::1/64
+	simple_if_fini $ol4 2001:db8:2::1/64
+}
+
+h2_create()
+{
+	simple_if_init $h2 2001:db8:2::2/64
+	ip -6 route add vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1
+}
+
+h2_destroy()
+{
+	ip -6 route del vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1
+	simple_if_fini $h2 2001:db8:2::2/64
+}
+
+setup_prepare()
+{
+	h1=${NETIFS[p1]}
+
+	ol1=${NETIFS[p2]}
+	ul1=${NETIFS[p3]}
+
+	ul21=${NETIFS[p4]}
+	ul22=${NETIFS[p5]}
+
+	ul32=${NETIFS[p6]}
+	ul31=${NETIFS[p7]}
+
+	ul4=${NETIFS[p8]}
+	ol4=${NETIFS[p9]}
+
+	h2=${NETIFS[p10]}
+
+	vrf_prepare
+	h1_create
+	sw1_create
+	sw2_create
+	sw3_create
+	sw4_create
+	h2_create
+
+	forwarding_enable
+}
+
+cleanup()
+{
+	pre_cleanup
+
+	forwarding_restore
+
+	h2_destroy
+	sw4_destroy
+	sw3_destroy
+	sw2_destroy
+	sw1_destroy
+	h1_destroy
+	vrf_cleanup
+}
+
+multipath6_test()
+{
+	local what=$1; shift
+	local weight1=$1; shift
+	local weight2=$1; shift
+
+	sysctl_set net.ipv6.fib_multipath_hash_policy 2
+	ip route replace vrf v$ul21 2001:db8:40::2/128 \
+	   nexthop via 2001:db8:81::2 weight $weight1 \
+	   nexthop via 2001:db8:82::2 weight $weight2
+
+	local t0_111=$(tc_rule_stats_get $ul32 111 ingress)
+	local t0_222=$(tc_rule_stats_get $ul32 222 ingress)
+
+	ip vrf exec v$h1 \
+	   $MZ $h1 -6 -q -p 64 -A "2001:db8:1::2-2001:db8:1::1e" \
+	       -B "2001:db8:2::2-2001:db8:2::1e" \
+	       -d 1msec -c 50 -t udp "sp=1024,dp=1024"
+	sleep 1
+
+	local t1_111=$(tc_rule_stats_get $ul32 111 ingress)
+	local t1_222=$(tc_rule_stats_get $ul32 222 ingress)
+
+	local d111=$((t1_111 - t0_111))
+	local d222=$((t1_222 - t0_222))
+	multipath_eval "$what" $weight1 $weight2 $d111 $d222
+
+	ip route replace vrf v$ul21 2001:db8:40::2/128 \
+	   nexthop via 2001:db8:81::2 \
+	   nexthop via 2001:db8:82::2
+	sysctl_restore net.ipv6.fib_multipath_hash_policy
+}
+
+ping_ipv6()
+{
+	ping_test $h1 2001:db8:2::2
+}
+
+multipath_ipv6()
+{
+	log_info "Running IPv6 over GRE over IPv6 multipath tests"
+	multipath6_test "ECMP" 1 1
+	multipath6_test "Weighted MP 2:1" 2 1
+	multipath6_test "Weighted MP 11:45" 11 45
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+tests_run
+
+exit $EXIT_STATUS
-- 
2.17.1


^ permalink raw reply related

* Re: kernel panic: corrupted stack end in dput
From: Al Viro @ 2019-07-03 15:23 UTC (permalink / raw)
  To: Hillf Danton
  Cc: syzbot, linux-fsdevel@vger.kernel.org,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	syzkaller-bugs@googlegroups.com
In-Reply-To: <20190703144000.GH17978@ZenIV.linux.org.uk>

On Wed, Jul 03, 2019 at 03:40:00PM +0100, Al Viro wrote:
> On Wed, Jul 03, 2019 at 02:43:07PM +0800, Hillf Danton wrote:
> 
> > > This is very much *NOT* fine.
> > > 	1) trylock can fail from any number of reasons, starting
> > > with "somebody is going through the hash chain doing a lookup on
> > > something completely unrelated"
> > 
> > They are also a red light that we need to bail out of spiraling up
> > the directory hierarchy imho.
> 
> Translation: "let's leak the reference to parent, shall we?"
> 
> > > 	2) whoever had been holding the lock and whatever they'd
> > > been doing might be over right after we get the return value from
> > > spin_trylock().
> > 
> > Or after we send a mail using git. I don't know.
> > 
> > > 	3) even had that been really somebody adding children in
> > > the same parent *AND* even if they really kept doing that, rather
> > > than unlocking and buggering off, would you care to explain why
> > > dentry_unlist() called by __dentry_kill() and removing the victim
> > > from the list of children would be safe to do in parallel with that?
> > >
> > My bad. I have to walk around that unsafety.
> 
> WHAT unsafety?  Can you explain what are you seeing and how to
> reproduce it, whatever it is?

BTW, what makes you think that it's something inside dput() itself?
All I see is that at some point in the beginning of the loop body
in dput() we observe a buggered stack.

Is that the first iteration through the loop?  IOW, is that just
the place where we first notice preexisting corruption, or is
that something the code called from that loop does?  If it's
a stack overflow, I would be very surprised to see it here -
dput() is iterative and it's called on a very shallow stack in
those traces.

What happens if you e.g. turn that
	dput(dentry);
in __fput() into
	rcu_read_lock(); rcu_read_unlock(); // trigger the check
	dput(dentry);

and run your reporducer?

^ permalink raw reply

* Re: [PATCH v2 1/4] net: dsa: Change DT bindings for Vitesse VSC73xx switches
From: Florian Fainelli @ 2019-07-03 15:26 UTC (permalink / raw)
  To: Pawel Dembicki
  Cc: linus.walleij, Andrew Lunn, Vivien Didelot, David S. Miller,
	Rob Herring, Mark Rutland, netdev, devicetree, linux-kernel
In-Reply-To: <20190703085757.1027-1-paweldembicki@gmail.com>



On 7/3/2019 1:57 AM, Pawel Dembicki wrote:
> This commit introduce how to use vsc73xx platform driver.
> 
> Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>

Pawel, please resubmit your patches starting a new thread, not as reply
to the existing ones, see
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/netdev-FAQ.rst#n134
for details. Also, David Miller typically likes to have a cover letter
for patch count > 1.

Thanks!

> ---
> Changes in v2:
> - Drop -spi and -platform suffix
> - Change commit message
> 
>  .../bindings/net/dsa/vitesse,vsc73xx.txt      | 57 +++++++++++++++++--
>  1 file changed, 53 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/dsa/vitesse,vsc73xx.txt b/Documentation/devicetree/bindings/net/dsa/vitesse,vsc73xx.txt
> index ed4710c40641..c55e0148657d 100644
> --- a/Documentation/devicetree/bindings/net/dsa/vitesse,vsc73xx.txt
> +++ b/Documentation/devicetree/bindings/net/dsa/vitesse,vsc73xx.txt
> @@ -2,8 +2,8 @@ Vitesse VSC73xx Switches
>  ========================
>  
>  This defines device tree bindings for the Vitesse VSC73xx switch chips.
> -The Vitesse company has been acquired by Microsemi and Microsemi in turn
> -acquired by Microchip but retains this vendor branding.
> +The Vitesse company has been acquired by Microsemi and Microsemi has
> +been acquired Microchip but retains this vendor branding.
>  
>  The currently supported switch chips are:
>  Vitesse VSC7385 SparX-G5 5+1-port Integrated Gigabit Ethernet Switch
> @@ -11,8 +11,13 @@ Vitesse VSC7388 SparX-G8 8-port Integrated Gigabit Ethernet Switch
>  Vitesse VSC7395 SparX-G5e 5+1-port Integrated Gigabit Ethernet Switch
>  Vitesse VSC7398 SparX-G8e 8-port Integrated Gigabit Ethernet Switch
>  
> -The device tree node is an SPI device so it must reside inside a SPI bus
> -device tree node, see spi/spi-bus.txt
> +This switch could have two different management interface.
> +
> +If SPI interface is used, the device tree node is an SPI device so it must
> +reside inside a SPI bus device tree node, see spi/spi-bus.txt
> +
> +If Platform driver is used, the device tree node is an platform device so it
> +must reside inside a platform bus device tree node.
>  
>  Required properties:
>  
> @@ -38,6 +43,7 @@ and subnodes of DSA switches.
>  
>  Examples:
>  
> +SPI:
>  switch@0 {
>  	compatible = "vitesse,vsc7395";
>  	reg = <0>;
> @@ -79,3 +85,46 @@ switch@0 {
>  		};
>  	};
>  };
> +
> +Platform:
> +switch@2,0 {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	compatible = "vitesse,vsc7385";
> +	reg = <0x2 0x0 0x20000>;
> +	reset-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
> +
> +	ports {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		port@0 {
> +			reg = <0>;
> +			label = "lan1";
> +		};
> +		port@1 {
> +			reg = <1>;
> +			label = "lan2";
> +		};
> +		port@2 {
> +			reg = <2>;
> +			label = "lan3";
> +		};
> +		port@3 {
> +			reg = <3>;
> +			label = "lan4";
> +		};
> +		vsc: port@6 {
> +			reg = <6>;
> +			label = "cpu";
> +			ethernet = <&enet0>;
> +			phy-mode = "rgmii";
> +			fixed-link {
> +				speed = <1000>;
> +				full-duplex;
> +				pause;
> +			};
> +		};
> +	};
> +
> +};
> 

-- 
Florian

^ permalink raw reply


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