All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 12/13] net: mctp: add gateway routing support
  2025-06-11  6:30 [PATCH net-next 00/13] net: mctp: Add support for gateway routing Jeremy Kerr
@ 2025-06-11  6:30 ` Jeremy Kerr
  2025-06-13 17:11   ` Simon Horman
  2025-06-18 17:26   ` Dan Carpenter
  0 siblings, 2 replies; 4+ messages in thread
From: Jeremy Kerr @ 2025-06-11  6:30 UTC (permalink / raw)
  To: Matt Johnston, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: netdev

This change allows for gateway routing, where a route table entry
may reference a routable endpoint (by network and EID), instead of
routing directly to a netdevice.

We add support for a RTM_GATEWAY attribute for netlink route updates,
with an attribute format of:

    struct mctp_fq_addr {
        unsigned int net;
        mctp_eid_t eid;
    }

- we need the net here to uniquely identify the target EID, as we no
longer have the device reference directly (which would provide the net
id in the case of direct routes).

This makes route lookups recursive, as a route lookup that returns a
gateway route must be resolved into a direct route (ie, to a device)
eventually. We provide a limit to the route lookups, to prevent infinite
loop routing.

The route lookup populates a new 'nexthop' field in the dst structure,
which now specifies the key for the neighbour table lookup on device
output, rather than using the packet destination address directly.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
 include/net/mctp.h        |  13 ++-
 include/uapi/linux/mctp.h |   8 ++
 net/mctp/route.c          | 200 ++++++++++++++++++++++++++++++++++------------
 net/mctp/test/utils.c     |   3 +-
 4 files changed, 171 insertions(+), 53 deletions(-)

diff --git a/include/net/mctp.h b/include/net/mctp.h
index b3af0690f60749a9bf9f489c7118c82cfd9d577e..ac4f4ecdfc24f1f481ff22a5673cb95e1bf21310 100644
--- a/include/net/mctp.h
+++ b/include/net/mctp.h
@@ -237,8 +237,18 @@ struct mctp_route {
 	mctp_eid_t		min, max;
 
 	unsigned char		type;
+
 	unsigned int		mtu;
-	struct mctp_dev		*dev;
+
+	enum {
+		MCTP_ROUTE_DIRECT,
+		MCTP_ROUTE_GATEWAY,
+	} dst_type;
+	union {
+		struct mctp_dev	*dev;
+		struct mctp_fq_addr gateway;
+	};
+
 	int			(*output)(struct mctp_dst *dst,
 					  struct sk_buff *skb);
 
@@ -256,6 +266,7 @@ struct mctp_route {
 struct mctp_dst {
 	struct mctp_dev *dev;
 	unsigned int mtu;
+	mctp_eid_t nexthop;
 
 	/* set for direct addressing */
 	unsigned char halen;
diff --git a/include/uapi/linux/mctp.h b/include/uapi/linux/mctp.h
index e1db65df9359fea810a876786b864743c77e2478..19ad12a0cd4b4599667519aaed73a12d2892aa25 100644
--- a/include/uapi/linux/mctp.h
+++ b/include/uapi/linux/mctp.h
@@ -37,6 +37,14 @@ struct sockaddr_mctp_ext {
 	__u8			smctp_haddr[MAX_ADDR_LEN];
 };
 
+/* A "fully qualified" MCTP address, which includes the system-local network ID,
+ * required to uniquely resolve a routable EID.
+ */
+struct mctp_fq_addr {
+	unsigned int	net;
+	mctp_eid_t	eid;
+};
+
 #define MCTP_NET_ANY		0x0
 
 #define MCTP_ADDR_NULL		0x00
diff --git a/net/mctp/route.c b/net/mctp/route.c
index ab5116c12b91461011c1ec3d9954609658a40a22..a3674730aaf04b01d943dc61ec8d64db174f9b53 100644
--- a/net/mctp/route.c
+++ b/net/mctp/route.c
@@ -563,7 +563,6 @@ static int mctp_dst_input(struct mctp_dst *dst, struct sk_buff *skb)
 
 static int mctp_dst_output(struct mctp_dst *dst, struct sk_buff *skb)
 {
-	struct mctp_hdr *hdr = mctp_hdr(skb);
 	char daddr_buf[MAX_ADDR_LEN];
 	char *daddr = NULL;
 	int rc;
@@ -586,7 +585,7 @@ static int mctp_dst_output(struct mctp_dst *dst, struct sk_buff *skb)
 		daddr = dst->haddr;
 	} else {
 		/* If lookup fails let the device handle daddr==NULL */
-		if (mctp_neigh_lookup(dst->dev, hdr->dest, daddr_buf) == 0)
+		if (mctp_neigh_lookup(dst->dev, dst->nexthop, daddr_buf) == 0)
 			daddr = daddr_buf;
 	}
 
@@ -610,7 +609,8 @@ static int mctp_dst_output(struct mctp_dst *dst, struct sk_buff *skb)
 static void mctp_route_release(struct mctp_route *rt)
 {
 	if (refcount_dec_and_test(&rt->refs)) {
-		mctp_dev_put(rt->dev);
+		if (rt->dst_type == MCTP_ROUTE_DIRECT)
+			mctp_dev_put(rt->dev);
 		kfree_rcu(rt, rcu);
 	}
 }
@@ -799,10 +799,16 @@ static struct mctp_sk_key *mctp_lookup_prealloc_tag(struct mctp_sock *msk,
 }
 
 /* routing lookups */
+static unsigned int mctp_route_netid(struct mctp_route *rt)
+{
+	return rt->dst_type == MCTP_ROUTE_DIRECT ?
+		READ_ONCE(rt->dev->net) : rt->gateway.net;
+}
+
 static bool mctp_rt_match_eid(struct mctp_route *rt,
 			      unsigned int net, mctp_eid_t eid)
 {
-	return READ_ONCE(rt->dev->net) == net &&
+	return mctp_route_netid(rt) == net &&
 		rt->min <= eid && rt->max >= eid;
 }
 
@@ -811,16 +817,21 @@ static bool mctp_rt_compare_exact(struct mctp_route *rt1,
 				  struct mctp_route *rt2)
 {
 	ASSERT_RTNL();
-	return rt1->dev->net == rt2->dev->net &&
+	return mctp_route_netid(rt1) == mctp_route_netid(rt2) &&
 		rt1->min == rt2->min &&
 		rt1->max == rt2->max;
 }
 
-static void mctp_dst_from_route(struct mctp_dst *dst, struct mctp_route *route)
+/* must only be called on a direct route, as the final output hop */
+static void mctp_dst_from_route(struct mctp_dst *dst, mctp_eid_t eid,
+				unsigned int mtu, struct mctp_route *route)
 {
 	mctp_dev_hold(route->dev);
+	dst->nexthop = eid;
 	dst->dev = route->dev;
-	dst->mtu = route->mtu ?: READ_ONCE(dst->dev->dev->mtu);
+	dst->mtu = READ_ONCE(dst->dev->dev->mtu);
+	if (mtu)
+		dst->mtu = min(dst->mtu, mtu);
 	dst->halen = 0;
 	dst->output = route->output;
 }
@@ -849,6 +860,7 @@ int mctp_dst_from_extaddr(struct mctp_dst *dst, struct net *net, int ifindex,
 	dst->mtu = READ_ONCE(netdev->mtu);
 	dst->halen = halen;
 	dst->output = mctp_dst_output;
+	dst->nexthop = 0;
 	memcpy(dst->haddr, haddr, halen);
 
 	rc = 0;
@@ -863,24 +875,54 @@ void mctp_dst_release(struct mctp_dst *dst)
 	mctp_dev_put(dst->dev);
 }
 
+static struct mctp_route *mctp_route_lookup_single(struct net *net,
+						   unsigned int dnet,
+						   mctp_eid_t daddr)
+{
+	struct mctp_route *rt;
+
+	list_for_each_entry_rcu(rt, &net->mctp.routes, list) {
+		if (mctp_rt_match_eid(rt, dnet, daddr))
+			return rt;
+	}
+
+	return NULL;
+}
+
 /* populates *dst on successful lookup, if set */
 int mctp_route_lookup(struct net *net, unsigned int dnet,
 		      mctp_eid_t daddr, struct mctp_dst *dst)
 {
+	const unsigned int max_depth = 32;
+	unsigned int depth, mtu = 0;
 	int rc = -EHOSTUNREACH;
-	struct mctp_route *rt;
 
 	rcu_read_lock();
 
-	list_for_each_entry_rcu(rt, &net->mctp.routes, list) {
-		/* TODO: add metrics */
-		if (!mctp_rt_match_eid(rt, dnet, daddr))
-			continue;
+	for (depth = 0; depth < max_depth; depth++) {
+		struct mctp_route *rt;
 
-		if (dst)
-			mctp_dst_from_route(dst, rt);
-		rc = 0;
-		break;
+		rt = mctp_route_lookup_single(net, dnet, daddr);
+		if (!rt)
+			break;
+
+		/* clamp mtu to the smallest in the path, allowing 0
+		 * to specify no restrictions
+		 */
+		if (mtu && rt->mtu)
+			mtu = min(mtu, rt->mtu);
+		else
+			mtu = mtu ?: rt->mtu;
+
+		if (rt->dst_type == MCTP_ROUTE_DIRECT) {
+			if (dst)
+				mctp_dst_from_route(dst, daddr, mtu, rt);
+			rc = 0;
+			break;
+
+		} else if (rt->dst_type == MCTP_ROUTE_GATEWAY) {
+			daddr = rt->gateway.eid;
+		}
 	}
 
 	rcu_read_unlock();
@@ -897,10 +939,13 @@ static int mctp_route_lookup_null(struct net *net, struct net_device *dev,
 	rcu_read_lock();
 
 	list_for_each_entry_rcu(rt, &net->mctp.routes, list) {
-		if (rt->dev->dev != dev || rt->type != RTN_LOCAL)
+		if (rt->dst_type != MCTP_ROUTE_DIRECT || rt->type != RTN_LOCAL)
 			continue;
 
-		mctp_dst_from_route(dst, rt);
+		if (rt->dev->dev != dev)
+			continue;
+
+		mctp_dst_from_route(dst, 0, 0, rt);
 		rc = 0;
 		break;
 	}
@@ -1080,11 +1125,6 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst,
 	return rc;
 }
 
-static unsigned int mctp_route_netid(struct mctp_route *rt)
-{
-	return rt->dev->net;
-}
-
 /* route management */
 
 /* mctp_route_add(): Add the provided route, previously allocated via
@@ -1092,9 +1132,9 @@ static unsigned int mctp_route_netid(struct mctp_route *rt)
  * hold on rt->dev for usage in the route table. On failure a caller will want
  * to mctp_route_release().
  *
- * We expect that the caller has set rt->type, rt->min, rt->max, rt->dev and
- * rt->mtu, and that the route holds a reference to rt->dev (via mctp_dev_hold).
- * Other fields will be populated.
+ * We expect that the caller has set rt->type, rt->dst_type, rt->min, rt->max,
+ * rt->mtu and either rt->dev (with a reference held appropriately) or
+ * rt->gateway. Other fields will be populated.
  */
 static int mctp_route_add(struct net *net, struct mctp_route *rt)
 {
@@ -1103,7 +1143,10 @@ static int mctp_route_add(struct net *net, struct mctp_route *rt)
 	if (!mctp_address_unicast(rt->min) || !mctp_address_unicast(rt->max))
 		return -EINVAL;
 
-	if (!rt->dev)
+	if (rt->dst_type == MCTP_ROUTE_DIRECT && !rt->dev)
+		return -EINVAL;
+
+	if (rt->dst_type == MCTP_ROUTE_GATEWAY && !rt->gateway.eid)
 		return -EINVAL;
 
 	switch (rt->type) {
@@ -1172,6 +1215,7 @@ int mctp_route_add_local(struct mctp_dev *mdev, mctp_eid_t addr)
 
 	rt->min = addr;
 	rt->max = addr;
+	rt->dst_type = MCTP_ROUTE_DIRECT;
 	rt->dev = mdev;
 	rt->type = RTN_LOCAL;
 
@@ -1198,7 +1242,7 @@ void mctp_route_remove_dev(struct mctp_dev *mdev)
 
 	ASSERT_RTNL();
 	list_for_each_entry_safe(rt, tmp, &net->mctp.routes, list) {
-		if (rt->dev == mdev) {
+		if (rt->dst_type == MCTP_ROUTE_DIRECT && rt->dev == mdev) {
 			list_del_rcu(&rt->list);
 			/* TODO: immediate RTM_DELROUTE */
 			mctp_route_release(rt);
@@ -1291,21 +1335,28 @@ static const struct nla_policy rta_mctp_policy[RTA_MAX + 1] = {
 	[RTA_DST]		= { .type = NLA_U8 },
 	[RTA_METRICS]		= { .type = NLA_NESTED },
 	[RTA_OIF]		= { .type = NLA_U32 },
+	[RTA_GATEWAY]		= NLA_POLICY_EXACT_LEN(sizeof(struct mctp_fq_addr)),
 };
 
 static const struct nla_policy rta_metrics_policy[RTAX_MAX + 1] = {
 	[RTAX_MTU]		= { .type = NLA_U32 },
 };
 
-/* base parsing; common to both _lookup and _populate variants */
+/* base parsing; common to both _lookup and _populate variants.
+ *
+ * For gateway routes (which have a RTA_GATEWAY, and no RTA_OIF), we populate
+ * *gatweayp. for direct routes (RTA_OIF, no RTA_GATEWAY), we populate *mdev.
+ */
 static int mctp_route_nlparse_common(struct net *net, struct nlmsghdr *nlh,
 				     struct netlink_ext_ack *extack,
 				     struct nlattr **tb, struct rtmsg **rtm,
 				     struct mctp_dev **mdev,
+				     struct mctp_fq_addr *gatewayp,
 				     mctp_eid_t *daddr_start)
 {
+	struct mctp_fq_addr *gateway;
+	unsigned int ifindex = 0;
 	struct net_device *dev;
-	unsigned int ifindex;
 	int rc;
 
 	rc = nlmsg_parse(nlh, sizeof(struct rtmsg), tb, RTA_MAX,
@@ -1321,11 +1372,44 @@ static int mctp_route_nlparse_common(struct net *net, struct nlmsghdr *nlh,
 	}
 	*daddr_start = nla_get_u8(tb[RTA_DST]);
 
-	if (!tb[RTA_OIF]) {
-		NL_SET_ERR_MSG(extack, "ifindex missing");
+	if (tb[RTA_OIF])
+		ifindex = nla_get_u32(tb[RTA_OIF]);
+
+	if (tb[RTA_GATEWAY])
+		gateway = nla_data(tb[RTA_GATEWAY]);
+
+	if (ifindex && gateway) {
+		NL_SET_ERR_MSG(extack,
+			       "cannot specify both ifindex and gateway");
+		return -EINVAL;
+
+	} else if (ifindex) {
+		dev = __dev_get_by_index(net, ifindex);
+		if (!dev) {
+			NL_SET_ERR_MSG(extack, "bad ifindex");
+			return -ENODEV;
+		}
+		*mdev = mctp_dev_get_rtnl(dev);
+		if (!*mdev)
+			return -ENODEV;
+		gatewayp->eid = 0;
+
+	} else if (gateway) {
+		if (!mctp_address_unicast(gateway->eid)) {
+			NL_SET_ERR_MSG(extack, "bad gateway");
+			return -EINVAL;
+		}
+
+		gatewayp->eid = gateway->eid;
+		gatewayp->net = gateway->net != MCTP_NET_ANY ?
+			gateway->net :
+			READ_ONCE(net->mctp.default_net);
+		*mdev = NULL;
+
+	} else {
+		NL_SET_ERR_MSG(extack, "no route output provided");
 		return -EINVAL;
 	}
-	ifindex = nla_get_u32(tb[RTA_OIF]);
 
 	*rtm = nlmsg_data(nlh);
 	if ((*rtm)->rtm_family != AF_MCTP) {
@@ -1338,16 +1422,6 @@ static int mctp_route_nlparse_common(struct net *net, struct nlmsghdr *nlh,
 		return -EINVAL;
 	}
 
-	dev = __dev_get_by_index(net, ifindex);
-	if (!dev) {
-		NL_SET_ERR_MSG(extack, "bad ifindex");
-		return -ENODEV;
-	}
-
-	*mdev = mctp_dev_get_rtnl(dev);
-	if (!*mdev)
-		return -ENODEV;
-
 	return 0;
 }
 
@@ -1361,16 +1435,25 @@ static int mctp_route_nlparse_lookup(struct net *net, struct nlmsghdr *nlh,
 				     unsigned int *daddr_extent)
 {
 	struct nlattr *tb[RTA_MAX + 1];
+	struct mctp_fq_addr gw;
 	struct mctp_dev *mdev;
 	struct rtmsg *rtm;
 	int rc;
 
 	rc = mctp_route_nlparse_common(net, nlh, extack, tb, &rtm,
-				       &mdev, daddr_start);
+				       &mdev, &gw, daddr_start);
 	if (rc)
 		return rc;
 
-	*netid = mdev->net;
+	if (mdev) {
+		*netid = mdev->net;
+	} else if (gw.eid) {
+		*netid = gw.net;
+	} else {
+		/* bug: _nlparse_common should not allow this */
+		return -1;
+	}
+
 	*type = rtm->rtm_type;
 	*daddr_extent = rtm->rtm_dst_len;
 
@@ -1385,11 +1468,13 @@ static int mctp_route_nlparse_populate(struct net *net, struct nlmsghdr *nlh,
 	struct nlattr *tbx[RTAX_MAX + 1];
 	struct nlattr *tb[RTA_MAX + 1];
 	unsigned int daddr_extent;
+	struct mctp_fq_addr gw;
+	struct mctp_dev *mdev;
 	struct rtmsg *rtm;
 	int rc;
 
 	rc = mctp_route_nlparse_common(net, nlh, extack, tb, &rtm,
-				       &rt->dev, &rt->min);
+				       &mdev, &gw, &rt->min);
 	if (rc)
 		return rc;
 
@@ -1400,6 +1485,15 @@ static int mctp_route_nlparse_populate(struct net *net, struct nlmsghdr *nlh,
 		return -EINVAL;
 	}
 
+	if (gw.eid) {
+		rt->dst_type = MCTP_ROUTE_GATEWAY;
+		rt->gateway.eid = gw.eid;
+		rt->gateway.net = gw.net;
+	} else {
+		rt->dst_type = MCTP_ROUTE_DIRECT;
+		rt->dev = mdev;
+	}
+
 	rt->type = rtm->rtm_type;
 	rt->max = rt->min + daddr_extent;
 	rt->mtu = 0;
@@ -1433,7 +1527,8 @@ static int mctp_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (rc < 0)
 		goto err_free;
 
-	mctp_dev_hold(rt->dev);
+	if (rt->dst_type == MCTP_ROUTE_DIRECT)
+		mctp_dev_hold(rt->dev);
 
 	rc = mctp_route_add(net, rt);
 	if (!rc)
@@ -1488,7 +1583,6 @@ static int mctp_fill_rtinfo(struct sk_buff *skb, struct mctp_route *rt,
 	hdr->rtm_tos = 0;
 	hdr->rtm_table = RT_TABLE_DEFAULT;
 	hdr->rtm_protocol = RTPROT_STATIC; /* everything is user-defined */
-	hdr->rtm_scope = RT_SCOPE_LINK; /* TODO: scope in mctp_route? */
 	hdr->rtm_type = rt->type;
 
 	if (nla_put_u8(skb, RTA_DST, rt->min))
@@ -1505,13 +1599,17 @@ static int mctp_fill_rtinfo(struct sk_buff *skb, struct mctp_route *rt,
 
 	nla_nest_end(skb, metrics);
 
-	if (rt->dev) {
+	if (rt->dst_type == MCTP_ROUTE_DIRECT) {
+		hdr->rtm_scope = RT_SCOPE_LINK;
 		if (nla_put_u32(skb, RTA_OIF, rt->dev->dev->ifindex))
 			goto cancel;
+	} else if (rt->dst_type == MCTP_ROUTE_GATEWAY) {
+		hdr->rtm_scope = RT_SCOPE_UNIVERSE;
+		if (nla_put(skb, RTA_GATEWAY,
+			    sizeof(rt->gateway), &rt->gateway))
+			goto cancel;
 	}
 
-	/* TODO: conditional neighbour physaddr? */
-
 	nlmsg_end(skb, nlh);
 
 	return 0;
diff --git a/net/mctp/test/utils.c b/net/mctp/test/utils.c
index 6b4dc40d882c912575e28dfd8f2e730bf346885f..97b05e340586f69d8ba04c970b0ee88391db006a 100644
--- a/net/mctp/test/utils.c
+++ b/net/mctp/test/utils.c
@@ -134,6 +134,7 @@ struct mctp_test_route *mctp_test_create_route(struct net *net,
 	rt->rt.max = eid;
 	rt->rt.mtu = mtu;
 	rt->rt.type = RTN_UNSPEC;
+	rt->rt.dst_type = MCTP_ROUTE_DIRECT;
 	if (dev)
 		mctp_dev_hold(dev);
 	rt->rt.dev = dev;
@@ -176,7 +177,7 @@ void mctp_test_route_destroy(struct kunit *test, struct mctp_test_route *rt)
 	list_del_rcu(&rt->rt.list);
 	rtnl_unlock();
 
-	if (rt->rt.dev)
+	if (rt->rt.dst_type == MCTP_ROUTE_DIRECT && rt->rt.dev)
 		mctp_dev_put(rt->rt.dev);
 
 	refs = refcount_read(&rt->rt.refs);

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next 12/13] net: mctp: add gateway routing support
@ 2025-06-13  7:34 kernel test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2025-06-13  7:34 UTC (permalink / raw)
  To: oe-kbuild; +Cc: lkp, Dan Carpenter

BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
In-Reply-To: <20250611-dev-forwarding-v1-12-6b69b1feb37f@codeconstruct.com.au>
References: <20250611-dev-forwarding-v1-12-6b69b1feb37f@codeconstruct.com.au>
TO: Jeremy Kerr <jk@codeconstruct.com.au>
TO: Matt Johnston <matt@codeconstruct.com.au>
TO: "David S. Miller" <davem@davemloft.net>
CC: netdev@vger.kernel.org
TO: Eric Dumazet <edumazet@google.com>
TO: Jakub Kicinski <kuba@kernel.org>
TO: Paolo Abeni <pabeni@redhat.com>
TO: Simon Horman <horms@kernel.org>

Hi Jeremy,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 0097c4195b1d0ca57d15979626c769c74747b5a0]

url:    https://github.com/intel-lab-lkp/linux/commits/Jeremy-Kerr/net-mctp-don-t-use-source-cb-data-when-forwarding-ensure-pkt_type-is-set/20250611-143319
base:   0097c4195b1d0ca57d15979626c769c74747b5a0
patch link:    https://lore.kernel.org/r/20250611-dev-forwarding-v1-12-6b69b1feb37f%40codeconstruct.com.au
patch subject: [PATCH net-next 12/13] net: mctp: add gateway routing support
:::::: branch date: 2 days ago
:::::: commit date: 2 days ago
config: csky-randconfig-r073-20250612 (https://download.01.org/0day-ci/archive/20250613/202506131515.a5tCsTj0-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 14.3.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Closes: https://lore.kernel.org/r/202506131515.a5tCsTj0-lkp@intel.com/

New smatch warnings:
net/mctp/route.c:1381 mctp_route_nlparse_common() error: uninitialized symbol 'gateway'.

Old smatch warnings:
net/mctp/route.c:1397 mctp_route_nlparse_common() error: uninitialized symbol 'gateway'.

vim +/gateway +1381 net/mctp/route.c

33d33bef994e518 Jeremy Kerr   2025-06-11  1344  
75626016e50cb9a Jeremy Kerr   2025-06-11  1345  /* base parsing; common to both _lookup and _populate variants.
75626016e50cb9a Jeremy Kerr   2025-06-11  1346   *
75626016e50cb9a Jeremy Kerr   2025-06-11  1347   * For gateway routes (which have a RTA_GATEWAY, and no RTA_OIF), we populate
75626016e50cb9a Jeremy Kerr   2025-06-11  1348   * *gatweayp. for direct routes (RTA_OIF, no RTA_GATEWAY), we populate *mdev.
75626016e50cb9a Jeremy Kerr   2025-06-11  1349   */
33d33bef994e518 Jeremy Kerr   2025-06-11  1350  static int mctp_route_nlparse_common(struct net *net, struct nlmsghdr *nlh,
06d2f4c583a7d89 Matt Johnston 2021-07-29  1351  				     struct netlink_ext_ack *extack,
06d2f4c583a7d89 Matt Johnston 2021-07-29  1352  				     struct nlattr **tb, struct rtmsg **rtm,
33d33bef994e518 Jeremy Kerr   2025-06-11  1353  				     struct mctp_dev **mdev,
75626016e50cb9a Jeremy Kerr   2025-06-11  1354  				     struct mctp_fq_addr *gatewayp,
33d33bef994e518 Jeremy Kerr   2025-06-11  1355  				     mctp_eid_t *daddr_start)
06d2f4c583a7d89 Matt Johnston 2021-07-29  1356  {
75626016e50cb9a Jeremy Kerr   2025-06-11  1357  	struct mctp_fq_addr *gateway;
75626016e50cb9a Jeremy Kerr   2025-06-11  1358  	unsigned int ifindex = 0;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1359  	struct net_device *dev;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1360  	int rc;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1361  
06d2f4c583a7d89 Matt Johnston 2021-07-29  1362  	rc = nlmsg_parse(nlh, sizeof(struct rtmsg), tb, RTA_MAX,
06d2f4c583a7d89 Matt Johnston 2021-07-29  1363  			 rta_mctp_policy, extack);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1364  	if (rc < 0) {
06d2f4c583a7d89 Matt Johnston 2021-07-29  1365  		NL_SET_ERR_MSG(extack, "incorrect format");
06d2f4c583a7d89 Matt Johnston 2021-07-29  1366  		return rc;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1367  	}
06d2f4c583a7d89 Matt Johnston 2021-07-29  1368  
06d2f4c583a7d89 Matt Johnston 2021-07-29  1369  	if (!tb[RTA_DST]) {
06d2f4c583a7d89 Matt Johnston 2021-07-29  1370  		NL_SET_ERR_MSG(extack, "dst EID missing");
06d2f4c583a7d89 Matt Johnston 2021-07-29  1371  		return -EINVAL;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1372  	}
06d2f4c583a7d89 Matt Johnston 2021-07-29  1373  	*daddr_start = nla_get_u8(tb[RTA_DST]);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1374  
75626016e50cb9a Jeremy Kerr   2025-06-11  1375  	if (tb[RTA_OIF])
06d2f4c583a7d89 Matt Johnston 2021-07-29  1376  		ifindex = nla_get_u32(tb[RTA_OIF]);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1377  
75626016e50cb9a Jeremy Kerr   2025-06-11  1378  	if (tb[RTA_GATEWAY])
75626016e50cb9a Jeremy Kerr   2025-06-11  1379  		gateway = nla_data(tb[RTA_GATEWAY]);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1380  
75626016e50cb9a Jeremy Kerr   2025-06-11 @1381  	if (ifindex && gateway) {
75626016e50cb9a Jeremy Kerr   2025-06-11  1382  		NL_SET_ERR_MSG(extack,
75626016e50cb9a Jeremy Kerr   2025-06-11  1383  			       "cannot specify both ifindex and gateway");
33d33bef994e518 Jeremy Kerr   2025-06-11  1384  		return -EINVAL;
33d33bef994e518 Jeremy Kerr   2025-06-11  1385  
75626016e50cb9a Jeremy Kerr   2025-06-11  1386  	} else if (ifindex) {
06d2f4c583a7d89 Matt Johnston 2021-07-29  1387  		dev = __dev_get_by_index(net, ifindex);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1388  		if (!dev) {
06d2f4c583a7d89 Matt Johnston 2021-07-29  1389  			NL_SET_ERR_MSG(extack, "bad ifindex");
06d2f4c583a7d89 Matt Johnston 2021-07-29  1390  			return -ENODEV;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1391  		}
06d2f4c583a7d89 Matt Johnston 2021-07-29  1392  		*mdev = mctp_dev_get_rtnl(dev);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1393  		if (!*mdev)
06d2f4c583a7d89 Matt Johnston 2021-07-29  1394  			return -ENODEV;
75626016e50cb9a Jeremy Kerr   2025-06-11  1395  		gatewayp->eid = 0;
75626016e50cb9a Jeremy Kerr   2025-06-11  1396  
75626016e50cb9a Jeremy Kerr   2025-06-11  1397  	} else if (gateway) {
75626016e50cb9a Jeremy Kerr   2025-06-11  1398  		if (!mctp_address_unicast(gateway->eid)) {
75626016e50cb9a Jeremy Kerr   2025-06-11  1399  			NL_SET_ERR_MSG(extack, "bad gateway");
75626016e50cb9a Jeremy Kerr   2025-06-11  1400  			return -EINVAL;
75626016e50cb9a Jeremy Kerr   2025-06-11  1401  		}
75626016e50cb9a Jeremy Kerr   2025-06-11  1402  
75626016e50cb9a Jeremy Kerr   2025-06-11  1403  		gatewayp->eid = gateway->eid;
75626016e50cb9a Jeremy Kerr   2025-06-11  1404  		gatewayp->net = gateway->net != MCTP_NET_ANY ?
75626016e50cb9a Jeremy Kerr   2025-06-11  1405  			gateway->net :
75626016e50cb9a Jeremy Kerr   2025-06-11  1406  			READ_ONCE(net->mctp.default_net);
75626016e50cb9a Jeremy Kerr   2025-06-11  1407  		*mdev = NULL;
75626016e50cb9a Jeremy Kerr   2025-06-11  1408  
75626016e50cb9a Jeremy Kerr   2025-06-11  1409  	} else {
75626016e50cb9a Jeremy Kerr   2025-06-11  1410  		NL_SET_ERR_MSG(extack, "no route output provided");
75626016e50cb9a Jeremy Kerr   2025-06-11  1411  		return -EINVAL;
75626016e50cb9a Jeremy Kerr   2025-06-11  1412  	}
75626016e50cb9a Jeremy Kerr   2025-06-11  1413  
75626016e50cb9a Jeremy Kerr   2025-06-11  1414  	*rtm = nlmsg_data(nlh);
75626016e50cb9a Jeremy Kerr   2025-06-11  1415  	if ((*rtm)->rtm_family != AF_MCTP) {
75626016e50cb9a Jeremy Kerr   2025-06-11  1416  		NL_SET_ERR_MSG(extack, "route family must be AF_MCTP");
75626016e50cb9a Jeremy Kerr   2025-06-11  1417  		return -EINVAL;
75626016e50cb9a Jeremy Kerr   2025-06-11  1418  	}
75626016e50cb9a Jeremy Kerr   2025-06-11  1419  
75626016e50cb9a Jeremy Kerr   2025-06-11  1420  	if ((*rtm)->rtm_type != RTN_UNICAST) {
75626016e50cb9a Jeremy Kerr   2025-06-11  1421  		NL_SET_ERR_MSG(extack, "rtm_type must be RTN_UNICAST");
75626016e50cb9a Jeremy Kerr   2025-06-11  1422  		return -EINVAL;
75626016e50cb9a Jeremy Kerr   2025-06-11  1423  	}
06d2f4c583a7d89 Matt Johnston 2021-07-29  1424  
33d33bef994e518 Jeremy Kerr   2025-06-11  1425  	return 0;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1426  }
06d2f4c583a7d89 Matt Johnston 2021-07-29  1427  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next 12/13] net: mctp: add gateway routing support
  2025-06-11  6:30 ` [PATCH net-next 12/13] net: mctp: add gateway routing support Jeremy Kerr
