mirror of
https://github.com/torvalds/linux.git
synced 2026-05-13 00:28:54 +02:00
net: mctp: don't require a route for null-EID ingress
Currently, if we receive a physically-addressed packet for the local stack, we perform a route_lookup_null to find a matching device-based route. If a route is present, it will always have the ->output fn set to mctp_dst_input, which provides our delivery mechanism. However, if we don't yet have any local addresses assigned, we won't have any local routes to lookup, so this will fail. One of the use-cases for physical addressing is initial address assignment on endpoint nodes, where we would have no addresses, and therefore no local routes. Instead of iterating routes (looking for one matching the dev), just create a suitable mctp_dst for the device directly. Add a testcase for the no-route case too. Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au> Link: https://patch.msgid.link/20260331-dev-mctp-null-eids-v1-3-b4d047372eaf@codeconstruct.com.au Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
8af20defc4
commit
0d8647bc74
|
|
@ -1017,29 +1017,22 @@ int mctp_route_lookup(struct net *net, unsigned int dnet,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int mctp_route_lookup_null(struct net *net, struct net_device *dev,
|
||||
struct mctp_dst *dst)
|
||||
static int mctp_dst_input_null(struct net *net, struct net_device *dev,
|
||||
struct mctp_dst *dst)
|
||||
{
|
||||
int rc = -EHOSTUNREACH;
|
||||
struct mctp_route *rt;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
list_for_each_entry_rcu(rt, &net->mctp.routes, list) {
|
||||
if (rt->dst_type != MCTP_ROUTE_DIRECT || rt->type != RTN_LOCAL)
|
||||
continue;
|
||||
|
||||
if (rt->dev->dev != dev)
|
||||
continue;
|
||||
|
||||
mctp_dst_from_route(dst, 0, 0, rt);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
dst->dev = __mctp_dev_get(dev);
|
||||
rcu_read_unlock();
|
||||
|
||||
return rc;
|
||||
if (!dst->dev)
|
||||
return -EHOSTUNREACH;
|
||||
|
||||
dst->mtu = READ_ONCE(dev->mtu);
|
||||
dst->halen = 0;
|
||||
dst->output = mctp_dst_input;
|
||||
dst->nexthop = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mctp_do_fragment_route(struct mctp_dst *dst, struct sk_buff *skb,
|
||||
|
|
@ -1369,7 +1362,7 @@ static int mctp_pkttype_receive(struct sk_buff *skb, struct net_device *dev,
|
|||
|
||||
/* NULL EID, but addressed to our physical address */
|
||||
if (rc && mh->dest == MCTP_ADDR_NULL && skb->pkt_type == PACKET_HOST)
|
||||
rc = mctp_route_lookup_null(net, dev, &dst);
|
||||
rc = mctp_dst_input_null(net, dev, &dst);
|
||||
|
||||
if (rc)
|
||||
goto err_drop;
|
||||
|
|
|
|||
|
|
@ -914,6 +914,48 @@ static void mctp_test_route_input_cloned_frag(struct kunit *test)
|
|||
__mctp_route_test_fini(test, dev, &dst, sock);
|
||||
}
|
||||
|
||||
/* check we can receive an incoming packet with the null EID as daddr, when
|
||||
* no RTN_LOCAL routes are present.
|
||||
*/
|
||||
static void mctp_test_route_input_null_eid(struct kunit *test)
|
||||
{
|
||||
struct mctp_hdr hdr = RX_HDR(1, 10, 0, FL_S | FL_E | FL_TO);
|
||||
struct sk_buff *skb_pkt, *skb_sk;
|
||||
struct mctp_test_dev *dev;
|
||||
struct sockaddr_mctp addr;
|
||||
struct socket *sock;
|
||||
u8 type = 0;
|
||||
int rc;
|
||||
|
||||
dev = mctp_test_create_dev();
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock);
|
||||
KUNIT_ASSERT_EQ(test, rc, 0);
|
||||
|
||||
addr.smctp_family = AF_MCTP;
|
||||
addr.smctp_network = MCTP_NET_ANY;
|
||||
addr.smctp_addr.s_addr = MCTP_ADDR_ANY;
|
||||
addr.smctp_type = type;
|
||||
rc = kernel_bind(sock, (struct sockaddr_unsized *)&addr, sizeof(addr));
|
||||
KUNIT_ASSERT_EQ(test, rc, 0);
|
||||
|
||||
skb_pkt = mctp_test_create_skb_data(&hdr, &type);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb_pkt);
|
||||
|
||||
skb_pkt->dev = dev->ndev;
|
||||
skb_pkt->pkt_type = PACKET_HOST;
|
||||
|
||||
mctp_pkttype_receive(skb_pkt, dev->ndev, &mctp_packet_type, NULL);
|
||||
|
||||
skb_sk = skb_recv_datagram(sock->sk, MSG_DONTWAIT, &rc);
|
||||
KUNIT_EXPECT_NOT_ERR_OR_NULL(test, skb_sk);
|
||||
|
||||
skb_free_datagram(sock->sk, skb_sk);
|
||||
sock_release(sock);
|
||||
mctp_test_destroy_dev(dev);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_MCTP_FLOWS)
|
||||
|
||||
static void mctp_test_flow_init(struct kunit *test,
|
||||
|
|
@ -1693,6 +1735,7 @@ static struct kunit_case mctp_test_cases[] = {
|
|||
KUNIT_CASE(mctp_test_route_input_sk_fail_frag),
|
||||
KUNIT_CASE(mctp_test_route_input_multiple_nets_bind),
|
||||
KUNIT_CASE(mctp_test_route_input_multiple_nets_key),
|
||||
KUNIT_CASE(mctp_test_route_input_null_eid),
|
||||
KUNIT_CASE(mctp_test_packet_flow),
|
||||
KUNIT_CASE(mctp_test_fragment_flow),
|
||||
KUNIT_CASE(mctp_test_route_output_key_create),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user