#include "queue.h"
#include "unix-manager.h"
+#define OFFLOAD_FLAG_SG (1<<0)
+#define OFFLOAD_FLAG_TSO (1<<1)
+#define OFFLOAD_FLAG_GSO (1<<2)
+#define OFFLOAD_FLAG_GRO (1<<3)
+#define OFFLOAD_FLAG_LRO (1<<4)
+#define OFFLOAD_FLAG_RXCSUM (1<<5)
+#define OFFLOAD_FLAG_TXCSUM (1<<6)
+#define OFFLOAD_FLAG_TOE (1<<7)
+
+void LiveSetOffloadDisable(void);
+void LiveSetOffloadWarn(void);
+int LiveGetOffload(void);
+
#define MAX_DEVNAME 10
/** storage for live device names */
SC_ATOMIC_DECLARE(uint64_t, drop);
SC_ATOMIC_DECLARE(uint64_t, invalid_checksums);
TAILQ_ENTRY(LiveDevice_) next;
-} LiveDevice;
-void LiveSetOffloadDisable(void);
-void LiveSetOffloadWarn(void);
-int LiveGetOffload(void);
+ uint32_t offload_orig; /**< original offload settings to restore @exit */
+} LiveDevice;
int LiveRegisterDevice(const char *dev);
int LiveGetDeviceCount(void);
#include "suricata-common.h"
#include "conf.h"
+#include "util-device.h"
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
return ret;
}
-static int DisableIfaceOffloadingLinux(const char *dev, int csum, int other)
+static int DisableIfaceOffloadingLinux(LiveDevice *ldev, int csum, int other)
{
int ret = 0;
uint32_t value = 0;
+ if (ldev == NULL)
+ return -1;
+
+ const char *dev = ldev->dev;
+
if (csum) {
#ifdef ETHTOOL_GRXCSUM
if (GetEthtoolValue(dev, ETHTOOL_GRXCSUM, &value) == 0 && value != 0) {
SCLogInfo("%s: disabling rxcsum offloading", dev);
SetEthtoolValue(dev, ETHTOOL_SRXCSUM, 0);
+ ldev->offload_orig |= OFFLOAD_FLAG_RXCSUM;
}
#endif
#ifdef ETHTOOL_GTXCSUM
if (GetEthtoolValue(dev, ETHTOOL_GTXCSUM, &value) == 0 && value != 0) {
SCLogInfo("%s: disabling txcsum offloading", dev);
SetEthtoolValue(dev, ETHTOOL_STXCSUM, 0);
+ ldev->offload_orig |= OFFLOAD_FLAG_TXCSUM;
}
#endif
}
if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) {
SCLogInfo("%s: disabling gro offloading", dev);
SetEthtoolValue(dev, ETHTOOL_SGRO, 0);
+ ldev->offload_orig |= OFFLOAD_FLAG_GRO;
}
#endif
#ifdef ETHTOOL_GTSO
if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) {
SCLogInfo("%s: disabling tso offloading", dev);
SetEthtoolValue(dev, ETHTOOL_STSO, 0);
+ ldev->offload_orig |= OFFLOAD_FLAG_TSO;
}
#endif
#ifdef ETHTOOL_GGSO
if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) {
SCLogInfo("%s: disabling gso offloading", dev);
SetEthtoolValue(dev, ETHTOOL_SGSO, 0);
+ ldev->offload_orig |= OFFLOAD_FLAG_GSO;
}
#endif
#ifdef ETHTOOL_GSG
if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) {
SCLogInfo("%s: disabling sg offloading", dev);
SetEthtoolValue(dev, ETHTOOL_SSG, 0);
+ ldev->offload_orig |= OFFLOAD_FLAG_SG;
}
#endif
#ifdef ETHTOOL_GFLAGS
if (value & ETH_FLAG_LRO) {
SCLogInfo("%s: disabling lro offloading", dev);
SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ~ETH_FLAG_LRO);
+ ldev->offload_orig |= OFFLOAD_FLAG_LRO;
}
}
#endif
return ret;
}
+static int RestoreIfaceOffloadingLinux(LiveDevice *ldev)
+{
+ if (ldev == NULL)
+ return -1;
+
+ const char *dev = ldev->dev;
+
+#ifdef ETHTOOL_GRXCSUM
+ if (ldev->offload_orig & OFFLOAD_FLAG_RXCSUM) {
+ SCLogInfo("%s: restoring rxcsum offloading", dev);
+ SetEthtoolValue(dev, ETHTOOL_SRXCSUM, 1);
+ }
+#endif
+#ifdef ETHTOOL_GTXCSUM
+ if (ldev->offload_orig & OFFLOAD_FLAG_TXCSUM) {
+ SCLogInfo("%s: restoring txcsum offloading", dev);
+ SetEthtoolValue(dev, ETHTOOL_STXCSUM, 1);
+ }
+#endif
+#ifdef ETHTOOL_GGRO
+ if (ldev->offload_orig & OFFLOAD_FLAG_GRO) {
+ SCLogInfo("%s: restoring gro offloading", dev);
+ SetEthtoolValue(dev, ETHTOOL_SGRO, 1);
+ }
+#endif
+#ifdef ETHTOOL_GTSO
+ if (ldev->offload_orig & OFFLOAD_FLAG_TSO) {
+ SCLogInfo("%s: restoring tso offloading", dev);
+ SetEthtoolValue(dev, ETHTOOL_STSO, 1);
+ }
+#endif
+#ifdef ETHTOOL_GGSO
+ if (ldev->offload_orig & OFFLOAD_FLAG_GSO) {
+ SCLogInfo("%s: restoring gso offloading", dev);
+ SetEthtoolValue(dev, ETHTOOL_SGSO, 1);
+ }
+#endif
+#ifdef ETHTOOL_GSG
+ if (ldev->offload_orig & OFFLOAD_FLAG_SG) {
+ SCLogInfo("%s: restoring sg offloading", dev);
+ SetEthtoolValue(dev, ETHTOOL_SSG, 1);
+ }
+#endif
+#ifdef ETHTOOL_GFLAGS
+ if (ldev->offload_orig & OFFLOAD_FLAG_LRO) {
+ uint32_t value = 0;
+ if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) {
+ SCLogInfo("%s: restoring lro offloading", dev);
+ SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ETH_FLAG_LRO);
+ }
+ }
+#endif
+ return 0;
+}
+
#endif /* defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL */
#ifdef SIOCGIFCAP
#endif
}
-int DisableIfaceOffloading(const char *dev, int csum, int other)
+int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
{
#if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
return DisableIfaceOffloadingLinux(dev, csum, other);
}
+void RestoreIfaceOffloading(LiveDevice *dev)
+{
+ if (dev->offload_orig != 0) {
+#if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
+ RestoreIfaceOffloadingLinux(dev);
+#endif
+ }
+}
+
int GetIfaceRSSQueuesNum(const char *pcap_dev)
{
#if defined HAVE_LINUX_ETHTOOL_H && defined ETHTOOL_GRXRINGS