From: David Ahern <dsa@cumulusnetworks.com>
To: netdev@vger.kernel.org, stephen@networkplumber.org, luto@amacapital.net
Cc: David Ahern <dsa@cumulusnetworks.com>
Subject: [PATCH iproute2 3/4] ip vrf: Handle VRF nesting in namespace
Date: Thu, 16 Feb 2017 08:58:57 -0800 [thread overview]
Message-ID: <1487264338-17588-4-git-send-email-dsa@cumulusnetworks.com> (raw)
In-Reply-To: <1487264338-17588-1-git-send-email-dsa@cumulusnetworks.com>
Since cgroups are not namespace aware, the directory heirarchy used by
ip vrf should account for network namespaces. In this case, change the
path from CGRP/BASE/vrf/NAME to CGRP/BASE/NETNS/vrf/NAME where CGRP is
the cgroup2 mount path, BASE in any base heirarchy inherited before VRF
is applied and NAME is the VRF name.
The intent is as follows: a user logs into the box into some namespace
with a name known to iproute2. Some other policy may have put the
process into a BASE heirarchy. From there the user executes a task in
a VRF and in doing so the task heirarchy becomes CGRP/BASE/NETNS/vrf/NAME.
The namespace level is omitted for the default namespace.
Reported-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
ip/ipvrf.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 55 insertions(+), 8 deletions(-)
diff --git a/ip/ipvrf.c b/ip/ipvrf.c
index 8d61d0718c66..cb7f9fa6d1db 100644
--- a/ip/ipvrf.c
+++ b/ip/ipvrf.c
@@ -134,8 +134,8 @@ static void read_cgroup_pids(const char *base_path, char *name)
close(fd);
}
-/* recurse path looking for PATH/vrf/NAME */
-static int recurse_dir(char *base_path, char *name)
+/* recurse path looking for PATH[/NETNS]/vrf/NAME */
+static int recurse_dir(char *base_path, char *name, const char *netns)
{
char path[PATH_MAX];
struct dirent *de;
@@ -152,7 +152,15 @@ static int recurse_dir(char *base_path, char *name)
continue;
if (!strcmp(de->d_name, "vrf")) {
- read_cgroup_pids(base_path, name);
+ const char *pdir = strrchr(base_path, '/');
+
+ /* found a 'vrf' directory. if it is for the given
+ * namespace then dump the cgroup pids
+ */
+ if (*netns == '\0' ||
+ (pdir && !strcmp(pdir+1, netns)))
+ read_cgroup_pids(base_path, name);
+
continue;
}
@@ -165,7 +173,7 @@ static int recurse_dir(char *base_path, char *name)
continue;
if (S_ISDIR(fstat.st_mode)) {
- rc = recurse_dir(path, name);
+ rc = recurse_dir(path, name, netns);
if (rc != 0)
goto out;
}
@@ -178,10 +186,25 @@ static int recurse_dir(char *base_path, char *name)
return rc;
}
+static int ipvrf_get_netns(char *netns, int len)
+{
+ if (netns_identify_pid("self", netns, len-3)) {
+ fprintf(stderr, "Failed to get name of network namespace: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ if (*netns != '\0')
+ strcat(netns, "-ns");
+
+ return 0;
+}
+
static int ipvrf_pids(int argc, char **argv)
{
char *mnt, *vrf;
- int ret;
+ char netns[256];
+ int ret = -1;
if (argc != 1) {
fprintf(stderr, "Invalid arguments\n");
@@ -194,8 +217,12 @@ static int ipvrf_pids(int argc, char **argv)
if (!mnt)
return -1;
- ret = recurse_dir(mnt, vrf);
+ if (ipvrf_get_netns(netns, sizeof(netns)) < 0)
+ goto out;
+
+ ret = recurse_dir(mnt, vrf, netns);
+out:
free(mnt);
return ret;
@@ -316,7 +343,7 @@ static int vrf_path(char *vpath, size_t len)
static int vrf_switch(const char *name)
{
char path[PATH_MAX], *mnt, pid[16];
- char vpath[PATH_MAX];
+ char vpath[PATH_MAX], netns[256];
int ifindex = 0;
int rc = -1, len, fd = -1;
@@ -332,17 +359,37 @@ static int vrf_switch(const char *name)
if (!mnt)
return -1;
+ /* -1 on length to add '/' to the end */
+ if (ipvrf_get_netns(netns, sizeof(netns) - 1) < 0)
+ return -1;
+
if (vrf_path(vpath, sizeof(vpath)) < 0) {
fprintf(stderr, "Failed to get base cgroup path: %s\n",
strerror(errno));
return -1;
}
+ /* if path already ends in netns then don't add it again */
+ if (*netns != '\0') {
+ char *pdir = strrchr(vpath, '/');
+
+ if (!pdir)
+ pdir = vpath;
+ else
+ pdir++;
+
+ if (strcmp(pdir, netns) == 0)
+ *pdir = '\0';
+
+ strcat(netns, "/");
+ }
+
/* path to cgroup; make sure buffer has room to cat "/cgroup.procs"
* to the end of the path
*/
len = snprintf(path, sizeof(path) - sizeof(CGRP_PROC_FILE),
- "%s%s/vrf/%s", mnt, vpath, ifindex ? name : "");
+ "%s%s/%svrf/%s",
+ mnt, vpath, netns, ifindex ? name : "");
if (len > sizeof(path) - sizeof(CGRP_PROC_FILE)) {
fprintf(stderr, "Invalid path to cgroup2 mount\n");
goto out;
--
2.1.4
next prev parent reply other threads:[~2017-02-16 16:59 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-16 16:58 [PATCH iproute2 0/4] ip vrf: updates to handle cgroup hiearchy and namespace nesting David Ahern
2017-02-16 16:58 ` [PATCH iproute2 1/4] ip vrf: Handle vrf in a cgroup hierarchy David Ahern
2017-02-16 16:58 ` [PATCH iproute2 2/4] ip netns: refactor netns_identify David Ahern
2017-02-16 16:58 ` David Ahern [this message]
2017-02-16 16:58 ` [PATCH iproute2 4/4] ip vrf: Detect invalid vrf name in pids command David Ahern
2017-02-19 0:11 ` [PATCH iproute2 0/4] ip vrf: updates to handle cgroup hiearchy and namespace nesting Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1487264338-17588-4-git-send-email-dsa@cumulusnetworks.com \
--to=dsa@cumulusnetworks.com \
--cc=luto@amacapital.net \
--cc=netdev@vger.kernel.org \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.