patchpanel: route arcbr0 through non-ARC VPNs
This patch sets ARC's arcbr0 routing tags so that traffic originated
through arcbr0 by ARC is routed through any non-ARC VPN connection.
Inside ARC, arcbr0 is used to expose a fake "facade" VPN network
corresponding to the non-ARC VPN established on the host environment.
BUG=b:161507671
BUG=b:161508179
BUG=chromium:1157515
TEST=unit tests. Checked that ARC traffic is correctly routed on the
host when a full tunnel VPN connection is set up on the host.
Change-Id: I7375af1a604bfc6ecb8a729decb55b13a8717af0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2586457
Tested-by: Hugo Benichi <hugobenichi@google.com>
Commit-Queue: Hugo Benichi <hugobenichi@google.com>
Reviewed-by: Taoyu Li <taoyl@chromium.org>
diff --git a/patchpanel/datapath.cc b/patchpanel/datapath.cc
index fc84da5..b9f0fef 100644
--- a/patchpanel/datapath.cc
+++ b/patchpanel/datapath.cc
@@ -26,6 +26,7 @@
#include <brillo/userdb_utils.h>
#include "patchpanel/adb_proxy.h"
+#include "patchpanel/arc_service.h"
#include "patchpanel/net_util.h"
#include "patchpanel/scoped_ns.h"
@@ -619,6 +620,7 @@
TrafficSource source,
bool route_on_vpn) {
if (source == TrafficSource::ARC && !ext_ifname.empty() &&
+ int_ipv4_addr != 0 &&
!AddInboundIPv4DNAT(ext_ifname, IPv4AddressToString(int_ipv4_addr)))
LOG(ERROR) << "Failed to configure ingress traffic rules for " << ext_ifname
<< "->" << int_ifname;
@@ -665,7 +667,7 @@
uint32_t int_ipv4_addr,
TrafficSource source,
bool route_on_vpn) {
- if (source == TrafficSource::ARC && !ext_ifname.empty())
+ if (source == TrafficSource::ARC && !ext_ifname.empty() && int_ipv4_addr != 0)
RemoveInboundIPv4DNAT(ext_ifname, IPv4AddressToString(int_ipv4_addr));
StopIpForwarding(IpFamily::IPv4, ext_ifname, int_ifname);
StopIpForwarding(IpFamily::IPv4, int_ifname, ext_ifname);
@@ -854,9 +856,15 @@
StartConnectionPinning(vpn_ifname);
if (!ModifyFwmarkRoutingTag(kApplyVpnMarkChain, "-A", vpn_ifname, ""))
LOG(ERROR) << "Failed to set up VPN set-mark rule for " << vpn_ifname;
+ if (vpn_ifname != kArcBridge)
+ StartRoutingDevice(vpn_ifname, kArcBridge, 0 /*no inbound DNAT */,
+ TrafficSource::ARC, true /* route_on_vpn */);
}
void Datapath::StopVpnRouting(const std::string& vpn_ifname) {
+ if (vpn_ifname != kArcBridge)
+ StopRoutingDevice(vpn_ifname, kArcBridge, 0 /* no inbound DNAT */,
+ TrafficSource::ARC, false /* route_on_vpn */);
if (!ModifyFwmarkRoutingTag(kApplyVpnMarkChain, "-D", vpn_ifname, ""))
LOG(ERROR) << "Failed to remove VPN set-mark rule for " << vpn_ifname;
StopConnectionPinning(vpn_ifname);