Merge branch 'master' into net-next
This commit is contained in:
commit
c5ecc59f10
|
|
@ -44,5 +44,11 @@ static inline int setns(int fd, int nstype)
|
|||
|
||||
extern int netns_switch(char *netns);
|
||||
extern int netns_get_fd(const char *netns);
|
||||
extern int netns_foreach(int (*func)(char *nsname, void *arg), void *arg);
|
||||
|
||||
struct netns_func {
|
||||
int (*func)(char *nsname, void *arg);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
#endif /* __NAMESPACE_H__ */
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <asm/types.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libnetlink.h"
|
||||
#include "ll_map.h"
|
||||
|
|
@ -23,6 +24,7 @@ extern int timestamp_short;
|
|||
extern char * _SL_;
|
||||
extern int max_flush_loops;
|
||||
extern int batch_mode;
|
||||
extern bool do_all;
|
||||
|
||||
#ifndef IPPROTO_ESP
|
||||
#define IPPROTO_ESP 50
|
||||
|
|
@ -162,4 +164,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
|
|||
char **name, char **type, char **link, char **dev,
|
||||
int *group, int *index);
|
||||
|
||||
extern int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
|
||||
bool show_label);
|
||||
|
||||
#endif /* __UTILS_H__ */
|
||||
|
|
|
|||
5
ip/ip.c
5
ip/ip.c
|
|
@ -36,6 +36,7 @@ char * _SL_ = NULL;
|
|||
int force = 0;
|
||||
int max_flush_loops = 10;
|
||||
int batch_mode = 0;
|
||||
bool do_all = false;
|
||||
|
||||
struct rtnl_handle rth = { .fd = -1 };
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ static void usage(void)
|
|||
" -4 | -6 | -I | -D | -B | -0 |\n"
|
||||
" -l[oops] { maximum-addr-flush-attempts } |\n"
|
||||
" -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
|
||||
" -rc[vbuf] [size] | -n[etns] name }\n");
|
||||
" -rc[vbuf] [size] | -n[etns] name | -a[ll] }\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
|
@ -270,6 +271,8 @@ int main(int argc, char **argv)
|
|||
NEXT_ARG();
|
||||
if (netns_switch(argv[1]))
|
||||
exit(-1);
|
||||
} else if (matches(opt, "-all") == 0) {
|
||||
do_all = true;
|
||||
} else {
|
||||
fprintf(stderr, "Option \"%s\" is unknown, try \"ip -help\".\n", opt);
|
||||
exit(-1);
|
||||
|
|
|
|||
|
|
@ -970,7 +970,8 @@ struct nlmsg_chain
|
|||
struct nlmsg_list *tail;
|
||||
};
|
||||
|
||||
static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp)
|
||||
static int print_selected_addrinfo(struct ifinfomsg *ifi,
|
||||
struct nlmsg_list *ainfo, FILE *fp)
|
||||
{
|
||||
for ( ;ainfo ; ainfo = ainfo->next) {
|
||||
struct nlmsghdr *n = &ainfo->h;
|
||||
|
|
@ -982,10 +983,13 @@ static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *
|
|||
if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa)))
|
||||
return -1;
|
||||
|
||||
if (ifa->ifa_index != ifindex ||
|
||||
if (ifa->ifa_index != ifi->ifi_index ||
|
||||
(filter.family && filter.family != ifa->ifa_family))
|
||||
continue;
|
||||
|
||||
if (filter.up && !(ifi->ifi_flags&IFF_UP))
|
||||
continue;
|
||||
|
||||
print_addrinfo(NULL, n, fp);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1446,7 +1450,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
|
|||
if (no_link || (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
|
||||
struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
|
||||
if (filter.family != AF_PACKET)
|
||||
print_selected_addrinfo(ifi->ifi_index,
|
||||
print_selected_addrinfo(ifi,
|
||||
ainfo.head, stdout);
|
||||
if (res > 0 && !do_link && show_stats)
|
||||
print_link_stats(stdout, &l->h);
|
||||
|
|
|
|||
98
ip/ipnetns.c
98
ip/ipnetns.c
|
|
@ -23,10 +23,10 @@ static int usage(void)
|
|||
{
|
||||
fprintf(stderr, "Usage: ip netns list\n");
|
||||
fprintf(stderr, " ip netns add NAME\n");
|
||||
fprintf(stderr, " ip netns delete NAME\n");
|
||||
fprintf(stderr, " ip [-all] netns delete [NAME]\n");
|
||||
fprintf(stderr, " ip netns identify [PID]\n");
|
||||
fprintf(stderr, " ip netns pids NAME\n");
|
||||
fprintf(stderr, " ip netns exec NAME cmd ...\n");
|
||||
fprintf(stderr, " ip [-all] netns exec [NAME] cmd ...\n");
|
||||
fprintf(stderr, " ip netns monitor\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
|
@ -51,29 +51,10 @@ static int netns_list(int argc, char **argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int netns_exec(int argc, char **argv)
|
||||
static int cmd_exec(const char *cmd, char **argv, bool do_fork)
|
||||
{
|
||||
/* Setup the proper environment for apps that are not netns
|
||||
* aware, and execute a program in that environment.
|
||||
*/
|
||||
const char *cmd;
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "No netns name specified\n");
|
||||
return -1;
|
||||
}
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "No command specified\n");
|
||||
return -1;
|
||||
}
|
||||
cmd = argv[1];
|
||||
|
||||
if (netns_switch(argv[0]))
|
||||
return -1;
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
if (batch_mode) {
|
||||
if (do_fork) {
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
|
|
@ -91,23 +72,56 @@ static int netns_exec(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
/* ip must return the status of the child,
|
||||
* but do_cmd() will add a minus to this,
|
||||
* so let's add another one here to cancel it.
|
||||
*/
|
||||
return -WEXITSTATUS(status);
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (execvp(cmd, argv + 1) < 0)
|
||||
if (execvp(cmd, argv) < 0)
|
||||
fprintf(stderr, "exec of \"%s\" failed: %s\n",
|
||||
cmd, strerror(errno));
|
||||
cmd, strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
static int on_netns_exec(char *nsname, void *arg)
|
||||
{
|
||||
char **argv = arg;
|
||||
cmd_exec(argv[1], argv + 1, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netns_exec(int argc, char **argv)
|
||||
{
|
||||
/* Setup the proper environment for apps that are not netns
|
||||
* aware, and execute a program in that environment.
|
||||
*/
|
||||
const char *cmd;
|
||||
|
||||
if (argc < 1 && !do_all) {
|
||||
fprintf(stderr, "No netns name specified\n");
|
||||
return -1;
|
||||
}
|
||||
if ((argc < 2 && !do_all) || (argc < 1 && do_all)) {
|
||||
fprintf(stderr, "No command specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (do_all)
|
||||
return do_each_netns(on_netns_exec, --argv, 1);
|
||||
|
||||
if (netns_switch(argv[0]))
|
||||
return -1;
|
||||
|
||||
/* ip must return the status of the child,
|
||||
* but do_cmd() will add a minus to this,
|
||||
* so let's add another one here to cancel it.
|
||||
*/
|
||||
cmd = argv[1];
|
||||
return -cmd_exec(cmd, argv + 1, !!batch_mode);
|
||||
}
|
||||
|
||||
static int is_pid(const char *str)
|
||||
{
|
||||
int ch;
|
||||
|
|
@ -245,18 +259,11 @@ static int netns_identify(int argc, char **argv)
|
|||
|
||||
}
|
||||
|
||||
static int netns_delete(int argc, char **argv)
|
||||
static int on_netns_del(char *nsname, void *arg)
|
||||
{
|
||||
const char *name;
|
||||
char netns_path[MAXPATHLEN];
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "No netns name specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
name = argv[0];
|
||||
snprintf(netns_path, sizeof(netns_path), "%s/%s", NETNS_RUN_DIR, name);
|
||||
snprintf(netns_path, sizeof(netns_path), "%s/%s", NETNS_RUN_DIR, nsname);
|
||||
umount2(netns_path, MNT_DETACH);
|
||||
if (unlink(netns_path) < 0) {
|
||||
fprintf(stderr, "Cannot remove namespace file \"%s\": %s\n",
|
||||
|
|
@ -266,6 +273,19 @@ static int netns_delete(int argc, char **argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int netns_delete(int argc, char **argv)
|
||||
{
|
||||
if (argc < 1 && !do_all) {
|
||||
fprintf(stderr, "No netns name specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (do_all)
|
||||
return netns_foreach(on_netns_del, NULL);
|
||||
|
||||
return on_netns_del(argv[0], NULL);
|
||||
}
|
||||
|
||||
static int create_netns_dir(void)
|
||||
{
|
||||
/* Create the base netns directory if it doesn't exist */
|
||||
|
|
|
|||
|
|
@ -99,3 +99,25 @@ int netns_get_fd(const char *name)
|
|||
}
|
||||
return open(path, O_RDONLY);
|
||||
}
|
||||
|
||||
int netns_foreach(int (*func)(char *nsname, void *arg), void *arg)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
|
||||
dir = opendir(NETNS_RUN_DIR);
|
||||
if (!dir)
|
||||
return -1;
|
||||
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (strcmp(entry->d_name, ".") == 0)
|
||||
continue;
|
||||
if (strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (func(entry->d_name, arg))
|
||||
break;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
28
lib/utils.c
28
lib/utils.c
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
|
||||
#include "utils.h"
|
||||
#include "namespace.h"
|
||||
|
||||
int timestamp_short = 0;
|
||||
|
||||
|
|
@ -878,3 +879,30 @@ void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n)
|
|||
tstr[strlen(tstr)-1] = 0;
|
||||
fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
|
||||
}
|
||||
|
||||
static int on_netns(char *nsname, void *arg)
|
||||
{
|
||||
struct netns_func *f = arg;
|
||||
|
||||
if (netns_switch(nsname))
|
||||
return -1;
|
||||
|
||||
return f->func(nsname, f->arg);
|
||||
}
|
||||
|
||||
static int on_netns_label(char *nsname, void *arg)
|
||||
{
|
||||
printf("\nnetns: %s\n", nsname);
|
||||
return on_netns(nsname, arg);
|
||||
}
|
||||
|
||||
int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
|
||||
bool show_label)
|
||||
{
|
||||
struct netns_func nsf = { .func = func, .arg = arg };
|
||||
|
||||
if (show_label)
|
||||
return netns_foreach(on_netns_label, &nsf);
|
||||
|
||||
return netns_foreach(on_netns, &nsf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@ ip-netns \- process network namespace management
|
|||
.BR "ip netns" " { " list " } "
|
||||
|
||||
.ti -8
|
||||
.BR "ip netns" " { " add " | " delete " } "
|
||||
.B ip netns add
|
||||
.I NETNSNAME
|
||||
|
||||
.ti -8
|
||||
.B ip [-all] netns del
|
||||
.RI "[ " NETNSNAME " ]"
|
||||
|
||||
.ti -8
|
||||
.BR "ip netns identify"
|
||||
.RI "[ " PID " ]"
|
||||
|
|
@ -28,8 +32,8 @@ ip-netns \- process network namespace management
|
|||
.I NETNSNAME
|
||||
|
||||
.ti -8
|
||||
.BR "ip netns exec "
|
||||
.I NETNSNAME command ...
|
||||
.BR "ip [-all] netns exec "
|
||||
.RI "[ " NETNSNAME " ] " command ...
|
||||
|
||||
.ti -8
|
||||
.BR "ip netns monitor"
|
||||
|
|
@ -76,7 +80,7 @@ If NAME is available in /var/run/netns/ this command creates a new
|
|||
network namespace and assigns NAME.
|
||||
|
||||
.TP
|
||||
.B ip netns delete NAME - delete the name of a network namespace
|
||||
.B ip [-all] netns delete [ NAME ] - delete the name of a network namespace(s)
|
||||
.sp
|
||||
If NAME is present in /var/run/netns it is umounted and the mount
|
||||
point is removed. If this is the last user of the network namespace the
|
||||
|
|
@ -84,6 +88,10 @@ network namespace will be freed, otherwise the network namespace
|
|||
persists until it has no more users. ip netns delete may fail if
|
||||
the mount point is in use in another mount namespace.
|
||||
|
||||
If
|
||||
.B -all
|
||||
option was specified then all the network namespace names will be removed.
|
||||
|
||||
.TP
|
||||
.B ip netns identify [PID] - Report network namespaces names for process
|
||||
.sp
|
||||
|
|
@ -98,7 +106,7 @@ This command walks through proc and finds all of the process who have
|
|||
the named network namespace as their primary network namespace.
|
||||
|
||||
.TP
|
||||
.B ip netns exec NAME cmd ... - Run cmd in the named network namespace
|
||||
.B ip [-all] netns exec [ NAME ] cmd ... - Run cmd in the named network namespace
|
||||
.sp
|
||||
This command allows applications that are network namespace unaware
|
||||
to be run in something other than the default network namespace with
|
||||
|
|
@ -107,6 +115,16 @@ in the customary global locations. A network namespace and bind mounts
|
|||
are used to move files from their network namespace specific location
|
||||
to their default locations without affecting other processes.
|
||||
|
||||
If
|
||||
.B -all
|
||||
option was specified then
|
||||
.B cmd
|
||||
will be executed synchronously on the each named network namespace even if
|
||||
.B cmd
|
||||
fails on some of them. Network namespace name is printed on each
|
||||
.B cmd
|
||||
executing.
|
||||
|
||||
.TP
|
||||
.B ip netns monitor - Report as network namespace names are added and deleted
|
||||
.sp
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
|
|||
\fB\-f\fR[\fIamily\fR] {
|
||||
.BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | "
|
||||
\fB\-o\fR[\fIneline\fR] |
|
||||
\fB\-n\fR[\fIetns\fR] name }
|
||||
\fB\-n\fR[\fIetns\fR] name |
|
||||
\fB\-a\fR[\fIll\fR] }
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
|
|
@ -155,6 +156,10 @@ to
|
|||
.RI "-n[etns] " NETNS " [ " OPTIONS " ] " OBJECT " { " COMMAND " | "
|
||||
.BR help " }"
|
||||
|
||||
.TP
|
||||
.BR "\-a" , " \-all"
|
||||
executes specified command over all objects, it depends if command supports this option.
|
||||
|
||||
.SH IP - COMMAND SYNTAX
|
||||
|
||||
.SS
|
||||
|
|
|
|||
Loading…
Reference in New Issue