* [iproute2-next v3 1/2] tipc: JSON support for showing nametable
From: Hoang Le @ 2018-06-12 2:32 UTC (permalink / raw)
To: netdev, tipc-discussion
Add json output support for nametable show
Example output:
$tipc -j -p nametable show
[ {
"type": 0,
"lower": 16781313,
"upper": 16781313,
"scope": "zone",
"port": 0,
"node": ""
},{
"type": 0,
"lower": 16781416,
"upper": 16781416,
"scope": "cluster",
"port": 0,
"node": ""
} ]
v2:
Replace variable 'json_flag' by 'json' declared in include/utils.h
Add new parameter '-pretty' to support pretty output
v3:
Update manual page
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Hoang Le <hoang.h.le@dektech.com.au>
---
man/man8/tipc-nametable.8 | 10 ++++++++++
man/man8/tipc.8 | 9 +++++++++
tipc/nametable.c | 31 ++++++++++++++++++++++---------
tipc/tipc.c | 20 +++++++++++++++++++-
4 files changed, 60 insertions(+), 10 deletions(-)
diff --git a/man/man8/tipc-nametable.8 b/man/man8/tipc-nametable.8
index 4bcefe47f6b1..b187d25e1e1f 100644
--- a/man/man8/tipc-nametable.8
+++ b/man/man8/tipc-nametable.8
@@ -18,6 +18,16 @@ tipc-nametable \- show TIPC nametable
Options (flags) that can be passed anywhere in the command chain.
.TP
.BR "\-h" , " --help"
+
+.TP
+.BR "\-j", " \-json"
+Output results in JavaScript Object Notation (JSON).
+
+.TP
+.BR "\-p", " \-pretty"
+The default JSON format is compact and more efficient to parse but hard for most users to read.
+This flag adds indentation for readability.
+
Show help about last valid command. For example
.B tipc nametable --help
will show nametable help and
diff --git a/man/man8/tipc.8 b/man/man8/tipc.8
index 32943fa50b23..6706cca12427 100644
--- a/man/man8/tipc.8
+++ b/man/man8/tipc.8
@@ -40,6 +40,15 @@ will show bearer help and
.B tipc --help
will show general help. The position of the option in the string is irrelevant.
+.TP
+.BR "\-j", " \-json"
+Output results in JavaScript Object Notation (JSON).
+
+.TP
+.BR "\-p", " \-pretty"
+The default JSON format is compact and more efficient to parse but hard for most users to read.
+This flag adds indentation for readability.
+
.SH COMMANDS
.TP
diff --git a/tipc/nametable.c b/tipc/nametable.c
index ae73dfa5f8b9..eb4bd0bda835 100644
--- a/tipc/nametable.c
+++ b/tipc/nametable.c
@@ -21,6 +21,7 @@
#include "msg.h"
#include "nametable.h"
#include "misc.h"
+#include "utils.h"
#define PORTID_STR_LEN 45 /* Four u32 and five delimiter chars */
@@ -46,7 +47,7 @@ static int nametable_show_cb(const struct nlmsghdr *nlh, void *data)
if (!publ[TIPC_NLA_NAME_TABLE_PUBL])
return MNL_CB_ERROR;
- if (!*iteration)
+ if (!*iteration && !is_json_context())
printf("%-10s %-10s %-10s %-8s %-10s %-33s\n",
"Type", "Lower", "Upper", "Scope", "Port",
"Node");
@@ -54,13 +55,20 @@ static int nametable_show_cb(const struct nlmsghdr *nlh, void *data)
hash2nodestr(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE]), str);
- printf("%-10u %-10u %-10u %-8s %-10u %s\n",
- mnl_attr_get_u32(publ[TIPC_NLA_PUBL_TYPE]),
- mnl_attr_get_u32(publ[TIPC_NLA_PUBL_LOWER]),
- mnl_attr_get_u32(publ[TIPC_NLA_PUBL_UPPER]),
- scope[mnl_attr_get_u32(publ[TIPC_NLA_PUBL_SCOPE])],
- mnl_attr_get_u32(publ[TIPC_NLA_PUBL_REF]),
- str);
+ open_json_object(NULL);
+ print_uint(PRINT_ANY, "type", "%-10u",
+ mnl_attr_get_u32(publ[TIPC_NLA_PUBL_TYPE]));
+ print_uint(PRINT_ANY, "lower", "%-10u",
+ mnl_attr_get_u32(publ[TIPC_NLA_PUBL_LOWER]));
+ print_uint(PRINT_ANY, "upper", "%-10u",
+ mnl_attr_get_u32(publ[TIPC_NLA_PUBL_UPPER]));
+ print_string(PRINT_ANY, "scope", "%-8s",
+ scope[mnl_attr_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]);
+ print_uint(PRINT_ANY, "port", "%-10u",
+ mnl_attr_get_u32(publ[TIPC_NLA_PUBL_REF]));
+ print_string(PRINT_ANY, "node", "%s", str);
+ print_string(PRINT_FP, NULL, "\n", "");
+ close_json_object();
return MNL_CB_OK;
}
@@ -70,6 +78,7 @@ static int cmd_nametable_show(struct nlmsghdr *nlh, const struct cmd *cmd,
{
int iteration = 0;
char buf[MNL_SOCKET_BUFFER_SIZE];
+ int rc = 0;
if (help_flag) {
fprintf(stderr, "Usage: %s nametable show\n", cmdl->argv[0]);
@@ -81,7 +90,11 @@ static int cmd_nametable_show(struct nlmsghdr *nlh, const struct cmd *cmd,
return -1;
}
- return msg_dumpit(nlh, nametable_show_cb, &iteration);
+ new_json_obj(json);
+ rc = msg_dumpit(nlh, nametable_show_cb, &iteration);
+ delete_json_obj();
+
+ return rc;
}
void cmd_nametable_help(struct cmdl *cmdl)
diff --git a/tipc/tipc.c b/tipc/tipc.c
index 600d5e2a160f..f85ddee0e278 100644
--- a/tipc/tipc.c
+++ b/tipc/tipc.c
@@ -24,6 +24,8 @@
#include "cmdl.h"
int help_flag;
+int json;
+int pretty;
static void about(struct cmdl *cmdl)
{
@@ -33,6 +35,8 @@ static void about(struct cmdl *cmdl)
"\n"
"Options:\n"
" -h, --help \t\tPrint help for last given command\n"
+ " -j, --json \t\tJson format printouts\n"
+ " -p, --pretty \t\tpretty print\n"
"\n"
"Commands:\n"
" bearer - Show or modify bearers\n"
@@ -53,6 +57,8 @@ int main(int argc, char *argv[])
const struct cmd cmd = {"tipc", NULL, about};
struct option long_options[] = {
{"help", no_argument, 0, 'h'},
+ {"json", no_argument, 0, 'j'},
+ {"pretty", no_argument, 0, 'p'},
{0, 0, 0, 0}
};
const struct cmd cmds[] = {
@@ -69,7 +75,7 @@ int main(int argc, char *argv[])
do {
int option_index = 0;
- i = getopt_long(argc, argv, "h", long_options, &option_index);
+ i = getopt_long(argc, argv, "hjp", long_options, &option_index);
switch (i) {
case 'h':
@@ -79,6 +85,18 @@ int main(int argc, char *argv[])
*/
help_flag = 1;
break;
+ case 'j':
+ /*
+ * Enable json format printouts
+ */
+ json = 1;
+ break;
+ case 'p':
+ /*
+ * Enable json pretty output
+ */
+ pretty = 1;
+ break;
case -1:
/* End of options */
break;
--
2.7.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [iproute2-next v3 2/2] tipc: JSON support for tipc link printouts
From: Hoang Le @ 2018-06-12 2:32 UTC (permalink / raw)
To: netdev, tipc-discussion
In-Reply-To: <1528770749-10415-1-git-send-email-hoang.h.le@dektech.com.au>
Add json output support for tipc link command
Example output:
$tipc -j -p link list
[ {
"broadcast-link": "up",
"1.1.1:bridge-1.1.104:eth0": "up",
"1.1.1:bridge-1.1.105:eth0": "up",
"1.1.1:bridge-1.1.106:eth0": "up"
} ]
--------------------
$tipc -j -p link stat show link broadcast-link
[ {
"link": "broadcast-link",
"window": 50,
"rx packets": {
"rx packets": 0,
"fragments": 0,
"fragmented": 0,
"bundles": 0,
"bundled": 0
},
"tx packets": {
"tx packets": 0,
"fragments": 0,
"fragmented": 0,
"bundles": 0,
"bundled": 0
},
"rx naks": {
"rx naks": 0,
"defs": 0,
"dups": 0
},
"tx naks": {
"tx naks": 0,
"acks": 0,
"retrans": 0
},
"congestion link": 0,
"send queue max": 0,
"avg": 0
} ]
v2:
Replace variable 'json_flag' by 'json' declared in include/utils.h
v3:
Update manual page
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Hoang Le <hoang.h.le@dektech.com.au>
---
man/man8/tipc-link.8 | 10 ++
tipc/link.c | 414 +++++++++++++++++++++++++++++++++------------------
2 files changed, 282 insertions(+), 142 deletions(-)
diff --git a/man/man8/tipc-link.8 b/man/man8/tipc-link.8
index fee283e5cfff..01afa1c3ad9f 100644
--- a/man/man8/tipc-link.8
+++ b/man/man8/tipc-link.8
@@ -71,6 +71,16 @@ Show help about last valid command. For example
will show link help and
.B tipc --help
will show general help. The position of the option in the string is irrelevant.
+
+.TP
+.BR "\-j", " \-json"
+Output results in JavaScript Object Notation (JSON).
+
+.TP
+.BR "\-p", " \-pretty"
+The default JSON format is compact and more efficient to parse but hard for most users to read.
+This flag adds indentation for readability.
+
.SH DESCRIPTION
.SS Link statistics
diff --git a/tipc/link.c b/tipc/link.c
index 02f14aadefa6..26d1293f121a 100644
--- a/tipc/link.c
+++ b/tipc/link.c
@@ -23,6 +23,11 @@
#include "msg.h"
#include "link.h"
#include "bearer.h"
+#include "utils.h"
+
+#define PRIORITY_STR "priority"
+#define TOLERANCE_STR "tolerance"
+#define WINDOW_STR "window"
static int link_list_cb(const struct nlmsghdr *nlh, void *data)
{
@@ -38,13 +43,14 @@ static int link_list_cb(const struct nlmsghdr *nlh, void *data)
if (!attrs[TIPC_NLA_LINK_NAME])
return MNL_CB_ERROR;
- printf("%s: ", mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]));
-
+ print_string(PRINT_FP, NULL, "%s: ",
+ mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]));
if (attrs[TIPC_NLA_LINK_UP])
- printf("up\n");
+ print_string(PRINT_ANY,
+ mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]),"%s\n", "up");
else
- printf("down\n");
-
+ print_string(PRINT_ANY,
+ mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]), "%s\n", "down");
return MNL_CB_OK;
}
@@ -52,6 +58,7 @@ static int cmd_link_list(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
+ int err = 0;
if (help_flag) {
fprintf(stderr, "Usage: %s link list\n", cmdl->argv[0]);
@@ -64,7 +71,12 @@ static int cmd_link_list(struct nlmsghdr *nlh, const struct cmd *cmd,
return -1;
}
- return msg_dumpit(nlh, link_list_cb, NULL);
+ new_json_obj(json);
+ open_json_object(NULL);
+ err = msg_dumpit(nlh, link_list_cb, NULL);
+ close_json_object();
+ delete_json_obj();
+ return err;
}
static int link_get_cb(const struct nlmsghdr *nlh, void *data)
@@ -87,8 +99,23 @@ static int link_get_cb(const struct nlmsghdr *nlh, void *data)
if (!props[*prop])
return MNL_CB_ERROR;
- printf("%u\n", mnl_attr_get_u32(props[*prop]));
-
+ new_json_obj(json);
+ open_json_object(NULL);
+ switch (*prop) {
+ case TIPC_NLA_PROP_PRIO:
+ print_uint(PRINT_ANY, PRIORITY_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
+ break;
+ case TIPC_NLA_PROP_TOL:
+ print_uint(PRINT_ANY, TOLERANCE_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
+ break;
+ case TIPC_NLA_PROP_WIN:
+ print_uint(PRINT_ANY, WINDOW_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
+ break;
+ default:
+ break;
+ }
+ close_json_object();
+ delete_json_obj();
return MNL_CB_OK;
}
@@ -103,11 +130,11 @@ static int cmd_link_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
{ NULL }
};
- if (strcmp(cmd->cmd, "priority") == 0)
+ if (strcmp(cmd->cmd, PRIORITY_STR) == 0)
prop = TIPC_NLA_PROP_PRIO;
- else if ((strcmp(cmd->cmd, "tolerance") == 0))
+ else if ((strcmp(cmd->cmd, TOLERANCE_STR) == 0))
prop = TIPC_NLA_PROP_TOL;
- else if ((strcmp(cmd->cmd, "window") == 0))
+ else if ((strcmp(cmd->cmd, WINDOW_STR) == 0))
prop = TIPC_NLA_PROP_WIN;
else
return -EINVAL;
@@ -150,9 +177,9 @@ static int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
const struct cmd cmds[] = {
- { "priority", cmd_link_get_prop, cmd_link_get_help },
- { "tolerance", cmd_link_get_prop, cmd_link_get_help },
- { "window", cmd_link_get_prop, cmd_link_get_help },
+ { PRIORITY_STR, cmd_link_get_prop, cmd_link_get_help },
+ { TOLERANCE_STR, cmd_link_get_prop, cmd_link_get_help },
+ { WINDOW_STR, cmd_link_get_prop, cmd_link_get_help },
{ NULL }
};
@@ -211,109 +238,178 @@ static uint32_t perc(uint32_t count, uint32_t total)
return (count * 100 + (total / 2)) / total;
}
-static int _show_link_stat(struct nlattr *attrs[], struct nlattr *prop[],
- struct nlattr *stats[])
+static int _show_link_stat(const char *name, struct nlattr *attrs[],
+ struct nlattr *prop[], struct nlattr *stats[])
{
uint32_t proft;
+ open_json_object(NULL);
+
+ print_string(PRINT_ANY, "link", "\nLink <%s>\n", name);
+ print_string(PRINT_JSON, "state", "", NULL);
+ open_json_array(PRINT_JSON, NULL);
if (attrs[TIPC_NLA_LINK_ACTIVE])
- printf(" ACTIVE");
+ print_string(PRINT_ANY, NULL, " %s", "ACTIVE");
else if (attrs[TIPC_NLA_LINK_UP])
- printf(" STANDBY");
+ print_string(PRINT_ANY, NULL, " %s", "STANDBY");
else
- printf(" DEFUNCT");
-
- printf(" MTU:%u Priority:%u Tolerance:%u ms Window:%u packets\n",
- mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU]),
- mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO]),
- mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL]),
- mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN]));
-
- printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
- mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) -
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));
-
- printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
- mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) -
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));
+ print_string(PRINT_ANY, NULL, " %s", "DEFUNCT");
+ close_json_array(PRINT_JSON, NULL);
+
+ print_uint(PRINT_ANY, "mtu", " MTU:%u",
+ mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU]));
+ print_uint(PRINT_ANY, PRIORITY_STR, " Priority:%u",
+ mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO]));
+ print_uint(PRINT_ANY, TOLERANCE_STR, " Tolerance:%u ms",
+ mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL]));
+ print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n",
+ mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN]));
+
+ open_json_object("rx packets");
+ print_uint(PRINT_ANY, "rx packets", " RX packets:%u",
+ mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) -
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]));
+ print_uint(PRINT_ANY, "fragments", " fragments:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]));
+ print_uint(PRINT_ANY, "fragmented", "/%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]));
+ print_uint(PRINT_ANY, "bundles", " bundles:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]));
+ print_uint(PRINT_ANY, "bundled", "/%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));
+ close_json_object();
+
+ open_json_object("tx packets");
+ print_uint(PRINT_ANY, "tx packets", " TX packets:%u",
+ mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) -
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]));
+ print_uint(PRINT_ANY, "fragments", " fragments:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]));
+ print_uint(PRINT_ANY, "fragmented", "/%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]));
+ print_uint(PRINT_ANY, "bundles", " bundles:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]));
+ print_uint(PRINT_ANY, "bundled", "/%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));
+ close_json_object();
proft = mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]);
- printf(" TX profile sample:%u packets average:%u octets\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft);
-
- printf(" 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% -16384:%u%% -32768:%u%% -66000:%u%%\n",
- perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft),
- perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft),
- perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft),
- perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft),
- perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft),
- perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft),
- perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft));
-
- printf(" RX states:%u probes:%u naks:%u defs:%u dups:%u\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));
-
- printf(" TX states:%u probes:%u naks:%u acks:%u dups:%u\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));
-
- printf(" Congestion link:%u Send queue max:%u avg:%u\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));
-
+ print_uint(PRINT_ANY, "tx profile sample", " TX profile sample:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]));
+ print_uint(PRINT_ANY, "packets average", " packets average:%u octets\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft);
+
+ print_uint(PRINT_ANY, "0-64", " 0-64:%u%%",
+ perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft));
+ print_uint(PRINT_ANY, "-256", " -256:%u%%",
+ perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft));
+ print_uint(PRINT_ANY, "-1024", " -1024:%u%%",
+ perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft));
+ print_uint(PRINT_ANY, "-4096", " -4096:%u%%",
+ perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft));
+ print_uint(PRINT_ANY, "-16384", " -16384:%u%%",
+ perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft));
+ print_uint(PRINT_ANY, "-32768", " -32768:%u%%",
+ perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft));
+ print_uint(PRINT_ANY, "-66000", " -66000:%u%%\n",
+ perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft));
+
+ open_json_object("rx states");
+ print_uint(PRINT_ANY, "rx states", " RX states:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES]));
+ print_uint(PRINT_ANY, "probes", " probes:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]));
+ print_uint(PRINT_ANY, "naks", " naks:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]));
+ print_uint(PRINT_ANY, "defs", " defs:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]));
+ print_uint(PRINT_ANY, "dups", " dups:%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));
+ close_json_object();
+
+ open_json_object("tx states");
+ print_uint(PRINT_ANY, "tx states", " TX states:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES]));
+ print_uint(PRINT_ANY, "probes", " probes:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]));
+ print_uint(PRINT_ANY, "naks", " naks:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]));
+ print_uint(PRINT_ANY, "acks", " acks:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]));
+ print_uint(PRINT_ANY, "retrans", " retrans:%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));
+ close_json_object();
+
+ print_uint(PRINT_ANY, "congestion link", " Congestion link:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]));
+ print_uint(PRINT_ANY, "send queue max", " Send queue max:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]));
+ print_uint(PRINT_ANY, "avg", " avg:%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));
+
+ close_json_object();
return MNL_CB_OK;
}
-static int _show_bc_link_stat(struct nlattr *prop[], struct nlattr *stats[])
+static int _show_bc_link_stat(const char *name, struct nlattr *prop[],
+ struct nlattr *stats[])
{
- printf(" Window:%u packets\n",
- mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN]));
-
- printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));
-
- printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));
-
- printf(" RX naks:%u defs:%u dups:%u\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));
-
- printf(" TX naks:%u acks:%u dups:%u\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));
-
- printf(" Congestion link:%u Send queue max:%u avg:%u\n",
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]),
- mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));
+ open_json_object(NULL);
+ print_string(PRINT_ANY, "link", "Link <%s>\n", name);
+ print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n",
+ mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN]));
+
+ open_json_object("rx packets");
+ print_uint(PRINT_ANY, "rx packets", " RX packets:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]));
+ print_uint(PRINT_ANY, "fragments", " fragments:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]));
+ print_uint(PRINT_ANY, "fragmented", "/%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]));
+ print_uint(PRINT_ANY, "bundles", " bundles:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]));
+ print_uint(PRINT_ANY, "bundled", "/%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));
+ close_json_object();
+
+ open_json_object("tx packets");
+ print_uint(PRINT_ANY, "tx packets", " TX packets:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]));
+ print_uint(PRINT_ANY, "fragments", " fragments:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]));
+ print_uint(PRINT_ANY, "fragmented", "/%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]));
+ print_uint(PRINT_ANY, "bundles", " bundles:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]));
+ print_uint(PRINT_ANY, "bundled", "/%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));
+ close_json_object();
+
+ open_json_object("rx naks");
+ print_uint(PRINT_ANY, "rx naks", " RX naks:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]));
+ print_uint(PRINT_ANY, "defs", " defs:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]));
+ print_uint(PRINT_ANY, "dups", " dups:%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));
+ close_json_object();
+
+ open_json_object("tx naks");
+ print_uint(PRINT_ANY, "tx naks", " TX naks:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]));
+ print_uint(PRINT_ANY, "acks", " acks:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]));
+ print_uint(PRINT_ANY, "retrans", " retrans:%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));
+ close_json_object();
+
+ print_uint(PRINT_ANY, "congestion link", " Congestion link:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]));
+ print_uint(PRINT_ANY, "send queue max", " Send queue max:%u",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]));
+ print_uint(PRINT_ANY, "avg", " avg:%u\n",
+ mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));
+ close_json_object();
return MNL_CB_OK;
}
@@ -347,13 +443,10 @@ static int link_stat_show_cb(const struct nlmsghdr *nlh, void *data)
return MNL_CB_OK;
if (attrs[TIPC_NLA_LINK_BROADCAST]) {
- printf("Link <%s>\n", name);
- return _show_bc_link_stat(prop, stats);
+ return _show_bc_link_stat(name, prop, stats);
}
- printf("\nLink <%s>\n", name);
-
- return _show_link_stat(attrs, prop, stats);
+ return _show_link_stat(name, attrs, prop, stats);
}
static void cmd_link_stat_show_help(struct cmdl *cmdl)
@@ -372,6 +465,7 @@ static int cmd_link_stat_show(struct nlmsghdr *nlh, const struct cmd *cmd,
{ "link", OPT_KEYVAL, NULL },
{ NULL }
};
+ int err = 0;
if (help_flag) {
(cmd->help)(cmdl);
@@ -391,7 +485,10 @@ static int cmd_link_stat_show(struct nlmsghdr *nlh, const struct cmd *cmd,
if (opt)
link = opt->val;
- return msg_dumpit(nlh, link_stat_show_cb, link);
+ new_json_obj(json);
+ err = msg_dumpit(nlh, link_stat_show_cb, link);
+ delete_json_obj();
+ return err;
}
static void cmd_link_stat_help(struct cmdl *cmdl)
@@ -439,11 +536,11 @@ static int cmd_link_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
{ NULL }
};
- if (strcmp(cmd->cmd, "priority") == 0)
+ if (strcmp(cmd->cmd, PRIORITY_STR) == 0)
prop = TIPC_NLA_PROP_PRIO;
- else if ((strcmp(cmd->cmd, "tolerance") == 0))
+ else if ((strcmp(cmd->cmd, TOLERANCE_STR) == 0))
prop = TIPC_NLA_PROP_TOL;
- else if ((strcmp(cmd->cmd, "window") == 0))
+ else if ((strcmp(cmd->cmd, WINDOW_STR) == 0))
prop = TIPC_NLA_PROP_WIN;
else
return -EINVAL;
@@ -489,9 +586,9 @@ static int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
const struct cmd cmds[] = {
- { "priority", cmd_link_set_prop, cmd_link_set_help },
- { "tolerance", cmd_link_set_prop, cmd_link_set_help },
- { "window", cmd_link_set_prop, cmd_link_set_help },
+ { PRIORITY_STR, cmd_link_set_prop, cmd_link_set_help },
+ { TOLERANCE_STR, cmd_link_set_prop, cmd_link_set_help },
+ { WINDOW_STR, cmd_link_set_prop, cmd_link_set_help },
{ NULL }
};
@@ -537,15 +634,17 @@ static int link_mon_summary_cb(const struct nlmsghdr *nlh, void *data)
mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs);
- printf("\nbearer %s\n",
+ open_json_object(NULL);
+ print_string(PRINT_ANY, "bearer", "\nbearer %s\n",
mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME]));
- printf(" table_generation %u\n",
+ print_uint(PRINT_ANY, "table_generation", " table_generation %u\n",
mnl_attr_get_u32(attrs[TIPC_NLA_MON_LISTGEN]));
- printf(" cluster_size %u\n",
+ print_uint(PRINT_ANY, "cluster_size", " cluster_size %u\n",
mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT]));
- printf(" algorithm %s\n",
+ print_string(PRINT_ANY, "algorithm", " algorithm %s\n",
attrs[TIPC_NLA_MON_ACTIVE] ? "overlapping-ring" : "full-mesh");
+ close_json_object();
return MNL_CB_OK;
}
@@ -554,6 +653,7 @@ static int cmd_link_mon_summary(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
+ int err = 0;
if (help_flag) {
fprintf(stderr, "Usage: %s monitor summary\n", cmdl->argv[0]);
@@ -566,7 +666,11 @@ static int cmd_link_mon_summary(struct nlmsghdr *nlh, const struct cmd *cmd,
return -1;
}
- return msg_dumpit(nlh, link_mon_summary_cb, NULL);
+ new_json_obj(json);
+ err = msg_dumpit(nlh, link_mon_summary_cb, NULL);
+ delete_json_obj();
+
+ return err;
}
#define STATUS_WIDTH 7
@@ -587,16 +691,19 @@ static int map_get(uint64_t up_map, int i)
static void link_mon_print_applied(uint16_t applied, uint64_t up_map)
{
int i;
- char state;
+ open_json_array(PRINT_JSON, "applied_node_status");
for (i = 0; i < applied; i++) {
+ char state_str[2] = {0};
+
/* print the delimiter for every -n- entry */
if (i && !(i % APPL_NODE_STATUS_WIDTH))
- printf(",");
+ print_string(PRINT_FP, NULL, "%s", ",");
- state = map_get(up_map, i) ? 'U' : 'D';
- printf("%c", state);
+ sprintf(state_str, "%c", map_get(up_map, i) ? 'U' : 'D');
+ print_string(PRINT_ANY, NULL, "%s", state_str);
}
+ close_json_array(PRINT_JSON, "applied_node_status");
}
/* print the non applied members, since we dont know
@@ -608,19 +715,23 @@ static void link_mon_print_non_applied(uint16_t applied, uint16_t member_cnt,
int i;
char state;
- printf(" [");
+ open_json_array(PRINT_JSON, "[non_applied_node:status]");
+ print_string(PRINT_FP, NULL, " %s", "[");
for (i = applied; i < member_cnt; i++) {
char addr_str[16];
+ char full_state[17] = {0};
/* print the delimiter for every entry */
if (i != applied)
- printf(",");
+ print_string(PRINT_FP, NULL, "%s", ",");
sprintf(addr_str, "%x:", members[i]);
state = map_get(up_map, i) ? 'U' : 'D';
- printf("%s%c", addr_str, state);
+ sprintf(full_state, "%s%c", addr_str, state);
+ print_string(PRINT_ANY, NULL, "%s", full_state);
}
- printf("]");
+ print_string(PRINT_FP, NULL, "%s", "]");
+ close_json_array(PRINT_JSON, "[non_applied_node:status]");
}
static void link_mon_print_peer_state(const uint32_t addr, const char *status,
@@ -631,11 +742,17 @@ static void link_mon_print_peer_state(const uint32_t addr, const char *status,
sprintf(addr_str, "%u.%u.%u", tipc_zone(addr), tipc_cluster(addr),
tipc_node(addr));
-
- printf("%-*s", MAX_NODE_WIDTH, addr_str);
- printf("%-*s", STATUS_WIDTH, status);
- printf("%-*s", DIRECTLY_MON_WIDTH, monitored);
- printf("%-*u", MAX_DOM_GEN_WIDTH, dom_gen);
+ if (is_json_context()) {
+ print_string(PRINT_JSON, "node", NULL, addr_str);
+ print_string(PRINT_JSON, "status", NULL, status);
+ print_string(PRINT_JSON, "monitored", NULL, monitored);
+ print_uint(PRINT_JSON, "generation", NULL, dom_gen);
+ } else {
+ printf("%-*s", MAX_NODE_WIDTH, addr_str);
+ printf("%-*s", STATUS_WIDTH, status);
+ printf("%-*s", DIRECTLY_MON_WIDTH, monitored);
+ printf("%-*u", MAX_DOM_GEN_WIDTH, dom_gen);
+ }
}
static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data)
@@ -654,6 +771,7 @@ static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data)
if (!info[TIPC_NLA_MON_PEER])
return MNL_CB_ERROR;
+ open_json_object(NULL);
mnl_attr_parse_nested(info[TIPC_NLA_MON_PEER], parse_attrs, attrs);
(attrs[TIPC_NLA_MON_PEER_LOCAL] || attrs[TIPC_NLA_MON_PEER_HEAD]) ?
@@ -688,8 +806,9 @@ static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data)
mnl_attr_get_payload(attrs[TIPC_NLA_MON_PEER_MEMBERS]));
exit:
- printf("\n");
+ print_string(PRINT_FP, NULL, "\n", "");
+ close_json_object();
return MNL_CB_OK;
}
@@ -698,6 +817,7 @@ static int link_mon_peer_list(uint32_t mon_ref)
struct nlmsghdr *nlh;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlattr *nest;
+ int err = 0;
nlh = msg_init(buf, TIPC_NL_MON_PEER_GET);
if (!nlh) {
@@ -709,7 +829,8 @@ static int link_mon_peer_list(uint32_t mon_ref)
mnl_attr_put_u32(nlh, TIPC_NLA_MON_REF, mon_ref);
mnl_attr_nest_end(nlh, nest);
- return msg_dumpit(nlh, link_mon_peer_list_cb, NULL);
+ err = msg_dumpit(nlh, link_mon_peer_list_cb, NULL);
+ return err;
}
static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data)
@@ -733,12 +854,16 @@ static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data)
if (*req_bearer && (strcmp(req_bearer, bname) != 0))
return MNL_CB_OK;
- printf("\nbearer %s\n", bname);
- printf("%s\n", title);
+ open_json_object(NULL);
+ print_string(PRINT_ANY, "bearer", "\nbearer %s\n", bname);
+ print_string(PRINT_FP, NULL, "%s\n", title);
+ open_json_array(PRINT_JSON, bname);
if (mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT]))
link_mon_peer_list(mnl_attr_get_u32(attrs[TIPC_NLA_MON_REF]));
+ close_json_array(PRINT_JSON, bname);
+ close_json_object();
return MNL_CB_OK;
}
@@ -804,7 +929,10 @@ static int cmd_link_mon_list(struct nlmsghdr *nlh, const struct cmd *cmd,
return -1;
}
- return msg_dumpit(nlh, link_mon_list_cb, bname);
+ new_json_obj(json);
+ err = msg_dumpit(nlh, link_mon_list_cb, bname);
+ delete_json_obj();
+ return err;
}
static void cmd_link_mon_set_help(struct cmdl *cmdl)
@@ -848,8 +976,10 @@ static int link_mon_get_cb(const struct nlmsghdr *nlh, void *data)
if (!attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD])
return MNL_CB_ERROR;
- printf("%u\n",
- mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]));
+ new_json_obj(json);
+ print_uint(PRINT_ANY, "threshold", "%u\n",
+ mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]));
+ delete_json_obj();
return MNL_CB_OK;
}
--
2.7.4
^ permalink raw reply related
* Re: [PATCH iproute2-next] ip-xfrm: Add support for OUTPUT_MARK
From: Lorenzo Colitti @ 2018-06-12 2:33 UTC (permalink / raw)
To: Subash Abhinov Kasiviswanathan
Cc: netdev, Stephen Hemminger, David Ahern, Steffen Klassert
In-Reply-To: <1528769493-25435-1-git-send-email-subashab@codeaurora.org>
On Tue, Jun 12, 2018 at 11:12 AM Subash Abhinov Kasiviswanathan
<subashab@codeaurora.org> wrote:
>
> This patch adds support for OUTPUT_MARK in xfrm state to exercise the
> functionality added by kernel commit 077fbac405bf
> ("net: xfrm: support setting an output mark.").
>
> Sample output with output-mark -
>
> src 192.168.1.1 dst 192.168.1.2
> proto esp spi 0x00004321 reqid 0 mode tunnel
> replay-window 0 flag af-unspec
> auth-trunc xcbc(aes) 0x3ed0af408cf5dcbf5d5d9a5fa806b211 96
> enc cbc(aes) 0x3ed0af408cf5dcbf5d5d9a5fa806b233
> anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
> output-mark 0x20000
Have you considered putting this earlier up in the output, where the
mark is printed as well?
> + if (tb[XFRMA_OUTPUT_MARK]) {
> + __u32 output_mark = rta_getattr_u32(tb[XFRMA_OUTPUT_MARK]);
> +
> + fprintf(fp, "\toutput-mark 0x%x %s", output_mark, _SL_);
> + }
> }
If you wanted to implement the suggestion above, I think you could do
that by moving this code into xfrm_xfrma_print.
Other than that, LGTM.
Acked-by: Lorenzo Colitti <lorenzo@google.com>
Steffen - what's the status of the set_mark patches? Are you holding
them until the tree opens again? If so, then once they go in, we can
just make "set-mark" behave the same as "output-mark" in the iproute2
code, and add support for the mask as well.
^ permalink raw reply
* Re: [PATCH bpf v2] tools/bpftool: fix a bug in bpftool perf
From: Jakub Kicinski @ 2018-06-12 2:42 UTC (permalink / raw)
To: Yonghong Song; +Cc: ast, daniel, netdev, kernel-team
In-Reply-To: <20180612020108.125247-1-yhs@fb.com>
On Mon, 11 Jun 2018 19:01:08 -0700, Yonghong Song wrote:
> Commit b04df400c302 ("tools/bpftool: add perf subcommand")
> introduced bpftool subcommand perf to query bpf program
> kuprobe and tracepoint attachments.
>
> The perf subcommand will first test whether bpf subcommand
> BPF_TASK_FD_QUERY is supported in kernel or not. It does it
> by opening a file with argv[0] and feeds the file descriptor
> and current task pid to the kernel for querying.
>
> Such an approach won't work if the argv[0] cannot be opened
> successfully in the current directory. This is especially
> true when bpftool is accessible through PATH env variable.
> The error below reflects the open failure for file argv[0]
> at home directory.
>
> [yhs@localhost ~]$ which bpftool
> /usr/local/sbin/bpftool
> [yhs@localhost ~]$ bpftool perf
> Error: perf_query_support: No such file or directory
>
> To fix the issue, let us open root directory ("/")
> which exists in every linux system. With the fix, the
> error message will correctly reflect the permission issue.
>
> [yhs@localhost ~]$ which bpftool
> /usr/local/sbin/bpftool
> [yhs@localhost ~]$ bpftool perf
> Error: perf_query_support: Operation not permitted
> HINT: non root or kernel doesn't support TASK_FD_QUERY
>
> Fixes: b04df400c302 ("tools/bpftool: add perf subcommand")
> Reported-by: Alexei Starovoitov <ast@kernel.org>
> Signed-off-by: Yonghong Song <yhs@fb.com>
> ---
> tools/bpf/bpftool/perf.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> Changelogs:
> v1 -> v2:
> . remove '\n' in the p_err format string in order to
> have valid json output.
>
> diff --git a/tools/bpf/bpftool/perf.c b/tools/bpf/bpftool/perf.c
> index ac6b1a12c9b7..239715aa6fb9 100644
> --- a/tools/bpf/bpftool/perf.c
> +++ b/tools/bpf/bpftool/perf.c
> @@ -29,9 +29,10 @@ static bool has_perf_query_support(void)
> if (perf_query_supported)
> goto out;
>
> - fd = open(bin_name, O_RDONLY);
> - if (fd < 0) {
> - p_err("perf_query_support: %s", strerror(errno));
> + fd = open("/", O_RDONLY);
> + if (fd > 0) {
Looking at this again, why change the comparison from less than to
greater than 0?
> + p_err("perf_query_support: cannot open directory \"/\" (%s)",
> + strerror(errno));
> goto out;
> }
>
^ permalink raw reply
* [PATCH RFC v2] rhashtable: implement rhashtable_walk_peek() using rhashtable_walk_last_seen()
From: NeilBrown @ 2018-06-12 2:48 UTC (permalink / raw)
To: Tom Herbert
Cc: Herbert Xu, Thomas Graf, Linux Kernel Network Developers, LKML,
Tom Herbert
In-Reply-To: <CALx6S35GgUOd0dPgv7P96wNNTv5pN7fij0pcAoccqcSWZhvY7Q@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4058 bytes --]
rhashtable_walk_last_seen() does most of the work that
rhashtable_walk_peek() needs done, so use it and put
it in a "static inline".
Also update the documentation for rhashtable_walk_peek() to clarify
the expected use case.
Signed-off-by: NeilBrown <neilb@suse.com>
---
v2 as static-inline - suggested by Tom.
Thanks,
NeilBrown
include/linux/rhashtable.h | 29 ++++++++++++++++++++++++++++-
lib/rhashtable.c | 34 ----------------------------------
2 files changed, 28 insertions(+), 35 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index d63b472e9d50..96ebc2690027 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -247,10 +247,37 @@ static inline void rhashtable_walk_start(struct rhashtable_iter *iter)
}
void *rhashtable_walk_next(struct rhashtable_iter *iter);
-void *rhashtable_walk_peek(struct rhashtable_iter *iter);
void *rhashtable_walk_last_seen(struct rhashtable_iter *iter);
void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU);
+/**
+ * rhashtable_walk_peek - Return the next object to use in an interrupted walk
+ * @iter: Hash table iterator
+ *
+ * Returns the "current" object or NULL when the end of the table is reached.
+ * When an rhashtable_walk is interrupted with rhashtable_walk_stop(),
+ * it is often because an object was found that could not be processed
+ * immediately, possible because there is no more space to encode details
+ * of the object (e.g. when producing a seq_file from the table).
+ * When the walk is restarted, the same object needs to be processed again,
+ * if possible. The object might have been removed from the table while
+ * the walk was paused, so it might not be available. In that case, the
+ * normal "next" object should be treated as "current".
+ *
+ * To support this common case, rhashtable_walk_peek() returns the
+ * appropriate object to process after an interrupted walk, either the
+ * one that was most recently returned, or if that doesn't exist - the
+ * next one.
+ *
+ * Returns -EAGAIN if resize event occurred. In that case the iterator
+ * will rewind back to the beginning and you may continue to use it.
+ */
+static inline void *rhashtable_walk_peek(struct rhashtable_iter *iter)
+{
+ return rhashtable_walk_last_seen(iter) ?:
+ rhashtable_walk_next(iter);
+}
+
void rhashtable_free_and_destroy(struct rhashtable *ht,
void (*free_fn)(void *ptr, void *arg),
void *arg);
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 45f2554399a5..354275037df3 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -915,40 +915,6 @@ void *rhashtable_walk_next(struct rhashtable_iter *iter)
}
EXPORT_SYMBOL_GPL(rhashtable_walk_next);
-/**
- * rhashtable_walk_peek - Return the next object but don't advance the iterator
- * @iter: Hash table iterator
- *
- * Returns the next object or NULL when the end of the table is reached.
- *
- * Returns -EAGAIN if resize event occurred. Note that the iterator
- * will rewind back to the beginning and you may continue to use it.
- */
-void *rhashtable_walk_peek(struct rhashtable_iter *iter)
-{
- struct rhlist_head *list = iter->list;
- struct rhashtable *ht = iter->ht;
- struct rhash_head *p = iter->p;
-
- if (p)
- return rht_obj(ht, ht->rhlist ? &list->rhead : p);
-
- /* No object found in current iter, find next one in the table. */
-
- if (iter->skip) {
- /* A nonzero skip value points to the next entry in the table
- * beyond that last one that was found. Decrement skip so
- * we find the current value. __rhashtable_walk_find_next
- * will restore the original value of skip assuming that
- * the table hasn't changed.
- */
- iter->skip--;
- }
-
- return __rhashtable_walk_find_next(iter);
-}
-EXPORT_SYMBOL_GPL(rhashtable_walk_peek);
-
/**
* rhashtable_walk_last_seen - Return the previously returned object, if available
* @iter: Hash table iterator
--
2.14.0.rc0.dirty
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply related
* Re: [PATCH RFC] tcp: Do not reload skb pointer after skb_gro_receive().
From: Eric Dumazet @ 2018-06-12 2:59 UTC (permalink / raw)
To: David Miller, netdev; +Cc: edumazet
In-Reply-To: <20180611.180013.526861738690091217.davem@davemloft.net>
On 06/11/2018 06:00 PM, David Miller wrote:
>
> This is not necessary. skb_gro_receive() will never change what
> 'head' points to.
>
> In it's original implementation (see commit 71d93b39e52e ("net: Add
> skb_gro_receive")), it did:
>
> ====================
> + *head = nskb;
> + nskb->next = p->next;
> + p->next = NULL;
> ====================
>
> This sequence was removed in commit 58025e46ea2d ("net: gro: remove
> obsolete code from skb_gro_receive()")
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
SGTM, thanks David !
Signed-off-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* Re: [PATCH 1/2] Convert target drivers to use sbitmap
From: Matthew Wilcox @ 2018-06-12 3:06 UTC (permalink / raw)
To: Jens Axboe
Cc: Juergen Gross, kvm, linux-scsi, Matthew Wilcox, netdev, linux-usb,
linux-kernel, virtualization, target-devel, qla2xxx-upstream,
linux1394-devel, Kent Overstreet
In-Reply-To: <02326395-3241-c94b-ad70-3de27a6f5a8c@kernel.dk>
On Mon, Jun 11, 2018 at 07:18:55PM -0600, Jens Axboe wrote:
> Are you going to push this further? I really think we should.
Yes, I'll resubmit it tomorrow. Sorry for dropping the ball on this one.
^ permalink raw reply
* Re: [PATCH iproute2-next] ip-xfrm: Add support for OUTPUT_MARK
From: Stephen Hemminger @ 2018-06-12 3:12 UTC (permalink / raw)
To: Subash Abhinov Kasiviswanathan; +Cc: lorenzo, netdev, dsahern
In-Reply-To: <1528769493-25435-1-git-send-email-subashab@codeaurora.org>
On Mon, 11 Jun 2018 20:11:33 -0600
Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> wrote:
> This patch adds support for OUTPUT_MARK in xfrm state to exercise the
> functionality added by kernel commit 077fbac405bf
> ("net: xfrm: support setting an output mark.").
>
> Sample output with output-mark -
>
> src 192.168.1.1 dst 192.168.1.2
> proto esp spi 0x00004321 reqid 0 mode tunnel
> replay-window 0 flag af-unspec
> auth-trunc xcbc(aes) 0x3ed0af408cf5dcbf5d5d9a5fa806b211 96
> enc cbc(aes) 0x3ed0af408cf5dcbf5d5d9a5fa806b233
> anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
> output-mark 0x20000
>
> Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
This reminds me. It is time to convert xfrm to json output.
^ permalink raw reply
* problems with SCTP GSO
From: David Miller @ 2018-06-12 3:29 UTC (permalink / raw)
To: marcelo.leitner; +Cc: lucien.xin, edumazet, netdev
I would like to bring up some problems with the current GSO
implementation in SCTP.
The most important for me right now is that SCTP uses
"skb_gro_receive()" to build "GSO" frames :-(
Really it just ends up using the slow path (basically, label 'merge'
and onwards).
So, using a GRO helper to build GSO packets is not great.
I want to make major surgery here and the only way I can is if
it is exactly the GRO demuxing path that uses skb_gro_receive().
Those paths pass in the list head from the NAPI struct that initiated
the GRO code paths. That makes it easy for me to change this to use a
list_head or a hash chain.
Probably in the short term SCTP should just have a private helper that
builds the frag list, appending 'skb' to 'head'.
In the long term, SCTP should use the page frags just like TCP to
append the data when building GSO frames. Then it could actually be
offloaded and passed into drivers without linearizing.
^ permalink raw reply
* Re: [PATCH bpf v2] tools/bpftool: fix a bug in bpftool perf
From: Yonghong Song @ 2018-06-12 3:45 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: ast, daniel, netdev, kernel-team
In-Reply-To: <20180611194257.5f72219b@cakuba.netronome.com>
On 6/11/18 7:42 PM, Jakub Kicinski wrote:
> On Mon, 11 Jun 2018 19:01:08 -0700, Yonghong Song wrote:
>> Commit b04df400c302 ("tools/bpftool: add perf subcommand")
>> introduced bpftool subcommand perf to query bpf program
>> kuprobe and tracepoint attachments.
>>
>> The perf subcommand will first test whether bpf subcommand
>> BPF_TASK_FD_QUERY is supported in kernel or not. It does it
>> by opening a file with argv[0] and feeds the file descriptor
>> and current task pid to the kernel for querying.
>>
>> Such an approach won't work if the argv[0] cannot be opened
>> successfully in the current directory. This is especially
>> true when bpftool is accessible through PATH env variable.
>> The error below reflects the open failure for file argv[0]
>> at home directory.
>>
>> [yhs@localhost ~]$ which bpftool
>> /usr/local/sbin/bpftool
>> [yhs@localhost ~]$ bpftool perf
>> Error: perf_query_support: No such file or directory
>>
>> To fix the issue, let us open root directory ("/")
>> which exists in every linux system. With the fix, the
>> error message will correctly reflect the permission issue.
>>
>> [yhs@localhost ~]$ which bpftool
>> /usr/local/sbin/bpftool
>> [yhs@localhost ~]$ bpftool perf
>> Error: perf_query_support: Operation not permitted
>> HINT: non root or kernel doesn't support TASK_FD_QUERY
>>
>> Fixes: b04df400c302 ("tools/bpftool: add perf subcommand")
>> Reported-by: Alexei Starovoitov <ast@kernel.org>
>> Signed-off-by: Yonghong Song <yhs@fb.com>
>> ---
>> tools/bpf/bpftool/perf.c | 7 ++++---
>> 1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> Changelogs:
>> v1 -> v2:
>> . remove '\n' in the p_err format string in order to
>> have valid json output.
>>
>> diff --git a/tools/bpf/bpftool/perf.c b/tools/bpf/bpftool/perf.c
>> index ac6b1a12c9b7..239715aa6fb9 100644
>> --- a/tools/bpf/bpftool/perf.c
>> +++ b/tools/bpf/bpftool/perf.c
>> @@ -29,9 +29,10 @@ static bool has_perf_query_support(void)
>> if (perf_query_supported)
>> goto out;
>>
>> - fd = open(bin_name, O_RDONLY);
>> - if (fd < 0) {
>> - p_err("perf_query_support: %s", strerror(errno));
>> + fd = open("/", O_RDONLY);
>> + if (fd > 0) {
>
> Looking at this again, why change the comparison from less than to
> greater than 0?
Totally my fault. I altered the condition to test p_err output since
I cannot trigger it normally, but forgot to change it back.
Will send yet another revision :-(
>> + p_err("perf_query_support: cannot open directory \"/\" (%s)",
>> + strerror(errno));
>> goto out;
>> }
>>
>
^ permalink raw reply
* [PATCH] net: add error handling for kmem_cache_create
From: Zhouyang Jia @ 2018-06-12 4:29 UTC (permalink / raw)
Cc: Zhouyang Jia, David S. Miller, Wei Wang, Martin KaFai Lau,
Kees Cook, Eric Dumazet, Florian Westphal, Joe Perches,
linux-decnet-user, netdev, linux-kernel
When kmem_cache_create fails, the lack of error-handling code may
cause unexpected results.
This patch adds error-handling code after calling kmem_cache_create.
Signed-off-by: Zhouyang Jia <jiazhouyang09@gmail.com>
---
net/decnet/dn_route.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index e747650..2b743c7 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1861,6 +1861,9 @@ void __init dn_route_init(void)
dn_dst_ops.kmem_cachep =
kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
+ if (!dn_dst_ops.kmem_cachep)
+ panic("Failed to create dn_dst_cache cache\n");
+
dst_entries_init(&dn_dst_ops);
timer_setup(&dn_route_timer, dn_dst_check_expire, 0);
dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] net: add error handling for kmem_cache_create
From: Eric Dumazet @ 2018-06-12 4:31 UTC (permalink / raw)
To: Zhouyang Jia
Cc: David S. Miller, Wei Wang, Martin KaFai Lau, Kees Cook,
Eric Dumazet, Florian Westphal, Joe Perches, linux-decnet-user,
netdev, linux-kernel
In-Reply-To: <1528777798-40722-1-git-send-email-jiazhouyang09@gmail.com>
On 06/11/2018 09:29 PM, Zhouyang Jia wrote:
> When kmem_cache_create fails, the lack of error-handling code may
> cause unexpected results.
>
> This patch adds error-handling code after calling kmem_cache_create.
>
> Signed-off-by: Zhouyang Jia <jiazhouyang09@gmail.com>
> ---
> net/decnet/dn_route.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
> index e747650..2b743c7 100644
> --- a/net/decnet/dn_route.c
> +++ b/net/decnet/dn_route.c
> @@ -1861,6 +1861,9 @@ void __init dn_route_init(void)
> dn_dst_ops.kmem_cachep =
> kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0,
> SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
> + if (!dn_dst_ops.kmem_cachep)
> + panic("Failed to create dn_dst_cache cache\n");
> +
Not needed, since SLAB_PANIC would have paniced the box earlier.
> dst_entries_init(&dn_dst_ops);
> timer_setup(&dn_route_timer, dn_dst_check_expire, 0);
> dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;
>
^ permalink raw reply
* [PATCH net 1/4] nfp: don't pad strings in nfp_cpp_resource_find() to avoid gcc 8 warning
From: Jakub Kicinski @ 2018-06-12 4:33 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, Jakub Kicinski
In-Reply-To: <20180612043338.5447-1-jakub.kicinski@netronome.com>
Once upon a time nfp_cpp_resource_find() took a name parameter,
which could be any user-chosen string. Resources are identified
by a CRC32 hash of a 8 byte string, so we had to pad user input
with zeros to make sure CRC32 gave the correct result.
Since then nfp_cpp_resource_find() was made to operate on allocated
resources only (struct nfp_resource). We kzalloc those so there is
no need to pad the strings and use memcmp.
This avoids a GCC 8 stringop-truncation warning:
In function ‘nfp_cpp_resource_find’,
inlined from ‘nfp_resource_try_acquire’ at .../nfpcore/nfp_resource.c:153:8,
inlined from ‘nfp_resource_acquire’ at .../nfpcore/nfp_resource.c:206:9:
.../nfpcore/nfp_resource.c:108:2: warning: strncpy’ output may be truncated copying 8 bytes from a string of length 8 [-Wstringop-truncation]
strncpy(name_pad, res->name, sizeof(name_pad));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
index 2dd89dba9311..d32af598da90 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
@@ -98,21 +98,18 @@ struct nfp_resource {
static int nfp_cpp_resource_find(struct nfp_cpp *cpp, struct nfp_resource *res)
{
- char name_pad[NFP_RESOURCE_ENTRY_NAME_SZ] = {};
struct nfp_resource_entry entry;
u32 cpp_id, key;
int ret, i;
cpp_id = NFP_CPP_ID(NFP_RESOURCE_TBL_TARGET, 3, 0); /* Atomic read */
- strncpy(name_pad, res->name, sizeof(name_pad));
-
/* Search for a matching entry */
- if (!memcmp(name_pad, NFP_RESOURCE_TBL_NAME "\0\0\0\0\0\0\0\0", 8)) {
+ if (!strcmp(res->name, NFP_RESOURCE_TBL_NAME)) {
nfp_err(cpp, "Grabbing device lock not supported\n");
return -EOPNOTSUPP;
}
- key = crc32_posix(name_pad, sizeof(name_pad));
+ key = crc32_posix(res->name, NFP_RESOURCE_ENTRY_NAME_SZ);
for (i = 0; i < NFP_RESOURCE_TBL_ENTRIES; i++) {
u64 addr = NFP_RESOURCE_TBL_BASE +
--
2.17.1
^ permalink raw reply related
* [PATCH net 2/4] nfp: include all ring counters in interface stats
From: Jakub Kicinski @ 2018-06-12 4:33 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, Jakub Kicinski
In-Reply-To: <20180612043338.5447-1-jakub.kicinski@netronome.com>
We are gathering software statistics on per-ring basis.
.ndo_get_stats64 handler adds the rings up. Unfortunately
we are currently only adding up active rings, which means
that if user decreases the number of active rings the
statistics from deactivated rings will no longer be counted
and total interface statistics may go backwards.
Always sum all possible rings, the stats are allocated
statically for max number of rings, so we don't have to
worry about them being removed. We could add the stats
up when user changes the ring count, but it seems unnecessary..
Adding up inactive rings will be very quick since no datapath
will be touching them.
Fixes: 164d1e9e5d52 ("nfp: add support for ethtool .set_channels")
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 75110c8d6a90..ed27176c2bce 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3121,7 +3121,7 @@ static void nfp_net_stat64(struct net_device *netdev,
struct nfp_net *nn = netdev_priv(netdev);
int r;
- for (r = 0; r < nn->dp.num_r_vecs; r++) {
+ for (r = 0; r < nn->max_r_vecs; r++) {
struct nfp_net_r_vector *r_vec = &nn->r_vecs[r];
u64 data[3];
unsigned int start;
--
2.17.1
^ permalink raw reply related
* [PATCH net 3/4] nfp: remove phys_port_name on flower's vNIC
From: Jakub Kicinski @ 2018-06-12 4:33 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, Jakub Kicinski
In-Reply-To: <20180612043338.5447-1-jakub.kicinski@netronome.com>
.ndo_get_phys_port_name was recently extended to support multi-vNIC
FWs. These are firmwares which can have more than one vNIC per PF
without associated port (e.g. Adaptive Buffer Management FW), therefore
we need a way of distinguishing the vNICs. Unfortunately, it's too
late to make flower use the same naming. Flower users may depend on
.ndo_get_phys_port_name returning -EOPNOTSUPP, for example the name
udev gave the PF vNIC was just the bare PCI device-based name before
the change, and will have 'nn0' appended after.
To ensure flower's vNIC doesn't have phys_port_name attribute, add
a flag to vNIC struct and set it in flower code. New projects will
not set the flag adhere to the naming scheme from the start.
Fixes: 51c1df83e35c ("nfp: assign vNIC id as phys_port_name of vNICs which are not ports")
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/flower/main.c | 1 +
drivers/net/ethernet/netronome/nfp/nfp_net.h | 4 ++++
drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 2 +-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c
index 19cfa162ac65..1decf3a1cad3 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -455,6 +455,7 @@ static int nfp_flower_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
eth_hw_addr_random(nn->dp.netdev);
netif_keep_dst(nn->dp.netdev);
+ nn->vnic_no_name = true;
return 0;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 57cb035dcc6d..2a71a9ffd095 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -590,6 +590,8 @@ struct nfp_net_dp {
* @vnic_list: Entry on device vNIC list
* @pdev: Backpointer to PCI device
* @app: APP handle if available
+ * @vnic_no_name: For non-port PF vNIC make ndo_get_phys_port_name return
+ * -EOPNOTSUPP to keep backwards compatibility (set by app)
* @port: Pointer to nfp_port structure if vNIC is a port
* @app_priv: APP private data for this vNIC
*/
@@ -663,6 +665,8 @@ struct nfp_net {
struct pci_dev *pdev;
struct nfp_app *app;
+ bool vnic_no_name;
+
struct nfp_port *port;
void *app_priv;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index ed27176c2bce..d4c27f849f9b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3286,7 +3286,7 @@ nfp_net_get_phys_port_name(struct net_device *netdev, char *name, size_t len)
if (nn->port)
return nfp_port_get_phys_port_name(netdev, name, len);
- if (nn->dp.is_vf)
+ if (nn->dp.is_vf || nn->vnic_no_name)
return -EOPNOTSUPP;
n = snprintf(name, len, "n%d", nn->id);
--
2.17.1
^ permalink raw reply related
* [PATCH net 0/4] nfp: fix a warning, stats, naming and route leak
From: Jakub Kicinski @ 2018-06-12 4:33 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, Jakub Kicinski
Hi!
Various fixes for the NFP. Patch 1 fixes a harmless GCC 8 warning.
Patch 2 ensures statistics are correct after users decrease the number
of channels/rings. Patch 3 restores phy_port_name behaviour for flower,
ndo_get_phy_port_name used to return -EOPNOTSUPP on one of the netdevs,
and we need to keep it that way otherwise interface names may change.
Patch 4 fixes refcnt leak in flower tunnel offload code.
Jakub Kicinski (3):
nfp: don't pad strings in nfp_cpp_resource_find() to avoid gcc 8
warning
nfp: include all ring counters in interface stats
nfp: remove phys_port_name on flower's vNIC
Pieter Jansen van Vuuren (1):
nfp: flower: free dst_entry in route table
drivers/net/ethernet/netronome/nfp/flower/main.c | 1 +
drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c | 2 ++
drivers/net/ethernet/netronome/nfp/nfp_net.h | 4 ++++
drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 4 ++--
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c | 7 ++-----
5 files changed, 11 insertions(+), 7 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH net 4/4] nfp: flower: free dst_entry in route table
From: Jakub Kicinski @ 2018-06-12 4:33 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, Pieter Jansen van Vuuren, Louis Peens
In-Reply-To: <20180612043338.5447-1-jakub.kicinski@netronome.com>
From: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
We need to release the refcnt on dst_entry in the route table, otherwise
we will leak the route.
Fixes: 8e6a9046b66a ("nfp: flower vxlan neighbour offload")
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Signed-off-by: Louis Peens <louis.peens@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
index ec524d97869d..78afe75129ab 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
@@ -381,6 +381,8 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
err = PTR_ERR_OR_ZERO(rt);
if (err)
return NOTIFY_DONE;
+
+ ip_rt_put(rt);
#else
return NOTIFY_DONE;
#endif
--
2.17.1
^ permalink raw reply related
* [PATCH] isdn/i4l: add error handling for try_module_get
From: Zhouyang Jia @ 2018-06-12 4:43 UTC (permalink / raw)
Cc: Zhouyang Jia, Karsten Keil, Kees Cook, Annie Cherkaev, Al Viro,
Jiten Thakkar, netdev, linux-kernel
When try_module_get fails, the lack of error-handling code may
cause unexpected results.
This patch adds error-handling code after calling try_module_get.
Signed-off-by: Zhouyang Jia <jiazhouyang09@gmail.com>
---
drivers/isdn/i4l/isdn_common.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 7c6f3f5..7e52851 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -71,7 +71,8 @@ static int isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding);
static inline void
isdn_lock_driver(isdn_driver_t *drv)
{
- try_module_get(drv->interface->owner);
+ if (!try_module_get(drv->interface->owner))
+ printk(KERN_WARNING "isdn_lock_driver: cannot get module\n");
drv->locks++;
}
--
2.7.4
^ permalink raw reply related
* Re: [Qemu-devel] [PATCH] qemu: Introduce VIRTIO_NET_F_STANDBY feature bit to virtio_net
From: Samudrala, Sridhar @ 2018-06-12 5:02 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang
Cc: alexander.h.duyck, virtio-dev, aaron.f.brown, jiri, kubakici,
netdev, qemu-devel, loseweigh, virtualization
In-Reply-To: <20180612051432-mutt-send-email-mst@kernel.org>
On 6/11/2018 7:17 PM, Michael S. Tsirkin wrote:
> On Tue, Jun 12, 2018 at 09:54:44AM +0800, Jason Wang wrote:
>>
>> On 2018年06月12日 01:26, Michael S. Tsirkin wrote:
>>> On Mon, May 07, 2018 at 04:09:54PM -0700, Sridhar Samudrala wrote:
>>>> This feature bit can be used by hypervisor to indicate virtio_net device to
>>>> act as a standby for another device with the same MAC address.
>>>>
>>>> I tested this with a small change to the patch to mark the STANDBY feature 'true'
>>>> by default as i am using libvirt to start the VMs.
>>>> Is there a way to pass the newly added feature bit 'standby' to qemu via libvirt
>>>> XML file?
>>>>
>>>> Signed-off-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
>>> So I do not think we can commit to this interface: we
>>> really need to control visibility of the primary device.
>> The problem is legacy guest won't use primary device at all if we do this.
> And that's by design - I think it's the only way to ensure the
> legacy guest isn't confused.
Yes. I think so. But i am not sure if Qemu is the right place to control the visibility
of the primary device. The primary device may not be specified as an argument to Qemu. It
may be plugged in later.
The cloud service provider is providing a feature that enables low latency datapath and live
migration capability.
A tenant can use this feature only if he is running a VM that has virtio-net with failover support.
I think Qemu should check if guest virtio-net supports this feature and provide a mechanism for
an upper layer indicating if the STANDBY feature is successfully negotiated or not.
The upper layer can then decide if it should hot plug a VF with the same MAC and manage the 2 links.
If VF is successfully hot plugged, virtio-net link should be disabled.
>
>> How about control the visibility of standby device?
>>
>> Thanks
> standy the always there to guarantee no downtime.
>
>>> However just for testing purposes, we could add a non-stable
>>> interface "x-standby" with the understanding that as any
>>> x- prefix it's unstable and will be changed down the road,
>>> likely in the next release.
>>>
>>>
>>>> ---
>>>> hw/net/virtio-net.c | 2 ++
>>>> include/standard-headers/linux/virtio_net.h | 3 +++
>>>> 2 files changed, 5 insertions(+)
>>>>
>>>> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
>>>> index 90502fca7c..38b3140670 100644
>>>> --- a/hw/net/virtio-net.c
>>>> +++ b/hw/net/virtio-net.c
>>>> @@ -2198,6 +2198,8 @@ static Property virtio_net_properties[] = {
>>>> true),
>>>> DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
>>>> DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
>>>> + DEFINE_PROP_BIT64("standby", VirtIONet, host_features, VIRTIO_NET_F_STANDBY,
>>>> + false),
>>>> DEFINE_PROP_END_OF_LIST(),
>>>> };
>>>> diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h
>>>> index e9f255ea3f..01ec09684c 100644
>>>> --- a/include/standard-headers/linux/virtio_net.h
>>>> +++ b/include/standard-headers/linux/virtio_net.h
>>>> @@ -57,6 +57,9 @@
>>>> * Steering */
>>>> #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
>>>> +#define VIRTIO_NET_F_STANDBY 62 /* Act as standby for another device
>>>> + * with the same MAC.
>>>> + */
>>>> #define VIRTIO_NET_F_SPEED_DUPLEX 63 /* Device set linkspeed and duplex */
>>>> #ifndef VIRTIO_NET_NO_LEGACY
>>>> --
>>>> 2.14.3
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH net] tls: fix NULL pointer dereference on poll
From: Christoph Hellwig @ 2018-06-12 5:37 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: davem, davejwatson, netdev, ast, Christoph Hellwig
In-Reply-To: <20180611212204.24002-1-daniel@iogearbox.net>
> Looks like the recent conversion from poll to poll_mask callback started
> in 152524231023 ("net: add support for ->poll_mask in proto_ops") missed
> to eventually convert kTLS, too: TCP's ->poll was converted over to the
> ->poll_mask in commit 2c7d3dacebd4 ("net/tcp: convert to ->poll_mask")
> and therefore kTLS wrongly saved the ->poll old one which is now NULL.
Looks like this TLS code was added in the same cycle.
> diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
> index 301f224..a127d61 100644
> --- a/net/tls/tls_main.c
> +++ b/net/tls/tls_main.c
> @@ -712,7 +712,7 @@ static int __init tls_register(void)
> build_protos(tls_prots[TLSV4], &tcp_prot);
>
> tls_sw_proto_ops = inet_stream_ops;
> - tls_sw_proto_ops.poll = tls_sw_poll;
> + tls_sw_proto_ops.poll_mask = tls_sw_poll_mask;
> tls_sw_proto_ops.splice_read = tls_sw_splice_read;
Not new in this patch, but copying ops vectors is a very bad idea, not
only because your new instance can't be marked const and you thus open
up exploit vectors. I would suggest to clean this up eventually.
> +__poll_t tls_sw_poll_mask(struct socket *sock, __poll_t events)
> {
> struct sock *sk = sock->sk;
> struct tls_context *tls_ctx = tls_get_ctx(sk);
> struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
> + __poll_t mask;
>
> + /* Grab EPOLLOUT and EPOLLHUP from the underlying socket */
> + mask = ctx->sk_poll_mask(sock, events);
>
> + /* Clear EPOLLIN bits, and set based on recv_pkt */
> + mask &= ~(EPOLLIN | EPOLLRDNORM);
> if (ctx->recv_pkt)
> + mask |= EPOLLIN | EPOLLRDNORM;
>
> + return mask;
So you call the underlying protocol method on the struct sock of
the TLS code? Again not reall new in this patch, but how is this
even supposed to work?
^ permalink raw reply
* [PATCH bpf v3] tools/bpftool: fix a bug in bpftool perf
From: Yonghong Song @ 2018-06-12 5:35 UTC (permalink / raw)
To: ast, daniel, netdev; +Cc: kernel-team
Commit b04df400c302 ("tools/bpftool: add perf subcommand")
introduced bpftool subcommand perf to query bpf program
kuprobe and tracepoint attachments.
The perf subcommand will first test whether bpf subcommand
BPF_TASK_FD_QUERY is supported in kernel or not. It does it
by opening a file with argv[0] and feeds the file descriptor
and current task pid to the kernel for querying.
Such an approach won't work if the argv[0] cannot be opened
successfully in the current directory. This is especially
true when bpftool is accessible through PATH env variable.
The error below reflects the open failure for file argv[0]
at home directory.
[yhs@localhost ~]$ which bpftool
/usr/local/sbin/bpftool
[yhs@localhost ~]$ bpftool perf
Error: perf_query_support: No such file or directory
To fix the issue, let us open root directory ("/")
which exists in every linux system. With the fix, the
error message will correctly reflect the permission issue.
[yhs@localhost ~]$ which bpftool
/usr/local/sbin/bpftool
[yhs@localhost ~]$ bpftool perf
Error: perf_query_support: Operation not permitted
HINT: non root or kernel doesn't support TASK_FD_QUERY
Fixes: b04df400c302 ("tools/bpftool: add perf subcommand")
Reported-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Yonghong Song <yhs@fb.com>
---
tools/bpf/bpftool/perf.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
Changelogs:
v2 -> v3:
. fix a stupid error (flippingg the condition) I introduced in v2.
v1 -> v2:
. remove '\n' in the p_err format string in order to
have valid json output.
diff --git a/tools/bpf/bpftool/perf.c b/tools/bpf/bpftool/perf.c
index ac6b1a12c9b7..b76b77dcfd1f 100644
--- a/tools/bpf/bpftool/perf.c
+++ b/tools/bpf/bpftool/perf.c
@@ -29,9 +29,10 @@ static bool has_perf_query_support(void)
if (perf_query_supported)
goto out;
- fd = open(bin_name, O_RDONLY);
+ fd = open("/", O_RDONLY);
if (fd < 0) {
- p_err("perf_query_support: %s", strerror(errno));
+ p_err("perf_query_support: cannot open directory \"/\" (%s)",
+ strerror(errno));
goto out;
}
--
2.14.3
^ permalink raw reply related
* Re: [Xen-devel] [PATCH] xen/netfront: raise max number of slots in xennet_get_responses()
From: Juergen Gross @ 2018-06-12 6:45 UTC (permalink / raw)
To: Boris Ostrovsky, linux-kernel, xen-devel, netdev; +Cc: davem
In-Reply-To: <e970a52b-d4ad-30c1-65ca-15d7679951da@oracle.com>
On 11/06/18 20:59, Boris Ostrovsky wrote:
> On 06/11/2018 03:57 AM, Juergen Gross wrote:
>> The max number of slots used in xennet_get_responses() is set to
>> MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD).
>>
>> In old kernel-xen MAX_SKB_FRAGS was 18, while nowadays it is 17. This
>> difference is resulting in frequent messages "too many slots" and a
>> reduced network throughput for some workloads (factor 10 below that of
>> a kernel-xen based guest).
>>
>> Replacing MAX_SKB_FRAGS by XEN_NETIF_NR_SLOTS_MIN for calculation of
>> the max number of slots to use solves that problem (tests showed no
>> more messages "too many slots" and throughput was as high as with the
>> kernel-xen based guest system).
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>
> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
>
> I wonder also whether netfront_tx_slot_available() is meant to be
>
> return (queue->tx.req_prod_pvt - queue->tx.rsp_cons) <
> (NET_TX_RING_SIZE - XEN_NETIF_NR_SLOTS_MIN - 1);
>
> which is the same numeric value but provides a more accurate description
> of what is being tested.
Yes, this is a sensible idea. I'll add that, keeping your R-b.
Juergen
^ permalink raw reply
* [PATCH v2] xen/netfront: raise max number of slots in xennet_get_responses()
From: Juergen Gross @ 2018-06-12 6:57 UTC (permalink / raw)
To: linux-kernel, xen-devel, netdev; +Cc: boris.ostrovsky, davem, Juergen Gross
The max number of slots used in xennet_get_responses() is set to
MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD).
In old kernel-xen MAX_SKB_FRAGS was 18, while nowadays it is 17. This
difference is resulting in frequent messages "too many slots" and a
reduced network throughput for some workloads (factor 10 below that of
a kernel-xen based guest).
Replacing MAX_SKB_FRAGS by XEN_NETIF_NR_SLOTS_MIN for calculation of
the max number of slots to use solves that problem (tests showed no
more messages "too many slots" and throughput was as high as with the
kernel-xen based guest system).
Replace MAX_SKB_FRAGS-2 by XEN_NETIF_NR_SLOTS_MIN-1 in
netfront_tx_slot_available() for making it clearer what is really being
tested without actually modifying the tested value.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
drivers/net/xen-netfront.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 679da1abd73c..922ce0abf5cf 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -239,7 +239,7 @@ static void rx_refill_timeout(struct timer_list *t)
static int netfront_tx_slot_available(struct netfront_queue *queue)
{
return (queue->tx.req_prod_pvt - queue->tx.rsp_cons) <
- (NET_TX_RING_SIZE - MAX_SKB_FRAGS - 2);
+ (NET_TX_RING_SIZE - XEN_NETIF_NR_SLOTS_MIN - 1);
}
static void xennet_maybe_wake_tx(struct netfront_queue *queue)
@@ -790,7 +790,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
RING_IDX cons = queue->rx.rsp_cons;
struct sk_buff *skb = xennet_get_rx_skb(queue, cons);
grant_ref_t ref = xennet_get_rx_ref(queue, cons);
- int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD);
+ int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD);
int slots = 1;
int err = 0;
unsigned long ret;
--
2.13.7
^ permalink raw reply related
* Re: [PATCH] net: phy: mdio-gpio: Cut surplus includes
From: Andrew Lunn @ 2018-06-12 7:05 UTC (permalink / raw)
To: Linus Walleij; +Cc: Florian Fainelli, netdev
In-Reply-To: <20180611111903.7221-1-linus.walleij@linaro.org>
On Mon, Jun 11, 2018 at 01:19:03PM +0200, Linus Walleij wrote:
> The GPIO MDIO driver now needs only <linux/gpio/consumer.h>
> so cut the legacy <linux/gpio.h> and <linux/of_gpio.h>
> includes that are no longer used.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH 1/3] m68k: coldfire: Normalize clk API
From: Greg Ungerer @ 2018-06-12 7:26 UTC (permalink / raw)
To: Geert Uytterhoeven, Ralf Baechle, James Hogan, Giuseppe Cavallaro,
Alexandre Torgue, Jose Abreu, Corentin Labbe, David S . Miller
Cc: Arnd Bergmann, linux-m68k, linux-mips, netdev, linux-kernel
In-Reply-To: <1528706663-20670-2-git-send-email-geert@linux-m68k.org>
Hi Geert,
On 11/06/18 18:44, Geert Uytterhoeven wrote:
> Coldfire still provides its own variant of the clk API rather than using
> the generic COMMON_CLK API. This generally works, but it causes some
> link errors with drivers using the clk_round_rate(), clk_set_rate(),
> clk_set_parent(), or clk_get_parent() functions when a platform lacks
> those interfaces.
>
> This adds empty stub implementations for each of them, and I don't even
> try to do something useful here but instead just print a WARN() message
> to make it obvious what is going on if they ever end up being called.
>
> The drivers that call these won't be used on these platforms (otherwise
> we'd get a link error today), so the added code is harmless bloat and
> will warn about accidental use.
>
> Based on commit bd7fefe1f06ca6cc ("ARM: w90x900: normalize clk API").
>
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
I am fine with this for ColdFire, so
Acked-by: Greg Ungerer <gerg@linux-m68k.org>
Are you going to take this/these via your m68k git tree?
Regards
Greg
> ---
> arch/m68k/coldfire/clk.c | 29 +++++++++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
> diff --git a/arch/m68k/coldfire/clk.c b/arch/m68k/coldfire/clk.c
> index 849cd208e2ed99e6..7bc666e482ebe82f 100644
> --- a/arch/m68k/coldfire/clk.c
> +++ b/arch/m68k/coldfire/clk.c
> @@ -129,4 +129,33 @@ unsigned long clk_get_rate(struct clk *clk)
> }
> EXPORT_SYMBOL(clk_get_rate);
>
> +/* dummy functions, should not be called */
> +long clk_round_rate(struct clk *clk, unsigned long rate)
> +{
> + WARN_ON(clk);
> + return 0;
> +}
> +EXPORT_SYMBOL(clk_round_rate);
> +
> +int clk_set_rate(struct clk *clk, unsigned long rate)
> +{
> + WARN_ON(clk);
> + return 0;
> +}
> +EXPORT_SYMBOL(clk_set_rate);
> +
> +int clk_set_parent(struct clk *clk, struct clk *parent)
> +{
> + WARN_ON(clk);
> + return 0;
> +}
> +EXPORT_SYMBOL(clk_set_parent);
> +
> +struct clk *clk_get_parent(struct clk *clk)
> +{
> + WARN_ON(clk);
> + return NULL;
> +}
> +EXPORT_SYMBOL(clk_get_parent);
> +
> /***************************************************************************/
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox