suricata
util-device.c
Go to the documentation of this file.
1/* Copyright (C) 2011-2021 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#include "suricata-common.h"
19#include "conf.h"
20#include "util-device-private.h"
21#include "util-ioctl.h"
22#include "util-misc.h"
23#include "util-dpdk.h"
24
25#include "device-storage.h"
26#include "util-debug.h"
27#include "util-affinity.h"
28
29#define MAX_DEVNAME 10
30
31static LiveDevStorageId g_bypass_storage_id = { .id = -1 };
32
33/**
34 * \file
35 *
36 * \author Eric Leblond <eric@regit.org>
37 *
38 * \brief Utility functions to handle device list
39 */
40
41/** private device list */
42static TAILQ_HEAD(, LiveDevice_) live_devices =
43 TAILQ_HEAD_INITIALIZER(live_devices);
44
45typedef struct LiveDeviceName_ {
46 char *dev; /**< the device (e.g. "eth0") */
47 TAILQ_ENTRY(LiveDeviceName_) next;
49
50/** List of the name of devices
51 *
52 * As we don't know the size of the Storage on devices
53 * before the parsing we need to wait and use this list
54 * to create later the LiveDevice via LiveDeviceFinalize()
55 */
56static TAILQ_HEAD(, LiveDeviceName_) pre_live_devices =
57 TAILQ_HEAD_INITIALIZER(pre_live_devices);
58
59typedef struct BypassInfo_ {
60 SC_ATOMIC_DECLARE(uint64_t, ipv4_hash_count);
61 SC_ATOMIC_DECLARE(uint64_t, ipv4_fail);
62 SC_ATOMIC_DECLARE(uint64_t, ipv4_success);
63 SC_ATOMIC_DECLARE(uint64_t, ipv6_hash_count);
64 SC_ATOMIC_DECLARE(uint64_t, ipv6_fail);
65 SC_ATOMIC_DECLARE(uint64_t, ipv6_success);
67
68/** if set to 0 when we don't have real devices */
69static int live_devices_stats = 1;
70
71
72static int LiveSafeDeviceName(const char *devname,
73 char *newdevname, size_t destlen);
74
75static int g_live_devices_disable_offloading = 1;
76
78{
79 g_live_devices_disable_offloading = 1;
80}
81
83{
84 g_live_devices_disable_offloading = 0;
85}
86
88{
89 return g_live_devices_disable_offloading;
90}
91
92/**
93 * \brief Add a device for monitoring
94 *
95 * To be used during option parsing. When a device has
96 * to be created during runmode init, use LiveRegisterDevice()
97 *
98 * \param dev string with the device name
99 *
100 * \retval 0 on success.
101 * \retval -1 on failure.
102 */
103int LiveRegisterDeviceName(const char *dev)
104{
105 LiveDeviceName *pd = NULL;
106
107 pd = SCCalloc(1, sizeof(LiveDeviceName));
108 if (unlikely(pd == NULL)) {
109 return -1;
110 }
111
112 pd->dev = SCStrdup(dev);
113 if (unlikely(pd->dev == NULL)) {
114 SCFree(pd);
115 return -1;
116 }
117
118 TAILQ_INSERT_TAIL(&pre_live_devices, pd, next);
119
120 SCLogDebug("Device \"%s\" registered.", dev);
121 return 0;
122}
123
124/**
125 * \brief Add a pcap device for monitoring and create structure
126 *
127 * \param dev string with the device name
128 *
129 * \retval 0 on success.
130 * \retval -1 on failure.
131 */
132int LiveRegisterDevice(const char *dev)
133{
134 LiveDevice *pd = NULL;
135
136 pd = SCCalloc(1, sizeof(LiveDevice) + LiveDevStorageSize());
137 if (unlikely(pd == NULL)) {
138 return -1;
139 }
140
141 int id = LiveGetDeviceCount();
142 if (id > UINT16_MAX) {
143 SCFree(pd);
144 return -1;
145 }
146
147 pd->dev = SCStrdup(dev);
148 if (unlikely(pd->dev == NULL)) {
149 SCFree(pd);
150 return -1;
151 }
152 /* create a short version to be used in thread names */
153 LiveSafeDeviceName(pd->dev, pd->dev_short, sizeof(pd->dev_short));
154
155 SC_ATOMIC_INIT(pd->pkts);
156 SC_ATOMIC_INIT(pd->drop);
157 SC_ATOMIC_INIT(pd->invalid_checksums);
158 pd->id = (uint16_t)id;
159 TAILQ_INSERT_TAIL(&live_devices, pd, next);
160
161 SCLogDebug("Device \"%s\" registered and created.", dev);
162 return 0;
163}
164
165/**
166 * \brief Get the number of registered devices
167 *
168 * \retval cnt the number of registered devices
169 */
171{
172 int i = 0;
173 LiveDevice *pd;
174
175 TAILQ_FOREACH(pd, &live_devices, next) {
176 i++;
177 }
178
179 return i;
180}
181
183{
184 int i = 0;
185 LiveDevice *pd;
186
187 TAILQ_FOREACH (pd, &live_devices, next) {
188 if (GetAffinityTypeForNameAndIface("worker-cpu-set", pd->dev) == NULL) {
189 i++;
190 }
191 }
192
193 return i;
194}
195
196/**
197 * \brief Get a pointer to the device name at idx
198 *
199 * \param number idx of the device in our list
200 *
201 * \retval ptr pointer to the string containing the device
202 * \retval NULL on error
203 */
204const char *LiveGetDeviceName(int number)
205{
206 int i = 0;
207 LiveDevice *pd;
208
209 TAILQ_FOREACH(pd, &live_devices, next) {
210 if (i == number) {
211 return pd->dev;
212 }
213
214 i++;
215 }
216
217 return NULL;
218}
219
220/** \internal
221 * \brief Shorten a device name that is to long
222 *
223 * \param device name from config and destination for modified
224 *
225 * \retval None, is added to destination char *newdevname
226 */
227static int LiveSafeDeviceName(const char *devname, char *newdevname, size_t destlen)
228{
229 const size_t devnamelen = strlen(devname);
230
231 /* If we have to shorten the interface name */
232 if (devnamelen > MAX_DEVNAME) {
233 /* special mode for DPDK pci addresses */
234 if (devnamelen >= 5 && strncmp(devname, "0000:", 5) == 0) {
235 strlcpy(newdevname, devname + 5, destlen);
236 return 0;
237 }
238
239 /* IF the dest length is over 10 chars long it will not do any
240 * good for the shortening. The shortening is done due to the
241 * max length of pthread names (15 chars) and we use 3 chars
242 * for the threadname indicator eg. "W#-" and one-two chars for
243 * the thread number. And if the destination buffer is under
244 * 6 chars there is no point in shortening it since we must at
245 * least enter two periods (.) into the string.
246 */
247 if ((destlen-1) > 10 || (destlen-1) < 6) {
248 return 1;
249 }
250
251 ShortenString(devname, newdevname, destlen, '.');
252
253 SCLogInfo("%s: shortening device name to %s", devname, newdevname);
254 } else {
255 strlcpy(newdevname, devname, destlen);
256 }
257 return 0;
258}
259
260/**
261 * \brief Get a pointer to the device at idx
262 *
263 * \param number idx of the device in our list
264 *
265 * \retval ptr pointer to the string containing the device
266 * \retval NULL on error
267 */
269{
270 LiveDevice *pd;
271
272 if (name == NULL) {
273 SCLogWarning("Name of device should not be null");
274 return NULL;
275 }
276
277 TAILQ_FOREACH(pd, &live_devices, next) {
278 if (!strcmp(name, pd->dev)) {
279 return pd;
280 }
281 }
282
283 return NULL;
284}
285
286const char *LiveGetShortName(const char *dev)
287{
288 LiveDevice *live_dev = LiveGetDevice(dev);
289 if (live_dev == NULL)
290 return NULL;
291 return live_dev->dev_short;
292}
293
294int LiveBuildDeviceList(const char *runmode)
295{
296 return LiveBuildDeviceListCustom(runmode, "interface");
297}
298
299int LiveBuildDeviceListCustom(const char *runmode, const char *itemname)
300{
301 SCConfNode *base = SCConfGetNode(runmode);
302 SCConfNode *child;
303 int i = 0;
304
305 if (base == NULL)
306 return 0;
307
308 TAILQ_FOREACH(child, &base->head, next) {
309 SCConfNode *subchild;
310 TAILQ_FOREACH(subchild, &child->head, next) {
311 if ((!strcmp(subchild->name, itemname))) {
312 if (!strcmp(subchild->val, "default"))
313 break;
314 SCLogConfig("Adding %s %s from config file",
315 itemname, subchild->val);
316 LiveRegisterDeviceName(subchild->val);
317 i++;
318 }
319 }
320 }
321
322 return i;
323}
324
325/** Call this function to disable stat on live devices
326 *
327 * This can be useful in the case, this is not a real interface.
328 */
330{
331 live_devices_stats = 0;
332}
333
335{
336 SCEnter();
337 LiveDevice *pd, *tpd;
338
339 /* dpdk: need to close all devices before freeing them. */
340 TAILQ_FOREACH (pd, &live_devices, next) {
341 DPDKCloseDevice(pd);
342 }
343 TAILQ_FOREACH_SAFE(pd, &live_devices, next, tpd) {
344 if (live_devices_stats) {
345 SCLogNotice("%s: packets: %" PRIu64 ", drops: %" PRIu64
346 " (%.2f%%), invalid chksum: %" PRIu64,
347 pd->dev, SC_ATOMIC_GET(pd->pkts), SC_ATOMIC_GET(pd->drop),
348 SC_ATOMIC_GET(pd->pkts) > 0 ? 100 * ((double)SC_ATOMIC_GET(pd->drop)) /
349 (double)SC_ATOMIC_GET(pd->pkts)
350 : 0,
351 SC_ATOMIC_GET(pd->invalid_checksums));
352 }
353
355 DPDKFreeDevice(pd);
356
357 if (pd->dev)
358 SCFree(pd->dev);
360 SCFree(pd);
361 }
362
364}
365
366#ifdef BUILD_UNIX_SOCKET
367TmEcode LiveDeviceIfaceStat(json_t *cmd, json_t *answer, void *data)
368{
369 SCEnter();
370 LiveDevice *pd;
371 const char * name = NULL;
372 json_t *jarg = json_object_get(cmd, "iface");
373 if(!json_is_string(jarg)) {
374 json_object_set_new(answer, "message", json_string("Iface is not a string"));
376 }
377 name = json_string_value(jarg);
378 if (name == NULL) {
379 json_object_set_new(answer, "message", json_string("Iface name is NULL"));
381 }
382
383 TAILQ_FOREACH(pd, &live_devices, next) {
384 if (!strcmp(name, pd->dev)) {
385 json_t *jdata = json_object();
386 if (jdata == NULL) {
387 json_object_set_new(answer, "message",
388 json_string("internal error at json object creation"));
390 }
391 json_object_set_new(jdata, "pkts",
392 json_integer(SC_ATOMIC_GET(pd->pkts)));
393 json_object_set_new(jdata, "invalid-checksums",
394 json_integer(SC_ATOMIC_GET(pd->invalid_checksums)));
395 json_object_set_new(jdata, "drop",
396 json_integer(SC_ATOMIC_GET(pd->drop)));
397 json_object_set_new(jdata, "bypassed",
398 json_integer(SC_ATOMIC_GET(pd->bypassed)));
399 json_object_set_new(answer, "message", jdata);
401 }
402 }
403 json_object_set_new(answer, "message", json_string("Iface does not exist"));
405}
406
407TmEcode LiveDeviceIfaceList(json_t *cmd, json_t *answer, void *data)
408{
409 SCEnter();
410 json_t *jdata;
411 json_t *jarray;
412 LiveDevice *pd;
413 int i = 0;
414
415 jdata = json_object();
416 if (jdata == NULL) {
417 json_object_set_new(answer, "message",
418 json_string("internal error at json object creation"));
419 return TM_ECODE_FAILED;
420 }
421 jarray = json_array();
422 if (jarray == NULL) {
423 json_object_set_new(answer, "message",
424 json_string("internal error at json object creation"));
425 return TM_ECODE_FAILED;
426 }
427 TAILQ_FOREACH(pd, &live_devices, next) {
428 json_array_append_new(jarray, json_string(pd->dev));
429 i++;
430 }
431
432 json_object_set_new(jdata, "count", json_integer(i));
433 json_object_set_new(jdata, "ifaces", jarray);
434 json_object_set_new(answer, "message", jdata);
436}
437
438#endif /* BUILD_UNIX_SOCKET */
439
441{
442 if (*ldev == NULL) {
443 *ldev = TAILQ_FIRST(&live_devices);
444 *ndev = TAILQ_NEXT(*ldev, next);
445 return *ldev;
446 } else {
447 *ldev = *ndev;
448 if (*ldev) {
449 *ndev = TAILQ_NEXT(*ldev, next);
450 }
451 return *ldev;
452 }
453 return NULL;
454}
455
456/**
457 * Create registered devices
458 *
459 * This function creates all needed LiveDevice from
460 * the LiveDeviceName list created via LiveRegisterDevice()
461 */
463{
464 LiveDeviceName *ld, *pld;
465 SCLogDebug("Finalize live device");
466 /* Iter on devices and register them */
467 TAILQ_FOREACH_SAFE(ld, &pre_live_devices, next, pld) {
468 if (ld->dev) {
469 LiveRegisterDevice(ld->dev);
470 SCFree(ld->dev);
471 }
472 SCFree(ld);
473 }
474}
475
476static void LiveDevExtensionFree(void *x)
477{
478 if (x)
479 SCFree(x);
480}
481
482/**
483 * Register bypass stats storage
484 */
486{
487 g_bypass_storage_id = LiveDevStorageRegister("bypass_stats", sizeof(void *),
488 NULL, LiveDevExtensionFree);
489}
490
491/**
492 * Prepare a LiveDevice so we can set bypass stats
493 */
495{
496 BypassInfo *bpinfo = SCCalloc(1, sizeof(*bpinfo));
497 if (bpinfo == NULL) {
498 SCLogError("Can't allocate bypass info structure");
499 return -1;
500 }
501
502 SC_ATOMIC_INIT(bpinfo->ipv4_hash_count);
503 SC_ATOMIC_INIT(bpinfo->ipv4_hash_count);
504
505 LiveDevSetStorageById(dev, g_bypass_storage_id, bpinfo);
506 return 0;
507}
508
509/**
510 * Increase number of currently bypassed flows for a protocol family
511 *
512 * \param dev pointer to LiveDevice to set stats for
513 * \param cnt number of flows to add
514 * \param family AF_INET to set IPv4 count or AF_INET6 to set IPv6 count
515 */
516void LiveDevAddBypassStats(LiveDevice *dev, uint64_t cnt, int family)
517{
518 BypassInfo *bpfdata = LiveDevGetStorageById(dev, g_bypass_storage_id);
519 if (bpfdata) {
520 if (family == AF_INET) {
521 SC_ATOMIC_ADD(bpfdata->ipv4_hash_count, cnt);
522 } else if (family == AF_INET6) {
523 SC_ATOMIC_ADD(bpfdata->ipv6_hash_count, cnt);
524 }
525 }
526}
527
528/**
529 * Decrease number of currently bypassed flows for a protocol family
530 *
531 * \param dev pointer to LiveDevice to set stats for
532 * \param cnt number of flows to remove
533 * \param family AF_INET to set IPv4 count or AF_INET6 to set IPv6 count
534 */
535void LiveDevSubBypassStats(LiveDevice *dev, uint64_t cnt, int family)
536{
537 BypassInfo *bpfdata = LiveDevGetStorageById(dev, g_bypass_storage_id);
538 if (bpfdata) {
539 if (family == AF_INET) {
540 SC_ATOMIC_SUB(bpfdata->ipv4_hash_count, cnt);
541 } else if (family == AF_INET6) {
542 SC_ATOMIC_SUB(bpfdata->ipv6_hash_count, cnt);
543 }
544 }
545}
546
547/**
548 * Increase number of failed captured flows for a protocol family
549 *
550 * \param dev pointer to LiveDevice to set stats for
551 * \param cnt number of flows to add
552 * \param family AF_INET to set IPv4 count or AF_INET6 to set IPv6 count
553 */
554void LiveDevAddBypassFail(LiveDevice *dev, uint64_t cnt, int family)
555{
556 BypassInfo *bpfdata = LiveDevGetStorageById(dev, g_bypass_storage_id);
557 if (bpfdata) {
558 if (family == AF_INET) {
559 SC_ATOMIC_ADD(bpfdata->ipv4_fail, cnt);
560 } else if (family == AF_INET6) {
561 SC_ATOMIC_ADD(bpfdata->ipv6_fail, cnt);
562 }
563 }
564}
565
566/**
567 * Increase number of currently successfully bypassed flows for a protocol family
568 *
569 * \param dev pointer to LiveDevice to set stats for
570 * \param cnt number of flows to add
571 * \param family AF_INET to set IPv4 count or AF_INET6 to set IPv6 count
572 */
573void LiveDevAddBypassSuccess(LiveDevice *dev, uint64_t cnt, int family)
574{
575 BypassInfo *bpfdata = LiveDevGetStorageById(dev, g_bypass_storage_id);
576 if (bpfdata) {
577 if (family == AF_INET) {
578 SC_ATOMIC_ADD(bpfdata->ipv4_success, cnt);
579 } else if (family == AF_INET6) {
580 SC_ATOMIC_ADD(bpfdata->ipv6_success, cnt);
581 }
582 }
583}
584
585#ifdef BUILD_UNIX_SOCKET
586TmEcode LiveDeviceGetBypassedStats(json_t *cmd, json_t *answer, void *data)
587{
588 if (g_bypass_storage_id.id < 0) {
589 json_object_set_new(answer, "message", json_string("Bypass not enabled"));
591 }
592 LiveDevice *ldev = NULL, *ndev = NULL;
593 json_t *ifaces = NULL;
594 while(LiveDeviceForEach(&ldev, &ndev)) {
595 BypassInfo *bpinfo = LiveDevGetStorageById(ldev, g_bypass_storage_id);
596 if (bpinfo) {
597 uint64_t ipv4_hash_count = SC_ATOMIC_GET(bpinfo->ipv4_hash_count);
598 uint64_t ipv6_hash_count = SC_ATOMIC_GET(bpinfo->ipv6_hash_count);
599 uint64_t ipv4_success = SC_ATOMIC_GET(bpinfo->ipv4_success);
600 uint64_t ipv4_fail = SC_ATOMIC_GET(bpinfo->ipv4_fail);
601 uint64_t ipv6_success = SC_ATOMIC_GET(bpinfo->ipv6_success);
602 uint64_t ipv6_fail = SC_ATOMIC_GET(bpinfo->ipv6_fail);
603 json_t *iface = json_object();
604 if (ifaces == NULL) {
605 ifaces = json_object();
606 if (ifaces == NULL) {
607 json_object_set_new(answer, "message",
608 json_string("internal error at json object creation"));
609 return TM_ECODE_FAILED;
610 }
611 }
612 json_object_set_new(iface, "ipv4_maps_count", json_integer(ipv4_hash_count));
613 json_object_set_new(iface, "ipv4_success", json_integer(ipv4_success));
614 json_object_set_new(iface, "ipv4_fail", json_integer(ipv4_fail));
615 json_object_set_new(iface, "ipv6_maps_count", json_integer(ipv6_hash_count));
616 json_object_set_new(iface, "ipv6_success", json_integer(ipv6_success));
617 json_object_set_new(iface, "ipv6_fail", json_integer(ipv6_fail));
618 json_object_set_new(ifaces, ldev->dev, iface);
619 }
620 }
621 if (ifaces) {
622 json_object_set_new(answer, "message", ifaces);
624 }
625
626 json_object_set_new(answer, "message",
627 json_string("No interface using bypass"));
629}
630#endif
631
633{
634 return SC_ATOMIC_GET(dev->pkts);
635}
636
638{
639 (void)SC_ATOMIC_ADD(dev->pkts, 1);
640}
641
642void LiveDevicePktsAdd(LiveDevice *dev, uint64_t n)
643{
644 (void)SC_ATOMIC_ADD(dev->pkts, n);
645}
646
647void LiveDeviceDropAdd(LiveDevice *dev, uint64_t n)
648{
649 (void)SC_ATOMIC_ADD(dev->drop, n);
650}
651
652void LiveDeviceBypassedAdd(LiveDevice *dev, uint64_t n)
653{
654 (void)SC_ATOMIC_ADD(dev->bypassed, n);
655}
656
658{
659 return SC_ATOMIC_GET(dev->invalid_checksums);
660}
struct HtpBodyChunk_ * next
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
Definition conf.c:181
void LiveDevFreeStorage(LiveDevice *d)
unsigned int LiveDevStorageSize(void)
int LiveDevSetStorageById(LiveDevice *d, LiveDevStorageId id, void *ptr)
Store a pointer in a given LiveDevice storage.
void * LiveDevGetStorageById(LiveDevice *d, LiveDevStorageId id)
Get a value from a given LiveDevice storage.
LiveDevStorageId LiveDevStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Register a LiveDevice storage.
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:252
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:329
#define TAILQ_HEAD(name, type)
Definition queue.h:230
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:294
#define TAILQ_FIRST(head)
Definition queue.h:250
#define TAILQ_NEXT(elm, field)
Definition queue.h:307
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:236
#define TAILQ_ENTRY(type)
Definition queue.h:239
char dev_short[MAX_DEVNAME+1]
char * name
Definition conf.h:38
char * val
Definition conf.h:39
size_t strlcpy(char *dst, const char *src, size_t siz)
@ TM_ECODE_FAILED
@ TM_ECODE_OK
const char * name
uint32_t cnt
ThreadsAffinityType * GetAffinityTypeForNameAndIface(const char *name, const char *interface_name)
Find affinity by name (*-cpu-set name) and an interface name.
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
#define SC_ATOMIC_DECLARE(type, name)
wrapper for declaring atomic variables.
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition util-debug.h:243
#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 SCLogConfig(...)
Definition util-debug.h:229
void LiveDeviceHasNoStats(void)
void LiveDevSubBypassStats(LiveDevice *dev, uint64_t cnt, int family)
void LiveDeviceFinalize(void)
LiveDeviceName
Definition util-device.c:48
uint64_t LiveDevicePktsGet(LiveDevice *dev)
uint64_t LiveDeviceInvalidChecksumsGet(LiveDevice *dev)
void LiveDevicePktsAdd(LiveDevice *dev, uint64_t n)
const char * LiveGetShortName(const char *dev)
BypassInfo
Definition util-device.c:66
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
LiveDevice * LiveDeviceForEach(LiveDevice **ldev, LiveDevice **ndev)
void LiveDevAddBypassStats(LiveDevice *dev, uint64_t cnt, int family)
int LiveGetDeviceCount(void)
Get the number of registered devices.
int LiveGetOffload(void)
Definition util-device.c:87
int LiveBuildDeviceList(const char *runmode)
int LiveDevUseBypass(LiveDevice *dev)
int LiveRegisterDevice(const char *dev)
Add a pcap device for monitoring and create structure.
int LiveGetDeviceCountWithoutAssignedThreading(void)
void LiveDeviceBypassedAdd(LiveDevice *dev, uint64_t n)
void LiveSetOffloadDisable(void)
Definition util-device.c:77
void LiveDevRegisterExtension(void)
int LiveBuildDeviceListCustom(const char *runmode, const char *itemname)
void LiveSetOffloadWarn(void)
Definition util-device.c:82
#define MAX_DEVNAME
Definition util-device.c:29
int LiveRegisterDeviceName(const char *dev)
Add a device for monitoring.
void LiveDevAddBypassSuccess(LiveDevice *dev, uint64_t cnt, int family)
void LiveDevAddBypassFail(LiveDevice *dev, uint64_t cnt, int family)
void LiveDevicePktsIncr(LiveDevice *dev)
int LiveDeviceListClean(void)
const char * LiveGetDeviceName(int number)
Get a pointer to the device name at idx.
void LiveDeviceDropAdd(LiveDevice *dev, uint64_t n)
void DPDKFreeDevice(LiveDevice *ldev)
Definition util-dpdk.c:59
void DPDKCloseDevice(LiveDevice *ldev)
Definition util-dpdk.c:41
void RestoreIfaceOffloading(LiveDevice *dev)
Definition util-ioctl.c:700
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define SCStrdup(s)
Definition util-mem.h:56
void ShortenString(const char *input, char *output, size_t output_size, char c)
Definition util-misc.c:207
#define unlikely(expr)