suricata
util-ioctl.c
Go to the documentation of this file.
1 /* Copyright (C) 2010 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Eric Leblond <eric@regit.org>
22  * \author Victor Julien <victor@inliniac.net>
23  */
24 
25 #include "suricata-common.h"
26 #include "conf.h"
27 #include "util-device.h"
28 #include "decode-sll.h"
29 
30 #ifdef HAVE_SYS_IOCTL_H
31 #include <sys/ioctl.h>
32 #endif
33 
34 #ifdef HAVE_LINUX_ETHTOOL_H
35 #include <linux/types.h>
36 #include <linux/ethtool.h>
37 #ifdef HAVE_LINUX_SOCKIOS_H
38 #include <linux/sockios.h>
39 #else
40 #error "ethtool.h present but sockios.h is missing"
41 #endif /* HAVE_LINUX_SOCKIOS_H */
42 #endif /* HAVE_LINUX_ETHTOOL_H */
43 
44 #ifdef HAVE_NET_IF_H
45 #include <net/if.h>
46 #endif
47 
48 #ifdef OS_WIN32
49 #include "win32-syscall.h"
50 #endif
51 
52 #include "util-ioctl.h"
53 
54 /**
55  * \brief output a majorant of hardware header length
56  *
57  * \param Name of a network interface
58  */
59 static int GetIfaceMaxHWHeaderLength(const char *pcap_dev)
60 {
61  if ((!strcmp("eth", pcap_dev))
62  ||
63  (!strcmp("br", pcap_dev))
64  ||
65  (!strcmp("bond", pcap_dev))
66  ||
67  (!strcmp("wlan", pcap_dev))
68  ||
69  (!strcmp("tun", pcap_dev))
70  ||
71  (!strcmp("tap", pcap_dev))
72  ||
73  (!strcmp("lo", pcap_dev))) {
74  /* Add possible VLAN tag or Qing headers */
75  return 8 + ETHERNET_HEADER_LEN;
76  }
77 
78  if (!strcmp("ppp", pcap_dev))
79  return SLL_HEADER_LEN;
80  /* SLL_HEADER_LEN is the biggest one and
81  add possible VLAN tag and Qing headers */
82  return 8 + SLL_HEADER_LEN;
83 }
84 
85 
86 /**
87  * \brief output the link MTU
88  *
89  * \param Name of link
90  * \retval -1 in case of error, 0 if MTU can not be found
91  */
92 int GetIfaceMTU(const char *pcap_dev)
93 {
94 #if defined SIOCGIFMTU
95  struct ifreq ifr;
96  int fd;
97 
98  (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name));
99  fd = socket(AF_INET, SOCK_DGRAM, 0);
100  if (fd == -1) {
101  return -1;
102  }
103 
104  if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
106  "Failure when trying to get MTU via ioctl for '%s': %s (%d)",
107  pcap_dev, strerror(errno), errno);
108  close(fd);
109  return -1;
110  }
111  close(fd);
112  SCLogInfo("Found an MTU of %d for '%s'", ifr.ifr_mtu,
113  pcap_dev);
114  return ifr.ifr_mtu;
115 #elif defined OS_WIN32
116  return GetIfaceMTUWin32(pcap_dev);
117 #else
118  /* ioctl is not defined, let's pretend returning 0 is ok */
119  return 0;
120 #endif
121 }
122 
123 /**
124  * \brief output max packet size for a link
125  *
126  * This does a best effort to find the maximum packet size
127  * for the link. In case of uncertainty, it will output a
128  * majorant to be sure avoid the cost of dynamic allocation.
129  *
130  * \param Name of a network interface
131  * \retval 0 in case of error
132  */
133 int GetIfaceMaxPacketSize(const char *pcap_dev)
134 {
135  if ((pcap_dev == NULL) || strlen(pcap_dev) == 0)
136  return 0;
137 
138  int mtu = GetIfaceMTU(pcap_dev);
139  switch (mtu) {
140  case 0:
141  case -1:
142  return 0;
143  }
144  int ll_header = GetIfaceMaxHWHeaderLength(pcap_dev);
145  if (ll_header == -1) {
146  /* be conservative, choose a big one */
147  ll_header = 16;
148  }
149  return ll_header + mtu;
150 }
151 
152 #ifdef SIOCGIFFLAGS
153 /**
154  * \brief Get interface flags.
155  * \param ifname Inteface name.
156  * \return Interface flags or -1 on error
157  */
158 int GetIfaceFlags(const char *ifname)
159 {
160  struct ifreq ifr;
161 
162  int fd = socket(AF_INET, SOCK_DGRAM, 0);
163  if (fd < 0) {
164  return -1;
165  }
166 
167  memset(&ifr, 0, sizeof(ifr));
168  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
169 
170  if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
172  "Unable to get flags for iface \"%s\": %s",
173  ifname, strerror(errno));
174  close(fd);
175  return -1;
176  }
177 
178  close(fd);
179 #ifdef OS_FREEBSD
180  int flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
181  return flags;
182 #else
183  return ifr.ifr_flags;
184 #endif
185 }
186 #endif
187 
188 #ifdef SIOCSIFFLAGS
189 /**
190  * \brief Set interface flags.
191  * \param ifname Inteface name.
192  * \param flags Flags to set.
193  * \return Zero on success.
194  */
195 int SetIfaceFlags(const char *ifname, int flags)
196 {
197  struct ifreq ifr;
198 
199  int fd = socket(AF_INET, SOCK_DGRAM, 0);
200  if (fd < 0) {
201  return -1;
202  }
203 
204  memset(&ifr, 0, sizeof(ifr));
205  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
206 #ifdef OS_FREEBSD
207  ifr.ifr_flags = flags & 0xffff;
208  ifr.ifr_flagshigh = flags >> 16;
209 #else
210  ifr.ifr_flags = (uint16_t)flags;
211 #endif
212 
213  if (ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) {
215  "Unable to set flags for iface \"%s\": %s",
216  ifname, strerror(errno));
217  close(fd);
218  return -1;
219  }
220 
221  close(fd);
222  return 0;
223 }
224 #endif /* SIOCGIFFLAGS */
225 
226 #ifdef SIOCGIFCAP
227 int GetIfaceCaps(const char *ifname)
228 {
229  struct ifreq ifr;
230 
231  int fd = socket(AF_INET, SOCK_DGRAM, 0);
232  if (fd < 0) {
233  return -1;
234  }
235 
236  memset(&ifr, 0, sizeof(ifr));
237  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
238 
239  if (ioctl(fd, SIOCGIFCAP, &ifr) == -1) {
241  "Unable to get caps for iface \"%s\": %s",
242  ifname, strerror(errno));
243  close(fd);
244  return -1;
245  }
246 
247  close(fd);
248  return ifr.ifr_curcap;
249 }
250 #endif
251 #ifdef SIOCSIFCAP
252 int SetIfaceCaps(const char *ifname, int caps)
253 {
254  struct ifreq ifr;
255 
256  int fd = socket(AF_INET, SOCK_DGRAM, 0);
257  if (fd < 0) {
258  return -1;
259  }
260 
261  memset(&ifr, 0, sizeof(ifr));
262  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
263  ifr.ifr_reqcap = caps;
264 
265  if (ioctl(fd, SIOCSIFCAP, &ifr) == -1) {
267  "Unable to set caps for iface \"%s\": %s",
268  ifname, strerror(errno));
269  close(fd);
270  return -1;
271  }
272 
273  close(fd);
274  return 0;
275 }
276 #endif
277 
278 
279 #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
280 static int GetEthtoolValue(const char *dev, int cmd, uint32_t *value)
281 {
282  struct ifreq ifr;
283  int fd;
284  struct ethtool_value ethv;
285 
286  fd = socket(AF_INET, SOCK_DGRAM, 0);
287  if (fd == -1) {
288  return -1;
289  }
290  (void)strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
291 
292  ethv.cmd = cmd;
293  ifr.ifr_data = (void *) &ethv;
294  if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
296  "Failure when trying to get feature via ioctl for '%s': %s (%d)",
297  dev, strerror(errno), errno);
298  close(fd);
299  return -1;
300  }
301 
302  *value = ethv.data;
303  close(fd);
304  return 0;
305 }
306 
307 static int SetEthtoolValue(const char *dev, int cmd, uint32_t value)
308 {
309  struct ifreq ifr;
310  int fd;
311  struct ethtool_value ethv;
312 
313  fd = socket(AF_INET, SOCK_DGRAM, 0);
314  if (fd == -1) {
315  return -1;
316  }
317  (void)strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
318 
319  ethv.cmd = cmd;
320  ethv.data = value;
321  ifr.ifr_data = (void *) &ethv;
322  if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
324  "Failure when trying to set feature via ioctl for '%s': %s (%d)",
325  dev, strerror(errno), errno);
326  close(fd);
327  return -1;
328  }
329 
330  close(fd);
331  return 0;
332 }
333 
334 static int GetIfaceOffloadingLinux(const char *dev, int csum, int other)
335 {
336  int ret = 0;
337  uint32_t value = 0;
338 
339  if (csum) {
340  const char *rx = "unset", *tx = "unset";
341  int csum_ret = 0;
342 #ifdef ETHTOOL_GRXCSUM
343  if (GetEthtoolValue(dev, ETHTOOL_GRXCSUM, &value) == 0 && value != 0) {
344  rx = "SET";
345  csum_ret = 1;
346  }
347 #endif
348 #ifdef ETHTOOL_GTXCSUM
349  if (GetEthtoolValue(dev, ETHTOOL_GTXCSUM, &value) == 0 && value != 0) {
350  tx = "SET";
351  csum_ret = 1;
352  }
353 #endif
354  if (csum_ret == 0)
355  SCLogPerf("NIC offloading on %s: RX %s TX %s", dev, rx, tx);
356  else {
358  "NIC offloading on %s: RX %s TX %s. Run: "
359  "ethtool -K %s rx off tx off", dev, rx, tx, dev);
360  ret = 1;
361  }
362  }
363 
364  if (other) {
365  const char *lro = "unset", *gro = "unset", *tso = "unset", *gso = "unset";
366  const char *sg = "unset";
367  int other_ret = 0;
368 #ifdef ETHTOOL_GGRO
369  if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) {
370  gro = "SET";
371  other_ret = 1;
372  }
373 #endif
374 #ifdef ETHTOOL_GTSO
375  if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) {
376  tso = "SET";
377  other_ret = 1;
378  }
379 #endif
380 #ifdef ETHTOOL_GGSO
381  if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) {
382  gso = "SET";
383  other_ret = 1;
384  }
385 #endif
386 #ifdef ETHTOOL_GSG
387  if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) {
388  sg = "SET";
389  other_ret = 1;
390  }
391 #endif
392 #ifdef ETHTOOL_GFLAGS
393  if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) {
394  if (value & ETH_FLAG_LRO) {
395  lro = "SET";
396  other_ret = 1;
397  }
398  }
399 #endif
400  if (other_ret == 0) {
401  SCLogPerf("NIC offloading on %s: SG: %s, GRO: %s, LRO: %s, "
402  "TSO: %s, GSO: %s", dev, sg, gro, lro, tso, gso);
403  } else {
404  SCLogWarning(SC_ERR_NIC_OFFLOADING, "NIC offloading on %s: SG: %s, "
405  " GRO: %s, LRO: %s, TSO: %s, GSO: %s. Run: "
406  "ethtool -K %s sg off gro off lro off tso off gso off",
407  dev, sg, gro, lro, tso, gso, dev);
408  ret = 1;
409  }
410  }
411  return ret;
412 }
413 
414 static int DisableIfaceOffloadingLinux(LiveDevice *ldev, int csum, int other)
415 {
416  int ret = 0;
417  uint32_t value = 0;
418 
419  if (ldev == NULL)
420  return -1;
421 
422  const char *dev = ldev->dev;
423 
424  if (csum) {
425 #ifdef ETHTOOL_GRXCSUM
426  if (GetEthtoolValue(dev, ETHTOOL_GRXCSUM, &value) == 0 && value != 0) {
427  SCLogPerf("%s: disabling rxcsum offloading", dev);
428  SetEthtoolValue(dev, ETHTOOL_SRXCSUM, 0);
430  }
431 #endif
432 #ifdef ETHTOOL_GTXCSUM
433  if (GetEthtoolValue(dev, ETHTOOL_GTXCSUM, &value) == 0 && value != 0) {
434  SCLogPerf("%s: disabling txcsum offloading", dev);
435  SetEthtoolValue(dev, ETHTOOL_STXCSUM, 0);
437  }
438 #endif
439  }
440  if (other) {
441 #ifdef ETHTOOL_GGRO
442  if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) {
443  SCLogPerf("%s: disabling gro offloading", dev);
444  SetEthtoolValue(dev, ETHTOOL_SGRO, 0);
446  }
447 #endif
448 #ifdef ETHTOOL_GTSO
449  if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) {
450  SCLogPerf("%s: disabling tso offloading", dev);
451  SetEthtoolValue(dev, ETHTOOL_STSO, 0);
453  }
454 #endif
455 #ifdef ETHTOOL_GGSO
456  if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) {
457  SCLogPerf("%s: disabling gso offloading", dev);
458  SetEthtoolValue(dev, ETHTOOL_SGSO, 0);
460  }
461 #endif
462 #ifdef ETHTOOL_GSG
463  if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) {
464  SCLogPerf("%s: disabling sg offloading", dev);
465  SetEthtoolValue(dev, ETHTOOL_SSG, 0);
466  ldev->offload_orig |= OFFLOAD_FLAG_SG;
467  }
468 #endif
469 #ifdef ETHTOOL_GFLAGS
470  if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) {
471  if (value & ETH_FLAG_LRO) {
472  SCLogPerf("%s: disabling lro offloading", dev);
473  SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ~ETH_FLAG_LRO);
475  }
476  }
477 #endif
478  }
479  return ret;
480 }
481 
482 static int RestoreIfaceOffloadingLinux(LiveDevice *ldev)
483 {
484  if (ldev == NULL)
485  return -1;
486 
487  const char *dev = ldev->dev;
488 
489 #ifdef ETHTOOL_GRXCSUM
490  if (ldev->offload_orig & OFFLOAD_FLAG_RXCSUM) {
491  SCLogPerf("%s: restoring rxcsum offloading", dev);
492  SetEthtoolValue(dev, ETHTOOL_SRXCSUM, 1);
493  }
494 #endif
495 #ifdef ETHTOOL_GTXCSUM
496  if (ldev->offload_orig & OFFLOAD_FLAG_TXCSUM) {
497  SCLogPerf("%s: restoring txcsum offloading", dev);
498  SetEthtoolValue(dev, ETHTOOL_STXCSUM, 1);
499  }
500 #endif
501 #ifdef ETHTOOL_GGRO
502  if (ldev->offload_orig & OFFLOAD_FLAG_GRO) {
503  SCLogPerf("%s: restoring gro offloading", dev);
504  SetEthtoolValue(dev, ETHTOOL_SGRO, 1);
505  }
506 #endif
507 #ifdef ETHTOOL_GTSO
508  if (ldev->offload_orig & OFFLOAD_FLAG_TSO) {
509  SCLogPerf("%s: restoring tso offloading", dev);
510  SetEthtoolValue(dev, ETHTOOL_STSO, 1);
511  }
512 #endif
513 #ifdef ETHTOOL_GGSO
514  if (ldev->offload_orig & OFFLOAD_FLAG_GSO) {
515  SCLogPerf("%s: restoring gso offloading", dev);
516  SetEthtoolValue(dev, ETHTOOL_SGSO, 1);
517  }
518 #endif
519 #ifdef ETHTOOL_GSG
520  if (ldev->offload_orig & OFFLOAD_FLAG_SG) {
521  SCLogPerf("%s: restoring sg offloading", dev);
522  SetEthtoolValue(dev, ETHTOOL_SSG, 1);
523  }
524 #endif
525 #ifdef ETHTOOL_GFLAGS
526  if (ldev->offload_orig & OFFLOAD_FLAG_LRO) {
527  uint32_t value = 0;
528  if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) {
529  SCLogPerf("%s: restoring lro offloading", dev);
530  SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ETH_FLAG_LRO);
531  }
532  }
533 #endif
534  return 0;
535 }
536 
537 #endif /* defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL */
538 
539 #ifdef SIOCGIFCAP
540 static int GetIfaceOffloadingBSD(const char *ifname)
541 {
542  int ret = 0;
543  int if_caps = GetIfaceCaps(ifname);
544  if (if_caps == -1) {
545  return -1;
546  }
547  SCLogDebug("if_caps %X", if_caps);
548 
549  if (if_caps & IFCAP_RXCSUM) {
551  "Using %s with RXCSUM activated can lead to capture "
552  "problems. Run: ifconfig %s -rxcsum", ifname, ifname);
553  ret = 1;
554  }
555 #ifdef IFCAP_TOE
556  if (if_caps & (IFCAP_TSO|IFCAP_TOE|IFCAP_LRO)) {
558  "Using %s with TSO, TOE or LRO activated can lead to "
559  "capture problems. Run: ifconfig %s -tso -toe -lro",
560  ifname, ifname);
561  ret = 1;
562  }
563 #else
564  if (if_caps & (IFCAP_TSO|IFCAP_LRO)) {
566  "Using %s with TSO or LRO activated can lead to "
567  "capture problems. Run: ifconfig %s -tso -lro",
568  ifname, ifname);
569  ret = 1;
570  }
571 #endif
572  return ret;
573 }
574 #endif
575 
576 #ifdef SIOCSIFCAP
577 static int DisableIfaceOffloadingBSD(LiveDevice *ldev)
578 {
579  int ret = 0;
580 
581  if (ldev == NULL)
582  return -1;
583 
584  const char *ifname = ldev->dev;
585  int if_caps = GetIfaceCaps(ifname);
586  int set_caps = if_caps;
587  if (if_caps == -1) {
588  return -1;
589  }
590  SCLogDebug("if_caps %X", if_caps);
591 
592  if (if_caps & IFCAP_RXCSUM) {
593  SCLogPerf("%s: disabling rxcsum offloading", ifname);
594  set_caps &= ~IFCAP_RXCSUM;
595  }
596  if (if_caps & IFCAP_TXCSUM) {
597  SCLogPerf("%s: disabling txcsum offloading", ifname);
598  set_caps &= ~IFCAP_TXCSUM;
599  }
600 #ifdef IFCAP_RXCSUM_IPV6
601  if (if_caps & IFCAP_RXCSUM_IPV6) {
602  SCLogPerf("%s: disabling rxcsum6 offloading", ifname);
603  set_caps &= ~IFCAP_RXCSUM_IPV6;
604  }
605 #endif
606 #ifdef IFCAP_TXCSUM_IPV6
607  if (if_caps & IFCAP_TXCSUM_IPV6) {
608  SCLogPerf("%s: disabling txcsum6 offloading", ifname);
609  set_caps &= ~IFCAP_TXCSUM_IPV6;
610  }
611 #endif
612 #ifdef IFCAP_TOE
613  if (if_caps & (IFCAP_TSO|IFCAP_TOE|IFCAP_LRO)) {
614  SCLogPerf("%s: disabling tso|toe|lro offloading", ifname);
615  set_caps &= ~(IFCAP_TSO|IFCAP_LRO);
616  }
617 #else
618  if (if_caps & (IFCAP_TSO|IFCAP_LRO)) {
619  SCLogPerf("%s: disabling tso|lro offloading", ifname);
620  set_caps &= ~(IFCAP_TSO|IFCAP_LRO);
621  }
622 #endif
623  if (set_caps != if_caps) {
624  if (if_caps & IFCAP_RXCSUM)
626  if (if_caps & IFCAP_TSO)
628 #ifdef IFCAP_TOE
629  if (if_caps & IFCAP_TOE)
631 #endif
632  if (if_caps & IFCAP_LRO)
634 
635  SetIfaceCaps(ifname, set_caps);
636  }
637  return ret;
638 }
639 
640 static int RestoreIfaceOffloadingBSD(LiveDevice *ldev)
641 {
642  int ret = 0;
643 
644  if (ldev == NULL)
645  return -1;
646 
647  const char *ifname = ldev->dev;
648  int if_caps = GetIfaceCaps(ifname);
649  int set_caps = if_caps;
650  if (if_caps == -1) {
651  return -1;
652  }
653  SCLogDebug("if_caps %X", if_caps);
654 
655  if (ldev->offload_orig & OFFLOAD_FLAG_RXCSUM) {
656  SCLogPerf("%s: restoring rxcsum offloading", ifname);
657  set_caps |= IFCAP_RXCSUM;
658  }
659  if (ldev->offload_orig & OFFLOAD_FLAG_TSO) {
660  SCLogPerf("%s: restoring tso offloading", ifname);
661  set_caps |= IFCAP_TSO;
662  }
663 #ifdef IFCAP_TOE
664  if (ldev->offload_orig & OFFLOAD_FLAG_TOE) {
665  SCLogPerf("%s: restoring toe offloading", ifname);
666  set_caps |= IFCAP_TOE;
667  }
668 #endif
669  if (ldev->offload_orig & OFFLOAD_FLAG_LRO) {
670  SCLogPerf("%s: restoring lro offloading", ifname);
671  set_caps |= IFCAP_LRO;
672  }
673 
674  if (set_caps != if_caps) {
675  SetIfaceCaps(ifname, set_caps);
676  }
677  return ret;
678 }
679 #endif
680 
681 /**
682  * \brief output offloading status of the link
683  *
684  * Test interface for offloading features. If one of them is
685  * activated then suricata mays received packets merge at reception.
686  * The result is oversized packets and this may cause some serious
687  * problem in some capture mode where the size of the packet is
688  * limited (AF_PACKET in V2 more for example).
689  *
690  * \param Name of link
691  * \param csum check if checksums are offloaded
692  * \param other check if other things are offloaded: TSO, GRO, etc.
693  * \retval -1 in case of error, 0 if none, 1 if some
694  */
695 int GetIfaceOffloading(const char *dev, int csum, int other)
696 {
697 #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
698  return GetIfaceOffloadingLinux(dev, csum, other);
699 #elif defined SIOCGIFCAP
700  return GetIfaceOffloadingBSD(dev);
701 #elif defined OS_WIN32
702  return GetIfaceOffloadingWin32(dev, csum, other);
703 #else
704  return 0;
705 #endif
706 }
707 
708 int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
709 {
710  /* already set */
711  if (dev->offload_orig != 0)
712  return 0;
713 #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
714  return DisableIfaceOffloadingLinux(dev, csum, other);
715 #elif defined SIOCSIFCAP
716  return DisableIfaceOffloadingBSD(dev);
717 #elif defined OS_WIN32
718  return DisableIfaceOffloadingWin32(dev, csum, other);
719 #else
720  return 0;
721 #endif
722 
723 }
724 
726 {
727  if (dev->offload_orig != 0) {
728 #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
729  RestoreIfaceOffloadingLinux(dev);
730 #elif defined SIOCSIFCAP
731  RestoreIfaceOffloadingBSD(dev);
732 #elif defined OS_WIN32
733  RestoreIfaceOffloadingWin32(dev);
734 #endif
735  }
736 }
737 
738 int GetIfaceRSSQueuesNum(const char *pcap_dev)
739 {
740 #if defined HAVE_LINUX_ETHTOOL_H && defined ETHTOOL_GRXRINGS
741  struct ifreq ifr;
742  struct ethtool_rxnfc nfccmd;
743  int fd;
744 
745  (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name));
746  fd = socket(AF_INET, SOCK_DGRAM, 0);
747  if (fd == -1) {
749  "Failure when opening socket for ioctl: %s (%d)",
750  strerror(errno), errno);
751  return -1;
752  }
753 
754  nfccmd.cmd = ETHTOOL_GRXRINGS;
755  ifr.ifr_data = (void*) &nfccmd;
756 
757  if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
758  if (errno != ENOTSUP) {
760  "Failure when trying to get number of RSS queue ioctl for '%s': %s (%d)",
761  pcap_dev, strerror(errno), errno);
762  }
763  close(fd);
764  return 0;
765  }
766  close(fd);
767  SCLogInfo("Found %d RX RSS queues for '%s'", (int)nfccmd.data,
768  pcap_dev);
769  return (int)nfccmd.data;
770 #else
771  return 0;
772 #endif
773 }
SC_ERR_NIC_OFFLOADING
@ SC_ERR_NIC_OFFLOADING
Definition: util-error.h:317
win32-syscall.h
SLL_HEADER_LEN
#define SLL_HEADER_LEN
Definition: decode-sll.h:27
GetIfaceRSSQueuesNum
int GetIfaceRSSQueuesNum(const char *pcap_dev)
Definition: util-ioctl.c:738
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:296
LiveDevice_
Definition: util-device.h:39
OFFLOAD_FLAG_TOE
#define OFFLOAD_FLAG_TOE
Definition: util-device.h:30
OFFLOAD_FLAG_TSO
#define OFFLOAD_FLAG_TSO
Definition: util-device.h:24
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
GetIfaceMaxPacketSize
int GetIfaceMaxPacketSize(const char *pcap_dev)
output max packet size for a link
Definition: util-ioctl.c:133
util-device.h
RestoreIfaceOffloading
void RestoreIfaceOffloading(LiveDevice *dev)
Definition: util-ioctl.c:725
LiveDevice_::dev
char * dev
Definition: util-device.h:40
SC_ERR_SYSCALL
@ SC_ERR_SYSCALL
Definition: util-error.h:80
decode-sll.h
ETHERNET_HEADER_LEN
#define ETHERNET_HEADER_LEN
Definition: decode-ethernet.h:27
conf.h
LiveDevice_::offload_orig
uint32_t offload_orig
Definition: util-device.h:53
GetIfaceOffloading
int GetIfaceOffloading(const char *dev, int csum, int other)
output offloading status of the link
Definition: util-ioctl.c:695
DisableIfaceOffloading
int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
Definition: util-ioctl.c:708
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:215
OFFLOAD_FLAG_GSO
#define OFFLOAD_FLAG_GSO
Definition: util-device.h:25
OFFLOAD_FLAG_SG
#define OFFLOAD_FLAG_SG
Definition: util-device.h:23
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
OFFLOAD_FLAG_GRO
#define OFFLOAD_FLAG_GRO
Definition: util-device.h:26
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:222
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:255
OFFLOAD_FLAG_LRO
#define OFFLOAD_FLAG_LRO
Definition: util-device.h:27
SCLogWarning
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:242
util-ioctl.h
OFFLOAD_FLAG_RXCSUM
#define OFFLOAD_FLAG_RXCSUM
Definition: util-device.h:28
OFFLOAD_FLAG_TXCSUM
#define OFFLOAD_FLAG_TXCSUM
Definition: util-device.h:29
GetIfaceMTU
int GetIfaceMTU(const char *pcap_dev)
output the link MTU
Definition: util-ioctl.c:92