summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-07-16 22:56:05 +0100
committerBen Hutchings <bhutchings@solarflare.com>2012-07-16 23:26:13 +0100
commit1cddbe64cfc66b58988c85086d6df3a77c0c61a5 (patch)
tree3244e14f36668acdde7de83d28f99b8cbaed5f37
parentb982755ffffb67ef8c5738707fbf8a1a8685d99b (diff)
downloadethtool-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.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/ethtool.c b/ethtool.c
index b424756..9991ce2 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -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) {