offloading: check for more offloading on Linux

pull/2160/head
Victor Julien 9 years ago
parent b1d191b478
commit 54bc471810

@ -137,75 +137,91 @@ int GetIfaceMaxPacketSize(const char *pcap_dev)
return ll_header + mtu;
}
/**
* \brief output offloading status of the link
*
* Test interface for GRO and LRO features. If one of them is
* activated then suricata mays received packets merge at reception.
* The result is oversized packets and this may cause some serious
* problem in some capture mode where the size of the packet is
* limited (AF_PACKET in V2 more for example).
*
* ETHTOOL_GGRO ETH_FLAG_LRO
*
* \param Name of link
* \retval -1 in case of error, 0 if none, 1 if some
*/
int GetIfaceOffloading(const char *pcap_dev)
#if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
static int GetEthtoolValue(const char *dev, int cmd, uint32_t *value)
{
#if defined (ETHTOOL_GGRO) && defined (ETHTOOL_GFLAGS)
struct ifreq ifr;
int fd;
struct ethtool_value ethv;
int ret = 0;
char *lro = "unset", *gro = "unset";
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1) {
return -1;
}
(void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name));
(void)strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
/* First get GRO */
ethv.cmd = ETHTOOL_GGRO;
ethv.cmd = cmd;
ifr.ifr_data = (void *) &ethv;
if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
SCLogWarning(SC_ERR_SYSCALL,
"Failure when trying to get feature via ioctl for '%s': %s (%d)",
pcap_dev, strerror(errno), errno);
dev, strerror(errno), errno);
close(fd);
return -1;
} else {
if (ethv.data) {
gro = "SET";
ret = 1;
}
}
/* Then get LRO which is set in a flag */
ethv.data = 0;
ethv.cmd = ETHTOOL_GFLAGS;
ifr.ifr_data = (void *) &ethv;
if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
SCLogWarning(SC_ERR_SYSCALL,
"Failure when trying to get feature via ioctl for '%s': %s (%d)",
pcap_dev, strerror(errno), errno);
close(fd);
return -1;
} else {
if (ethv.data & ETH_FLAG_LRO) {
*value = ethv.data;
close(fd);
return 0;
}
#endif
/**
* \brief output offloading status of the link
*
* Test interface for offloading features. If one of them is
* activated then suricata mays received packets merge at reception.
* The result is oversized packets and this may cause some serious
* problem in some capture mode where the size of the packet is
* limited (AF_PACKET in V2 more for example).
*
* \param Name of link
* \retval -1 in case of error, 0 if none, 1 if some
*/
int GetIfaceOffloading(const char *dev)
{
int ret = 0;
char *lro = "unset", *gro = "unset", *tso = "unset", *gso = "unset";
char *sg = "unset";
#if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
uint32_t value = 0;
#ifdef ETHTOOL_GGRO
if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) {
gro = "SET";
ret = 1;
}
#endif
#ifdef ETHTOOL_GTSO
if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) {
tso = "SET";
ret = 1;
}
#endif
#ifdef ETHTOOL_GGSO
if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) {
gso = "SET";
ret = 1;
}
#endif
#ifdef ETHTOOL_GSG
if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) {
sg = "SET";
ret = 1;
}
#endif
#ifdef ETHTOOL_GFLAGS
if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) {
if (value & ETH_FLAG_LRO) {
lro = "SET";
ret = 1;
}
}
close(fd);
SCLogInfo("NIC offloading on %s: GRO: %s, LRO: %s", pcap_dev, gro, lro);
return ret;
#else
/* ioctl is not defined, let's pretend returning 0 is ok */
return 0;
#endif
#endif
SCLogInfo("NIC offloading on %s: SG: %s, GRO: %s, LRO: %s, "
"TSO: %s, GSO: %s", dev, sg, gro, lro, tso, gso);
return ret;
}
int GetIfaceRSSQueuesNum(const char *pcap_dev)

Loading…
Cancel
Save