diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-07-16 22:56:05 +0100 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2012-07-16 23:26:13 +0100 |
commit | 1cddbe64cfc66b58988c85086d6df3a77c0c61a5 (patch) | |
tree | 3244e14f36668acdde7de83d28f99b8cbaed5f37 | |
parent | b982755ffffb67ef8c5738707fbf8a1a8685d99b (diff) | |
download | ethtool-1cddbe64cfc66b58988c85086d6df3a77c0c61a5.tar.gz |
Fix reporting of VLAN tag offload flags on Linux < 2.6.37
These kernel versions implement ETHTOOL_GFLAGS but do not include the
flags for VLAN tag offload (and do not implement ETHTOOL_GFEATURES).
Since the VLAN tag offload features were already 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.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r-- | ethtool.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -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> @@ -1417,6 +1419,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; @@ -1858,6 +1885,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) { |