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