ratelimiter.c 5.2 KB

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