Netdev List
 help / color / mirror / Atom feed
* RE: [PATCH net] net: fec: Coverity issue: Dereference null return value
From: Wei Fang @ 2022-12-19  2:21 UTC (permalink / raw)
  To: Alexander H Duyck, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, Clark Wang, Shenwei Wang,
	dl-linux-imx
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <be98552a061f6249de558b210ff25de45e80d690.camel@gmail.com>


> -----Original Message-----
> From: Alexander H Duyck <alexander.duyck@gmail.com>
> Sent: 2022年12月16日 23:34
> To: Wei Fang <wei.fang@nxp.com>; davem@davemloft.net;
> edumazet@google.com; kuba@kernel.org; pabeni@redhat.com; Clark Wang
> <xiaoning.wang@nxp.com>; Shenwei Wang <shenwei.wang@nxp.com>;
> dl-linux-imx <linux-imx@nxp.com>
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH net] net: fec: Coverity issue: Dereference null return value
> 
> On Thu, 2022-12-15 at 17:11 +0800, wei.fang@nxp.com wrote:
> > From: Wei Fang <wei.fang@nxp.com>
> >
> > The build_skb might return a null pointer but there is no check on the
> > return value in the fec_enet_rx_queue(). So a null pointer dereference
> > might occur. To avoid this, we check the return value of build_skb. If
> > the return value is a null pointer, the driver will recycle the page
> > and update the statistic of ndev. Then jump to rx_processing_done to
> > clear the status flags of the BD so that the hardware can recycle the BD.
> >
> > Signed-off-by: Wei Fang <wei.fang@nxp.com>
> > Reviewed-by: Shenwei Wang <Shenwei.wang@nxp.com>
> > ---
> >  drivers/net/ethernet/freescale/fec_main.c | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/drivers/net/ethernet/freescale/fec_main.c
> > b/drivers/net/ethernet/freescale/fec_main.c
> > index 5528b0af82ae..c78aaa780983 100644
> > --- a/drivers/net/ethernet/freescale/fec_main.c
> > +++ b/drivers/net/ethernet/freescale/fec_main.c
> > @@ -1674,6 +1674,16 @@ fec_enet_rx_queue(struct net_device *ndev, int
> budget, u16 queue_id)
> >  		 * bridging applications.
> >  		 */
> >  		skb = build_skb(page_address(page), PAGE_SIZE);
> > +		if (unlikely(!skb)) {
> > +			page_pool_recycle_direct(rxq->page_pool, page);
> > +			ndev->stats.rx_packets--;
> > +			ndev->stats.rx_bytes -= pkt_len;
> > +			ndev->stats.rx_dropped++;
> 
> I'm not sure you really need to bother with rewinding the rx_packets and
> rx_bytes counters. I know that the rx_dropped statistic will get incremented in
> the network stack in the event of a packet failing to enqueue to the backlog, so
> it might be better to just leave the rx_packets counter as is and assume the
> actual packet count is rx_packets - rx_dropped.
> 
According to your advice, I looked up the Linux document, actually as you said,
the rx_packets should include packets which host had to drop at various stages
of processing (even in the driver). Thanks for your review, I‘ll amend this in the
next version.

> > +
> > +			netdev_err(ndev, "build_skb failed!\n");
> 
> Instead of netdev_err you may want to consider netdev_err_once for this.
> Generally speaking when we start seeing memory allocation error issues they
> can get very noisy very quickly as you are likely to fail the allocation for every
> packet in a given polling session, and sessions to follow.
> 
Yes, it's better to use netdev_err_once than netdev_err in the situation you describe.
Thanks again!

> > +			goto rx_processing_done;
> > +		}
> > +
> >  		skb_reserve(skb, data_start);
> >  		skb_put(skb, pkt_len - sub_len);
> >  		skb_mark_for_recycle(skb);


^ permalink raw reply

* Re: [PATCH iproute2-next 0/6] bridge: mdb: Add support for new attributes
From: patchwork-bot+netdevbpf @ 2022-12-19  1:50 UTC (permalink / raw)
  To: Ido Schimmel; +Cc: netdev, dsahern, stephen, razor, mlxsw
In-Reply-To: <20221215175230.1907938-1-idosch@nvidia.com>

Hello:

This series was applied to iproute2/iproute2-next.git (main)
by David Ahern <dsahern@kernel.org>:

On Thu, 15 Dec 2022 19:52:24 +0200 you wrote:
> Add support for new MDB attributes and replace command.
> 
> See kernel merge commit 8150f0cfb24f ("Merge branch
> 'bridge-mcast-extensions-for-evpn'") for background and motivation.
> 
> Patches #1-#2 are preparations.
> 
> [...]

Here is the summary with links:
  - [iproute2-next,1/6] bridge: mdb: Use a boolean to indicate nest is required
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=935d942e6939
  - [iproute2-next,2/6] bridge: mdb: Split source parsing to a separate function
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=c305c76a01e1
  - [iproute2-next,3/6] bridge: mdb: Add filter mode support
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=7fe47f5160d3
  - [iproute2-next,4/6] bridge: mdb: Add source list support
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=aa9a0b0fa9c2
  - [iproute2-next,5/6] bridge: mdb: Add routing protocol support
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=7921c336dba4
  - [iproute2-next,6/6] bridge: mdb: Add replace support
    https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=9edecafda31e

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* [PATCH 0/2] ip/ip6_gre: Fix GRE tunnels not generating IPv6 link local addresses
From: Thomas Winter @ 2022-12-19  1:06 UTC (permalink / raw)
  To: davem, yoshfuji, dsahern, kuba, a, netdev, linux-kernel; +Cc: Thomas Winter

For our point-to-point GRE tunnels, they have IN6_ADDR_GEN_MODE_NONE
when they are created then we set IN6_ADDR_GEN_MODE_EUI64 when they
come up to generate the IPv6 link local address for the interface.
Recently we found that they were no longer generating IPv6 addresses.

Also, non-point-to-point tunnels were not generating any IPv6 link
local address and instead generating an IPv6 compat address,
breaking IPv6 communication on the tunnel.

These failures were caused by commit e5dd729460ca and this patch set
aims to resolve these issues.

Thomas Winter (2):
  ip/ip6_gre: Fix changing addr gen mode not generating IPv6 link local
    address
  ip/ip6_gre: Fix non-point-to-point tunnel not generating IPv6 link
    local address

 net/ipv6/addrconf.c | 57 ++++++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

-- 
2.37.3


^ permalink raw reply

* [PATCH 2/2] ip/ip6_gre: Fix non-point-to-point tunnel not generating IPv6 link local address
From: Thomas Winter @ 2022-12-19  1:06 UTC (permalink / raw)
  To: davem, yoshfuji, dsahern, kuba, a, netdev, linux-kernel; +Cc: Thomas Winter
In-Reply-To: <20221219010619.1826599-1-Thomas.Winter@alliedtelesis.co.nz>

Previously, addrconf_gre_config always would call addrconf_addr_gen
and generate a EUI64 link local address for the tunnel.
Then commit e5dd729460ca changed the code path so that add_v4_addrs
is called but this only generates a compat IPv6 address for
non-point-to-point tunnels.

I assume the compat address is specifically for SIT tunnels so
have kept that only for SIT - GRE tunnels now always generate link
local addresses.

Fixes: e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address")
Signed-off-by: Thomas Winter <Thomas.Winter@alliedtelesis.co.nz>
---
 net/ipv6/addrconf.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e9d7ec03316d..a51fb106fa4a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3129,17 +3129,17 @@ static void add_v4_addrs(struct inet6_dev *idev)
 		offset = sizeof(struct in6_addr) - 4;
 	memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4);
 
-	if (idev->dev->flags&IFF_POINTOPOINT) {
+	if (!(idev->dev->flags & IFF_POINTOPOINT) && idev->dev->type == ARPHRD_SIT) {
+		scope = IPV6_ADDR_COMPATv4;
+		plen = 96;
+		pflags |= RTF_NONEXTHOP;
+	} else {
 		if (idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_NONE)
 			return;
 
 		addr.s6_addr32[0] = htonl(0xfe800000);
 		scope = IFA_LINK;
 		plen = 64;
-	} else {
-		scope = IPV6_ADDR_COMPATv4;
-		plen = 96;
-		pflags |= RTF_NONEXTHOP;
 	}
 
 	if (addr.s6_addr32[3]) {
-- 
2.37.3


^ permalink raw reply related

* [PATCH 1/2] ip/ip6_gre: Fix changing addr gen mode not generating IPv6 link local address
From: Thomas Winter @ 2022-12-19  1:06 UTC (permalink / raw)
  To: davem, yoshfuji, dsahern, kuba, a, netdev, linux-kernel; +Cc: Thomas Winter
In-Reply-To: <20221219010619.1826599-1-Thomas.Winter@alliedtelesis.co.nz>

Commit e5dd729460ca changed the code path so that GRE tunnels
generate an IPv6 address based on the tunnel source address.
It also changed the code path so GRE tunnels don't call addrconf_addr_gen
in addrconf_dev_config which is called by addrconf_sysctl_addr_gen_mode
when the IN6_ADDR_GEN_MODE is changed.

This patch aims to fix this issue by moving the code in addrconf_notify
which calls the addr gen for GRE and SIT into a separate function
and calling it in the places that expect the IPv6 address to be
generated.

The previous addrconf_dev_config is renamed to addrconf_eth_config
since it only expected eth type interfaces and follows the
addrconf_gre/sit_config format.

Fixes: e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address")
Signed-off-by: Thomas Winter <Thomas.Winter@alliedtelesis.co.nz>
---
 net/ipv6/addrconf.c | 47 +++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6dcf034835ec..e9d7ec03316d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3355,7 +3355,7 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)
 	}
 }
 
