public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Kerr <jk@codeconstruct.com.au>
To: Matt Johnston <matt@codeconstruct.com.au>,
	 "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	 Jakub Kicinski <kuba@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>,  Simon Horman <horms@kernel.org>
Cc: netdev@vger.kernel.org
Subject: [PATCH net-next 2/3] net: mctp: allow local TX with no address assigned
Date: Tue, 31 Mar 2026 15:41:07 +0800	[thread overview]
Message-ID: <20260331-dev-mctp-null-eids-v1-2-b4d047372eaf@codeconstruct.com.au> (raw)
In-Reply-To: <20260331-dev-mctp-null-eids-v1-0-b4d047372eaf@codeconstruct.com.au>

If we're operating as a non-bus-owner endpoint, we may want to perform
MCTP communication to get an address assigned. In this case, we'll have
no local addresses, but can TX just fine either with extended routing,
or where a direct route exists.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
 net/mctp/route.c           |  18 ++-----
 net/mctp/test/route-test.c | 114 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+), 14 deletions(-)

diff --git a/net/mctp/route.c b/net/mctp/route.c
index f6a88e668e68a8431e58ccc46e7ebb7bf2303f71..8c484776e9e42e246d5e214f5c997281f820a43a 100644
--- a/net/mctp/route.c
+++ b/net/mctp/route.c
@@ -997,8 +997,8 @@ int mctp_route_lookup(struct net *net, unsigned int dnet,
 
 		if (rt->dst_type == MCTP_ROUTE_DIRECT) {
 			mctp_dst_from_route(&dst_tmp, daddr, mtu, rt);
-			/* we need a source address */
-			if (dst_tmp.saddr == MCTP_ADDR_NULL) {
+			/* cannot do gateway-ed routes without a src  */
+			if (dst_tmp.saddr == MCTP_ADDR_NULL && depth != 0) {
 				mctp_dst_release(&dst_tmp);
 			} else {
 				if (dst)
@@ -1141,19 +1141,13 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst,
 	struct mctp_sk_key *key;
 	struct mctp_hdr *hdr;
 	unsigned int netid;
-	int rc = 0;
 	u8 tag;
 
 	KUNIT_STATIC_STUB_REDIRECT(mctp_local_output, sk, dst, skb, daddr,
 				   req_tag);
 
-	if (dst->saddr == MCTP_ADDR_NULL)
-		rc = -EHOSTUNREACH;
 	netid = READ_ONCE(dst->dev->net);
 
-	if (rc)
-		goto err_free;
-
 	if (req_tag & MCTP_TAG_OWNER) {
 		if (req_tag & MCTP_TAG_PREALLOC)
 			key = mctp_lookup_prealloc_tag(msk, netid, daddr,
@@ -1163,8 +1157,8 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst,
 						   daddr, false, &tag);
 
 		if (IS_ERR(key)) {
-			rc = PTR_ERR(key);
-			goto err_free;
+			kfree_skb(skb);
+			return PTR_ERR(key);
 		}
 		mctp_skb_set_flow(skb, key);
 		/* done with the key in this scope */
@@ -1191,10 +1185,6 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst,
 
 	/* route output functions consume the skb, even on error */
 	return mctp_do_fragment_route(dst, skb, dst->mtu, tag);
-
-err_free:
-	kfree_skb(skb);
-	return rc;
 }
 
 /* route management */
diff --git a/net/mctp/test/route-test.c b/net/mctp/test/route-test.c
index 639b7c41c2a233fa78f789d0ef25b87a15fb702b..fa28af9ac18e6605867c475ee7110fbbfd556edb 100644
--- a/net/mctp/test/route-test.c
+++ b/net/mctp/test/route-test.c
@@ -1570,6 +1570,117 @@ static void mctp_test_bind_lookup(struct kunit *test)
 	__mctp_route_test_fini(test, dev, &dst, sock_ty0);
 }
 
+static void mctp_test_route_output_direct_no_eids(struct kunit *test)
+{
+	struct mctp_dst dst = { 0 };
+	struct sk_buff *skb, *skb2;
+	struct mctp_test_route *rt;
+	struct mctp_test_dev *dev;
+	struct socket *sock;
+	const int len = 2;
+	int rc;
+
+	dev = mctp_test_create_dev();
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	rt = mctp_test_create_route_direct(&init_net, dev->mdev, 9, 68);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt);
+
+	rc = mctp_route_lookup(&init_net, dev->mdev->net, 9, &dst);
+	KUNIT_ASSERT_EQ(test, rc, 0);
+
+	rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock);
+	KUNIT_ASSERT_EQ(test, rc, 0);
+
+	skb = alloc_skb(sizeof(struct mctp_hdr) + 1 + len, GFP_KERNEL);
+	KUNIT_ASSERT_TRUE(test, skb);
+	__mctp_cb(skb);
+	skb_reserve(skb, sizeof(struct mctp_hdr) + 1 + len);
+	memset(skb_put(skb, len), 0, len);
+
+	rc = mctp_local_output(sock->sk, &dst, skb, 9, MCTP_TAG_OWNER);
+	KUNIT_ASSERT_EQ(test, rc, 0);
+
+	KUNIT_ASSERT_EQ(test, dev->pkts.qlen, 1);
+
+	skb2 = skb_dequeue(&dev->pkts);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb2);
+
+	kfree_skb(skb2);
+	sock_release(sock);
+	mctp_dst_release(&dst);
+	mctp_test_route_destroy(test, rt);
+	mctp_test_destroy_dev(dev);
+}
+
+static void mctp_test_route_output_gw_no_eids(struct kunit *test)
+{
+	struct mctp_test_route *rt1, *rt2;
+	struct mctp_test_dev *dev;
+	struct mctp_dst dst = { 0 };
+	int rc;
+
+	dev = mctp_test_create_dev();
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	/* route: direct to bridge */
+	rt1 = mctp_test_create_route_direct(&init_net, dev->mdev, 9, 68);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt1);
+
+	/* route: bridge gw to final dest */
+	rt2 = mctp_test_create_route_gw(&init_net, dev->mdev->net, 10, 9, 0);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt2);
+
+	/* route lookup should fail, due to no source address on dev */
+	rc = mctp_route_lookup(&init_net, dev->mdev->net, 10, &dst);
+	KUNIT_ASSERT_NE(test, rc, 0);
+
+	mctp_test_route_destroy(test, rt1);
+	mctp_test_route_destroy(test, rt2);
+	mctp_test_destroy_dev(dev);
+}
+
+static void mctp_test_route_output_extaddr_no_eids(struct kunit *test)
+{
+	struct mctp_dst dst = { 0 };
+	struct sk_buff *skb, *skb2;
+	struct mctp_test_dev *dev;
+	struct socket *sock;
+	const int len = 1;
+	struct net *net;
+	int rc;
+
+	dev = mctp_test_create_dev();
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	net = dev_net(dev->ndev);
+
+	rc = mctp_dst_from_extaddr(&dst, net, dev->ndev->ifindex, 0, NULL);
+	KUNIT_ASSERT_EQ(test, rc, 0);
+
+	rc = sock_create_kern(net, AF_MCTP, SOCK_DGRAM, 0, &sock);
+	KUNIT_ASSERT_EQ(test, rc, 0);
+
+	skb = alloc_skb(sizeof(struct mctp_hdr) + 1 + len, GFP_KERNEL);
+	KUNIT_ASSERT_TRUE(test, skb);
+	__mctp_cb(skb);
+	skb_reserve(skb, sizeof(struct mctp_hdr) + 1 + len);
+	memset(skb_put(skb, len), 0, len);
+
+	rc = mctp_local_output(sock->sk, &dst, skb, 9, MCTP_TAG_OWNER);
+	KUNIT_ASSERT_EQ(test, rc, 0);
+
+	KUNIT_ASSERT_EQ(test, dev->pkts.qlen, 1);
+
+	skb2 = skb_dequeue(&dev->pkts);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb2);
+
+	kfree_skb(skb2);
+	sock_release(sock);
+	mctp_dst_release(&dst);
+	mctp_test_destroy_dev(dev);
+}
+
 static struct kunit_case mctp_test_cases[] = {
 	KUNIT_CASE_PARAM(mctp_test_fragment, mctp_frag_gen_params),
 	KUNIT_CASE_PARAM(mctp_test_rx_input, mctp_rx_input_gen_params),
@@ -1592,6 +1703,9 @@ static struct kunit_case mctp_test_cases[] = {
 	KUNIT_CASE_PARAM(mctp_test_route_gw_mtu, mctp_route_gw_mtu_gen_params),
 	KUNIT_CASE(mctp_test_route_gw_output),
 	KUNIT_CASE_PARAM(mctp_test_bind_lookup, mctp_bind_lookup_gen_params),
+	KUNIT_CASE(mctp_test_route_output_direct_no_eids),
+	KUNIT_CASE(mctp_test_route_output_gw_no_eids),
+	KUNIT_CASE(mctp_test_route_output_extaddr_no_eids),
 	{}
 };
 

-- 
2.39.5


  parent reply	other threads:[~2026-03-31  7:41 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-31  7:41 [PATCH net-next 0/3] net: mctp: improvements for NULL-EID addressing Jeremy Kerr
2026-03-31  7:41 ` [PATCH net-next 1/3] net: mctp: perform source address lookups when we populate our dst Jeremy Kerr
2026-04-02 11:30   ` Paolo Abeni
2026-04-02 11:48     ` Jeremy Kerr
2026-03-31  7:41 ` Jeremy Kerr [this message]
2026-03-31  7:41 ` [PATCH net-next 3/3] net: mctp: don't require a route for null-EID ingress Jeremy Kerr
2026-04-02 11:40 ` [PATCH net-next 0/3] net: mctp: improvements for NULL-EID addressing patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260331-dev-mctp-null-eids-v1-2-b4d047372eaf@codeconstruct.com.au \
    --to=jk@codeconstruct.com.au \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=matt@codeconstruct.com.au \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox