offloading: restore settings on exit

pull/2266/head
Victor Julien 9 years ago
parent 9d48720f9a
commit 499e27de14

@ -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:

@ -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;
}

@ -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)) {

@ -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;

@ -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);

@ -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);

@ -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

@ -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);

Loading…
Cancel
Save