Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next 0/6] net: add support for ip_tun_info options setting
From: Xin Long @ 2019-09-16  7:17 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, William Tu
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2040 bytes --]

On Mon, Sep 16, 2019 at 3:10 PM Xin Long <lucien.xin@gmail.com> wrote:
>
> With this patchset, users can configure options with LWTUNNEL_IP(6)_OPTS
> by ip route encap for ersapn or vxlan lwtunnel. Note that in kernel part
> it won't parse the option details but do some check and memcpy only, and
> the options will be parsed by iproute in userspace.
>
> We also improve the vxlan and erspan options processing in this patchset.
>
> As an example I also wrote a patch for iproute2 that I will reply on this
> mail, with it we can add options for erspan lwtunnel like:
>
>    # ip net a a; ip net a b
>    # ip -n a l a eth0 type veth peer name eth0 netns b
>    # ip -n a l s eth0 up; ip -n b link set eth0 up
>    # ip -n a a a 10.1.0.1/24 dev eth0; ip -n b a a 10.1.0.2/24 dev eth0
>    # ip -n b l a erspan1 type erspan key 1 seq erspan 123 \
>         local 10.1.0.2 remote 10.1.0.1
>    # ip -n b a a 1.1.1.1/24 dev erspan1; ip -n b l s erspan1 up
>    # ip -n b r a 2.1.1.0/24 dev erspan1
>    # ip -n a l a erspan1 type erspan key 1 seq local 10.1.0.1 external
>    # ip -n a a a 2.1.1.1/24 dev erspan1; ip -n a l s erspan1 up
>    # ip -n a r a 1.1.1.0/24 encap ip id 1 erspan ver 1 idx 123 \
>         dst 10.1.0.2 dev erspan1
>    # ip -n a r s; ip net exec a ping 1.1.1.1 -c 1
the iproute2 patch for testing is as attached.

>
> Xin Long (6):
>   lwtunnel: add options process for arp request
>   lwtunnel: add LWTUNNEL_IP_OPTS support for lwtunnel_ip
>   lwtunnel: add LWTUNNEL_IP6_OPTS support for lwtunnel_ip6
>   vxlan: check tun_info options_len properly
>   erspan: fix the tun_info options_len check
>   erspan: make md work without TUNNEL_ERSPAN_OPT set
>
>  drivers/net/vxlan.c           |  6 +++--
>  include/uapi/linux/lwtunnel.h |  2 ++
>  net/ipv4/ip_gre.c             | 31 ++++++++++-------------
>  net/ipv4/ip_tunnel_core.c     | 59 +++++++++++++++++++++++++++++++++----------
>  net/ipv6/ip6_gre.c            | 35 +++++++++++++------------
>  5 files changed, 84 insertions(+), 49 deletions(-)
>
> --
> 2.1.0
>

[-- Attachment #2: 0001-iproute_lwtunnel-add-support-options-for-erspan-meta.patch --]
[-- Type: application/octet-stream, Size: 7224 bytes --]

From c852e8b4c6838b5beed3e477bb6bfb9dbd9b2900 Mon Sep 17 00:00:00 2001
From: Xin Long <lucien.xin@gmail.com>
Date: Mon, 16 Sep 2019 03:14:07 -0400
Subject: [PATCH] iproute_lwtunnel: add support options for erspan metadata

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/uapi/linux/lwtunnel.h |   2 +
 ip/iproute_lwtunnel.c         | 131 ++++++++++++++++++++++++++++++++--
 2 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
index 3f3fe6f3..c25ff92d 100644
--- a/include/uapi/linux/lwtunnel.h
+++ b/include/uapi/linux/lwtunnel.h
@@ -27,6 +27,7 @@ enum lwtunnel_ip_t {
 	LWTUNNEL_IP_TOS,
 	LWTUNNEL_IP_FLAGS,
 	LWTUNNEL_IP_PAD,
+	LWTUNNEL_IP_OPTS,
 	__LWTUNNEL_IP_MAX,
 };
 
@@ -41,6 +42,7 @@ enum lwtunnel_ip6_t {
 	LWTUNNEL_IP6_TC,
 	LWTUNNEL_IP6_FLAGS,
 	LWTUNNEL_IP6_PAD,
+	LWTUNNEL_IP6_OPTS,
 	__LWTUNNEL_IP6_MAX,
 };
 
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 03217b8f..ff7eb450 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -32,6 +32,7 @@
 #include <linux/seg6_hmac.h>
 #include <linux/seg6_local.h>
 #include <linux/if_tunnel.h>
+#include <linux/erspan.h>
 
 static const char *format_encap_type(int type)
 {
@@ -294,7 +295,7 @@ static void print_encap_mpls(FILE *fp, struct rtattr *encap)
 static void print_encap_ip(FILE *fp, struct rtattr *encap)
 {
 	struct rtattr *tb[LWTUNNEL_IP_MAX+1];
-	__u16 flags;
+	__u16 flags = 0;
 
 	parse_rtattr_nested(tb, LWTUNNEL_IP_MAX, encap);
 
@@ -329,6 +330,25 @@ static void print_encap_ip(FILE *fp, struct rtattr *encap)
 		if (flags & TUNNEL_SEQ)
 			print_bool(PRINT_ANY, "seq", "seq ", true);
 	}
+
+	if (tb[LWTUNNEL_IP_OPTS]) {
+		if (flags & TUNNEL_ERSPAN_OPT) {
+			struct erspan_metadata *em = RTA_DATA(tb[LWTUNNEL_IP_OPTS]);
+
+			if (em->version == 1) {
+				print_bool(PRINT_ANY, "erspan", "erspan ", true);
+				print_uint(PRINT_ANY, "ver", "ver %u ", 1);
+				print_uint(PRINT_ANY, "idx", "idx %u ",
+					   ntohl(em->u.index));
+			} else if (em->version == 2) {
+				print_bool(PRINT_ANY, "erspan", "erspan ", true);
+				print_color_string(PRINT_ANY, COLOR_INET,
+						   "dir", "dir %s ",
+						   em->u.md2.dir ? "ingress" : "exgress");
+				print_uint(PRINT_ANY, "hwid", "hwid %u ", em->u.md2.hwid);
+			}
+		}
+	}
 }
 
 static void print_encap_ila(FILE *fp, struct rtattr *encap)
@@ -365,7 +385,7 @@ static void print_encap_ila(FILE *fp, struct rtattr *encap)
 static void print_encap_ip6(FILE *fp, struct rtattr *encap)
 {
 	struct rtattr *tb[LWTUNNEL_IP6_MAX+1];
-	__u16 flags;
+	__u16 flags = 0;
 
 	parse_rtattr_nested(tb, LWTUNNEL_IP6_MAX, encap);
 
@@ -401,6 +421,25 @@ static void print_encap_ip6(FILE *fp, struct rtattr *encap)
 		if (flags & TUNNEL_SEQ)
 			print_bool(PRINT_ANY, "seq", "seq ", true);
 	}
+
+	if (tb[LWTUNNEL_IP6_OPTS]) {
+		if (flags & TUNNEL_ERSPAN_OPT) {
+			struct erspan_metadata *em = RTA_DATA(tb[LWTUNNEL_IP6_OPTS]);
+
+			if (em->version == 1) {
+				print_bool(PRINT_ANY, "erspan", "erspan ", true);
+				print_uint(PRINT_ANY, "ver", "ver %u ", 1);
+				print_uint(PRINT_ANY, "idx", "idx %u ",
+					   ntohl(em->u.index));
+			} else if (em->version == 2) {
+				print_bool(PRINT_ANY, "erspan", "erspan ", true);
+				print_color_string(PRINT_ANY, COLOR_INET,
+						   "dir", "dir %s ",
+						   em->u.md2.dir ? "ingress" : "exgress");
+				print_uint(PRINT_ANY, "hwid", "hwid %u ", em->u.md2.hwid);
+			}
+		}
+	}
 }
 
 static void print_encap_bpf(FILE *fp, struct rtattr *encap)
