* [PATCH net-next] net: mctp: add MCTP_OPT_ROUTE_SRCADDR getsockopt
@ 2026-09-21 3:51 Faizan Ali
2026-09-22 1:23 ` Jeremy Kerr
0 siblings, 1 reply; 3+ messages in thread
From: Faizan Ali @ 2026-09-21 3:51 UTC (permalink / raw)
To: Jeremy Kerr, Matt Johnston
Cc: netdev, linux-kernel, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
David S . Miller, Simon Horman, Faizan Ali
Add a new socket option MCTP_OPT_ROUTE_SRCADDR that allows applications
to query which local EID the kernel would use as the source address
when sending to a given destination EID.
Applications such as PLDM need to advertise a local EID as the event
receiver address to remote endpoints. Previously this required a manual
multi-step lookup via the mctp tool (route show + addr show).
The kernel routing table is the authoritative
source for this mapping, so expose it directly via a socket option.
The caller fills in net and daddr in struct mctp_route_srcaddr before
calling getsockopt(SOL_MCTP, MCTP_OPT_ROUTE_SRCADDR); the kernel
performs the same route lookup used for actual packet output and
returns the resolved local EID in saddr.
Verified with the included kunit tests, and manually validated on
hardware that the resolved source EID matches mctp route show / addr
show output for both reachable and unreachable destinations.
Link: https://github.com/CodeConstruct/mctp/issues/147
Signed-off-by: Faizan Ali <faizana@nvidia.com>
---
include/uapi/linux/mctp.h | 13 +++++++++
net/mctp/af_mctp.c | 31 ++++++++++++++++++++
net/mctp/test/sock-test.c | 61 +++++++++++++++++++++++++++++++++++++++
3 files changed, 105 insertions(+)
diff --git a/include/uapi/linux/mctp.h b/include/uapi/linux/mctp.h
index 19ad12a0c..7c3d4a936 100644
--- a/include/uapi/linux/mctp.h
+++ b/include/uapi/linux/mctp.h
@@ -55,6 +55,19 @@ struct mctp_fq_addr {
#define MCTP_TAG_PREALLOC 0x10
#define MCTP_OPT_ADDR_EXT 1
+#define MCTP_OPT_ROUTE_SRCADDR 2
+
+/* Query structure for MCTP_OPT_ROUTE_SRCADDR getsockopt.
+ *
+ * Caller fills in @net and @daddr before calling getsockopt.
+ * Performs a route lookup and returns the local source EID in @saddr.
+ */
+struct mctp_route_srcaddr {
+ unsigned int net;
+ mctp_eid_t daddr;
+ mctp_eid_t saddr;
+ __u8 __pad[2];
+};
#define SIOCMCTPALLOCTAG (SIOCPROTOPRIVATE + 0)
#define SIOCMCTPDROPTAG (SIOCPROTOPRIVATE + 1)
diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
index 8af5e2b3c..5c6077e03 100644
--- a/net/mctp/af_mctp.c
+++ b/net/mctp/af_mctp.c
@@ -425,6 +425,37 @@ static int mctp_getsockopt(struct socket *sock, int level, int optname,
return 0;
}
+ if (optname == MCTP_OPT_ROUTE_SRCADDR) {
+ struct mctp_route_srcaddr rsa;
+ struct mctp_dst dst;
+ unsigned int net;
+ int rc;
+
+ if (len != sizeof(rsa))
+ return -EINVAL;
+
+ if (copy_from_iter(&rsa, len, &opt->iter_in) != len)
+ return -EFAULT;
+
+ net = rsa.net;
+ if (net == MCTP_NET_ANY)
+ net = mctp_default_net(sock_net(sock->sk));
+
+ rc = mctp_route_lookup(sock_net(sock->sk), net, rsa.daddr, &dst);
+ if (rc)
+ return rc;
+
+ rsa.saddr = dst.saddr;
+ mctp_dst_release(&dst);
+
+ if (rsa.saddr == MCTP_ADDR_NULL)
+ return -EADDRNOTAVAIL;
+
+ if (copy_to_iter(&rsa, len, &opt->iter_out) != len)
+ return -EFAULT;
+ return 0;
+ }
+
return -ENOPROTOOPT;
}
diff --git a/net/mctp/test/sock-test.c b/net/mctp/test/sock-test.c
index b0942deb5..b3ebc504b 100644
--- a/net/mctp/test/sock-test.c
+++ b/net/mctp/test/sock-test.c
@@ -379,10 +379,71 @@ static void mctp_test_assumptions(struct kunit *test)
KUNIT_ASSERT_EQ(test, mctp_default_net(&init_net), 1);
}
+static void mctp_test_sockopt_init(sockopt_t *opt, struct kvec *vec,
+ void *buf, size_t len)
+{
+ vec->iov_base = buf;
+ vec->iov_len = len;
+ iov_iter_kvec(&opt->iter_in, ITER_SOURCE, vec, 1, len);
+ iov_iter_kvec(&opt->iter_out, ITER_DEST, vec, 1, len);
+ opt->optlen = len;
+}
+
+static void mctp_test_getsockopt_route_srcaddr(struct kunit *test)
+{
+ struct mctp_route_srcaddr rsa = {
+ .net = MCTP_INITIAL_DEFAULT_NET,
+ .daddr = 9,
+ };
+ struct mctp_test_route *rt;
+ struct mctp_test_dev *dev;
+ struct socket *sock;
+ struct kvec vec;
+ sockopt_t opt;
+ int rc;
+
+ __mctp_sock_test_init(test, &dev, &rt, &sock);
+
+ /* Query the source EID for destination EID 9; the device has
+ * local EID 8, so the route lookup should return saddr=8.
+ */
+ mctp_test_sockopt_init(&opt, &vec, &rsa, sizeof(rsa));
+ rc = mctp_getsockopt(sock, SOL_MCTP, MCTP_OPT_ROUTE_SRCADDR, &opt);
+ KUNIT_EXPECT_EQ(test, rc, 0);
+ KUNIT_EXPECT_EQ(test, (int)rsa.saddr, 8);
+ KUNIT_EXPECT_EQ(test, opt.optlen, (int)sizeof(rsa));
+
+ __mctp_sock_test_fini(test, dev, rt, sock);
+}
+
+static void mctp_test_getsockopt_route_srcaddr_no_route(struct kunit *test)
+{
+ struct mctp_route_srcaddr rsa = {
+ .net = MCTP_INITIAL_DEFAULT_NET,
+ .daddr = 99, /* no route for this EID */
+ };
+ struct mctp_test_route *rt;
+ struct mctp_test_dev *dev;
+ struct socket *sock;
+ struct kvec vec;
+ sockopt_t opt;
+ int rc;
+
+ __mctp_sock_test_init(test, &dev, &rt, &sock);
+
+ mctp_test_sockopt_init(&opt, &vec, &rsa, sizeof(rsa));
+ rc = mctp_getsockopt(sock, SOL_MCTP, MCTP_OPT_ROUTE_SRCADDR, &opt);
+ KUNIT_EXPECT_EQ(test, rc, -EHOSTUNREACH);
+
+ __mctp_sock_test_fini(test, dev, rt, sock);
+}
+
static struct kunit_case mctp_test_cases[] = {
KUNIT_CASE(mctp_test_assumptions),
KUNIT_CASE(mctp_test_sock_sendmsg_extaddr),
KUNIT_CASE(mctp_test_sock_recvmsg_extaddr),
+ KUNIT_CASE(mctp_test_getsockopt_route_srcaddr),
+ KUNIT_CASE(mctp_test_getsockopt_route_srcaddr_no_route),
KUNIT_CASE_PARAM(mctp_test_bind_conflicts, mctp_bind_pair_gen_params),
KUNIT_CASE(mctp_test_bind_invalid),
{}
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net-next] net: mctp: add MCTP_OPT_ROUTE_SRCADDR getsockopt
2026-09-21 3:51 [PATCH net-next] net: mctp: add MCTP_OPT_ROUTE_SRCADDR getsockopt Faizan Ali
@ 2026-09-22 1:23 ` Jeremy Kerr
2026-09-23 8:27 ` Faizan Ali
0 siblings, 1 reply; 3+ messages in thread
From: Jeremy Kerr @ 2026-09-22 1:23 UTC (permalink / raw)
To: Faizan Ali, Matt Johnston
Cc: netdev, linux-kernel, Jakub Kicinski, Paolo Abeni, Eric Dumazet,
David S . Miller, Simon Horman
Hi Faizan,
> Add a new socket option MCTP_OPT_ROUTE_SRCADDR that allows applications
> to query which local EID the kernel would use as the source address
> when sending to a given destination EID.
>
> Applications such as PLDM need to advertise a local EID as the event
> receiver address to remote endpoints. Previously this required a manual
> multi-step lookup via the mctp tool (route show + addr show).
> The kernel routing table is the authoritative
> source for this mapping, so expose it directly via a socket option.
As I had asked earlier, can you elaborate on why this is needed over
choosing any local address? Is there a routing topology where this
would not work?
I'm not against the idea, we just need a fairly solidy justification
for adding user ABI that cannot be changed in future.
Cheers,
Jeremy
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net-next] net: mctp: add MCTP_OPT_ROUTE_SRCADDR getsockopt
2026-09-22 1:23 ` Jeremy Kerr
@ 2026-09-23 8:27 ` Faizan Ali
0 siblings, 0 replies; 3+ messages in thread
From: Faizan Ali @ 2026-09-23 8:27 UTC (permalink / raw)
To: Jeremy Kerr
Cc: Matt Johnston, netdev, linux-kernel, Jakub Kicinski, Paolo Abeni,
Eric Dumazet, David S . Miller, Simon Horman, Faizan Ali
Hello Jeremy,
Sorry, I missed following up on this earlier - continuing our
conversation from the earlier thread.
> As I had asked earlier, can you elaborate on why this is needed over
> choosing any local address? Is there a routing topology where this
> would not work?
>
> I'm not against the idea, we just need a fairly solidy justification
> for adding user ABI that cannot be changed in future.
In theory, yes - any incoming message destined to an active local EID
should reach an application bound to that message type. That said, I
still find these problems with simply picking any local EID:
1. It requires a snapshot of all available local EIDs first -
information the kernel already has internally via the routing
table, but which applications can today only get via ad-hoc mctp
route/addr correlation.
2. Not every local EID is reachable from every peer, even on the same
network. Example from our hardware:
BMC --USB(EID 8)--> SMA(EID 20) --I3C--> GPU(EID 30)
BMC also has a separate mctpi2c0 (EID 9), unrelated to the SMA.
Reaching the GPU is a gateway route (30 -> via 20 -> via 8), which
mctp_route_lookup() already resolves correctly today for
sendmsg(). If PLDM instead picks "any" EID and gets 9, the GPU's
event notifications go out via I3C to the SMA - which has no
knowledge of EID 9 at all (it's on an unrelated bus). The packet is
undeliverable at the SMA itself, one hop before it would even reach
the BMC.
I acknowledge this is implementation-specific, and additional
route provisioning on the bridge could help - but that still
requires out-of-band configuration to stay in sync with every
local EID. Separately, how device firmware handles Set Event
Receiver packets carrying an EID different from the one it saw
during Set Endpoint ID discovery is also implementation-defined.
3. A picked EID doesn't stay valid - interface teardown (hot unplug)
removes its local EID from the available routes, and Set Event
Receiver is a one-shot registration with no way to detect that
drift later. Further events would then be silently dropped by the
kernel, since it has no route for the removed EID, and would never
reach the application.
The kernel already walks this resolution (including gateway chains)
correctly for every sendmsg() - this just exposes that same lookup,
rather than requiring applications to parse route/addr output and
re-derive it themselves.
Regards,
Faizan
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-23 8:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-21 3:51 [PATCH net-next] net: mctp: add MCTP_OPT_ROUTE_SRCADDR getsockopt Faizan Ali
2026-09-22 1:23 ` Jeremy Kerr
2026-09-23 8:27 ` Faizan Ali
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®