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/scoped_ns.h b/patchpanel/scoped_ns.h
index a77a8f1..ab25180 100644
--- a/patchpanel/scoped_ns.h
+++ b/patchpanel/scoped_ns.h
@@ -5,6 +5,9 @@
#ifndef PATCHPANEL_SCOPED_NS_H_
#define PATCHPANEL_SCOPED_NS_H_
+#include <memory>
+#include <string>
+
#include <base/files/scoped_file.h>
#include <base/macros.h>
@@ -14,21 +17,24 @@
// namespace.
class ScopedNS {
public:
- enum Type {
- Network = 1,
- Mount,
- };
+ // Records the current mount (network) namespace and enters another namespace
+ // identified by the input argument. Will go back to the current namespace if
+ // the returned object goes out of scope. Returns nullptr on failure.
+ static std::unique_ptr<ScopedNS> EnterMountNS(pid_t pid);
+ static std::unique_ptr<ScopedNS> EnterNetworkNS(pid_t pid);
+ static std::unique_ptr<ScopedNS> EnterNetworkNS(
+ const std::string& netns_name);
- explicit ScopedNS(pid_t pid, Type type);
ScopedNS(const ScopedNS&) = delete;
ScopedNS& operator=(const ScopedNS&) = delete;
~ScopedNS();
- // Returns whether or not the object was able to enter the target namespace.
- bool IsValid() const { return valid_; }
-
private:
+ ScopedNS(int nstype,
+ const std::string& current_ns_path,
+ const std::string& target_ns_path);
+
int nstype_;
bool valid_;
base::ScopedFD ns_fd_;