[Oisf-users] [PATCH 2/2] IPS: be sure to destroy packet when cleaning

Eric Leblond eric at regit.org
Wed Aug 17 17:36:05 UTC 2011


If there is some problem during the treatment of a packet, the
TmqhOutputPacketpool() function is called. This function was not
taking a decision on the packet which would become for the kernel
a ghost. This patch adds warning message and treat the NFQ case.
Ghosts remains possible for ipfw.
---
 src/decode.h          |    1 +
 src/source-ipfw.c     |    1 +
 src/source-nfq.c      |    9 +++++++++
 src/source-nfq.h      |    1 +
 src/tmqh-packetpool.c |   36 ++++++++++++++++++++++++++++++++++++
 5 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/src/decode.h b/src/decode.h
index 876b3cc..2c587b7 100644
--- a/src/decode.h
+++ b/src/decode.h
@@ -819,6 +819,7 @@ void AddressDebugPrint(Address *);
 
 #define PKT_TUNNEL                      0x1000
 #define PKT_TUNNEL_VERDICTED            0x2000
+#define PKT_DECISION_TAKEN              0x4000    /**< In IPS mode: if set packet has been sent back to kernel */
 
 /** \brief return 1 if the packet is a pseudo packet */
 #define PKT_IS_PSEUDOPKT(p) ((p)->flags & PKT_PSEUDO_STREAM_END)
diff --git a/src/source-ipfw.c b/src/source-ipfw.c
index 53c7097..cdfe3a9 100644
--- a/src/source-ipfw.c
+++ b/src/source-ipfw.c
@@ -518,6 +518,7 @@ TmEcode IPFWSetVerdict(ThreadVars *tv, IPFWThreadVars *ptv, Packet *p) {
 
     } /* end IPFW_DROP */
 
+    p->flags |= PKT_DECISION_TAKEN;
     SCReturnInt(TM_ECODE_OK);
 }
 
diff --git a/src/source-nfq.c b/src/source-nfq.c
index 4910005..978b2cd 100644
--- a/src/source-nfq.c
+++ b/src/source-nfq.c
@@ -339,6 +339,7 @@ static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
         nfq_q->bytes += GET_PKT_LEN(p);
 #endif /* COUNTERS */
         /* recycle Packet and leave */
+        p->flags |= PKT_DECISION_TAKEN;
         TmqhOutputPacketpool(tv, p);
         return 0;
     }
@@ -918,9 +919,17 @@ TmEcode NFQSetVerdict(Packet *p) {
         SCLogWarning(SC_ERR_NFQ_SET_VERDICT, "nfq_set_verdict of %p failed %" PRId32 "", p, ret);
         return TM_ECODE_FAILED;
     }
+
+    p->flags |= PKT_DECISION_TAKEN;
     return TM_ECODE_OK;
 }
 
+void NFQSetVerdictRescue(void *p) {
+    Packet *bp = (Packet *)p;
+    SCLogWarning(SC_ERR_NFQ_SET_VERDICT, "trying to issue verdict on %d", bp->nfq_v.id);
+    NFQSetVerdict(bp);
+}
+
 /**
  * \brief NFQ verdict module packet entry function
  */
diff --git a/src/source-nfq.h b/src/source-nfq.h
index bb7f78f..a79a4a9 100644
--- a/src/source-nfq.h
+++ b/src/source-nfq.h
@@ -105,6 +105,7 @@ int NFQGetQueueCount(void);
 void *NFQGetQueue(int number);
 int NFQGetQueueNum(int number);
 void *NFQGetThread(int number);
+void NFQSetVerdictRescue(void *p);
 #endif /* NFQ */
 #endif /* __SOURCE_NFQ_H__ */
 
diff --git a/src/tmqh-packetpool.c b/src/tmqh-packetpool.c
index b61f6ce..bd350f6 100644
--- a/src/tmqh-packetpool.c
+++ b/src/tmqh-packetpool.c
@@ -49,6 +49,11 @@
 #include "util-debug.h"
 #include "util-error.h"
 
+
+#include "runmodes.h"
+
+extern int run_mode;
+
 static RingBuffer16 *ringbuffer = NULL;
 /**
  * \brief TmqhPacketpoolRegister
@@ -154,6 +159,21 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
                  * by the tunnel packets, and we will enqueue it
                  * when we handle them */
                 SET_TUNNEL_PKT_VERDICTED(p);
+                switch (run_mode) {
+                    case RUNMODE_NFQ:
+                        if (!(p->flags & PKT_DECISION_TAKEN)) {
+                            SCLogInfo("Packet %p has been outed without verdict, dropping it", p);
+                            p->action |= ACTION_DROP;
+                            NFQSetVerdictRescue(p);
+                        }
+                    case RUNMODE_IPFW:
+                        if (!(p->flags & PKT_DECISION_TAKEN)) {
+                            SCLogInfo("Packet %p has been outed without verdict", p);
+                            SCLogInfo("Running ipfw is bad luck here");
+                        }
+                    default:
+                        break;
+                }
                 SCReturn;
             }
         } else {
@@ -187,6 +207,22 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
             }
         }
         SCLogDebug("tunnel stuff done, move on (proot %d)", proot);
+    } else {
+        switch (run_mode) {
+            case RUNMODE_NFQ:
+                if (!(p->flags & PKT_DECISION_TAKEN)) {
+                    SCLogInfo("Packet %p has been outed without verdict, dropping it", p);
+                    p->action |= ACTION_DROP;
+                    NFQSetVerdictRescue(p);
+                }
+            case RUNMODE_IPFW:
+                if (!(p->flags & PKT_DECISION_TAKEN)) {
+                    SCLogInfo("Packet %p has been outed without verdict", p);
+                    SCLogInfo("Running ipfw is bad luck here");
+                }
+            default:
+                break;
+        }
     }
 
     FlowDecrUsecnt(p->flow);
-- 
1.7.5.4




More information about the Oisf-users mailing list