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