From f76448c1e6d220169f68a3504d35fbe8fdcab257 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Wed, 4 Dec 2013 10:43:17 +0100 Subject: [PATCH] decode: fix failure in layered tunnel If we have multiple layer of tunnel, the decoding of initial Packet will recurse in DecodeTunnel function called in PacketTunnelPktSetup. If we are not setting the pseudo packet root before calling DecodeTunnel (as done in previous code), then the tunnel root will no be correct for the lower layer packets. This result in an counter problem and a suricata failure after some time. --- src/decode.c | 16 ++++++++++------ src/decode.h | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/decode.c b/src/decode.c index 65deed8e0a..409203775c 100644 --- a/src/decode.c +++ b/src/decode.c @@ -250,12 +250,6 @@ Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *pare SCReturnPtr(NULL, "Packet"); } - /* set the root ptr to the lowest layer */ - if (parent->root != NULL) - p->root = parent->root; - else - p->root = parent; - /* copy packet and set lenght, proto */ PacketCopyData(p, pkt, len); p->recursion_level = parent->recursion_level + 1; @@ -263,6 +257,12 @@ Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *pare p->ts.tv_usec = parent->ts.tv_usec; p->datalink = DLT_RAW; + /* set the root ptr to the lowest layer */ + if (parent->root != NULL) + p->root = parent->root; + else + p->root = parent; + /* tell new packet it's part of a tunnel */ SET_TUNNEL_PKT(p); @@ -270,10 +270,14 @@ Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *pare GET_PKT_LEN(p), pq, proto); if (unlikely(ret != TM_ECODE_OK)) { + /* Not a tunnel packet, just a pseudo packet */ + p->root = NULL; + UNSET_TUNNEL_PKT(p); TmqhOutputPacketpool(tv, p); SCReturnPtr(NULL, "Packet"); } + /* tell parent packet it's part of a tunnel */ SET_TUNNEL_PKT(parent); diff --git a/src/decode.h b/src/decode.h index 1d9555f66d..d2e85cd7a0 100644 --- a/src/decode.h +++ b/src/decode.h @@ -803,6 +803,7 @@ typedef struct DecodeThreadVars_ #define IS_TUNNEL_PKT(p) (((p)->flags & PKT_TUNNEL)) #define SET_TUNNEL_PKT(p) ((p)->flags |= PKT_TUNNEL) +#define UNSET_TUNNEL_PKT(p) ((p)->flags &= ~PKT_TUNNEL) #define IS_TUNNEL_ROOT_PKT(p) (IS_TUNNEL_PKT(p) && (p)->root == NULL) #define IS_TUNNEL_PKT_VERDICTED(p) (((p)->flags & PKT_TUNNEL_VERDICTED))