summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--configure.ac2
-rw-r--r--ethtool.8.in2
-rw-r--r--ethtool.c12
-rw-r--r--test-features.c28
5 files changed, 48 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 4f8746d..b72df24 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+Version 3.4.1 - June 13, 2012
+
+ * Fix: Work around failure of ETHTOOL_GSSET_INFO for unprivileged
+ users (-k option)
+ * Fix: Report any unexpected error code from ETHTOOL_GSSET_INFO
+ (-k and -K options)
+ * Doc: Fix the date of the man page to match the last update
+
Version 3.4 - June 8, 2012
* Cleanup: Merge RX NFC options
diff --git a/configure.ac b/configure.ac
index a55fca4..11b4935 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(ethtool, 3.4, netdev@vger.kernel.org)
+AC_INIT(ethtool, 3.4.1, netdev@vger.kernel.org)
AC_PREREQ(2.52)
AC_CONFIG_SRCDIR([ethtool.c])
AM_INIT_AUTOMAKE([gnu])
diff --git a/ethtool.8.in b/ethtool.8.in
index 70ae31d..cf2a09c 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -113,7 +113,7 @@
. hy \\n(HY
..
.
-.TH ETHTOOL 8 "January 2011" "Ethtool version @VERSION@"
+.TH ETHTOOL 8 "June 2012" "Ethtool version @VERSION@"
.SH NAME
ethtool \- query or control network driver and hardware settings
.
diff --git a/ethtool.c b/ethtool.c
index 3576f4c..b0d3eea 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1337,6 +1337,10 @@ static struct feature_defs *get_feature_defs(struct cmd_context *ctx)
} else if (errno == EOPNOTSUPP || errno == EINVAL) {
/* Kernel doesn't support named features; not an error */
n_features = 0;
+ } else if (errno == EPERM) {
+ /* Kernel bug: ETHTOOL_GSSET_INFO was privileged.
+ * Work around it. */
+ n_features = 0;
} else {
return NULL;
}
@@ -1850,8 +1854,10 @@ static int do_gfeatures(struct cmd_context *ctx)
exit_bad_args();
defs = get_feature_defs(ctx);
- if (!defs)
+ if (!defs) {
+ perror("Cannot get device feature names");
return 1;
+ }
fprintf(stdout, "Features for %s:\n", ctx->devname);
@@ -1879,8 +1885,10 @@ static int do_sfeatures(struct cmd_context *ctx)
int i, j;
defs = get_feature_defs(ctx);
- if (!defs)
+ if (!defs) {
+ perror("Cannot get device feature names");
return 1;
+ }
if (defs->n_features) {
efeatures = malloc(sizeof(*efeatures) +
FEATURE_BITS_TO_BLOCKS(defs->n_features) *
diff --git a/test-features.c b/test-features.c
index a48c701..d7bd994 100644
--- a/test-features.c
+++ b/test-features.c
@@ -80,6 +80,32 @@ static const struct cmd_expect cmd_expect_get_features_off_old[] = {
{ 0, 0, 0, 0, 0 }
};
+static const struct cmd_expect cmd_expect_get_features_off_old_some_unsup[] = {
+ { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
+ { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
+ { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
+ { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
+ { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
+ { &cmd_gufo_off, 4, -EOPNOTSUPP },
+ { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
+ { &cmd_ggro_off, 4, -EOPNOTSUPP },
+ { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
+ { 0, 0, 0, 0, 0 }
+};
+
+static const struct cmd_expect cmd_expect_get_features_off_old_some_priv[] = {
+ { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EPERM },
+ { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
+ { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
+ { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
+ { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
+ { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
+ { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
+ { &cmd_ggro_off, 4, -EPERM },
+ { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
+ { 0, 0, 0, 0, 0 }
+};
+
static const struct cmd_expect cmd_expect_set_features_off_old[] = {
{ &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
{ &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
@@ -443,6 +469,8 @@ static struct test_case {
const struct cmd_expect *expect;
} const test_cases[] = {
{ 0, "-k devname", cmd_expect_get_features_off_old },
+ { 0, "-k dev_unsup", cmd_expect_get_features_off_old_some_unsup },
+ { 0, "-k dev_priv", cmd_expect_get_features_off_old_some_priv },
{ 0, "-K devname rx off tx off sg off tso off ufo off gso off lro off rxvlan off txvlan off ntuple off rxhash off gro off",
cmd_expect_set_features_off_old },
{ 0, "-K devname rx on tx on sg on tso on ufo on gso on lro on rxvlan on txvlan on ntuple on rxhash on gro on",