@@ -799,7 +838,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
 			  int *argcp, char ***argvp)
 {
 	int id_ok = 0, dst_ok = 0, src_ok = 0, tos_ok = 0, ttl_ok = 0;
-	int key_ok = 0, csum_ok = 0, seq_ok = 0;
+	int key_ok = 0, csum_ok = 0, seq_ok = 0, erspan_ok = 0;
 	char **argv = *argvp;
 	int argc = *argcp;
 	int ret = 0;
@@ -851,6 +890,48 @@ static int parse_encap_ip(struct rtattr *rta, size_t len,
 			if (get_u8(&ttl, *argv, 0))
 				invarg("\"ttl\" value is invalid\n", *argv);
 			ret = rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl);
+		} else if (strcmp(*argv, "erspan") == 0) {
+			struct erspan_metadata em;
+
+			memset(&em, 0, sizeof(em));
+			if (erspan_ok++)
+				duparg2("erspan", *argv);
+			flags |= TUNNEL_ERSPAN_OPT;
+			NEXT_ARG();
+			if (strcmp(*argv, "ver"))
+				duparg2("ver", *argv);
+			NEXT_ARG();
+			if (get_s32(&em.version, *argv, 0) ||
+			    (em.version != 1 && em.version != 2))
+				invarg("\"tos\" value is invalid\n", *argv);
+			NEXT_ARG();
+			if (em.version == 1) {
+				if (strcmp(*argv, "idx"))
+					duparg2("idx", *argv);
+				NEXT_ARG();
+				if (get_be32(&em.u.index, *argv, 0))
+					invarg("\"idx\" value is invalid\n", *argv);
+			} else {
+				__u8 hwid;
+
+				if (strcmp(*argv, "dir"))
+					duparg2("dir", *argv);
+				NEXT_ARG();
+				if (strcmp(*argv, "ingress") == 0)
+					em.u.md2.dir = 0;
+				else if (strcmp(*argv, "exgress") == 0)
+					em.u.md2.dir = 1;
+				else
+					invarg("\"dir\" value is invalid\n", *argv);
+				NEXT_ARG();
+				if (strcmp(*argv, "hwid"))
+					duparg2("hwid", *argv);
+				NEXT_ARG();
+				if (get_u8(&hwid, *argv, 0))
+					invarg("\"hwid\" value is invalid\n", *argv);
+				em.u.md2.hwid = hwid;
+			}
+			rta_addattr_l(rta, len, LWTUNNEL_IP_OPTS, &em, sizeof(em));
 		} else if (strcmp(*argv, "key") == 0) {
 			if (key_ok++)
 				duparg2("key", *argv);
@@ -966,7 +1047,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
 			   int *argcp, char ***argvp)
 {
 	int id_ok = 0, dst_ok = 0, src_ok = 0, tos_ok = 0, ttl_ok = 0;
-	int key_ok = 0, csum_ok = 0, seq_ok = 0;
+	int key_ok = 0, csum_ok = 0, seq_ok = 0, erspan_ok = 0;
 	char **argv = *argvp;
 	int argc = *argcp;
 	int ret = 0;
@@ -1020,6 +1101,48 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
 				       *argv);
 			ret = rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT,
 					   hoplimit);
+		} else if (strcmp(*argv, "erspan") == 0) {
+			struct erspan_metadata em;
+
+			memset(&em, 0, sizeof(em));
+			if (erspan_ok++)
+				duparg2("erspan", *argv);
+			flags |= TUNNEL_ERSPAN_OPT;
+			NEXT_ARG();
+			if (strcmp(*argv, "ver"))
+				duparg2("ver", *argv);
+			NEXT_ARG();
+			if (get_s32(&em.version, *argv, 0) ||
+			    (em.version != 1 && em.version != 2))
+				invarg("\"tos\" value is invalid\n", *argv);
+			NEXT_ARG();
+			if (em.version == 1) {
+				if (strcmp(*argv, "idx"))
+					duparg2("idx", *argv);
+				NEXT_ARG();
+				if (get_be32(&em.u.index, *argv, 0))
+					invarg("\"idx\" value is invalid\n", *argv);
+			} else {
+				__u8 hwid;
+
+				if (strcmp(*argv, "dir"))
+					duparg2("dir", *argv);
+				NEXT_ARG();
+				if (strcmp(*argv, "ingress") == 0)
+					em.u.md2.dir = 0;
+				else if (strcmp(*argv, "exgress") == 0)
+					em.u.md2.dir = 1;
+				else
+					invarg("\"dir\" value is invalid\n", *argv);
+				NEXT_ARG();
+				if (strcmp(*argv, "hwid"))
+					duparg2("hwid", *argv);
+				NEXT_ARG();
+				if (get_u8(&hwid, *argv, 0))
+					invarg("\"hwid\" value is invalid\n", *argv);
+				em.u.md2.hwid = hwid;
+			}
+			rta_addattr_l(rta, len, LWTUNNEL_IP6_OPTS, &em, sizeof(em));
 		} else if (strcmp(*argv, "key") == 0) {
 			if (key_ok++)
 				duparg2("key", *argv);
-- 
2.18.1


^ permalink raw reply related

* Re: [PATCH 1/1] MAINTAINERS: update FORCEDETH MAINTAINERS info
From: David Miller @ 2019-09-16  7:16 UTC (permalink / raw)
  To: rain.1986.08.12; +Cc: mchehab+samsung, gregkh, linux-kernel, netdev
In-Reply-To: <20190913134345.28318-1-rain.1986.08.12@gmail.com>

From: rain.1986.08.12@gmail.com
Date: Fri, 13 Sep 2019 21:43:45 +0800

> From: Rain River <rain.1986.08.12@gmail.com>
> 
> Many FORCEDETH NICs are used in our hosts. Several bugs are fixed and
> some features are developed for FORCEDETH NICs. And I have been
> reviewing patches for FORCEDETH NIC for several months. Mark me as the
> FORCEDETH NIC maintainer. I will send out the patches and maintain
> FORCEDETH NIC.
> 
> Signed-off-by: Rain River <rain.1986.08.12@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net/wan: dscc4: remove broken dscc4 driver
From: David Miller @ 2019-09-16  7:15 UTC (permalink / raw)
  To: dan.carpenter; +Cc: romieu, netdev, kernel-janitors
In-Reply-To: <20190913132817.GA13179@mwanda>

From: Dan Carpenter <dan.carpenter@oracle.com>
Date: Fri, 13 Sep 2019 16:28:17 +0300

> Using static analysis, I discovered that the "dpriv->pci_priv->pdev"
> pointer is always NULL.  This pointer was supposed to be initialized
> during probe and is essential for the driver to work.  It would be easy
> to add a "ppriv->pdev = pdev;" to dscc4_found1() but this driver has
> been broken since before we started using git and no one has complained
> so probably we should just remove it.
> 
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

Applied to net-next.

^ permalink raw reply

* Re: [PATCH net-next] MAINTAINERS: xen-netback: update my email address
From: David Miller @ 2019-09-16  7:13 UTC (permalink / raw)
  To: paul.durrant; +Cc: netdev, xen-devel, wei.liu
In-Reply-To: <20190913124727.3277-1-paul.durrant@citrix.com>

From: Paul Durrant <paul.durrant@citrix.com>
Date: Fri, 13 Sep 2019 13:47:27 +0100

> My Citrix email address will expire shortly.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Applied.

^ permalink raw reply

* Re: [PATCH net] net: stmmac: Hold rtnl lock in suspend/resume callbacks
From: David Miller @ 2019-09-16  7:12 UTC (permalink / raw)
  To: Jose.Abreu
  Cc: netdev, Joao.Pinto, peppe.cavallaro, alexandre.torgue,
	mcoquelin.stm32, linux-stm32, linux-arm-kernel, linux-kernel,
	christophe.roullier
In-Reply-To: <66b6c1395e4bbc836e80083b89b2189ce7382d7b.1568360548.git.joabreu@synopsys.com>

From: Jose Abreu <Jose.Abreu@synopsys.com>
Date: Fri, 13 Sep 2019 11:50:32 +0200

> We need to hold rnl lock in suspend and resume callbacks because phylink
> requires it. Otherwise we will get a WARN() in suspend and resume.
> 
> Also, move phylink start and stop callbacks to inside device's internal
> lock so that we prevent concurrent HW accesses.
> 
> Fixes: 74371272f97f ("net: stmmac: Convert to phylink and remove phylib logic")
> Reported-by: Christophe ROULLIER <christophe.roullier@st.com>
> Tested-by: Christophe ROULLIER <christophe.roullier@st.com>
> Signed-off-by: Jose Abreu <joabreu@synopsys.com>

Applied and queued up for v5.3 -stable.

Thanks.

^ permalink raw reply

* [PATCH net-next 6/6] erspan: make md work without TUNNEL_ERSPAN_OPT set
From: Xin Long @ 2019-09-16  7:10 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>

Now when a skb comes with ip_tun_info but with no TUNNEL_ERSPAN_OPT to
a md erspan device, it will be dropped.

This patch is to allow this skb to go through this erspan device, and
the options (version, index, hwid, dir, etc.) will be filled with
tunnel's params, which can be configured by users.

This can be verified by:

 # ip net a a; ip net a b
 # ip -n a l a eth0 type veth peer name eth0 netns b
 # ip -n a l s eth0 up; ip -n b link set eth0 up
 # ip -n a a a 10.1.0.1/24 dev eth0; ip -n b a a 10.1.0.2/24 dev eth0
 # ip -n b l a erspan1 type erspan key 1 seq local 10.1.0.2 remote 10.1.0.1
 # ip -n b a a 1.1.1.1/24 dev erspan1; ip -n b l s erspan1 up
 # ip -n b r a 2.1.1.0/24 dev erspan1
 # ip -n a l a erspan1 type erspan key 1 seq local 10.1.0.1 external
 # ip -n a a a 2.1.1.1/24 dev erspan1; ip -n a l s erspan1 up
 # ip -n a r a 1.1.1.0/24 encap ip id 1 dst 10.1.0.2 dev erspan1
 # ip net exec a ping 1.1.1.1 -c 1

Reported-by: Jianlin Shi <jishi@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/ipv4/ip_gre.c  | 31 +++++++++++++------------------
 net/ipv6/ip6_gre.c | 35 +++++++++++++++++++----------------
 2 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index df7149c..ac4cbb8 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -491,15 +491,12 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
 static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
+	struct erspan_metadata *md = NULL;
 	struct ip_tunnel_info *tun_info;
 	const struct ip_tunnel_key *key;
-	struct erspan_metadata *md;
+	int version, nhoff, thoff;
 	bool truncate = false;
 	__be16 proto;
-	int tunnel_hlen;
-	int version;
-	int nhoff;
-	int thoff;
 
 	tun_info = skb_tunnel_info(skb);
 	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
@@ -507,15 +504,11 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 		goto err_free_skb;
 
 	key = &tun_info->key;
-	if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
-		goto err_free_skb;
-	if (sizeof(*md) > tun_info->options_len)
-		goto err_free_skb;
-	md = ip_tunnel_info_opts(tun_info);
-
-	/* ERSPAN has fixed 8 byte GRE header */
-	version = md->version;
-	tunnel_hlen = 8 + erspan_hdr_len(version);
+	if (key->tun_flags & TUNNEL_ERSPAN_OPT) {
+		if (tun_info->options_len < sizeof(*md))
+			goto err_free_skb;
+		md = ip_tunnel_info_opts(tun_info);
+	}
 
 	if (skb_cow_head(skb, dev->needed_headroom))
 		goto err_free_skb;
@@ -538,15 +531,17 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 	    (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff))
 		truncate = true;
 