@ 2025-06-13 17:11   ` Simon Horman
  2025-06-18 17:26   ` Dan Carpenter
  1 sibling, 0 replies; 4+ messages in thread
From: Simon Horman @ 2025-06-13 17:11 UTC (permalink / raw)
  To: Jeremy Kerr
  Cc: Matt Johnston, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, netdev

On Wed, Jun 11, 2025 at 02:30:39PM +0800, Jeremy Kerr wrote:
> This change allows for gateway routing, where a route table entry
> may reference a routable endpoint (by network and EID), instead of
> routing directly to a netdevice.
> 
> We add support for a RTM_GATEWAY attribute for netlink route updates,
> with an attribute format of:
> 
>     struct mctp_fq_addr {
>         unsigned int net;
>         mctp_eid_t eid;
>     }
> 
> - we need the net here to uniquely identify the target EID, as we no
> longer have the device reference directly (which would provide the net
> id in the case of direct routes).
> 
> This makes route lookups recursive, as a route lookup that returns a
> gateway route must be resolved into a direct route (ie, to a device)
> eventually. We provide a limit to the route lookups, to prevent infinite
> loop routing.
> 
> The route lookup populates a new 'nexthop' field in the dst structure,
> which now specifies the key for the neighbour table lookup on device
> output, rather than using the packet destination address directly.
> 
> Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>

