blob: 933465476902403685c825d4bb478cac7d5d2baf [file] [log] [blame]
naoyatezuka02db5c12023-08-23 01:46:111// Copyright 2023 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "patchpanel/clat_service.h"
6
7#include <optional>
8#include <string>
9#include <vector>
10
Jie Jiange970cc22024-06-12 07:03:1011#include <chromeos/net-base/ip_address_utils.h>
12#include <chromeos/net-base/ipv4_address.h>
13#include <chromeos/net-base/ipv6_address.h>
14#include <chromeos/net-base/mock_process_manager.h>
15#include <chromeos/net-base/process_manager.h>
16#include <chromeos/net-base/technology.h>
naoyatezuka02db5c12023-08-23 01:46:1117#include <gmock/gmock.h>
18#include <gtest/gtest.h>
naoyatezuka02db5c12023-08-23 01:46:1119
naoyatezukaca02c502023-09-05 06:53:4320#include "patchpanel/datapath.h"
Chih-Yu Huang3ac56852024-07-16 09:19:2821#include "patchpanel/fake_process_runner.h"
naoyatezukac8ebb462023-09-21 10:52:3322#include "patchpanel/iptables.h"
naoyatezukaca02c502023-09-05 06:53:4323#include "patchpanel/mock_datapath.h"
Jie Jiang3fd49e72024-09-13 13:23:5124#include "patchpanel/mock_system.h"
naoyatezuka02db5c12023-08-23 01:46:1125#include "patchpanel/shill_client.h"
naoyatezukaca02c502023-09-05 06:53:4326#include "patchpanel/system.h"
naoyatezuka02db5c12023-08-23 01:46:1127
28using testing::_;
naoyatezukaca02c502023-09-05 06:53:4329using testing::Eq;
naoyatezuka02db5c12023-08-23 01:46:1130using testing::Exactly;
31using testing::Invoke;
naoyatezukaca02c502023-09-05 06:53:4332using testing::IsEmpty;
Hugo Benichi55004b42025-01-27 15:34:0633using testing::Mock;
Jie Jiang4db85572024-09-13 14:04:4334using testing::NiceMock;
naoyatezukaca02c502023-09-05 06:53:4335using testing::Return;
36using testing::StrEq;
naoyatezuka02db5c12023-08-23 01:46:1137
38namespace patchpanel {
39namespace {
40
41MATCHER_P(ShillDeviceHasInterfaceName, expected_ifname, "") {
42 return arg.ifname == expected_ifname;
43}
44
naoyatezukaca02c502023-09-05 06:53:4345MATCHER_P(CIDRHasPrefix, expected_prefix_str, "") {
46 return net_base::IPv6CIDR::CreateFromCIDRString(expected_prefix_str)
47 ->InSameSubnetWith(arg.address());
48}
49
50MATCHER_P(AddressHasPrefix, expected_prefix_str, "") {
51 return net_base::IPv6CIDR::CreateFromCIDRString(expected_prefix_str)
52 ->InSameSubnetWith(arg);
53}
54
naoyatezuka02db5c12023-08-23 01:46:1155class ClatServiceUnderTest : public ClatService {
56 public:
naoyatezukaca02c502023-09-05 06:53:4357 ClatServiceUnderTest(Datapath* datapath,
Chih-Yu Huangf4449c22023-12-13 06:31:1658 net_base::ProcessManager* process_manager,
naoyatezukaca02c502023-09-05 06:53:4359 System* system)
60 : ClatService(datapath, process_manager, system) {
naoyatezuka02db5c12023-08-23 01:46:1161 ON_CALL(*this, StartClat(_))
62 .WillByDefault(
63 (Invoke(this, &ClatServiceUnderTest::SetClatRunningDeviceForTest)));
naoyatezuka6e778df2023-09-01 00:44:0064 ON_CALL(*this, StopClat(true))
naoyatezuka02db5c12023-08-23 01:46:1165 .WillByDefault(
66 Invoke(this, &ClatServiceUnderTest::ResetClatRunningDeviceForTest));
naoyatezuka6e778df2023-09-01 00:44:0067 Enable();
naoyatezuka02db5c12023-08-23 01:46:1168 }
69
70 MOCK_METHOD(void,
71 StartClat,
72 (const ShillClient::Device& shill_device),
73 (override));
74
naoyatezuka6e778df2023-09-01 00:44:0075 MOCK_METHOD(void, StopClat, (bool clear_running_device), (override));
naoyatezuka02db5c12023-08-23 01:46:1176};
77
78constexpr char kIPv4CIDR[] = "10.10.0.2/16";
79constexpr char kIPv6CIDR[] = "2001:db8::1/64";
80
81ShillClient::Device MakeFakeShillDevice(const std::string& ifname,
82 int ifindex) {
83 ShillClient::Device dev;
Chih-Yu Huang8194a032024-04-22 06:35:5584 dev.technology = net_base::Technology::kEthernet;
naoyatezuka02db5c12023-08-23 01:46:1185 dev.ifindex = ifindex;
86 dev.ifname = ifname;
87
88 return dev;
89}
90
91ShillClient::Device MakeFakeIPv4OnlyShillDevice(
92 const std::string& ifname,
93 int ifindex = 1,
94 const char ipv4_cidr[] = kIPv4CIDR) {
95 ShillClient::Device dev = MakeFakeShillDevice(ifname, ifindex);
Taoyu Li110deb42024-08-21 08:51:2896 dev.network_config.ipv4_address =
97 net_base::IPv4CIDR::CreateFromCIDRString(ipv4_cidr);
naoyatezuka02db5c12023-08-23 01:46:1198
99 return dev;
100}
101
102ShillClient::Device MakeFakeIPv6OnlyShillDevice(
103 const std::string& ifname,
104 int ifindex = 1,
Hugo Benichi55004b42025-01-27 15:34:06105 const char ipv6_cidr[] = kIPv6CIDR,
106 std::optional<net_base::IPv6CIDR> pref64 = std::nullopt) {
naoyatezuka02db5c12023-08-23 01:46:11107 ShillClient::Device dev = MakeFakeShillDevice(ifname, ifindex);
Taoyu Li110deb42024-08-21 08:51:28108 dev.network_config.ipv6_addresses = {
109 *net_base::IPv6CIDR::CreateFromCIDRString(ipv6_cidr)};
Hugo Benichi55004b42025-01-27 15:34:06110 dev.network_config.pref64 = pref64;
naoyatezuka02db5c12023-08-23 01:46:11111 return dev;
112}
113
114ShillClient::Device MakeFakeDualStackShillDevice(
115 const std::string& ifname,
116 int ifindex = 1,
117 const char ipv4_cidr[] = kIPv4CIDR,
118 const char ipv6_cidr[] = kIPv6CIDR) {
119 ShillClient::Device dev = MakeFakeShillDevice(ifname, ifindex);
Taoyu Li110deb42024-08-21 08:51:28120 dev.network_config.ipv4_address =
121 net_base::IPv4CIDR::CreateFromCIDRString(ipv4_cidr);
122 dev.network_config.ipv6_addresses = {
123 *net_base::IPv6CIDR::CreateFromCIDRString(ipv6_cidr)};
naoyatezuka02db5c12023-08-23 01:46:11124
125 return dev;
naoyatezuka02db5c12023-08-23 01:46:11126} // namespace
127
naoyatezukaca02c502023-09-05 06:53:43128class ClatServiceTest : public ::testing::Test {
129 protected:
Chih-Yu Huang3ac56852024-07-16 09:19:28130 ClatServiceTest()
131 : datapath_(&process_runner_, &system_),
132 target_(&datapath_, &process_manager_, &system_) {}
Chih-Yu Huanga9c929c2024-07-22 04:48:20133
Chih-Yu Huang3ac56852024-07-16 09:19:28134 FakeProcessRunner process_runner_;
Jie Jiang4db85572024-09-13 14:04:43135 NiceMock<MockSystem> system_;
136 NiceMock<MockDatapath> datapath_;
137 NiceMock<net_base::MockProcessManager> process_manager_;
Chih-Yu Huanga9c929c2024-07-22 04:48:20138 ClatServiceUnderTest target_;
naoyatezukaca02c502023-09-05 06:53:43139};
140
naoyatezuka02db5c12023-08-23 01:46:11141// TODO(b/278970851): Merge tests for OnShillDefaultLogicalDeviceChanged into a
142// single test with a testcase data array.
naoyatezukaca02c502023-09-05 06:53:43143TEST_F(ClatServiceTest, ChangeFromIPv4DeviceToIPv6OnlyDevice) {
naoyatezuka02db5c12023-08-23 01:46:11144 const auto v4only_dev = MakeFakeIPv4OnlyShillDevice("v4only", 1);
145 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 2);
146
Chih-Yu Huanga9c929c2024-07-22 04:48:20147 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("v6only")));
148 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, &v4only_dev);
naoyatezuka02db5c12023-08-23 01:46:11149}
150
naoyatezukaca02c502023-09-05 06:53:43151TEST_F(ClatServiceTest, ChangeFromIPv6OnlyDeviceToIPv4Device) {
naoyatezuka02db5c12023-08-23 01:46:11152 const auto v4only_dev = MakeFakeIPv4OnlyShillDevice("v4only", 1);
153 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 2);
154
naoyatezukaca02c502023-09-05 06:53:43155 // Start CLAT on the new_device.
Chih-Yu Huanga9c929c2024-07-22 04:48:20156 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11157
Chih-Yu Huanga9c929c2024-07-22 04:48:20158 EXPECT_CALL(target_, StopClat(true));
159 target_.OnShillDefaultLogicalDeviceChanged(&v4only_dev, &v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11160}
161
naoyatezukaca02c502023-09-05 06:53:43162TEST_F(ClatServiceTest, ChangeFromIPv6OnlyDeviceToAnother) {
naoyatezuka02db5c12023-08-23 01:46:11163 const auto new_v6only_dev =
164 MakeFakeIPv6OnlyShillDevice("new_v6only", 1, "1020:db8::1/64");
165 const auto prev_v6only_dev =
166 MakeFakeIPv6OnlyShillDevice("prev_v6only", 1, "2001:db8::2/64");
167
naoyatezukaca02c502023-09-05 06:53:43168 // Start CLAT on the new_device.
Chih-Yu Huanga9c929c2024-07-22 04:48:20169 target_.OnShillDefaultLogicalDeviceChanged(&prev_v6only_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11170
Chih-Yu Huanga9c929c2024-07-22 04:48:20171 EXPECT_CALL(target_, StopClat(true));
172 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("new_v6only")));
naoyatezuka02db5c12023-08-23 01:46:11173
Chih-Yu Huanga9c929c2024-07-22 04:48:20174 target_.OnShillDefaultLogicalDeviceChanged(&new_v6only_dev, &prev_v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11175}
176
naoyatezukaca02c502023-09-05 06:53:43177TEST_F(ClatServiceTest, ChangeFromDualStackDeviceToIPv4OnlyDevice) {
naoyatezuka02db5c12023-08-23 01:46:11178 const auto dual_dev = MakeFakeDualStackShillDevice("dual_dev", 1);
179 const auto v4only_dev = MakeFakeIPv4OnlyShillDevice("v4only", 2);
180
Chih-Yu Huanga9c929c2024-07-22 04:48:20181 target_.OnShillDefaultLogicalDeviceChanged(&dual_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11182
Chih-Yu Huanga9c929c2024-07-22 04:48:20183 EXPECT_CALL(target_, StopClat(_)).Times(Exactly(0));
184 EXPECT_CALL(target_, StartClat(_)).Times(Exactly(0));
185 target_.OnShillDefaultLogicalDeviceChanged(&v4only_dev, &dual_dev);
naoyatezuka02db5c12023-08-23 01:46:11186}
187
naoyatezukaca02c502023-09-05 06:53:43188TEST_F(ClatServiceTest, ChangeFromIPv4OnlyDeviceToDualStackDevice) {
naoyatezuka02db5c12023-08-23 01:46:11189 const auto dual_dev = MakeFakeDualStackShillDevice("dual_dev", 1);
190 const auto v4only_dev = MakeFakeIPv4OnlyShillDevice("v4only", 2);
191
Chih-Yu Huanga9c929c2024-07-22 04:48:20192 target_.OnShillDefaultLogicalDeviceChanged(&v4only_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11193
Chih-Yu Huanga9c929c2024-07-22 04:48:20194 EXPECT_CALL(target_, StopClat(_)).Times(Exactly(0));
195 EXPECT_CALL(target_, StartClat(_)).Times(Exactly(0));
196 target_.OnShillDefaultLogicalDeviceChanged(&dual_dev, &v4only_dev);
naoyatezuka02db5c12023-08-23 01:46:11197}
198
naoyatezukaca02c502023-09-05 06:53:43199TEST_F(ClatServiceTest, ChangeFromDualStackDeviceToIPv6OnlyDevice) {
naoyatezuka02db5c12023-08-23 01:46:11200 const auto dual_dev = MakeFakeDualStackShillDevice("dual_dev", 1);
201 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 2);
202
Chih-Yu Huanga9c929c2024-07-22 04:48:20203 target_.OnShillDefaultLogicalDeviceChanged(&dual_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11204
Chih-Yu Huanga9c929c2024-07-22 04:48:20205 EXPECT_CALL(target_, StopClat(_)).Times(Exactly(0));
206 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("v6only")));
207 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, &dual_dev);
naoyatezuka02db5c12023-08-23 01:46:11208}
209
naoyatezukaca02c502023-09-05 06:53:43210TEST_F(ClatServiceTest, ChangeFromIPv6OnlyDeviceToDualStackDevice) {
naoyatezuka02db5c12023-08-23 01:46:11211 const auto dual_dev = MakeFakeDualStackShillDevice("dual_dev", 1);
212 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 2);
213
Chih-Yu Huanga9c929c2024-07-22 04:48:20214 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11215
Chih-Yu Huanga9c929c2024-07-22 04:48:20216 EXPECT_CALL(target_, StopClat(true));
217 EXPECT_CALL(target_, StartClat(_)).Times(Exactly(0));
218 target_.OnShillDefaultLogicalDeviceChanged(&dual_dev, &v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11219}
220
naoyatezukaca02c502023-09-05 06:53:43221TEST_F(ClatServiceTest, ChangeFromDualStackDeviceToAnother) {
naoyatezuka02db5c12023-08-23 01:46:11222 const auto new_v6only_dev = MakeFakeDualStackShillDevice(
223 "new_dual_dev", 1, "10.10.0.2/24", "1020:db8::1/64");
224
225 const auto prev_v6only_dev = MakeFakeDualStackShillDevice(
226 "prev_dual_dev", 2, "10.20.0.2/24", "2001:db8::1/64");
227
Chih-Yu Huanga9c929c2024-07-22 04:48:20228 target_.OnShillDefaultLogicalDeviceChanged(&prev_v6only_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11229
Chih-Yu Huanga9c929c2024-07-22 04:48:20230 EXPECT_CALL(target_, StopClat(_)).Times(Exactly(0));
231 EXPECT_CALL(target_, StartClat(_)).Times(Exactly(0));
232 target_.OnShillDefaultLogicalDeviceChanged(&new_v6only_dev, &prev_v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11233}
234
naoyatezukaca02c502023-09-05 06:53:43235TEST_F(ClatServiceTest, ChangeFromNonExstingDeviceToExistingDevice) {
naoyatezuka02db5c12023-08-23 01:46:11236 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only");
237
Chih-Yu Huanga9c929c2024-07-22 04:48:20238 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("v6only")));
239 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11240}
241
naoyatezukaca02c502023-09-05 06:53:43242TEST_F(ClatServiceTest, ChangeFromExstingDeviceToNonExistingDevice) {
naoyatezuka02db5c12023-08-23 01:46:11243 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only");
244
naoyatezukaca02c502023-09-05 06:53:43245 // Start CLAT on the new_device.
Chih-Yu Huanga9c929c2024-07-22 04:48:20246 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11247
Chih-Yu Huanga9c929c2024-07-22 04:48:20248 EXPECT_CALL(target_, StopClat(true));
249 EXPECT_CALL(target_, StartClat(_)).Times(Exactly(0));
250 target_.OnShillDefaultLogicalDeviceChanged(nullptr, &v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11251}
252
naoyatezukaca02c502023-09-05 06:53:43253TEST_F(ClatServiceTest,
254 DefaultDeviceChangeWhileClatIsRunningOnDifferentDevice) {
naoyatezuka02db5c12023-08-23 01:46:11255 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 1);
256 const auto prev_v6only_dev =
257 MakeFakeIPv6OnlyShillDevice("new_v6only", 2, "1020:db8::1/64");
258 const auto new_v6only_dev =
259 MakeFakeIPv6OnlyShillDevice("prev_v6only", 3, "1030:db8::1/64");
260
naoyatezukaca02c502023-09-05 06:53:43261 // Start CLAT on device "v6only_dev1".
Chih-Yu Huanga9c929c2024-07-22 04:48:20262 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
naoyatezuka02db5c12023-08-23 01:46:11263
264 // Unexpectedly the default logical device changes from an device different
265 // from v6only_dev1 to another.
Chih-Yu Huanga9c929c2024-07-22 04:48:20266 EXPECT_CALL(target_, StopClat(true));
267 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("new_v6only")));
268 target_.OnShillDefaultLogicalDeviceChanged(&prev_v6only_dev,
269 &prev_v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11270}
271
naoyatezukaca02c502023-09-05 06:53:43272TEST_F(ClatServiceTest, NewDefaultDeviceIsTheSameWithClatDevice) {
naoyatezuka02db5c12023-08-23 01:46:11273 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 1);
274 const auto dual_dev = MakeFakeDualStackShillDevice("dual", 2);
275
Hugo Benichi55004b42025-01-27 15:34:06276 EXPECT_CALL(target_, StartClat);
Chih-Yu Huanga9c929c2024-07-22 04:48:20277 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
Hugo Benichi55004b42025-01-27 15:34:06278 Mock::VerifyAndClearExpectations(&target_);
naoyatezuka02db5c12023-08-23 01:46:11279
Hugo Benichi55004b42025-01-27 15:34:06280 EXPECT_CALL(target_, StopClat).Times(Exactly(0));
281 EXPECT_CALL(target_, StartClat).Times(Exactly(0));
Chih-Yu Huanga9c929c2024-07-22 04:48:20282 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, &dual_dev);
naoyatezuka02db5c12023-08-23 01:46:11283}
284
Hugo Benichi55004b42025-01-27 15:34:06285TEST_F(ClatServiceTest, DefaultDeviceChangeToDefaultNAT64Prefix) {
286 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 1);
287 auto v6only_dev2 = MakeFakeIPv6OnlyShillDevice(
288 "v6only", 1, kIPv6CIDR,
289 net_base::IPv6CIDR::CreateFromCIDRString("64:ff9b::/96"));
290
291 EXPECT_CALL(target_, StartClat);
292 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
293 Mock::VerifyAndClearExpectations(&target_);
294
295 EXPECT_CALL(target_, StopClat).Times(0);
296 EXPECT_CALL(target_, StartClat).Times(0);
297 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev2, &v6only_dev);
298}
299
300TEST_F(ClatServiceTest, DefaultDeviceLosesDefaultNAT64Prefix) {
301 auto v6only_dev = MakeFakeIPv6OnlyShillDevice(
302 "v6only", 1, kIPv6CIDR,
303 net_base::IPv6CIDR::CreateFromCIDRString("64:ff9b::/96"));
304 const auto v6only_dev2 = MakeFakeIPv6OnlyShillDevice("v6only", 1);
305
306 EXPECT_CALL(target_, StartClat);
307 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
308 Mock::VerifyAndClearExpectations(&target_);
309
310 EXPECT_CALL(target_, StopClat).Times(0);
311 EXPECT_CALL(target_, StartClat).Times(0);
312 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev2, &v6only_dev);
313}
314
315TEST_F(ClatServiceTest, DefaultDeviceChangeToNonDefaultNAT64Prefix) {
316 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 1);
317 auto v6only_dev2 = MakeFakeIPv6OnlyShillDevice(
318 "v6only", 1, kIPv6CIDR,
319 net_base::IPv6CIDR::CreateFromCIDRString("2001:db8::/32"));
320
321 EXPECT_CALL(target_, StartClat);
322 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
323 Mock::VerifyAndClearExpectations(&target_);
324
325 EXPECT_CALL(target_, StopClat);
326 EXPECT_CALL(target_, StartClat);
327 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev2, &v6only_dev);
328}
329
330TEST_F(ClatServiceTest, DefaultDeviceLosesNonDefaultNAT64Prefix) {
331 auto v6only_dev = MakeFakeIPv6OnlyShillDevice(
332 "v6only", 1, kIPv6CIDR,
333 net_base::IPv6CIDR::CreateFromCIDRString("2001:db8::/32"));
334 const auto v6only_dev2 = MakeFakeIPv6OnlyShillDevice("v6only", 1);
335
336 EXPECT_CALL(target_, StartClat);
337 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
338 Mock::VerifyAndClearExpectations(&target_);
339
340 EXPECT_CALL(target_, StopClat);
341 EXPECT_CALL(target_, StartClat);
342 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev2, &v6only_dev);
343}
344
345TEST_F(ClatServiceTest, DefaultDeviceNAT64PrefixChange) {
346 auto v6only_dev = MakeFakeIPv6OnlyShillDevice(
347 "v6only", 1, kIPv6CIDR,
348 net_base::IPv6CIDR::CreateFromCIDRString("2001:db8:1::/48"));
349 auto v6only_dev2 = MakeFakeIPv6OnlyShillDevice(
350 "v6only", 1, kIPv6CIDR,
351 net_base::IPv6CIDR::CreateFromCIDRString("2001:db8:2::/48"));
352
353 EXPECT_CALL(target_, StartClat);
354 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
355 Mock::VerifyAndClearExpectations(&target_);
356
357 EXPECT_CALL(target_, StopClat);
358 EXPECT_CALL(target_, StartClat);
359 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev2, &v6only_dev);
360}
361
naoyatezukaca02c502023-09-05 06:53:43362TEST_F(ClatServiceTest,
363 ChangeFromDualStackDeviceToIPv6OnlyDeviceWhileDisabled) {
naoyatezuka6e778df2023-09-01 00:44:00364 const auto dual_dev = MakeFakeDualStackShillDevice("dual", 1);
365 const auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 2);
366
Chih-Yu Huanga9c929c2024-07-22 04:48:20367 target_.OnShillDefaultLogicalDeviceChanged(&dual_dev, nullptr);
naoyatezuka6e778df2023-09-01 00:44:00368
Chih-Yu Huanga9c929c2024-07-22 04:48:20369 EXPECT_CALL(target_, StopClat(false));
370 target_.Disable();
naoyatezuka6e778df2023-09-01 00:44:00371
Chih-Yu Huanga9c929c2024-07-22 04:48:20372 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("v6only")));
373 target_.OnShillDefaultLogicalDeviceChanged(&v6only_dev, &dual_dev);
naoyatezuka6e778df2023-09-01 00:44:00374
375 // The default logical device is IPv6-only, so CLAT starts immdiately after
376 // it's enabled.
Chih-Yu Huanga9c929c2024-07-22 04:48:20377 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("v6only")));
378 target_.Enable();
naoyatezuka6e778df2023-09-01 00:44:00379}
380
naoyatezukaca02c502023-09-05 06:53:43381TEST_F(ClatServiceTest, IPv6OnlyDeviceGetIPv4Address) {
naoyatezuka02db5c12023-08-23 01:46:11382 auto default_logical_device = MakeFakeIPv6OnlyShillDevice("v6only");
383
Chih-Yu Huanga9c929c2024-07-22 04:48:20384 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("v6only")));
385 target_.OnDefaultLogicalDeviceIPConfigChanged(default_logical_device);
naoyatezuka02db5c12023-08-23 01:46:11386
387 // The default logical device gets IPv4 address because of IPConfig changes.
Taoyu Li110deb42024-08-21 08:51:28388 default_logical_device.network_config.ipv4_address =
naoyatezuka02db5c12023-08-23 01:46:11389 net_base::IPv4CIDR::CreateFromCIDRString(kIPv4CIDR);
390
Chih-Yu Huanga9c929c2024-07-22 04:48:20391 EXPECT_CALL(target_, StopClat(true));
392 target_.OnDefaultLogicalDeviceIPConfigChanged(default_logical_device);
naoyatezuka02db5c12023-08-23 01:46:11393}
394
naoyatezukaca02c502023-09-05 06:53:43395TEST_F(ClatServiceTest, DeviceLoseIPv4Address) {
naoyatezuka02db5c12023-08-23 01:46:11396 auto default_logical_device = MakeFakeDualStackShillDevice("dual_stack", 1);
397
naoyatezuka02db5c12023-08-23 01:46:11398 // The default logical device loses IPv4 address because of IPConfig changes.
Taoyu Li110deb42024-08-21 08:51:28399 default_logical_device.network_config.ipv4_address.reset();
naoyatezuka02db5c12023-08-23 01:46:11400
Chih-Yu Huanga9c929c2024-07-22 04:48:20401 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("dual_stack")));
402 target_.OnDefaultLogicalDeviceIPConfigChanged(default_logical_device);
naoyatezuka02db5c12023-08-23 01:46:11403}
404
naoyatezukaca02c502023-09-05 06:53:43405TEST_F(ClatServiceTest, IPConfigChangeWithoutIPv6AddressChange) {
naoyatezuka02db5c12023-08-23 01:46:11406 auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only");
Taoyu Li110deb42024-08-21 08:51:28407 v6only_dev.network_config.dns_servers = {
408 *net_base::IPAddress::CreateFromString("8.8.8.8")};
naoyatezuka02db5c12023-08-23 01:46:11409
Chih-Yu Huanga9c929c2024-07-22 04:48:20410 target_.OnDefaultLogicalDeviceIPConfigChanged(v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11411
Taoyu Li110deb42024-08-21 08:51:28412 v6only_dev.network_config.dns_servers = {
413 *net_base::IPAddress::CreateFromString("1.1.1.1")};
naoyatezuka02db5c12023-08-23 01:46:11414
415 // This change has nothing with CLAT.
Chih-Yu Huanga9c929c2024-07-22 04:48:20416 EXPECT_CALL(target_, StopClat(_)).Times(Exactly(0));
417 EXPECT_CALL(target_, StartClat(_)).Times(Exactly(0));
418 target_.OnDefaultLogicalDeviceIPConfigChanged(v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11419}
420
naoyatezukaca02c502023-09-05 06:53:43421TEST_F(ClatServiceTest, IPv6AddressChangeInTheSamePrefix) {
naoyatezuka02db5c12023-08-23 01:46:11422 auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 1, "2001:db8::1/64");
423
Chih-Yu Huanga9c929c2024-07-22 04:48:20424 target_.OnDefaultLogicalDeviceIPConfigChanged(v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11425
Taoyu Li110deb42024-08-21 08:51:28426 v6only_dev.network_config.ipv6_addresses = {
427 *net_base::IPv6CIDR::CreateFromCIDRString("2001:db8::2/64")};
naoyatezuka02db5c12023-08-23 01:46:11428
429 // Even the new IPn6 address of the default logical device has the same prefix
430 // as the old one, CLAT needs to be reconfigured because the new address
431 // conflict with the IPv6 address used by CLAT.
Chih-Yu Huanga9c929c2024-07-22 04:48:20432 EXPECT_CALL(target_, StopClat(true));
433 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("v6only")));
434 target_.OnDefaultLogicalDeviceIPConfigChanged(v6only_dev);
naoyatezuka02db5c12023-08-23 01:46:11435}
436
naoyatezukaca02c502023-09-05 06:53:43437TEST_F(ClatServiceTest, EnabledAfterGettingIPv4AddressWhileDisabled) {
naoyatezuka6e778df2023-09-01 00:44:00438 auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only");
439
Chih-Yu Huanga9c929c2024-07-22 04:48:20440 target_.OnDefaultLogicalDeviceIPConfigChanged(v6only_dev);
naoyatezuka6e778df2023-09-01 00:44:00441
Chih-Yu Huanga9c929c2024-07-22 04:48:20442 EXPECT_CALL(target_, StopClat(false));
443 target_.Disable();
naoyatezuka6e778df2023-09-01 00:44:00444
Taoyu Li110deb42024-08-21 08:51:28445 v6only_dev.network_config.ipv4_address =
naoyatezuka6e778df2023-09-01 00:44:00446 net_base::IPv4CIDR::CreateFromCIDRString(kIPv4CIDR);
447
Chih-Yu Huanga9c929c2024-07-22 04:48:20448 EXPECT_CALL(target_, StopClat(true));
449 target_.OnDefaultLogicalDeviceIPConfigChanged(v6only_dev);
naoyatezuka6e778df2023-09-01 00:44:00450
Chih-Yu Huanga9c929c2024-07-22 04:48:20451 EXPECT_CALL(target_, StartClat(_)).Times(Exactly(0));
452 target_.Enable();
naoyatezuka6e778df2023-09-01 00:44:00453}
454
naoyatezukaca02c502023-09-05 06:53:43455TEST_F(ClatServiceTest, EnabledAfterBecomingIPv6OnlyWhileDisabled) {
naoyatezuka6e778df2023-09-01 00:44:00456 auto dual_dev = MakeFakeDualStackShillDevice("dual");
457
Chih-Yu Huanga9c929c2024-07-22 04:48:20458 target_.OnDefaultLogicalDeviceIPConfigChanged(dual_dev);
naoyatezuka6e778df2023-09-01 00:44:00459
Chih-Yu Huanga9c929c2024-07-22 04:48:20460 EXPECT_CALL(target_, StopClat(false));
461 target_.Disable();
naoyatezuka6e778df2023-09-01 00:44:00462
Taoyu Li110deb42024-08-21 08:51:28463 dual_dev.network_config.ipv4_address.reset();
naoyatezuka6e778df2023-09-01 00:44:00464
Chih-Yu Huanga9c929c2024-07-22 04:48:20465 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("dual")));
466 target_.OnDefaultLogicalDeviceIPConfigChanged(dual_dev);
naoyatezuka6e778df2023-09-01 00:44:00467
468 // The default logical device is IPv6-only, so CLAT starts immdiately after
469 // it's enabled.
Chih-Yu Huanga9c929c2024-07-22 04:48:20470 EXPECT_CALL(target_, StartClat(ShillDeviceHasInterfaceName("dual")));
471 target_.Enable();
naoyatezuka6e778df2023-09-01 00:44:00472}
473
naoyatezukaca02c502023-09-05 06:53:43474TEST_F(ClatServiceTest, VerifyStartAndStopClat) {
475 ClatService target(&datapath_, &process_manager_, &system_);
476 target.Enable();
477
478 auto v4only_dev = MakeFakeIPv4OnlyShillDevice("v4only", 1);
479 auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 2);
480
481 target.OnShillDefaultLogicalDeviceChanged(&v4only_dev, nullptr);
482
naoyatezuka71a3b772023-09-29 06:40:13483 EXPECT_CALL(system_, WriteConfigFile).WillOnce(Return(true));
naoyatezukaca02c502023-09-05 06:53:43484 EXPECT_CALL(
485 datapath_,
486 AddTunTap(StrEq("tun_nat64"), Eq(std::nullopt),
487 net_base::IPv4CIDR::CreateFromCIDRString("192.0.0.1/29"),
488 IsEmpty(), DeviceMode::kTun))
489 .WillOnce(Return("tun_nat64"));
naoyatezukac8ebb462023-09-21 10:52:33490 EXPECT_CALL(datapath_,
491 ModifyClatAcceptRules(Iptables::Command::kA, StrEq("tun_nat64")))
492 .WillOnce(Return(true));
naoyatezukaca02c502023-09-05 06:53:43493 EXPECT_CALL(datapath_, AddIPv6HostRoute(StrEq("tun_nat64"),
494 CIDRHasPrefix("2001:db8::/64"),
495 Eq(std::nullopt)))
496 .WillOnce(Return(true));
497 EXPECT_CALL(
498 datapath_,
499 AddIPv6NeighborProxy(StrEq("v6only"), AddressHasPrefix("2001:db8::/64")))
500 .WillOnce(Return(true));
501 EXPECT_CALL(datapath_, AddIPv4RouteToTable(StrEq("tun_nat64"),
502 net_base::IPv4CIDR(), 249))
503 .WillOnce(Return(true));
504 // StartClat() is called.
505 target.OnShillDefaultLogicalDeviceChanged(&v6only_dev, &v4only_dev);
506
507 EXPECT_CALL(datapath_, DeleteIPv4RouteFromTable(StrEq("tun_nat64"),
508 net_base::IPv4CIDR(), 249));
509 EXPECT_CALL(datapath_,
510 RemoveIPv6NeighborProxy(StrEq("v6only"),
511 AddressHasPrefix("2001:db8::/64")));
naoyatezukac8ebb462023-09-21 10:52:33512 EXPECT_CALL(datapath_,
513 ModifyClatAcceptRules(Iptables::Command::kD, StrEq("tun_nat64")));
naoyatezukaca02c502023-09-05 06:53:43514 EXPECT_CALL(datapath_, RemoveIPv6HostRoute(CIDRHasPrefix("2001:db8::/64")));
515 EXPECT_CALL(datapath_, RemoveTunTap(StrEq("tun_nat64"), DeviceMode::kTun));
516 // StopClat() is called.
517 target.OnShillDefaultLogicalDeviceChanged(&v4only_dev, &v6only_dev);
518}
519
naoyatezuka71a3b772023-09-29 06:40:13520TEST_F(ClatServiceTest, CleanUpDatapathWhenDisabled) {
521 ClatService target(&datapath_, &process_manager_, &system_);
522 target.Enable();
523
524 auto v6only_dev = MakeFakeIPv6OnlyShillDevice("v6only", 2);
525 ON_CALL(system_, WriteConfigFile).WillByDefault(Return(true));
526 ON_CALL(datapath_, AddTunTap).WillByDefault(Return("tun_nat64"));
527 ON_CALL(datapath_, ModifyClatAcceptRules).WillByDefault(Return(true));
528 ON_CALL(datapath_, AddIPv6HostRoute).WillByDefault(Return(true));
529 ON_CALL(datapath_, AddIPv6NeighborProxy).WillByDefault(Return(true));
530 ON_CALL(datapath_, AddIPv4RouteToTable).WillByDefault(Return(true));
531 // Start CLAT.
532 target.OnShillDefaultLogicalDeviceChanged(&v6only_dev, nullptr);
533
534 EXPECT_CALL(datapath_, DeleteIPv4RouteFromTable(StrEq("tun_nat64"),
535 net_base::IPv4CIDR(), 249));
536 EXPECT_CALL(datapath_,
537 RemoveIPv6NeighborProxy(StrEq("v6only"),
538 AddressHasPrefix("2001:db8::/64")));
539 EXPECT_CALL(datapath_,
540 ModifyClatAcceptRules(Iptables::Command::kD, StrEq("tun_nat64")));
541 EXPECT_CALL(datapath_, RemoveIPv6HostRoute(CIDRHasPrefix("2001:db8::/64")));
542 EXPECT_CALL(datapath_, RemoveTunTap(StrEq("tun_nat64"), DeviceMode::kTun));
543 target.Disable();
544}
545
naoyatezukaca02c502023-09-05 06:53:43546} // namespace
naoyatezuka02db5c12023-08-23 01:46:11547} // namespace patchpanel