]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
offloading: restore settings on exit
authorVictor Julien <victor@inliniac.net>
Tue, 21 Jun 2016 07:35:33 +0000 (09:35 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 22 Sep 2016 11:36:27 +0000 (13:36 +0200)
src/runmode-af-packet.c
src/runmode-netmap.c
src/source-netmap.c
src/source-pcap.c
src/util-device.c
src/util-device.h
src/util-ioctl.c
src/util-ioctl.h

index 65ba213b3b7c15b97efbd28974fa8ce47c0a1a26..959617889b91cc4cbfb959c112e9583a25782cdc 100644 (file)
@@ -459,7 +459,7 @@ finalize:
                             "Using AF_PACKET with offloading activated leads to capture problems");
                 }
             } else {
-                DisableIfaceOffloading(iface, 0, 1);
+                DisableIfaceOffloading(LiveGetDevice(iface), 0, 1);
             }
             break;
         case -1:
index 1cf08bc8298709b54e42bddca222ea8690a2ed0b..88d2de3f60fafed79e49523820a478a62122c90a 100644 (file)
@@ -269,6 +269,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;
 }
 
index 48c16fe55d061699603120a83338cf7c835ff191..5f81f1a69453b5cc308e8d697dc6a708193bec98 100644 (file)
@@ -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)) {
index 4385231b0be8658692c208f623a19ef8030fe39b..33d8c72529a8fcdc499ed4c06fd1c744c2a9b663 100644 (file)
@@ -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;
index 2a37bffc5a0417b979a093e5f7d2e9f7d370a7cd..f8afbc239cd076a6f49c393bbbfa2e2884b932f1 100644 (file)
@@ -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);
index 307e4634ec4587f4d62f564aaa0875cef8a3b043..5c4e76c09f3733461fbd34a0c716da1c70edeb19 100644 (file)
 #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);
index ae1bded7e58f1dcee90df222a8f9731b1860f341..ff6646adc5181c9ac954f6cdd1ec47e253c4b8da 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "suricata-common.h"
 #include "conf.h"
+#include "util-device.h"
 
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
@@ -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,61 @@ static int DisableIfaceOffloadingLinux(const char *dev, int csum, int other)
     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
@@ -554,7 +622,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 +634,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
index da3bd616911d6ab9a44aed3cf902467374178261..54020e4c7cf8d996142f5cccf2f21c2f57c71ef5 100644 (file)
@@ -21,6 +21,8 @@
  * \author Eric Leblond <eleblond@edenwall.com>
  */
 
+#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);