util-device: change logic of registration

Device storage requires the devices to be created after storage
is finalized so we need to first get the list of devices then
create them when the storage is finalized.

This patch introduces the LiveDeviceName structure that is a list
of device name used during registration.

Code uses LiveRegisterDeviceName for pre registration and keep
using the LiveRegisterDevice function for part of the code that
create the interface during the runmode creation.
pull/3221/head
Eric Leblond 7 years ago
parent 0998f37b78
commit 4474889667

@ -737,7 +737,7 @@ int IPFWRegisterQueue(char *queue)
nq->port_num = port_num;
receive_port_num++;
SCMutexUnlock(&ipfw_init_lock);
LiveRegisterDevice(queue);
LiveRegisterDeviceName(queue);
SCLogDebug("Queue \"%s\" registered.", queue);
return 0;

@ -856,7 +856,7 @@ int NFQRegisterQueue(char *queue)
nq->queue_num = queue_num;
receive_queue_num++;
SCMutexUnlock(&nfq_init_lock);
LiveRegisterDevice(queue);
LiveRegisterDeviceName(queue);
SCLogDebug("Queue \"%s\" registered.", queue);
return 0;

@ -1102,7 +1102,7 @@ static int ParseCommandLineAfpacket(SCInstance *suri, const char *in_arg)
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_AFP_DEV;
if (in_arg) {
LiveRegisterDevice(in_arg);
LiveRegisterDeviceName(in_arg);
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
strlcpy(suri->pcap_dev, in_arg, sizeof(suri->pcap_dev));
}
@ -1110,7 +1110,7 @@ static int ParseCommandLineAfpacket(SCInstance *suri, const char *in_arg)
SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using "
"multiple devices to get packets is experimental.");
if (in_arg) {
LiveRegisterDevice(in_arg);
LiveRegisterDeviceName(in_arg);
} else {
SCLogInfo("Multiple af-packet option without interface on each is useless");
}
@ -1154,7 +1154,7 @@ static int ParseCommandLinePcapLive(SCInstance *suri, const char *in_arg)
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_PCAP_DEV;
if (in_arg) {
LiveRegisterDevice(suri->pcap_dev);
LiveRegisterDeviceName(suri->pcap_dev);
}
} else if (suri->run_mode == RUNMODE_PCAP_DEV) {
#ifdef OS_WIN32
@ -1164,7 +1164,7 @@ static int ParseCommandLinePcapLive(SCInstance *suri, const char *in_arg)
#else
SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using "
"multiple pcap devices to get packets is experimental.");
LiveRegisterDevice(suri->pcap_dev);
LiveRegisterDeviceName(suri->pcap_dev);
#endif
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
@ -1557,7 +1557,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
strlcpy(suri->pcap_dev, optarg,
((strlen(optarg) < sizeof(suri->pcap_dev)) ?
(strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
LiveRegisterDevice(optarg);
LiveRegisterDeviceName(optarg);
}
#else
SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
@ -1599,7 +1599,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_NETMAP;
if (optarg) {
LiveRegisterDevice(optarg);
LiveRegisterDeviceName(optarg);
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
strlcpy(suri->pcap_dev, optarg,
((strlen(optarg) < sizeof(suri->pcap_dev)) ?
@ -1609,7 +1609,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using "
"multiple devices to get packets is experimental.");
if (optarg) {
LiveRegisterDevice(optarg);
LiveRegisterDeviceName(optarg);
} else {
SCLogInfo("Multiple netmap option without interface on each is useless");
break;
@ -1758,7 +1758,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
PrintUsage(argv[0]);
return TM_ECODE_FAILED;
}
LiveRegisterDevice(optarg);
LiveRegisterDeviceName(optarg);
#else
SCLogError(SC_ERR_DAG_REQUIRED, "libdag and a DAG card are required"
" to receive packets using --dag.");
@ -1798,7 +1798,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
strlcpy(suri->pcap_dev, optarg,
((strlen(optarg) < sizeof(suri->pcap_dev)) ?
(strlen(optarg) + 1) : sizeof(suri->pcap_dev)));
LiveRegisterDevice(optarg);
LiveRegisterDeviceName(optarg);
}
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE,
@ -2847,6 +2847,8 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
LiveDeviceFinalize();
SCDropMainThreadCaps(suricata.userid, suricata.groupid);
PreRunPostPrivsDropInit(suricata.run_mode);

@ -36,6 +36,15 @@
static TAILQ_HEAD(, LiveDevice_) live_devices =
TAILQ_HEAD_INITIALIZER(live_devices);
/** List of the name of devices
*
* As we don't know the size of the Storage on devices
* before the parsing we need to wait and use this list
* to create later the LiveDevice via LiveDeviceFinalize()
*/
static TAILQ_HEAD(, LiveDeviceName_) pre_live_devices =
TAILQ_HEAD_INITIALIZER(pre_live_devices);
/** if set to 0 when we don't have real devices */
static int live_devices_stats = 1;
@ -60,7 +69,39 @@ int LiveGetOffload(void)
}
/**
* \brief Add a pcap device for monitoring
* \brief Add a device for monitoring
*
* To be used during option parsing. When a device has
* to be created during runmode init, use LiveRegisterDevice()
*
* \param dev string with the device name
*
* \retval 0 on success.
* \retval -1 on failure.
*/
int LiveRegisterDeviceName(const char *dev)
{
LiveDeviceName *pd = NULL;
pd = SCCalloc(1, sizeof(LiveDeviceName));
if (unlikely(pd == NULL)) {
return -1;
}
pd->dev = SCStrdup(dev);
if (unlikely(pd->dev == NULL)) {
SCFree(pd);
return -1;
}
TAILQ_INSERT_TAIL(&pre_live_devices, pd, next);
SCLogDebug("Device \"%s\" registered.", dev);
return 0;
}
/**
* \brief Add a pcap device for monitoring and create structure
*
* \param dev string with the device name
*
@ -94,7 +135,7 @@ int LiveRegisterDevice(const char *dev)
pd->ignore_checksum = 0;
TAILQ_INSERT_TAIL(&live_devices, pd, next);
SCLogDebug("Device \"%s\" registered.", dev);
SCLogDebug("Device \"%s\" registered and created.", dev);
return 0;
}
@ -254,7 +295,7 @@ int LiveBuildDeviceListCustom(const char *runmode, const char *itemname)
break;
SCLogConfig("Adding %s %s from config file",
itemname, subchild->val);
LiveRegisterDevice(subchild->val);
LiveRegisterDeviceName(subchild->val);
i++;
}
}
@ -389,3 +430,22 @@ LiveDevice *LiveDeviceForEach(LiveDevice **ldev, LiveDevice **ndev)
return NULL;
}
/**
* Create registered devices
*
* This function creates all needed LiveDevice from
* the LiveDeviceName list created via LiveRegisterDevice()
*/
void LiveDeviceFinalize(void)
{
LiveDeviceName *ld, *pld;
SCLogDebug("Finalize live device");
/* Iter on devices and register them */
TAILQ_FOREACH_SAFE(ld, &pre_live_devices, next, pld) {
if (ld->dev) {
LiveRegisterDevice(ld->dev);
SCFree(ld->dev);
}
SCFree(ld);
}
}

@ -50,6 +50,12 @@ typedef struct LiveDevice_ {
uint32_t offload_orig; /**< original offload settings to restore @exit */
} LiveDevice;
typedef struct LiveDeviceName_ {
char *dev; /**< the device (e.g. "eth0") */
TAILQ_ENTRY(LiveDeviceName_) next;
} LiveDeviceName;
int LiveRegisterDeviceName(const char *dev);
int LiveRegisterDevice(const char *dev);
int LiveGetDeviceCount(void);
const char *LiveGetDeviceName(int number);
@ -62,6 +68,8 @@ int LiveBuildDeviceListCustom(const char *base, const char *itemname);
LiveDevice *LiveDeviceForEach(LiveDevice **ldev, LiveDevice **ndev);
void LiveDeviceFinalize(void);
#ifdef BUILD_UNIX_SOCKET
TmEcode LiveDeviceIfaceStat(json_t *cmd, json_t *server_msg, void *data);
TmEcode LiveDeviceIfaceList(json_t *cmd, json_t *server_msg, void *data);

Loading…
Cancel
Save