[iproute2 net-next 8/8] Introduce ip vrf command
'ip vrf' follows the user semnatics established by 'ip netns'. The 'ip vrf' subcommand supports 3 usages: 1. Run a command against a given vrf: ip vrf exec NAME CMD Uses the recently committed cgroup/sock BPF option. vrf directory is added to cgroup2 mount. Individual vrfs are created under it. BPF filter attached to vrf/NAME cgroup2 to set sk_bound_dev_if to the VRF device index. From there the current process (ip's pid) is addded to the cgroups.proc file and the given command is exected. In doing so all AF_INET/AF_INET6 (ipv4/ipv6) sockets are automatically bound to the VRF domain. The association is inherited parent to child allowing the command to be a shell from which other commands are run relative to the VRF. 2. Show the VRF a process is bound to: ip vrf id This command essentially looks at /proc/pid/cgroup for a "::/vrf/" entry with the VRF name following. 3. Show process ids bound to a VRF ip vrf pids NAME This command dumps the file MNT/vrf/NAME/cgroup.procs since that file shows the process ids in the particular vrf cgroup. Signed-off-by: David Ahern --- ip/Makefile | 3 +- ip/ip.c | 4 +- ip/ip_common.h| 2 + ip/ipvrf.c| 289 ++ man/man8/ip-vrf.8 | 88 + 5 files changed, 384 insertions(+), 2 deletions(-) create mode 100644 ip/ipvrf.c create mode 100644 man/man8/ip-vrf.8 diff --git a/ip/Makefile b/ip/Makefile index c8e6c6172741..1928489e7f90 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -7,7 +7,8 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \ link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \ iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \ -iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o +iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \ +ipvrf.o RTMONOBJ=rtmon.o diff --git a/ip/ip.c b/ip/ip.c index cb3adcb3f57d..07050b07592a 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -51,7 +51,8 @@ static void usage(void) " ip [ -force ] -batch filename\n" "where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n" " tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n" -" netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila }\n" +" netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |\n" +" vrf }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" "-h[uman-readable] | -iec |\n" "-f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n" @@ -99,6 +100,7 @@ static const struct cmd { { "mrule", do_multirule }, { "netns", do_netns }, { "netconf",do_ipnetconf }, + { "vrf",do_ipvrf}, { "help", do_help }, { 0 } }; diff --git a/ip/ip_common.h b/ip/ip_common.h index 3162f1ca5b2c..28763e81e4a4 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -57,6 +57,8 @@ extern int do_ipila(int argc, char **argv); int do_tcp_metrics(int argc, char **argv); int do_ipnetconf(int argc, char **argv); int do_iptoken(int argc, char **argv); +int do_ipvrf(int argc, char **argv); + int iplink_get(unsigned int flags, char *name, __u32 filt_mask); static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb) diff --git a/ip/ipvrf.c b/ip/ipvrf.c new file mode 100644 index ..d49af774438e --- /dev/null +++ b/ip/ipvrf.c @@ -0,0 +1,289 @@ +/* + * ipvrf.c "ip vrf" + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors:David Ahern + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rt_names.h" +#include "utils.h" +#include "ip_common.h" +#include "bpf_util.h" + +#define CGRP_PROC_FILE "/cgroup.procs" + +static void usage(void) +{ + fprintf(stderr, "Usage: ip vrf exec [NAME] cmd ...\n"); + fprintf(stderr, " ip vrf identify [PID]\n"); + fprintf(stderr, " ip vrf pids [NAME]\n"); + + exit(-1); +} + +static int ipvrf_identify(int argc, char **argv) +{ + char path[PATH_MAX]; + char buf[4096]; + char *vrf, *end; + int fd, rc = -1; + unsigned int pid; + ssize_t n; + + if (argc < 1) + pid = getpid(); + else if (argc > 1) + invarg("Extra arguments specified\n", argv[1
[iproute2 net-next 8/8] Introduce ip vrf command
'ip vrf' follows the user semnatics established by 'ip netns'. The 'ip vrf' subcommand supports 3 usages: 1. Run a command against a given vrf: ip vrf exec NAME CMD Uses the recently committed cgroup/sock BPF option. vrf directory is added to cgroup2 mount. Individual vrfs are created under it. BPF filter attached to vrf/NAME cgroup2 to set sk_bound_dev_if to the VRF device index. From there the current process (ip's pid) is addded to the cgroups.proc file and the given command is exected. In doing so all AF_INET/AF_INET6 (ipv4/ipv6) sockets are automatically bound to the VRF domain. The association is inherited parent to child allowing the command to be a shell from which other commands are run relative to the VRF. 2. Show the VRF a process is bound to: ip vrf id This command essentially looks at /proc/pid/cgroup for a "::/vrf/" entry with the VRF name following. 3. Show process ids bound to a VRF ip vrf pids NAME This command dumps the file MNT/vrf/NAME/cgroup.procs since that file shows the process ids in the particular vrf cgroup. Signed-off-by: David Ahern --- ip/Makefile | 3 +- ip/ip.c | 4 +- ip/ip_common.h| 2 + ip/ipvrf.c| 289 ++ man/man8/ip-vrf.8 | 88 + 5 files changed, 384 insertions(+), 2 deletions(-) create mode 100644 ip/ipvrf.c create mode 100644 man/man8/ip-vrf.8 diff --git a/ip/Makefile b/ip/Makefile index c8e6c6172741..1928489e7f90 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -7,7 +7,8 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \ link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \ iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \ -iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o +iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \ +ipvrf.o RTMONOBJ=rtmon.o diff --git a/ip/ip.c b/ip/ip.c index cb3adcb3f57d..07050b07592a 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -51,7 +51,8 @@ static void usage(void) " ip [ -force ] -batch filename\n" "where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n" " tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n" -" netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila }\n" +" netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |\n" +" vrf }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" "-h[uman-readable] | -iec |\n" "-f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n" @@ -99,6 +100,7 @@ static const struct cmd { { "mrule", do_multirule }, { "netns", do_netns }, { "netconf",do_ipnetconf }, + { "vrf",do_ipvrf}, { "help", do_help }, { 0 } }; diff --git a/ip/ip_common.h b/ip/ip_common.h index 3162f1ca5b2c..28763e81e4a4 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -57,6 +57,8 @@ extern int do_ipila(int argc, char **argv); int do_tcp_metrics(int argc, char **argv); int do_ipnetconf(int argc, char **argv); int do_iptoken(int argc, char **argv); +int do_ipvrf(int argc, char **argv); + int iplink_get(unsigned int flags, char *name, __u32 filt_mask); static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb) diff --git a/ip/ipvrf.c b/ip/ipvrf.c new file mode 100644 index ..c4f0e53532e2 --- /dev/null +++ b/ip/ipvrf.c @@ -0,0 +1,289 @@ +/* + * ipvrf.c "ip vrf" + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors:David Ahern + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rt_names.h" +#include "utils.h" +#include "ip_common.h" +#include "libbpf.h" +#include "bpf_util.h" + +#define CGRP_PROC_FILE "/cgroup.procs" + +static void usage(void) +{ + fprintf(stderr, "Usage: ip vrf exec [NAME] cmd ...\n"); + fprintf(stderr, " ip vrf identify [PID]\n"); + fprintf(stderr, " ip vrf pids [NAME]\n"); + + exit(-1); +} + +static int ipvrf_identify(int argc, char **argv) +{ + char path[PATH_MAX]; + char buf[4096]; + char *vrf, *end; + int fd, rc = -1; + unsigned int pid; + ssize_t n; + + if (argc < 1) + pid = getpid(); + else if (argc > 1) + invarg("Extra arguments
[iproute2 net-next 8/8] Introduce ip vrf command
'ip vrf' follows the user semnatics established by 'ip netns'. The 'ip vrf' subcommand supports 3 usages: 1. Run a command against a given vrf: ip vrf exec NAME CMD Uses the recently committed cgroup/sock BPF option. vrf directory is added to cgroup2 mount. Individual vrfs are created under it. BPF filter attached to vrf/NAME cgroup2 to set sk_bound_dev_if to the VRF device index. From there the current process (ip's pid) is addded to the cgroups.proc file and the given command is exected. In doing so all AF_INET/AF_INET6 (ipv4/ipv6) sockets are automatically bound to the VRF domain. The association is inherited parent to child allowing the command to be a shell from which other commands are run relative to the VRF. 2. Show the VRF a process is bound to: ip vrf id This command essentially looks at /proc/pid/cgroup for a "::/vrf/" entry with the VRF name following. 3. Show process ids bound to a VRF ip vrf pids NAME This command dumps the file MNT/vrf/NAME/cgroup.procs since that file shows the process ids in the particular vrf cgroup. Signed-off-by: David Ahern --- ip/Makefile | 3 +- ip/ip.c | 4 +- ip/ip_common.h| 2 + ip/ipvrf.c| 289 ++ man/man8/ip-vrf.8 | 88 + 5 files changed, 384 insertions(+), 2 deletions(-) create mode 100644 ip/ipvrf.c create mode 100644 man/man8/ip-vrf.8 diff --git a/ip/Makefile b/ip/Makefile index c8e6c6172741..1928489e7f90 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -7,7 +7,8 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \ link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \ iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \ -iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o +iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \ +ipvrf.o RTMONOBJ=rtmon.o diff --git a/ip/ip.c b/ip/ip.c index cb3adcb3f57d..07050b07592a 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -51,7 +51,8 @@ static void usage(void) " ip [ -force ] -batch filename\n" "where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n" " tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n" -" netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila }\n" +" netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |\n" +" vrf }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" "-h[uman-readable] | -iec |\n" "-f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n" @@ -99,6 +100,7 @@ static const struct cmd { { "mrule", do_multirule }, { "netns", do_netns }, { "netconf",do_ipnetconf }, + { "vrf",do_ipvrf}, { "help", do_help }, { 0 } }; diff --git a/ip/ip_common.h b/ip/ip_common.h index 3162f1ca5b2c..28763e81e4a4 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -57,6 +57,8 @@ extern int do_ipila(int argc, char **argv); int do_tcp_metrics(int argc, char **argv); int do_ipnetconf(int argc, char **argv); int do_iptoken(int argc, char **argv); +int do_ipvrf(int argc, char **argv); + int iplink_get(unsigned int flags, char *name, __u32 filt_mask); static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb) diff --git a/ip/ipvrf.c b/ip/ipvrf.c new file mode 100644 index ..c4f0e53532e2 --- /dev/null +++ b/ip/ipvrf.c @@ -0,0 +1,289 @@ +/* + * ipvrf.c "ip vrf" + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors:David Ahern + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rt_names.h" +#include "utils.h" +#include "ip_common.h" +#include "libbpf.h" +#include "bpf_util.h" + +#define CGRP_PROC_FILE "/cgroup.procs" + +static void usage(void) +{ + fprintf(stderr, "Usage: ip vrf exec [NAME] cmd ...\n"); + fprintf(stderr, " ip vrf identify [PID]\n"); + fprintf(stderr, " ip vrf pids [NAME]\n"); + + exit(-1); +} + +static int ipvrf_identify(int argc, char **argv) +{ + char path[PATH_MAX]; + char buf[4096]; + char *vrf, *end; + int fd, rc = -1; + unsigned int pid; + ssize_t n; + + if (argc < 1) + pid = getpid(); + else if (argc > 1) + invarg("Extra arguments