]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfq: implement "fail-open" support.
authorEric Leblond <eric@regit.org>
Tue, 7 Aug 2012 16:20:13 +0000 (18:20 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 22 Aug 2012 07:31:47 +0000 (09:31 +0200)
On linux >= 3.6, you can use the fail-open option on a NFQ queue
to have the kernel accept the packet if userspace is not able to keep
pace.

Please note that the kernel will not trigger an error if the feature is activated
in userspace libraries but not available in kernel.

This patch implements the option for suricata by adding a nfq.fail-open
configuration variable which is desactivated by default.

configure.ac
src/source-nfq.c
suricata.yaml.in

index 6c0f4df79ad1363f4c25b021f5ddde051e34922b..9a6d13a049c7f89cf64dfac2acddc17ac4251cda 100644 (file)
@@ -553,6 +553,7 @@ AC_INIT(configure.ac)
         AC_CHECK_LIB(netfilter_queue, nfq_open,, NFQ="no",)
         AC_CHECK_LIB([netfilter_queue], [nfq_set_queue_maxlen],AC_DEFINE_UNQUOTED([HAVE_NFQ_MAXLEN],[1],[Found queue max length support in netfilter_queue]) ,,[-lnfnetlink])
         AC_CHECK_LIB([netfilter_queue], [nfq_set_verdict2],AC_DEFINE_UNQUOTED([HAVE_NFQ_SET_VERDICT2],[1],[Found nfq_set_verdict2 function in netfilter_queue]) ,,[-lnfnetlink])
+        AC_CHECK_LIB([netfilter_queue], [nfq_set_queue_flags],AC_DEFINE_UNQUOTED([HAVE_NFQ_SET_QUEUE_FLAGS],[1],[Found nfq_set_queue_flags function in netfilter_queue]) ,,[-lnfnetlink])
 
         # check if the argument to nfq_get_payload is signed or unsigned
         AC_MSG_CHECKING([for signed nfq_get_payload payload argument])
index 9b3018acb6d93ab59ebee7448ca8e2c4c9a644f4..78b936d45c49c497fe46543e316020a7e801d586 100644 (file)
@@ -156,11 +156,14 @@ typedef enum NFQMode_ {
     NFQ_ROUTE_MODE,
 } NFQMode;
 
+#define NFQ_FLAG_FAIL_OPEN  (1 << 0)
+
 typedef struct NFQCnf_ {
     NFQMode mode;
     uint32_t mark;
     uint32_t mask;
     uint32_t next_queue;
+    uint32_t flags;
 } NFQCnf;
 
 NFQCnf nfq_config;
@@ -208,6 +211,7 @@ void NFQInitConfig(char quiet)
 {
     intmax_t value = 0;
     char* nfq_mode = NULL;
+    int boolval;
 
     SCLogDebug("Initializing NFQ");
 
@@ -228,6 +232,17 @@ void NFQInitConfig(char quiet)
         }
     }
 
+    (void)ConfGetBool("nfq.fail-open", (int *)&boolval);
+    if (boolval) {
+#ifdef HAVE_NFQ_SET_QUEUE_FLAGS
+        SCLogInfo("Enabling fail-open on queue");
+        nfq_config.flags |= NFQ_FLAG_FAIL_OPEN;
+#else
+        SCLogError(SC_ERR_NFQ_NOSUPPORT,
+                   "nfq.fail-open set but NFQ library has no support for it.");
+#endif
+    }
+
     if ((ConfGetInt("nfq.repeat-mark", &value)) == 1) {
         nfq_config.mark = (uint32_t)value;
     }
@@ -497,6 +512,21 @@ TmEcode NFQInitThread(NFQThreadVars *nfq_t, uint32_t queue_maxlen)
     setsockopt(nfq_q->fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(int));
 #endif
 
+#ifdef HAVE_NFQ_SET_QUEUE_FLAGS
+    if (nfq_config.flags & NFQ_FLAG_FAIL_OPEN) {
+        uint32_t flags = NFQA_CFG_F_FAIL_OPEN;
+        uint32_t mask = NFQA_CFG_F_FAIL_OPEN;
+        int r = nfq_set_queue_flags(nfq_q->qh, mask, flags);
+
+        if (r == -1) {
+            SCLogWarning(SC_ERR_NFQ_SET_MODE, "can't set fail-open mode: %s",
+                         strerror(errno));
+        } else {
+            SCLogInfo("fail-open mode should be set on queue");
+        }
+    }
+#endif
+
     /* set a timeout to the socket so we can check for a signal
      * in case we don't get packets for a longer period. */
     tv.tv_sec = 1;
index a554a1e8ff48f253254699a4746dfc319c5370ef..a2ceaba5c7464b6da2ce9719ab02fda1e8196107 100644 (file)
@@ -189,11 +189,14 @@ magic-file: @e_magic_file@
 # this mode, you need to set mode to 'repeat'
 # If you want packet to be sent to another queue after an ACCEPT decision
 # set mode to 'route' and set next-queue value.
+# On linux >= 3.6, you can set the fail-open option to yes to have the kernel
+# accept the packet if suricata is not able to keep pace.
 nfq:
 #  mode: accept
 #  repeat-mark: 1
 #  repeat-mask: 1
 #  route-queue: 2
+#  fail-open: yes
 
 # af-packet support
 # Set threads to > 1 to use PACKET_FANOUT support