mirror of
https://github.com/torvalds/linux.git
synced 2025-08-15 14:11:42 +02:00
net: mctp: Add bind lookup test
Test the preference order of bound socket matches with a series of test packets. Signed-off-by: Matt Johnston <matt@codeconstruct.com.au> Link: https://patch.msgid.link/20250710-mctp-bind-v4-8-8ec2f6460c56@codeconstruct.com.au Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
b7e28129b6
commit
e6d8e7dbc5
2 changed files with 191 additions and 0 deletions
|
@ -1408,6 +1408,193 @@ static void mctp_test_route_gw_output(struct kunit *test)
|
|||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
struct mctp_bind_lookup_test {
|
||||
/* header of incoming message */
|
||||
struct mctp_hdr hdr;
|
||||
u8 ty;
|
||||
/* mctp network of incoming interface (smctp_network) */
|
||||
unsigned int net;
|
||||
|
||||
/* expected socket, matches .name in lookup_binds, NULL for dropped */
|
||||
const char *expect;
|
||||
};
|
||||
|
||||
/* Single-packet TO-set message */
|
||||
#define LK(src, dst) RX_HDR(1, (src), (dst), FL_S | FL_E | FL_TO)
|
||||
|
||||
/* Input message test cases for bind lookup tests.
|
||||
*
|
||||
* 10 and 11 are local EIDs.
|
||||
* 20 and 21 are remote EIDs.
|
||||
*/
|
||||
static const struct mctp_bind_lookup_test mctp_bind_lookup_tests[] = {
|
||||
/* both local-eid and remote-eid binds, remote eid is preferenced */
|
||||
{ .hdr = LK(20, 10), .ty = 1, .net = 1, .expect = "remote20" },
|
||||
|
||||
{ .hdr = LK(20, 255), .ty = 1, .net = 1, .expect = "remote20" },
|
||||
{ .hdr = LK(20, 0), .ty = 1, .net = 1, .expect = "remote20" },
|
||||
{ .hdr = LK(0, 255), .ty = 1, .net = 1, .expect = "any" },
|
||||
{ .hdr = LK(0, 11), .ty = 1, .net = 1, .expect = "any" },
|
||||
{ .hdr = LK(0, 0), .ty = 1, .net = 1, .expect = "any" },
|
||||
{ .hdr = LK(0, 10), .ty = 1, .net = 1, .expect = "local10" },
|
||||
{ .hdr = LK(21, 10), .ty = 1, .net = 1, .expect = "local10" },
|
||||
{ .hdr = LK(21, 11), .ty = 1, .net = 1, .expect = "remote21local11" },
|
||||
|
||||
/* both src and dest set to eid=99. unusual, but accepted
|
||||
* by MCTP stack currently.
|
||||
*/
|
||||
{ .hdr = LK(99, 99), .ty = 1, .net = 1, .expect = "any" },
|
||||
|
||||
/* unbound smctp_type */
|
||||
{ .hdr = LK(20, 10), .ty = 3, .net = 1, .expect = NULL },
|
||||
|
||||
/* smctp_network tests */
|
||||
|
||||
{ .hdr = LK(0, 0), .ty = 1, .net = 7, .expect = "any" },
|
||||
{ .hdr = LK(21, 10), .ty = 1, .net = 2, .expect = "any" },
|
||||
|
||||
/* remote EID 20 matches, but MCTP_NET_ANY in "remote20" resolved
|
||||
* to net=1, so lookup doesn't match "remote20"
|
||||
*/
|
||||
{ .hdr = LK(20, 10), .ty = 1, .net = 3, .expect = "any" },
|
||||
|
||||
{ .hdr = LK(21, 10), .ty = 1, .net = 3, .expect = "remote21net3" },
|
||||
{ .hdr = LK(21, 10), .ty = 1, .net = 4, .expect = "remote21net4" },
|
||||
{ .hdr = LK(21, 10), .ty = 1, .net = 5, .expect = "remote21net5" },
|
||||
|
||||
{ .hdr = LK(21, 10), .ty = 1, .net = 5, .expect = "remote21net5" },
|
||||
|
||||
{ .hdr = LK(99, 10), .ty = 1, .net = 8, .expect = "local10net8" },
|
||||
|
||||
{ .hdr = LK(99, 10), .ty = 1, .net = 9, .expect = "anynet9" },
|
||||
{ .hdr = LK(0, 0), .ty = 1, .net = 9, .expect = "anynet9" },
|
||||
{ .hdr = LK(99, 99), .ty = 1, .net = 9, .expect = "anynet9" },
|
||||
{ .hdr = LK(20, 10), .ty = 1, .net = 9, .expect = "anynet9" },
|
||||
};
|
||||
|
||||
/* Binds to create during the lookup tests */
|
||||
static const struct mctp_test_bind_setup lookup_binds[] = {
|
||||
/* any address and net, type 1 */
|
||||
{ .name = "any", .bind_addr = MCTP_ADDR_ANY,
|
||||
.bind_net = MCTP_NET_ANY, .bind_type = 1, },
|
||||
/* local eid 10, net 1 (resolved from MCTP_NET_ANY) */
|
||||
{ .name = "local10", .bind_addr = 10,
|
||||
.bind_net = MCTP_NET_ANY, .bind_type = 1, },
|
||||
/* local eid 10, net 8 */
|
||||
{ .name = "local10net8", .bind_addr = 10,
|
||||
.bind_net = 8, .bind_type = 1, },
|
||||
/* any EID, net 9 */
|
||||
{ .name = "anynet9", .bind_addr = MCTP_ADDR_ANY,
|
||||
.bind_net = 9, .bind_type = 1, },
|
||||
|
||||
/* remote eid 20, net 1, any local eid */
|
||||
{ .name = "remote20", .bind_addr = MCTP_ADDR_ANY,
|
||||
.bind_net = MCTP_NET_ANY, .bind_type = 1,
|
||||
.have_peer = true, .peer_addr = 20, .peer_net = MCTP_NET_ANY, },
|
||||
|
||||
/* remote eid 20, net 1, local eid 11 */
|
||||
{ .name = "remote21local11", .bind_addr = 11,
|
||||
.bind_net = MCTP_NET_ANY, .bind_type = 1,
|
||||
.have_peer = true, .peer_addr = 21, .peer_net = MCTP_NET_ANY, },
|
||||
|
||||
/* remote eid 21, specific net=3 for connect() */
|
||||
{ .name = "remote21net3", .bind_addr = MCTP_ADDR_ANY,
|
||||
.bind_net = MCTP_NET_ANY, .bind_type = 1,
|
||||
.have_peer = true, .peer_addr = 21, .peer_net = 3, },
|
||||
|
||||
/* remote eid 21, net 4 for bind, specific net=4 for connect() */
|
||||
{ .name = "remote21net4", .bind_addr = MCTP_ADDR_ANY,
|
||||
.bind_net = 4, .bind_type = 1,
|
||||
.have_peer = true, .peer_addr = 21, .peer_net = 4, },
|
||||
|
||||
/* remote eid 21, net 5 for bind, specific net=5 for connect() */
|
||||
{ .name = "remote21net5", .bind_addr = MCTP_ADDR_ANY,
|
||||
.bind_net = 5, .bind_type = 1,
|
||||
.have_peer = true, .peer_addr = 21, .peer_net = 5, },
|
||||
};
|
||||
|
||||
static void mctp_bind_lookup_desc(const struct mctp_bind_lookup_test *t,
|
||||
char *desc)
|
||||
{
|
||||
snprintf(desc, KUNIT_PARAM_DESC_SIZE,
|
||||
"{src %d dst %d ty %d net %d expect %s}",
|
||||
t->hdr.src, t->hdr.dest, t->ty, t->net, t->expect);
|
||||
}
|
||||
|
||||
KUNIT_ARRAY_PARAM(mctp_bind_lookup, mctp_bind_lookup_tests,
|
||||
mctp_bind_lookup_desc);
|
||||
|
||||
static void mctp_test_bind_lookup(struct kunit *test)
|
||||
{
|
||||
const struct mctp_bind_lookup_test *rx;
|
||||
struct socket *socks[ARRAY_SIZE(lookup_binds)];
|
||||
struct sk_buff *skb_pkt = NULL, *skb_sock = NULL;
|
||||
struct socket *sock_ty0, *sock_expect = NULL;
|
||||
struct mctp_test_pktqueue tpq;
|
||||
struct mctp_test_dev *dev;
|
||||
struct mctp_dst dst;
|
||||
int rc;
|
||||
|
||||
rx = test->param_value;
|
||||
|
||||
__mctp_route_test_init(test, &dev, &dst, &tpq, &sock_ty0, rx->net);
|
||||
/* Create all binds */
|
||||
for (size_t i = 0; i < ARRAY_SIZE(lookup_binds); i++) {
|
||||
mctp_test_bind_run(test, &lookup_binds[i],
|
||||
&rc, &socks[i]);
|
||||
KUNIT_ASSERT_EQ(test, rc, 0);
|
||||
|
||||
/* Record the expected receive socket */
|
||||
if (rx->expect &&
|
||||
strcmp(rx->expect, lookup_binds[i].name) == 0) {
|
||||
KUNIT_ASSERT_NULL(test, sock_expect);
|
||||
sock_expect = socks[i];
|
||||
}
|
||||
}
|
||||
KUNIT_ASSERT_EQ(test, !!sock_expect, !!rx->expect);
|
||||
|
||||
/* Create test message */
|
||||
skb_pkt = mctp_test_create_skb_data(&rx->hdr, &rx->ty);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb_pkt);
|
||||
mctp_test_skb_set_dev(skb_pkt, dev);
|
||||
mctp_test_pktqueue_init(&tpq);
|
||||
|
||||
rc = mctp_dst_input(&dst, skb_pkt);
|
||||
if (rx->expect) {
|
||||
/* Test the message is received on the expected socket */
|
||||
KUNIT_EXPECT_EQ(test, rc, 0);
|
||||
skb_sock = skb_recv_datagram(sock_expect->sk,
|
||||
MSG_DONTWAIT, &rc);
|
||||
if (!skb_sock) {
|
||||
/* Find which socket received it instead */
|
||||
for (size_t i = 0; i < ARRAY_SIZE(lookup_binds); i++) {
|
||||
skb_sock = skb_recv_datagram(socks[i]->sk,
|
||||
MSG_DONTWAIT, &rc);
|
||||
if (skb_sock) {
|
||||
KUNIT_FAIL(test,
|
||||
"received on incorrect socket '%s', expect '%s'",
|
||||
lookup_binds[i].name,
|
||||
rx->expect);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
KUNIT_FAIL(test, "no message received");
|
||||
}
|
||||
} else {
|
||||
KUNIT_EXPECT_NE(test, rc, 0);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
kfree_skb(skb_sock);
|
||||
kfree_skb(skb_pkt);
|
||||
|
||||
/* Drop all binds */
|
||||
for (size_t i = 0; i < ARRAY_SIZE(lookup_binds); i++)
|
||||
sock_release(socks[i]);
|
||||
|
||||
__mctp_route_test_fini(test, dev, &dst, &tpq, sock_ty0);
|
||||
}
|
||||
|
||||
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),
|
||||
|
@ -1429,6 +1616,7 @@ static struct kunit_case mctp_test_cases[] = {
|
|||
KUNIT_CASE(mctp_test_route_gw_loop),
|
||||
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),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@ struct mctp_test_bind_setup {
|
|||
bool have_peer;
|
||||
mctp_eid_t peer_addr;
|
||||
int peer_net;
|
||||
|
||||
/* optional name. Used for comparison in "lookup" tests */
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct mctp_test_dev *mctp_test_create_dev(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue