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.cc b/patchpanel/routing_service.cc
new file mode 100644
index 0000000..994dcc8
--- /dev/null
+++ b/patchpanel/routing_service.cc
@@ -0,0 +1,75 @@
+// 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 <iostream>
+
+#include <base/logging.h>
+
+namespace {
+// TODO(hugobenichi) Formalize the semantics of fwmark bits with a bitfield
+// struct.
+constexpr const uint32_t kFwmarkRouteOnVpnBit = 0x80000000; // 1st MSB
+constexpr const uint32_t kFwmarkBypassVpnBit = 0x40000000; // 2nd MSB
+constexpr const uint32_t kFwmarkVpnMask =
+ kFwmarkBypassVpnBit | kFwmarkRouteOnVpnBit;
+} // namespace
+
+namespace patchpanel {
+
+RoutingService::RoutingService() {}
+
+int RoutingService::GetSockopt(
+ int sockfd, int level, int optname, void* optval, socklen_t* optlen) {
+ return getsockopt(sockfd, level, optname, optval, optlen);
+}
+
+int RoutingService::SetSockopt(
+ int sockfd, int level, int optname, const void* optval, socklen_t optlen) {
+ return setsockopt(sockfd, level, optname, optval, optlen);
+}
+
+bool RoutingService::SetFwmark(int sockfd, uint32_t mark, uint32_t mask) {
+ uint32_t fwmark_value = 0;
+ socklen_t fwmark_len = sizeof(fwmark_value);
+ if (GetSockopt(sockfd, SOL_SOCKET, SO_MARK, &fwmark_value, &fwmark_len) < 0) {
+ PLOG(ERROR) << "SetFwmark mark=0x" << std::hex << mark << " mask=0x"
+ << std::hex << mask << " getsockopt SOL_SOCKET SO_MARK failed";
+ return false;
+ }
+
+ fwmark_value = (mark & mask) | (fwmark_value & ~mask);
+
+ fwmark_len = sizeof(fwmark_value);
+ if (SetSockopt(sockfd, SOL_SOCKET, SO_MARK, &fwmark_value, fwmark_len) < 0) {
+ PLOG(ERROR) << "SetFwmark mark=0x" << std::hex << mark << " mask=0x"
+ << std::hex << mask << " setsockopt SOL_SOCKET SO_MARK failed";
+ return false;
+ }
+
+ return true;
+}
+
+bool RoutingService::SetVpnFwmark(
+ int sockfd, patchpanel::SetVpnIntentRequest::VpnRoutingPolicy policy) {
+ uint32_t mark;
+ switch (policy) {
+ case patchpanel::SetVpnIntentRequest::DEFAULT_ROUTING:
+ mark = 0;
+ break;
+ case patchpanel::SetVpnIntentRequest::ROUTE_ON_VPN:
+ mark = kFwmarkRouteOnVpnBit;
+ break;
+ case patchpanel::SetVpnIntentRequest::BYPASS_VPN:
+ mark = kFwmarkBypassVpnBit;
+ break;
+ default:
+ LOG(ERROR) << "Incorrect SetVpnIntent policy value " << policy;
+ return false;
+ }
+ return SetFwmark(sockfd, mark, kFwmarkVpnMask);
+}
+
+} // namespace patchpanel