MCTP core protocol updates, minor fixes & tests
Jeremy Kerr
maintainercover MCTP core protocol updates, minor fixes & tests
This series implements some procotol improvements for AF_MCTP, particularly for systems with multiple MCTP networks defined. For those, we need to add the network ID to the tag lookups, which then suggests an updated version of the tag allocate / drop ioctl to allow the net ID to be specified there too.
The ioctl change affects uabi, so might warrant some extra attention.
There are also a couple of new kunit tests for multiple-net configurations.
We have a fix for populating the flow data when fragmenting, and a testcase for that too.
Of course, any queries/comments/etc., please let me know!
Cheers,
Jeremy
Jeremy Kerr (11):
net: mctp: avoid confusion over local/peer dest/source addresses
net: mctp: Add some detail on the key allocation implementation
net: mctp: make key lookups match the ANY address on either local or
peer
net: mctp: tests: create test skbs with the correct net and device
net: mctp: separate key correlation across nets
net: mctp: provide a more specific tag allocation ioctl
net: mctp: tests: Add netid argument to __mctp_route_test_init
net: mctp: tests: Add MCTP net isolation tests
net: mctp: copy skb ext data when fragmenting
net: mctp: tests: Test that outgoing skbs have flow data populated
net: mctp: tests: Add a test for proper tag creation on local output
include/net/mctp.h | 6 +- include/uapi/linux/mctp.h | 32 +++ net/core/skbuff.c | 8 + net/mctp/af_mctp.c | 117 +++++++++-- net/mctp/route.c | 105 ++++++++-- net/mctp/test/route-test.c | 413 +++++++++++++++++++++++++++++++++++-- net/mctp/test/utils.c | 2 + 7 files changed, 628 insertions(+), 55 deletions(-)
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 1/11 net: mctp: avoid confusion over local/peer dest/source addresses
We have a double-swap of local and peer addresses in mctp_alloc_local_tag; the arguments in both call sites are swapped, but there is also a swap in the implementation of alloc_local_tag. This is opaque because we're using source/dest address references, which don't match the local/peer semantics.
Avoid this confusion by naming the arguments as 'local' and 'peer', and remove the double swap. The calling order now matches mctp_key_alloc.
--- include/net/mctp.h | 4 ++-- net/mctp/af_mctp.c | 2 +- net/mctp/route.c | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-)
include/net/mctp.h +2 -2
@@ -87,7 +87,7 @@ struct mctp_sock { };/* Key for matching incoming packets to sockets or reassembly contexts. -* Packets are matched on (src,dest,tag). +* Packets are matched on (peer EID, local EID, tag). * * Lifetime / locking requirements: *
@@ -255,7 +255,7 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt,void mctp_key_unref (struct mctp_sk_key *key);struct mctp_sk_key *mctp_alloc_local_tag (struct mctp_sock *msk, -mctp_eid_t daddr,mctp_eid_t saddr, +mctp_eid_t local,mctp_eid_t peer,bool manual,u8 *tagp);/* routing <--> device interface */
net/mctp/af_mctp.c +1 -1
@@ -367,7 +367,7 @@ static int mctp_ioctl_alloctag(struct mctp_sock *msk, unsigned long arg)if (ctl.flags)return -EINVAL ; - key =mctp_alloc_local_tag (msk, ctl.peer_addr,MCTP_ADDR_ANY , + key =mctp_alloc_local_tag (msk,MCTP_ADDR_ANY , ctl.peer_addr, true, &tag);if (IS_ERR (key))return PTR_ERR (key);
net/mctp/route.c +8 -8
@@ -596,11 +596,11 @@ static void mctp_reserve_tag(struct net *net, struct mctp_sk_key *key,refcount_inc (&key->refs); } -/* Allocate a locally-owned tag value for (saddr, daddr), and reserve +/* Allocate a locally-owned tag value for (local, peer), and reserve * it for the socket msk */ struct mctp_sk_key *mctp_alloc_local_tag (struct mctp_sock *msk, -mctp_eid_t daddr,mctp_eid_t saddr, +mctp_eid_t local,mctp_eid_t peer,bool manual,u8 *tagp) {struct net *net =sock_net (&msk->sk);
@@ -610,11 +610,11 @@ struct mctp_sk_key *mctp_alloc_local_tag(struct mctp_sock *msk,u8 tagbits;/* for NULL destination EIDs, we may get a response from any peer */ -if (daddr ==MCTP_ADDR_NULL ) - daddr =MCTP_ADDR_ANY ; +if (peer ==MCTP_ADDR_NULL ) + peer =MCTP_ADDR_ANY ;/* be optimistic, alloc now */ - key =mctp_key_alloc (msk, saddr, daddr,0 ,GFP_KERNEL ); + key =mctp_key_alloc (msk, local, peer,0 ,GFP_KERNEL );if (!key)return ERR_PTR (-ENOMEM );
@@ -635,8 +635,8 @@ struct mctp_sk_key *mctp_alloc_local_tag(struct mctp_sock *msk,if (tmp->tag &MCTP_HDR_FLAG_TO )continue ; -if (!(mctp_address_matches (tmp->peer_addr, daddr) && -mctp_address_matches (tmp->local_addr, saddr))) +if (!(mctp_address_matches (tmp->peer_addr, peer) && +mctp_address_matches (tmp->local_addr, local)))continue ;spin_lock (&tmp->lock);
@@ -924,7 +924,7 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt, key =mctp_lookup_prealloc_tag (msk, daddr, req_tag, &tag); else - key =mctp_alloc_local_tag (msk, daddr, saddr, + key =mctp_alloc_local_tag (msk, saddr, daddr, false, &tag);if (IS_ERR (key)) {
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 2/11 net: mctp: Add some detail on the key allocation implementation
In reply to Jeremy KerrWe could do with a little more comment on where MCTP_ADDR_ANY will match in the key allocations.
--- net/mctp/route.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
net/mctp/route.c +37 -0
@@ -73,6 +73,40 @@ static struct mctp_sock *mctp_lookup_bind(struct net *net, struct sk_buff *skb)return NULL ; } +/* A note on the key allocations. +* +* struct net->mctp.keys contains our set of currently-allocated keys for +* MCTP tag management. The lookup tuple for these is the peer EID, +* local EID and MCTP tag. +* +* In some cases, the peer EID may be MCTP_EID_ANY: for example, when a +* broadcast message is sent, we may receive responses from any peer EID. +* Because the broadcast dest address is equivalent to ANY, we create +* a key with (local = local-eid, peer = ANY). This allows a match on the +* incoming broadcast responses from any peer. +* +* We perform lookups when packets are received, and when tags are allocated +* in two scenarios: +* +* - when a packet is sent, with a locally-owned tag: we need to find an +* unused tag value for the (local, peer) EID pair. +* +* - when a tag is manually allocated: we need to find an unused tag value +* for the peer EID, but don't have a specific local EID at that stage. +* +* in the latter case, on successful allocation, we end up with a tag with +* (local = ANY, peer = peer-eid). +* +* So, the key set allows both a local EID of ANY, as well as a peer EID of +* ANY in the lookup tuple. Both may be ANY if we prealloc for a broadcast. +* The matching (in mctp_key_match()) during lookup allows the match value to +* be ANY in either the dest or source addresses. +* +* When allocating (+ inserting) a tag, we need to check for conflicts amongst +* the existing tag set. This requires macthing either exactly on the local +* and peer addresses, or either being ANY. +*/ +static bool mctp_key_match (struct mctp_sk_key *key,mctp_eid_t local,mctp_eid_t peer,u8 tag) {
@@ -368,6 +402,9 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)* key lookup to find the socket, but don't use this * key for reassembly - we'll create a more specific * one for future packets if required (ie, !EOM). +* +* this lookup requires key->peer to be MCTP_ADDR_ANY, +* it doesn't match just any key->peer. */ any_key =mctp_lookup_key (net, skb,MCTP_ADDR_ANY , &f);if (any_key) {
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 3/11 net: mctp: make key lookups match the ANY address on either local or peer
In reply to Jeremy KerrWe may have an ANY address in either the local or peer address of a sk_key, and may want to match on an incoming daddr or saddr being ANY.
Do this by altering the conflicting-tag lookup to also accept ANY as the local/peer address.
We don't want mctp_address_matches to match on the requested EID being ANY, as that is a specific lookup case on packet input.
--- net/mctp/route.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
net/mctp/route.c +11 -3
@@ -113,7 +113,7 @@ static bool mctp_key_match(struct mctp_sk_key *key, mctp_eid_t local,if (!mctp_address_matches (key->local_addr, local))return false; -if (key->peer_addr != peer) +if (!mctp_address_matches (key->peer_addr, peer))return false;if (key->tag != tag)
@@ -672,8 +672,16 @@ struct mctp_sk_key *mctp_alloc_local_tag(struct mctp_sock *msk,if (tmp->tag &MCTP_HDR_FLAG_TO )continue ; -if (!(mctp_address_matches (tmp->peer_addr, peer) && -mctp_address_matches (tmp->local_addr, local))) +/* Since we're avoiding conflicting entries, match peer and +* local addresses, including with a wildcard on ANY. See +* 'A note on key allocations' for background. +*/ +if (peer !=MCTP_ADDR_ANY && + !mctp_address_matches (tmp->peer_addr, peer)) +continue ; + +if (local !=MCTP_ADDR_ANY && + !mctp_address_matches (tmp->local_addr, local))continue ;spin_lock (&tmp->lock);
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 4/11 net: mctp: tests: create test skbs with the correct net and device
In reply to Jeremy KerrIn our test skb creation functions, we're not setting up the net and device data. This doesn't matter at the moment, but we will want to add support for distinct net IDs in future.
Set the ->net identifier on the test MCTP device, and ensure that test skbs are set up with the correct device-related data on creation. Create a helper for setting skb->dev and mctp_skb_cb->net.
We have a few cases where we're calling __mctp_cb() to initialise the cb (which we need for the above) separately, so integrate this into the skb creation helpers.
--- net/mctp/test/route-test.c | 23 +++++++++++++++-------- net/mctp/test/utils.c | 2 ++ 2 files changed, 17 insertions(+), 8 deletions(-)
net/mctp/test/route-test.c +15 -8
@@ -79,6 +79,16 @@ static void mctp_test_route_destroy(struct kunit *test,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) {
@@ -91,6 +101,7 @@ static struct sk_buff *mctp_test_create_skb(const struct mctp_hdr *hdr,if (!skb)return NULL ; +__mctp_cb (skb);memcpy (skb_put (skb, hdr_len), hdr, hdr_len); buf =skb_put (skb, data_len);
@@ -111,6 +122,7 @@ static struct sk_buff *__mctp_test_create_skb_data(const struct mctp_hdr *hdr,if (!skb)return NULL ; +__mctp_cb (skb);memcpy (skb_put (skb, hdr_len), hdr, hdr_len);memcpy (skb_put (skb, data_len), data, data_len);
@@ -249,8 +261,6 @@ static void mctp_test_rx_input(struct kunit *test) skb =mctp_test_create_skb (¶ms->hdr,1 );KUNIT_ASSERT_NOT_ERR_OR_NULL (test, skb); -__mctp_cb (skb); -mctp_pkttype_receive (skb, dev->ndev, &mctp_packet_type,NULL );KUNIT_EXPECT_EQ (test, !!rt->pkts.qlen, params->input);
@@ -344,8 +354,7 @@ static void mctp_test_route_input_sk(struct kunit *test) skb =mctp_test_create_skb_data (¶ms->hdr, ¶ms->type);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, skb); - skb->dev = dev->ndev; -__mctp_cb (skb); +mctp_test_skb_set_dev (skb, dev); rc =mctp_route_input (&rt->rt, skb);
@@ -417,8 +426,7 @@ static void mctp_test_route_input_sk_reasm(struct kunit *test) skb =mctp_test_create_skb_data (¶ms->hdrs[i], &c);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, skb); - skb->dev = dev->ndev; -__mctp_cb (skb); +mctp_test_skb_set_dev (skb, dev); rc =mctp_route_input (&rt->rt, skb); }
@@ -576,8 +584,7 @@ static void mctp_test_route_input_sk_keys(struct kunit *test) skb =mctp_test_create_skb_data (¶ms->hdr, &c);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, skb); - skb->dev = dev->ndev; -__mctp_cb (skb); +mctp_test_skb_set_dev (skb, dev); rc =mctp_route_input (&rt->rt, skb);
net/mctp/test/utils.c +2 -0
@@ -4,6 +4,7 @@#include <linux/mctp.h> #include <linux/if_arp.h> +#include <net/mctp.h> #include <net/mctpdevice.h> #include <net/pkt_sched.h>
@@ -54,6 +55,7 @@ struct mctp_test_dev *mctp_test_create_dev(void)rcu_read_lock (); dev->mdev =__mctp_dev_get (ndev); + dev->mdev->net =mctp_default_net (dev_net (ndev));rcu_read_unlock ();return dev;
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 5/11 net: mctp: separate key correlation across nets
In reply to Jeremy KerrCurrently, we lookup sk_keys from the entire struct net_namespace, which may contain multiple MCTP net IDs. In those cases we want to distinguish between endpoints with the same EID but different net ID.
Add the net ID data to the struct mctp_sk_key, populate on add and filter on this during route lookup.
For the ioctl interface, we use a default net of MCTP_INITIAL_DEFAULT_NET (ie., what will be in use for single-net configurations), but we'll extend the ioctl interface to provide net-specific tag allocation in an upcoming change.
--- include/net/mctp.h | 2 ++ net/mctp/af_mctp.c | 4 ++-- net/mctp/route.c | 43 +++++++++++++++++++++++++++----------- net/mctp/test/route-test.c | 7 +++++-- 4 files changed, 40 insertions(+), 16 deletions(-)
include/net/mctp.h +2 -0
@@ -133,6 +133,7 @@ struct mctp_sock {* - through an expiry timeout, on a per-socket timer */ struct mctp_sk_key { +unsigned int net;mctp_eid_t peer_addr;mctp_eid_t local_addr;/* MCTP_ADDR_ANY for local owned tags */ __u8 tag;/* incoming tag match; invert TO for local */
@@ -255,6 +256,7 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt,void mctp_key_unref (struct mctp_sk_key *key);struct mctp_sk_key *mctp_alloc_local_tag (struct mctp_sock *msk, +unsigned int netid,mctp_eid_t local,mctp_eid_t peer,bool manual,u8 *tagp);
net/mctp/af_mctp.c +2 -2
@@ -367,8 +367,8 @@ static int mctp_ioctl_alloctag(struct mctp_sock *msk, unsigned long arg)if (ctl.flags)return -EINVAL ; - key =mctp_alloc_local_tag (msk,MCTP_ADDR_ANY , ctl.peer_addr, - true, &tag); + key =mctp_alloc_local_tag (msk,MCTP_INITIAL_DEFAULT_NET , +MCTP_ADDR_ANY , ctl.peer_addr, true, &tag);if (IS_ERR (key))return PTR_ERR (key);
net/mctp/route.c +31 -12
160 lines not on this page · raw message
net/mctp/test/route-test.c +5 -2
@@ -552,6 +552,7 @@ static void mctp_test_route_input_sk_keys(struct kunit *test)struct mctp_sock *msk;struct socket *sock;unsigned long flags; +unsigned int net;int rc;u8 c;
@@ -559,6 +560,7 @@ static void mctp_test_route_input_sk_keys(struct kunit *test) dev =mctp_test_create_dev ();KUNIT_ASSERT_NOT_ERR_OR_NULL (test, dev); + net =READ_ONCE (dev->mdev->net); rt =mctp_test_create_route (&init_net, dev->mdev,8 ,68 );KUNIT_ASSERT_NOT_ERR_OR_NULL (test, rt);
@@ -570,8 +572,9 @@ static void mctp_test_route_input_sk_keys(struct kunit *test) mns = &sock_net (sock->sk)->mctp;/* set the incoming tag according to test params */ - key =mctp_key_alloc (msk, params->key_local_addr, params->key_peer_addr, - params->key_tag,GFP_KERNEL ); + key =mctp_key_alloc (msk, net, params->key_local_addr, + params->key_peer_addr, params->key_tag, +GFP_KERNEL );KUNIT_ASSERT_NOT_ERR_OR_NULL (test, key);
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 6/11 net: mctp: provide a more specific tag allocation ioctl
In reply to Jeremy KerrNow that we have net-specific tags, extend the tag allocation ioctls (SIOCMCTPALLOCTAG / SIOCMCTPDROPTAG) to allow a network parameter to be passed to the tag allocation.
We also add a local_addr member to the ioc struct, to allow for a future finer-grained tag allocation using local EIDs too. We don't add any specific support for that now though, so require MCTP_ADDR_ANY or MCTP_ADDR_NULL for those at present.
The old ioctls will still work, but allocate for the default MCTP net. These are now marked as deprecated in the header.
--- include/uapi/linux/mctp.h | 32 +++++++++++ net/mctp/af_mctp.c | 117 +++++++++++++++++++++++++++++++------- 2 files changed, 129 insertions(+), 20 deletions(-)
include/uapi/linux/mctp.h +32 -0
@@ -50,7 +50,14 @@ struct sockaddr_mctp_ext {#define SIOCMCTPALLOCTAG (SIOCPROTOPRIVATE + 0)#define SIOCMCTPDROPTAG (SIOCPROTOPRIVATE + 1) +#define SIOCMCTPALLOCTAG2 (SIOCPROTOPRIVATE + 2) +#define SIOCMCTPDROPTAG2 (SIOCPROTOPRIVATE + 3) +/* Deprecated: use mctp_ioc_tag_ctl2 / TAG2 ioctls instead, which defines the +* MCTP network ID as part of the allocated tag. Using this assumes the default +* net ID for allocated tags, which may not give correct behaviour on system +* with multiple networks configured. +*/ struct mctp_ioc_tag_ctl {mctp_eid_t peer_addr;
@@ -65,4 +72,29 @@ struct mctp_ioc_tag_ctl { __u16 flags; }; +struct mctp_ioc_tag_ctl2 { +/* Peer details: network ID, peer EID, local EID. All set by the +* caller. +* +* Local EID must be MCTP_ADDR_NULL or MCTP_ADDR_ANY in current +* kernels. +*/ +unsigned int net; +mctp_eid_t peer_addr; +mctp_eid_t local_addr; + +/* Set by caller, but no flags defined currently. Must be 0 */ +__u16 flags; + +/* For SIOCMCTPALLOCTAG2: must be passed as zero, kernel will +* populate with the allocated tag value. Returned tag value will +* always have TO and PREALLOC set. +* +* For SIOCMCTPDROPTAG2: userspace provides tag value to drop, from +* a prior SIOCMCTPALLOCTAG2 call (and so must have TO and PREALLOC set). +*/ +__u8 tag; + +}; +#endif /* __UAPI_MCTP_H */
net/mctp/af_mctp.c +97 -20
173 lines not on this page · raw message
Signature · 1 line
2.39.2
Re: [PATCH net-next 06/11] net: mctp: provide a more specific tag allocation ioctl
Hi Jeremy,
kernel test robot noticed the following build warnings:
url: https://github.com/intel-lab-lkp/linux/commits/Jeremy-Kerr/net-mctp-avoid-confusion-over-local-peer-dest-source-addresses/20240216-163203 base: net-next/main patch link: https://lore.kernel.org/r/424009ba3e320ae93eb6bd44ef5e474aa5c9221f.1708071380.git.jk%40codeconstruct.com.au patch subject: [PATCH net-next 06/11] net: mctp: provide a more specific tag allocation ioctl config: parisc-randconfig-r081-20240218 (https://download.01.org/0day-ci/archive/20240218/[email protected]/config) compiler: hppa-linux-gcc (GCC) 13.2.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 <[email protected]> | Reported-by: Dan Carpenter <[email protected]> | Closes: https://lore.kernel.org/r/[email protected]/
smatch warnings:net/mctp/af_mctp.c:389 mctp_ioctl_tag_copy_from_user() warn: was && intended here instead of ||?
vim +389 net/mctp/af_mctp.c
28828bad95a357 Jeremy Kerr 2024-02-16 356 static int mctp_ioctl_tag_copy_from_user(unsigned long arg,
28828bad95a357 Jeremy Kerr 2024-02-16 357 struct mctp_ioc_tag_ctl2 *ctl,
28828bad95a357 Jeremy Kerr 2024-02-16 358 bool tagv2)
28828bad95a357 Jeremy Kerr 2024-02-16 359 {
28828bad95a357 Jeremy Kerr 2024-02-16 360 struct mctp_ioc_tag_ctl ctl_compat;
28828bad95a357 Jeremy Kerr 2024-02-16 361 unsigned long size;
28828bad95a357 Jeremy Kerr 2024-02-16 362 void *ptr;
28828bad95a357 Jeremy Kerr 2024-02-16 363 int rc;
28828bad95a357 Jeremy Kerr 2024-02-16 364
28828bad95a357 Jeremy Kerr 2024-02-16 365 if (tagv2) {
28828bad95a357 Jeremy Kerr 2024-02-16 366 size = sizeof(*ctl);
28828bad95a357 Jeremy Kerr 2024-02-16 367 ptr = ctl;
28828bad95a357 Jeremy Kerr 2024-02-16 368 } else {
28828bad95a357 Jeremy Kerr 2024-02-16 369 size = sizeof(ctl_compat);
28828bad95a357 Jeremy Kerr 2024-02-16 370 ptr = &ctl_compat;
28828bad95a357 Jeremy Kerr 2024-02-16 371 }
28828bad95a357 Jeremy Kerr 2024-02-16 372
28828bad95a357 Jeremy Kerr 2024-02-16 373 rc = copy_from_user(ptr, (void __user *)arg, size);
28828bad95a357 Jeremy Kerr 2024-02-16 374 if (rc)
28828bad95a357 Jeremy Kerr 2024-02-16 375 return -EFAULT;
28828bad95a357 Jeremy Kerr 2024-02-16 376
28828bad95a357 Jeremy Kerr 2024-02-16 377 if (!tagv2) {
28828bad95a357 Jeremy Kerr 2024-02-16 378 /* compat, using defaults for new fields */
28828bad95a357 Jeremy Kerr 2024-02-16 379 ctl->net = MCTP_INITIAL_DEFAULT_NET;
28828bad95a357 Jeremy Kerr 2024-02-16 380 ctl->peer_addr = ctl_compat.peer_addr;
28828bad95a357 Jeremy Kerr 2024-02-16 381 ctl->local_addr = MCTP_ADDR_ANY;
28828bad95a357 Jeremy Kerr 2024-02-16 382 ctl->flags = ctl_compat.flags;
28828bad95a357 Jeremy Kerr 2024-02-16 383 ctl->tag = ctl_compat.tag;
28828bad95a357 Jeremy Kerr 2024-02-16 384 }
28828bad95a357 Jeremy Kerr 2024-02-16 385
28828bad95a357 Jeremy Kerr 2024-02-16 386 if (ctl->flags)
28828bad95a357 Jeremy Kerr 2024-02-16 387 return -EINVAL;
28828bad95a357 Jeremy Kerr 2024-02-16 388
28828bad95a357 Jeremy Kerr 2024-02-16 @389 if (!(ctl->local_addr != MCTP_ADDR_ANY ||
28828bad95a357 Jeremy Kerr 2024-02-16 390 ctl->local_addr != MCTP_ADDR_NULL))
28828bad95a357 Jeremy Kerr 2024-02-16 391 return -EINVAL;Should be &&. This function will always return -EINVAL. I haven't looked at the context outside of this automatically generated email but it suggests a failure in our test process.
28828bad95a357 Jeremy Kerr 2024-02-16 392 28828bad95a357 Jeremy Kerr 2024-02-16 393 return 0; 28828bad95a357 Jeremy Kerr 2024-02-16 394 }
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Jeremy Kerr
maintainerRe: [PATCH net-next 06/11] net: mctp: provide a more specific tag allocation ioctl
Hi Dan,
Quoted 7 lines
28828bad95a357Jeremy Kerr 2024-02-16 @389 if (!(ctl->local_addr !=MCTP_ADDR_ANY||28828bad95a357Jeremy Kerr 2024-02-16 390ctl->local_addr!=MCTP_ADDR_NULL))28828bad95a357Jeremy Kerr 2024-02-16 391 return-EINVAL;Should be &&. This function will always return -EINVAL. I haven't looked at the context outside of this automatically generated email but it suggests a failure in our test process.
Nice catch, thanks.
The issue means it would *never* detect that (not ANY, not NULL) case, rather than always returning -EINVAL; so my ioctl test passed, but we wouldn't have caught the forwards-compatibility check.
Given the potential for confusion here, I'll go with the simpler:
if (ctl->local_addr != MCTP_ADDR_ANY && ctl->local_addr != MCTP_ADDR_NULL) return -EINVAL;
Jakub: I will send a series v2 soon, including those kunit all-tests changes.
Cheers,
Jeremy
Jeremy Kerr
maintainerPATCH 7/11 net: mctp: tests: Add netid argument to __mctp_route_test_init
In reply to Jeremy KerrWe'll want to create net-specific test setups in an upcoming change, so allow the caller to provide a non-default netid.
--- net/mctp/test/route-test.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
net/mctp/test/route-test.c +7 -4
@@ -293,7 +293,8 @@ KUNIT_ARRAY_PARAM(mctp_rx_input, mctp_rx_input_tests,static void __mctp_route_test_init (struct kunit *test,struct mctp_test_dev **devp,struct mctp_test_route **rtp, -struct socket **sockp) +struct socket **sockp, +unsigned int netid) {struct sockaddr_mctp addr = {0 };struct mctp_test_route *rt;
@@ -303,6 +304,8 @@ static void __mctp_route_test_init(struct kunit *test, dev =mctp_test_create_dev ();KUNIT_ASSERT_NOT_ERR_OR_NULL (test, dev); +if (netid !=MCTP_NET_ANY ) +WRITE_ONCE (dev->mdev->net, netid); rt =mctp_test_create_route (&init_net, dev->mdev,8 ,68 );KUNIT_ASSERT_NOT_ERR_OR_NULL (test, rt);
@@ -311,7 +314,7 @@ static void __mctp_route_test_init(struct kunit *test,KUNIT_ASSERT_EQ (test, rc,0 ); addr.smctp_family =AF_MCTP ; - addr.smctp_network =MCTP_NET_ANY ; + addr.smctp_network = netid; addr.smctp_addr.s_addr =8 ; addr.smctp_type =0 ; rc =kernel_bind (sock, (struct sockaddr *)&addr,sizeof (addr));
@@ -349,7 +352,7 @@ static void mctp_test_route_input_sk(struct kunit *test) params = test->param_value; -__mctp_route_test_init (test, &dev, &rt, &sock); +__mctp_route_test_init (test, &dev, &rt, &sock,MCTP_NET_ANY ); skb =mctp_test_create_skb_data (¶ms->hdr, ¶ms->type);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, skb);
@@ -419,7 +422,7 @@ static void mctp_test_route_input_sk_reasm(struct kunit *test) params = test->param_value; -__mctp_route_test_init (test, &dev, &rt, &sock); +__mctp_route_test_init (test, &dev, &rt, &sock,MCTP_NET_ANY );for (i =0 ; i < params->n_hdrs; i++) { c = i;
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 8/11 net: mctp: tests: Add MCTP net isolation tests
In reply to Jeremy KerrAdd a couple of tests that excersise the new net-specific sk_key and bind lookups
--- net/mctp/test/route-test.c | 161 +++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+)
net/mctp/test/route-test.c +161 -0
@@ -678,6 +678,165 @@ static void mctp_route_input_sk_keys_to_desc(KUNIT_ARRAY_PARAM (mctp_route_input_sk_keys, mctp_route_input_sk_keys_tests, mctp_route_input_sk_keys_to_desc); +struct test_net { +unsigned int netid; +struct mctp_test_dev *dev; +struct mctp_test_route *rt; +struct socket *sock; +struct sk_buff *skb; +struct mctp_sk_key *key; +struct { +u8 type; +unsigned int data; + } msg; +}; + +static void +mctp_test_route_input_multiple_nets_bind_init (struct kunit *test, +struct test_net *t) +{ +struct mctp_hdr hdr =RX_HDR (1 ,9 ,8 ,FL_S |FL_E |FL_T (1 ) |FL_TO ); + + t->msg.data = t->netid; + +__mctp_route_test_init (test, &t->dev, &t->rt, &t->sock, t->netid); + + t->skb =mctp_test_create_skb_data (&hdr, &t->msg); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, t->skb); +mctp_test_skb_set_dev (t->skb, t->dev); +} + +static void +mctp_test_route_input_multiple_nets_bind_fini (struct kunit *test, +struct test_net *t) +{ +__mctp_route_test_fini (test, t->dev, t->rt, t->sock); +} + +/* Test that skbs from different nets (otherwise identical) get routed to their +* corresponding socket via the sockets' bind() +*/ +static void mctp_test_route_input_multiple_nets_bind (struct kunit *test) +{ +struct sk_buff *rx_skb1, *rx_skb2; +struct test_net t1, t2; +int rc; + + t1.netid =1 ; + t2.netid =2 ; + + t1.msg.type =0 ; + t2.msg.type =0 ; + +mctp_test_route_input_multiple_nets_bind_init (test, &t1); +mctp_test_route_input_multiple_nets_bind_init (test, &t2); + + rc =mctp_route_input (&t1.rt->rt, t1.skb); +KUNIT_ASSERT_EQ (test, rc,0 ); + rc =mctp_route_input (&t2.rt->rt, t2.skb); +KUNIT_ASSERT_EQ (test, rc,0 ); + + rx_skb1 =skb_recv_datagram (t1.sock->sk,MSG_DONTWAIT , &rc); +KUNIT_EXPECT_NOT_ERR_OR_NULL (test, rx_skb1); +KUNIT_EXPECT_EQ (test, rx_skb1->len,sizeof (t1.msg)); +KUNIT_EXPECT_EQ (test, + *(unsigned int *)skb_pull (rx_skb1,sizeof (t1.msg.data)), + t1.netid); +kfree_skb (rx_skb1); + + rx_skb2 =skb_recv_datagram (t2.sock->sk,MSG_DONTWAIT , &rc); +KUNIT_EXPECT_NOT_ERR_OR_NULL (test, rx_skb2); +KUNIT_EXPECT_EQ (test, rx_skb2->len,sizeof (t2.msg)); +KUNIT_EXPECT_EQ (test, + *(unsigned int *)skb_pull (rx_skb2,sizeof (t2.msg.data)), + t2.netid); +kfree_skb (rx_skb2); + +mctp_test_route_input_multiple_nets_bind_fini (test, &t1); +mctp_test_route_input_multiple_nets_bind_fini (test, &t2); +} + +static void +mctp_test_route_input_multiple_nets_key_init (struct kunit *test, +struct test_net *t) +{ +struct mctp_hdr hdr =RX_HDR (1 ,9 ,8 ,FL_S |FL_E |FL_T (1 )); +struct mctp_sock *msk; +struct netns_mctp *mns; +unsigned long flags; + + t->msg.data = t->netid; + +__mctp_route_test_init (test, &t->dev, &t->rt, &t->sock, t->netid); + + msk = container_of(t->sock->sk, struct mctp_sock, sk); + + t->key =mctp_key_alloc (msk, t->netid, hdr.dest, hdr.src,1 ,GFP_KERNEL ); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, t->key); + + mns = &sock_net (t->sock->sk)->mctp; +spin_lock_irqsave (&mns->keys_lock, flags); +mctp_reserve_tag (&init_net, t->key, msk); +spin_unlock_irqrestore (&mns->keys_lock, flags); + +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, t->key); + t->skb =mctp_test_create_skb_data (&hdr, &t->msg); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, t->skb); +mctp_test_skb_set_dev (t->skb, t->dev); +} + +static void +mctp_test_route_input_multiple_nets_key_fini (struct kunit *test, +struct test_net *t) +{ +mctp_key_unref (t->key); +__mctp_route_test_fini (test, t->dev, t->rt, t->sock); +} + +/* test that skbs from different nets (otherwise identical) get routed to their +* corresponding socket via the sk_key +*/ +static void mctp_test_route_input_multiple_nets_key (struct kunit *test) +{ +struct sk_buff *rx_skb1, *rx_skb2; +struct test_net t1, t2; +int rc; + + t1.netid =1 ; + t2.netid =2 ; + +/* use type 1 which is not bound */ + t1.msg.type =1 ; + t2.msg.type =1 ; + +mctp_test_route_input_multiple_nets_key_init (test, &t1); +mctp_test_route_input_multiple_nets_key_init (test, &t2); + + rc =mctp_route_input (&t1.rt->rt, t1.skb); +KUNIT_ASSERT_EQ (test, rc,0 ); + rc =mctp_route_input (&t2.rt->rt, t2.skb); +KUNIT_ASSERT_EQ (test, rc,0 ); + + rx_skb1 =skb_recv_datagram (t1.sock->sk,MSG_DONTWAIT , &rc); +KUNIT_EXPECT_NOT_ERR_OR_NULL (test, rx_skb1); +KUNIT_EXPECT_EQ (test, rx_skb1->len,sizeof (t1.msg)); +KUNIT_EXPECT_EQ (test, + *(unsigned int *)skb_pull (rx_skb1,sizeof (t1.msg.data)), + t1.netid); +kfree_skb (rx_skb1); + + rx_skb2 =skb_recv_datagram (t2.sock->sk,MSG_DONTWAIT , &rc); +KUNIT_EXPECT_NOT_ERR_OR_NULL (test, rx_skb2); +KUNIT_EXPECT_EQ (test, rx_skb2->len,sizeof (t2.msg)); +KUNIT_EXPECT_EQ (test, + *(unsigned int *)skb_pull (rx_skb2,sizeof (t2.msg.data)), + t2.netid); +kfree_skb (rx_skb2); + +mctp_test_route_input_multiple_nets_key_fini (test, &t1); +mctp_test_route_input_multiple_nets_key_fini (test, &t2); +} +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),
@@ -686,6 +845,8 @@ static struct kunit_case mctp_test_cases[] = { mctp_route_input_sk_reasm_gen_params),KUNIT_CASE_PARAM (mctp_test_route_input_sk_keys, mctp_route_input_sk_keys_gen_params), +KUNIT_CASE (mctp_test_route_input_multiple_nets_bind), + KUNIT_CASE(mctp_test_route_input_multiple_nets_key), {} };
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 9/11 net: mctp: copy skb ext data when fragmenting
In reply to Jeremy KerrIf we're fragmenting on local output, the original packet may contain ext data for the MCTP flows. We'll want this in the resulting fragment skbs too.
So, do a skb_ext_copy() in the fragmentation path, and implement the MCTP-specific parts of an ext copy operation.
--- net/core/skbuff.c | 8 ++++++++ net/mctp/route.c | 3 +++ 2 files changed, 11 insertions(+)
net/core/skbuff.c +8 -0
@@ -6736,6 +6736,14 @@ static struct skb_ext *skb_ext_maybe_cow(struct skb_ext *old,for (i =0 ; i < sp->len; i++) xfrm_state_hold(sp->xvec[i]); } +#endif +#ifdef CONFIG_MCTP_FLOWS +if (old_active & (1 <<SKB_EXT_MCTP )) { +struct mctp_flow *flow =skb_ext_get_ptr (old,SKB_EXT_MCTP ); + +if (flow->key) +refcount_inc (&flow->key->refs); + }#endif __skb_ext_put (old);return new;
net/mctp/route.c +3 -0
@@ -905,6 +905,9 @@ static int mctp_do_fragment_route(struct mctp_route *rt, struct sk_buff *skb,/* copy message payload */ skb_copy_bits (skb, pos,skb_transport_header (skb2), size); +/* we need to copy the extensions, for MCTP flow data */ +skb_ext_copy (skb2, skb); +/* do route */ rc = rt->output (rt, skb2);if (rc)
Signature · 1 line
2.39.2
Jeremy Kerr
maintainerPATCH 10/11 net: mctp: tests: Test that outgoing skbs have flow data populated
In reply to Jeremy KerrWhen CONFIG_MCTP_FLOWS is enabled, outgoing skbs should have their SKB_EXT_MCTP extension set for drivers to consume.
Add two tests for local-to-output routing that check for the flow
extensions: one for the simple single-packet case, and one for fragmentation.
--- net/mctp/test/route-test.c | 136 +++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+)
net/mctp/test/route-test.c +136 -0
@@ -837,6 +837,140 @@ static void mctp_test_route_input_multiple_nets_key(struct kunit *test)mctp_test_route_input_multiple_nets_key_fini (test, &t2); } +#if IS_ENABLED (CONFIG_MCTP_FLOWS ) + +static void mctp_test_flow_init (struct kunit *test, +struct mctp_test_dev **devp, +struct mctp_test_route **rtp, +struct socket **sock, +struct sk_buff **skbp, +unsigned int len) +{ +struct mctp_test_route *rt; +struct mctp_test_dev *dev; +struct sk_buff *skb; + +/* we have a slightly odd routing setup here; the test route +* is for EID 8, which is our local EID. We don't do a routing +* lookup, so that's fine - all we require is a path through +* mctp_local_output, which will call rt->output on whatever +* route we provide +*/ +__mctp_route_test_init (test, &dev, &rt, sock,MCTP_NET_ANY ); + +/* Assign a single EID. ->addrs is freed on mctp netdev release */ + dev->mdev->addrs =kmalloc (sizeof (u8),GFP_KERNEL ); + dev->mdev->num_addrs =1 ; + dev->mdev->addrs[0 ] =8 ; + + skb =alloc_skb (len +sizeof (struct mctp_hdr ) +1 ,GFP_KERNEL ); +KUNIT_ASSERT_TRUE (test, skb); +__mctp_cb (skb); +skb_reserve (skb,sizeof (struct mctp_hdr ) +1 ); +memset (skb_put (skb, len),0 , len); + +/* take a ref for the route, we'll decrement in local output */ +refcount_inc (&rt->rt.refs); + + *devp = dev; + *rtp = rt; + *skbp = skb; +} + +static void mctp_test_flow_fini (struct kunit *test, +struct mctp_test_dev *dev, +struct mctp_test_route *rt, +struct socket *sock) +{ +__mctp_route_test_fini (test, dev, rt, sock); +} + +/* test that an outgoing skb has the correct MCTP extension data set */ +static void mctp_test_packet_flow (struct kunit *test) +{ +struct sk_buff *skb, *skb2; +struct mctp_test_route *rt; +struct mctp_test_dev *dev; +struct mctp_flow *flow; +struct socket *sock; +u8 dst =8 ; +int n, rc; + +mctp_test_flow_init (test, &dev, &rt, &sock, &skb,30 ); + + rc =mctp_local_output (sock->sk, &rt->rt, skb, dst,MCTP_TAG_OWNER ); +KUNIT_ASSERT_EQ (test, rc,0 ); + + n = rt->pkts.qlen; +KUNIT_ASSERT_EQ (test, n,1 ); + + skb2 =skb_dequeue (&rt->pkts); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, skb2); + + flow =skb_ext_find (skb2,SKB_EXT_MCTP ); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, flow); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, flow->key); +KUNIT_ASSERT_PTR_EQ (test, flow->key->sk, sock->sk); + +kfree_skb (skb2); +mctp_test_flow_fini (test, dev, rt, sock); +} + +/* test that outgoing skbs, after fragmentation, all have the correct MCTP +* extension data set. +*/ +static void mctp_test_fragment_flow (struct kunit *test) +{ +struct mctp_flow *flows[2 ]; +struct sk_buff *tx_skbs[2 ]; +struct mctp_test_route *rt; +struct mctp_test_dev *dev; +struct sk_buff *skb; +struct socket *sock; +u8 dst =8 ; +int n, rc; + +mctp_test_flow_init (test, &dev, &rt, &sock, &skb,100 ); + + rc =mctp_local_output (sock->sk, &rt->rt, skb, dst,MCTP_TAG_OWNER ); +KUNIT_ASSERT_EQ (test, rc,0 ); + + n = rt->pkts.qlen; +KUNIT_ASSERT_EQ (test, n,2 ); + +/* both resulting packets should have the same flow data */ + tx_skbs[0 ] =skb_dequeue (&rt->pkts); + tx_skbs[1 ] =skb_dequeue (&rt->pkts); + +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, tx_skbs[0 ]); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, tx_skbs[1 ]); + + flows[0 ] =skb_ext_find (tx_skbs[0 ],SKB_EXT_MCTP ); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, flows[0 ]); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, flows[0 ]->key); +KUNIT_ASSERT_PTR_EQ (test, flows[0 ]->key->sk, sock->sk); + + flows[1 ] =skb_ext_find (tx_skbs[1 ],SKB_EXT_MCTP ); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, flows[1 ]); +KUNIT_ASSERT_PTR_EQ (test, flows[1 ]->key, flows[0 ]->key); + +kfree_skb (tx_skbs[0 ]); +kfree_skb (tx_skbs[1 ]); +mctp_test_flow_fini (test, dev, rt, sock); +} + +#else +static void mctp_test_packet_flow (struct kunit *test) +{ +kunit_skip (test,"Requires CONFIG_MCTP_FLOWS=y" ); +} + +static void mctp_test_fragment_flow (struct kunit *test) +{ +kunit_skip (test,"Requires CONFIG_MCTP_FLOWS=y" ); +} +#endif +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),
@@ -847,6 +981,8 @@ static struct kunit_case mctp_test_cases[] = { mctp_route_input_sk_keys_gen_params),KUNIT_CASE (mctp_test_route_input_multiple_nets_bind),KUNIT_CASE (mctp_test_route_input_multiple_nets_key), +KUNIT_CASE (mctp_test_packet_flow), + KUNIT_CASE(mctp_test_fragment_flow), {} };
Signature · 1 line
2.39.2
Jakub Kicinski
maintainerRe: [PATCH net-next 10/11] net: mctp: tests: Test that outgoing skbs have flow data populated
net/mctp/test/route-test.c static void mctp_test_route_input_multiple_nets_key(struct kunit *test) · line 971
Quoted 9 lines · On Fri, 16 Feb 2024 16:19:20 +0800 Jeremy Kerr wrote:
net/mctp/test/route-test.c +9
-0+static void mctp_test_packet_flow (struct kunit *test) +{ +kunit_skip (test,"Requires CONFIG_MCTP_FLOWS=y" ); +} + +static void mctp_test_fragment_flow (struct kunit *test) +{ +kunit_skip (test,"Requires CONFIG_MCTP_FLOWS=y" ); +}
These two get skipped when running:
./tools/testing/kunit/kunit.py run --alltests
Is it possible to make all-test include the right config option automatically, so they can run?
Jeremy Kerr
maintainerRe: [PATCH net-next 10/11] net: mctp: tests: Test that outgoing skbs have flow data populated
Hi Jakub,
Quoted 12 lines
net/mctp/test/route-test.c static void mctp_test_route_input_multiple_nets_key(struct kunit *test) · line 971
Quoted 9 lines
net/mctp/test/route-test.c +9
-0+static void mctp_test_packet_flow (struct kunit *test) +{ + kunit_skip(test, "Requires CONFIG_MCTP_FLOWS=y"); +} + +static void mctp_test_fragment_flow (struct kunit *test) +{ + kunit_skip(test, "Requires CONFIG_MCTP_FLOWS=y"); +}These two get skipped when running:
Quoted 4 lines
./tools/testing/kunit/kunit.pyrun --alltestsIs it possible to make all-test include the right config option automatically, so they can run?
Sure! I assume that's just a matter of adding to all_tests.config, and getting the dependencies sorted. I will send an update shortly.
Would you prefer a v2 of the series, or just that one patch?
Cheers,
Jeremy
Jeremy Kerr
maintainerPATCH 11/11 net: mctp: tests: Add a test for proper tag creation on local output
In reply to Jeremy KerrEnsure we have the correct key parameters on sending a message.
--- net/mctp/test/route-test.c | 75 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
net/mctp/test/route-test.c +75 -0
@@ -971,6 +971,80 @@ static void mctp_test_fragment_flow(struct kunit *test) }#endif +/* Test that outgoing skbs cause a suitable tag to be created */ +static void mctp_test_route_output_key_create (struct kunit *test) +{ +const unsigned int netid =50 ; +const u8 dst =26 , src =15 ; +struct mctp_test_route *rt; +struct mctp_test_dev *dev; +struct mctp_sk_key *key; +struct netns_mctp *mns; +unsigned long flags; +struct socket *sock; +struct sk_buff *skb; +bool empty, single; +const int len =2 ; +int rc; + + dev =mctp_test_create_dev (); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, dev); +WRITE_ONCE (dev->mdev->net, netid); + + rt =mctp_test_create_route (&init_net, dev->mdev, dst,68 ); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, rt); + + rc =sock_create_kern (&init_net,AF_MCTP ,SOCK_DGRAM ,0 , &sock); +KUNIT_ASSERT_EQ (test, rc,0 ); + + dev->mdev->addrs =kmalloc (sizeof (u8),GFP_KERNEL ); + dev->mdev->num_addrs =1 ; + dev->mdev->addrs[0 ] = src; + + skb =alloc_skb (sizeof (struct mctp_hdr ) +1 + len,GFP_KERNEL ); +KUNIT_ASSERT_TRUE (test, skb); +__mctp_cb (skb); +skb_reserve (skb,sizeof (struct mctp_hdr ) +1 + len); +memset (skb_put (skb, len),0 , len); + +refcount_inc (&rt->rt.refs); + + mns = &sock_net (sock->sk)->mctp; + +/* We assume we're starting from an empty keys list, which requires +* preceding tests to clean up correctly! +*/ +spin_lock_irqsave (&mns->keys_lock, flags); + empty =hlist_empty (&mns->keys); +spin_unlock_irqrestore (&mns->keys_lock, flags); +KUNIT_ASSERT_TRUE (test, empty); + + rc =mctp_local_output (sock->sk, &rt->rt, skb, dst,MCTP_TAG_OWNER ); +KUNIT_ASSERT_EQ (test, rc,0 ); + + key =NULL ; + single = false; +spin_lock_irqsave (&mns->keys_lock, flags); +if (!hlist_empty (&mns->keys)) { + key = hlist_entry(mns->keys.first, struct mctp_sk_key, hlist); + single =hlist_is_singular_node (&key->hlist, &mns->keys); + } +spin_unlock_irqrestore (&mns->keys_lock, flags); + +KUNIT_ASSERT_NOT_NULL (test, key); +KUNIT_ASSERT_TRUE (test, single); + +KUNIT_EXPECT_EQ (test, key->net, netid); +KUNIT_EXPECT_EQ (test, key->local_addr, src); +KUNIT_EXPECT_EQ (test, key->peer_addr, dst); +/* key has incoming tag, so inverse of what we sent */ +KUNIT_EXPECT_FALSE (test, key->tag &MCTP_TAG_OWNER ); + +sock_release (sock); +mctp_test_route_destroy (test, rt); +mctp_test_destroy_dev (dev); +} +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),
@@ -983,6 +1057,7 @@ static struct kunit_case mctp_test_cases[] = {KUNIT_CASE (mctp_test_route_input_multiple_nets_key),KUNIT_CASE (mctp_test_packet_flow),KUNIT_CASE (mctp_test_fragment_flow), + KUNIT_CASE(mctp_test_route_output_key_create), {} };
Signature · 1 line
2.39.2