]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
util-device: change logic of registration
authorEric Leblond <eric@regit.org>
Sat, 30 Dec 2017 18:50:12 +0000 (19:50 +0100)
committerEric Leblond <eric@regit.org>
Tue, 6 Feb 2018 15:58:19 +0000 (16:58 +0100)
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.

src/source-ipfw.c
src/source-nfq.c
src/suricata.c
src/util-device.c
src/util-device.h

index 6821d69456cdc78b71796bf2a4a7a3a4557873e2..fb89a03cc8b1349a06eb238ed1afeed6a4303e68 100644 (file)
@@ -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;
index 4f1eb6bb78b0c86cd54db5428da109290e8a94b3..f693bccf23ea6564cd7fab462cb6fe04a06e69d3 100644 (file)
@@ -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;
index dd7aad9902a811120338818081d7fd3372dd62b2..dae12f0d1096d1f5c9d776ec5ad57aee590c7ac6 100644 (file)
@@ -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);
 
index 1a7aacf0206003c8bf84510dc5f2ffac23665212..439d06abb9e32b859c058d932d7151e79b3d8b1f 100644 (file)
 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);
+    }
+}
index 80b372ac99c6a1969bc6d6ae3b440c79933bdf86..2bdd00d33c44282545270754981845bf32f74ac7 100644 (file)
@@ -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);