1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 4 */ 5 6 #ifdef DEBUG 7 8 #include <linux/jiffies.h> 9 #include <linux/hrtimer.h> 10 11 static const struct { 12 bool result; 13 u64 nsec_to_sleep_before; 14 } expected_results[] __initconst = { 15 [0 ... PACKETS_BURSTABLE - 1] = { true, 0 }, 16 [PACKETS_BURSTABLE] = { false, 0 }, 17 [PACKETS_BURSTABLE + 1] = { true, NSEC_PER_SEC / PACKETS_PER_SECOND }, 18 [PACKETS_BURSTABLE + 2] = { false, 0 }, 19 [PACKETS_BURSTABLE + 3] = { true, (NSEC_PER_SEC / PACKETS_PER_SECOND) * 2 }, 20 [PACKETS_BURSTABLE + 4] = { true, 0 }, 21 [PACKETS_BURSTABLE + 5] = { false, 0 } 22 }; 23 24 static __init unsigned int maximum_jiffies_at_index(int index) 25 { 26 u64 total_nsecs = 2 * NSEC_PER_SEC / PACKETS_PER_SECOND / 3; 27 int i; 28 29 for (i = 0; i <= index; ++i) 30 total_nsecs += expected_results[i].nsec_to_sleep_before; 31 return nsecs_to_jiffies(total_nsecs); 32 } 33 34 static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4, 35 struct sk_buff *skb6, struct ipv6hdr *hdr6, 36 int *test) 37 { 38 unsigned long loop_start_time; 39 int i; 40 41 wg_ratelimiter_gc_entries(NULL); 42 rcu_barrier(); 43 loop_start_time = jiffies; 44 45 for (i = 0; i < ARRAY_SIZE(expected_results); ++i) { 46 if (expected_results[i].nsec_to_sleep_before) { 47 ktime_t timeout = ktime_add(ktime_add_ns(ktime_get_coarse_boottime(), TICK_NSEC * 4 / 3), 48 ns_to_ktime(expected_results[i].nsec_to_sleep_before)); 49 set_current_state(TASK_UNINTERRUPTIBLE); 50 schedule_hrtimeout_range_clock(&timeout, 0, HRTIMER_MODE_ABS, CLOCK_BOOTTIME); 51 } 52 53 if (time_is_before_jiffies(loop_start_time + 54 maximum_jiffies_at_index(i))) 55 return -ETIMEDOUT; 56 if (wg_ratelimiter_allow(skb4, &init_net) != 57 expected_results[i].result) 58 return -EXFULL; 59 ++(*test); 60 61 hdr4->saddr = htonl(ntohl(hdr4->saddr) + i + 1); 62 if (time_is_before_jiffies(loop_start_time + 63 maximum_jiffies_at_index(i))) 64 return -ETIMEDOUT; 65 if (!wg_ratelimiter_allow(skb4, &init_net)) 66 return -EXFULL; 67 ++(*test); 68 69 hdr4->saddr = htonl(ntohl(hdr4->saddr) - i - 1); 70 71 #if IS_ENABLED(CONFIG_IPV6) 72 hdr6->saddr.in6_u.u6_addr32[2] = htonl(i); 73 hdr6->saddr.in6_u.u6_addr32[3] = htonl(i); 74 if (time_is_before_jiffies(loop_start_time + 75 maximum_jiffies_at_index(i))) 76 return -ETIMEDOUT; 77 if (wg_ratelimiter_allow(skb6, &init_net) != 78 expected_results[i].result) 79 return -EXFULL; 80 ++(*test); 81 82 hdr6->saddr.in6_u.u6_addr32[0] = 83 htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) + i + 1); 84 if (time_is_before_jiffies(loop_start_time + 85 maximum_jiffies_at_index(i))) 86 return -ETIMEDOUT; 87 if (!wg_ratelimiter_allow(skb6, &init_net)) 88 return -EXFULL; 89 ++(*test); 90 91 hdr6->saddr.in6_u.u6_addr32[0] = 92 htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) - i - 1); 93 94 if (time_is_before_jiffies(loop_start_time + 95 maximum_jiffies_at_index(i))) 96 return -ETIMEDOUT; 97 #endif 98 } 99 return 0; 100 } 101 102 static __init int capacity_test(struct sk_buff *skb4, struct iphdr *hdr4, 103 int *test) 104 { 105 int i; 106 107 wg_ratelimiter_gc_entries(NULL); 108 rcu_barrier(); 109 110 if (atomic_read(&total_entries)) 111 return -EXFULL; 112 ++(*test); 113 114 for (i = 0; i <= max_entries; ++i) { 115 hdr4->saddr = htonl(i); 116 if (wg_ratelimiter_allow(skb4, &init_net) != (i != max_entries)) 117 return -EXFULL; 118 ++(*test); 119 } 120 return 0; 121 } 122 123 bool __init wg_ratelimiter_selftest(void) 124 { 125 enum { TRIALS_BEFORE_GIVING_UP = 5000 }; 126 bool success = false; 127 int test = 0, trials; 128 struct sk_buff *skb4, *skb6 = NULL; 129 struct iphdr *hdr4; 130 struct ipv6hdr *hdr6 = NULL; 131 132 if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN)) 133 return true; 134 135 BUILD_BUG_ON(NSEC_PER_SEC % PACKETS_PER_SECOND != 0); 136 137 if (wg_ratelimiter_init()) 138 goto out; 139 ++test; 140 if (wg_ratelimiter_init()) { 141 wg_ratelimiter_uninit(); 142 goto out; 143 } 144 ++test; 145 if (wg_ratelimiter_init()) { 146 wg_ratelimiter_uninit(); 147 wg_ratelimiter_uninit(); 148 goto out; 149 } 150 ++test; 151 152 skb4 = alloc_skb(sizeof(struct iphdr), GFP_KERNEL); 153 if (unlikely(!skb4)) 154 goto err_nofree; 155 skb4->protocol = htons(ETH_P_IP); 156 hdr4 = (struct iphdr *)skb_put(skb4, sizeof(*hdr4)); 157 hdr4->saddr = htonl(8182); 158 skb_reset_network_header(skb4); 159 ++test; 160 161 #if IS_ENABLED(CONFIG_IPV6) 162 skb6 = alloc_skb(sizeof(struct ipv6hdr), GFP_KERNEL); 163 if (unlikely(!skb6)) { 164 kfree_skb(skb4); 165 goto err_nofree; 166 } 167 skb6->protocol = htons(ETH_P_IPV6); 168 hdr6 = (struct ipv6hdr *)skb_put(skb6, sizeof(*hdr6)); 169 hdr6->saddr.in6_u.u6_addr32[0] = htonl(1212); 170 hdr6->saddr.in6_u.u6_addr32[1] = htonl(289188); 171 skb_reset_network_header(skb6); 172 ++test; 173 #endif 174 175 for (trials = TRIALS_BEFORE_GIVING_UP;;) { 176 int test_count = 0, ret; 177 178 ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count); 179 if (ret == -ETIMEDOUT) { 180 if (!trials--) { 181 test += test_count; 182 goto err; 183 } 184 continue; 185 } else if (ret < 0) { 186 test += test_count; 187 goto err; 188 } else { 189 test += test_count; 190 break; 191 } 192 } 193 194 for (trials = TRIALS_BEFORE_GIVING_UP;;) { 195 int test_count = 0; 196 197 if (capacity_test(skb4, hdr4, &test_count) < 0) { 198 if (!trials--) { 199 test += test_count; 200 goto err; 201 } 202 continue; 203 } 204 test += test_count; 205 break; 206 } 207 208 success = true; 209 210 err: 211 kfree_skb(skb4); 212 #if IS_ENABLED(CONFIG_IPV6) 213 kfree_skb(skb6); 214 #endif 215 err_nofree: 216 wg_ratelimiter_uninit(); 217 wg_ratelimiter_uninit(); 218 wg_ratelimiter_uninit(); 219 /* Uninit one extra time to check underflow detection. */ 220 wg_ratelimiter_uninit(); 221 out: 222 if (success) 223 pr_info("ratelimiter self-tests: pass\n"); 224 else 225 pr_err("ratelimiter self-test %d: FAIL\n", test); 226 227 return success; 228 } 229 #endif 230