ControllersTest.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * Copyright 2017 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. * ControllersTest.cpp - unit tests for Controllers.cpp
  17. */
  18. #include <set>
  19. #include <string>
  20. #include <vector>
  21. #include <gmock/gmock.h>
  22. #include <gtest/gtest.h>
  23. #include <android-base/strings.h>
  24. #include "Controllers.h"
  25. #include "IptablesBaseTest.h"
  26. using testing::ContainerEq;
  27. namespace android {
  28. namespace net {
  29. class ControllersTest : public IptablesBaseTest {
  30. public:
  31. ControllersTest() {
  32. Controllers::execIptablesRestore = fakeExecIptablesRestore;
  33. Controllers::execIptablesRestoreWithOutput = fakeExecIptablesRestoreWithOutput;
  34. }
  35. protected:
  36. void initChildChains() { Controllers::initChildChains(); };
  37. std::set<std::string> findExistingChildChains(IptablesTarget a, const char* b, const char*c) {
  38. return Controllers::findExistingChildChains(a, b, c);
  39. }
  40. };
  41. TEST_F(ControllersTest, TestFindExistingChildChains) {
  42. ExpectedIptablesCommands expectedCmds = {
  43. { V6, "*raw\n-S PREROUTING\nCOMMIT\n" },
  44. };
  45. sIptablesRestoreOutput.push_back(
  46. "-P PREROUTING ACCEPT\n"
  47. "-A PREROUTING -j bw_raw_PREROUTING\n"
  48. "-A PREROUTING -j idletimer_raw_PREROUTING\n"
  49. "-A PREROUTING -j tetherctrl_raw_PREROUTING\n"
  50. );
  51. std::set<std::string> expectedChains = {
  52. "bw_raw_PREROUTING",
  53. "idletimer_raw_PREROUTING",
  54. "tetherctrl_raw_PREROUTING",
  55. };
  56. std::set<std::string> actual = findExistingChildChains(V6, "raw", "PREROUTING");
  57. EXPECT_THAT(expectedChains, ContainerEq(actual));
  58. expectIptablesRestoreCommands(expectedCmds);
  59. }
  60. TEST_F(ControllersTest, TestInitIptablesRules) {
  61. // Test what happens when we boot and there are no rules.
  62. ExpectedIptablesCommands expected = {
  63. {V4V6,
  64. "*filter\n"
  65. ":INPUT -\n"
  66. "-F INPUT\n"
  67. ":bw_INPUT -\n"
  68. "-A INPUT -j bw_INPUT\n"
  69. ":fw_INPUT -\n"
  70. "-A INPUT -j fw_INPUT\n"
  71. "COMMIT\n"},
  72. {V4V6,
  73. "*filter\n"
  74. ":FORWARD -\n"
  75. "-F FORWARD\n"
  76. ":oem_fwd -\n"
  77. "-A FORWARD -j oem_fwd\n"
  78. ":fw_FORWARD -\n"
  79. "-A FORWARD -j fw_FORWARD\n"
  80. ":bw_FORWARD -\n"
  81. "-A FORWARD -j bw_FORWARD\n"
  82. ":tetherctrl_FORWARD -\n"
  83. "-A FORWARD -j tetherctrl_FORWARD\n"
  84. "COMMIT\n"},
  85. {V4V6,
  86. "*raw\n"
  87. ":PREROUTING -\n"
  88. "-F PREROUTING\n"
  89. ":clat_raw_PREROUTING -\n"
  90. "-A PREROUTING -j clat_raw_PREROUTING\n"
  91. ":bw_raw_PREROUTING -\n"
  92. "-A PREROUTING -j bw_raw_PREROUTING\n"
  93. ":idletimer_raw_PREROUTING -\n"
  94. "-A PREROUTING -j idletimer_raw_PREROUTING\n"
  95. ":tetherctrl_raw_PREROUTING -\n"
  96. "-A PREROUTING -j tetherctrl_raw_PREROUTING\n"
  97. "COMMIT\n"},
  98. {V4V6,
  99. "*mangle\n"
  100. ":FORWARD -\n"
  101. "-F FORWARD\n"
  102. ":tetherctrl_mangle_FORWARD -\n"
  103. "-A FORWARD -j tetherctrl_mangle_FORWARD\n"
  104. "COMMIT\n"},
  105. {V4V6,
  106. "*mangle\n"
  107. ":INPUT -\n"
  108. "-F INPUT\n"
  109. ":wakeupctrl_mangle_INPUT -\n"
  110. "-A INPUT -j wakeupctrl_mangle_INPUT\n"
  111. ":routectrl_mangle_INPUT -\n"
  112. "-A INPUT -j routectrl_mangle_INPUT\n"
  113. "COMMIT\n"},
  114. {V4,
  115. "*nat\n"
  116. ":PREROUTING -\n"
  117. "-F PREROUTING\n"
  118. ":oem_nat_pre -\n"
  119. "-A PREROUTING -j oem_nat_pre\n"
  120. "COMMIT\n"},
  121. {V4,
  122. "*nat\n"
  123. ":POSTROUTING -\n"
  124. "-F POSTROUTING\n"
  125. ":tetherctrl_nat_POSTROUTING -\n"
  126. "-A POSTROUTING -j tetherctrl_nat_POSTROUTING\n"
  127. "COMMIT\n"},
  128. {V4,
  129. "*filter\n"
  130. "-S OUTPUT\n"
  131. "COMMIT\n"},
  132. {V4,
  133. "*filter\n"
  134. ":oem_out -\n"
  135. "-A OUTPUT -j oem_out\n"
  136. ":fw_OUTPUT -\n"
  137. "-A OUTPUT -j fw_OUTPUT\n"
  138. ":st_OUTPUT -\n"
  139. "-A OUTPUT -j st_OUTPUT\n"
  140. ":bw_OUTPUT -\n"
  141. "-A OUTPUT -j bw_OUTPUT\n"
  142. "COMMIT\n"},
  143. {V6,
  144. "*filter\n"
  145. "-S OUTPUT\n"
  146. "COMMIT\n"},
  147. {V6,
  148. "*filter\n"
  149. ":oem_out -\n"
  150. "-A OUTPUT -j oem_out\n"
  151. ":fw_OUTPUT -\n"
  152. "-A OUTPUT -j fw_OUTPUT\n"
  153. ":st_OUTPUT -\n"
  154. "-A OUTPUT -j st_OUTPUT\n"
  155. ":bw_OUTPUT -\n"
  156. "-A OUTPUT -j bw_OUTPUT\n"
  157. "COMMIT\n"},
  158. {V4,
  159. "*mangle\n"
  160. "-S POSTROUTING\n"
  161. "COMMIT\n"},
  162. {V4,
  163. "*mangle\n"
  164. ":oem_mangle_post -\n"
  165. "-A POSTROUTING -j oem_mangle_post\n"
  166. ":bw_mangle_POSTROUTING -\n"
  167. "-A POSTROUTING -j bw_mangle_POSTROUTING\n"
  168. ":idletimer_mangle_POSTROUTING -\n"
  169. "-A POSTROUTING -j idletimer_mangle_POSTROUTING\n"
  170. "COMMIT\n"},
  171. {V6,
  172. "*mangle\n"
  173. "-S POSTROUTING\n"
  174. "COMMIT\n"},
  175. {V6,
  176. "*mangle\n"
  177. ":oem_mangle_post -\n"
  178. "-A POSTROUTING -j oem_mangle_post\n"
  179. ":bw_mangle_POSTROUTING -\n"
  180. "-A POSTROUTING -j bw_mangle_POSTROUTING\n"
  181. ":idletimer_mangle_POSTROUTING -\n"
  182. "-A POSTROUTING -j idletimer_mangle_POSTROUTING\n"
  183. "COMMIT\n"},
  184. };
  185. // Check that we run these commands and these only.
  186. initChildChains();
  187. expectIptablesRestoreCommands(expected);
  188. expectIptablesRestoreCommands(ExpectedIptablesCommands{});
  189. // Now test what happens when some rules exist (e.g., if we crash and restart).
  190. // First, explicitly tell the iptables test code to return empty output to all the commands we
  191. // send. This allows us to tell it to return non-empty output to particular commands in the
  192. // following code.
  193. for (size_t i = 0; i < expected.size(); i++) {
  194. sIptablesRestoreOutput.push_back("");
  195. }
  196. // Define a macro to remove a substring from a string. We use a macro instead of a function so
  197. // we can assert in it. In the following code, we use ASSERT_* to check for programming errors
  198. // in the test code, and EXPECT_* to check for errors in the actual code.
  199. #define DELETE_SUBSTRING(substr, str) { \
  200. size_t start = (str).find((substr)); \
  201. ASSERT_NE(std::string::npos, start); \
  202. (str).erase(start, strlen((substr))); \
  203. ASSERT_EQ(std::string::npos, (str).find((substr))); \
  204. }
  205. // Now set test expectations.
  206. // 1. Test that if we find rules that we don't create ourselves, we ignore them.
  207. // First check that command #7 is where we list the OUTPUT chain in the (IPv4) filter table:
  208. ASSERT_NE(std::string::npos, expected[7].second.find("*filter\n-S OUTPUT\n"));
  209. // ... and pretend that when we run that command, we find the following rules. Because we don't
  210. // create any of these rules ourselves, our behaviour is unchanged.
  211. sIptablesRestoreOutput[7] =
  212. "-P OUTPUT ACCEPT\n"
  213. "-A OUTPUT -o r_rmnet_data8 -p udp -m udp --dport 1900 -j DROP\n";
  214. // 2. Test that rules that we create ourselves are not added if they already exist.
  215. // Pretend that when we list the OUTPUT chain in the (IPv6) filter table, we find the oem_out
  216. // and st_OUTPUT chains:
  217. ASSERT_NE(std::string::npos, expected[9].second.find("*filter\n-S OUTPUT\n"));
  218. sIptablesRestoreOutput[9] =
  219. "-A OUTPUT -j oem_out\n"
  220. "-A OUTPUT -j st_OUTPUT\n";
  221. // ... and expect that when we populate the OUTPUT chain, we do not re-add them.
  222. DELETE_SUBSTRING("-A OUTPUT -j oem_out\n", expected[10].second);
  223. DELETE_SUBSTRING("-A OUTPUT -j st_OUTPUT\n", expected[10].second);
  224. // 3. Now test that when we list the POSTROUTING chain in the mangle table, we find a mixture of
  225. // netd-created rules and vendor rules:
  226. ASSERT_NE(std::string::npos, expected[13].second.find("*mangle\n-S POSTROUTING\n"));
  227. sIptablesRestoreOutput[13] =
  228. "-P POSTROUTING ACCEPT\n"
  229. "-A POSTROUTING -j oem_mangle_post\n"
  230. "-A POSTROUTING -j bw_mangle_POSTROUTING\n"
  231. "-A POSTROUTING -j idletimer_mangle_POSTROUTING\n"
  232. "-A POSTROUTING -j qcom_qos_reset_POSTROUTING\n"
  233. "-A POSTROUTING -j qcom_qos_filter_POSTROUTING\n";
  234. // and expect that we don't re-add the netd-created rules that already exist.
  235. DELETE_SUBSTRING("-A POSTROUTING -j oem_mangle_post\n", expected[14].second);
  236. DELETE_SUBSTRING("-A POSTROUTING -j bw_mangle_POSTROUTING\n", expected[14].second);
  237. DELETE_SUBSTRING("-A POSTROUTING -j idletimer_mangle_POSTROUTING\n", expected[14].second);
  238. // In this last case, also check that our expectations are reasonable.
  239. std::string expectedCmd14 =
  240. "*mangle\n"
  241. ":oem_mangle_post -\n"
  242. ":bw_mangle_POSTROUTING -\n"
  243. ":idletimer_mangle_POSTROUTING -\n"
  244. "COMMIT\n";
  245. ASSERT_EQ(expectedCmd14, expected[14].second);
  246. // Finally, actually test that initChildChains runs the expected commands, and nothing more.
  247. initChildChains();
  248. expectIptablesRestoreCommands(expected);
  249. expectIptablesRestoreCommands(ExpectedIptablesCommands{});
  250. }
  251. } // namespace net
  252. } // namespace android