mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-08-14 05:16:11 +00:00
ipnetns: enable to dump nsid conversion table
This patch enables to dump/get nsid from a netns into another netns. Example: $ ./test.sh + ip netns add foo + ip netns add bar + touch /var/run/netns/init_net + mount --bind /proc/1/ns/net /var/run/netns/init_net + ip netns set init_net 11 + ip netns set foo 12 + ip netns set bar 13 + ip netns init_net (id: 11) bar (id: 13) foo (id: 12) + ip -n foo netns set init_net 21 + ip -n foo netns set foo 22 + ip -n foo netns set bar 23 + ip -n foo netns init_net (id: 21) bar (id: 23) foo (id: 22) + ip -n bar netns set init_net 31 + ip -n bar netns set foo 32 + ip -n bar netns set bar 33 + ip -n bar netns init_net (id: 31) bar (id: 33) foo (id: 32) + ip netns list-id target-nsid 12 nsid 21 current-nsid 11 (iproute2 netns name: init_net) nsid 22 current-nsid 12 (iproute2 netns name: foo) nsid 23 current-nsid 13 (iproute2 netns name: bar) + ip -n foo netns list-id target-nsid 21 nsid 11 current-nsid 21 (iproute2 netns name: init_net) nsid 12 current-nsid 22 (iproute2 netns name: foo) nsid 13 current-nsid 23 (iproute2 netns name: bar) + ip -n bar netns list-id target-nsid 33 nsid 32 nsid 32 current-nsid 32 (iproute2 netns name: foo) + ip -n bar netns list-id target-nsid 31 nsid 32 nsid 12 current-nsid 32 (iproute2 netns name: foo) + ip netns list-id nsid 13 nsid 13 (iproute2 netns name: bar) CC: Petr Oros <poros@redhat.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Tested-by: Petr Oros <poros@redhat.com> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
This commit is contained in:
parent
94ff4d6882
commit
eaefb07804
@ -71,8 +71,6 @@ int rtnl_mdbdump_req(struct rtnl_handle *rth, int family)
|
||||
__attribute__((warn_unused_result));
|
||||
int rtnl_netconfdump_req(struct rtnl_handle *rth, int family)
|
||||
__attribute__((warn_unused_result));
|
||||
int rtnl_nsiddump_req(struct rtnl_handle *rth, int family)
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
int rtnl_linkdump_req(struct rtnl_handle *rth, int fam)
|
||||
__attribute__((warn_unused_result));
|
||||
@ -85,6 +83,9 @@ int rtnl_linkdump_req_filter_fn(struct rtnl_handle *rth, int fam,
|
||||
int rtnl_fdb_linkdump_req_filter_fn(struct rtnl_handle *rth,
|
||||
req_filter_fn_t filter_fn)
|
||||
__attribute__((warn_unused_result));
|
||||
int rtnl_nsiddump_req_filter_fn(struct rtnl_handle *rth, int family,
|
||||
req_filter_fn_t filter_fn)
|
||||
__attribute__((warn_unused_result));
|
||||
int rtnl_statsdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask)
|
||||
__attribute__((warn_unused_result));
|
||||
int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req,
|
||||
|
@ -24,6 +24,7 @@ struct link_filter {
|
||||
int master;
|
||||
char *kind;
|
||||
char *slave_kind;
|
||||
int target_nsid;
|
||||
};
|
||||
|
||||
int get_operstate(const char *name);
|
||||
|
115
ip/ipnetns.c
115
ip/ipnetns.c
@ -36,7 +36,7 @@ static int usage(void)
|
||||
" ip netns pids NAME\n"
|
||||
" ip [-all] netns exec [NAME] cmd ...\n"
|
||||
" ip netns monitor\n"
|
||||
" ip netns list-id\n"
|
||||
" ip netns list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT]\n"
|
||||
"NETNSID := auto | POSITIVE-INT\n");
|
||||
exit(-1);
|
||||
}
|
||||
@ -46,6 +46,7 @@ static struct rtnl_handle rtnsh = { .fd = -1 };
|
||||
|
||||
static int have_rtnl_getnsid = -1;
|
||||
static int saved_netns = -1;
|
||||
static struct link_filter filter;
|
||||
|
||||
static int ipnetns_accept_msg(struct rtnl_ctrl_data *ctrl,
|
||||
struct nlmsghdr *n, void *arg)
|
||||
@ -294,7 +295,7 @@ int print_nsid(struct nlmsghdr *n, void *arg)
|
||||
FILE *fp = (FILE *)arg;
|
||||
struct nsid_cache *c;
|
||||
char name[NAME_MAX];
|
||||
int nsid;
|
||||
int nsid, current;
|
||||
|
||||
if (n->nlmsg_type != RTM_NEWNSID && n->nlmsg_type != RTM_DELNSID)
|
||||
return 0;
|
||||
@ -317,9 +318,22 @@ int print_nsid(struct nlmsghdr *n, void *arg)
|
||||
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
|
||||
|
||||
nsid = rta_getattr_u32(tb[NETNSA_NSID]);
|
||||
print_uint(PRINT_ANY, "nsid", "nsid %u ", nsid);
|
||||
if (nsid < 0)
|
||||
print_string(PRINT_ANY, "nsid", "nsid %s ", "not-assigned");
|
||||
else
|
||||
print_uint(PRINT_ANY, "nsid", "nsid %u ", nsid);
|
||||
|
||||
c = netns_map_get_by_nsid(nsid);
|
||||
if (tb[NETNSA_CURRENT_NSID]) {
|
||||
current = rta_getattr_u32(tb[NETNSA_CURRENT_NSID]);
|
||||
if (current < 0)
|
||||
print_string(PRINT_ANY, "current-nsid",
|
||||
"current-nsid %s ", "not-assigned");
|
||||
else
|
||||
print_uint(PRINT_ANY, "current-nsid",
|
||||
"current-nsid %u ", current);
|
||||
}
|
||||
|
||||
c = netns_map_get_by_nsid(tb[NETNSA_CURRENT_NSID] ? current : nsid);
|
||||
if (c != NULL) {
|
||||
print_string(PRINT_ANY, "name",
|
||||
"(iproute2 netns name: %s)", c->name);
|
||||
@ -340,15 +354,106 @@ int print_nsid(struct nlmsghdr *n, void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_netnsid_from_netnsid(int nsid)
|
||||
{
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct rtgenmsg g;
|
||||
char buf[1024];
|
||||
} req = {
|
||||
.n.nlmsg_len = NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct rtgenmsg))),
|
||||
.n.nlmsg_flags = NLM_F_REQUEST,
|
||||
.n.nlmsg_type = RTM_GETNSID,
|
||||
.g.rtgen_family = AF_UNSPEC,
|
||||
};
|
||||
struct nlmsghdr *answer;
|
||||
int err;
|
||||
|
||||
netns_nsid_socket_init();
|
||||
|
||||
err = addattr32(&req.n, sizeof(req), NETNSA_NSID, nsid);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (filter.target_nsid >= 0) {
|
||||
err = addattr32(&req.n, sizeof(req), NETNSA_TARGET_NSID,
|
||||
filter.target_nsid);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (rtnl_talk(&rtnsh, &req.n, &answer) < 0)
|
||||
return -2;
|
||||
|
||||
/* Validate message and parse attributes */
|
||||
if (answer->nlmsg_type == NLMSG_ERROR)
|
||||
goto err_out;
|
||||
|
||||
new_json_obj(json);
|
||||
err = print_nsid(answer, stdout);
|
||||
delete_json_obj();
|
||||
err_out:
|
||||
free(answer);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int netns_filter_req(struct nlmsghdr *nlh, int reqlen)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (filter.target_nsid >= 0) {
|
||||
err = addattr32(nlh, reqlen, NETNSA_TARGET_NSID,
|
||||
filter.target_nsid);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netns_list_id(int argc, char **argv)
|
||||
{
|
||||
int nsid = -1;
|
||||
|
||||
if (!ipnetns_have_nsid()) {
|
||||
fprintf(stderr,
|
||||
"RTM_GETNSID is not supported by the kernel.\n");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (rtnl_nsiddump_req(&rth, AF_UNSPEC) < 0) {
|
||||
filter.target_nsid = -1;
|
||||
while (argc > 0) {
|
||||
if (strcmp(*argv, "target-nsid") == 0) {
|
||||
if (filter.target_nsid >= 0)
|
||||
duparg("target-nsid", *argv);
|
||||
NEXT_ARG();
|
||||
|
||||
if (get_integer(&filter.target_nsid, *argv, 0))
|
||||
invarg("\"target-nsid\" value is invalid\n",
|
||||
*argv);
|
||||
else if (filter.target_nsid < 0)
|
||||
invarg("\"target-nsid\" value should be >= 0\n",
|
||||
argv[1]);
|
||||
} else if (strcmp(*argv, "nsid") == 0) {
|
||||
if (nsid >= 0)
|
||||
duparg("nsid", *argv);
|
||||
NEXT_ARG();
|
||||
|
||||
if (get_integer(&nsid, *argv, 0))
|
||||
invarg("\"nsid\" value is invalid\n", *argv);
|
||||
else if (nsid < 0)
|
||||
invarg("\"nsid\" value should be >= 0\n",
|
||||
argv[1]);
|
||||
} else
|
||||
usage();
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
if (nsid >= 0)
|
||||
return get_netnsid_from_netnsid(nsid);
|
||||
|
||||
if (rtnl_nsiddump_req_filter_fn(&rth, AF_UNSPEC,
|
||||
netns_filter_req) < 0) {
|
||||
perror("Cannot send dump request");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -438,12 +438,13 @@ int rtnl_netconfdump_req(struct rtnl_handle *rth, int family)
|
||||
return send(rth->fd, &req, sizeof(req), 0);
|
||||
}
|
||||
|
||||
int rtnl_nsiddump_req(struct rtnl_handle *rth, int family)
|
||||
int rtnl_nsiddump_req_filter_fn(struct rtnl_handle *rth, int family,
|
||||
req_filter_fn_t filter_fn)
|
||||
{
|
||||
struct {
|
||||
struct nlmsghdr nlh;
|
||||
struct rtgenmsg rtm;
|
||||
char buf[0] __aligned(NLMSG_ALIGNTO);
|
||||
char buf[1024];
|
||||
} req = {
|
||||
.nlh.nlmsg_len = NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct rtgenmsg))),
|
||||
.nlh.nlmsg_type = RTM_GETNSID,
|
||||
@ -451,8 +452,16 @@ int rtnl_nsiddump_req(struct rtnl_handle *rth, int family)
|
||||
.nlh.nlmsg_seq = rth->dump = ++rth->seq,
|
||||
.rtm.rtgen_family = family,
|
||||
};
|
||||
int err;
|
||||
|
||||
return send(rth->fd, &req, sizeof(req), 0);
|
||||
if (!filter_fn)
|
||||
return -EINVAL;
|
||||
|
||||
err = filter_fn(&req.nlh, sizeof(req));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return send(rth->fd, &req, req.nlh.nlmsg_len, 0);
|
||||
}
|
||||
|
||||
static int __rtnl_linkdump_req(struct rtnl_handle *rth, int family)
|
||||
|
Loading…
Reference in New Issue
Block a user