Merge branch 'master' into next

Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
David Ahern 2019-10-27 09:53:46 -07:00
commit c9dc3af42e
9 changed files with 212 additions and 46 deletions

View File

@ -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();

View File

@ -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,

View File

@ -24,6 +24,7 @@ struct link_filter {
int master;
char *kind;
char *slave_kind;
int target_nsid;
};
int get_operstate(const char *name);

View File

@ -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);
}

View File

@ -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)

View File

@ -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 "

View File

@ -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>

View File

@ -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

View File

@ -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;