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