diff options
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | ethtool.c | 101 | ||||
-rw-r--r-- | rxclass.c | 1 |
4 files changed, 85 insertions, 28 deletions
@@ -1,3 +1,12 @@ +Version 3.4.2 - July 16, 2012 + + * Fix: Fix regression in RX NFC rule insertion for drivers that do + not select rule locations (-N/-U option) + * Fix: Remove bogus error message when changing offload settings + on Linux < 2.6.39 (-K option) + * Fix: Use alternate method to check for VLAN tag offload on Linux + < 2.6.37 (-k option) + Version 3.4.1 - June 13, 2012 * Fix: Work around failure of ETHTOOL_GSSET_INFO for unprivileged diff --git a/configure.ac b/configure.ac index 11b4935..16d8e62 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.1, netdev@vger.kernel.org) +AC_INIT(ethtool, 3.4.2, netdev@vger.kernel.org) AC_PREREQ(2.52) AC_CONFIG_SRCDIR([ethtool.c]) AM_INIT_AUTOMAKE([gnu]) @@ -33,6 +33,8 @@ #include <sys/utsname.h> #include <limits.h> #include <ctype.h> +#include <assert.h> +#include <sys/fcntl.h> #include <sys/socket.h> #include <netinet/in.h> @@ -1435,6 +1437,31 @@ static struct feature_defs *get_feature_defs(struct cmd_context *ctx) return defs; } +static int get_netdev_attr(struct cmd_context *ctx, const char *name, + char *buf, size_t buf_len) +{ +#ifdef TEST_ETHTOOL + errno = ENOENT; + return -1; +#else + char path[40 + IFNAMSIZ]; + ssize_t len; + int fd; + + len = snprintf(path, sizeof(path), "/sys/class/net/%s/%s", + ctx->devname, name); + assert(len < sizeof(path)); + fd = open(path, O_RDONLY); + if (fd < 0) + return fd; + len = read(fd, buf, buf_len - 1); + if (len >= 0) + buf[len] = 0; + close(fd); + return len; +#endif +} + static int do_gdrv(struct cmd_context *ctx) { int err; @@ -1876,6 +1903,20 @@ get_features(struct cmd_context *ctx, const struct feature_defs *defs) perror("Cannot get device generic features"); else allfail = 0; + } else { + /* We should have got VLAN tag offload flags through + * ETHTOOL_GFLAGS. However, prior to Linux 2.6.37 + * they were not exposed in this way - and since VLAN + * tag offload was defined and implemented by many + * drivers, we shouldn't assume they are off. + * Instead, since these feature flag values were + * stable, read them from sysfs. + */ + char buf[20]; + if (get_netdev_attr(ctx, "features", buf, sizeof(buf)) > 0) + state->off_flags |= + strtoul(buf, NULL, 0) & + (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); } if (allfail) { @@ -1980,39 +2021,45 @@ static int do_sfeatures(struct cmd_context *ctx) if (!old_state) return 1; - /* For each offload that the user specified, update any - * related features that the user did not specify and that - * are not fixed. Warn if all related features are fixed. - */ - for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { - int fixed = 1; - - if (!(off_flags_mask & off_flag_def[i].value)) - continue; + if (efeatures) { + /* For each offload that the user specified, update any + * related features that the user did not specify and that + * are not fixed. Warn if all related features are fixed. + */ + for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { + int fixed = 1; - for (j = 0; j < defs->n_features; j++) { - if (defs->def[j].off_flag_index != i || - !FEATURE_BIT_IS_SET(old_state->features.features, - j, available) || - FEATURE_BIT_IS_SET(old_state->features.features, - j, never_changed)) + if (!(off_flags_mask & off_flag_def[i].value)) continue; - fixed = 0; - if (!FEATURE_BIT_IS_SET(efeatures->features, j, valid)) { - FEATURE_BIT_SET(efeatures->features, j, valid); - if (off_flags_wanted & off_flag_def[i].value) - FEATURE_BIT_SET(efeatures->features, j, - requested); + for (j = 0; j < defs->n_features; j++) { + if (defs->def[j].off_flag_index != i || + !FEATURE_BIT_IS_SET( + old_state->features.features, + j, available) || + FEATURE_BIT_IS_SET( + old_state->features.features, + j, never_changed)) + continue; + + fixed = 0; + if (!FEATURE_BIT_IS_SET(efeatures->features, + j, valid)) { + FEATURE_BIT_SET(efeatures->features, + j, valid); + if (off_flags_wanted & + off_flag_def[i].value) + FEATURE_BIT_SET( + efeatures->features, + j, requested); + } } - } - if (fixed) - fprintf(stderr, "Cannot change %s\n", - off_flag_def[i].long_name); - } + if (fixed) + fprintf(stderr, "Cannot change %s\n", + off_flag_def[i].long_name); + } - if (efeatures) { err = send_ioctl(ctx, efeatures); if (err < 0) { perror("Cannot set device feature settings"); @@ -207,6 +207,7 @@ static int rxclass_get_dev_info(struct cmd_context *ctx, __u32 *count, int err; nfccmd.cmd = ETHTOOL_GRXCLSRLCNT; + nfccmd.data = 0; err = send_ioctl(ctx, &nfccmd); *count = nfccmd.rule_cnt; if (driver_select) |