-static void addrconf_dev_config(struct net_device *dev)
+static void addrconf_eth_config(struct net_device *dev)
 {
 	struct inet6_dev *idev;
 
@@ -3447,6 +3447,30 @@ static void addrconf_gre_config(struct net_device *dev)
 }
 #endif
 
+static void addrconf_dev_config(struct net_device *dev)
+{
+	switch (dev->type) {
+#if IS_ENABLED(CONFIG_IPV6_SIT)
+	case ARPHRD_SIT:
+		addrconf_sit_config(dev);
+		break;
+#endif
+#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE)
+	case ARPHRD_IP6GRE:
+	case ARPHRD_IPGRE:
+		addrconf_gre_config(dev);
+		break;
+#endif
+	case ARPHRD_LOOPBACK:
+		init_loopback(dev);
+		break;
+
+	default:
+		addrconf_eth_config(dev);
+		break;
+	}
+}
+
 static int fixup_permanent_addr(struct net *net,
 				struct inet6_dev *idev,
 				struct inet6_ifaddr *ifp)
@@ -3611,26 +3635,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 			run_pending = 1;
 		}
 
-		switch (dev->type) {
-#if IS_ENABLED(CONFIG_IPV6_SIT)
-		case ARPHRD_SIT:
-			addrconf_sit_config(dev);
-			break;
-#endif
-#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE)
-		case ARPHRD_IP6GRE:
-		case ARPHRD_IPGRE:
-			addrconf_gre_config(dev);
-			break;
-#endif
-		case ARPHRD_LOOPBACK:
-			init_loopback(dev);
-			break;
-
-		default:
-			addrconf_dev_config(dev);
-			break;
-		}
+		addrconf_dev_config(dev);
 
 		if (!IS_ERR_OR_NULL(idev)) {
 			if (run_pending)
-- 
2.37.3


^ permalink raw reply related

* Re: [PATCH net 7/9] rxrpc: Fix I/O thread stop
From: David Howells @ 2022-12-19  0:20 UTC (permalink / raw)
  To: Hillf Danton; +Cc: dhowells, netdev, Marc Dionne, linux-afs, linux-kernel
In-Reply-To: <20221218120951.1212-1-hdanton@sina.com>

Hillf Danton <hdanton@sina.com> wrote:

> > So once we've observed that we've been asked to stop, we need to check if
> > there's more work to be done and, if so, do that work first.
> 
> In line with
> 
> 	if (condition)
> 		return;
> 	add to wait queue
> 	if (!condition)
> 		schedule();
> 
> this change should look like
> 
>    		if (!skb_queue_empty(&local->rx_queue) ...)
>  			continue;
> 
>  		if (kthread_should_stop())
>    			if (!skb_queue_empty(&local->rx_queue) ...)
>  				continue;
> 			else
>   				break;
> 
> as checking condition once barely makes sense.

Note that these are not really analogous.  The add-to-wait-queue step is
significantly more expensive than kthread_should_stop() and requires removal
in the event that the condition becomes true in the window.

In the case of kthread_should_stop(), it's just a test_bit() of a word that's
in a cacheline not going to get changed until the thread is stopped.  Testing
the value first and then checking the condition should be fine as the stop
flag can be shared in the cpu's data cache until it's set.

Also from a code-maintenance PoV, I don't want to write the condition twice if
I can avoid it.  That allows for the two copies to get out of sync.

> Because of a bit complex condition does not mean checking it once is neither
> sane nor correct.

So you agree with me, I think?

David


^ permalink raw reply

* [net-next] ipv6: fix routing cache overflow for raw sockets
From: Jon Maxwell @ 2022-12-18 23:48 UTC (permalink / raw)
  To: davem
  Cc: edumazet, kuba, pabeni, yoshfuji, dsahern, netdev, linux-kernel,
	Jon Maxwell

Sending Ipv6 packets in a loop via a raw socket triggers an issue where a 
route is cloned by ip6_rt_cache_alloc() for each packet sent. This quickly 
consumes the Ipv6 max_size threshold which defaults to 4096 resulting in 
these warnings:

[1]   99.187805] dst_alloc: 7728 callbacks suppressed
[2] Route cache is full: consider increasing sysctl net.ipv6.route.max_size.
.
.
[300] Route cache is full: consider increasing sysctl net.ipv6.route.max_size.

When this happens the packet is dropped and sendto() gets a network is 
unreachable error:

# ./a.out -s 

remaining pkt 200557 errno 101
remaining pkt 196462 errno 101
.
.
remaining pkt 126821 errno 101

Fix this by adding a flag to prevent the cloning of routes for raw sockets. 
Which makes the Ipv6 routing code use per-cpu routes instead which prevents 
packet drop due to max_size overflow. 

Ipv4 is not affected because it has a very large default max_size.

Signed-off-by: Jon Maxwell <jmaxwell37@gmail.com>
---
 include/net/flow.h | 1 +
 net/ipv6/raw.c     | 2 +-
 net/ipv6/route.c   | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/net/flow.h b/include/net/flow.h
