0001
0002
0003
0004
0005
0006 #ifdef DEBUG
0007
0008 #include <linux/jiffies.h>
0009
0010 static const struct {
0011 bool result;
0012 unsigned int msec_to_sleep_before;
0013 } expected_results[] __initconst = {
0014 [0 ... PACKETS_BURSTABLE - 1] = { true, 0 },
0015 [PACKETS_BURSTABLE] = { false, 0 },
0016 [PACKETS_BURSTABLE + 1] = { true, MSEC_PER_SEC / PACKETS_PER_SECOND },
0017 [PACKETS_BURSTABLE + 2] = { false, 0 },
0018 [PACKETS_BURSTABLE + 3] = { true, (MSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
0019 [PACKETS_BURSTABLE + 4] = { true, 0 },
0020 [PACKETS_BURSTABLE + 5] = { false, 0 }
0021 };
0022
0023 static __init unsigned int maximum_jiffies_at_index(int index)
0024 {
0025 unsigned int total_msecs = 2 * MSEC_PER_SEC / PACKETS_PER_SECOND / 3;
0026 int i;
0027
0028 for (i = 0; i <= index; ++i)
0029 total_msecs += expected_results[i].msec_to_sleep_before;
0030 return msecs_to_jiffies(total_msecs);
0031 }
0032
0033 static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
0034 struct sk_buff *skb6, struct ipv6hdr *hdr6,
0035 int *test)
0036 {
0037 unsigned long loop_start_time;
0038 int i;
0039
0040 wg_ratelimiter_gc_entries(NULL);
0041 rcu_barrier();
0042 loop_start_time = jiffies;
0043
0044 for (i = 0; i < ARRAY_SIZE(expected_results); ++i) {
0045 if (expected_results[i].msec_to_sleep_before)
0046 msleep(expected_results[i].msec_to_sleep_before);
0047
0048 if (time_is_before_jiffies(loop_start_time +
0049 maximum_jiffies_at_index(i)))
0050 return -ETIMEDOUT;
0051 if (wg_ratelimiter_allow(skb4, &init_net) !=
0052 expected_results[i].result)
0053 return -EXFULL;
0054 ++(*test);
0055
0056 hdr4->saddr = htonl(ntohl(hdr4->saddr) + i + 1);
0057 if (time_is_before_jiffies(loop_start_time +
0058 maximum_jiffies_at_index(i)))
0059 return -ETIMEDOUT;
0060 if (!wg_ratelimiter_allow(skb4, &init_net))
0061 return -EXFULL;
0062 ++(*test);
0063
0064 hdr4->saddr = htonl(ntohl(hdr4->saddr) - i - 1);
0065
0066 #if IS_ENABLED(CONFIG_IPV6)
0067 hdr6->saddr.in6_u.u6_addr32[2] = htonl(i);
0068 hdr6->saddr.in6_u.u6_addr32[3] = htonl(i);
0069 if (time_is_before_jiffies(loop_start_time +
0070 maximum_jiffies_at_index(i)))
0071 return -ETIMEDOUT;
0072 if (wg_ratelimiter_allow(skb6, &init_net) !=
0073 expected_results[i].result)
0074 return -EXFULL;
0075 ++(*test);
0076
0077 hdr6->saddr.in6_u.u6_addr32[0] =
0078 htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) + i + 1);
0079 if (time_is_before_jiffies(loop_start_time +
0080 maximum_jiffies_at_index(i)))
0081 return -ETIMEDOUT;
0082 if (!wg_ratelimiter_allow(skb6, &init_net))
0083 return -EXFULL;
0084 ++(*test);
0085
0086 hdr6->saddr.in6_u.u6_addr32[0] =
0087 htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) - i - 1);
0088
0089 if (time_is_before_jiffies(loop_start_time +
0090 maximum_jiffies_at_index(i)))
0091 return -ETIMEDOUT;
0092 #endif
0093 }
0094 return 0;
0095 }
0096
0097 static __init int capacity_test(struct sk_buff *skb4, struct iphdr *hdr4,
0098 int *test)
0099 {
0100 int i;
0101
0102 wg_ratelimiter_gc_entries(NULL);
0103 rcu_barrier();
0104
0105 if (atomic_read(&total_entries))
0106 return -EXFULL;
0107 ++(*test);
0108
0109 for (i = 0; i <= max_entries; ++i) {
0110 hdr4->saddr = htonl(i);
0111 if (wg_ratelimiter_allow(skb4, &init_net) != (i != max_entries))
0112 return -EXFULL;
0113 ++(*test);
0114 }
0115 return 0;
0116 }
0117
0118 bool __init wg_ratelimiter_selftest(void)
0119 {
0120 enum { TRIALS_BEFORE_GIVING_UP = 5000 };
0121 bool success = false;
0122 int test = 0, trials;
0123 struct sk_buff *skb4, *skb6 = NULL;
0124 struct iphdr *hdr4;
0125 struct ipv6hdr *hdr6 = NULL;
0126
0127 if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
0128 return true;
0129
0130 BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0);
0131
0132 if (wg_ratelimiter_init())
0133 goto out;
0134 ++test;
0135 if (wg_ratelimiter_init()) {
0136 wg_ratelimiter_uninit();
0137 goto out;
0138 }
0139 ++test;
0140 if (wg_ratelimiter_init()) {
0141 wg_ratelimiter_uninit();
0142 wg_ratelimiter_uninit();
0143 goto out;
0144 }
0145 ++test;
0146
0147 skb4 = alloc_skb(sizeof(struct iphdr), GFP_KERNEL);
0148 if (unlikely(!skb4))
0149 goto err_nofree;
0150 skb4->protocol = htons(ETH_P_IP);
0151 hdr4 = (struct iphdr *)skb_put(skb4, sizeof(*hdr4));
0152 hdr4->saddr = htonl(8182);
0153 skb_reset_network_header(skb4);
0154 ++test;
0155
0156 #if IS_ENABLED(CONFIG_IPV6)
0157 skb6 = alloc_skb(sizeof(struct ipv6hdr), GFP_KERNEL);
0158 if (unlikely(!skb6)) {
0159 kfree_skb(skb4);
0160 goto err_nofree;
0161 }
0162 skb6->protocol = htons(ETH_P_IPV6);
0163 hdr6 = (struct ipv6hdr *)skb_put(skb6, sizeof(*hdr6));
0164 hdr6->saddr.in6_u.u6_addr32[0] = htonl(1212);
0165 hdr6->saddr.in6_u.u6_addr32[1] = htonl(289188);
0166 skb_reset_network_header(skb6);
0167 ++test;
0168 #endif
0169
0170 for (trials = TRIALS_BEFORE_GIVING_UP; IS_ENABLED(DEBUG_RATELIMITER_TIMINGS);) {
0171 int test_count = 0, ret;
0172
0173 ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count);
0174 if (ret == -ETIMEDOUT) {
0175 if (!trials--) {
0176 test += test_count;
0177 goto err;
0178 }
0179 continue;
0180 } else if (ret < 0) {
0181 test += test_count;
0182 goto err;
0183 } else {
0184 test += test_count;
0185 break;
0186 }
0187 }
0188
0189 for (trials = TRIALS_BEFORE_GIVING_UP;;) {
0190 int test_count = 0;
0191
0192 if (capacity_test(skb4, hdr4, &test_count) < 0) {
0193 if (!trials--) {
0194 test += test_count;
0195 goto err;
0196 }
0197 continue;
0198 }
0199 test += test_count;
0200 break;
0201 }
0202
0203 success = true;
0204
0205 err:
0206 kfree_skb(skb4);
0207 #if IS_ENABLED(CONFIG_IPV6)
0208 kfree_skb(skb6);
0209 #endif
0210 err_nofree:
0211 wg_ratelimiter_uninit();
0212 wg_ratelimiter_uninit();
0213 wg_ratelimiter_uninit();
0214
0215 wg_ratelimiter_uninit();
0216 out:
0217 if (success)
0218 pr_info("ratelimiter self-tests: pass\n");
0219 else
0220 pr_err("ratelimiter self-test %d: FAIL\n", test);
0221
0222 return success;
0223 }
0224 #endif