Merge branch 'master' into next
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
commit
c9dc3af42e
|
|
@ -383,6 +383,12 @@ static bool dl_no_arg(struct dl *dl)
|
|||
return dl_argc(dl) == 0;
|
||||
}
|
||||
|
||||
static void __pr_out_indent_newline(struct dl *dl)
|
||||
{
|
||||
if (!g_indent_newline && !dl->json_output)
|
||||
pr_out(" ");
|
||||
}
|
||||
|
||||
static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
|
||||
[DEVLINK_ATTR_BUS_NAME] = MNL_TYPE_NUL_STRING,
|
||||
[DEVLINK_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING,
|
||||
|
|
@ -1852,14 +1858,11 @@ static void pr_out_port_handle_end(struct dl *dl)
|
|||
|
||||
static void pr_out_str(struct dl *dl, const char *name, const char *val)
|
||||
{
|
||||
if (dl->json_output) {
|
||||
__pr_out_indent_newline(dl);
|
||||
if (dl->json_output)
|
||||
jsonw_string_field(dl->jw, name, val);
|
||||
} else {
|
||||
if (g_indent_newline)
|
||||
pr_out("%s %s", name, val);
|
||||
else
|
||||
pr_out(" %s %s", name, val);
|
||||
}
|
||||
else
|
||||
pr_out("%s %s", name, val);
|
||||
}
|
||||
|
||||
static void pr_out_bool(struct dl *dl, const char *name, bool val)
|
||||
|
|
@ -1872,53 +1875,50 @@ static void pr_out_bool(struct dl *dl, const char *name, bool val)
|
|||
|
||||
static void pr_out_uint(struct dl *dl, const char *name, unsigned int val)
|
||||
{
|
||||
if (dl->json_output) {
|
||||
__pr_out_indent_newline(dl);
|
||||
if (dl->json_output)
|
||||
jsonw_uint_field(dl->jw, name, val);
|
||||
} else {
|
||||
if (g_indent_newline)
|
||||
pr_out("%s %u", name, val);
|
||||
else
|
||||
pr_out(" %s %u", name, val);
|
||||
}
|
||||
else
|
||||
pr_out("%s %u", name, val);
|
||||
}
|
||||
|
||||
static void pr_out_u64(struct dl *dl, const char *name, uint64_t val)
|
||||
{
|
||||
__pr_out_indent_newline(dl);
|
||||
if (val == (uint64_t) -1)
|
||||
return pr_out_str(dl, name, "unlimited");
|
||||
|
||||
if (dl->json_output) {
|
||||
if (dl->json_output)
|
||||
jsonw_u64_field(dl->jw, name, val);
|
||||
} else {
|
||||
if (g_indent_newline)
|
||||
pr_out("%s %"PRIu64, name, val);
|
||||
else
|
||||
pr_out(" %s %"PRIu64, name, val);
|
||||
}
|
||||
else
|
||||
pr_out("%s %"PRIu64, name, val);
|
||||
}
|
||||
|
||||
static void pr_out_bool_value(struct dl *dl, bool value)
|
||||
{
|
||||
__pr_out_indent_newline(dl);
|
||||
if (dl->json_output)
|
||||
jsonw_bool(dl->jw, value);
|
||||
else
|
||||
pr_out(" %s", value ? "true" : "false");
|
||||
pr_out("%s", value ? "true" : "false");
|
||||
}
|
||||
|
||||
static void pr_out_uint_value(struct dl *dl, unsigned int value)
|
||||
{
|
||||
__pr_out_indent_newline(dl);
|
||||
if (dl->json_output)
|
||||
jsonw_uint(dl->jw, value);
|
||||
else
|
||||
pr_out(" %u", value);
|
||||
pr_out("%u", value);
|
||||
}
|
||||
|
||||
static void pr_out_uint64_value(struct dl *dl, uint64_t value)
|
||||
{
|
||||
__pr_out_indent_newline(dl);
|
||||
if (dl->json_output)
|
||||
jsonw_u64(dl->jw, value);
|
||||
else
|
||||
pr_out(" %"PRIu64, value);
|
||||
pr_out("%"PRIu64, value);
|
||||
}
|
||||
|
||||
static bool is_binary_eol(int i)
|
||||
|
|
@ -1945,18 +1945,20 @@ static void pr_out_binary_value(struct dl *dl, uint8_t *data, uint32_t len)
|
|||
|
||||
static void pr_out_str_value(struct dl *dl, const char *value)
|
||||
{
|
||||
__pr_out_indent_newline(dl);
|
||||
if (dl->json_output)
|
||||
jsonw_string(dl->jw, value);
|
||||
else
|
||||
pr_out(" %s", value);
|
||||
pr_out("%s", value);
|
||||
}
|
||||
|
||||
static void pr_out_name(struct dl *dl, const char *name)
|
||||
{
|
||||
__pr_out_indent_newline(dl);
|
||||
if (dl->json_output)
|
||||
jsonw_name(dl->jw, name);
|
||||
else
|
||||
pr_out(" %s:", name);
|
||||
pr_out("%s:", name);
|
||||
}
|
||||
|
||||
static void pr_out_region_chunk_start(struct dl *dl, uint64_t addr)
|
||||
|
|
@ -6142,14 +6144,12 @@ static void pr_out_region_handle_end(struct dl *dl)
|
|||
|
||||
static void pr_out_region_snapshots_start(struct dl *dl, bool array)
|
||||
{
|
||||
__pr_out_indent_newline(dl);
|
||||
if (dl->json_output) {
|
||||
jsonw_name(dl->jw, "snapshot");
|
||||
jsonw_start_array(dl->jw);
|
||||
} else {
|
||||
if (g_indent_newline)
|
||||
pr_out("snapshot %s", array ? "[" : "");
|
||||
else
|
||||
pr_out(" snapshot %s", array ? "[" : "");
|
||||
pr_out("snapshot %s", array ? "[" : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6684,7 +6684,7 @@ static void pr_out_health(struct dl *dl, struct nlattr **tb_health)
|
|||
|
||||
pr_out_handle_start_arr(dl, tb_health);
|
||||
|
||||
pr_out_str(dl, "name",
|
||||
pr_out_str(dl, "reporter",
|
||||
mnl_attr_get_str(tb[DEVLINK_ATTR_HEALTH_REPORTER_NAME]));
|
||||
if (!dl->json_output) {
|
||||
__pr_out_newline();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -2364,7 +2364,6 @@ Commands:
|
|||
.BI dev " NAME " (default)
|
||||
.I NAME
|
||||
specifies the network device to show.
|
||||
If this argument is omitted all devices in the default group are listed.
|
||||
|
||||
.TP
|
||||
.BI group " GROUP "
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ ip-netns \- process network namespace management
|
|||
.B ip netns set
|
||||
.I NETNSNAME NETNSID
|
||||
|
||||
.ti -8
|
||||
.IR NETNSID " := " auto " | " POSITIVE-INT
|
||||
|
||||
.ti -8
|
||||
.BR "ip netns identify"
|
||||
.RI "[ " PID " ]"
|
||||
|
|
@ -48,6 +51,7 @@ ip-netns \- process network namespace management
|
|||
|
||||
.ti -8
|
||||
.BR "ip netns list-id"
|
||||
.RI "[ target-nsid " POSITIVE-INT " ] [ nsid " POSITIVE-INT " ]"
|
||||
|
||||
.SH DESCRIPTION
|
||||
A network namespace is logically another copy of the network stack,
|
||||
|
|
@ -193,12 +197,28 @@ This command watches network namespace name addition and deletion events
|
|||
and prints a line for each event it sees.
|
||||
|
||||
.TP
|
||||
.B ip netns list-id - list network namespace ids (nsid)
|
||||
.B ip netns list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT] - list network namespace ids (nsid)
|
||||
.sp
|
||||
Network namespace ids are used to identify a peer network namespace. This
|
||||
command displays nsid of the current network namespace and provides the
|
||||
command displays nsids of the current network namespace and provides the
|
||||
corresponding iproute2 netns name (from /var/run/netns) if any.
|
||||
|
||||
The
|
||||
.B target-nsid
|
||||
option enables to display nsids of the specified network namespace instead of the current network
|
||||
namespace. This
|
||||
.B target-nsid
|
||||
is a nsid from the current network namespace.
|
||||
|
||||
The
|
||||
.B nsid
|
||||
option enables to display only this nsid. It is a nsid from the current network namespace. In
|
||||
combination with the
|
||||
.B target-nsid
|
||||
option, it enables to convert a specific nsid from the current network namespace to a nsid of the
|
||||
.B target-nsid
|
||||
network namespace.
|
||||
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
ip netns list
|
||||
|
|
@ -215,6 +235,31 @@ ip netns exec vpn ip link set lo up
|
|||
.RS
|
||||
Bring up the loopback interface in the vpn network namespace.
|
||||
.RE
|
||||
.PP
|
||||
ip netns add foo
|
||||
.br
|
||||
ip netns add bar
|
||||
.br
|
||||
ip netns set foo 12
|
||||
.br
|
||||
ip netns set bar 13
|
||||
.br
|
||||
ip -n foo netns set foo 22
|
||||
.br
|
||||
ip -n foo netns set bar 23
|
||||
.br
|
||||
ip -n bar netns set foo 32
|
||||
.br
|
||||
ip -n bar netns set bar 33
|
||||
.br
|
||||
ip netns list-id target-nsid 12
|
||||
.RS
|
||||
Shows the list of nsids from the network namespace foo.
|
||||
.RE
|
||||
ip netns list-id target-nsid 12 nsid 13
|
||||
.RS
|
||||
Get nsid of bar from the network namespace foo (result is 23).
|
||||
.RE
|
||||
|
||||
.SH SEE ALSO
|
||||
.br
|
||||
|
|
@ -222,3 +267,5 @@ Bring up the loopback interface in the vpn network namespace.
|
|||
|
||||
.SH AUTHOR
|
||||
Original Manpage by Eric W. Biederman
|
||||
.br
|
||||
Manpage revised by Nicolas Dichtel <nicolas.dichtel@6wind.com>
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
|
|||
.IR TUNNEL_ID
|
||||
.B dst
|
||||
.IR REMOTE_IP " [ "
|
||||
.B src
|
||||
.IR SRC " ] ["
|
||||
.B tos
|
||||
.IR TOS " ] ["
|
||||
.B ttl
|
||||
|
|
@ -740,11 +742,13 @@ is a set of encapsulation attributes specific to the
|
|||
.I TUNNEL_ID
|
||||
.B dst
|
||||
.IR REMOTE_IP " [ "
|
||||
.B src
|
||||
.IR SRC " ] ["
|
||||
.B tos
|
||||
.IR TOS " ] ["
|
||||
.B ttl
|
||||
.IR TTL " ] [ "
|
||||
.BR key " ] [" csum " ] [ " seq " ] "
|
||||
.BR key " ] [ " csum " ] [ " seq " ] "
|
||||
.in -2
|
||||
.sp
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
|
|||
return -1;
|
||||
|
||||
if (!matches(*argv, "gact"))
|
||||
NEXT_ARG_FWD();
|
||||
NEXT_ARG();
|
||||
/* we're binding existing gact action to filter by index. */
|
||||
if (!matches(*argv, "index"))
|
||||
goto skip_args;
|
||||
|
|
|
|||
Loading…
Reference in New Issue