|
|
a4b897 |
commit f389090cd1dc2f9945c19f837ade98bd733015cb
|
|
|
a4b897 |
Author: Pavel Šimerda <psimerda@redhat.com>
|
|
|
a4b897 |
Date: Thu May 28 23:39:22 2015 +0200
|
|
|
a4b897 |
|
|
|
a4b897 |
backport selected library functions
|
|
|
a4b897 |
|
|
|
a4b897 |
diff --git a/include/libnetlink.h b/include/libnetlink.h
|
|
|
a4b897 |
index ec3d657..5dcc0c3 100644
|
|
|
a4b897 |
--- a/include/libnetlink.h
|
|
|
a4b897 |
+++ b/include/libnetlink.h
|
|
|
a4b897 |
@@ -18,6 +18,7 @@ struct rtnl_handle
|
|
|
a4b897 |
struct sockaddr_nl peer;
|
|
|
a4b897 |
__u32 seq;
|
|
|
a4b897 |
__u32 dump;
|
|
|
a4b897 |
+ FILE *dump_fp;
|
|
|
a4b897 |
};
|
|
|
a4b897 |
|
|
|
a4b897 |
extern int rcvbuf;
|
|
|
a4b897 |
@@ -68,11 +69,15 @@ extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int le
|
|
|
a4b897 |
extern int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
|
|
|
a4b897 |
int len, unsigned short flags);
|
|
|
a4b897 |
extern int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len);
|
|
|
a4b897 |
+extern struct rtattr *parse_rtattr_one(int type, struct rtattr *rta, int len);
|
|
|
a4b897 |
extern int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len);
|
|
|
a4b897 |
|
|
|
a4b897 |
#define parse_rtattr_nested(tb, max, rta) \
|
|
|
a4b897 |
(parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)))
|
|
|
a4b897 |
|
|
|
a4b897 |
+#define parse_rtattr_one_nested(type, rta) \
|
|
|
a4b897 |
+ (parse_rtattr_one(type, RTA_DATA(rta), RTA_PAYLOAD(rta)))
|
|
|
a4b897 |
+
|
|
|
a4b897 |
#define parse_rtattr_nested_compat(tb, max, rta, data, len) \
|
|
|
a4b897 |
({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
|
|
|
a4b897 |
__parse_rtattr_nested_compat(tb, max, rta, len); })
|
|
|
a4b897 |
@@ -140,5 +145,17 @@ extern int rtnl_from_file(FILE *, rtnl_filter_t handler,
|
|
|
a4b897 |
#define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg))
|
|
|
a4b897 |
#endif
|
|
|
a4b897 |
|
|
|
a4b897 |
+#ifndef NETNS_RTA
|
|
|
a4b897 |
+#define NETNS_RTA(r) \
|
|
|
a4b897 |
+ ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))))
|
|
|
a4b897 |
+#endif
|
|
|
a4b897 |
+#ifndef NETNS_PAYLOAD
|
|
|
a4b897 |
+#define NETNS_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtgenmsg))
|
|
|
a4b897 |
+#endif
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+/* User defined nlmsg_type which is used mostly for logging netlink
|
|
|
a4b897 |
+ * messages from dump file */
|
|
|
a4b897 |
+#define NLMSG_TSTAMP 15
|
|
|
a4b897 |
+
|
|
|
a4b897 |
#endif /* __LIBNETLINK_H__ */
|
|
|
a4b897 |
|
|
|
a4b897 |
diff --git a/include/namespace.h b/include/namespace.h
|
|
|
a4b897 |
new file mode 100644
|
|
|
a4b897 |
index 0000000..a2ac7dc
|
|
|
a4b897 |
--- /dev/null
|
|
|
a4b897 |
+++ b/include/namespace.h
|
|
|
a4b897 |
@@ -0,0 +1,54 @@
|
|
|
a4b897 |
+#ifndef __NAMESPACE_H__
|
|
|
a4b897 |
+#define __NAMESPACE_H__ 1
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#include <sched.h>
|
|
|
a4b897 |
+#include <sys/mount.h>
|
|
|
a4b897 |
+#include <sys/syscall.h>
|
|
|
a4b897 |
+#include <errno.h>
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#define NETNS_RUN_DIR "/var/run/netns"
|
|
|
a4b897 |
+#define NETNS_ETC_DIR "/etc/netns"
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#ifndef CLONE_NEWNET
|
|
|
a4b897 |
+#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
|
|
|
a4b897 |
+#endif
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#ifndef MNT_DETACH
|
|
|
a4b897 |
+#define MNT_DETACH 0x00000002 /* Just detach from the tree */
|
|
|
a4b897 |
+#endif /* MNT_DETACH */
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+/* sys/mount.h may be out too old to have these */
|
|
|
a4b897 |
+#ifndef MS_REC
|
|
|
a4b897 |
+#define MS_REC 16384
|
|
|
a4b897 |
+#endif
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#ifndef MS_SLAVE
|
|
|
a4b897 |
+#define MS_SLAVE (1 << 19)
|
|
|
a4b897 |
+#endif
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#ifndef MS_SHARED
|
|
|
a4b897 |
+#define MS_SHARED (1 << 20)
|
|
|
a4b897 |
+#endif
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#ifndef HAVE_SETNS
|
|
|
a4b897 |
+static inline int setns(int fd, int nstype)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+#ifdef __NR_setns
|
|
|
a4b897 |
+ return syscall(__NR_setns, fd, nstype);
|
|
|
a4b897 |
+#else
|
|
|
a4b897 |
+ errno = ENOSYS;
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+#endif
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+#endif /* HAVE_SETNS */
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+extern int netns_switch(char *netns);
|
|
|
a4b897 |
+extern int netns_get_fd(const char *netns);
|
|
|
a4b897 |
+extern int netns_foreach(int (*func)(char *nsname, void *arg), void *arg);
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+struct netns_func {
|
|
|
a4b897 |
+ int (*func)(char *nsname, void *arg);
|
|
|
a4b897 |
+ void *arg;
|
|
|
a4b897 |
+};
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#endif /* __NAMESPACE_H__ */
|
|
|
a4b897 |
diff --git a/include/rt_names.h b/include/rt_names.h
|
|
|
a4b897 |
index 37adbd3..c0ea4f9 100644
|
|
|
a4b897 |
--- a/include/rt_names.h
|
|
|
a4b897 |
+++ b/include/rt_names.h
|
|
|
a4b897 |
@@ -8,6 +8,7 @@ const char *rtnl_rtscope_n2a(int id, char *buf, int len);
|
|
|
a4b897 |
const char *rtnl_rttable_n2a(__u32 id, char *buf, int len);
|
|
|
a4b897 |
const char *rtnl_rtrealm_n2a(int id, char *buf, int len);
|
|
|
a4b897 |
const char *rtnl_dsfield_n2a(int id, char *buf, int len);
|
|
|
a4b897 |
+const char *rtnl_group_n2a(int id, char *buf, int len);
|
|
|
a4b897 |
|
|
|
a4b897 |
int rtnl_rtprot_a2n(__u32 *id, const char *arg);
|
|
|
a4b897 |
int rtnl_rtscope_a2n(__u32 *id, const char *arg);
|
|
|
a4b897 |
@@ -28,5 +29,7 @@ int ll_addr_a2n(char *lladdr, int len, const char *arg);
|
|
|
a4b897 |
const char * ll_proto_n2a(unsigned short id, char *buf, int len);
|
|
|
a4b897 |
int ll_proto_a2n(unsigned short *id, const char *buf);
|
|
|
a4b897 |
|
|
|
a4b897 |
+const char *nl_proto_n2a(int id, char *buf, int len);
|
|
|
a4b897 |
+int nl_proto_a2n(__u32 *id, const char *arg);
|
|
|
a4b897 |
|
|
|
a4b897 |
#endif
|
|
|
a4b897 |
diff --git a/include/utils.h b/include/utils.h
|
|
|
a4b897 |
index 24ff19f..ca05b02 100644
|
|
|
a4b897 |
--- a/include/utils.h
|
|
|
a4b897 |
+++ b/include/utils.h
|
|
|
a4b897 |
@@ -5,12 +5,15 @@
|
|
|
a4b897 |
#include <asm/types.h>
|
|
|
a4b897 |
#include <resolv.h>
|
|
|
a4b897 |
#include <stdlib.h>
|
|
|
a4b897 |
+#include <stdbool.h>
|
|
|
a4b897 |
|
|
|
a4b897 |
#include "libnetlink.h"
|
|
|
a4b897 |
#include "ll_map.h"
|
|
|
a4b897 |
#include "rtm_map.h"
|
|
|
a4b897 |
|
|
|
a4b897 |
extern int preferred_family;
|
|
|
a4b897 |
+extern int human_readable;
|
|
|
a4b897 |
+extern int use_iec;
|
|
|
a4b897 |
extern int show_stats;
|
|
|
a4b897 |
extern int show_details;
|
|
|
a4b897 |
extern int show_raw;
|
|
|
a4b897 |
@@ -20,6 +23,7 @@ extern int timestamp;
|
|
|
a4b897 |
extern char * _SL_;
|
|
|
a4b897 |
extern int max_flush_loops;
|
|
|
a4b897 |
extern int batch_mode;
|
|
|
a4b897 |
+extern bool do_all;
|
|
|
a4b897 |
|
|
|
a4b897 |
#ifndef IPPROTO_ESP
|
|
|
a4b897 |
#define IPPROTO_ESP 50
|
|
|
a4b897 |
@@ -151,9 +155,16 @@ int print_timestamp(FILE *fp);
|
|
|
a4b897 |
extern int cmdlineno;
|
|
|
a4b897 |
extern ssize_t getcmdline(char **line, size_t *len, FILE *in);
|
|
|
a4b897 |
extern int makeargs(char *line, char *argv[], int maxargs);
|
|
|
a4b897 |
+extern int inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6);
|
|
|
a4b897 |
|
|
|
a4b897 |
struct iplink_req;
|
|
|
a4b897 |
int iplink_parse(int argc, char **argv, struct iplink_req *req,
|
|
|
a4b897 |
char **name, char **type, char **link, char **dev,
|
|
|
a4b897 |
int *group);
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+extern int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
|
|
|
a4b897 |
+ bool show_label);
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+char *int_to_str(int val, char *buf);
|
|
|
a4b897 |
+
|
|
|
a4b897 |
#endif /* __UTILS_H__ */
|
|
|
a4b897 |
diff --git a/lib/Makefile b/lib/Makefile
|
|
|
a4b897 |
index a42b885..66f89f1 100644
|
|
|
a4b897 |
--- a/lib/Makefile
|
|
|
a4b897 |
+++ b/lib/Makefile
|
|
|
a4b897 |
@@ -1,8 +1,12 @@
|
|
|
a4b897 |
include ../Config
|
|
|
a4b897 |
|
|
|
a4b897 |
+ifeq ($(IP_CONFIG_SETNS),y)
|
|
|
a4b897 |
+ CFLAGS += -DHAVE_SETNS
|
|
|
a4b897 |
+endif
|
|
|
a4b897 |
+
|
|
|
a4b897 |
CFLAGS += -fPIC
|
|
|
a4b897 |
|
|
|
a4b897 |
-UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o
|
|
|
a4b897 |
+UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o namespace.o
|
|
|
a4b897 |
|
|
|
a4b897 |
NLOBJ=libgenl.o ll_map.o libnetlink.o
|
|
|
a4b897 |
|
|
|
a4b897 |
diff --git a/lib/namespace.c b/lib/namespace.c
|
|
|
a4b897 |
new file mode 100644
|
|
|
a4b897 |
index 0000000..c03a103
|
|
|
a4b897 |
--- /dev/null
|
|
|
a4b897 |
+++ b/lib/namespace.c
|
|
|
a4b897 |
@@ -0,0 +1,123 @@
|
|
|
a4b897 |
+/*
|
|
|
a4b897 |
+ * namespace.c
|
|
|
a4b897 |
+ *
|
|
|
a4b897 |
+ * This program is free software; you can redistribute it and/or
|
|
|
a4b897 |
+ * modify it under the terms of the GNU General Public License
|
|
|
a4b897 |
+ * as published by the Free Software Foundation; either version
|
|
|
a4b897 |
+ * 2 of the License, or (at your option) any later version.
|
|
|
a4b897 |
+ */
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#include <fcntl.h>
|
|
|
a4b897 |
+#include <dirent.h>
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+#include "utils.h"
|
|
|
a4b897 |
+#include "namespace.h"
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+static void bind_etc(const char *name)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ char etc_netns_path[MAXPATHLEN];
|
|
|
a4b897 |
+ char netns_name[MAXPATHLEN];
|
|
|
a4b897 |
+ char etc_name[MAXPATHLEN];
|
|
|
a4b897 |
+ struct dirent *entry;
|
|
|
a4b897 |
+ DIR *dir;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ snprintf(etc_netns_path, sizeof(etc_netns_path), "%s/%s", NETNS_ETC_DIR, name);
|
|
|
a4b897 |
+ dir = opendir(etc_netns_path);
|
|
|
a4b897 |
+ if (!dir)
|
|
|
a4b897 |
+ return;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ while ((entry = readdir(dir)) != NULL) {
|
|
|
a4b897 |
+ if (strcmp(entry->d_name, ".") == 0)
|
|
|
a4b897 |
+ continue;
|
|
|
a4b897 |
+ if (strcmp(entry->d_name, "..") == 0)
|
|
|
a4b897 |
+ continue;
|
|
|
a4b897 |
+ snprintf(netns_name, sizeof(netns_name), "%s/%s", etc_netns_path, entry->d_name);
|
|
|
a4b897 |
+ snprintf(etc_name, sizeof(etc_name), "/etc/%s", entry->d_name);
|
|
|
a4b897 |
+ if (mount(netns_name, etc_name, "none", MS_BIND, NULL) < 0) {
|
|
|
a4b897 |
+ fprintf(stderr, "Bind %s -> %s failed: %s\n",
|
|
|
a4b897 |
+ netns_name, etc_name, strerror(errno));
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+ closedir(dir);
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+int netns_switch(char *name)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ char net_path[MAXPATHLEN];
|
|
|
a4b897 |
+ int netns;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name);
|
|
|
a4b897 |
+ netns = open(net_path, O_RDONLY | O_CLOEXEC);
|
|
|
a4b897 |
+ if (netns < 0) {
|
|
|
a4b897 |
+ fprintf(stderr, "Cannot open network namespace \"%s\": %s\n",
|
|
|
a4b897 |
+ name, strerror(errno));
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (setns(netns, CLONE_NEWNET) < 0) {
|
|
|
a4b897 |
+ fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n",
|
|
|
a4b897 |
+ name, strerror(errno));
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (unshare(CLONE_NEWNS) < 0) {
|
|
|
a4b897 |
+ fprintf(stderr, "unshare failed: %s\n", strerror(errno));
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+ /* Don't let any mounts propagate back to the parent */
|
|
|
a4b897 |
+ if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) {
|
|
|
a4b897 |
+ fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n",
|
|
|
a4b897 |
+ strerror(errno));
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+ /* Mount a version of /sys that describes the network namespace */
|
|
|
a4b897 |
+ if (umount2("/sys", MNT_DETACH) < 0) {
|
|
|
a4b897 |
+ fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno));
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+ if (mount(name, "/sys", "sysfs", 0, NULL) < 0) {
|
|
|
a4b897 |
+ fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno));
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ /* Setup bind mounts for config files in /etc */
|
|
|
a4b897 |
+ bind_etc(name);
|
|
|
a4b897 |
+ return 0;
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+int netns_get_fd(const char *name)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ char pathbuf[MAXPATHLEN];
|
|
|
a4b897 |
+ const char *path, *ptr;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ path = name;
|
|
|
a4b897 |
+ ptr = strchr(name, '/');
|
|
|
a4b897 |
+ if (!ptr) {
|
|
|
a4b897 |
+ snprintf(pathbuf, sizeof(pathbuf), "%s/%s",
|
|
|
a4b897 |
+ NETNS_RUN_DIR, name );
|
|
|
a4b897 |
+ path = pathbuf;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+ return open(path, O_RDONLY);
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+int netns_foreach(int (*func)(char *nsname, void *arg), void *arg)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ DIR *dir;
|
|
|
a4b897 |
+ struct dirent *entry;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ dir = opendir(NETNS_RUN_DIR);
|
|
|
a4b897 |
+ if (!dir)
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ while ((entry = readdir(dir)) != NULL) {
|
|
|
a4b897 |
+ if (strcmp(entry->d_name, ".") == 0)
|
|
|
a4b897 |
+ continue;
|
|
|
a4b897 |
+ if (strcmp(entry->d_name, "..") == 0)
|
|
|
a4b897 |
+ continue;
|
|
|
a4b897 |
+ if (func(entry->d_name, arg))
|
|
|
a4b897 |
+ break;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ closedir(dir);
|
|
|
a4b897 |
+ return 0;
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
diff --git a/lib/rt_names.c b/lib/rt_names.c
|
|
|
a4b897 |
index 02f1417..c2e60de 100644
|
|
|
a4b897 |
--- a/lib/rt_names.c
|
|
|
a4b897 |
+++ b/lib/rt_names.c
|
|
|
a4b897 |
@@ -500,3 +500,104 @@ int rtnl_group_a2n(int *id, const char *arg)
|
|
|
a4b897 |
*id = i;
|
|
|
a4b897 |
return 0;
|
|
|
a4b897 |
}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+const char *rtnl_group_n2a(int id, char *buf, int len)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ struct rtnl_hash_entry *entry;
|
|
|
a4b897 |
+ int i;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (!rtnl_group_init)
|
|
|
a4b897 |
+ rtnl_group_initialize();
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ for (i=0; i<256; i++) {
|
|
|
a4b897 |
+ entry = rtnl_group_hash[i];
|
|
|
a4b897 |
+ if (entry && entry->id == id) {
|
|
|
a4b897 |
+ return entry->name;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ snprintf(buf, len, "%d", id);
|
|
|
a4b897 |
+ return buf;
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+static char *nl_proto_tab[256] = {
|
|
|
a4b897 |
+ [NETLINK_ROUTE] = "rtnl",
|
|
|
a4b897 |
+ [NETLINK_UNUSED] = "unused",
|
|
|
a4b897 |
+ [NETLINK_USERSOCK] = "usersock",
|
|
|
a4b897 |
+ [NETLINK_FIREWALL] = "fw",
|
|
|
a4b897 |
+ [NETLINK_SOCK_DIAG] = "tcpdiag",
|
|
|
a4b897 |
+ [NETLINK_NFLOG] = "nflog",
|
|
|
a4b897 |
+ [NETLINK_XFRM] = "xfrm",
|
|
|
a4b897 |
+ [NETLINK_SELINUX] = "selinux",
|
|
|
a4b897 |
+ [NETLINK_ISCSI] = "iscsi",
|
|
|
a4b897 |
+ [NETLINK_AUDIT] = "audit",
|
|
|
a4b897 |
+ [NETLINK_FIB_LOOKUP] = "fiblookup",
|
|
|
a4b897 |
+ [NETLINK_CONNECTOR] = "connector",
|
|
|
a4b897 |
+ [NETLINK_NETFILTER] = "nft",
|
|
|
a4b897 |
+ [NETLINK_IP6_FW] = "ip6fw",
|
|
|
a4b897 |
+ [NETLINK_DNRTMSG] = "dec-rt",
|
|
|
a4b897 |
+ [NETLINK_KOBJECT_UEVENT] = "uevent",
|
|
|
a4b897 |
+ [NETLINK_GENERIC] = "genl",
|
|
|
a4b897 |
+ [NETLINK_SCSITRANSPORT] = "scsi-trans",
|
|
|
a4b897 |
+ [NETLINK_ECRYPTFS] = "ecryptfs",
|
|
|
a4b897 |
+ [NETLINK_RDMA] = "rdma",
|
|
|
a4b897 |
+ [NETLINK_CRYPTO] = "crypto",
|
|
|
a4b897 |
+};
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+static int nl_proto_init;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+static void nl_proto_initialize(void)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ nl_proto_init = 1;
|
|
|
a4b897 |
+ rtnl_tab_initialize(CONFDIR "/nl_protos",
|
|
|
a4b897 |
+ nl_proto_tab, 256);
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+const char *nl_proto_n2a(int id, char *buf, int len)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ if (id < 0 || id >= 256) {
|
|
|
a4b897 |
+ snprintf(buf, len, "%u", id);
|
|
|
a4b897 |
+ return buf;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (!nl_proto_init)
|
|
|
a4b897 |
+ nl_proto_initialize();
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (nl_proto_tab[id])
|
|
|
a4b897 |
+ return nl_proto_tab[id];
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ snprintf(buf, len, "%u", id);
|
|
|
a4b897 |
+ return buf;
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+int nl_proto_a2n(__u32 *id, const char *arg)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ static char *cache = NULL;
|
|
|
a4b897 |
+ static unsigned long res;
|
|
|
a4b897 |
+ char *end;
|
|
|
a4b897 |
+ int i;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (cache && strcmp(cache, arg) == 0) {
|
|
|
a4b897 |
+ *id = res;
|
|
|
a4b897 |
+ return 0;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (!nl_proto_init)
|
|
|
a4b897 |
+ nl_proto_initialize();
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ for (i = 0; i < 256; i++) {
|
|
|
a4b897 |
+ if (nl_proto_tab[i] &&
|
|
|
a4b897 |
+ strcmp(nl_proto_tab[i], arg) == 0) {
|
|
|
a4b897 |
+ cache = nl_proto_tab[i];
|
|
|
a4b897 |
+ res = i;
|
|
|
a4b897 |
+ *id = res;
|
|
|
a4b897 |
+ return 0;
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+ }
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ res = strtoul(arg, &end, 0);
|
|
|
a4b897 |
+ if (!end || end == arg || *end || res > 255)
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+ *id = res;
|
|
|
a4b897 |
+ return 0;
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
diff --git a/lib/utils.c b/lib/utils.c
|
|
|
a4b897 |
index 0f9de02..299b485 100644
|
|
|
a4b897 |
--- a/lib/utils.c
|
|
|
a4b897 |
+++ b/lib/utils.c
|
|
|
a4b897 |
@@ -31,6 +31,7 @@
|
|
|
a4b897 |
|
|
|
a4b897 |
|
|
|
a4b897 |
#include "utils.h"
|
|
|
a4b897 |
+#include "namespace.h"
|
|
|
a4b897 |
|
|
|
a4b897 |
int get_integer(int *val, const char *arg, int base)
|
|
|
a4b897 |
{
|
|
|
a4b897 |
@@ -864,3 +865,44 @@ int makeargs(char *line, char *argv[], int maxargs)
|
|
|
a4b897 |
|
|
|
a4b897 |
return argc;
|
|
|
a4b897 |
}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+int inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ if (strchr(src, ':'))
|
|
|
a4b897 |
+ return inet_pton(AF_INET6, src, dst6);
|
|
|
a4b897 |
+ else
|
|
|
a4b897 |
+ return inet_pton(AF_INET, src, dst);
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+static int on_netns(char *nsname, void *arg)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ struct netns_func *f = arg;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (netns_switch(nsname))
|
|
|
a4b897 |
+ return -1;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ return f->func(nsname, f->arg);
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+static int on_netns_label(char *nsname, void *arg)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ printf("\nnetns: %s\n", nsname);
|
|
|
a4b897 |
+ return on_netns(nsname, arg);
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
|
|
|
a4b897 |
+ bool show_label)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ struct netns_func nsf = { .func = func, .arg = arg };
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ if (show_label)
|
|
|
a4b897 |
+ return netns_foreach(on_netns_label, &nsf;;
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+ return netns_foreach(on_netns, &nsf;;
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
+
|
|
|
a4b897 |
+char *int_to_str(int val, char *buf)
|
|
|
a4b897 |
+{
|
|
|
a4b897 |
+ sprintf(buf, "%d", val);
|
|
|
a4b897 |
+ return buf;
|
|
|
a4b897 |
+}
|
|
|
a4b897 |
diff --git a/misc/Makefile b/misc/Makefile
|
|
|
a4b897 |
index a59ff87..a516bd8 100644
|
|
|
a4b897 |
--- a/misc/Makefile
|
|
|
a4b897 |
+++ b/misc/Makefile
|
|
|
a4b897 |
@@ -5,6 +5,10 @@ TARGETS=ss nstat ifstat rtacct arpd lnstat
|
|
|
a4b897 |
|
|
|
a4b897 |
include ../Config
|
|
|
a4b897 |
|
|
|
a4b897 |
+ifeq ($(IP_CONFIG_SETNS),y)
|
|
|
a4b897 |
+ CFLAGS += -DHAVE_SETNS
|
|
|
a4b897 |
+endif
|
|
|
a4b897 |
+
|
|
|
a4b897 |
all: $(TARGETS)
|
|
|
a4b897 |
|
|
|
a4b897 |
ss: $(SSOBJ)
|