The legacy ethtool prints an error message and returns 1 if no features were changed as requested. Port this behavior to ethtool-netlink. req_mask is compared to wanted_mask to detect if any feature was changed. If these masks are equal, it means that the kernel hasn't changed anything, and all bits got to wanted.
Signed-off-by: Maxim Mikityanskiy <maxi...@mellanox.com> --- netlink/features.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/netlink/features.c b/netlink/features.c index 133529d..4f63fa2 100644 --- a/netlink/features.c +++ b/netlink/features.c @@ -378,7 +378,7 @@ err: return ret; } -static void show_feature_changes(struct nl_context *nlctx, +static bool show_feature_changes(struct nl_context *nlctx, const struct nlattr *const *tb) { struct sfeatures_context *sfctx = nlctx->cmd_private; @@ -388,8 +388,8 @@ static void show_feature_changes(struct nl_context *nlctx, const uint32_t *wanted_val; const uint32_t *active_val; unsigned int count, words; + bool any_changed, diff; unsigned int i; - bool diff; int ret; feature_names = global_stringset(ETH_SS_FEATURES, nlctx->ethnl_socket); @@ -411,12 +411,20 @@ static void show_feature_changes(struct nl_context *nlctx, if (!wanted_val || !wanted_mask || !active_val || !active_mask) goto err; + any_changed = false; diff = false; - for (i = 0; i < words; i++) + for (i = 0; i < words; i++) { + if (wanted_mask[i] != sfctx->req_mask[i]) + any_changed = true; if (wanted_mask[i] || (active_mask[i] & ~sfctx->req_mask[i])) diff = true; + } + if (!any_changed) { + fprintf(stderr, "Could not change any device features\n"); + nlctx->exit_code = 1; + } if (!diff) - return; + return any_changed; /* result is not exactly as requested, show differences */ printf("Actual changes:\n"); @@ -442,9 +450,10 @@ static void show_feature_changes(struct nl_context *nlctx, fputc('\n', stdout); } - return; + return any_changed; err: fprintf(stderr, "malformed diff info from kernel\n"); + return false; } int sfeatures_reply_cb(const struct nlmsghdr *nlhdr, void *data) @@ -471,8 +480,10 @@ int sfeatures_reply_cb(const struct nlmsghdr *nlhdr, void *data) return MNL_CB_OK; } - show_feature_changes(nlctx, tb); - return MNL_CB_OK; + if (show_feature_changes(nlctx, tb)) + return MNL_CB_OK; + else + return MNL_CB_ERROR; } int nl_sfeatures(struct cmd_context *ctx) -- 2.21.0