[libvirt] [PATCH v2] virnetdev: fix build with old kernel

Commit c9027d8f added a detection of NIC HW features, but some of them are not available in old kernel. Very old kernels lack enum ethtool_flags and even if this enum is present, not all values are available for all kernels. To be sure that we have everything in kernel that we need, we must check for existence of most of that flags, because only few of them were defined at first. Also to successfully build libvirt with older kernel we need to include <linux/types.h> before <linux/ethtool.h> to have __u32 and friends defined. Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- configure.ac | 5 +++++ src/util/virnetdev.c | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index e071813..2fedd1a 100644 --- a/configure.ac +++ b/configure.ac @@ -383,6 +383,11 @@ AC_CHECK_TYPE([struct ifreq], #include <net/if.h> ]]) +AC_CHECK_DECLS([ETH_FLAG_TXVLAN, ETH_FLAG_NTUPLE, ETH_FLAG_RXHASH, ETH_FLAG_LRO, + ETHTOOL_GGSO, ETHTOOL_GGRO, ETHTOOL_GFLAGS], + [], [], [[#include <linux/ethtool.h> + ]]) + dnl Our only use of libtasn1.h is in the testsuite, and can be skipped dnl if the header is not present. Assume -ltasn1 is present if the dnl header could be found. diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 971db43..093c99c 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -48,6 +48,7 @@ #endif #if defined(SIOCETHTOOL) && defined(HAVE_STRUCT_IFREQ) +# include <linux/types.h> # include <linux/ethtool.h> #endif @@ -2800,9 +2801,7 @@ int virNetDevGetFeatures(const char *ifname, virBitmapPtr *out) { - int ret = -1; size_t i = -1; - size_t j = -1; struct ethtool_value cmd = { 0 }; struct elem{ @@ -2815,20 +2814,16 @@ virNetDevGetFeatures(const char *ifname, {ETHTOOL_GTXCSUM, VIR_NET_DEV_FEAT_GTXCSUM}, {ETHTOOL_GSG, VIR_NET_DEV_FEAT_GSG}, {ETHTOOL_GTSO, VIR_NET_DEV_FEAT_GTSO}, +# if HAVE_DECL_ETHTOOL_GGSO {ETHTOOL_GGSO, VIR_NET_DEV_FEAT_GGSO}, +# endif +# if HAVE_DECL_ETHTOOL_GGRO {ETHTOOL_GGRO, VIR_NET_DEV_FEAT_GGRO}, - }; - /* ethtool masks */ - struct elem flags[] = { - {ETH_FLAG_LRO, VIR_NET_DEV_FEAT_LRO}, - {ETH_FLAG_RXVLAN, VIR_NET_DEV_FEAT_RXVLAN}, - {ETH_FLAG_TXVLAN, VIR_NET_DEV_FEAT_TXVLAN}, - {ETH_FLAG_NTUPLE, VIR_NET_DEV_FEAT_NTUPLE}, - {ETH_FLAG_RXHASH, VIR_NET_DEV_FEAT_RXHASH}, +# endif }; if (!(*out = virBitmapNew(VIR_NET_DEV_FEAT_LAST))) - goto cleanup; + return -1; for (i = 0; i < ARRAY_CARDINALITY(cmds); i++) { cmd.cmd = cmds[i].cmd; @@ -2836,6 +2831,25 @@ virNetDevGetFeatures(const char *ifname, ignore_value(virBitmapSetBit(*out, cmds[i].feat)); } +# if HAVE_DECL_ETHTOOL_GFLAGS + size_t j = -1; + /* ethtool masks */ + struct elem flags[] = { +# if HAVE_DECL_ETH_FLAG_LRO + {ETH_FLAG_LRO, VIR_NET_DEV_FEAT_LRO}, +# endif +# if HAVE_DECL_ETH_FLAG_TXVLAN + {ETH_FLAG_RXVLAN, VIR_NET_DEV_FEAT_RXVLAN}, + {ETH_FLAG_TXVLAN, VIR_NET_DEV_FEAT_TXVLAN}, +# endif +# if HAVE_DECL_ETH_FLAG_NTUBLE + {ETH_FLAG_NTUPLE, VIR_NET_DEV_FEAT_NTUPLE}, +# endif +# if HAVE_DECL_ETH_FLAG_RXHASH + {ETH_FLAG_RXHASH, VIR_NET_DEV_FEAT_RXHASH}, +# endif + }; + cmd.cmd = ETHTOOL_GFLAGS; if (virNetDevFeatureAvailable(ifname, &cmd)) { for (j = 0; j < ARRAY_CARDINALITY(flags); j++) { @@ -2843,12 +2857,9 @@ virNetDevGetFeatures(const char *ifname, ignore_value(virBitmapSetBit(*out, flags[j].feat)); } } +# endif - ret = 0; - cleanup: - - return ret; - + return 0; } #else int -- 2.0.5

On 11.03.2015 15:27, Pavel Hrdina wrote:
Commit c9027d8f added a detection of NIC HW features, but some of them are not available in old kernel. Very old kernels lack enum ethtool_flags and even if this enum is present, not all values are available for all kernels. To be sure that we have everything in kernel that we need, we must check for existence of most of that flags, because only few of them were defined at first.
Also to successfully build libvirt with older kernel we need to include <linux/types.h> before <linux/ethtool.h> to have __u32 and friends defined.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- configure.ac | 5 +++++ src/util/virnetdev.c | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/configure.ac b/configure.ac index e071813..2fedd1a 100644 --- a/configure.ac +++ b/configure.ac @@ -383,6 +383,11 @@ AC_CHECK_TYPE([struct ifreq], #include <net/if.h> ]])
+AC_CHECK_DECLS([ETH_FLAG_TXVLAN, ETH_FLAG_NTUPLE, ETH_FLAG_RXHASH, ETH_FLAG_LRO, + ETHTOOL_GGSO, ETHTOOL_GGRO, ETHTOOL_GFLAGS], + [], [], [[#include <linux/ethtool.h> + ]]) +
GSO and GRO were added in the same commit 37c3185a. So one of these checks can be dropped. ACK with that fixed. Michal

On Thu, Mar 12, 2015 at 04:43:28PM +0100, Michal Privoznik wrote:
On 11.03.2015 15:27, Pavel Hrdina wrote:
Commit c9027d8f added a detection of NIC HW features, but some of them are not available in old kernel. Very old kernels lack enum ethtool_flags and even if this enum is present, not all values are available for all kernels. To be sure that we have everything in kernel that we need, we must check for existence of most of that flags, because only few of them were defined at first.
Also to successfully build libvirt with older kernel we need to include <linux/types.h> before <linux/ethtool.h> to have __u32 and friends defined.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- configure.ac | 5 +++++ src/util/virnetdev.c | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/configure.ac b/configure.ac index e071813..2fedd1a 100644 --- a/configure.ac +++ b/configure.ac @@ -383,6 +383,11 @@ AC_CHECK_TYPE([struct ifreq], #include <net/if.h> ]])
+AC_CHECK_DECLS([ETH_FLAG_TXVLAN, ETH_FLAG_NTUPLE, ETH_FLAG_RXHASH, ETH_FLAG_LRO, + ETHTOOL_GGSO, ETHTOOL_GGRO, ETHTOOL_GFLAGS], + [], [], [[#include <linux/ethtool.h> + ]]) +
GSO and GRO were added in the same commit 37c3185a. So one of these checks can be dropped.
Well, actually only SGSO and GGSO are in that commit and SGRO and GGRO are in different commit b240a0e5. Pushed now with both checks, thanks for review. Pavel
ACK with that fixed.
Michal
participants (2)
-
Michal Privoznik
-
Pavel Hrdina