patchpanel: create veth pairs directly across 2 netns
This patch changes how veth pairs are created by patchpanel for ARC++
and for patchpanel ConnectNamespace DBus API. Instead of creating the
veth pair in the target network namespace and briging back one half to
the host network namespace, the pair is directly created across the host
network namespace and target network namespace. This requires naming the
network namespace with $ ip netns attach NAME PID. Therefore ArcService
will now systematically attach the name "arc_netns" to the ARC++
network namespace at ARC++ startup.
The advantages of creating the veth pair directly across 2 namespaces
are:
- does not require to call RestoreDefaultNamespace (equivalent to
the command $ nsenter -i <pid> -n -- ip link set arc_ns<id> netns 1)
which was found to be racy in crbug/1095170).
- does not require to enter the ARC network namespace for ARC interface
creation. Eventually when ARC will obtain the full interface
configuration from patchpanel, pending migrating net.mojom from Chrome
to patchpanel, it will not be necessary to enter the ARC container at
all from patchpanel.
BUG=b:160736881
BUG=crbug:1095170
Test: Unit tests pass. Manual tests are WIP
Change-Id: Ic31c7dfbb1eb88b55314e44733ff55ba821b41a4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2289719
Tested-by: Hugo Benichi <hugobenichi@google.com>
Tested-by: Andreea-Elena Costinas <acostinas@google.com>
Reviewed-by: Andreea-Elena Costinas <acostinas@google.com>
Reviewed-by: Garrick Evans <garrick@chromium.org>
Commit-Queue: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/arc_service_test.cc b/patchpanel/arc_service_test.cc
index d064eb7..01aad32 100644
--- a/patchpanel/arc_service_test.cc
+++ b/patchpanel/arc_service_test.cc
@@ -113,6 +113,8 @@
}
TEST_F(ArcServiceTest, VerifyAddrConfigs) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
@@ -138,6 +140,8 @@
}
TEST_F(ArcServiceTest, VerifyAddrOrder) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
@@ -177,11 +181,14 @@
// ContainerImpl
TEST_F(ArcServiceTest, ContainerImpl_Start) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
// Expectations for arc0 setup.
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
+ StrEq("arc0")))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
@@ -197,10 +204,13 @@
}
TEST_F(ArcServiceTest, ContainerImpl_FailsToCreateInterface) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
+ StrEq("arc0")))
.WillOnce(Return(false));
EXPECT_CALL(*datapath_, ConfigureInterface(_, _, _, _, _, _)).Times(0);
EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
@@ -210,10 +220,13 @@
}
TEST_F(ArcServiceTest, ContainerImpl_FailsToConfigureInterface) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
+ StrEq("arc0")))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
@@ -228,10 +241,13 @@
}
TEST_F(ArcServiceTest, ContainerImpl_FailsToAddInterfaceToBridge) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
+ StrEq("arc0")))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
@@ -249,11 +265,14 @@
}
TEST_F(ArcServiceTest, ContainerImpl_OnStartDevice) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
// Expectations for arc0 setup.
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
+ StrEq("arc0")))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
@@ -266,7 +285,8 @@
EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetheth0"), StrEq("eth0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetheth0"),
+ StrEq("eth0")))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_, ConfigureInterface(StrEq("eth0"), _, kFirstEthGuestIP,
30, true, _))
@@ -290,11 +310,16 @@
}
TEST_F(ArcServiceTest, ContainerImpl_Stop) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*datapath_, NetnsDeleteName(StrEq("arc_netns")))
+ .WillOnce(Return(true));
// Expectations for arc0 setup.
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
+ StrEq("arc0")))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
@@ -316,11 +341,14 @@
}
TEST_F(ArcServiceTest, ContainerImpl_OnStopDevice) {
+ EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
+ .WillOnce(Return(true));
// Expectations for arc0 setup.
EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetharc0"), StrEq("arc0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetharc0"),
+ StrEq("arc0")))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
ConfigureInterface(StrEq("arc0"), _, kArcGuestIP, 30, true, _))
@@ -333,7 +361,8 @@
EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_,
- AddVirtualInterfacePair(StrEq("vetheth0"), StrEq("eth0")))
+ AddVirtualInterfacePair(StrEq("arc_netns"), StrEq("vetheth0"),
+ StrEq("eth0")))
.WillOnce(Return(true));
EXPECT_CALL(*datapath_, ConfigureInterface(StrEq("eth0"), _, kFirstEthGuestIP,
30, true, _))