+	version = md ? md->version : tunnel->erspan_ver;
 	if (version == 1) {
 		erspan_build_header(skb, ntohl(tunnel_id_to_key32(key->tun_id)),
-				    ntohl(md->u.index), truncate, true);
+				    md ? ntohl(md->u.index) : tunnel->index,
+				    truncate, true);
 		proto = htons(ETH_P_ERSPAN);
 	} else if (version == 2) {
 		erspan_build_header_v2(skb,
 				       ntohl(tunnel_id_to_key32(key->tun_id)),
-				       md->u.md2.dir,
-				       get_hwid(&md->u.md2),
+				       md ? md->u.md2.dir : tunnel->dir,
+				       md ? get_hwid(&md->u.md2) : tunnel->hwid,
 				       truncate, true);
 		proto = htons(ETH_P_ERSPAN2);
 	} else {
@@ -556,7 +551,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 	gre_build_header(skb, 8, TUNNEL_SEQ,
 			 proto, 0, htonl(tunnel->o_seqno++));
 
-	ip_md_tunnel_xmit(skb, dev, IPPROTO_GRE, tunnel_hlen);
+	ip_md_tunnel_xmit(skb, dev, IPPROTO_GRE, 8 + erspan_hdr_len(version));
 
 	return;
 
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 4aba9e0..a48cec3 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -959,10 +959,11 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
 	 * for native mode, call prepare_ip6gre_xmit_{ipv4,ipv6}.
 	 */
 	if (t->parms.collect_md) {
+		struct erspan_metadata *md = NULL;
 		struct ip_tunnel_info *tun_info;
 		const struct ip_tunnel_key *key;
-		struct erspan_metadata *md;
 		__be32 tun_id;
+		int version;
 
 		tun_info = skb_tunnel_info(skb);
 		if (unlikely(!tun_info ||
@@ -978,23 +979,25 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
 		fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
 
 		dsfield = key->tos;
-		if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
-			goto tx_err;
-		if (sizeof(*md) > tun_info->options_len)
-			goto tx_err;
-		md = ip_tunnel_info_opts(tun_info);
+		if (key->tun_flags & TUNNEL_ERSPAN_OPT) {
+			if (tun_info->options_len < sizeof(*md))
+				goto tx_err;
+			md = ip_tunnel_info_opts(tun_info);
+		}
 
 		tun_id = tunnel_id_to_key32(key->tun_id);
-		if (md->version == 1) {
-			erspan_build_header(skb,
-					    ntohl(tun_id),
-					    ntohl(md->u.index), truncate,
-					    false);
-		} else if (md->version == 2) {
-			erspan_build_header_v2(skb,
-					       ntohl(tun_id),
-					       md->u.md2.dir,
-					       get_hwid(&md->u.md2),
+		version = md ? md->version : t->parms.erspan_ver;
+		if (version == 1) {
+			erspan_build_header(skb, ntohl(tun_id),
+					    md ? ntohl(md->u.index)
+					       : t->parms.index,
+					    truncate, false);
+		} else if (version == 2) {
+			erspan_build_header_v2(skb, ntohl(tun_id),
+					       md ? md->u.md2.dir
+						  : t->parms.dir,
+					       md ? get_hwid(&md->u.md2)
+						  : t->parms.hwid,
 					       truncate, false);
 		} else {
 			goto tx_err;
-- 
2.1.0


^ permalink raw reply related

* [PATCH net-next 5/6] erspan: fix the tun_info options_len check
From: Xin Long @ 2019-09-16  7:10 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>

The check for !md doens't really work for ip_tunnel_info_opts(info) which
only does info + 1. Also to avoid out-of-bounds access on info, it should
ensure options_len is not less than erspan_metadata in both erspan_xmit()
and ip6erspan_tunnel_xmit().

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/ipv4/ip_gre.c  | 4 ++--
 net/ipv6/ip6_gre.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index a53a543..df7149c 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -509,9 +509,9 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 	key = &tun_info->key;
 	if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
 		goto err_free_skb;
-	md = ip_tunnel_info_opts(tun_info);
-	if (!md)
+	if (sizeof(*md) > tun_info->options_len)
 		goto err_free_skb;
+	md = ip_tunnel_info_opts(tun_info);
 
 	/* ERSPAN has fixed 8 byte GRE header */
 	version = md->version;
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index dd2d0b96..4aba9e0 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -980,9 +980,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
 		dsfield = key->tos;
 		if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
 			goto tx_err;
-		md = ip_tunnel_info_opts(tun_info);
-		if (!md)
+		if (sizeof(*md) > tun_info->options_len)
 			goto tx_err;
+		md = ip_tunnel_info_opts(tun_info);
 
 		tun_id = tunnel_id_to_key32(key->tun_id);
 		if (md->version == 1) {
-- 
2.1.0


^ permalink raw reply related

* [PATCH net-next 4/6] vxlan: check tun_info options_len properly
From: Xin Long @ 2019-09-16  7:10 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>

This patch is to improve the tun_info options_len by dropping
the skb when TUNNEL_VXLAN_OPT is set but options_len is less
than vxlan_metadata. This can void a potential out-of-bounds
access on ip_tun_info.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 drivers/net/vxlan.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 3d9bcc9..e0787286 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2487,9 +2487,11 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 		vni = tunnel_id_to_key32(info->key.tun_id);
 		ifindex = 0;
 		dst_cache = &info->dst_cache;
-		if (info->options_len &&
-		    info->key.tun_flags & TUNNEL_VXLAN_OPT)
+		if (info->key.tun_flags & TUNNEL_VXLAN_OPT) {
+			if (info->options_len < sizeof(*md))
+				goto drop;
 			md = ip_tunnel_info_opts(info);
+		}
 		ttl = info->key.ttl;
 		tos = info->key.tos;
 		label = info->key.label;
-- 
2.1.0


^ permalink raw reply related

* [PATCH net-next 3/6] lwtunnel: add LWTUNNEL_IP6_OPTS support for lwtunnel_ip6
From: Xin Long @ 2019-09-16  7:10 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>

Similar to lwtunnel_ip, this patch is to add options set/dump support
for lwtunnel_ip6.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/uapi/linux/lwtunnel.h |  1 +
 net/ipv4/ip_tunnel_core.c     | 22 ++++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
index 93f2c05..4bed5e6 100644
--- a/include/uapi/linux/lwtunnel.h
+++ b/include/uapi/linux/lwtunnel.h
@@ -42,6 +42,7 @@ enum lwtunnel_ip6_t {
 	LWTUNNEL_IP6_TC,
 	LWTUNNEL_IP6_FLAGS,
 	LWTUNNEL_IP6_PAD,
+	LWTUNNEL_IP6_OPTS,
 	__LWTUNNEL_IP6_MAX,
 };
 
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index d9b7188..c8f5375a 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -353,6 +353,7 @@ static const struct nla_policy ip6_tun_policy[LWTUNNEL_IP6_MAX + 1] = {
 	[LWTUNNEL_IP6_HOPLIMIT]		= { .type = NLA_U8 },
 	[LWTUNNEL_IP6_TC]		= { .type = NLA_U8 },
 	[LWTUNNEL_IP6_FLAGS]		= { .type = NLA_U16 },
+	[LWTUNNEL_IP6_OPTS]		= { .type = NLA_BINARY },
 };
 
 static int ip6_tun_build_state(struct nlattr *attr,
@@ -363,14 +364,20 @@ static int ip6_tun_build_state(struct nlattr *attr,
 	struct ip_tunnel_info *tun_info;
 	struct lwtunnel_state *new_state;
 	struct nlattr *tb[LWTUNNEL_IP6_MAX + 1];
-	int err;
+	int err, opts_len = 0;
+	void *opts;
 
 	err = nla_parse_nested_deprecated(tb, LWTUNNEL_IP6_MAX, attr,
 					  ip6_tun_policy, extack);
 	if (err < 0)
 		return err;
 
-	new_state = lwtunnel_state_alloc(sizeof(*tun_info));
+	if (tb[LWTUNNEL_IP6_OPTS]) {
+		opts = nla_data(tb[LWTUNNEL_IP6_OPTS]);
+		opts_len = nla_len(tb[LWTUNNEL_IP6_OPTS]);
+	}
+
+	new_state = lwtunnel_state_alloc(sizeof(*tun_info)  + opts_len);
 	if (!new_state)
 		return -ENOMEM;
 
@@ -396,8 +403,10 @@ static int ip6_tun_build_state(struct nlattr *attr,
 	if (tb[LWTUNNEL_IP6_FLAGS])
 		tun_info->key.tun_flags = nla_get_be16(tb[LWTUNNEL_IP6_FLAGS]);
 
+	if (opts_len)
+		ip_tunnel_info_opts_set(tun_info, opts, opts_len, 0);
+
 	tun_info->mode = IP_TUNNEL_INFO_TX | IP_TUNNEL_INFO_IPV6;
-	tun_info->options_len = 0;
 
 	*ts = new_state;
 
@@ -417,6 +426,10 @@ static int ip6_tun_fill_encap_info(struct sk_buff *skb,
 	    nla_put_u8(skb, LWTUNNEL_IP6_HOPLIMIT, tun_info->key.ttl) ||
 	    nla_put_be16(skb, LWTUNNEL_IP6_FLAGS, tun_info->key.tun_flags))
 		return -ENOMEM;
+	if (tun_info->options_len &&
+	    nla_put(skb, LWTUNNEL_IP6_OPTS,
+		    tun_info->options_len, ip_tunnel_info_opts(tun_info)))
+		return -ENOMEM;
 
 	return 0;
 }
@@ -428,7 +441,8 @@ static int ip6_tun_encap_nlsize(struct lwtunnel_state *lwtstate)
 		+ nla_total_size(16)	/* LWTUNNEL_IP6_SRC */
 		+ nla_total_size(1)	/* LWTUNNEL_IP6_HOPLIMIT */
 		+ nla_total_size(1)	/* LWTUNNEL_IP6_TC */
-		+ nla_total_size(2);	/* LWTUNNEL_IP6_FLAGS */
+		+ nla_total_size(2)	/* LWTUNNEL_IP6_FLAGS */
+		+ lwt_tun_info(lwtstate)->options_len;  /* LWTUNNEL_IP6_OPTS */
 }
 
 static const struct lwtunnel_encap_ops ip6_tun_lwt_ops = {
-- 
2.1.0


^ permalink raw reply related

* [PATCH net-next 2/6] lwtunnel: add LWTUNNEL_IP_OPTS support for lwtunnel_ip
From: Xin Long @ 2019-09-16  7:10 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>

This patch is to add LWTUNNEL_IP_OPTS into lwtunnel_ip_t, by which
users will be able to set options for ip_tunnel_info by "ip route
encap" for erspan and vxlan's private metadata. Like one way to go
in iproute is:

  # ip route add 1.1.1.0/24 encap ip id 1 erspan ver 1 idx 123 \
      dst 10.1.0.2 dev erspan1
  # ip route show
    1.1.1.0/24  encap ip id 1 src 0.0.0.0 dst 10.1.0.2 ttl 0 \
      tos 0 erspan ver 1 idx 123 dev erspan1 scope link

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/uapi/linux/lwtunnel.h |  1 +
 net/ipv4/ip_tunnel_core.c     | 30 ++++++++++++++++++++++++------
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
index de696ca..93f2c05 100644
--- a/include/uapi/linux/lwtunnel.h
+++ b/include/uapi/linux/lwtunnel.h
@@ -27,6 +27,7 @@ enum lwtunnel_ip_t {
 	LWTUNNEL_IP_TOS,
 	LWTUNNEL_IP_FLAGS,
 	LWTUNNEL_IP_PAD,
+	LWTUNNEL_IP_OPTS,
 	__LWTUNNEL_IP_MAX,
 };
 
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 10f0848..d9b7188 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -218,6 +218,7 @@ static const struct nla_policy ip_tun_policy[LWTUNNEL_IP_MAX + 1] = {
 	[LWTUNNEL_IP_TTL]	= { .type = NLA_U8 },
 	[LWTUNNEL_IP_TOS]	= { .type = NLA_U8 },
 	[LWTUNNEL_IP_FLAGS]	= { .type = NLA_U16 },
+	[LWTUNNEL_IP_OPTS]	= { .type = NLA_BINARY },
 };
 
 static int ip_tun_build_state(struct nlattr *attr,
@@ -228,14 +229,20 @@ static int ip_tun_build_state(struct nlattr *attr,
 	struct ip_tunnel_info *tun_info;
 	struct lwtunnel_state *new_state;
 	struct nlattr *tb[LWTUNNEL_IP_MAX + 1];
-	int err;
+	int err, opts_len = 0;
+	void *opts;
 
 	err = nla_parse_nested_deprecated(tb, LWTUNNEL_IP_MAX, attr,
 					  ip_tun_policy, extack);
 	if (err < 0)
 		return err;
 
-	new_state = lwtunnel_state_alloc(sizeof(*tun_info));
+	if (tb[LWTUNNEL_IP_OPTS]) {
+		opts = nla_data(tb[LWTUNNEL_IP_OPTS]);
+		opts_len = nla_len(tb[LWTUNNEL_IP_OPTS]);
+	}
+
+	new_state = lwtunnel_state_alloc(sizeof(*tun_info) + opts_len);
 	if (!new_state)
 		return -ENOMEM;
 
@@ -269,8 +276,10 @@ static int ip_tun_build_state(struct nlattr *attr,
 	if (tb[LWTUNNEL_IP_FLAGS])
 		tun_info->key.tun_flags = nla_get_be16(tb[LWTUNNEL_IP_FLAGS]);
 
+	if (opts_len)
+		ip_tunnel_info_opts_set(tun_info, opts, opts_len, 0);
+
 	tun_info->mode = IP_TUNNEL_INFO_TX;
-	tun_info->options_len = 0;
 
 	*ts = new_state;
 
@@ -299,6 +308,10 @@ static int ip_tun_fill_encap_info(struct sk_buff *skb,
 	    nla_put_u8(skb, LWTUNNEL_IP_TTL, tun_info->key.ttl) ||
 	    nla_put_be16(skb, LWTUNNEL_IP_FLAGS, tun_info->key.tun_flags))
 		return -ENOMEM;
+	if (tun_info->options_len &&
+	    nla_put(skb, LWTUNNEL_IP_OPTS,
+		    tun_info->options_len, ip_tunnel_info_opts(tun_info)))
+		return -ENOMEM;
 
 	return 0;
 }
@@ -310,13 +323,18 @@ static int ip_tun_encap_nlsize(struct lwtunnel_state *lwtstate)
 		+ nla_total_size(4)	/* LWTUNNEL_IP_SRC */
 		+ nla_total_size(1)	/* LWTUNNEL_IP_TOS */
 		+ nla_total_size(1)	/* LWTUNNEL_IP_TTL */
-		+ nla_total_size(2);	/* LWTUNNEL_IP_FLAGS */
+		+ nla_total_size(2)	/* LWTUNNEL_IP_FLAGS */
+		+ lwt_tun_info(lwtstate)->options_len;	/* LWTUNNEL_IP_OPTS */
 }
 
 static int ip_tun_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b)
 {
-	return memcmp(lwt_tun_info(a), lwt_tun_info(b),
-		      sizeof(struct ip_tunnel_info));
+	struct ip_tunnel_info *info_a = lwt_tun_info(a);
+	struct ip_tunnel_info *info_b = lwt_tun_info(b);
+	u8 opts_len;
+
+	opts_len = min(info_a->options_len, info_b->options_len);
+	return memcmp(info_a, info_b, sizeof(*info_a) + opts_len);
 }
 
 static const struct lwtunnel_encap_ops ip_tun_lwt_ops = {
-- 
2.1.0


^ permalink raw reply related

* [PATCH net-next 1/6] lwtunnel: add options process for arp request
From: Xin Long @ 2019-09-16  7:10 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>

Without options copied to the dst tun_info in iptunnel_metadata_reply()
called by arp_process for handling arp_request, the generated arp_reply
packet may be dropped or sent out with wrong options for some tunnels
like erspan and vxlan, and the traffic will break.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/ipv4/ip_tunnel_core.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 1452a97..10f0848 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -126,15 +126,14 @@ struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
 
 	if (!md || md->type != METADATA_IP_TUNNEL ||
 	    md->u.tun_info.mode & IP_TUNNEL_INFO_TX)
-
 		return NULL;
 
-	res = metadata_dst_alloc(0, METADATA_IP_TUNNEL, flags);
+	src = &md->u.tun_info;
+	res = metadata_dst_alloc(src->options_len, METADATA_IP_TUNNEL, flags);
 	if (!res)
 		return NULL;
 
 	dst = &res->u.tun_info;
-	src = &md->u.tun_info;
 	dst->key.tun_id = src->key.tun_id;
 	if (src->mode & IP_TUNNEL_INFO_IPV6)
 		memcpy(&dst->key.u.ipv6.dst, &src->key.u.ipv6.src,
@@ -143,6 +142,8 @@ struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
 		dst->key.u.ipv4.dst = src->key.u.ipv4.src;
 	dst->key.tun_flags = src->key.tun_flags;
 	dst->mode = src->mode | IP_TUNNEL_INFO_TX;
+	ip_tunnel_info_opts_set(dst, ip_tunnel_info_opts(src),
+				src->options_len, 0);
 
 	return res;
 }
-- 
2.1.0


^ permalink raw reply related

* [PATCH net-next 0/6] net: add support for ip_tun_info options setting
From: Xin Long @ 2019-09-16  7:10 UTC (permalink / raw)
  To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063

With this patchset, users can configure options with LWTUNNEL_IP(6)_OPTS
by ip route encap for ersapn or vxlan lwtunnel. Note that in kernel part
it won't parse the option details but do some check and memcpy only, and
the options will be parsed by iproute in userspace.

We also improve the vxlan and erspan options processing in this patchset.

As an example I also wrote a patch for iproute2 that I will reply on this
mail, with it we can add options for erspan lwtunnel like:

   # ip net a a; ip net a b
   # ip -n a l a eth0 type veth peer name eth0 netns b
   # ip -n a l s eth0 up; ip -n b link set eth0 up
   # ip -n a a a 10.1.0.1/24 dev eth0; ip -n b a a 10.1.0.2/24 dev eth0
   # ip -n b l a erspan1 type erspan key 1 seq erspan 123 \
        local 10.1.0.2 remote 10.1.0.1
   # ip -n b a a 1.1.1.1/24 dev erspan1; ip -n b l s erspan1 up
   # ip -n b r a 2.1.1.0/24 dev erspan1
   # ip -n a l a erspan1 type erspan key 1 seq local 10.1.0.1 external
   # ip -n a a a 2.1.1.1/24 dev erspan1; ip -n a l s erspan1 up
   # ip -n a r a 1.1.1.0/24 encap ip id 1 erspan ver 1 idx 123 \
        dst 10.1.0.2 dev erspan1
   # ip -n a r s; ip net exec a ping 1.1.1.1 -c 1

Xin Long (6):
  lwtunnel: add options process for arp request
  lwtunnel: add LWTUNNEL_IP_OPTS support for lwtunnel_ip
  lwtunnel: add LWTUNNEL_IP6_OPTS support for lwtunnel_ip6
  vxlan: check tun_info options_len properly
  erspan: fix the tun_info options_len check
  erspan: make md work without TUNNEL_ERSPAN_OPT set

 drivers/net/vxlan.c           |  6 +++--
 include/uapi/linux/lwtunnel.h |  2 ++
 net/ipv4/ip_gre.c             | 31 ++++++++++-------------
 net/ipv4/ip_tunnel_core.c     | 59 +++++++++++++++++++++++++++++++++----------
 net/ipv6/ip6_gre.c            | 35 +++++++++++++------------
 5 files changed, 84 insertions(+), 49 deletions(-)

-- 
2.1.0


^ permalink raw reply

* Re: [patch net-next 00/15] devlink: allow devlink instances to change network namespace
From: Jiri Pirko @ 2019-09-16  7:09 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, idosch, dsahern, jakub.kicinski, tariqt, saeedm, kuznet,
	yoshfuji, shuah, mlxsw
In-Reply-To: <20190916.090111.605211597512563157.davem@davemloft.net>

Mon, Sep 16, 2019 at 09:01:11AM CEST, davem@davemloft.net wrote:
>
>Jiri, this has to wait until the next merge window sorry.

Sure, no worries :)

^ permalink raw reply

* Re: [PATCH net] ip6_gre: fix a dst leak in ip6erspan_tunnel_xmit
From: David Miller @ 2019-09-16  7:09 UTC (permalink / raw)
  To: lucien.xin; +Cc: netdev, u9012063
In-Reply-To: <1bfbf329c5b3649a6c6362350a0d609ff184deba.1568367947.git.lucien.xin@gmail.com>

From: Xin Long <lucien.xin@gmail.com>
Date: Fri, 13 Sep 2019 17:45:47 +0800

> In ip6erspan_tunnel_xmit(), if the skb will not be sent out, it has to
> be freed on the tx_err path. Otherwise when deleting a netns, it would
> cause dst/dev to leak, and dmesg shows:
> 
>   unregister_netdevice: waiting for lo to become free. Usage count = 1
> 
> Fixes: ef7baf5e083c ("ip6_gre: add ip6 erspan collect_md mode")
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Applied and queued up for -stable.

^ permalink raw reply

* Re: [PATCH net-next v2 2/3] mlxsw: spectrum: Register CPU port with devlink
From: Jiri Pirko @ 2019-09-16  7:08 UTC (permalink / raw)
  To: Ido Schimmel; +Cc: netdev, davem, jiri, shalomt, mlxsw, Ido Schimmel
In-Reply-To: <20190916061750.26207-3-idosch@idosch.org>

Mon, Sep 16, 2019 at 08:17:49AM CEST, idosch@idosch.org wrote:
>From: Shalom Toledo <shalomt@mellanox.com>
>
>Register CPU port with devlink.
>
>Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
>Signed-off-by: Ido Schimmel <idosch@mellanox.com>
>---
> drivers/net/ethernet/mellanox/mlxsw/core.c    | 65 ++++++++++++++++---
> drivers/net/ethernet/mellanox/mlxsw/core.h    |  5 ++
> .../net/ethernet/mellanox/mlxsw/spectrum.c    | 46 +++++++++++++
> 3 files changed, 107 insertions(+), 9 deletions(-)
>
>diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
>index 3fa96076e8a5..66354b05fd6c 100644
>--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
>+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
>@@ -1864,11 +1864,13 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
> }
> EXPORT_SYMBOL(mlxsw_core_res_get);
> 
>-int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
>-			 u32 port_number, bool split,
>-			 u32 split_port_subnumber,
>-			 const unsigned char *switch_id,
>-			 unsigned char switch_id_len)
>+static int
>+__mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
>+		       enum devlink_port_flavour flavour,
>+		       u32 port_number, bool split,
>+		       u32 split_port_subnumber,
>+		       const unsigned char *switch_id,
>+		       unsigned char switch_id_len)

No need to wrap after "static int":

static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
				  enum devlink_port_flavour flavour,
				  u32 port_number, bool split,
				  u32 split_port_subnumber,
				  const unsigned char *switch_id,
				  unsigned char switch_id_len)


> {
> 	struct devlink *devlink = priv_to_devlink(mlxsw_core);
> 	struct mlxsw_core_port *mlxsw_core_port =
>@@ -1877,17 +1879,17 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
> 	int err;
> 
> 	mlxsw_core_port->local_port = local_port;
>-	devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
>-			       port_number, split, split_port_subnumber,
>+	devlink_port_attrs_set(devlink_port, flavour, port_number,
>+			       split, split_port_subnumber,
> 			       switch_id, switch_id_len);
> 	err = devlink_port_register(devlink, devlink_port, local_port);
> 	if (err)
> 		memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
> 	return err;
> }
>-EXPORT_SYMBOL(mlxsw_core_port_init);
> 
>-void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
>+static void
>+__mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)

No need to wrap:

static void __mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)


> {
> 	struct mlxsw_core_port *mlxsw_core_port =
> 					&mlxsw_core->ports[local_port];
>@@ -1896,8 +1898,53 @@ void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
> 	devlink_port_unregister(devlink_port);
> 	memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
> }
>+
>+int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
>+			 u32 port_number, bool split,
>+			 u32 split_port_subnumber,
>+			 const unsigned char *switch_id,
>+			 unsigned char switch_id_len)
>+{
>+	return __mlxsw_core_port_init(mlxsw_core, local_port,
>+				      DEVLINK_PORT_FLAVOUR_PHYSICAL,
>+				      port_number, split, split_port_subnumber,
>+				      switch_id, switch_id_len);
>+}
>+EXPORT_SYMBOL(mlxsw_core_port_init);
>+
>+void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
>+{
>+	__mlxsw_core_port_fini(mlxsw_core, local_port);
>+}
> EXPORT_SYMBOL(mlxsw_core_port_fini);
> 
>+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
>+			     void *port_driver_priv,
>+			     const unsigned char *switch_id,
>+			     unsigned char switch_id_len)
>+{
>+	struct mlxsw_core_port *mlxsw_core_port =
>+				&mlxsw_core->ports[MLXSW_PORT_CPU_PORT];
>+	int err;
>+
>+	err = __mlxsw_core_port_init(mlxsw_core, MLXSW_PORT_CPU_PORT,
>+				     DEVLINK_PORT_FLAVOUR_CPU,
>+				     0, false, 0,
>+				     switch_id, switch_id_len);
>+	if (err)
>+		return err;
>+
>+	mlxsw_core_port->port_driver_priv = port_driver_priv;

It is a bit confusing why this is done here comparing to physical ports,
where it is done during type set. But I didn't find better solution.


>+	return 0;
>+}
>+EXPORT_SYMBOL(mlxsw_core_cpu_port_init);
>+
>+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core)
>+{
>+	__mlxsw_core_port_fini(mlxsw_core, MLXSW_PORT_CPU_PORT);
>+}
>+EXPORT_SYMBOL(mlxsw_core_cpu_port_fini);
>+
> void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
> 			     void *port_driver_priv, struct net_device *dev)
> {
>diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
>index b65a17d49e43..5d7d2ab6d155 100644
>--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
>+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
>@@ -177,6 +177,11 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
> 			 const unsigned char *switch_id,
> 			 unsigned char switch_id_len);
> void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
>+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
>+			     void *port_driver_priv,
>+			     const unsigned char *switch_id,
>+			     unsigned char switch_id_len);
>+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core);
> void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
> 			     void *port_driver_priv, struct net_device *dev);
> void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
>diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
>index 91e4792bb7e7..dd234cf7b39d 100644
>--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
>+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
>@@ -3872,6 +3872,45 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
> 	mlxsw_core_port_fini(mlxsw_sp->core, local_port);
> }
> 
>+static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp)
>+{
>+	struct mlxsw_sp_port *mlxsw_sp_port;
>+	int err;
>+
>+	mlxsw_sp_port = kzalloc(sizeof(*mlxsw_sp_port), GFP_KERNEL);
>+	if (!mlxsw_sp_port)
>+		return -ENOMEM;
>+
>+	mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
>+	mlxsw_sp_port->local_port = MLXSW_PORT_CPU_PORT;
>+
>+	err = mlxsw_core_cpu_port_init(mlxsw_sp->core,
>+				       mlxsw_sp_port,
>+				       mlxsw_sp->base_mac,
>+				       sizeof(mlxsw_sp->base_mac));
>+	if (err) {
>+		dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize core CPU port\n");
>+		goto err_core_cpu_port_init;
>+	}
>+
>+	mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = mlxsw_sp_port;
>+	return 0;
>+
>+err_core_cpu_port_init:
>+	kfree(mlxsw_sp_port);
>+	return err;
>+}
>+
>+static void mlxsw_sp_cpu_port_remove(struct mlxsw_sp *mlxsw_sp)
>+{
>+	struct mlxsw_sp_port *mlxsw_sp_port =
>+				mlxsw_sp->ports[MLXSW_PORT_CPU_PORT];
>+
>+	mlxsw_core_cpu_port_fini(mlxsw_sp->core);
>+	mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL;
>+	kfree(mlxsw_sp_port);
>+}
>+
> static bool mlxsw_sp_port_created(struct mlxsw_sp *mlxsw_sp, u8 local_port)
> {
> 	return mlxsw_sp->ports[local_port] != NULL;
>@@ -3884,6 +3923,7 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
> 	for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++)
> 		if (mlxsw_sp_port_created(mlxsw_sp, i))
> 			mlxsw_sp_port_remove(mlxsw_sp, i);
>+	mlxsw_sp_cpu_port_remove(mlxsw_sp);
> 	kfree(mlxsw_sp->port_to_module);
> 	kfree(mlxsw_sp->ports);
> }
>@@ -3908,6 +3948,10 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
> 		goto err_port_to_module_alloc;
> 	}
> 
>+	err = mlxsw_sp_cpu_port_create(mlxsw_sp);
>+	if (err)
>+		goto err_cpu_port_create;
>+
> 	for (i = 1; i < max_ports; i++) {
> 		/* Mark as invalid */
> 		mlxsw_sp->port_to_module[i] = -1;
>@@ -3931,6 +3975,8 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
> 	for (i--; i >= 1; i--)
> 		if (mlxsw_sp_port_created(mlxsw_sp, i))
> 			mlxsw_sp_port_remove(mlxsw_sp, i);
>+	mlxsw_sp_cpu_port_remove(mlxsw_sp);
>+err_cpu_port_create:
> 	kfree(mlxsw_sp->port_to_module);
> err_port_to_module_alloc:
> 	kfree(mlxsw_sp->ports);
>-- 
>2.21.0
>

^ permalink raw reply

* Re: [PATCH] qed: fix spelling mistake "fullill" -> "fulfill"
From: David Miller @ 2019-09-16  7:07 UTC (permalink / raw)
  To: colin.king
  Cc: aelior, GR-everest-linux-l2, netdev, kernel-janitors,
	linux-kernel
In-Reply-To: <20190913090759.3490-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Fri, 13 Sep 2019 10:07:59 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> There is a spelling mistake in a DP_VERBOSE debug message. Fix it.
> (Using American English spelling as this is the most common way
> to spell this in the kernel).
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied to net-next

^ permalink raw reply

* Re: [PATCH net-next] net: dsa: b53: Add support for port_egress_floods callback
From: David Miller @ 2019-09-16  7:06 UTC (permalink / raw)
  To: f.fainelli; +Cc: netdev, b.spranger, andrew, vivien.didelot, linux-kernel
In-Reply-To: <20190913032841.4302-1-f.fainelli@gmail.com>

From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 12 Sep 2019 20:28:39 -0700

> Add support for configuring the per-port egress flooding control for
> both Unicast and Multicast traffic.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

Applied with comment typo fixed.

^ permalink raw reply

* net-next is CLOSED...
From: David Miller @ 2019-09-16  7:05 UTC (permalink / raw)
  To: netdev


It's merge window time...

^ permalink raw reply

* [PATCH v3] net: stmmac: socfpga: re-use the `interface` parameter from platform data
From: Alexandru Ardelean @ 2019-09-16  7:04 UTC (permalink / raw)
  To: netdev, linux-stm32, linux-arm-kernel, linux-kernel
  Cc: peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
	davem, Alexandru Ardelean

The socfpga sub-driver defines an `interface` field in the `socfpga_dwmac`
struct and parses it on init.

The shared `stmmac_probe_config_dt()` function also parses this from the
device-tree and makes it available on the returned `plat_data` (which is
the same data available via `netdev_priv()`).

All that's needed now is to dig that information out, via some
`dev_get_drvdata()` && `netdev_priv()` calls and re-use it.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
Changelog v2 -> v3:
* drop `inline` keyword

Changelog v1 -> v2:
* initially, this patch was developed on a 4.14 kernel, and adapted (badly)
  to `net-next`, so it did not build ; the v2 has been fixed and adapted
  correctly

 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c   | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index c141fe783e87..e0212d2fc2a1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -46,7 +46,6 @@ struct socfpga_dwmac_ops {
 };
 
 struct socfpga_dwmac {
-	int	interface;
 	u32	reg_offset;
 	u32	reg_shift;
 	struct	device *dev;
@@ -110,8 +109,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
 	struct resource res_tse_pcs;
 	struct resource res_sgmii_adapter;
 
-	dwmac->interface = of_get_phy_mode(np);
-
 	sys_mgr_base_addr =
 		altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
 	if (IS_ERR(sys_mgr_base_addr)) {
@@ -231,6 +228,14 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
 	return ret;
 }
 
+static int socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
+{
+	struct net_device *ndev = dev_get_drvdata(dwmac->dev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
+
+	return priv->plat->interface;
+}
+
 static int socfpga_set_phy_mode_common(int phymode, u32 *val)
 {
 	switch (phymode) {
@@ -255,7 +260,7 @@ static int socfpga_set_phy_mode_common(int phymode, u32 *val)
 static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
 {
 	struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
-	int phymode = dwmac->interface;
+	int phymode = socfpga_get_plat_phymode(dwmac);
 	u32 reg_offset = dwmac->reg_offset;
 	u32 reg_shift = dwmac->reg_shift;
 	u32 ctrl, val, module;
@@ -314,7 +319,7 @@ static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
 static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac)
 {
 	struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
-	int phymode = dwmac->interface;
+	int phymode = socfpga_get_plat_phymode(dwmac);
 	u32 reg_offset = dwmac->reg_offset;
 	u32 reg_shift = dwmac->reg_shift;
 	u32 ctrl, val, module;
-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH net] udp: correct reuseport selection with connected sockets
From: David Miller @ 2019-09-16  7:03 UTC (permalink / raw)
  To: willemdebruijn.kernel
  Cc: netdev, edumazet, kraig, zabele, pabeni, mark.keaton, willemb
In-Reply-To: <20190913011639.55895-1-willemdebruijn.kernel@gmail.com>

From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Thu, 12 Sep 2019 21:16:39 -0400

> From: Willem de Bruijn <willemb@google.com>
> 
> UDP reuseport groups can hold a mix unconnected and connected sockets.
> Ensure that connections only receive all traffic to their 4-tuple.
> 
> Fast reuseport returns on the first reuseport match on the assumption
> that all matches are equal. Only if connections are present, return to
> the previous behavior of scoring all sockets.
> 
> Record if connections are present and if so (1) treat such connected
> sockets as an independent match from the group, (2) only return
> 2-tuple matches from reuseport and (3) do not return on the first
> 2-tuple reuseport match to allow for a higher scoring match later.
> 
> New field has_conns is set without locks. No other fields in the
> bitmap are modified at runtime and the field is only ever set
> unconditionally, so an RMW cannot miss a change.
> 
> Fixes: e32ea7e74727 ("soreuseport: fast reuseport UDP socket selection")
> Link: http://lkml.kernel.org/r/CA+FuTSfRP09aJNYRt04SS6qj22ViiOEWaWmLAwX0psk8-PGNxw@mail.gmail.com
> Signed-off-by: Willem de Bruijn <willemb@google.com>

Applied and queued up for -stable, thanks.

^ permalink raw reply

* Re: [patch net-next 00/15] devlink: allow devlink instances to change network namespace
From: David Miller @ 2019-09-16  7:01 UTC (permalink / raw)
  To: jiri
  Cc: netdev, idosch, dsahern, jakub.kicinski, tariqt, saeedm, kuznet,
	yoshfuji, shuah, mlxsw
In-Reply-To: <20190914064608.26799-1-jiri@resnulli.us>


Jiri, this has to wait until the next merge window sorry.

^ permalink raw reply

* Re: [PATCH net-next v2 1/3] mlxsw: spectrum_buffers: Prevent changing CPU port's configuration
From: Jiri Pirko @ 2019-09-16  7:00 UTC (permalink / raw)
  To: Ido Schimmel; +Cc: netdev, davem, jiri, shalomt, mlxsw, Ido Schimmel
In-Reply-To: <20190916061750.26207-2-idosch@idosch.org>

Mon, Sep 16, 2019 at 08:17:48AM CEST, idosch@idosch.org wrote:
>From: Shalom Toledo <shalomt@mellanox.com>
>
>Next patch is going to register the CPU port with devlink, but only so
>that the CPU port's shared buffer configuration and occupancy could be
>queried.
>
>Prevent changing CPU port's shared buffer threshold and binding
>configuration.
>
>Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
>Signed-off-by: Ido Schimmel <idosch@mellanox.com>

Acked-by: Jiri Pirko <jiri@mellanox.com>

^ permalink raw reply

* Re: [PATCH v2] net: stmmac: socfpga: re-use the `interface` parameter from platform data
From: Ardelean, Alexandru @ 2019-09-16  6:58 UTC (permalink / raw)
  To: davem@davemloft.net
  Cc: linux-stm32@st-md-mailman.stormreply.com, joabreu@synopsys.com,
	linux-kernel@vger.kernel.org, mcoquelin.stm32@gmail.com,
	netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	peppe.cavallaro@st.com, alexandre.torgue@st.com
In-Reply-To: <20190915.195149.86866545205816280.davem@davemloft.net>

On Sun, 2019-09-15 at 19:51 +0100, David Miller wrote:
> [External]
> 
> From: Alexandru Ardelean <alexandru.ardelean@analog.com>
> Date: Thu, 12 Sep 2019 16:28:50 +0300
> 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-
> > socfpga.c
> > index c141fe783e87..5b6213207c43 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
>  ...
> > +static inline int socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
> 
> Please do not use the inline keyword in foo.c files, let the compiler device.

Ack.
Will remove.


^ permalink raw reply

* Re: [v3 2/3] samples: pktgen: add helper functions for IP(v4/v6) CIDR parsing
From: Jesper Dangaard Brouer @ 2019-09-16  6:53 UTC (permalink / raw)
  To: Daniel T. Lee
  Cc: David S . Miller, netdev, brouer,
	Toke Høiland-Jørgensen
In-Reply-To: <20190914151353.18054-2-danieltimlee@gmail.com>

On Sun, 15 Sep 2019 00:13:52 +0900
"Daniel T. Lee" <danieltimlee@gmail.com> wrote:

> This commit adds CIDR parsing and IP validate helper function to parse
> single IP or range of IP with CIDR. (e.g. 198.18.0.0/15)
> 
> Helpers will be used in prior to set target address in samples/pktgen.
> 
> Signed-off-by: Daniel T. Lee <danieltimlee@gmail.com>
> ---
> Changes since v3:
>  * Set errexit option to stop script execution on error
> 
>  samples/pktgen/functions.sh | 124 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 124 insertions(+)
> 
> diff --git a/samples/pktgen/functions.sh b/samples/pktgen/functions.sh
> index 4af4046d71be..87ae61701904 100644
> --- a/samples/pktgen/functions.sh
> +++ b/samples/pktgen/functions.sh
> @@ -5,6 +5,8 @@
>  # Author: Jesper Dangaaard Brouer
>  # License: GPL
>  
> +set -o errexit

Unfortunately, this breaks the scripts.

The function proc_cmd are designed to grep after "Result: OK:" which
might fail, and your patch/change makes the script stop immediately.
We actually want to continue, and output what command that failed (and
also grep again after "Result:" to provide the kernel reason).

Even if you somehow "fix" function proc_cmd, then we in general want to
catch different error situations by looking at status $?, and output
meaning full errors via calling err() function.  IHMO as minimum with
errexit you need a 'trap' function that can help/inform the user of
what went wrong.

-- 
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 2/2] dt-bindings: net: dwmac: document 'mac-mode' property
From: Ardelean, Alexandru @ 2019-09-16  6:49 UTC (permalink / raw)
  To: robh@kernel.org
  Cc: alexandre.torgue@st.com, --cc=andrew@lunn.ch,
	devicetree@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, peppe.cavallaro@st.com,
	davem@davemloft.net
In-Reply-To: <5d7ba95d.1c69fb81.dabe4.8057@mx.google.com>

On Fri, 2019-09-13 at 15:36 +0100, Rob Herring wrote:
> [External]
> 
> On Fri, Sep 06, 2019 at 04:02:56PM +0300, Alexandru Ardelean wrote:
> > This change documents the 'mac-mode' property that was introduced in the
> > 'stmmac' driver to support passive mode converters that can sit in-between
> > the MAC & PHY.
> > 
> > Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
> > ---
> >  Documentation/devicetree/bindings/net/snps,dwmac.yaml | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > index c78be15704b9..ebe4537a7cce 100644
> > --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > @@ -112,6 +112,14 @@ properties:
> >    reset-names:
> >      const: stmmaceth
> >  
> > +  mac-mode:
> > +    maxItems: 1
> 
> Is this an array because {min,max}Items is for arrays? It should be 
> defined as a string with possible values.
> 
> As this property is the same as another, you can do this:
> 
> $ref: ethernet-controller.yaml#/properties/phy-connection-type
> 
> Unless only a small subset of those values are valid here, then you may 
> want to list them here.
> 

Ack.
Thank you.

Will investigate and re-spin.


> > +    description:
> > +      The property is identical to 'phy-mode', and assumes that there is mode
> > +      converter in-between the MAC & PHY (e.g. GMII-to-RGMII). This converter
> > +      can be passive (no SW requirement), and requires that the MAC operate
> > +      in a different mode than the PHY in order to function.
> > +
> >    snps,axi-config:
> >      $ref: /schemas/types.yaml#definitions/phandle
> >      description:
> > -- 
> > 2.20.1
> > 

^ 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