#include <sys/ioctl.h>
#endif
+#ifdef HAVE_LINUX_ETHTOOL_H
+#include <linux/ethtool.h>
+#ifdef HAVE_LINUX_SOCKIOS_H
+#include <linux/sockios.h>
+#else
+#error "ethtool.h present but sockios.h is missing"
+#endif /* HAVE_LINUX_SOCKIOS_H */
+#endif /* HAVE_LINUX_ETHTOOL_H */
+
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
}
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(char *pcap_dev)
+{
+#ifdef ETHTOOL_GGRO
+ struct ifreq ifr;
+ int fd;
+ struct ethtool_value ethv;
+ int ret = 0;
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ return -1;
+ }
+ (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name));
+
+ /* First get GRO */
+ ethv.cmd = ETHTOOL_GGRO;
+ ifr.ifr_data = (void *) ðv;
+ if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
+ SCLogWarning(SC_ERR_SYSCALL,
+ "Failure when trying to get feature via ioctl: %s (%d)",
+ strerror(errno), errno);
+ close(fd);
+ return -1;
+ } else {
+ if (ethv.data) {
+ SCLogInfo("Generic Receive Offload is set on %s", pcap_dev);
+ ret = 1;
+ } else {
+ SCLogInfo("Generic Receive Offload is unset on %s", pcap_dev);
+ }
+ }
+
+ /* Then get LRO which is set in a flag */
+ ethv.data = 0;
+ ethv.cmd = ETHTOOL_GFLAGS;
+ ifr.ifr_data = (void *) ðv;
+ if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
+ SCLogWarning(SC_ERR_SYSCALL,
+ "Failure when trying to get feature via ioctl: %s (%d)",
+ strerror(errno), errno);
+ close(fd);
+ return -1;
+ } else {
+ if (ethv.data & ETH_FLAG_LRO) {
+ SCLogInfo("Large Receive Offload is set on %s", pcap_dev);
+ ret = 1;
+ } else {
+ SCLogInfo("Large Receive Offload is unset on %s", pcap_dev);
+ }
+ }
+
+ close(fd);
+
+ return ret;
+#else
+ /* ioctl is not defined, let's pretend returning 0 is ok */
+ return 0;
+#endif
+}
+