From: Victor Julien Date: Mon, 13 Jun 2016 10:55:29 +0000 (+0200) Subject: offloading: distinguish between csum and the rest X-Git-Tag: suricata-3.1.1~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b80c21d787b5e7b4c221c91b71619e6e8eb11f0;p=thirdparty%2Fsuricata.git offloading: distinguish between csum and the rest As AF_PACKET handles csum offloading don't check for this type of offloading. Other methods like pcap and netmap do require it to be turned off. Improve disable command suggestion wording. --- diff --git a/src/runmode-af-packet.c b/src/runmode-af-packet.c index 3d9cacb5cb..1e003f7c16 100644 --- a/src/runmode-af-packet.c +++ b/src/runmode-af-packet.c @@ -426,7 +426,8 @@ finalize: int ltype = AFPGetLinkType(iface); switch (ltype) { case LINKTYPE_ETHERNET: - if (GetIfaceOffloading(iface) == 1) { + /* 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"); } diff --git a/src/source-netmap.c b/src/source-netmap.c index 21d21579bf..ec38c1f7a6 100644 --- a/src/source-netmap.c +++ b/src/source-netmap.c @@ -293,7 +293,8 @@ static int NetmapOpen(char *ifname, int promisc, NetmapDevice **pdevice, int ver } } - (void)GetIfaceOffloading(ifname); + /* netmap needs all offloading to be disabled */ + (void)GetIfaceOffloading(ifname, 1, 1); /* not found, create new record */ pdev = SCMalloc(sizeof(*pdev)); diff --git a/src/source-pcap.c b/src/source-pcap.c index 304e713304..97fcd72e6f 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -510,7 +510,8 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) SCMutexUnlock(&pcap_bpf_compile_lock); } - (void)GetIfaceOffloading(pcapconfig->iface); + /* no offloading supported at all */ + (void)GetIfaceOffloading(pcapconfig->iface, 1, 1); ptv->datalink = pcap_datalink(ptv->pcap_handle); diff --git a/src/util-ioctl.c b/src/util-ioctl.c index 54d2626661..866e6a0f61 100644 --- a/src/util-ioctl.c +++ b/src/util-ioctl.c @@ -265,53 +265,82 @@ static int GetEthtoolValue(const char *dev, int cmd, uint32_t *value) return 0; } -static int GetIfaceOffloadingLinux(const char *dev) +static int GetIfaceOffloadingLinux(const char *dev, int csum, int other) { int ret = 0; - char *lro = "unset", *gro = "unset", *tso = "unset", *gso = "unset"; - char *sg = "unset"; uint32_t value = 0; -#ifdef ETHTOOL_GGRO - if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) { - gro = "SET"; - ret = 1; + if (csum) { + char *rx = "unset", *tx = "unset"; + int csum_ret = 0; +#ifdef ETHTOOL_GRXCSUM + if (GetEthtoolValue(dev, ETHTOOL_GRXCSUM, &value) == 0 && value != 0) { + rx = "SET"; + csum_ret = 1; + } +#endif +#ifdef ETHTOOL_GTXCSUM + if (GetEthtoolValue(dev, ETHTOOL_GTXCSUM, &value) == 0 && value != 0) { + tx = "SET"; + csum_ret = 1; + } +#endif + if (csum_ret == 0) + SCLogPerf("NIC offloading on %s: RX %s TX %s", dev, rx, tx); + else { + SCLogWarning(SC_ERR_NIC_OFFLOADING, + "NIC offloading on %s: RX %s TX %s. Run: " + "ethtool -K %s rx off tx off", dev, rx, tx, dev); + ret = 1; + } } + + if (other) { + char *lro = "unset", *gro = "unset", *tso = "unset", *gso = "unset"; + char *sg = "unset"; + int other_ret = 0; +#ifdef ETHTOOL_GGRO + if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) { + gro = "SET"; + other_ret = 1; + } #endif #ifdef ETHTOOL_GTSO - if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) { - tso = "SET"; - ret = 1; - } + if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) { + tso = "SET"; + other_ret = 1; + } #endif #ifdef ETHTOOL_GGSO - if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) { - gso = "SET"; - ret = 1; - } + if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) { + gso = "SET"; + other_ret = 1; + } #endif #ifdef ETHTOOL_GSG - if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) { - sg = "SET"; - ret = 1; - } + if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) { + sg = "SET"; + other_ret = 1; + } #endif #ifdef ETHTOOL_GFLAGS - if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) { - if (value & ETH_FLAG_LRO) { - lro = "SET"; - ret = 1; + if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) { + if (value & ETH_FLAG_LRO) { + lro = "SET"; + other_ret = 1; + } } - } #endif - if (ret == 0) { - SCLogPerf("NIC offloading on %s: SG: %s, GRO: %s, LRO: %s, " - "TSO: %s, GSO: %s", dev, sg, gro, lro, tso, gso); - } else { - SCLogWarning(SC_ERR_NIC_OFFLOADING, "NIC offloading on %s: SG: %s, " - " GRO: %s, LRO: %s, TSO: %s, GSO: %s: " - "ethtool -K %s sg off gro off lro off tso off gso off", - dev, sg, gro, lro, tso, gso, dev); + if (other_ret == 0) { + SCLogPerf("NIC offloading on %s: SG: %s, GRO: %s, LRO: %s, " + "TSO: %s, GSO: %s", dev, sg, gro, lro, tso, gso); + } else { + SCLogWarning(SC_ERR_NIC_OFFLOADING, "NIC offloading on %s: SG: %s, " + " GRO: %s, LRO: %s, TSO: %s, GSO: %s. Run: " + "ethtool -K %s sg off gro off lro off tso off gso off", + dev, sg, gro, lro, tso, gso, dev); + ret = 1; + } } return ret; } @@ -331,13 +360,13 @@ static int GetIfaceOffloadingBSD(const char *ifname) if (if_caps & IFCAP_RXCSUM) { SCLogWarning(SC_ERR_NIC_OFFLOADING, "Using %s with RXCSUM activated can lead to capture " - "problems: ifconfig %s -rxcsum", ifname, ifname); + "problems. Run: ifconfig %s -rxcsum", ifname, ifname); ret = 1; } if (if_caps & (IFCAP_TSO|IFCAP_TOE|IFCAP_LRO)) { SCLogWarning(SC_ERR_NIC_OFFLOADING, "Using %s with TSO, TOE or LRO activated can lead to " - "capture problems: ifconfig %s -tso -toe -lro", + "capture problems. Run: ifconfig %s -tso -toe -lro", ifname, ifname); ret = 1; } @@ -355,12 +384,14 @@ static int GetIfaceOffloadingBSD(const char *ifname) * limited (AF_PACKET in V2 more for example). * * \param Name of link + * \param csum check if checksums are offloaded + * \param other check if other things are offloaded: TSO, GRO, etc. * \retval -1 in case of error, 0 if none, 1 if some */ -int GetIfaceOffloading(const char *dev) +int GetIfaceOffloading(const char *dev, int csum, int other) { #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL - return GetIfaceOffloadingLinux(dev); + return GetIfaceOffloadingLinux(dev, csum, other); #elif defined SIOCGIFCAP return GetIfaceOffloadingBSD(dev); #else diff --git a/src/util-ioctl.h b/src/util-ioctl.h index 76195ac76f..79018754b0 100644 --- a/src/util-ioctl.h +++ b/src/util-ioctl.h @@ -23,7 +23,7 @@ int GetIfaceMTU(const char *pcap_dev); int GetIfaceMaxPacketSize(const char *pcap_dev); -int GetIfaceOffloading(const char *pcap_dev); +int GetIfaceOffloading(const char *dev, int csum, int other); int GetIfaceRSSQueuesNum(const char *pcap_dev); #ifdef SIOCGIFFLAGS int GetIfaceFlags(const char *ifname);