arc: Move platform2/arc/network/ to platform2/patchpanel
Next step in the arc-networkd -> patchpanel rename, this patch moves the
location of the code.
BUG=b:151879931
TEST=units,flashed image to atlas
TEST=tasts arc.PlayStore, crostini.LaunchTerminal.download
Change-Id: I1b5cf8d670e1631d46f6449b725395157bf88dde
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2115863
Tested-by: Garrick Evans <garrick@chromium.org>
Commit-Queue: Garrick Evans <garrick@chromium.org>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Eric Caruso <ejcaruso@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/routing_service_test.cc b/patchpanel/routing_service_test.cc
new file mode 100644
index 0000000..70e4504
--- /dev/null
+++ b/patchpanel/routing_service_test.cc
@@ -0,0 +1,187 @@
+// Copyright 2020 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "patchpanel/routing_service.h"
+
+#include <algorithm>
+#include <sstream>
+
+#include <gtest/gtest.h>
+
+namespace patchpanel {
+namespace {
+
+auto& BYPASS_VPN = patchpanel::SetVpnIntentRequest::BYPASS_VPN;
+auto& DEFAULT_ROUTING = patchpanel::SetVpnIntentRequest::DEFAULT_ROUTING;
+auto& ROUTE_ON_VPN = patchpanel::SetVpnIntentRequest::ROUTE_ON_VPN;
+
+std::string hex(uint32_t val) {
+ std::stringstream ss;
+ ss << "0x" << std::hex << val;
+ return ss.str();
+}
+
+struct sockopt_data {
+ int sockfd;
+ int level;
+ int optname;
+ char optval[256];
+ socklen_t optlen;
+};
+
+void SetOptval(sockopt_data& sockopt, uint32_t optval) {
+ sockopt.optlen = sizeof(optval);
+ memcpy(sockopt.optval, &optval, sizeof(optval));
+}
+
+uint32_t GetOptval(const sockopt_data& sockopt) {
+ uint32_t optval;
+ memcpy(&optval, sockopt.optval, sizeof(optval));
+ return optval;
+}
+
+class TestableRoutingService : public RoutingService {
+ public:
+ TestableRoutingService() = default;
+ ~TestableRoutingService() = default;
+
+ int GetSockopt(int sockfd,
+ int level,
+ int optname,
+ void* optval,
+ socklen_t* optlen) override {
+ sockopt.sockfd = sockfd;
+ sockopt.level = level;
+ sockopt.optname = optname;
+ memcpy(optval, sockopt.optval,
+ std::min(*optlen, (socklen_t)sizeof(sockopt.optval)));
+ *optlen = sockopt.optlen;
+ return getsockopt_ret;
+ }
+
+ int SetSockopt(int sockfd,
+ int level,
+ int optname,
+ const void* optval,
+ socklen_t optlen) override {
+ sockopt.sockfd = sockfd;
+ sockopt.level = level;
+ sockopt.optname = optname;
+ sockopt.optlen = optlen;
+ memcpy(sockopt.optval, optval,
+ std::min(optlen, (socklen_t)sizeof(sockopt.optval)));
+ return setsockopt_ret;
+ }
+
+ // Variables used to mock and track interactions with getsockopt and
+ // setsockopt.
+ int getsockopt_ret;
+ int setsockopt_ret;
+ sockopt_data sockopt;
+};
+
+class RoutingServiceTest : public testing::Test {
+ public:
+ RoutingServiceTest() = default;
+
+ protected:
+ void SetUp() override {}
+};
+
+} // namespace
+
+TEST_F(RoutingServiceTest, SetVpnFwmark) {
+ auto svc = std::make_unique<TestableRoutingService>();
+ svc->getsockopt_ret = 0;
+ svc->setsockopt_ret = 0;
+
+ struct {
+ patchpanel::SetVpnIntentRequest::VpnRoutingPolicy policy;
+ uint32_t initial_fwmark;
+ uint32_t expected_fwmark;
+ } testcases[] = {
+ {ROUTE_ON_VPN, 0x0, 0x80000000},
+ {BYPASS_VPN, 0x0, 0x40000000},
+ {ROUTE_ON_VPN, 0x1, 0x80000001},
+ {BYPASS_VPN, 0x00abcdef, 0x40abcdef},
+ {ROUTE_ON_VPN, 0x11223344, 0x91223344},
+ {BYPASS_VPN, 0x11223344, 0x51223344},
+ {ROUTE_ON_VPN, 0x80000000, 0x80000000},
+ {BYPASS_VPN, 0x40000000, 0x40000000},
+ {BYPASS_VPN, 0x80000000, 0x40000000},
+ {ROUTE_ON_VPN, 0x40000000, 0x80000000},
+ {DEFAULT_ROUTING, 0x80000000, 0x00000000},
+ {DEFAULT_ROUTING, 0x40000000, 0x00000000},
+ };
+
+ for (const auto& tt : testcases) {
+ SetOptval(svc->sockopt, tt.initial_fwmark);
+ EXPECT_TRUE(svc->SetVpnFwmark(4, tt.policy));
+ EXPECT_EQ(4, svc->sockopt.sockfd);
+ EXPECT_EQ(SOL_SOCKET, svc->sockopt.level);
+ EXPECT_EQ(SO_MARK, svc->sockopt.optname);
+ EXPECT_EQ(hex(tt.expected_fwmark), hex(GetOptval(svc->sockopt)));
+ }
+
+ svc->getsockopt_ret = -1;
+ svc->setsockopt_ret = 0;
+ EXPECT_FALSE(svc->SetVpnFwmark(4, ROUTE_ON_VPN));
+
+ svc->getsockopt_ret = 0;
+ svc->setsockopt_ret = -1;
+ EXPECT_FALSE(svc->SetVpnFwmark(4, ROUTE_ON_VPN));
+
+ svc->getsockopt_ret = 0;
+ svc->setsockopt_ret = 0;
+ EXPECT_FALSE(svc->SetVpnFwmark(
+ 4, (patchpanel::SetVpnIntentRequest::VpnRoutingPolicy)-1));
+}
+
+TEST_F(RoutingServiceTest, SetFwmark) {
+ auto svc = std::make_unique<TestableRoutingService>();
+ svc->getsockopt_ret = 0;
+ svc->setsockopt_ret = 0;
+
+ struct {
+ uint32_t initial_fwmark;
+ uint32_t fwmark_value;
+ uint32_t fwmark_mask;
+ uint32_t expected_fwmark;
+ } testcases[] = {
+ {0x0, 0x0, 0x0, 0x0},
+ {0x1, 0x0, 0x0, 0x1},
+ {0x1, 0x0, 0x1, 0x0},
+ {0xaabbccdd, 0x11223344, 0xf0f0f0f0, 0x1a2b3c4d},
+ {0xaabbccdd, 0x11223344, 0xffff0000, 0x1122ccdd},
+ {0xaabbccdd, 0x11223344, 0x0000ffff, 0xaabb3344},
+ };
+
+ for (const auto& tt : testcases) {
+ SetOptval(svc->sockopt, tt.initial_fwmark);
+ EXPECT_TRUE(svc->SetFwmark(4, tt.fwmark_value, tt.fwmark_mask));
+ EXPECT_EQ(4, svc->sockopt.sockfd);
+ EXPECT_EQ(SOL_SOCKET, svc->sockopt.level);
+ EXPECT_EQ(SO_MARK, svc->sockopt.optname);
+ EXPECT_EQ(hex(tt.expected_fwmark), hex(GetOptval(svc->sockopt)));
+ }
+}
+
+TEST_F(RoutingServiceTest, SetFwmark_Failures) {
+ auto svc = std::make_unique<TestableRoutingService>();
+ svc->getsockopt_ret = -1;
+ svc->setsockopt_ret = 0;
+ EXPECT_FALSE(svc->SetFwmark(4, 0x1, 0x1));
+
+ svc = std::make_unique<TestableRoutingService>();
+ svc->getsockopt_ret = 0;
+ svc->setsockopt_ret = -1;
+ EXPECT_FALSE(svc->SetFwmark(5, 0x1, 0x1));
+
+ svc = std::make_unique<TestableRoutingService>();
+ svc->getsockopt_ret = 0;
+ svc->setsockopt_ret = 0;
+ EXPECT_TRUE(svc->SetFwmark(6, 0x1, 0x1));
+}
+
+} // namespace patchpanel