|
|
3259a4 |
From fc5f2a6bb2911a951bf5a1364dc5732e521d735a Mon Sep 17 00:00:00 2001
|
|
|
3259a4 |
From: Michal Kubecek <mkubecek@suse.cz>
|
|
|
3259a4 |
Date: Mon, 9 Nov 2020 14:29:56 +0100
|
|
|
3259a4 |
Subject: [PATCH 25/26] netlink: do not send messages and process replies in
|
|
|
3259a4 |
nl_parser()
|
|
|
3259a4 |
|
|
|
3259a4 |
When called with group_style = PARSER_GROUP_MSG, nl_parser() not only
|
|
|
3259a4 |
parses the command line and composes the messages but also sends them to
|
|
|
3259a4 |
kernel and processes the replies. This is inconsistent with other modes and
|
|
|
3259a4 |
also impractical as it takes the control over the process from caller where
|
|
|
3259a4 |
it belongs.
|
|
|
3259a4 |
|
|
|
3259a4 |
Modify nl_parser() to pass composed messages back to caller (which is only
|
|
|
3259a4 |
nl_sset() at the moment) and let it send requests and process replies. This
|
|
|
3259a4 |
will be needed for an upcoming backward compatibility patch which will need
|
|
|
3259a4 |
to inspect and possibly modify one of the composed messages.
|
|
|
3259a4 |
|
|
|
3259a4 |
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
|
|
|
3259a4 |
(cherry picked from commit acd9730d1e794f85caf1192fe8788876e6f96305)
|
|
|
3259a4 |
---
|
|
|
3259a4 |
netlink/cable_test.c | 2 +-
|
|
|
3259a4 |
netlink/channels.c | 2 +-
|
|
|
3259a4 |
netlink/coalesce.c | 2 +-
|
|
|
3259a4 |
netlink/eee.c | 2 +-
|
|
|
3259a4 |
netlink/parser.c | 43 ++++++++++++++++++++++++++++---------------
|
|
|
3259a4 |
netlink/parser.h | 3 ++-
|
|
|
3259a4 |
netlink/pause.c | 2 +-
|
|
|
3259a4 |
netlink/rings.c | 2 +-
|
|
|
3259a4 |
netlink/settings.c | 35 ++++++++++++++++++++++++++++++-----
|
|
|
3259a4 |
9 files changed, 66 insertions(+), 27 deletions(-)
|
|
|
3259a4 |
|
|
|
3259a4 |
diff --git a/netlink/cable_test.c b/netlink/cable_test.c
|
|
|
3259a4 |
index d39b7d82efb0..e05b67c4e231 100644
|
|
|
3259a4 |
--- a/netlink/cable_test.c
|
|
|
3259a4 |
+++ b/netlink/cable_test.c
|
|
|
3259a4 |
@@ -574,7 +574,7 @@ int nl_cable_test_tdr(struct cmd_context *ctx)
|
|
|
3259a4 |
ctx->devname, 0))
|
|
|
3259a4 |
return -EMSGSIZE;
|
|
|
3259a4 |
|
|
|
3259a4 |
- ret = nl_parser(nlctx, tdr_params, NULL, PARSER_GROUP_NEST);
|
|
|
3259a4 |
+ ret = nl_parser(nlctx, tdr_params, NULL, PARSER_GROUP_NEST, NULL);
|
|
|
3259a4 |
if (ret < 0)
|
|
|
3259a4 |
return ret;
|
|
|
3259a4 |
|
|
|
3259a4 |
diff --git a/netlink/channels.c b/netlink/channels.c
|
|
|
3259a4 |
index c6002ceeb121..894c74bcc11a 100644
|
|
|
3259a4 |
--- a/netlink/channels.c
|
|
|
3259a4 |
+++ b/netlink/channels.c
|
|
|
3259a4 |
@@ -126,7 +126,7 @@ int nl_schannels(struct cmd_context *ctx)
|
|
|
3259a4 |
ctx->devname, 0))
|
|
|
3259a4 |
return -EMSGSIZE;
|
|
|
3259a4 |
|
|
|
3259a4 |
- ret = nl_parser(nlctx, schannels_params, NULL, PARSER_GROUP_NONE);
|
|
|
3259a4 |
+ ret = nl_parser(nlctx, schannels_params, NULL, PARSER_GROUP_NONE, NULL);
|
|
|
3259a4 |
if (ret < 0)
|
|
|
3259a4 |
return 1;
|
|
|
3259a4 |
|
|
|
3259a4 |
diff --git a/netlink/coalesce.c b/netlink/coalesce.c
|
|
|
3259a4 |
index 65f75cf9a8dd..0223f8e3484e 100644
|
|
|
3259a4 |
--- a/netlink/coalesce.c
|
|
|
3259a4 |
+++ b/netlink/coalesce.c
|
|
|
3259a4 |
@@ -254,7 +254,7 @@ int nl_scoalesce(struct cmd_context *ctx)
|
|
|
3259a4 |
ctx->devname, 0))
|
|
|
3259a4 |
return -EMSGSIZE;
|
|
|
3259a4 |
|
|
|
3259a4 |
- ret = nl_parser(nlctx, scoalesce_params, NULL, PARSER_GROUP_NONE);
|
|
|
3259a4 |
+ ret = nl_parser(nlctx, scoalesce_params, NULL, PARSER_GROUP_NONE, NULL);
|
|
|
3259a4 |
if (ret < 0)
|
|
|
3259a4 |
return 1;
|
|
|
3259a4 |
|
|
|
3259a4 |
diff --git a/netlink/eee.c b/netlink/eee.c
|
|
|
3259a4 |
index d3135b2094a4..04d8f0bbe3fc 100644
|
|
|
3259a4 |
--- a/netlink/eee.c
|
|
|
3259a4 |
+++ b/netlink/eee.c
|
|
|
3259a4 |
@@ -174,7 +174,7 @@ int nl_seee(struct cmd_context *ctx)
|
|
|
3259a4 |
ctx->devname, 0))
|
|
|
3259a4 |
return -EMSGSIZE;
|
|
|
3259a4 |
|
|
|
3259a4 |
- ret = nl_parser(nlctx, seee_params, NULL, PARSER_GROUP_NONE);
|
|
|
3259a4 |
+ ret = nl_parser(nlctx, seee_params, NULL, PARSER_GROUP_NONE, NULL);
|
|
|
3259a4 |
if (ret < 0)
|
|
|
3259a4 |
return 1;
|
|
|
3259a4 |
|
|
|
3259a4 |
diff --git a/netlink/parser.c b/netlink/parser.c
|
|
|
3259a4 |
index 3b25f5d5a88e..c2eae93efb69 100644
|
|
|
3259a4 |
--- a/netlink/parser.c
|
|
|
3259a4 |
+++ b/netlink/parser.c
|
|
|
3259a4 |
@@ -920,7 +920,7 @@ static void __parser_set(uint64_t *map, unsigned int idx)
|
|
|
3259a4 |
}
|
|
|
3259a4 |
|
|
|
3259a4 |
struct tmp_buff {
|
|
|
3259a4 |
- struct nl_msg_buff msgbuff;
|
|
|
3259a4 |
+ struct nl_msg_buff *msgbuff;
|
|
|
3259a4 |
unsigned int id;
|
|
|
3259a4 |
unsigned int orig_len;
|
|
|
3259a4 |
struct tmp_buff *next;
|
|
|
3259a4 |
@@ -951,7 +951,12 @@ static struct tmp_buff *tmp_buff_find_or_create(struct tmp_buff **phead,
|
|
|
3259a4 |
if (!new_buff)
|
|
|
3259a4 |
return NULL;
|
|
|
3259a4 |
new_buff->id = id;
|
|
|
3259a4 |
- msgbuff_init(&new_buff->msgbuff);
|
|
|
3259a4 |
+ new_buff->msgbuff = malloc(sizeof(*new_buff->msgbuff));
|
|
|
3259a4 |
+ if (!new_buff->msgbuff) {
|
|
|
3259a4 |
+ free(new_buff);
|
|
|
3259a4 |
+ return NULL;
|
|
|
3259a4 |
+ }
|
|
|
3259a4 |
+ msgbuff_init(new_buff->msgbuff);
|
|
|
3259a4 |
new_buff->next = NULL;
|
|
|
3259a4 |
*pbuff = new_buff;
|
|
|
3259a4 |
|
|
|
3259a4 |
@@ -965,7 +970,10 @@ static void tmp_buff_destroy(struct tmp_buff *head)
|
|
|
3259a4 |
|
|
|
3259a4 |
while (buff) {
|
|
|
3259a4 |
next = buff->next;
|
|
|
3259a4 |
- msgbuff_done(&buff->msgbuff);
|
|
|
3259a4 |
+ if (buff->msgbuff) {
|
|
|
3259a4 |
+ msgbuff_done(buff->msgbuff);
|
|
|
3259a4 |
+ free(buff->msgbuff);
|
|
|
3259a4 |
+ }
|
|
|
3259a4 |
free(buff);
|
|
|
3259a4 |
buff = next;
|
|
|
3259a4 |
}
|
|
|
3259a4 |
@@ -980,13 +988,22 @@ static void tmp_buff_destroy(struct tmp_buff *head)
|
|
|
3259a4 |
* param_parser::offset)
|
|
|
3259a4 |
* @group_style: defines if identifiers in .group represent separate messages,
|
|
|
3259a4 |
* nested attributes or are not allowed
|
|
|
3259a4 |
+ * @msgbuffs: (only used for @group_style = PARSER_GROUP_MSG) array to store
|
|
|
3259a4 |
+ * pointers to composed messages; caller must make sure this
|
|
|
3259a4 |
+ * array is sufficient, i.e. that it has at least as many entries
|
|
|
3259a4 |
+ * as the number of different .group values in params array;
|
|
|
3259a4 |
+ * entries are filled from the start, remaining entries are not
|
|
|
3259a4 |
+ * modified; caller should zero initialize the array before
|
|
|
3259a4 |
+ * calling nl_parser()
|
|
|
3259a4 |
*/
|
|
|
3259a4 |
int nl_parser(struct nl_context *nlctx, const struct param_parser *params,
|
|
|
3259a4 |
- void *dest, enum parser_group_style group_style)
|
|
|
3259a4 |
+ void *dest, enum parser_group_style group_style,
|
|
|
3259a4 |
+ struct nl_msg_buff **msgbuffs)
|
|
|
3259a4 |
{
|
|
|
3259a4 |
struct nl_socket *nlsk = nlctx->ethnl_socket;
|
|
|
3259a4 |
const struct param_parser *parser;
|
|
|
3259a4 |
struct tmp_buff *buffs = NULL;
|
|
|
3259a4 |
+ unsigned int n_msgbuffs = 0;
|
|
|
3259a4 |
struct tmp_buff *buff;
|
|
|
3259a4 |
unsigned int n_params;
|
|
|
3259a4 |
uint64_t *params_seen;
|
|
|
3259a4 |
@@ -1004,7 +1021,7 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params,
|
|
|
3259a4 |
buff = tmp_buff_find_or_create(&buffs, parser->group);
|
|
|
3259a4 |
if (!buff)
|
|
|
3259a4 |
goto out_free_buffs;
|
|
|
3259a4 |
- msgbuff = &buff->msgbuff;
|
|
|
3259a4 |
+ msgbuff = buff->msgbuff;
|
|
|
3259a4 |
ret = msg_init(nlctx, msgbuff, parser->group,
|
|
|
3259a4 |
NLM_F_REQUEST | NLM_F_ACK);
|
|
|
3259a4 |
if (ret < 0)
|
|
|
3259a4 |
@@ -1013,7 +1030,7 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params,
|
|
|
3259a4 |
switch (group_style) {
|
|
|
3259a4 |
case PARSER_GROUP_NEST:
|
|
|
3259a4 |
ret = -EMSGSIZE;
|
|
|
3259a4 |
- nest = ethnla_nest_start(&buff->msgbuff, parser->group);
|
|
|
3259a4 |
+ nest = ethnla_nest_start(buff->msgbuff, parser->group);
|
|
|
3259a4 |
if (!nest)
|
|
|
3259a4 |
goto out_free_buffs;
|
|
|
3259a4 |
break;
|
|
|
3259a4 |
@@ -1062,7 +1079,7 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params,
|
|
|
3259a4 |
buff = NULL;
|
|
|
3259a4 |
if (parser->group)
|
|
|
3259a4 |
buff = tmp_buff_find(buffs, parser->group);
|
|
|
3259a4 |
- msgbuff = buff ? &buff->msgbuff : &nlsk->msgbuff;
|
|
|
3259a4 |
+ msgbuff = buff ? buff->msgbuff : &nlsk->msgbuff;
|
|
|
3259a4 |
|
|
|
3259a4 |
param_dest = dest ? ((char *)dest + parser->dest_offset) : NULL;
|
|
|
3259a4 |
ret = parser->handler(nlctx, parser->type, parser->handler_data,
|
|
|
3259a4 |
@@ -1074,12 +1091,12 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params,
|
|
|
3259a4 |
if (group_style == PARSER_GROUP_MSG) {
|
|
|
3259a4 |
ret = -EOPNOTSUPP;
|
|
|
3259a4 |
for (buff = buffs; buff; buff = buff->next)
|
|
|
3259a4 |
- if (msgbuff_len(&buff->msgbuff) > buff->orig_len &&
|
|
|
3259a4 |
+ if (msgbuff_len(buff->msgbuff) > buff->orig_len &&
|
|
|
3259a4 |
netlink_cmd_check(nlctx->ctx, buff->id, false))
|
|
|
3259a4 |
goto out_free;
|
|
|
3259a4 |
}
|
|
|
3259a4 |
for (buff = buffs; buff; buff = buff->next) {
|
|
|
3259a4 |
- struct nl_msg_buff *msgbuff = &buff->msgbuff;
|
|
|
3259a4 |
+ struct nl_msg_buff *msgbuff = buff->msgbuff;
|
|
|
3259a4 |
|
|
|
3259a4 |
if (group_style == PARSER_GROUP_NONE ||
|
|
|
3259a4 |
msgbuff_len(msgbuff) == buff->orig_len)
|
|
|
3259a4 |
@@ -1092,12 +1109,8 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params,
|
|
|
3259a4 |
goto out_free;
|
|
|
3259a4 |
break;
|
|
|
3259a4 |
case PARSER_GROUP_MSG:
|
|
|
3259a4 |
- ret = nlsock_sendmsg(nlsk, msgbuff);
|
|
|
3259a4 |
- if (ret < 0)
|
|
|
3259a4 |
- goto out_free;
|
|
|
3259a4 |
- ret = nlsock_process_reply(nlsk, nomsg_reply_cb, NULL);
|
|
|
3259a4 |
- if (ret < 0)
|
|
|
3259a4 |
- goto out_free;
|
|
|
3259a4 |
+ msgbuffs[n_msgbuffs++] = msgbuff;
|
|
|
3259a4 |
+ buff->msgbuff = NULL;
|
|
|
3259a4 |
break;
|
|
|
3259a4 |
default:
|
|
|
3259a4 |
break;
|
|
|
3259a4 |
diff --git a/netlink/parser.h b/netlink/parser.h
|
|
|
3259a4 |
index fd55bc768d42..28f26ccc2a1c 100644
|
|
|
3259a4 |
--- a/netlink/parser.h
|
|
|
3259a4 |
+++ b/netlink/parser.h
|
|
|
3259a4 |
@@ -143,6 +143,7 @@ int nl_parse_char_bitset(struct nl_context *nlctx, uint16_t type,
|
|
|
3259a4 |
|
|
|
3259a4 |
/* main entry point called to parse the command line */
|
|
|
3259a4 |
int nl_parser(struct nl_context *nlctx, const struct param_parser *params,
|
|
|
3259a4 |
- void *dest, enum parser_group_style group_style);
|
|
|
3259a4 |
+ void *dest, enum parser_group_style group_style,
|
|
|
3259a4 |
+ struct nl_msg_buff **msgbuffs);
|
|
|
3259a4 |
|
|
|
3259a4 |
#endif /* ETHTOOL_NETLINK_PARSER_H__ */
|
|
|
3259a4 |
diff --git a/netlink/pause.c b/netlink/pause.c
|
|
|
3259a4 |
index 7b6b3a1d2c10..048320b123d2 100644
|
|
|
3259a4 |
--- a/netlink/pause.c
|
|
|
3259a4 |
+++ b/netlink/pause.c
|
|
|
3259a4 |
@@ -208,7 +208,7 @@ int nl_spause(struct cmd_context *ctx)
|
|
|
3259a4 |
ctx->devname, 0))
|
|
|
3259a4 |
return -EMSGSIZE;
|
|
|
3259a4 |
|
|
|
3259a4 |
- ret = nl_parser(nlctx, spause_params, NULL, PARSER_GROUP_NONE);
|
|
|
3259a4 |
+ ret = nl_parser(nlctx, spause_params, NULL, PARSER_GROUP_NONE, NULL);
|
|
|
3259a4 |
if (ret < 0)
|
|
|
3259a4 |
return 1;
|
|
|
3259a4 |
|
|
|
3259a4 |
diff --git a/netlink/rings.c b/netlink/rings.c
|
|
|
3259a4 |
index 4061520212d5..b8c458fce25f 100644
|
|
|
3259a4 |
--- a/netlink/rings.c
|
|
|
3259a4 |
+++ b/netlink/rings.c
|
|
|
3259a4 |
@@ -126,7 +126,7 @@ int nl_sring(struct cmd_context *ctx)
|
|
|
3259a4 |
ctx->devname, 0))
|
|
|
3259a4 |
return -EMSGSIZE;
|
|
|
3259a4 |
|
|
|
3259a4 |
- ret = nl_parser(nlctx, sring_params, NULL, PARSER_GROUP_NONE);
|
|
|
3259a4 |
+ ret = nl_parser(nlctx, sring_params, NULL, PARSER_GROUP_NONE, NULL);
|
|
|
3259a4 |
if (ret < 0)
|
|
|
3259a4 |
return 1;
|
|
|
3259a4 |
|
|
|
3259a4 |
diff --git a/netlink/settings.c b/netlink/settings.c
|
|
|
3259a4 |
index 75db15e5069c..fac192e2fbb7 100644
|
|
|
3259a4 |
--- a/netlink/settings.c
|
|
|
3259a4 |
+++ b/netlink/settings.c
|
|
|
3259a4 |
@@ -1108,9 +1108,16 @@ static const struct param_parser sset_params[] = {
|
|
|
3259a4 |
{}
|
|
|
3259a4 |
};
|
|
|
3259a4 |
|
|
|
3259a4 |
+/* Maximum number of request messages sent to kernel; must be equal to the
|
|
|
3259a4 |
+ * number of different .group values in sset_params[] array.
|
|
|
3259a4 |
+ */
|
|
|
3259a4 |
+#define SSET_MAX_MSGS 4
|
|
|
3259a4 |
+
|
|
|
3259a4 |
int nl_sset(struct cmd_context *ctx)
|
|
|
3259a4 |
{
|
|
|
3259a4 |
+ struct nl_msg_buff *msgbuffs[SSET_MAX_MSGS] = {};
|
|
|
3259a4 |
struct nl_context *nlctx = ctx->nlctx;
|
|
|
3259a4 |
+ unsigned int i;
|
|
|
3259a4 |
int ret;
|
|
|
3259a4 |
|
|
|
3259a4 |
nlctx->cmd = "-s";
|
|
|
3259a4 |
@@ -1118,11 +1125,29 @@ int nl_sset(struct cmd_context *ctx)
|
|
|
3259a4 |
nlctx->argc = ctx->argc;
|
|
|
3259a4 |
nlctx->devname = ctx->devname;
|
|
|
3259a4 |
|
|
|
3259a4 |
- ret = nl_parser(nlctx, sset_params, NULL, PARSER_GROUP_MSG);
|
|
|
3259a4 |
- if (ret < 0)
|
|
|
3259a4 |
- return 1;
|
|
|
3259a4 |
+ ret = nl_parser(nlctx, sset_params, NULL, PARSER_GROUP_MSG, msgbuffs);
|
|
|
3259a4 |
+ if (ret < 0) {
|
|
|
3259a4 |
+ ret = 1;
|
|
|
3259a4 |
+ goto out_free;
|
|
|
3259a4 |
+ }
|
|
|
3259a4 |
+
|
|
|
3259a4 |
+ for (i = 0; i < SSET_MAX_MSGS && msgbuffs[i]; i++) {
|
|
|
3259a4 |
+ struct nl_socket *nlsk = nlctx->ethnl_socket;
|
|
|
3259a4 |
|
|
|
3259a4 |
- if (ret == 0)
|
|
|
3259a4 |
- return 0;
|
|
|
3259a4 |
+ ret = nlsock_sendmsg(nlsk, msgbuffs[i]);
|
|
|
3259a4 |
+ if (ret < 0)
|
|
|
3259a4 |
+ goto out_free;
|
|
|
3259a4 |
+ ret = nlsock_process_reply(nlsk, nomsg_reply_cb, NULL);
|
|
|
3259a4 |
+ if (ret < 0)
|
|
|
3259a4 |
+ goto out_free;
|
|
|
3259a4 |
+ }
|
|
|
3259a4 |
+
|
|
|
3259a4 |
+out_free:
|
|
|
3259a4 |
+ for (i = 0; i < SSET_MAX_MSGS && msgbuffs[i]; i++) {
|
|
|
3259a4 |
+ msgbuff_done(msgbuffs[i]);
|
|
|
3259a4 |
+ free(msgbuffs[i]);
|
|
|
3259a4 |
+ }
|
|
|
3259a4 |
+ if (ret >= 0)
|
|
|
3259a4 |
+ return ret;
|
|
|
3259a4 |
return nlctx->exit_code ?: 75;
|
|
|
3259a4 |
}
|
|
|
3259a4 |
--
|
|
|
3259a4 |
2.26.2
|
|
|
3259a4 |
|