When more than one namespace is used by the interfaces, the ptp4l program needs the possibility to switch between namespaces when configuring those interfaces. This patch adds that possibility.
The patch require the ptp4l program to start in default namespace so that the program can switch back to default if needed. Signed-off-by: Anders Selhammer <anders.selham...@est.tech> --- sk.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ sk.h | 19 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/sk.c b/sk.c index 69492d4..f4bd69a 100644 --- a/sk.c +++ b/sk.c @@ -25,6 +25,8 @@ #include <netinet/in.h> #include <string.h> #include <sys/ioctl.h> +#include <fcntl.h> +#include <sched.h> #include <unistd.h> #include <ifaddrs.h> #include <stdlib.h> @@ -42,6 +44,9 @@ int sk_tx_timeout; /* Initialized by configuration file */ int sk_check_fupsync; /* Initialized by configuration file */ enum hwts_filter_mode sk_hwts_filter_mode = HWTS_FILTER_NORMAL; +static int sk_initial_fd = -1; +static char sk_netns_path[64]; + /* private methods */ static void init_ifreq(struct ifreq *ifreq, struct hwtstamp_config *cfg, @@ -152,6 +157,52 @@ int sk_general_init(int fd) return 0; } +int sk_initiate_namespace_reassociation(const char *netns) { + snprintf(sk_netns_path, sizeof sk_netns_path, "%s", netns); + sk_initial_fd = open("/proc/self/ns/net", O_RDONLY); + if (sk_initial_fd < 0) { + pr_err("open initial namespace fd failed: %m"); + return -1; + } + return 0; +} + +void sk_close_initial_namespace_fd(void) { + if (sk_initial_fd >= 0) { + close(sk_initial_fd); + sk_initial_fd = -1; + } +} + +int sk_reassociate_namespace(const char *ns) +{ + char path[64]; + int fd; + + if (*ns == '\0') { + if (setns(sk_initial_fd, CLONE_NEWNET) < 0) { + pr_err("setns failed: %m"); + return -1; + } + pr_notice("setns for default namespace ok"); + } else { + snprintf(path, sizeof path, "%s%s", sk_netns_path, ns); + fd = open(path, O_RDONLY); + if (fd < 0) { + pr_err("failed to open %s: %m", path); + return -1; + } + if (setns(fd, CLONE_NEWNET) < 0) { + pr_err("setns failed: %m"); + close(fd); + return -1; + } + pr_notice("setns ok, %s", path); + close(fd); + } + return 0; +} + int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info) { #ifdef ETHTOOL_GET_TS_INFO diff --git a/sk.h b/sk.h index 04d26ee..5751ef2 100644 --- a/sk.h +++ b/sk.h @@ -71,6 +71,25 @@ int sk_interface_index(int fd, const char *device); int sk_general_init(int fd); /** + * Initialize netns path and initial file descriptor + * @param netns Path to netns object. + * @return zero on success, negative on failure. + */ +int sk_initiate_namespace_reassociation(const char *netns); + +/** + * Close initial namespace file descriptor + */ +void sk_close_initial_namespace_fd(void); + +/** + * Prepare namespace for the process before socket is opened + * @param ns The namespace to reassociate to. + * @return zero on success, negative on failure. + */ +int sk_reassociate_namespace(const char *ns); + +/** * Obtain supported timestamping information * @param name The name of the interface * @param info Struct containing obtained timestamping information. -- 1.8.3.1 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel