From d8fcd41f2c776e12d859a5e7693176dc9f55cca6 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 20 Jun 2016 20:11:55 +0200 Subject: [PATCH 1/9] offloading: preparation for disabling offload on BSD Add functions for setting IFCAP flags. --- src/util-ioctl.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ src/util-ioctl.h | 1 + 2 files changed, 72 insertions(+) diff --git a/src/util-ioctl.c b/src/util-ioctl.c index cfca00b3a4b2..5eb7b408c1f8 100644 --- a/src/util-ioctl.c +++ b/src/util-ioctl.c @@ -236,6 +236,33 @@ int GetIfaceCaps(const char *ifname) return ifr.ifr_curcap; } #endif +#ifdef SIOCSIFCAP +int SetIfaceCaps(const char *ifname, int caps) +{ + struct ifreq ifr; + + int fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + ifr.ifr_reqcap = caps; + + if (ioctl(fd, SIOCSIFCAP, &ifr) == -1) { + SCLogError(SC_ERR_SYSCALL, + "Unable to set caps for iface \"%s\": %s", + ifname, strerror(errno)); + close(fd); + return -1; + } + + close(fd); + return 0; +} +#endif + #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL static int GetEthtoolValue(const char *dev, int cmd, uint32_t *value) @@ -384,6 +411,40 @@ static int GetIfaceOffloadingBSD(const char *ifname) } #endif +#ifdef SIOCSIFCAP +static int DisableIfaceOffloadingBSD(const char *ifname) +{ + int ret = 0; + int if_caps = GetIfaceCaps(ifname); + int set_caps = if_caps; + if (if_caps == -1) { + return -1; + } + SCLogDebug("if_caps %X", if_caps); + + if (if_caps & IFCAP_RXCSUM) { + SCLogInfo("%s: disabling rxcsum offloading", ifname); + set_caps &= ~IFCAP_RXCSUM; + } + +#ifdef IFCAP_TOE + if (if_caps & (IFCAP_TSO|IFCAP_TOE|IFCAP_LRO)) { + SCLogInfo("%s: disabling tso|toe|lro offloading", ifname); + set_caps &= ~(IFCAP_TSO|IFCAP_LRO); + } +#else + if (if_caps & (IFCAP_TSO|IFCAP_LRO)) { + SCLogInfo("%s: disabling tso|lro offloading", ifname); + set_caps &= ~(IFCAP_TSO|IFCAP_LRO); + } +#endif + if (set_caps != if_caps) { + SetIfaceCaps(ifname, set_caps); + } + return ret; +} +#endif + /** * \brief output offloading status of the link * @@ -409,6 +470,16 @@ int GetIfaceOffloading(const char *dev, int csum, int other) #endif } +int DisableIfaceOffloading(const char *dev, int csum, int other) +{ +#if defined SIOCSIFCAP + return DisableIfaceOffloadingBSD(dev); +#else + return 0; +#endif + +} + int GetIfaceRSSQueuesNum(const char *pcap_dev) { #if defined HAVE_LINUX_ETHTOOL_H && defined ETHTOOL_GRXRINGS diff --git a/src/util-ioctl.h b/src/util-ioctl.h index 79018754b0c4..da3bd616911d 100644 --- a/src/util-ioctl.h +++ b/src/util-ioctl.h @@ -34,3 +34,4 @@ int SetIfaceFlags(const char *ifname, int flags); #ifdef SIOCGIFCAP int GetIfaceCaps(const char *ifname); #endif +int DisableIfaceOffloading(const char *dev, int csum, int other); From 9bac4a055dc1e466864ef60d7118ce4cd84797b8 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 20 Jun 2016 20:15:37 +0200 Subject: [PATCH 2/9] device: add global flag for disabling offloading Add global flag to disable offloading or just warn on it. --- src/util-device.c | 17 +++++++++++++++++ src/util-device.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/src/util-device.c b/src/util-device.c index 582746ac126f..2a37bffc5a04 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -39,6 +39,23 @@ static int live_devices_stats = 1; static int LiveSafeDeviceName(const char *devname, char *newdevname, size_t destlen); +static int g_live_devices_disable_offloading = 1; + +void LiveSetOffloadDisable(void) +{ + g_live_devices_disable_offloading = 1; +} + +void LiveSetOffloadWarn(void) +{ + g_live_devices_disable_offloading = 0; +} + +int LiveGetOffload(void) +{ + return g_live_devices_disable_offloading; +} + /** * \brief Add a pcap device for monitoring * diff --git a/src/util-device.h b/src/util-device.h index ca3d91331a35..307e4634ec45 100644 --- a/src/util-device.h +++ b/src/util-device.h @@ -34,6 +34,9 @@ typedef struct LiveDevice_ { TAILQ_ENTRY(LiveDevice_) next; } LiveDevice; +void LiveSetOffloadDisable(void); +void LiveSetOffloadWarn(void); +int LiveGetOffload(void); int LiveRegisterDevice(const char *dev); int LiveGetDeviceCount(void); From ef407d7386e935df6310c5f8b62c6be67a421384 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 20 Jun 2016 20:17:30 +0200 Subject: [PATCH 3/9] netmap: optionally disable offloading --- src/source-netmap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/source-netmap.c b/src/source-netmap.c index ec38c1f7a618..48c16fe55d06 100644 --- a/src/source-netmap.c +++ b/src/source-netmap.c @@ -294,7 +294,11 @@ static int NetmapOpen(char *ifname, int promisc, NetmapDevice **pdevice, int ver } /* netmap needs all offloading to be disabled */ - (void)GetIfaceOffloading(ifname, 1, 1); + if (LiveGetOffload() == 0) { + (void)GetIfaceOffloading(ifname, 1, 1); + } else { + DisableIfaceOffloading(ifname, 1, 1); + } /* not found, create new record */ pdev = SCMalloc(sizeof(*pdev)); From 649a1e9d8065be9b5e8ff36e0080ac76a65ee73d Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 20 Jun 2016 20:18:43 +0200 Subject: [PATCH 4/9] pcap: optionally disable offloading --- src/source-pcap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/source-pcap.c b/src/source-pcap.c index 97fcd72e6f93..068a83fd9d9e 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -395,6 +395,12 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) SCLogInfo("using interface %s", (char *)pcapconfig->iface); + if (LiveGetOffload() == 0) { + (void)GetIfaceOffloading((char *)pcapconfig->iface, 1, 1); + } else { + DisableIfaceOffloading((char *)pcapconfig->iface, 1, 1); + } + ptv->checksum_mode = pcapconfig->checksum_mode; if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) { SCLogInfo("Running in 'auto' checksum mode. Detection of interface state will require " From a789e1708017ab819f8c737e27986b060f6de601 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 20 Jun 2016 23:00:38 +0200 Subject: [PATCH 5/9] offloading: Linux ethtool offloading support --- src/util-ioctl.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/src/util-ioctl.c b/src/util-ioctl.c index 5eb7b408c1f8..ae1bded7e58f 100644 --- a/src/util-ioctl.c +++ b/src/util-ioctl.c @@ -19,6 +19,7 @@ * \file * * \author Eric Leblond + * \author Victor Julien */ #include "suricata-common.h" @@ -292,6 +293,33 @@ static int GetEthtoolValue(const char *dev, int cmd, uint32_t *value) return 0; } +static int SetEthtoolValue(const char *dev, int cmd, uint32_t value) +{ + struct ifreq ifr; + int fd; + struct ethtool_value ethv; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) { + return -1; + } + (void)strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); + + ethv.cmd = cmd; + ethv.data = value; + ifr.ifr_data = (void *) ðv; + if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) { + SCLogWarning(SC_ERR_SYSCALL, + "Failure when trying to get feature via ioctl for '%s': %s (%d)", + dev, strerror(errno), errno); + close(fd); + return -1; + } + + close(fd); + return 0; +} + static int GetIfaceOffloadingLinux(const char *dev, int csum, int other) { int ret = 0; @@ -372,6 +400,62 @@ static int GetIfaceOffloadingLinux(const char *dev, int csum, int other) return ret; } +static int DisableIfaceOffloadingLinux(const char *dev, int csum, int other) +{ + int ret = 0; + uint32_t value = 0; + + 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); + } +#endif +#ifdef ETHTOOL_GTXCSUM + if (GetEthtoolValue(dev, ETHTOOL_GTXCSUM, &value) == 0 && value != 0) { + SCLogInfo("%s: disabling txcsum offloading", dev); + SetEthtoolValue(dev, ETHTOOL_STXCSUM, 0); + } +#endif + } + if (other) { +#ifdef ETHTOOL_GGRO + if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) { + SCLogInfo("%s: disabling gro offloading", dev); + SetEthtoolValue(dev, ETHTOOL_SGRO, 0); + } +#endif +#ifdef ETHTOOL_GTSO + if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) { + SCLogInfo("%s: disabling tso offloading", dev); + SetEthtoolValue(dev, ETHTOOL_STSO, 0); + } +#endif +#ifdef ETHTOOL_GGSO + if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) { + SCLogInfo("%s: disabling gso offloading", dev); + SetEthtoolValue(dev, ETHTOOL_SGSO, 0); + } +#endif +#ifdef ETHTOOL_GSG + if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) { + SCLogInfo("%s: disabling sg offloading", dev); + SetEthtoolValue(dev, ETHTOOL_SSG, 0); + } +#endif +#ifdef ETHTOOL_GFLAGS + if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) { + if (value & ETH_FLAG_LRO) { + SCLogInfo("%s: disabling lro offloading", dev); + SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ~ETH_FLAG_LRO); + } + } +#endif + } + return ret; +} + #endif /* defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL */ #ifdef SIOCGIFCAP @@ -472,7 +556,9 @@ int GetIfaceOffloading(const char *dev, int csum, int other) int DisableIfaceOffloading(const char *dev, int csum, int other) { -#if defined SIOCSIFCAP +#if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL + return DisableIfaceOffloadingLinux(dev, csum, other); +#elif defined SIOCSIFCAP return DisableIfaceOffloadingBSD(dev); #else return 0; From 4bfb427ae3975601d61fc7384b152bf55f227e9f Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 20 Jun 2016 23:02:02 +0200 Subject: [PATCH 6/9] af-packet: optionally disable offloading --- src/runmode-af-packet.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/runmode-af-packet.c b/src/runmode-af-packet.c index 1e003f7c16fa..36b1dc0c1079 100644 --- a/src/runmode-af-packet.c +++ b/src/runmode-af-packet.c @@ -427,10 +427,15 @@ void *ParseAFPConfig(const char *iface) switch (ltype) { case LINKTYPE_ETHERNET: /* af-packet can handle csum offloading */ - if (GetIfaceOffloading(iface, 0, 1) == 1) { - SCLogWarning(SC_ERR_AFP_CREATE, - "Using AF_PACKET with offloading activated leads to capture problems"); + if (LiveGetOffload() == 0) { + if (GetIfaceOffloading(iface, 0, 1) == 1) { + SCLogWarning(SC_ERR_AFP_CREATE, + "Using AF_PACKET with offloading activated leads to capture problems"); + } + } else { + DisableIfaceOffloading(iface, 0, 1); } + break; case -1: default: break; From b1cb598b90316a0e93b9fb7d479b0d90716e20ed Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 21 Jun 2016 09:35:33 +0200 Subject: [PATCH 7/9] offloading: restore settings on exit --- src/runmode-af-packet.c | 2 +- src/runmode-netmap.c | 7 ++++ src/source-netmap.c | 7 ---- src/source-pcap.c | 2 +- src/util-device.c | 6 ++- src/util-device.h | 19 ++++++++-- src/util-ioctl.c | 82 ++++++++++++++++++++++++++++++++++++++++- src/util-ioctl.h | 5 ++- 8 files changed, 113 insertions(+), 17 deletions(-) diff --git a/src/runmode-af-packet.c b/src/runmode-af-packet.c index 36b1dc0c1079..46a3c080b7c8 100644 --- a/src/runmode-af-packet.c +++ b/src/runmode-af-packet.c @@ -433,7 +433,7 @@ void *ParseAFPConfig(const char *iface) "Using AF_PACKET with offloading activated leads to capture problems"); } } else { - DisableIfaceOffloading(iface, 0, 1); + DisableIfaceOffloading(LiveGetDevice(iface), 0, 1); } break; case -1: diff --git a/src/runmode-netmap.c b/src/runmode-netmap.c index 81c409c2835e..db682124bc25 100644 --- a/src/runmode-netmap.c +++ b/src/runmode-netmap.c @@ -267,6 +267,13 @@ static void *ParseNetmapConfig(const char *iface_name) SCLogPerf("Using %d threads for interface %s", aconf->in.threads, aconf->iface_name); + /* netmap needs all offloading to be disabled */ + if (LiveGetOffload() == 0) { + (void)GetIfaceOffloading(aconf->in.iface, 1, 1); + } else { + DisableIfaceOffloading(LiveGetDevice(aconf->in.iface), 1, 1); + } + return aconf; } diff --git a/src/source-netmap.c b/src/source-netmap.c index 48c16fe55d06..5f81f1a69453 100644 --- a/src/source-netmap.c +++ b/src/source-netmap.c @@ -293,13 +293,6 @@ static int NetmapOpen(char *ifname, int promisc, NetmapDevice **pdevice, int ver } } - /* netmap needs all offloading to be disabled */ - if (LiveGetOffload() == 0) { - (void)GetIfaceOffloading(ifname, 1, 1); - } else { - DisableIfaceOffloading(ifname, 1, 1); - } - /* not found, create new record */ pdev = SCMalloc(sizeof(*pdev)); if (unlikely(pdev == NULL)) { diff --git a/src/source-pcap.c b/src/source-pcap.c index 068a83fd9d9e..d5cbd1c1ca1c 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -398,7 +398,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) if (LiveGetOffload() == 0) { (void)GetIfaceOffloading((char *)pcapconfig->iface, 1, 1); } else { - DisableIfaceOffloading((char *)pcapconfig->iface, 1, 1); + DisableIfaceOffloading(ptv->livedev, 1, 1); } ptv->checksum_mode = pcapconfig->checksum_mode; diff --git a/src/util-device.c b/src/util-device.c index 2a37bffc5a04..f8afbc239cd0 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -18,6 +18,7 @@ #include "suricata-common.h" #include "conf.h" #include "util-device.h" +#include "util-ioctl.h" #define MAX_DEVNAME 10 @@ -66,7 +67,7 @@ int LiveGetOffload(void) */ int LiveRegisterDevice(const char *dev) { - LiveDevice *pd = SCMalloc(sizeof(LiveDevice)); + LiveDevice *pd = SCCalloc(1, sizeof(LiveDevice)); if (unlikely(pd == NULL)) { return -1; } @@ -281,6 +282,9 @@ int LiveDeviceListClean() 100 * (SC_ATOMIC_GET(pd->drop) * 1.0) / SC_ATOMIC_GET(pd->pkts), SC_ATOMIC_GET(pd->invalid_checksums)); } + + RestoreIfaceOffloading(pd); + if (pd->dev) SCFree(pd->dev); SC_ATOMIC_DESTROY(pd->pkts); diff --git a/src/util-device.h b/src/util-device.h index 307e4634ec45..5c4e76c09f37 100644 --- a/src/util-device.h +++ b/src/util-device.h @@ -21,6 +21,19 @@ #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 */ @@ -32,11 +45,9 @@ typedef struct LiveDevice_ { 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); diff --git a/src/util-ioctl.c b/src/util-ioctl.c index ae1bded7e58f..9c9b3dd353a1 100644 --- a/src/util-ioctl.c +++ b/src/util-ioctl.c @@ -24,6 +24,7 @@ #include "suricata-common.h" #include "conf.h" +#include "util-device.h" #ifdef HAVE_SYS_IOCTL_H #include @@ -400,22 +401,29 @@ static int GetIfaceOffloadingLinux(const char *dev, int csum, int other) 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 } @@ -424,24 +432,28 @@ static int DisableIfaceOffloadingLinux(const char *dev, int csum, int other) 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 @@ -449,6 +461,7 @@ static int DisableIfaceOffloadingLinux(const char *dev, int csum, int other) 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 @@ -456,6 +469,62 @@ static int DisableIfaceOffloadingLinux(const char *dev, int csum, int other) return ret; } +static int RestoreIfaceOffloadingLinux(LiveDevice *ldev) +{ + uint32_t value = 0; + + 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) { + 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 @@ -554,7 +623,7 @@ int GetIfaceOffloading(const char *dev, int csum, int other) #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); @@ -566,6 +635,15 @@ int DisableIfaceOffloading(const char *dev, int csum, int 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 diff --git a/src/util-ioctl.h b/src/util-ioctl.h index da3bd616911d..54020e4c7cf8 100644 --- a/src/util-ioctl.h +++ b/src/util-ioctl.h @@ -21,6 +21,8 @@ * \author Eric Leblond */ +#include "util-device.h" + int GetIfaceMTU(const char *pcap_dev); int GetIfaceMaxPacketSize(const char *pcap_dev); int GetIfaceOffloading(const char *dev, int csum, int other); @@ -34,4 +36,5 @@ int SetIfaceFlags(const char *ifname, int flags); #ifdef SIOCGIFCAP int GetIfaceCaps(const char *ifname); #endif -int DisableIfaceOffloading(const char *dev, int csum, int other); +int DisableIfaceOffloading(LiveDevice *dev, int csum, int other); +void RestoreIfaceOffloading(LiveDevice *dev); From 5795717e5804020a8eee8f027cc6701dbff4ba32 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 21 Jun 2016 07:59:51 +0200 Subject: [PATCH 8/9] offloading: implement restoring settings for BSD --- src/runmode-netmap.c | 14 +++++------ src/util-ioctl.c | 60 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/runmode-netmap.c b/src/runmode-netmap.c index db682124bc25..e41100ac5cc2 100644 --- a/src/runmode-netmap.c +++ b/src/runmode-netmap.c @@ -207,6 +207,13 @@ static int ParseNetmapSettings(NetmapIfaceSettings *ns, const char *iface, ns->threads = 1; } + /* netmap needs all offloading to be disabled */ + if (LiveGetOffload() == 0) { + (void)GetIfaceOffloading(ns->iface, 1, 1); + } else { + DisableIfaceOffloading(LiveGetDevice(ns->iface), 1, 1); + } + return 0; } @@ -267,13 +274,6 @@ static void *ParseNetmapConfig(const char *iface_name) SCLogPerf("Using %d threads for interface %s", aconf->in.threads, aconf->iface_name); - /* netmap needs all offloading to be disabled */ - if (LiveGetOffload() == 0) { - (void)GetIfaceOffloading(aconf->in.iface, 1, 1); - } else { - DisableIfaceOffloading(LiveGetDevice(aconf->in.iface), 1, 1); - } - return aconf; } diff --git a/src/util-ioctl.c b/src/util-ioctl.c index 9c9b3dd353a1..e6e00f944863 100644 --- a/src/util-ioctl.c +++ b/src/util-ioctl.c @@ -565,9 +565,14 @@ static int GetIfaceOffloadingBSD(const char *ifname) #endif #ifdef SIOCSIFCAP -static int DisableIfaceOffloadingBSD(const char *ifname) +static int DisableIfaceOffloadingBSD(LiveDevice *ldev) { int ret = 0; + + if (ldev == NULL) + return -1; + + const char *ifname = ldev->dev; int if_caps = GetIfaceCaps(ifname); int set_caps = if_caps; if (if_caps == -1) { @@ -591,6 +596,57 @@ static int DisableIfaceOffloadingBSD(const char *ifname) set_caps &= ~(IFCAP_TSO|IFCAP_LRO); } #endif + if (set_caps != if_caps) { + if (if_caps & IFCAP_RXCSUM) + ldev->offload_orig |= OFFLOAD_FLAG_RXCSUM; + if (if_caps & IFCAP_TSO) + ldev->offload_orig |= OFFLOAD_FLAG_TSO; +#ifdef IFCAP_TOE + if (if_caps & IFCAP_TOE) + ldev->offload_orig |= OFFLOAD_FLAG_TOE; +#endif + if (if_caps & IFCAP_LRO) + ldev->offload_orig |= OFFLOAD_FLAG_LRO; + + SetIfaceCaps(ifname, set_caps); + } + return ret; +} + +static int RestoreIfaceOffloadingBSD(LiveDevice *ldev) +{ + int ret = 0; + + if (ldev == NULL) + return -1; + + const char *ifname = ldev->dev; + int if_caps = GetIfaceCaps(ifname); + int set_caps = if_caps; + if (if_caps == -1) { + return -1; + } + SCLogDebug("if_caps %X", if_caps); + + if (ldev->offload_orig & OFFLOAD_FLAG_RXCSUM) { + SCLogInfo("%s: restoring rxcsum offloading", ifname); + set_caps |= IFCAP_RXCSUM; + } + if (ldev->offload_orig & OFFLOAD_FLAG_TSO) { + SCLogInfo("%s: restoring tso offloading", ifname); + set_caps |= IFCAP_TSO; + } +#ifdef IFCAP_TOE + if (ldev->offload_orig & OFFLOAD_FLAG_TOE) { + SCLogInfo("%s: restoring toe offloading", ifname); + set_caps |= IFCAP_TOE; + } +#endif + if (ldev->offload_orig & OFFLOAD_FLAG_LRO) { + SCLogInfo("%s: restoring lro offloading", ifname); + set_caps |= IFCAP_LRO; + } + if (set_caps != if_caps) { SetIfaceCaps(ifname, set_caps); } @@ -640,6 +696,8 @@ void RestoreIfaceOffloading(LiveDevice *dev) if (dev->offload_orig != 0) { #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL RestoreIfaceOffloadingLinux(dev); +#elif defined SIOCSIFCAP + RestoreIfaceOffloadingBSD(dev); #endif } } From 7782ace965b4fdf3d6f16f06b6e98730fa8d9040 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 21 Jun 2016 10:05:40 +0200 Subject: [PATCH 9/9] offloading: reduce verbosity to 'perf' --- src/util-ioctl.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/util-ioctl.c b/src/util-ioctl.c index e6e00f944863..7c7efaa3b7e5 100644 --- a/src/util-ioctl.c +++ b/src/util-ioctl.c @@ -414,14 +414,14 @@ static int DisableIfaceOffloadingLinux(LiveDevice *ldev, int csum, int other) if (csum) { #ifdef ETHTOOL_GRXCSUM if (GetEthtoolValue(dev, ETHTOOL_GRXCSUM, &value) == 0 && value != 0) { - SCLogInfo("%s: disabling rxcsum offloading", dev); + SCLogPerf("%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); + SCLogPerf("%s: disabling txcsum offloading", dev); SetEthtoolValue(dev, ETHTOOL_STXCSUM, 0); ldev->offload_orig |= OFFLOAD_FLAG_TXCSUM; } @@ -430,28 +430,28 @@ static int DisableIfaceOffloadingLinux(LiveDevice *ldev, int csum, int other) if (other) { #ifdef ETHTOOL_GGRO if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) { - SCLogInfo("%s: disabling gro offloading", dev); + SCLogPerf("%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); + SCLogPerf("%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); + SCLogPerf("%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); + SCLogPerf("%s: disabling sg offloading", dev); SetEthtoolValue(dev, ETHTOOL_SSG, 0); ldev->offload_orig |= OFFLOAD_FLAG_SG; } @@ -459,7 +459,7 @@ static int DisableIfaceOffloadingLinux(LiveDevice *ldev, int csum, int other) #ifdef ETHTOOL_GFLAGS if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) { if (value & ETH_FLAG_LRO) { - SCLogInfo("%s: disabling lro offloading", dev); + SCLogPerf("%s: disabling lro offloading", dev); SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ~ETH_FLAG_LRO); ldev->offload_orig |= OFFLOAD_FLAG_LRO; } @@ -480,44 +480,44 @@ static int RestoreIfaceOffloadingLinux(LiveDevice *ldev) #ifdef ETHTOOL_GRXCSUM if (ldev->offload_orig & OFFLOAD_FLAG_RXCSUM) { - SCLogInfo("%s: restoring rxcsum offloading", dev); + SCLogPerf("%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); + SCLogPerf("%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); + SCLogPerf("%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); + SCLogPerf("%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); + SCLogPerf("%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); + SCLogPerf("%s: restoring sg offloading", dev); SetEthtoolValue(dev, ETHTOOL_SSG, 1); } #endif #ifdef ETHTOOL_GFLAGS if (ldev->offload_orig & OFFLOAD_FLAG_LRO) { if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) { - SCLogInfo("%s: restoring lro offloading", dev); + SCLogPerf("%s: restoring lro offloading", dev); SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ETH_FLAG_LRO); } } @@ -581,18 +581,18 @@ static int DisableIfaceOffloadingBSD(LiveDevice *ldev) SCLogDebug("if_caps %X", if_caps); if (if_caps & IFCAP_RXCSUM) { - SCLogInfo("%s: disabling rxcsum offloading", ifname); + SCLogPerf("%s: disabling rxcsum offloading", ifname); set_caps &= ~IFCAP_RXCSUM; } #ifdef IFCAP_TOE if (if_caps & (IFCAP_TSO|IFCAP_TOE|IFCAP_LRO)) { - SCLogInfo("%s: disabling tso|toe|lro offloading", ifname); + SCLogPerf("%s: disabling tso|toe|lro offloading", ifname); set_caps &= ~(IFCAP_TSO|IFCAP_LRO); } #else if (if_caps & (IFCAP_TSO|IFCAP_LRO)) { - SCLogInfo("%s: disabling tso|lro offloading", ifname); + SCLogPerf("%s: disabling tso|lro offloading", ifname); set_caps &= ~(IFCAP_TSO|IFCAP_LRO); } #endif @@ -629,21 +629,21 @@ static int RestoreIfaceOffloadingBSD(LiveDevice *ldev) SCLogDebug("if_caps %X", if_caps); if (ldev->offload_orig & OFFLOAD_FLAG_RXCSUM) { - SCLogInfo("%s: restoring rxcsum offloading", ifname); + SCLogPerf("%s: restoring rxcsum offloading", ifname); set_caps |= IFCAP_RXCSUM; } if (ldev->offload_orig & OFFLOAD_FLAG_TSO) { - SCLogInfo("%s: restoring tso offloading", ifname); + SCLogPerf("%s: restoring tso offloading", ifname); set_caps |= IFCAP_TSO; } #ifdef IFCAP_TOE if (ldev->offload_orig & OFFLOAD_FLAG_TOE) { - SCLogInfo("%s: restoring toe offloading", ifname); + SCLogPerf("%s: restoring toe offloading", ifname); set_caps |= IFCAP_TOE; } #endif if (ldev->offload_orig & OFFLOAD_FLAG_LRO) { - SCLogInfo("%s: restoring lro offloading", ifname); + SCLogPerf("%s: restoring lro offloading", ifname); set_caps |= IFCAP_LRO; }