Rather than querying the output device for its address in mctp_local_output, set up the source address when we're populating the dst structure. If no address is assigned, use MCTP_ADDR_NULL. This will allow us more flexibility when routing for NULL-source-eid cases. For now though, we still reject a NULL source address in the output path. We need to update the tests a little, so that addresses are assigned before we do the dst lookups. Signed-off-by: Jeremy Kerr --- include/net/mctp.h | 1 + net/mctp/route.c | 51 +++++++++++++++++++++++++++++----------------- net/mctp/test/route-test.c | 23 +++++++++++---------- net/mctp/test/utils.c | 27 ++++++++++++++++++++++++ net/mctp/test/utils.h | 1 + 5 files changed, 73 insertions(+), 30 deletions(-) diff --git a/include/net/mctp.h b/include/net/mctp.h index c3207ce98f07fcbb436e968d503bc45666794fdc..e1e0a69afdcef7f0924523757010e75ea53e8e7c 100644 --- a/include/net/mctp.h +++ b/include/net/mctp.h @@ -270,6 +270,7 @@ struct mctp_dst { struct mctp_dev *dev; unsigned int mtu; mctp_eid_t nexthop; + mctp_eid_t saddr; /* set for direct addressing */ unsigned char halen; diff --git a/net/mctp/route.c b/net/mctp/route.c index 021e04f1ea7c950af4c4e21d7afbc8c98d093186..f6a88e668e68a8431e58ccc46e7ebb7bf2303f71 100644 --- a/net/mctp/route.c +++ b/net/mctp/route.c @@ -880,6 +880,21 @@ static bool mctp_rt_compare_exact(struct mctp_route *rt1, rt1->max == rt2->max; } +static mctp_eid_t mctp_dev_saddr(struct mctp_dev *dev) +{ + mctp_eid_t addr = MCTP_ADDR_NULL; + unsigned long flags; + + spin_lock_irqsave(&dev->addrs_lock, flags); + if (dev->num_addrs) { + /* use the outbound interface's first address as our source */ + addr = dev->addrs[0]; + } + spin_unlock_irqrestore(&dev->addrs_lock, flags); + + return addr; +} + /* must only be called on a direct route, as the final output hop */ static void mctp_dst_from_route(struct mctp_dst *dst, mctp_eid_t eid, unsigned int mtu, struct mctp_route *route) @@ -892,6 +907,7 @@ static void mctp_dst_from_route(struct mctp_dst *dst, mctp_eid_t eid, dst->mtu = min(dst->mtu, mtu); dst->halen = 0; dst->output = route->output; + dst->saddr = mctp_dev_saddr(route->dev); } int mctp_dst_from_extaddr(struct mctp_dst *dst, struct net *net, int ifindex, @@ -924,6 +940,7 @@ int mctp_dst_from_extaddr(struct mctp_dst *dst, struct net *net, int ifindex, dst->halen = halen; dst->output = mctp_dst_output; dst->nexthop = 0; + dst->saddr = mctp_dev_saddr(dev); memcpy(dst->haddr, haddr, halen); rc = 0; @@ -958,6 +975,7 @@ int mctp_route_lookup(struct net *net, unsigned int dnet, { const unsigned int max_depth = 32; unsigned int depth, mtu = 0; + struct mctp_dst dst_tmp; int rc = -EHOSTUNREACH; rcu_read_lock(); @@ -978,9 +996,15 @@ int mctp_route_lookup(struct net *net, unsigned int dnet, mtu = mtu ?: rt->mtu; if (rt->dst_type == MCTP_ROUTE_DIRECT) { - if (dst) - mctp_dst_from_route(dst, daddr, mtu, rt); - rc = 0; + mctp_dst_from_route(&dst_tmp, daddr, mtu, rt); + /* we need a source address */ + if (dst_tmp.saddr == MCTP_ADDR_NULL) { + mctp_dst_release(&dst_tmp); + } else { + if (dst) + *dst = dst_tmp; + rc = 0; + } break; } else if (rt->dst_type == MCTP_ROUTE_GATEWAY) { @@ -1116,26 +1140,15 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst, struct mctp_sock *msk = container_of(sk, struct mctp_sock, sk); struct mctp_sk_key *key; struct mctp_hdr *hdr; - unsigned long flags; unsigned int netid; - mctp_eid_t saddr; - int rc; + int rc = 0; u8 tag; KUNIT_STATIC_STUB_REDIRECT(mctp_local_output, sk, dst, skb, daddr, req_tag); - rc = -ENODEV; - - spin_lock_irqsave(&dst->dev->addrs_lock, flags); - if (dst->dev->num_addrs == 0) { + if (dst->saddr == MCTP_ADDR_NULL) rc = -EHOSTUNREACH; - } else { - /* use the outbound interface's first address as our source */ - saddr = dst->dev->addrs[0]; - rc = 0; - } - spin_unlock_irqrestore(&dst->dev->addrs_lock, flags); netid = READ_ONCE(dst->dev->net); if (rc) @@ -1146,8 +1159,8 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst, key = mctp_lookup_prealloc_tag(msk, netid, daddr, req_tag, &tag); else - key = mctp_alloc_local_tag(msk, netid, saddr, daddr, - false, &tag); + key = mctp_alloc_local_tag(msk, netid, dst->saddr, + daddr, false, &tag); if (IS_ERR(key)) { rc = PTR_ERR(key); @@ -1174,7 +1187,7 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst, hdr = mctp_hdr(skb); hdr->ver = 1; hdr->dest = daddr; - hdr->src = saddr; + hdr->src = dst->saddr; /* route output functions consume the skb, even on error */ return mctp_do_fragment_route(dst, skb, dst->mtu, tag); diff --git a/net/mctp/test/route-test.c b/net/mctp/test/route-test.c index 61c989c43ec09c9e105de4e51b295d07bb93d6da..639b7c41c2a233fa78f789d0ef25b87a15fb702b 100644 --- a/net/mctp/test/route-test.c +++ b/net/mctp/test/route-test.c @@ -174,7 +174,9 @@ static void mctp_rx_input_test_to_desc(const struct mctp_rx_input_test *t, KUNIT_ARRAY_PARAM(mctp_rx_input, mctp_rx_input_tests, mctp_rx_input_test_to_desc); -/* set up a local dev, route on EID 8, and a socket listening on type 0 */ +/* set up a local dev (with addr 8), route on EID 8, and a socket listening on + * type 0 + */ static void __mctp_route_test_init(struct kunit *test, struct mctp_test_dev **devp, struct mctp_dst *dst, @@ -191,6 +193,10 @@ static void __mctp_route_test_init(struct kunit *test, if (netid != MCTP_NET_ANY) WRITE_ONCE(dev->mdev->net, netid); + dev->mdev->addrs = kmalloc_objs(u8, 1, GFP_KERNEL); + dev->mdev->num_addrs = 1; + dev->mdev->addrs[0] = 8; + mctp_test_dst_setup(test, dst, dev, 68); rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock); @@ -928,11 +934,6 @@ static void mctp_test_flow_init(struct kunit *test, */ __mctp_route_test_init(test, &dev, dst, 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); @@ -1058,8 +1059,6 @@ static void mctp_test_route_output_key_create(struct kunit *test) KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); WRITE_ONCE(dev->mdev->net, netid); - mctp_test_dst_setup(test, &dst, dev, 68); - rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock); KUNIT_ASSERT_EQ(test, rc, 0); @@ -1067,6 +1066,8 @@ static void mctp_test_route_output_key_create(struct kunit *test) dev->mdev->num_addrs = 1; dev->mdev->addrs[0] = src_eid; + mctp_test_dst_setup(test, &dst, dev, 68); + skb = alloc_skb(sizeof(struct mctp_hdr) + 1 + len, GFP_KERNEL); KUNIT_ASSERT_TRUE(test, skb); __mctp_cb(skb); @@ -1165,7 +1166,7 @@ static void mctp_test_route_gw_lookup(struct kunit *test) struct mctp_test_dev *dev; int rc; - dev = mctp_test_create_dev(); + dev = mctp_test_create_dev_with_addr(8); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); /* 8 (local) -> 10 (gateway) via 9 (direct) */ @@ -1195,7 +1196,7 @@ static void mctp_test_route_gw_loop(struct kunit *test) struct mctp_test_dev *dev; int rc; - dev = mctp_test_create_dev(); + dev = mctp_test_create_dev_with_addr(8); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); /* two routes using each other as the gw */ @@ -1254,7 +1255,7 @@ static void mctp_test_route_gw_mtu(struct kunit *test) unsigned int netid; int rc; - dev = mctp_test_create_dev(); + dev = mctp_test_create_dev_with_addr(8); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); dev->ndev->mtu = mtus->dev; mdev = dev->mdev; diff --git a/net/mctp/test/utils.c b/net/mctp/test/utils.c index 97afe8cd2b05c9f047c4a6e8c9fb1b4496183cfe..2f79f8c1a2b44beb4917a9b92ffd72955a3a03c6 100644 --- a/net/mctp/test/utils.c +++ b/net/mctp/test/utils.c @@ -80,6 +80,26 @@ struct mctp_test_dev *mctp_test_create_dev(void) return __mctp_test_create_dev(0, NULL); } +struct mctp_test_dev *mctp_test_create_dev_with_addr(mctp_eid_t addr) +{ + struct mctp_test_dev *dev; + + dev = __mctp_test_create_dev(0, NULL); + if (!dev) + return NULL; + + dev->mdev->addrs = kmalloc_objs(u8, 1, GFP_KERNEL); + if (!dev->mdev->addrs) { + mctp_test_destroy_dev(dev); + return NULL; + } + + dev->mdev->num_addrs = 1; + dev->mdev->addrs[0] = 8; + + return dev; +} + struct mctp_test_dev *mctp_test_create_dev_lladdr(unsigned short lladdr_len, const unsigned char *lladdr) { @@ -171,6 +191,8 @@ struct mctp_test_route *mctp_test_create_route_gw(struct net *net, void mctp_test_dst_setup(struct kunit *test, struct mctp_dst *dst, struct mctp_test_dev *dev, unsigned int mtu) { + unsigned long flags; + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev); memset(dst, 0, sizeof(*dst)); @@ -179,6 +201,11 @@ void mctp_test_dst_setup(struct kunit *test, struct mctp_dst *dst, __mctp_dev_get(dst->dev->dev); dst->mtu = mtu; dst->output = mctp_test_dst_output; + dst->saddr = MCTP_ADDR_NULL; + spin_lock_irqsave(&dev->mdev->addrs_lock, flags); + if (dev->mdev->num_addrs) + dst->saddr = dev->mdev->addrs[0]; + spin_unlock_irqrestore(&dev->mdev->addrs_lock, flags); } void mctp_test_route_destroy(struct kunit *test, struct mctp_test_route *rt) diff --git a/net/mctp/test/utils.h b/net/mctp/test/utils.h index 4cc90c9da4d1bfe9c63b2cac5253f9e09be3b147..47603732e6a570f7bb7e138246071fdbc092f790 100644 --- a/net/mctp/test/utils.h +++ b/net/mctp/test/utils.h @@ -42,6 +42,7 @@ struct mctp_test_bind_setup { }; struct mctp_test_dev *mctp_test_create_dev(void); +struct mctp_test_dev *mctp_test_create_dev_with_addr(mctp_eid_t eid); 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); -- 2.39.5 If we're operating as a non-bus-owner endpoint, we may want to perform MCTP communication to get an address assigned. In this case, we'll have no local addresses, but can TX just fine either with extended routing, or where a direct route exists. Signed-off-by: Jeremy Kerr --- net/mctp/route.c | 18 ++----- net/mctp/test/route-test.c | 114 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 14 deletions(-) diff --git a/net/mctp/route.c b/net/mctp/route.c index f6a88e668e68a8431e58ccc46e7ebb7bf2303f71..8c484776e9e42e246d5e214f5c997281f820a43a 100644 --- a/net/mctp/route.c +++ b/net/mctp/route.c @@ -997,8 +997,8 @@ int mctp_route_lookup(struct net *net, unsigned int dnet, if (rt->dst_type == MCTP_ROUTE_DIRECT) { mctp_dst_from_route(&dst_tmp, daddr, mtu, rt); - /* we need a source address */ - if (dst_tmp.saddr == MCTP_ADDR_NULL) { + /* cannot do gateway-ed routes without a src */ + if (dst_tmp.saddr == MCTP_ADDR_NULL && depth != 0) { mctp_dst_release(&dst_tmp); } else { if (dst) @@ -1141,19 +1141,13 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst, struct mctp_sk_key *key; struct mctp_hdr *hdr; unsigned int netid; - int rc = 0; u8 tag; KUNIT_STATIC_STUB_REDIRECT(mctp_local_output, sk, dst, skb, daddr, req_tag); - if (dst->saddr == MCTP_ADDR_NULL) - rc = -EHOSTUNREACH; netid = READ_ONCE(dst->dev->net); - if (rc) - goto err_free; - if (req_tag & MCTP_TAG_OWNER) { if (req_tag & MCTP_TAG_PREALLOC) key = mctp_lookup_prealloc_tag(msk, netid, daddr, @@ -1163,8 +1157,8 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst, daddr, false, &tag); if (IS_ERR(key)) { - rc = PTR_ERR(key); - goto err_free; + kfree_skb(skb); + return PTR_ERR(key); } mctp_skb_set_flow(skb, key); /* done with the key in this scope */ @@ -1191,10 +1185,6 @@ int mctp_local_output(struct sock *sk, struct mctp_dst *dst, /* route output functions consume the skb, even on error */ return mctp_do_fragment_route(dst, skb, dst->mtu, tag); - -err_free: - kfree_skb(skb); - return rc; } /* route management */ diff --git a/net/mctp/test/route-test.c b/net/mctp/test/route-test.c index 639b7c41c2a233fa78f789d0ef25b87a15fb702b..fa28af9ac18e6605867c475ee7110fbbfd556edb 100644 --- a/net/mctp/test/route-test.c +++ b/net/mctp/test/route-test.c @@ -1570,6 +1570,117 @@ static void mctp_test_bind_lookup(struct kunit *test) __mctp_route_test_fini(test, dev, &dst, sock_ty0); } +static void mctp_test_route_output_direct_no_eids(struct kunit *test) +{ + struct mctp_dst dst = { 0 }; + struct sk_buff *skb, *skb2; + struct mctp_test_route *rt; + struct mctp_test_dev *dev; + struct socket *sock; + const int len = 2; + int rc; + + dev = mctp_test_create_dev(); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + rt = mctp_test_create_route_direct(&init_net, dev->mdev, 9, 68); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt); + + rc = mctp_route_lookup(&init_net, dev->mdev->net, 9, &dst); + KUNIT_ASSERT_EQ(test, rc, 0); + + rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock); + KUNIT_ASSERT_EQ(test, rc, 0); + + 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); + + rc = mctp_local_output(sock->sk, &dst, skb, 9, MCTP_TAG_OWNER); + KUNIT_ASSERT_EQ(test, rc, 0); + + KUNIT_ASSERT_EQ(test, dev->pkts.qlen, 1); + + skb2 = skb_dequeue(&dev->pkts); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb2); + + kfree_skb(skb2); + sock_release(sock); + mctp_dst_release(&dst); + mctp_test_route_destroy(test, rt); + mctp_test_destroy_dev(dev); +} + +static void mctp_test_route_output_gw_no_eids(struct kunit *test) +{ + struct mctp_test_route *rt1, *rt2; + struct mctp_test_dev *dev; + struct mctp_dst dst = { 0 }; + int rc; + + dev = mctp_test_create_dev(); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + /* route: direct to bridge */ + rt1 = mctp_test_create_route_direct(&init_net, dev->mdev, 9, 68); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt1); + + /* route: bridge gw to final dest */ + rt2 = mctp_test_create_route_gw(&init_net, dev->mdev->net, 10, 9, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt2); + + /* route lookup should fail, due to no source address on dev */ + rc = mctp_route_lookup(&init_net, dev->mdev->net, 10, &dst); + KUNIT_ASSERT_NE(test, rc, 0); + + mctp_test_route_destroy(test, rt1); + mctp_test_route_destroy(test, rt2); + mctp_test_destroy_dev(dev); +} + +static void mctp_test_route_output_extaddr_no_eids(struct kunit *test) +{ + struct mctp_dst dst = { 0 }; + struct sk_buff *skb, *skb2; + struct mctp_test_dev *dev; + struct socket *sock; + const int len = 1; + struct net *net; + int rc; + + dev = mctp_test_create_dev(); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + net = dev_net(dev->ndev); + + rc = mctp_dst_from_extaddr(&dst, net, dev->ndev->ifindex, 0, NULL); + KUNIT_ASSERT_EQ(test, rc, 0); + + rc = sock_create_kern(net, AF_MCTP, SOCK_DGRAM, 0, &sock); + KUNIT_ASSERT_EQ(test, rc, 0); + + 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); + + rc = mctp_local_output(sock->sk, &dst, skb, 9, MCTP_TAG_OWNER); + KUNIT_ASSERT_EQ(test, rc, 0); + + KUNIT_ASSERT_EQ(test, dev->pkts.qlen, 1); + + skb2 = skb_dequeue(&dev->pkts); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb2); + + kfree_skb(skb2); + sock_release(sock); + mctp_dst_release(&dst); + 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), @@ -1592,6 +1703,9 @@ static struct kunit_case mctp_test_cases[] = { 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), + KUNIT_CASE(mctp_test_route_output_direct_no_eids), + KUNIT_CASE(mctp_test_route_output_gw_no_eids), + KUNIT_CASE(mctp_test_route_output_extaddr_no_eids), {} }; -- 2.39.5 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 --- net/mctp/route.c | 31 ++++++++++++------------------- net/mctp/test/route-test.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/net/mctp/route.c b/net/mctp/route.c index 8c484776e9e42e246d5e214f5c997281f820a43a..78263e7ae423d5bd92b10920b5c42c5f51a15a75 100644 --- a/net/mctp/route.c +++ b/net/mctp/route.c @@ -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(); + dst->dev = __mctp_dev_get(dev); + rcu_read_unlock(); - 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; - } + if (!dst->dev) + return -EHOSTUNREACH; - rcu_read_unlock(); + dst->mtu = READ_ONCE(dev->mtu); + dst->halen = 0; + dst->output = mctp_dst_input; + dst->nexthop = 0; - return rc; + 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; diff --git a/net/mctp/test/route-test.c b/net/mctp/test/route-test.c index fa28af9ac18e6605867c475ee7110fbbfd556edb..e1033643fab0e2045fef34b42cab87f746761545 100644 --- a/net/mctp/test/route-test.c +++ b/net/mctp/test/route-test.c @@ -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), -- 2.39.5