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