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 */
59static 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 */
82int 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 */
150int 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 */
185int 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
215int 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
238int 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
264static 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
289static 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
314static 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
392static 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);
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
460static 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
518static 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)) {
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
552static 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
615static 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 */
670int 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
683int 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
713int 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}
#define ETHERNET_HEADER_LEN
uint8_t flags
Definition decode-gre.h:0
#define SLL_HEADER_LEN
Definition decode-sll.h:27
size_t strlcpy(char *dst, const char *src, size_t siz)
#define SCLogPerf(...)
Definition util-debug.h:234
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition util-debug.h:225
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define OFFLOAD_FLAG_SG
Definition util-device.h:26
#define OFFLOAD_FLAG_LRO
Definition util-device.h:30
#define OFFLOAD_FLAG_TXCSUM
Definition util-device.h:32
#define OFFLOAD_FLAG_RXCSUM
Definition util-device.h:31
#define OFFLOAD_FLAG_GRO
Definition util-device.h:29
#define OFFLOAD_FLAG_TOE
Definition util-device.h:33
#define OFFLOAD_FLAG_TSO
Definition util-device.h:27
#define OFFLOAD_FLAG_GSO
Definition util-device.h:28
int GetIfaceMaxPacketSize(LiveDevice *ld)
output max packet size for a link
Definition util-ioctl.c:121
int GetIfaceRSSQueuesNum(const char *dev)
Definition util-ioctl.c:713
int GetIfaceOffloading(const char *dev, int csum, int other)
output offloading status of the link
Definition util-ioctl.c:670
int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
Definition util-ioctl.c:683
int GetIfaceMTU(const char *dev)
output the link MTU
Definition util-ioctl.c:82
void RestoreIfaceOffloading(LiveDevice *dev)
Definition util-ioctl.c:700