index 2f0da4f0318b..30b8973ffb4b 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -37,6 +37,7 @@ struct flowi_common {
 	__u8	flowic_flags;
 #define FLOWI_FLAG_ANYSRC		0x01
 #define FLOWI_FLAG_KNOWN_NH		0x02
+#define FLOWI_FLAG_SKIP_RAW		0x04
 	__u32	flowic_secid;
 	kuid_t  flowic_uid;
 	struct flowi_tunnel flowic_tun_key;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a06a9f847db5..0b89a7e66d09 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -884,7 +884,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
 
 	if (hdrincl)
-		fl6.flowi6_flags |= FLOWI_FLAG_KNOWN_NH;
+		fl6.flowi6_flags |= FLOWI_FLAG_KNOWN_NH | FLOWI_FLAG_SKIP_RAW;
 
 	if (ipc6.tclass < 0)
 		ipc6.tclass = np->tclass;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e74e0361fd92..beae0bd61738 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2226,6 +2226,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
 	if (rt) {
 		goto out;
 	} else if (unlikely((fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH) &&
+			    !(fl6->flowi6_flags & FLOWI_FLAG_SKIP_RAW) &&
 			    !res.nh->fib_nh_gw_family)) {
 		/* Create a RTF_CACHE clone which will not be
 		 * owned by the fib6 tree.  It is for the special case where
-- 
2.31.1


^ permalink raw reply related

* Re: [PULL] Networking for next-6.1
From: Kuniyuki Iwashima @ 2022-12-18 23:25 UTC (permalink / raw)
  To: jirislaby
  Cc: davem, joannelkoong, kuba, linux-kernel, netdev, pabeni, edumazet,
	kuniyu
In-Reply-To: <6b971a4e-c7d8-411e-1f92-fda29b5b2fb9@kernel.org>

From:   Jiri Slaby <jirislaby@kernel.org>
Date:   Fri, 16 Dec 2022 11:49:01 +0100
> Hi,
> 
> On 04. 10. 22, 7:20, Jakub Kicinski wrote:
> > Joanne Koong (7):
> 
> >        net: Add a bhash2 table hashed by port and address
> 
> This makes regression tests of python-ephemeral-port-reserve to fail.
> 
> I'm not sure if the issue is in the commit or in the test.

Hi Jiri,

Thanks for reporting the issue.

It seems we forgot to add TIME_WAIT sockets into bhash2 in
inet_twsk_hashdance(), therefore inet_bhash2_conflict() misses
TIME_WAIT sockets when validating bind() requests if the address
is not a wildcard one.

I'll fix it.

Thank you.

> 
> This C reproducer used to fail with 6.0, now it succeeds:
> #include <err.h>
> #include <errno.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> 
> #include <sys/socket.h>
> 
> #include <arpa/inet.h>
> #include <netinet/ip.h>
> 
> int main()
> {
>          int x;
>          int s1 = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP);
>          if (s1 < 0)
>                  err(1, "sock1");
>          x = 1;
>          if (setsockopt(s1, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)))
>                  err(1, "setsockopt1");
> 
>          struct sockaddr_in in = {
>                  .sin_family = AF_INET,
>                  .sin_port = INADDR_ANY,
>                  .sin_addr = { htonl(INADDR_LOOPBACK) },
>          };
>          if (bind(s1, (const struct sockaddr *)&in, sizeof(in)) < 0)
>                  err(1, "bind1");
> 
>          if (listen(s1, 1) < 0)
>                  err(1, "listen1");
> 
>          socklen_t inl = sizeof(in);
>          if (getsockname(s1, (struct sockaddr *)&in, &inl) < 0)
>                  err(1, "getsockname1");
> 
>          int s2 = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP);
>          if (s1 < 0)
>                  err(1, "sock2");
> 
>          if (connect(s2, (struct sockaddr *)&in, inl) < 0)
>                  err(1, "conn2");
> 
>          struct sockaddr_in acc;
>          inl = sizeof(acc);
>          int fdX = accept(s1, (struct sockaddr *)&acc, &inl);
>          if (fdX < 0)
>                  err(1, "accept");
> 
>          close(fdX);
>          close(s2);
>          close(s1);
> 
>          int s3 = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP);
>          if (s3 < 0)
>                  err(1, "sock3");
> 
>          if (bind(s3, (struct sockaddr *)&in, sizeof(in)) < 0)
>                  err(1, "bind3");
> 
>          close(s3);
> 
>          return 0;
> }
> 
> 
> 
> thanks,
> -- 
> js
> suse labs

^ permalink raw reply

* [PATCH net-next v1 1/2] net: marvell: prestera: Add router ipv6 ABI
From: Yevhen Orlov @ 2022-12-18 22:16 UTC (permalink / raw)
  To: netdev
  Cc: Volodymyr Mytnyk, Taras Chornyi, Mickey Rachamim, Serhiy Pshyk,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, Stephen Hemminger, linux-kernel

There are only lpm add/del for ipv6 needed.
Nexthops indexes shared with ipv4.

Limitations:
- Only "local" and "main" tables supported
- Only generic interfaces supported for router (no bridges or vlans)

Co-developed-by: Taras Chornyi <taras.chornyi@plvision.eu>
Signed-off-by: Taras Chornyi <taras.chornyi@plvision.eu>
Co-developed-by: Elad Nachman <enachman@marvell.com>
Signed-off-by: Elad Nachman <enachman@marvell.com>
Signed-off-by: Yevhen Orlov <yevhen.orlov@plvision.eu>
---
 .../ethernet/marvell/prestera/prestera_hw.c   | 34 +++++++++++++++++++
 .../ethernet/marvell/prestera/prestera_hw.h   |  4 +++
 .../marvell/prestera/prestera_router_hw.c     | 33 ++++++++++++++----
 3 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
index fc6f7d2746e8..13341056599a 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_hw.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
@@ -540,6 +540,11 @@ struct prestera_msg_iface {
 	u8 __pad[3];
 };
 
+enum prestera_msg_ip_addr_v {
+	PRESTERA_MSG_IPV4 = 0,
+	PRESTERA_MSG_IPV6
+};
+
 struct prestera_msg_ip_addr {
 	union {
 		__be32 ipv4;
@@ -2088,6 +2093,35 @@ int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id,
 			    sizeof(req));
 }
 
+int prestera_hw_lpm6_add(struct prestera_switch *sw, u16 vr_id,
+			 __u8 *dst, u32 dst_len, u32 grp_id)
+{
+	struct prestera_msg_lpm_req req;
+
+	req.dst.v = PRESTERA_MSG_IPV6;
+	memcpy(&req.dst.u.ipv6, dst, 16);
+	req.dst_len = __cpu_to_le32(dst_len);
+	req.vr_id = __cpu_to_le16(vr_id);
+	req.grp_id = __cpu_to_le32(grp_id);
+
+	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_ADD, &req.cmd,
+			    sizeof(req));
+}
+
+int prestera_hw_lpm6_del(struct prestera_switch *sw, u16 vr_id,
+			 __u8 *dst, u32 dst_len)
+{
+	struct prestera_msg_lpm_req req;
+
+	req.dst.v = PRESTERA_MSG_IPV6;
+	memcpy(&req.dst.u.ipv6, dst, 16);
+	req.dst_len = __cpu_to_le32(dst_len);
+	req.vr_id = __cpu_to_le16(vr_id);
+
+	return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE, &req.cmd,
+			    sizeof(req));
+}
+
 int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count,
 			       struct prestera_neigh_info *nhs, u32 grp_id)
 {
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.h b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
index 0a929279e1ce..8769be6752bc 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_hw.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
@@ -266,6 +266,10 @@ int prestera_hw_lpm_add(struct prestera_switch *sw, u16 vr_id,
 			__be32 dst, u32 dst_len, u32 grp_id);
 int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id,
 			__be32 dst, u32 dst_len);
+int prestera_hw_lpm6_add(struct prestera_switch *sw, u16 vr_id,
+			 __u8 *dst, u32 dst_len, u32 grp_id);
+int prestera_hw_lpm6_del(struct prestera_switch *sw, u16 vr_id,
+			 __u8 *dst, u32 dst_len);
 
 /* NH API */
 int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count,
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
index 02faaea2aefa..1c6d0cdbdfdf 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
@@ -581,8 +581,16 @@ static void __prestera_fib_node_destruct(struct prestera_switch *sw,
 	struct prestera_vr *vr;
 
 	vr = fib_node->info.vr;
-	prestera_hw_lpm_del(sw, vr->hw_vr_id, fib_node->key.addr.u.ipv4,
-			    fib_node->key.prefix_len);
+	if (fib_node->key.addr.v == PRESTERA_IPV4)
+		prestera_hw_lpm_del(sw, vr->hw_vr_id, fib_node->key.addr.u.ipv4,
+				    fib_node->key.prefix_len);
+	else if (fib_node->key.addr.v == PRESTERA_IPV6)
+		prestera_hw_lpm6_del(sw, vr->hw_vr_id,
+				     (u8 *)&fib_node->key.addr.u.ipv6.s6_addr,
+				     fib_node->key.prefix_len);
+	else
+		WARN(1, "Invalid address version. Memory corrupted?");
+
 	switch (fib_node->info.type) {
 	case PRESTERA_FIB_TYPE_UC_NH:
 		prestera_nexthop_group_put(sw, fib_node->info.nh_grp);
@@ -661,8 +669,16 @@ prestera_fib_node_create(struct prestera_switch *sw,
 		goto err_nh_grp_get;
 	}
 
-	err = prestera_hw_lpm_add(sw, vr->hw_vr_id, key->addr.u.ipv4,
-				  key->prefix_len, grp_id);
+	if (key->addr.v == PRESTERA_IPV4)
+		err = prestera_hw_lpm_add(sw, vr->hw_vr_id, key->addr.u.ipv4,
+					  key->prefix_len, grp_id);
+	else if (key->addr.v == PRESTERA_IPV6)
+		err = prestera_hw_lpm6_add(sw, vr->hw_vr_id,
+					   (u8 *)&key->addr.u.ipv6.s6_addr,
+					   key->prefix_len, grp_id);
+	else
+		WARN(1, "Invalid address version. Memory corrupted?");
+
 	if (err)
 		goto err_lpm_add;
 
@@ -674,8 +690,13 @@ prestera_fib_node_create(struct prestera_switch *sw,
 	return fib_node;
 
 err_ht_insert:
-	prestera_hw_lpm_del(sw, vr->hw_vr_id, key->addr.u.ipv4,
-			    key->prefix_len);
+	if (key->addr.v == PRESTERA_IPV4)
+		prestera_hw_lpm_del(sw, vr->hw_vr_id, key->addr.u.ipv4,
+				    key->prefix_len);
+	else if (key->addr.v == PRESTERA_IPV6)
+		prestera_hw_lpm6_del(sw, vr->hw_vr_id,
+				     (u8 *)&key->addr.u.ipv6.s6_addr,
+				     key->prefix_len);
 err_lpm_add:
 	if (fib_type == PRESTERA_FIB_TYPE_UC_NH)
 		prestera_nexthop_group_put(sw, fib_node->info.nh_grp);
-- 
2.17.1


^ permalink raw reply related

* Re: [PATCH 1/2] ip/ip6_gre: Fix changing addr gen mode not generating IPv6 link local address
From: Stephen Hemminger @ 2022-12-18 22:16 UTC (permalink / raw)
  To: Thomas Winter; +Cc: davem, yoshfuji, dsahern, kuba, a, netdev, linux-kernel
In-Reply-To: <20221218215718.1491444-2-Thomas.Winter@alliedtelesis.co.nz>

On Mon, 19 Dec 2022 10:57:17 +1300
Thomas Winter <Thomas.Winter@alliedtelesis.co.nz> wrote:

> +	switch (dev->type) {
> +	#if IS_ENABLED(CONFIG_IPV6_SIT)
> +	case ARPHRD_SIT:
> +		addrconf_sit_config(dev);
> +		break;
> +	#endif
> +	#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE)
> +	case ARPHRD_IP6GRE:
> +	case ARPHRD_IPGRE:
> +		addrconf_gre_config(dev);
> +		break;
> +	#endif

Linux kernel style is to start any conditional compilation in first column

I.e.

#if IS_ENABLED(CONFIG_IPV6_SIT)

Not
	#if IS_ENABLED(CONFIG_IPV6_SIT)

^ permalink raw reply

* [PATCH net-next v1 2/2] net: marvell: prestera: Handle ipv6 lpm/neigh events
From: Yevhen Orlov @ 2022-12-18 22:16 UTC (permalink / raw)
  To: netdev
  Cc: Volodymyr Mytnyk, Taras Chornyi, Mickey Rachamim, Serhiy Pshyk,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, Stephen Hemminger, linux-kernel

Handle AF_INET6 for events:
 - NETEVENT_NEIGH_UPDATE
 - FIB_EVENT_ENTRY_REPLACE
 - FIB_EVENT_ENTRY_DEL

Also try to make wrappers for ipv4/6 specific functions.
This allow us to pass fib_notifier_info for most cases.
E.g  prestera_util_fen_info_copy, prestera_util_fen_info_release.
Main idea is to increase number of agnostic about ip version functions.

Limitations:
- Only "local" and "main" tables supported
- Only generic interfaces supported for router (no bridges or vlans)

Co-developed-by: Taras Chornyi <taras.chornyi@plvision.eu>
Signed-off-by: Taras Chornyi <taras.chornyi@plvision.eu>
Co-developed-by: Elad Nachman <enachman@marvell.com>
Signed-off-by: Elad Nachman <enachman@marvell.com>
Signed-off-by: Yevhen Orlov <yevhen.orlov@plvision.eu>
---
 .../marvell/prestera/prestera_router.c        | 138 +++++++++++++-----
 1 file changed, 101 insertions(+), 37 deletions(-)

diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router.c b/drivers/net/ethernet/marvell/prestera/prestera_router.c
index a9a1028cb17b..5ee0a9511878 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_router.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_router.c
@@ -12,6 +12,7 @@
 #include <linux/if_vlan.h>
 #include <linux/if_macvlan.h>
 #include <net/netevent.h>
+#include <net/ip6_route.h>
 
 #include "prestera.h"
 #include "prestera_router_hw.h"
@@ -60,6 +61,7 @@ struct prestera_kern_fib_cache {
 	union {
 		struct fib_notifier_info info; /* point to any of 4/6 */
 		struct fib_entry_notifier_info fen4_info;
+		struct fib6_entry_notifier_info fen6_info;
 	};
 	bool reachable;
 };
@@ -89,18 +91,67 @@ static u32 prestera_fix_tb_id(u32 tb_id)
 	return tb_id;
 }
 
+static void
+prestera_util_fen_info_copy(struct fib_notifier_info *sinfo,
+			    struct fib_notifier_info *tinfo)
+{
+	struct fib6_entry_notifier_info *sinfo6 =
+		container_of(sinfo, struct fib6_entry_notifier_info, info);
+	struct fib_entry_notifier_info *sinfo4 =
+		container_of(sinfo, struct fib_entry_notifier_info, info);
+	struct fib6_entry_notifier_info *tinfo6 =
+		container_of(tinfo, struct fib6_entry_notifier_info, info);
+	struct fib_entry_notifier_info *tinfo4 =
+		container_of(tinfo, struct fib_entry_notifier_info, info);
+
+	if (sinfo->family == AF_INET) {
+		fib_info_hold(sinfo4->fi);
+		*tinfo4 = *sinfo4;
+	} else if (sinfo->family == AF_INET6) {
+		fib6_info_hold(sinfo6->rt);
+		*tinfo6 = *sinfo6;
+	} else {
+		WARN(1, "Invalid address family %s %d", __func__, sinfo->family);
+	}
+}
+
+static void prestera_util_fen_info_release(struct fib_notifier_info *info)
+{
+	struct fib6_entry_notifier_info *info6 =
+		container_of(info, struct fib6_entry_notifier_info, info);
+	struct fib_entry_notifier_info *info4 =
+		container_of(info, struct fib_entry_notifier_info, info);
+
+	if (info->family == AF_INET)
+		fib_info_put(info4->fi);
+	else if (info->family == AF_INET6)
+		fib6_info_release(info6->rt);
+	else
+		WARN(1, "Invalid address family %s %d",
+		     __func__, info->family);
+}
+
 static void
 prestera_util_fen_info2fib_cache_key(struct fib_notifier_info *info,
 				     struct prestera_kern_fib_cache_key *key)
 {
+	struct fib6_entry_notifier_info *fen6_info =
+		container_of(info, struct fib6_entry_notifier_info, info);
 	struct fib_entry_notifier_info *fen_info =
 		container_of(info, struct fib_entry_notifier_info, info);
 
 	memset(key, 0, sizeof(*key));
-	key->addr.v = PRESTERA_IPV4;
-	key->addr.u.ipv4 = cpu_to_be32(fen_info->dst);
-	key->prefix_len = fen_info->dst_len;
-	key->kern_tb_id = fen_info->tb_id;
+	if (info->family == AF_INET) {
+		key->addr.v = PRESTERA_IPV4;
+		key->addr.u.ipv4 = cpu_to_be32(fen_info->dst);
+		key->prefix_len = fen_info->dst_len;
+		key->kern_tb_id = fen_info->tb_id;
+	} else if (info->family == AF_INET6) {
+		key->addr.v = PRESTERA_IPV6;
+		key->addr.u.ipv6 = fen6_info->rt->fib6_dst.addr;
+		key->prefix_len = fen6_info->rt->fib6_dst.plen;
+		key->kern_tb_id = fen6_info->rt->fib6_table->tb6_id;
+	}
 }
 
 static int prestera_util_nhc2nc_key(struct prestera_switch *sw,
@@ -155,6 +206,9 @@ prestera_util_neigh2nc_key(struct prestera_switch *sw, struct neighbour *n,
 	if (n->tbl->family == AF_INET) {
 		key->addr.v = PRESTERA_IPV4;
 		key->addr.u.ipv4 = *(__be32 *)n->primary_key;
+	} else if (n->tbl->family == AF_INET6) {
+		key->addr.v = PRESTERA_IPV6;
+		key->addr.u.ipv6 = *(struct in6_addr *)n->primary_key;
 	} else {
 		return -ENOENT;
 	}
@@ -683,8 +737,15 @@ __prestera_k_arb_n_offload_set(struct prestera_switch *sw,
 {
 	struct neighbour *n;
 
-	n = neigh_lookup(&arp_tbl, &nc->key.addr.u.ipv4,
-			 nc->key.dev);
+	if (nc->key.addr.v == PRESTERA_IPV4)
+		n = neigh_lookup(&arp_tbl, &nc->key.addr.u.ipv4,
+				 nc->key.dev);
+	else if (nc->key.addr.v == PRESTERA_IPV6)
+		n = neigh_lookup(&nd_tbl, &nc->key.addr.u.ipv6,
+				 nc->key.dev);
+	else
+		n = NULL;
+
 	if (!n)
 		return;
 
@@ -715,7 +776,8 @@ __prestera_k_arb_fib_lpm_offload_set(struct prestera_switch *sw,
 		fib_alias_hw_flags_set(&init_net, &fri);
 		return;
 	case PRESTERA_IPV6:
-		/* TODO */
+		fib6_info_hw_flags_set(&init_net, fc->fen6_info.rt,
+				       offload, trap, fail);
 		return;
 	}
 }
@@ -1384,44 +1446,43 @@ static int __prestera_inetaddr_valid_cb(struct notifier_block *nb,
 struct prestera_fib_event_work {
 	struct work_struct work;
 	struct prestera_switch *sw;
-	struct fib_entry_notifier_info fen_info;
+	union {
+		struct fib_notifier_info info; /* point to any of 4/6 */
+		struct fib6_entry_notifier_info fen6_info;
+		struct fib_entry_notifier_info fen4_info;
+	};
 	unsigned long event;
 };
 
 static void __prestera_router_fib_event_work(struct work_struct *work)
 {
 	struct prestera_fib_event_work *fib_work =
-			container_of(work, struct prestera_fib_event_work, work);
-	struct prestera_switch *sw = fib_work->sw;
+		container_of(work, struct prestera_fib_event_work,
+			     work);
 	int err;
 
 	rtnl_lock();
 
 	switch (fib_work->event) {
 	case FIB_EVENT_ENTRY_REPLACE:
-		err = prestera_k_arb_fib_evt(sw, true,
-					     &fib_work->fen_info.info);
+		err = prestera_k_arb_fib_evt(fib_work->sw, true,
+					     &fib_work->info);
 		if (err)
-			goto err_out;
+			dev_err(fib_work->sw->dev->dev,
+				"Error when processing lpm entry");
 
 		break;
 	case FIB_EVENT_ENTRY_DEL:
-		err = prestera_k_arb_fib_evt(sw, false,
-					     &fib_work->fen_info.info);
+		err = prestera_k_arb_fib_evt(fib_work->sw, false,
+					     &fib_work->info);
 		if (err)
-			goto err_out;
+			dev_err(fib_work->sw->dev->dev,
+				"Cant delete lpm entry");
 
 		break;
 	}
 
-	goto out;
-
-err_out:
-	dev_err(sw->dev->dev, "Error when processing %pI4h/%d",
-		&fib_work->fen_info.dst,
-		fib_work->fen_info.dst_len);
-out:
-	fib_info_put(fib_work->fen_info.fi);
+	prestera_util_fen_info_release(&fib_work->info);
 	rtnl_unlock();
 	kfree(fib_work);
 }
@@ -1430,30 +1491,33 @@ static void __prestera_router_fib_event_work(struct work_struct *work)
 static int __prestera_router_fib_event(struct notifier_block *nb,
 				       unsigned long event, void *ptr)
 {
+	struct fib6_entry_notifier_info *info6 =
+		container_of(ptr, struct fib6_entry_notifier_info, info);
+	struct fib_entry_notifier_info *info4 =
+		container_of(ptr, struct fib_entry_notifier_info, info);
+	struct prestera_router *router =
+		container_of(nb, struct prestera_router, fib_nb);
 	struct prestera_fib_event_work *fib_work;
-	struct fib_entry_notifier_info *fen_info;
 	struct fib_notifier_info *info = ptr;
-	struct prestera_router *router;
-
-	if (info->family != AF_INET)
-		return NOTIFY_DONE;
-
-	router = container_of(nb, struct prestera_router, fib_nb);
 
 	switch (event) {
 	case FIB_EVENT_ENTRY_REPLACE:
 	case FIB_EVENT_ENTRY_DEL:
-		fen_info = container_of(info, struct fib_entry_notifier_info,
-					info);
-		if (!fen_info->fi)
+		if (info->family == AF_INET6) {
+			if (!info6->rt)
+				return NOTIFY_DONE;
+		} else if (info->family == AF_INET) {
+			if (!info4->fi)
+				return NOTIFY_DONE;
+		} else {
 			return NOTIFY_DONE;
+		}
 
 		fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC);
 		if (WARN_ON(!fib_work))
 			return NOTIFY_BAD;
 
-		fib_info_hold(fen_info->fi);
-		fib_work->fen_info = *fen_info;
+		prestera_util_fen_info_copy(info, &fib_work->info);
 		fib_work->event = event;
 		fib_work->sw = router->sw;
 		INIT_WORK(&fib_work->work, __prestera_router_fib_event_work);
@@ -1500,7 +1564,7 @@ static int prestera_router_netevent_event(struct notifier_block *nb,
 
 	switch (event) {
 	case NETEVENT_NEIGH_UPDATE:
-		if (n->tbl->family != AF_INET)
+		if (n->tbl->family != AF_INET && n->tbl->family != AF_INET6)
 			return NOTIFY_DONE;
 
 		net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
-- 
2.17.1

^ permalink raw reply related

* [PATCH net-next v1 0/2] net: marvell: prestera: add ipv6 routes offloading
From: Yevhen Orlov @ 2022-12-18 22:15 UTC (permalink / raw)
  To: netdev
  Cc: Volodymyr Mytnyk, Taras Chornyi, Mickey Rachamim, Serhiy Pshyk,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, Stephen Hemminger, linux-kernel

Add support for IPv6 nexthop/blackhole/connected routes for Marvell Prestera driver.
Handle AF_INET6 neigbours, fib entries.

Add features:
 - IPv6:
   - Support "offload", "offload_failed", "trap" flags
   - Support blackhole, nexthop, local/connected/unreachable/etc (trap)
     e.g.: "ip addr add 2001:1::1/64 dev sw1p2"
     e.g.: "ip route add 2002:2::/64 via 2001:2::2"
     e.g.: "ip route add blachole 2003:2::/64 dev lo"

Limitations:
 - ipv6 ECMP is not supported
 - Only "local" and "main" tables supported
 - Only generic interfaces supported for router (no bridges or vlans)

Yevhen Orlov (2):
  net: marvell: prestera: Add router ipv6 ABI
  net: marvell: prestera: Handle ipv6 lpm/neigh events

 .../ethernet/marvell/prestera/prestera_hw.c   |  34 +++++
 .../ethernet/marvell/prestera/prestera_hw.h   |   4 +
 .../marvell/prestera/prestera_router.c        | 138 +++++++++++++-----
 .../marvell/prestera/prestera_router_hw.c     |  33 ++++-
 4 files changed, 166 insertions(+), 43 deletions(-)

-- 
2.17.1

^ permalink raw reply

* [PATCH 1/2] ip/ip6_gre: Fix changing addr gen mode not generating IPv6 link local address
From: Thomas Winter @ 2022-12-18 21:57 UTC (permalink / raw)
  To: davem, yoshfuji, dsahern, kuba, a, netdev, linux-kernel; +Cc: Thomas Winter
In-Reply-To: <20221218215718.1491444-1-Thomas.Winter@alliedtelesis.co.nz>

Commit e5dd729460ca changed the code path so that GRE tunnels
generate an IPv6 address based on the tunnel source address.
It also changed the code path so GRE tunnels don't call addrconf_addr_gen
in addrconf_dev_config which is called by addrconf_sysctl_addr_gen_mode
when the IN6_ADDR_GEN_MODE is changed.

This patch aims to fix this issue by moving the code in addrconf_notify
which calls the addr gen for GRE and SIT into a separate function
and calling it in the places that expect the IPv6 address to be
generated.

The previous addrconf_dev_config is renamed to addrconf_eth_config
since it only expected eth type interfaces and follows the
addrconf_gre/sit_config format.

Fixes: e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address")
Signed-off-by: Thomas Winter <Thomas.Winter@alliedtelesis.co.nz>
---
 net/ipv6/addrconf.c | 47 +++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6dcf034835ec..9c0d085fb9af 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3355,7 +3355,7 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route)
 	}
 }
 
-static void addrconf_dev_config(struct net_device *dev)
+static void addrconf_eth_config(struct net_device *dev)
 {
 	struct inet6_dev *idev;
 
@@ -3447,6 +3447,30 @@ static void addrconf_gre_config(struct net_device *dev)
 }
 #endif
 
+static void addrconf_dev_config(struct net_device *dev)
+{
+	switch (dev->type) {
+	#if IS_ENABLED(CONFIG_IPV6_SIT)
+	case ARPHRD_SIT:
+		addrconf_sit_config(dev);
+		break;
+	#endif
+	#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE)
+	case ARPHRD_IP6GRE:
+	case ARPHRD_IPGRE:
+		addrconf_gre_config(dev);
+		break;
+	#endif
+	case ARPHRD_LOOPBACK:
+		init_loopback(dev);
+		break;
+
+	default:
+		addrconf_eth_config(dev);
+		break;
+	}
+}
+
 static int fixup_permanent_addr(struct net *net,
 				struct inet6_dev *idev,
 				struct inet6_ifaddr *ifp)
@@ -3611,26 +3635,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 			run_pending = 1;
 		}
 
-		switch (dev->type) {
-#if IS_ENABLED(CONFIG_IPV6_SIT)
-		case ARPHRD_SIT:
-			addrconf_sit_config(dev);
-			break;
-#endif
-#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE)
-		case ARPHRD_IP6GRE:
-		case ARPHRD_IPGRE:
-			addrconf_gre_config(dev);
-			break;
-#endif
-		case ARPHRD_LOOPBACK:
-			init_loopback(dev);
-			break;
-
-		default:
-			addrconf_dev_config(dev);
-			break;
-		}
+		addrconf_dev_config(dev);
 
 		if (!IS_ERR_OR_NULL(idev)) {
 			if (run_pending)
-- 
2.37.3


^ permalink raw reply related

* [PATCH 0/2] ip/ip6_gre: Fix GRE tunnels not generating IPv6 link local addresses
From: Thomas Winter @ 2022-12-18 21:57 UTC (permalink / raw)
  To: davem, yoshfuji, dsahern, kuba, a, netdev, linux-kernel; +Cc: Thomas Winter

For our point-to-point GRE tunnels, they have IN6_ADDR_GEN_MODE_NONE
when they are created then we set IN6_ADDR_GEN_MODE_EUI64 when they
come up to generate the IPv6 link local address for the interface.
Recently we found that they were no longer generating IPv6 addresses.

Also, non-point-to-point tunnels were not generating any IPv6 link
local address and instead generating an IPv6 compat address,
breaking IPv6 communication on the tunnel.

These failures were caused by commit e5dd729460ca and this patch set
aims to resolve these issues.

Thomas Winter (2):
  ip/ip6_gre: Fix changing addr gen mode not generating IPv6 link local
    address
  ip/ip6_gre: Fix non-point-to-point tunnel not generating IPv6 link
    local address

 net/ipv6/addrconf.c | 57 ++++++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

-- 
2.37.3


^ permalink raw reply

* [PATCH 2/2] ip/ip6_gre: Fix non-point-to-point tunnel not generating IPv6 link local address
From: Thomas Winter @ 2022-12-18 21:57 UTC (permalink / raw)
  To: davem, yoshfuji, dsahern, kuba, a, netdev, linux-kernel; +Cc: Thomas Winter
In-Reply-To: <20221218215718.1491444-1-Thomas.Winter@alliedtelesis.co.nz>

Previously, addrconf_gre_config always would call addrconf_addr_gen
and generate a EUI64 link local address for the tunnel.
Then commit e5dd729460ca changed the code path so that add_v4_addrs
is called but this only generates a compat IPv6 address for
non-point-to-point tunnels.

I assume the compat address is specifically for SIT tunnels so
have kept that only for SIT - GRE tunnels now always generate link
local addresses.

Fixes: e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address")
Signed-off-by: Thomas Winter <Thomas.Winter@alliedtelesis.co.nz>
---
 net/ipv6/addrconf.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 9c0d085fb9af..12126601093d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3129,17 +3129,17 @@ static void add_v4_addrs(struct inet6_dev *idev)
 		offset = sizeof(struct in6_addr) - 4;
 	memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4);
 
-	if (idev->dev->flags&IFF_POINTOPOINT) {
+	if (!(idev->dev->flags & IFF_POINTOPOINT) && idev->dev->type == ARPHRD_SIT) {
+		scope = IPV6_ADDR_COMPATv4;
+		plen = 96;
+		pflags |= RTF_NONEXTHOP;
+	} else {
 		if (idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_NONE)
 			return;
 
 		addr.s6_addr32[0] = htonl(0xfe800000);
 		scope = IFA_LINK;
 		plen = 64;
-	} else {
-		scope = IPV6_ADDR_COMPATv4;
-		plen = 96;
-		pflags |= RTF_NONEXTHOP;
 	}
 
 	if (addr.s6_addr32[3]) {
-- 
2.37.3


^ permalink raw reply related

* Re: [PATCH net 0/6][pull request] Intel Wired LAN Driver Updates 2022-12-15 (igc)
From: patchwork-bot+netdevbpf @ 2022-12-18 21:10 UTC (permalink / raw)
  To: Tony Nguyen
  Cc: davem, kuba, pabeni, edumazet, netdev, muhammad.husaini.zulkifli,
	sasha.neftin
In-Reply-To: <20221215230758.3595578-1-anthony.l.nguyen@intel.com>

Hello:

This series was applied to netdev/net.git (master)
by Tony Nguyen <anthony.l.nguyen@intel.com>:

On Thu, 15 Dec 2022 15:07:52 -0800 you wrote:
> Muhammad Husaini Zulkifli says:
> 
> This patch series fixes bugs for the Time-Sensitive Networking(TSN)
> Qbv Scheduling features.
> 
> An overview of each patch series is given below:
> 
> [...]

Here is the summary with links:
  - [net,1/6] igc: Enhance Qbv scheduling by using first flag bit
    https://git.kernel.org/netdev/net/c/db0b124f02ba
  - [net,2/6] igc: Use strict cycles for Qbv scheduling
    https://git.kernel.org/netdev/net/c/d8f45be01dd9
  - [net,3/6] igc: Add checking for basetime less than zero
    https://git.kernel.org/netdev/net/c/3b61764fb49a
  - [net,4/6] igc: allow BaseTime 0 enrollment for Qbv
    https://git.kernel.org/netdev/net/c/e17090eb2494
  - [net,5/6] igc: recalculate Qbv end_time by considering cycle time
    https://git.kernel.org/netdev/net/c/6d05251d537a
  - [net,6/6] igc: Set Qbv start_time and end_time to end_time if not being configured in GCL
    https://git.kernel.org/netdev/net/c/72abeedd8398

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH net 7/9] rxrpc: Fix I/O thread stop
From: David Howells @ 2022-12-18 19:59 UTC (permalink / raw)
  To: Hillf Danton; +Cc: dhowells, netdev, Marc Dionne, linux-afs, linux-kernel
In-Reply-To: <20221218120951.1212-1-hdanton@sina.com>

Hillf Danton <hdanton@sina.com> wrote:

> In line with
> 
> 	if (condition)
> 		return;
> 	add to wait queue
> 	if (!condition)
> 		schedule();
> 
> this change should look like
> 
>    		if (!skb_queue_empty(&local->rx_queue) ...)
>  			continue;
> 
>  		if (kthread_should_stop())
>    			if (!skb_queue_empty(&local->rx_queue) ...)
>  				continue;
> 			else
>   				break;
> 
> as checking condition once barely makes sense.

Really, no.  The condition is going to expand to have a whole bunch of things
in it and I don't want to have it twice, e.g.:

                if (!skb_queue_empty(&local->rx_queue) ||
                   READ_ONCE(local->events) ||
                    !list_empty(&local->call_attend_q) ||
                    !list_empty(&local->conn_attend_q) ||
                    !list_empty(&local->new_client_calls) ||
		    test_bit(RXRPC_CLIENT_CONN_REAP_TIMER,
			     &local->client_conn_flags)) {
			...

Hmmm...  I wonder if kthread_should_stop() needs a barrier associated with
it.  It's just a test_bit(), so the compiler can cache the results of all
these tests - or reorder them.

David


^ permalink raw reply

* [PATCH] myri10ge: Fix an error handling path in myri10ge_probe()
From: Christophe JAILLET @ 2022-12-18 18:08 UTC (permalink / raw)
  To: Chris Lee, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Andrew Gallatin, Brice Goglin, Jeff Garzik
  Cc: linux-kernel, kernel-janitors, Christophe JAILLET, netdev

Some memory allocated in myri10ge_probe_slices() is not released in the
error handling path of myri10ge_probe().

Add the corresponding kfree(), as already done in the remove function.

Fixes: 0dcffac1a329 ("myri10ge: add multislices support")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
 drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 8073d7a90a26..c5687d94ea88 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -3912,6 +3912,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	myri10ge_free_slices(mgp);
 
 abort_with_firmware:
+	kfree(mgp->msix_vectors);
 	myri10ge_dummy_rdma(mgp, 0);
 
 abort_with_ioremap:
-- 
2.34.1


^ permalink raw reply related

* [PATCH AUTOSEL 4.9 14/20] ppp: associate skb with a device at tx
From: Sasha Levin @ 2022-12-18 16:22 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Stanislav Fomichev, Paul Mackerras, linux-ppp,
	syzbot+41cab52ab62ee99ed24a, David S . Miller, Sasha Levin,
	edumazet, kuba, pabeni, netdev, bpf
In-Reply-To: <20221218162305.935724-1-sashal@kernel.org>

From: Stanislav Fomichev <sdf@google.com>

[ Upstream commit 9f225444467b98579cf28d94f4ad053460dfdb84 ]

Syzkaller triggered flow dissector warning with the following:

r0 = openat$ppp(0xffffffffffffff9c, &(0x7f0000000000), 0xc0802, 0x0)
ioctl$PPPIOCNEWUNIT(r0, 0xc004743e, &(0x7f00000000c0))
ioctl$PPPIOCSACTIVE(r0, 0x40107446, &(0x7f0000000240)={0x2, &(0x7f0000000180)=[{0x20, 0x0, 0x0, 0xfffff034}, {0x6}]})
pwritev(r0, &(0x7f0000000040)=[{&(0x7f0000000140)='\x00!', 0x2}], 0x1, 0x0, 0x0)

[    9.485814] WARNING: CPU: 3 PID: 329 at net/core/flow_dissector.c:1016 __skb_flow_dissect+0x1ee0/0x1fa0
[    9.485929]  skb_get_poff+0x53/0xa0
[    9.485937]  bpf_skb_get_pay_offset+0xe/0x20
[    9.485944]  ? ppp_send_frame+0xc2/0x5b0
[    9.485949]  ? _raw_spin_unlock_irqrestore+0x40/0x60
[    9.485958]  ? __ppp_xmit_process+0x7a/0xe0
[    9.485968]  ? ppp_xmit_process+0x5b/0xb0
[    9.485974]  ? ppp_write+0x12a/0x190
[    9.485981]  ? do_iter_write+0x18e/0x2d0
[    9.485987]  ? __import_iovec+0x30/0x130
[    9.485997]  ? do_pwritev+0x1b6/0x240
[    9.486016]  ? trace_hardirqs_on+0x47/0x50
[    9.486023]  ? __x64_sys_pwritev+0x24/0x30
[    9.486026]  ? do_syscall_64+0x3d/0x80
[    9.486031]  ? entry_SYSCALL_64_after_hwframe+0x63/0xcd

Flow dissector tries to find skb net namespace either via device
or via socket. Neigher is set in ppp_send_frame, so let's manually
use ppp->dev.

Cc: Paul Mackerras <paulus@samba.org>
Cc: linux-ppp@vger.kernel.org
Reported-by: syzbot+41cab52ab62ee99ed24a@syzkaller.appspotmail.com
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ppp/ppp_generic.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 6287d2ad77c6..f6cf25cba16e 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1541,6 +1541,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
 	int len;
 	unsigned char *cp;
 
+	skb->dev = ppp->dev;
+
 	if (proto < 0x8000) {
 #ifdef CONFIG_PPP_FILTER
 		/* check if we should pass this packet */
-- 
2.35.1


^ permalink raw reply related

* [PATCH AUTOSEL 4.9 13/20] mrp: introduce active flags to prevent UAF when applicant uninit
From: Sasha Levin @ 2022-12-18 16:22 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Schspa Shi, syzbot+6fd64001c20aa99e34a4, David S . Miller,
	Sasha Levin, edumazet, kuba, pabeni, yury.norov, djwong, hca,
	christoph.boehmwalder, jack, Jason, netdev
In-Reply-To: <20221218162305.935724-1-sashal@kernel.org>

From: Schspa Shi <schspa@gmail.com>

[ Upstream commit ab0377803dafc58f1e22296708c1c28e309414d6 ]

The caller of del_timer_sync must prevent restarting of the timer, If
we have no this synchronization, there is a small probability that the
cancellation will not be successful.

And syzbot report the fellowing crash:
==================================================================
BUG: KASAN: use-after-free in hlist_add_head include/linux/list.h:929 [inline]
BUG: KASAN: use-after-free in enqueue_timer+0x18/0xa4 kernel/time/timer.c:605
Write at addr f9ff000024df6058 by task syz-fuzzer/2256
Pointer tag: [f9], memory tag: [fe]

CPU: 1 PID: 2256 Comm: syz-fuzzer Not tainted 6.1.0-rc5-syzkaller-00008-
ge01d50cbd6ee #0
Hardware name: linux,dummy-virt (DT)
Call trace:
 dump_backtrace.part.0+0xe0/0xf0 arch/arm64/kernel/stacktrace.c:156
 dump_backtrace arch/arm64/kernel/stacktrace.c:162 [inline]
 show_stack+0x18/0x40 arch/arm64/kernel/stacktrace.c:163
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0x68/0x84 lib/dump_stack.c:106
 print_address_description mm/kasan/report.c:284 [inline]
 print_report+0x1a8/0x4a0 mm/kasan/report.c:395
 kasan_report+0x94/0xb4 mm/kasan/report.c:495
 __do_kernel_fault+0x164/0x1e0 arch/arm64/mm/fault.c:320
 do_bad_area arch/arm64/mm/fault.c:473 [inline]
 do_tag_check_fault+0x78/0x8c arch/arm64/mm/fault.c:749
 do_mem_abort+0x44/0x94 arch/arm64/mm/fault.c:825
 el1_abort+0x40/0x60 arch/arm64/kernel/entry-common.c:367
 el1h_64_sync_handler+0xd8/0xe4 arch/arm64/kernel/entry-common.c:427
 el1h_64_sync+0x64/0x68 arch/arm64/kernel/entry.S:576
 hlist_add_head include/linux/list.h:929 [inline]
 enqueue_timer+0x18/0xa4 kernel/time/timer.c:605
 mod_timer+0x14/0x20 kernel/time/timer.c:1161
 mrp_periodic_timer_arm net/802/mrp.c:614 [inline]
 mrp_periodic_timer+0xa0/0xc0 net/802/mrp.c:627
 call_timer_fn.constprop.0+0x24/0x80 kernel/time/timer.c:1474
 expire_timers+0x98/0xc4 kernel/time/timer.c:1519

To fix it, we can introduce a new active flags to make sure the timer will
not restart.

Reported-by: syzbot+6fd64001c20aa99e34a4@syzkaller.appspotmail.com

Signed-off-by: Schspa Shi <schspa@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/mrp.h |  1 +
 net/802/mrp.c     | 18 +++++++++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/include/net/mrp.h b/include/net/mrp.h
index 31912c3be772..9338d6305159 100644
--- a/include/net/mrp.h
+++ b/include/net/mrp.h
@@ -119,6 +119,7 @@ struct mrp_applicant {
 	struct sk_buff		*pdu;
 	struct rb_root		mad;
 	struct rcu_head		rcu;
+	bool			active;
 };
 
 struct mrp_port {
diff --git a/net/802/mrp.c b/net/802/mrp.c
index 4ee3af3d400b..ac6b6374a1fc 100644
--- a/net/802/mrp.c
+++ b/net/802/mrp.c
@@ -610,7 +610,10 @@ static void mrp_join_timer(unsigned long data)
 	spin_unlock(&app->lock);
 
 	mrp_queue_xmit(app);
-	mrp_join_timer_arm(app);
+	spin_lock(&app->lock);
+	if (likely(app->active))
+		mrp_join_timer_arm(app);
+	spin_unlock(&app->lock);
 }
 
 static void mrp_periodic_timer_arm(struct mrp_applicant *app)
@@ -624,11 +627,12 @@ static void mrp_periodic_timer(unsigned long data)
 	struct mrp_applicant *app = (struct mrp_applicant *)data;
 
 	spin_lock(&app->lock);
-	mrp_mad_event(app, MRP_EVENT_PERIODIC);
-	mrp_pdu_queue(app);
+	if (likely(app->active)) {
+		mrp_mad_event(app, MRP_EVENT_PERIODIC);
+		mrp_pdu_queue(app);
+		mrp_periodic_timer_arm(app);
+	}
 	spin_unlock(&app->lock);
-
-	mrp_periodic_timer_arm(app);
 }
 
 static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset)
@@ -876,6 +880,7 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl)
 	app->dev = dev;
 	app->app = appl;
 	app->mad = RB_ROOT;
+	app->active = true;
 	spin_lock_init(&app->lock);
 	skb_queue_head_init(&app->queue);
 	rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app);
@@ -905,6 +910,9 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
 
 	RCU_INIT_POINTER(port->applicants[appl->type], NULL);
 
+	spin_lock_bh(&app->lock);
+	app->active = false;
+	spin_unlock_bh(&app->lock);
 	/* Delete timer and generate a final TX event to flush out
 	 * all pending messages before the applicant is gone.
 	 */
-- 
2.35.1


^ permalink raw reply related

* [PATCH AUTOSEL 4.9 10/20] s390/lcs: Fix return type of lcs_start_xmit()
From: Sasha Levin @ 2022-12-18 16:22 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Nathan Chancellor, Alexandra Winter, Kees Cook, David S . Miller,
	Sasha Levin, wenjia, hca, gor, agordeev, ndesaulniers, linux-s390,
	netdev, llvm
In-Reply-To: <20221218162305.935724-1-sashal@kernel.org>

From: Nathan Chancellor <nathan@kernel.org>

[ Upstream commit bb16db8393658e0978c3f0d30ae069e878264fa3 ]

With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
indirect call targets are validated against the expected function
pointer prototype to make sure the call target is valid to help mitigate
ROP attacks. If they are not identical, there is a failure at run time,
which manifests as either a kernel panic or thread getting killed. A
proposed warning in clang aims to catch these at compile time, which
reveals:

  drivers/s390/net/lcs.c:2090:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
          .ndo_start_xmit         = lcs_start_xmit,
                                    ^~~~~~~~~~~~~~
  drivers/s390/net/lcs.c:2097:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
          .ndo_start_xmit         = lcs_start_xmit,
                                    ^~~~~~~~~~~~~~

->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
'netdev_tx_t', not 'int'. Adjust the return type of lcs_start_xmit() to
match the prototype's to resolve the warning and potential CFI failure,
should s390 select ARCH_SUPPORTS_CFI_CLANG in the future.

Link: https://github.com/ClangBuiltLinux/linux/issues/1750
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/s390/net/lcs.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 4d3caad7e981..3bd2241c13e8 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1544,9 +1544,8 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
 /**
  * Packet transmit function called by network stack
  */
-static int
-__lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
-		 struct net_device *dev)
+static netdev_tx_t __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	struct lcs_header *header;
 	int rc = NETDEV_TX_OK;
@@ -1607,8 +1606,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
 	return rc;
 }
 
-static int
-lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct lcs_card *card;
 	int rc;
-- 
2.35.1


^ permalink raw reply related

* [PATCH AUTOSEL 4.9 09/20] s390/netiucv: Fix return type of netiucv_tx()
From: Sasha Levin @ 2022-12-18 16:22 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Nathan Chancellor, Alexandra Winter, Kees Cook, David S . Miller,
	Sasha Levin, wenjia, hca, gor, agordeev, ndesaulniers, linux-s390,
	netdev, llvm
In-Reply-To: <20221218162305.935724-1-sashal@kernel.org>

From: Nathan Chancellor <nathan@kernel.org>

[ Upstream commit 88d86d18d7cf7e9137c95f9d212bb9fff8a1b4be ]

With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
indirect call targets are validated against the expected function
pointer prototype to make sure the call target is valid to help mitigate
ROP attacks. If they are not identical, there is a failure at run time,
which manifests as either a kernel panic or thread getting killed. A
proposed warning in clang aims to catch these at compile time, which
reveals:

  drivers/s390/net/netiucv.c:1854:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
          .ndo_start_xmit         = netiucv_tx,
                                    ^~~~~~~~~~

->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
'netdev_tx_t', not 'int'. Adjust the return type of netiucv_tx() to
match the prototype's to resolve the warning and potential CFI failure,
should s390 select ARCH_SUPPORTS_CFI_CLANG in the future.

Additionally, while in the area, remove a comment block that is no
longer relevant.

Link: https://github.com/ClangBuiltLinux/linux/issues/1750
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/s390/net/netiucv.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index b0e8ffdf864b..3465ea3d667b 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1361,15 +1361,8 @@ static int netiucv_pm_restore_thaw(struct device *dev)
 /**
  * Start transmission of a packet.
  * Called from generic network device layer.
- *
- * @param skb Pointer to buffer containing the packet.
- * @param dev Pointer to interface struct.
- *
- * @return 0 if packet consumed, !0 if packet rejected.
- *         Note: If we return !0, then the packet is free'd by
- *               the generic network layer.
  */
-static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t netiucv_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct netiucv_priv *privptr = netdev_priv(dev);
 	int rc;
-- 
2.35.1


^ permalink raw reply related

* [PATCH AUTOSEL 4.9 08/20] s390/ctcm: Fix return type of ctc{mp,}m_tx()
From: Sasha Levin @ 2022-12-18 16:22 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Nathan Chancellor, Alexandra Winter, Kees Cook, David S . Miller,
	Sasha Levin, wenjia, hca, gor, agordeev, ndesaulniers, linux-s390,
	netdev, llvm
In-Reply-To: <20221218162305.935724-1-sashal@kernel.org>

From: Nathan Chancellor <nathan@kernel.org>

[ Upstream commit aa5bf80c3c067b82b4362cd6e8e2194623bcaca6 ]

With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
indirect call targets are validated against the expected function
pointer prototype to make sure the call target is valid to help mitigate
ROP attacks. If they are not identical, there is a failure at run time,
which manifests as either a kernel panic or thread getting killed. A
proposed warning in clang aims to catch these at compile time, which
reveals:

  drivers/s390/net/ctcm_main.c:1064:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
          .ndo_start_xmit         = ctcm_tx,
                                    ^~~~~~~
  drivers/s390/net/ctcm_main.c:1072:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
          .ndo_start_xmit         = ctcmpc_tx,
                                    ^~~~~~~~~

->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
'netdev_tx_t', not 'int'. Adjust the return type of ctc{mp,}m_tx() to
match the prototype's to resolve the warning and potential CFI failure,
should s390 select ARCH_SUPPORTS_CFI_CLANG in the future.

Additionally, while in the area, remove a comment block that is no
longer relevant.

Link: https://github.com/ClangBuiltLinux/linux/issues/1750
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/s390/net/ctcm_main.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index e22b9ac3e564..ab48eef72d4f 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -866,16 +866,9 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
 /**
  * Start transmission of a packet.
  * Called from generic network device layer.
- *
- *  skb		Pointer to buffer containing the packet.
- *  dev		Pointer to interface struct.
- *
- * returns 0 if packet consumed, !0 if packet rejected.
- *         Note: If we return !0, then the packet is free'd by
- *               the generic network layer.
  */
 /* first merge version - leaving both functions separated */
-static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ctcm_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ctcm_priv *priv = dev->ml_priv;
 
@@ -918,7 +911,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
 }
 
 /* unmerged MPC variant of ctcm_tx */
-static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	int len = 0;
 	struct ctcm_priv *priv = dev->ml_priv;
-- 
2.35.1


^ permalink raw reply related

* [PATCH AUTOSEL 4.9 07/20] igb: Do not free q_vector unless new one was allocated
From: Sasha Levin @ 2022-12-18 16:22 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Kees Cook, Jesse Brandeburg, Tony Nguyen, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, intel-wired-lan,
	netdev, Michael J . Ruhl, Jacob Keller, Gurucharan, Sasha Levin
In-Reply-To: <20221218162305.935724-1-sashal@kernel.org>

From: Kees Cook <keescook@chromium.org>

[ Upstream commit 0668716506ca66f90d395f36ccdaebc3e0e84801 ]

Avoid potential use-after-free condition under memory pressure. If the
kzalloc() fails, q_vector will be freed but left in the original
adapter->q_vector[v_idx] array position.

Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: Tony Nguyen <anthony.l.nguyen@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: intel-wired-lan@lists.osuosl.org
Cc: netdev@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Gurucharan <gurucharanx.g@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/intel/igb/igb_main.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 2e713e5f75cd..bbca786f0427 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1219,8 +1219,12 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
 	if (!q_vector) {
 		q_vector = kzalloc(size, GFP_KERNEL);
 	} else if (size > ksize(q_vector)) {
-		kfree_rcu(q_vector, rcu);
-		q_vector = kzalloc(size, GFP_KERNEL);
+		struct igb_q_vector *new_q_vector;
+
+		new_q_vector = kzalloc(size, GFP_KERNEL);
+		if (new_q_vector)
+			kfree_rcu(q_vector, rcu);
+		q_vector = new_q_vector;
 	} else {
 		memset(q_vector, 0, size);
 	}
-- 
2.35.1


^ permalink raw reply related

* [PATCH AUTOSEL 4.9 06/20] wifi: brcmfmac: Fix potential shift-out-of-bounds in brcmf_fw_alloc_request()
From: Sasha Levin @ 2022-12-18 16:22 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Minsuk Kang, Dokyung Song, Jisoo Jang, Kalle Valo, Sasha Levin,
	aspriel, franky.lin, hante.meuleman, davem, edumazet, kuba,
	pabeni, marcan, alsi, rmk+kernel, wsa+renesas, ardb, phil,
	linux-wireless, brcm80211-dev-list.pdl, SHA-cyfmac-dev-list,
	netdev
In-Reply-To: <20221218162305.935724-1-sashal@kernel.org>

From: Minsuk Kang <linuxlovemin@yonsei.ac.kr>

[ Upstream commit 81d17f6f3331f03c8eafdacea68ab773426c1e3c ]

This patch fixes a shift-out-of-bounds in brcmfmac that occurs in
BIT(chiprev) when a 'chiprev' provided by the device is too large.
It should also not be equal to or greater than BITS_PER_TYPE(u32)
as we do bitwise AND with a u32 variable and BIT(chiprev). The patch
adds a check that makes the function return NULL if that is the case.
Note that the NULL case is later handled by the bus-specific caller,
brcmf_usb_probe_cb() or brcmf_usb_reset_resume(), for example.

Found by a modified version of syzkaller.

UBSAN: shift-out-of-bounds in drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
shift exponent 151055786 is too large for 64-bit type 'long unsigned int'
CPU: 0 PID: 1885 Comm: kworker/0:2 Tainted: G           O      5.14.0+ #132
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
Workqueue: usb_hub_wq hub_event
Call Trace:
 dump_stack_lvl+0x57/0x7d
 ubsan_epilogue+0x5/0x40
 __ubsan_handle_shift_out_of_bounds.cold+0x53/0xdb
 ? lock_chain_count+0x20/0x20
 brcmf_fw_alloc_request.cold+0x19/0x3ea
 ? brcmf_fw_get_firmwares+0x250/0x250
 ? brcmf_usb_ioctl_resp_wait+0x1a7/0x1f0
 brcmf_usb_get_fwname+0x114/0x1a0
 ? brcmf_usb_reset_resume+0x120/0x120
 ? number+0x6c4/0x9a0
 brcmf_c_process_clm_blob+0x168/0x590
 ? put_dec+0x90/0x90
 ? enable_ptr_key_workfn+0x20/0x20
 ? brcmf_common_pd_remove+0x50/0x50
 ? rcu_read_lock_sched_held+0xa1/0xd0
 brcmf_c_preinit_dcmds+0x673/0xc40
 ? brcmf_c_set_joinpref_default+0x100/0x100
 ? rcu_read_lock_sched_held+0xa1/0xd0
 ? rcu_read_lock_bh_held+0xb0/0xb0
 ? lock_acquire+0x19d/0x4e0
 ? find_held_lock+0x2d/0x110
 ? brcmf_usb_deq+0x1cc/0x260
 ? mark_held_locks+0x9f/0xe0
 ? lockdep_hardirqs_on_prepare+0x273/0x3e0
 ? _raw_spin_unlock_irqrestore+0x47/0x50
 ? trace_hardirqs_on+0x1c/0x120
 ? brcmf_usb_deq+0x1a7/0x260
 ? brcmf_usb_rx_fill_all+0x5a/0xf0
 brcmf_attach+0x246/0xd40
 ? wiphy_new_nm+0x1476/0x1d50
 ? kmemdup+0x30/0x40
 brcmf_usb_probe+0x12de/0x1690
 ? brcmf_usbdev_qinit.constprop.0+0x470/0x470
 usb_probe_interface+0x25f/0x710
 really_probe+0x1be/0xa90
 __driver_probe_device+0x2ab/0x460
 ? usb_match_id.part.0+0x88/0xc0
 driver_probe_device+0x49/0x120
 __device_attach_driver+0x18a/0x250
 ? driver_allows_async_probing+0x120/0x120
 bus_for_each_drv+0x123/0x1a0
 ? bus_rescan_devices+0x20/0x20
 ? lockdep_hardirqs_on_prepare+0x273/0x3e0
 ? trace_hardirqs_on+0x1c/0x120
 __device_attach+0x207/0x330
 ? device_bind_driver+0xb0/0xb0
 ? kobject_uevent_env+0x230/0x12c0
 bus_probe_device+0x1a2/0x260
 device_add+0xa61/0x1ce0
 ? __mutex_unlock_slowpath+0xe7/0x660
 ? __fw_devlink_link_to_suppliers+0x550/0x550
 usb_set_configuration+0x984/0x1770
 ? kernfs_create_link+0x175/0x230
 usb_generic_driver_probe+0x69/0x90
 usb_probe_device+0x9c/0x220
 really_probe+0x1be/0xa90
 __driver_probe_device+0x2ab/0x460
 driver_probe_device+0x49/0x120
 __device_attach_driver+0x18a/0x250
 ? driver_allows_async_probing+0x120/0x120
 bus_for_each_drv+0x123/0x1a0
 ? bus_rescan_devices+0x20/0x20
 ? lockdep_hardirqs_on_prepare+0x273/0x3e0
 ? trace_hardirqs_on+0x1c/0x120
 __device_attach+0x207/0x330
 ? device_bind_driver+0xb0/0xb0
 ? kobject_uevent_env+0x230/0x12c0
 bus_probe_device+0x1a2/0x260
 device_add+0xa61/0x1ce0
 ? __fw_devlink_link_to_suppliers+0x550/0x550
 usb_new_device.cold+0x463/0xf66
 ? hub_disconnect+0x400/0x400
 ? _raw_spin_unlock_irq+0x24/0x30
 hub_event+0x10d5/0x3330
 ? hub_port_debounce+0x280/0x280
 ? __lock_acquire+0x1671/0x5790
 ? wq_calc_node_cpumask+0x170/0x2a0
 ? lock_release+0x640/0x640
 ? rcu_read_lock_sched_held+0xa1/0xd0
 ? rcu_read_lock_bh_held+0xb0/0xb0
 ? lockdep_hardirqs_on_prepare+0x273/0x3e0
 process_one_work+0x873/0x13e0
 ? lock_release+0x640/0x640
 ? pwq_dec_nr_in_flight+0x320/0x320
 ? rwlock_bug.part.0+0x90/0x90
 worker_thread+0x8b/0xd10
 ? __kthread_parkme+0xd9/0x1d0
 ? process_one_work+0x13e0/0x13e0
 kthread+0x379/0x450
 ? _raw_spin_unlock_irq+0x24/0x30
 ? set_kthread_struct+0x100/0x100
 ret_from_fork+0x1f/0x30

Reported-by: Dokyung Song <dokyungs@yonsei.ac.kr>
Reported-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
Reported-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
Signed-off-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20221024071329.504277-1-linuxlovemin@yonsei.ac.kr
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index 33a7378164b8..6675de16e3b9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -572,6 +572,11 @@ int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev,
 	u32 i;
 	char end;
 
+	if (chiprev >= BITS_PER_TYPE(u32)) {
+		brcmf_err("Invalid chip revision %u\n", chiprev);
+		return NULL;
+	}
+
 	for (i = 0; i < table_size; i++) {
 		if (mapping_table[i].chipid == chip &&
 		    mapping_table[i].revmask & BIT(chiprev))
-- 
2.35.1


^ permalink raw reply related


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