// SPDX-License-Identifier: GPL-2.0
#include <kunit/test.h>
#include "utils.h"
struct mctp_test_route {
struct mctp_route rt;
struct sk_buff_head pkts;
};
static int mctp_test_route_output(struct mctp_route *rt, struct sk_buff *skb)
{
struct mctp_test_route *test_rt = container_of(rt, struct mctp_test_route, rt);
skb_queue_tail(&test_rt->pkts, skb);
return 0;
}
/* local version of mctp_route_alloc() */
static struct mctp_test_route *mctp_route_test_alloc(void)
{
struct mctp_test_route *rt;
rt = kzalloc(sizeof(*rt), GFP_KERNEL);
if (!rt)
return NULL;
INIT_LIST_HEAD(&rt->rt.list);
refcount_set(&rt->rt.refs, 1);
rt->rt.output = mctp_test_route_output;
skb_queue_head_init(&rt->pkts);
return rt;
}
static 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 *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;
if (dev)
mctp_dev_hold(dev);
rt->rt.dev = dev;
list_add_rcu(&rt->rt.list, &net->mctp.routes);
return rt;
}
static void mctp_test_route_destroy(struct kunit *test,
struct mctp_test_route *rt)
{
unsigned int refs;
rtnl_lock();
list_del_rcu(&rt->rt.list);
rtnl_unlock();
skb_queue_purge(&rt->pkts);
if (rt->rt.dev)
mctp_dev_put(rt->rt.dev);
refs = refcount_read(&rt->rt.refs);
KUNIT_ASSERT_EQ_MSG(test, refs, 1, "route ref imbalance");
kfree_rcu(&rt->rt, rcu);
}
static void mctp_test_skb_set_dev(struct sk_buff *skb,
struct mctp_test_dev *dev)
{
struct mctp_skb_cb *cb;
cb = mctp_cb(skb);
cb->net = READ_ONCE(dev->mdev->net);
skb->dev = dev->ndev;
}
static struct sk_buff *mctp_test_create_skb(const struct mctp_hdr *hdr,
unsigned int data_len)
{
size_t hdr_len = sizeof(*hdr);
struct sk_buff *skb;
unsigned int i;
u8 *buf;
skb = alloc_skb(hdr_len + data_len, GFP_KERNEL);
if (!skb)
return NULL;
__mctp_cb(skb);
memcpy(skb_put(skb, hdr_len), hdr,