mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
net: mctp: test: Add tests for gateway routes
Add a few kunit tests for the gateway routing. Because we have multiple route types now (direct and gateway), rename mctp_test_create_route to mctp_test_create_route_direct, and add a _gateway variant too. Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au> Link: https://patch.msgid.link/20250702-dev-forwarding-v5-14-1468191da8a4@codeconstruct.com.au Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
ad39c12fce
commit
48e1736e5d
@ -141,7 +141,7 @@ static void mctp_test_rx_input(struct kunit *test)
|
||||
dev = mctp_test_create_dev();
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
rt = mctp_test_create_route(&init_net, dev->mdev, 8, 68);
|
||||
rt = mctp_test_create_route_direct(&init_net, dev->mdev, 8, 68);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt);
|
||||
|
||||
skb = mctp_test_create_skb(¶ms->hdr, 1);
|
||||
@ -1183,6 +1183,233 @@ static void mctp_test_route_extaddr_input(struct kunit *test)
|
||||
mctp_test_destroy_dev(dev);
|
||||
}
|
||||
|
||||
static void mctp_test_route_gw_lookup(struct kunit *test)
|
||||
{
|
||||
struct mctp_test_route *rt1, *rt2;
|
||||
struct mctp_dst dst = { 0 };
|
||||
struct mctp_test_dev *dev;
|
||||
int rc;
|
||||
|
||||
dev = mctp_test_create_dev();
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
/* 8 (local) -> 10 (gateway) via 9 (direct) */
|
||||
rt1 = mctp_test_create_route_direct(&init_net, dev->mdev, 9, 0);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt1);
|
||||
rt2 = mctp_test_create_route_gw(&init_net, dev->mdev->net, 10, 9, 0);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt2);
|
||||
|
||||
rc = mctp_route_lookup(&init_net, dev->mdev->net, 10, &dst);
|
||||
KUNIT_EXPECT_EQ(test, rc, 0);
|
||||
KUNIT_EXPECT_PTR_EQ(test, dst.dev, dev->mdev);
|
||||
KUNIT_EXPECT_EQ(test, dst.mtu, dev->ndev->mtu);
|
||||
KUNIT_EXPECT_EQ(test, dst.nexthop, 9);
|
||||
KUNIT_EXPECT_EQ(test, dst.halen, 0);
|
||||
|
||||
mctp_dst_release(&dst);
|
||||
|
||||
mctp_test_route_destroy(test, rt2);
|
||||
mctp_test_route_destroy(test, rt1);
|
||||
mctp_test_destroy_dev(dev);
|
||||
}
|
||||
|
||||
static void mctp_test_route_gw_loop(struct kunit *test)
|
||||
{
|
||||
struct mctp_test_route *rt1, *rt2;
|
||||
struct mctp_dst dst = { 0 };
|
||||
struct mctp_test_dev *dev;
|
||||
int rc;
|
||||
|
||||
dev = mctp_test_create_dev();
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
/* two routes using each other as the gw */
|
||||
rt1 = mctp_test_create_route_gw(&init_net, dev->mdev->net, 9, 10, 0);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt1);
|
||||
rt2 = mctp_test_create_route_gw(&init_net, dev->mdev->net, 10, 9, 0);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt2);
|
||||
|
||||
/* this should fail, rather than infinite-loop */
|
||||
rc = mctp_route_lookup(&init_net, dev->mdev->net, 10, &dst);
|
||||
KUNIT_EXPECT_NE(test, rc, 0);
|
||||
|
||||
mctp_test_route_destroy(test, rt2);
|
||||
mctp_test_route_destroy(test, rt1);
|
||||
mctp_test_destroy_dev(dev);
|
||||
}
|
||||
|
||||
struct mctp_route_gw_mtu_test {
|
||||
/* working away from the local stack */
|
||||
unsigned int dev, neigh, gw, dst;
|
||||
unsigned int exp;
|
||||
};
|
||||
|
||||
static void mctp_route_gw_mtu_to_desc(const struct mctp_route_gw_mtu_test *t,
|
||||
char *desc)
|
||||
{
|
||||
sprintf(desc, "dev %d, neigh %d, gw %d, dst %d -> %d",
|
||||
t->dev, t->neigh, t->gw, t->dst, t->exp);
|
||||
}
|
||||
|
||||
static const struct mctp_route_gw_mtu_test mctp_route_gw_mtu_tests[] = {
|
||||
/* no route-specific MTUs */
|
||||
{ 68, 0, 0, 0, 68 },
|
||||
{ 100, 0, 0, 0, 100 },
|
||||
/* one route MTU (smaller than dev mtu), others unrestricted */
|
||||
{ 100, 68, 0, 0, 68 },
|
||||
{ 100, 0, 68, 0, 68 },
|
||||
{ 100, 0, 0, 68, 68 },
|
||||
/* smallest applied, regardless of order */
|
||||
{ 100, 99, 98, 68, 68 },
|
||||
{ 99, 100, 98, 68, 68 },
|
||||
{ 98, 99, 100, 68, 68 },
|
||||
{ 68, 98, 99, 100, 68 },
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM(mctp_route_gw_mtu, mctp_route_gw_mtu_tests,
|
||||
mctp_route_gw_mtu_to_desc);
|
||||
|
||||
static void mctp_test_route_gw_mtu(struct kunit *test)
|
||||
{
|
||||
const struct mctp_route_gw_mtu_test *mtus = test->param_value;
|
||||
struct mctp_test_route *rt1, *rt2, *rt3;
|
||||
struct mctp_dst dst = { 0 };
|
||||
struct mctp_test_dev *dev;
|
||||
struct mctp_dev *mdev;
|
||||
unsigned int netid;
|
||||
int rc;
|
||||
|
||||
dev = mctp_test_create_dev();
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
dev->ndev->mtu = mtus->dev;
|
||||
mdev = dev->mdev;
|
||||
netid = mdev->net;
|
||||
|
||||
/* 8 (local) -> 11 (dst) via 10 (gw) via 9 (neigh) */
|
||||
rt1 = mctp_test_create_route_direct(&init_net, mdev, 9, mtus->neigh);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt1);
|
||||
|
||||
rt2 = mctp_test_create_route_gw(&init_net, netid, 10, 9, mtus->gw);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt2);
|
||||
|
||||
rt3 = mctp_test_create_route_gw(&init_net, netid, 11, 10, mtus->dst);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt3);
|
||||
|
||||
rc = mctp_route_lookup(&init_net, dev->mdev->net, 11, &dst);
|
||||
KUNIT_EXPECT_EQ(test, rc, 0);
|
||||
KUNIT_EXPECT_EQ(test, dst.mtu, mtus->exp);
|
||||
|
||||
mctp_dst_release(&dst);
|
||||
|
||||
mctp_test_route_destroy(test, rt3);
|
||||
mctp_test_route_destroy(test, rt2);
|
||||
mctp_test_route_destroy(test, rt1);
|
||||
mctp_test_destroy_dev(dev);
|
||||
}
|
||||
|
||||
#define MCTP_TEST_LLADDR_LEN 2
|
||||
struct mctp_test_llhdr {
|
||||
unsigned int magic;
|
||||
unsigned char src[MCTP_TEST_LLADDR_LEN];
|
||||
unsigned char dst[MCTP_TEST_LLADDR_LEN];
|
||||
};
|
||||
|
||||
static const unsigned int mctp_test_llhdr_magic = 0x5c78339c;
|
||||
|
||||
static int test_dev_header_create(struct sk_buff *skb, struct net_device *dev,
|
||||
unsigned short type, const void *daddr,
|
||||
const void *saddr, unsigned int len)
|
||||
{
|
||||
struct kunit *test = current->kunit_test;
|
||||
struct mctp_test_llhdr *hdr;
|
||||
|
||||
hdr = skb_push(skb, sizeof(*hdr));
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hdr);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
hdr->magic = mctp_test_llhdr_magic;
|
||||
memcpy(&hdr->src, saddr, sizeof(hdr->src));
|
||||
memcpy(&hdr->dst, daddr, sizeof(hdr->dst));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test the dst_output path for a gateway-routed skb: we should have it
|
||||
* lookup the nexthop EID in the neighbour table, and call into
|
||||
* header_ops->create to resolve that to a lladdr. Our mock header_ops->create
|
||||
* will just set a synthetic link-layer header, which we check after transmit.
|
||||
*/
|
||||
static void mctp_test_route_gw_output(struct kunit *test)
|
||||
{
|
||||
const unsigned char haddr_self[MCTP_TEST_LLADDR_LEN] = { 0xaa, 0x03 };
|
||||
const unsigned char haddr_peer[MCTP_TEST_LLADDR_LEN] = { 0xaa, 0x02 };
|
||||
const struct header_ops ops = {
|
||||
.create = test_dev_header_create,
|
||||
};
|
||||
struct mctp_neigh neigh = { 0 };
|
||||
struct mctp_test_llhdr *ll_hdr;
|
||||
struct mctp_dst dst = { 0 };
|
||||
struct mctp_hdr hdr = { 0 };
|
||||
struct mctp_test_dev *dev;
|
||||
struct sk_buff *skb;
|
||||
unsigned char *buf;
|
||||
int i, rc;
|
||||
|
||||
dev = mctp_test_create_dev_lladdr(sizeof(haddr_self), haddr_self);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
dev->ndev->header_ops = &ops;
|
||||
|
||||
dst.dev = dev->mdev;
|
||||
__mctp_dev_get(dst.dev->dev);
|
||||
dst.mtu = 68;
|
||||
dst.nexthop = 9;
|
||||
|
||||
/* simple mctp_neigh_add for the gateway (not dest!) endpoint */
|
||||
INIT_LIST_HEAD(&neigh.list);
|
||||
neigh.dev = dev->mdev;
|
||||
mctp_dev_hold(dev->mdev);
|
||||
neigh.eid = 9;
|
||||
neigh.source = MCTP_NEIGH_STATIC;
|
||||
memcpy(neigh.ha, haddr_peer, sizeof(haddr_peer));
|
||||
list_add_rcu(&neigh.list, &init_net.mctp.neighbours);
|
||||
|
||||
hdr.ver = 1;
|
||||
hdr.src = 8;
|
||||
hdr.dest = 10;
|
||||
hdr.flags_seq_tag = FL_S | FL_E | FL_TO;
|
||||
|
||||
/* construct enough for a future link-layer header, the provided
|
||||
* mctp header, and 4 bytes of data
|
||||
*/
|
||||
skb = alloc_skb(sizeof(*ll_hdr) + sizeof(hdr) + 4, GFP_KERNEL);
|
||||
skb->dev = dev->ndev;
|
||||
__mctp_cb(skb);
|
||||
|
||||
skb_reserve(skb, sizeof(*ll_hdr));
|
||||
|
||||
memcpy(skb_put(skb, sizeof(hdr)), &hdr, sizeof(hdr));
|
||||
buf = skb_put(skb, 4);
|
||||
for (i = 0; i < 4; i++)
|
||||
buf[i] = i;
|
||||
|
||||
/* extra ref over the dev_xmit */
|
||||
skb_get(skb);
|
||||
|
||||
rc = mctp_dst_output(&dst, skb);
|
||||
KUNIT_EXPECT_EQ(test, rc, 0);
|
||||
|
||||
mctp_dst_release(&dst);
|
||||
list_del_rcu(&neigh.list);
|
||||
mctp_dev_put(dev->mdev);
|
||||
|
||||
/* check that we have our header created with the correct neighbour */
|
||||
ll_hdr = (void *)skb_mac_header(skb);
|
||||
KUNIT_EXPECT_EQ(test, ll_hdr->magic, mctp_test_llhdr_magic);
|
||||
KUNIT_EXPECT_MEMEQ(test, ll_hdr->src, haddr_self, sizeof(haddr_self));
|
||||
KUNIT_EXPECT_MEMEQ(test, ll_hdr->dst, haddr_peer, sizeof(haddr_peer));
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
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),
|
||||
@ -1200,6 +1427,10 @@ static struct kunit_case mctp_test_cases[] = {
|
||||
KUNIT_CASE(mctp_test_route_output_key_create),
|
||||
KUNIT_CASE(mctp_test_route_input_cloned_frag),
|
||||
KUNIT_CASE(mctp_test_route_extaddr_input),
|
||||
KUNIT_CASE(mctp_test_route_gw_lookup),
|
||||
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),
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -40,7 +40,7 @@ static void __mctp_sock_test_init(struct kunit *test,
|
||||
|
||||
kfree(addrs);
|
||||
|
||||
rt = mctp_test_create_route(dev_net(dev->ndev), dev->mdev, 9, 0);
|
||||
rt = mctp_test_create_route_direct(dev_net(dev->ndev), dev->mdev, 9, 0);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt);
|
||||
|
||||
rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock);
|
||||
|
@ -119,10 +119,10 @@ static struct mctp_test_route *mctp_route_test_alloc(void)
|
||||
return rt;
|
||||
}
|
||||
|
||||
struct mctp_test_route *mctp_test_create_route(struct net *net,
|
||||
struct mctp_dev *dev,
|
||||
mctp_eid_t eid,
|
||||
unsigned int mtu)
|
||||
struct mctp_test_route *mctp_test_create_route_direct(struct net *net,
|
||||
struct mctp_dev *dev,
|
||||
mctp_eid_t eid,
|
||||
unsigned int mtu)
|
||||
{
|
||||
struct mctp_test_route *rt;
|
||||
|
||||
@ -144,6 +144,31 @@ struct mctp_test_route *mctp_test_create_route(struct net *net,
|
||||
return rt;
|
||||
}
|
||||
|
||||
struct mctp_test_route *mctp_test_create_route_gw(struct net *net,
|
||||
unsigned int netid,
|
||||
mctp_eid_t eid,
|
||||
mctp_eid_t gw,
|
||||
unsigned int mtu)
|
||||
{
|
||||
struct mctp_test_route *rt;
|
||||
|
||||
rt = mctp_route_test_alloc();
|
||||
if (!rt)
|
||||
return NULL;
|
||||
|
||||
rt->rt.min = eid;
|
||||
rt->rt.max = eid;
|
||||
rt->rt.mtu = mtu;
|
||||
rt->rt.type = RTN_UNSPEC;
|
||||
rt->rt.dst_type = MCTP_ROUTE_GATEWAY;
|
||||
rt->rt.gateway.eid = gw;
|
||||
rt->rt.gateway.net = netid;
|
||||
|
||||
list_add_rcu(&rt->rt.list, &net->mctp.routes);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
/* Convenience function for our test dst; release with mctp_test_dst_release()
|
||||
*/
|
||||
void mctp_test_dst_setup(struct kunit *test, struct mctp_dst *dst,
|
||||
|
@ -36,10 +36,15 @@ struct mctp_test_dev *mctp_test_create_dev_lladdr(unsigned short lladdr_len,
|
||||
const unsigned char *lladdr);
|
||||
void mctp_test_destroy_dev(struct mctp_test_dev *dev);
|
||||
|
||||
struct mctp_test_route *mctp_test_create_route(struct net *net,
|
||||
struct mctp_dev *dev,
|
||||
mctp_eid_t eid,
|
||||
unsigned int mtu);
|
||||
struct mctp_test_route *mctp_test_create_route_direct(struct net *net,
|
||||
struct mctp_dev *dev,
|
||||
mctp_eid_t eid,
|
||||
unsigned int mtu);
|
||||
struct mctp_test_route *mctp_test_create_route_gw(struct net *net,
|
||||
unsigned int netid,
|
||||
mctp_eid_t eid,
|
||||
mctp_eid_t gw,
|
||||
unsigned int mtu);
|
||||
void mctp_test_dst_setup(struct kunit *test, struct mctp_dst *dst,
|
||||
struct mctp_test_dev *dev,
|
||||
struct mctp_test_pktqueue *tpq, unsigned int mtu);
|
||||
|
Loading…
Reference in New Issue
Block a user