Commit | Line | Data |
---|---|---|
a8ee9c9b PA |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <kunit/test.h> | |
3 | ||
4 | #include "protocol.h" | |
5 | ||
6 | static struct mptcp_subflow_request_sock *build_req_sock(struct kunit *test) | |
7 | { | |
8 | struct mptcp_subflow_request_sock *req; | |
9 | ||
10 | req = kunit_kzalloc(test, sizeof(struct mptcp_subflow_request_sock), | |
11 | GFP_USER); | |
12 | KUNIT_EXPECT_NOT_ERR_OR_NULL(test, req); | |
13 | mptcp_token_init_request((struct request_sock *)req); | |
ea1300b9 | 14 | sock_net_set((struct sock *)req, &init_net); |
a8ee9c9b PA |
15 | return req; |
16 | } | |
17 | ||
18 | static void mptcp_token_test_req_basic(struct kunit *test) | |
19 | { | |
20 | struct mptcp_subflow_request_sock *req = build_req_sock(test); | |
21 | struct mptcp_sock *null_msk = NULL; | |
22 | ||
23 | KUNIT_ASSERT_EQ(test, 0, | |
24 | mptcp_token_new_request((struct request_sock *)req)); | |
25 | KUNIT_EXPECT_NE(test, 0, (int)req->token); | |
ea1300b9 | 26 | KUNIT_EXPECT_PTR_EQ(test, null_msk, mptcp_token_get_sock(&init_net, req->token)); |
a8ee9c9b PA |
27 | |
28 | /* cleanup */ | |
29 | mptcp_token_destroy_request((struct request_sock *)req); | |
30 | } | |
31 | ||
32 | static struct inet_connection_sock *build_icsk(struct kunit *test) | |
33 | { | |
34 | struct inet_connection_sock *icsk; | |
35 | ||
36 | icsk = kunit_kzalloc(test, sizeof(struct inet_connection_sock), | |
37 | GFP_USER); | |
38 | KUNIT_EXPECT_NOT_ERR_OR_NULL(test, icsk); | |
39 | return icsk; | |
40 | } | |
41 | ||
42 | static struct mptcp_subflow_context *build_ctx(struct kunit *test) | |
43 | { | |
44 | struct mptcp_subflow_context *ctx; | |
45 | ||
46 | ctx = kunit_kzalloc(test, sizeof(struct mptcp_subflow_context), | |
47 | GFP_USER); | |
48 | KUNIT_EXPECT_NOT_ERR_OR_NULL(test, ctx); | |
49 | return ctx; | |
50 | } | |
51 | ||
52 | static struct mptcp_sock *build_msk(struct kunit *test) | |
53 | { | |
54 | struct mptcp_sock *msk; | |
55 | ||
56 | msk = kunit_kzalloc(test, sizeof(struct mptcp_sock), GFP_USER); | |
57 | KUNIT_EXPECT_NOT_ERR_OR_NULL(test, msk); | |
58 | refcount_set(&((struct sock *)msk)->sk_refcnt, 1); | |
ea1300b9 | 59 | sock_net_set((struct sock *)msk, &init_net); |
a8ee9c9b PA |
60 | return msk; |
61 | } | |
62 | ||
63 | static void mptcp_token_test_msk_basic(struct kunit *test) | |
64 | { | |
65 | struct inet_connection_sock *icsk = build_icsk(test); | |
66 | struct mptcp_subflow_context *ctx = build_ctx(test); | |
67 | struct mptcp_sock *msk = build_msk(test); | |
68 | struct mptcp_sock *null_msk = NULL; | |
69 | struct sock *sk; | |
70 | ||
71 | rcu_assign_pointer(icsk->icsk_ulp_data, ctx); | |
72 | ctx->conn = (struct sock *)msk; | |
73 | sk = (struct sock *)msk; | |
74 | ||
75 | KUNIT_ASSERT_EQ(test, 0, | |
76 | mptcp_token_new_connect((struct sock *)icsk)); | |
77 | KUNIT_EXPECT_NE(test, 0, (int)ctx->token); | |
78 | KUNIT_EXPECT_EQ(test, ctx->token, msk->token); | |
ea1300b9 | 79 | KUNIT_EXPECT_PTR_EQ(test, msk, mptcp_token_get_sock(&init_net, ctx->token)); |
a8ee9c9b PA |
80 | KUNIT_EXPECT_EQ(test, 2, (int)refcount_read(&sk->sk_refcnt)); |
81 | ||
82 | mptcp_token_destroy(msk); | |
ea1300b9 | 83 | KUNIT_EXPECT_PTR_EQ(test, null_msk, mptcp_token_get_sock(&init_net, ctx->token)); |
a8ee9c9b PA |
84 | } |
85 | ||
86 | static void mptcp_token_test_accept(struct kunit *test) | |
87 | { | |
88 | struct mptcp_subflow_request_sock *req = build_req_sock(test); | |
89 | struct mptcp_sock *msk = build_msk(test); | |
90 | ||
91 | KUNIT_ASSERT_EQ(test, 0, | |
92 | mptcp_token_new_request((struct request_sock *)req)); | |
93 | msk->token = req->token; | |
94 | mptcp_token_accept(req, msk); | |
ea1300b9 | 95 | KUNIT_EXPECT_PTR_EQ(test, msk, mptcp_token_get_sock(&init_net, msk->token)); |
a8ee9c9b PA |
96 | |
97 | /* this is now a no-op */ | |
98 | mptcp_token_destroy_request((struct request_sock *)req); | |
ea1300b9 | 99 | KUNIT_EXPECT_PTR_EQ(test, msk, mptcp_token_get_sock(&init_net, msk->token)); |
a8ee9c9b PA |
100 | |
101 | /* cleanup */ | |
102 | mptcp_token_destroy(msk); | |
103 | } | |
104 | ||
105 | static void mptcp_token_test_destroyed(struct kunit *test) | |
106 | { | |
107 | struct mptcp_subflow_request_sock *req = build_req_sock(test); | |
108 | struct mptcp_sock *msk = build_msk(test); | |
109 | struct mptcp_sock *null_msk = NULL; | |
110 | struct sock *sk; | |
111 | ||
112 | sk = (struct sock *)msk; | |
113 | ||
114 | KUNIT_ASSERT_EQ(test, 0, | |
115 | mptcp_token_new_request((struct request_sock *)req)); | |
116 | msk->token = req->token; | |
117 | mptcp_token_accept(req, msk); | |
118 | ||
119 | /* simulate race on removal */ | |
120 | refcount_set(&sk->sk_refcnt, 0); | |
ea1300b9 | 121 | KUNIT_EXPECT_PTR_EQ(test, null_msk, mptcp_token_get_sock(&init_net, msk->token)); |
a8ee9c9b PA |
122 | |
123 | /* cleanup */ | |
124 | mptcp_token_destroy(msk); | |
125 | } | |
126 | ||
127 | static struct kunit_case mptcp_token_test_cases[] = { | |
128 | KUNIT_CASE(mptcp_token_test_req_basic), | |
129 | KUNIT_CASE(mptcp_token_test_msk_basic), | |
130 | KUNIT_CASE(mptcp_token_test_accept), | |
131 | KUNIT_CASE(mptcp_token_test_destroyed), | |
132 | {} | |
133 | }; | |
134 | ||
135 | static struct kunit_suite mptcp_token_suite = { | |
136 | .name = "mptcp-token", | |
137 | .test_cases = mptcp_token_test_cases, | |
138 | }; | |
139 | ||
140 | kunit_test_suite(mptcp_token_suite); | |
141 | ||
142 | MODULE_LICENSE("GPL"); |