patchpanel: Support open a new netns via ConnectNamespace
Currently the ConnectNamespace API exposed by patchpanel via d-bus only
supports passing in a pid of a process and doing "ConnectNamespace" for
the netns associated with this process. While in the tast tests,
sometimes we need to open a new netns directly, and execute processes in
the created netns.
For this usage, this patch modifies the ConnectNamespace API so that
patchpanel accepts passing a special pid (i.e., pid==-1) to indicates
the client wants a new netns, invokes `ip netns add` for this case, and
returns the name of the created netns.
BUG=b:185210339
TEST=unit_tests;
TEST=Used this API in test VPN tast test, verified it worked;
TEST=Checked playstore still worked.
Change-Id: I3bbfab89df24899127e6087b0c0533e2c96037dc
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2896672
Reviewed-by: Garrick Evans <garrick@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
Tested-by: Jie Jiang <jiejiang@chromium.org>
Commit-Queue: Jie Jiang <jiejiang@chromium.org>
diff --git a/patchpanel/datapath.cc b/patchpanel/datapath.cc
index 7335a25..caf6d9f 100644
--- a/patchpanel/datapath.cc
+++ b/patchpanel/datapath.cc
@@ -340,7 +340,11 @@
// did not exit cleanly.
if (process_runner_->ip_netns_delete(netns_name, false /*log_failures*/) == 0)
LOG(INFO) << "Deleted left over network namespace name " << netns_name;
- return process_runner_->ip_netns_attach(netns_name, netns_pid) == 0;
+
+ if (netns_pid == ConnectedNamespace::kNewNetnsPid)
+ return process_runner_->ip_netns_add(netns_name) == 0;
+ else
+ return process_runner_->ip_netns_attach(netns_name, netns_pid) == 0;
}
bool Datapath::NetnsDeleteName(const std::string& netns_name) {
@@ -520,8 +524,8 @@
// Configure the remote veth in namespace |netns_name|.
{
- ScopedNS ns(netns_pid, ScopedNS::Type::Network);
- if (!ns.IsValid() && netns_pid != kTestPID) {
+ auto ns = ScopedNS::EnterNetworkNS(netns_name);
+ if (!ns && netns_pid != kTestPID) {
LOG(ERROR)
<< "Cannot create virtual link -- invalid container namespace?";
return false;
@@ -597,7 +601,8 @@
bool Datapath::StartRoutingNamespace(const ConnectedNamespace& nsinfo) {
// Veth interface configuration and client routing configuration:
- // - attach a name to the client namespace.
+ // - attach a name to the client namespace (or create a new named namespace
+ // if no client is specified).
// - create veth pair across the current namespace and the client namespace.
// - configure IPv4 address on remote veth inside client namespace.
// - configure IPv4 address on local veth inside host namespace.
@@ -630,8 +635,8 @@
}
{
- ScopedNS ns(nsinfo.pid, ScopedNS::Type::Network);
- if (!ns.IsValid() && nsinfo.pid != kTestPID) {
+ auto ns = ScopedNS::EnterNetworkNS(nsinfo.netns_name);
+ if (!ns && nsinfo.pid != kTestPID) {
LOG(ERROR) << "Invalid namespace pid " << nsinfo.pid;
RemoveInterface(nsinfo.host_ifname);
NetnsDeleteName(nsinfo.netns_name);