}
/* ok, we have a flow in the bucket. Let's find out if it is our flow */
+ Flow *pf = NULL; /* previous flow */
f = fb->head;
-
- /* see if this is the flow we are looking for */
- if (FlowCompare(f, p) == 0) {
- Flow *pf = NULL; /* previous flow */
-
- while (f) {
- pf = f;
- f = f->hnext;
-
- if (f == NULL) {
- f = pf->hnext = FlowGetNew(tv, dtv, p);
- if (f == NULL) {
- FBLOCK_UNLOCK(fb);
- return NULL;
- }
- fb->tail = f;
-
- /* flow is locked */
-
- f->hprev = pf;
-
- /* initialize and return */
- FlowInit(f, p);
- f->flow_hash = hash;
- f->fb = fb;
- FlowUpdateState(f, FLOW_STATE_NEW);
-
- FlowReference(dest, f);
-
- FBLOCK_UNLOCK(fb);
- return f;
- }
-
- if (FlowCompare(f, p) != 0) {
- /* we found our flow, lets put it on top of the
- * hash list -- this rewards active flows */
+ do {
+ if (FlowCompare(f, p) != 0) {
+ /* we found our flow, lets put it on top of the
+ * hash list -- this rewards active flows */
+ if (f->hprev) {
if (f->hnext) {
f->hnext->hprev = f->hprev;
}
- if (f->hprev) {
- f->hprev->hnext = f->hnext;
- }
+ f->hprev->hnext = f->hnext;
if (f == fb->tail) {
fb->tail = f->hprev;
}
f->hprev = NULL;
fb->head->hprev = f;
fb->head = f;
-
- /* found our flow, lock & return */
- FLOWLOCK_WRLOCK(f);
- if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx) == 1)) {
- f = TcpReuseReplace(tv, dtv, fb, f, hash, p);
- if (f == NULL) {
- FBLOCK_UNLOCK(fb);
- return NULL;
- }
+ }
+ /* found our flow, lock & return */
+ FLOWLOCK_WRLOCK(f);
+ if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx) == 1)) {
+ f = TcpReuseReplace(tv, dtv, fb, f, hash, p);
+ if (f == NULL) {
+ FBLOCK_UNLOCK(fb);
+ return NULL;
}
+ }
- FlowReference(dest, f);
+ FlowReference(dest, f);
+ FBLOCK_UNLOCK(fb);
+ return f;
+ }
+ if (f->hnext == NULL) {
+ pf = f;
+ f = pf->hnext = FlowGetNew(tv, dtv, p);
+ if (f == NULL) {
FBLOCK_UNLOCK(fb);
- return f;
+ return NULL;
}
- }
- }
+ fb->tail = f;
- /* lock & return */
- FLOWLOCK_WRLOCK(f);
- if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx) == 1)) {
- f = TcpReuseReplace(tv, dtv, fb, f, hash, p);
- if (f == NULL) {
+ /* flow is locked */
+
+ f->hprev = pf;
+
+ /* initialize and return */
+ FlowInit(f, p);
+ f->flow_hash = hash;
+ f->fb = fb;
+ FlowUpdateState(f, FLOW_STATE_NEW);
+ FlowReference(dest, f);
FBLOCK_UNLOCK(fb);
- return NULL;
+ return f;
}
- }
-
- FlowReference(dest, f);
+ pf = f;
+ f = f->hnext;
+ } while (f != NULL);
- FBLOCK_UNLOCK(fb);
- return f;
+ /* should be unreachable */
+ BUG_ON(1);
+ return NULL;
}
static inline int FlowCompareKey(Flow *f, FlowKey *key)