18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <kunit/test.h> 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "protocol.h" 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_cistatic struct mptcp_subflow_request_sock *build_req_sock(struct kunit *test) 78c2ecf20Sopenharmony_ci{ 88c2ecf20Sopenharmony_ci struct mptcp_subflow_request_sock *req; 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci req = kunit_kzalloc(test, sizeof(struct mptcp_subflow_request_sock), 118c2ecf20Sopenharmony_ci GFP_USER); 128c2ecf20Sopenharmony_ci KUNIT_EXPECT_NOT_ERR_OR_NULL(test, req); 138c2ecf20Sopenharmony_ci mptcp_token_init_request((struct request_sock *)req); 148c2ecf20Sopenharmony_ci sock_net_set((struct sock *)req, &init_net); 158c2ecf20Sopenharmony_ci return req; 168c2ecf20Sopenharmony_ci} 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistatic void mptcp_token_test_req_basic(struct kunit *test) 198c2ecf20Sopenharmony_ci{ 208c2ecf20Sopenharmony_ci struct mptcp_subflow_request_sock *req = build_req_sock(test); 218c2ecf20Sopenharmony_ci struct mptcp_sock *null_msk = NULL; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci KUNIT_ASSERT_EQ(test, 0, 248c2ecf20Sopenharmony_ci mptcp_token_new_request((struct request_sock *)req)); 258c2ecf20Sopenharmony_ci KUNIT_EXPECT_NE(test, 0, (int)req->token); 268c2ecf20Sopenharmony_ci KUNIT_EXPECT_PTR_EQ(test, null_msk, mptcp_token_get_sock(&init_net, req->token)); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci /* cleanup */ 298c2ecf20Sopenharmony_ci mptcp_token_destroy_request((struct request_sock *)req); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic struct inet_connection_sock *build_icsk(struct kunit *test) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci struct inet_connection_sock *icsk; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci icsk = kunit_kzalloc(test, sizeof(struct inet_connection_sock), 378c2ecf20Sopenharmony_ci GFP_USER); 388c2ecf20Sopenharmony_ci KUNIT_EXPECT_NOT_ERR_OR_NULL(test, icsk); 398c2ecf20Sopenharmony_ci return icsk; 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic struct mptcp_subflow_context *build_ctx(struct kunit *test) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci struct mptcp_subflow_context *ctx; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci ctx = kunit_kzalloc(test, sizeof(struct mptcp_subflow_context), 478c2ecf20Sopenharmony_ci GFP_USER); 488c2ecf20Sopenharmony_ci KUNIT_EXPECT_NOT_ERR_OR_NULL(test, ctx); 498c2ecf20Sopenharmony_ci return ctx; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistatic struct mptcp_sock *build_msk(struct kunit *test) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci struct mptcp_sock *msk; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci msk = kunit_kzalloc(test, sizeof(struct mptcp_sock), GFP_USER); 578c2ecf20Sopenharmony_ci KUNIT_EXPECT_NOT_ERR_OR_NULL(test, msk); 588c2ecf20Sopenharmony_ci refcount_set(&((struct sock *)msk)->sk_refcnt, 1); 598c2ecf20Sopenharmony_ci sock_net_set((struct sock *)msk, &init_net); 608c2ecf20Sopenharmony_ci return msk; 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic void mptcp_token_test_msk_basic(struct kunit *test) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci struct inet_connection_sock *icsk = build_icsk(test); 668c2ecf20Sopenharmony_ci struct mptcp_subflow_context *ctx = build_ctx(test); 678c2ecf20Sopenharmony_ci struct mptcp_sock *msk = build_msk(test); 688c2ecf20Sopenharmony_ci struct mptcp_sock *null_msk = NULL; 698c2ecf20Sopenharmony_ci struct sock *sk; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci rcu_assign_pointer(icsk->icsk_ulp_data, ctx); 728c2ecf20Sopenharmony_ci ctx->conn = (struct sock *)msk; 738c2ecf20Sopenharmony_ci sk = (struct sock *)msk; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci KUNIT_ASSERT_EQ(test, 0, 768c2ecf20Sopenharmony_ci mptcp_token_new_connect((struct sock *)icsk)); 778c2ecf20Sopenharmony_ci KUNIT_EXPECT_NE(test, 0, (int)ctx->token); 788c2ecf20Sopenharmony_ci KUNIT_EXPECT_EQ(test, ctx->token, msk->token); 798c2ecf20Sopenharmony_ci KUNIT_EXPECT_PTR_EQ(test, msk, mptcp_token_get_sock(&init_net, ctx->token)); 808c2ecf20Sopenharmony_ci KUNIT_EXPECT_EQ(test, 2, (int)refcount_read(&sk->sk_refcnt)); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci mptcp_token_destroy(msk); 838c2ecf20Sopenharmony_ci KUNIT_EXPECT_PTR_EQ(test, null_msk, mptcp_token_get_sock(&init_net, ctx->token)); 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic void mptcp_token_test_accept(struct kunit *test) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci struct mptcp_subflow_request_sock *req = build_req_sock(test); 898c2ecf20Sopenharmony_ci struct mptcp_sock *msk = build_msk(test); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci KUNIT_ASSERT_EQ(test, 0, 928c2ecf20Sopenharmony_ci mptcp_token_new_request((struct request_sock *)req)); 938c2ecf20Sopenharmony_ci msk->token = req->token; 948c2ecf20Sopenharmony_ci mptcp_token_accept(req, msk); 958c2ecf20Sopenharmony_ci KUNIT_EXPECT_PTR_EQ(test, msk, mptcp_token_get_sock(&init_net, msk->token)); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci /* this is now a no-op */ 988c2ecf20Sopenharmony_ci mptcp_token_destroy_request((struct request_sock *)req); 998c2ecf20Sopenharmony_ci KUNIT_EXPECT_PTR_EQ(test, msk, mptcp_token_get_sock(&init_net, msk->token)); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci /* cleanup */ 1028c2ecf20Sopenharmony_ci mptcp_token_destroy(msk); 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistatic void mptcp_token_test_destroyed(struct kunit *test) 1068c2ecf20Sopenharmony_ci{ 1078c2ecf20Sopenharmony_ci struct mptcp_subflow_request_sock *req = build_req_sock(test); 1088c2ecf20Sopenharmony_ci struct mptcp_sock *msk = build_msk(test); 1098c2ecf20Sopenharmony_ci struct mptcp_sock *null_msk = NULL; 1108c2ecf20Sopenharmony_ci struct sock *sk; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci sk = (struct sock *)msk; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci KUNIT_ASSERT_EQ(test, 0, 1158c2ecf20Sopenharmony_ci mptcp_token_new_request((struct request_sock *)req)); 1168c2ecf20Sopenharmony_ci msk->token = req->token; 1178c2ecf20Sopenharmony_ci mptcp_token_accept(req, msk); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /* simulate race on removal */ 1208c2ecf20Sopenharmony_ci refcount_set(&sk->sk_refcnt, 0); 1218c2ecf20Sopenharmony_ci KUNIT_EXPECT_PTR_EQ(test, null_msk, mptcp_token_get_sock(&init_net, msk->token)); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci /* cleanup */ 1248c2ecf20Sopenharmony_ci mptcp_token_destroy(msk); 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistatic struct kunit_case mptcp_token_test_cases[] = { 1288c2ecf20Sopenharmony_ci KUNIT_CASE(mptcp_token_test_req_basic), 1298c2ecf20Sopenharmony_ci KUNIT_CASE(mptcp_token_test_msk_basic), 1308c2ecf20Sopenharmony_ci KUNIT_CASE(mptcp_token_test_accept), 1318c2ecf20Sopenharmony_ci KUNIT_CASE(mptcp_token_test_destroyed), 1328c2ecf20Sopenharmony_ci {} 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_cistatic struct kunit_suite mptcp_token_suite = { 1368c2ecf20Sopenharmony_ci .name = "mptcp-token", 1378c2ecf20Sopenharmony_ci .test_cases = mptcp_token_test_cases, 1388c2ecf20Sopenharmony_ci}; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cikunit_test_suite(mptcp_token_suite); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 143