...

> diff --git a/net/mctp/route.c b/net/mctp/route.c

...

> -/* base parsing; common to both _lookup and _populate variants */
> +/* base parsing; common to both _lookup and _populate variants.
> + *
> + * For gateway routes (which have a RTA_GATEWAY, and no RTA_OIF), we populate
> + * *gatweayp. for direct routes (RTA_OIF, no RTA_GATEWAY), we populate *mdev.
> + */
>  static int mctp_route_nlparse_common(struct net *net, struct nlmsghdr *nlh,
>  				     struct netlink_ext_ack *extack,
>  				     struct nlattr **tb, struct rtmsg **rtm,
>  				     struct mctp_dev **mdev,
> +				     struct mctp_fq_addr *gatewayp,
>  				     mctp_eid_t *daddr_start)
>  {
> +	struct mctp_fq_addr *gateway;
> +	unsigned int ifindex = 0;
>  	struct net_device *dev;
> -	unsigned int ifindex;
>  	int rc;
>  
>  	rc = nlmsg_parse(nlh, sizeof(struct rtmsg), tb, RTA_MAX,
> @@ -1321,11 +1372,44 @@ static int mctp_route_nlparse_common(struct net *net, struct nlmsghdr *nlh,
>  	}
>  	*daddr_start = nla_get_u8(tb[RTA_DST]);
>  
> -	if (!tb[RTA_OIF]) {
> -		NL_SET_ERR_MSG(extack, "ifindex missing");
> +	if (tb[RTA_OIF])
> +		ifindex = nla_get_u32(tb[RTA_OIF]);
> +
> +	if (tb[RTA_GATEWAY])
> +		gateway = nla_data(tb[RTA_GATEWAY]);
> +
> +	if (ifindex && gateway) {

Hi Jeremy,

gateway may be uninitialised here...

> +		NL_SET_ERR_MSG(extack,
> +			       "cannot specify both ifindex and gateway");
> +		return -EINVAL;
> +
> +	} else if (ifindex) {
> +		dev = __dev_get_by_index(net, ifindex);
> +		if (!dev) {
> +			NL_SET_ERR_MSG(extack, "bad ifindex");
> +			return -ENODEV;
> +		}
> +		*mdev = mctp_dev_get_rtnl(dev);
> +		if (!*mdev)
> +			return -ENODEV;
> +		gatewayp->eid = 0;
> +
> +	} else if (gateway) {

... and here.

Flagged by Smatch.

> +		if (!mctp_address_unicast(gateway->eid)) {
> +			NL_SET_ERR_MSG(extack, "bad gateway");
> +			return -EINVAL;
> +		}
> +
> +		gatewayp->eid = gateway->eid;
> +		gatewayp->net = gateway->net != MCTP_NET_ANY ?
> +			gateway->net :
> +			READ_ONCE(net->mctp.default_net);
> +		*mdev = NULL;
> +
> +	} else {
> +		NL_SET_ERR_MSG(extack, "no route output provided");
>  		return -EINVAL;
>  	}
> -	ifindex = nla_get_u32(tb[RTA_OIF]);
>  
>  	*rtm = nlmsg_data(nlh);
>  	if ((*rtm)->rtm_family != AF_MCTP) {

...

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next 12/13] net: mctp: add gateway routing support
  2025-06-11  6:30 ` [PATCH net-next 12/13] net: mctp: add gateway routing support Jeremy Kerr
  2025-06-13 17:11   ` Simon Horman
@ 2025-06-18 17:26   ` Dan Carpenter
  1 sibling, 0 replies; 4+ messages in thread
From: Dan Carpenter @ 2025-06-18 17:26 UTC (permalink / raw)
  To: oe-kbuild, Jeremy Kerr, Matt Johnston, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman
  Cc: lkp, oe-kbuild-all, netdev

Hi Jeremy,

kernel test robot noticed the following build warnings:

url:    https://github.com/intel-lab-lkp/linux/commits/Jeremy-Kerr/net-mctp-don-t-use-source-cb-data-when-forwarding-ensure-pkt_type-is-set/20250611-143319
base:   0097c4195b1d0ca57d15979626c769c74747b5a0
patch link:    https://lore.kernel.org/r/20250611-dev-forwarding-v1-12-6b69b1feb37f%40codeconstruct.com.au
patch subject: [PATCH net-next 12/13] net: mctp: add gateway routing support
config: csky-randconfig-r073-20250612 (https://download.01.org/0day-ci/archive/20250613/202506131515.a5tCsTj0-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 14.3.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202506131515.a5tCsTj0-lkp@intel.com/

New smatch warnings:
net/mctp/route.c:1381 mctp_route_nlparse_common() error: uninitialized symbol 'gateway'.

vim +/gateway +1381 net/mctp/route.c

33d33bef994e518 Jeremy Kerr   2025-06-11  1350  static int mctp_route_nlparse_common(struct net *net, struct nlmsghdr *nlh,
06d2f4c583a7d89 Matt Johnston 2021-07-29  1351  				     struct netlink_ext_ack *extack,
06d2f4c583a7d89 Matt Johnston 2021-07-29  1352  				     struct nlattr **tb, struct rtmsg **rtm,
33d33bef994e518 Jeremy Kerr   2025-06-11  1353  				     struct mctp_dev **mdev,
75626016e50cb9a Jeremy Kerr   2025-06-11  1354  				     struct mctp_fq_addr *gatewayp,
33d33bef994e518 Jeremy Kerr   2025-06-11  1355  				     mctp_eid_t *daddr_start)
06d2f4c583a7d89 Matt Johnston 2021-07-29  1356  {
75626016e50cb9a Jeremy Kerr   2025-06-11  1357  	struct mctp_fq_addr *gateway;
75626016e50cb9a Jeremy Kerr   2025-06-11  1358  	unsigned int ifindex = 0;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1359  	struct net_device *dev;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1360  	int rc;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1361  
06d2f4c583a7d89 Matt Johnston 2021-07-29  1362  	rc = nlmsg_parse(nlh, sizeof(struct rtmsg), tb, RTA_MAX,
06d2f4c583a7d89 Matt Johnston 2021-07-29  1363  			 rta_mctp_policy, extack);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1364  	if (rc < 0) {
06d2f4c583a7d89 Matt Johnston 2021-07-29  1365  		NL_SET_ERR_MSG(extack, "incorrect format");
06d2f4c583a7d89 Matt Johnston 2021-07-29  1366  		return rc;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1367  	}
06d2f4c583a7d89 Matt Johnston 2021-07-29  1368  
06d2f4c583a7d89 Matt Johnston 2021-07-29  1369  	if (!tb[RTA_DST]) {
06d2f4c583a7d89 Matt Johnston 2021-07-29  1370  		NL_SET_ERR_MSG(extack, "dst EID missing");
06d2f4c583a7d89 Matt Johnston 2021-07-29  1371  		return -EINVAL;
06d2f4c583a7d89 Matt Johnston 2021-07-29  1372  	}
06d2f4c583a7d89 Matt Johnston 2021-07-29  1373  	*daddr_start = nla_get_u8(tb[RTA_DST]);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1374  
75626016e50cb9a Jeremy Kerr   2025-06-11  1375  	if (tb[RTA_OIF])
06d2f4c583a7d89 Matt Johnston 2021-07-29  1376  		ifindex = nla_get_u32(tb[RTA_OIF]);
06d2f4c583a7d89 Matt Johnston 2021-07-29  1377  
75626016e50cb9a Jeremy Kerr   2025-06-11  1378  	if (tb[RTA_GATEWAY])
75626016e50cb9a Jeremy Kerr   2025-06-11  1379  		gateway = nla_data(tb[RTA_GATEWAY]);

Unitialized on else path

06d2f4c583a7d89 Matt Johnston 2021-07-29  1380  
75626016e50cb9a Jeremy Kerr   2025-06-11 @1381  	if (ifindex && gateway) {
                                                                       ^^^^^^^
warning.

75626016e50cb9a Jeremy Kerr   2025-06-11  1382  		NL_SET_ERR_MSG(extack,
75626016e50cb9a Jeremy Kerr   2025-06-11  1383  			       "cannot specify both ifindex and gateway");
33d33bef994e518 Jeremy Kerr   2025-06-11  1384  		return -EINVAL;

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-06-18 17:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-13  7:34 [PATCH net-next 12/13] net: mctp: add gateway routing support kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2025-06-11  6:30 [PATCH net-next 00/13] net: mctp: Add support for gateway routing Jeremy Kerr
2025-06-11  6:30 ` [PATCH net-next 12/13] net: mctp: add gateway routing support Jeremy Kerr
2025-06-13 17:11   ` Simon Horman
2025-06-18 17:26   ` Dan Carpenter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.