From 8cda70668c714437ec3aad976c8be16cbbb65462 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Fri, 24 Oct 2008 10:00:36 +0200 Subject: [PATCH] Tunnel fixes. --- src/decode-ipv4.c | 11 +++++++-- src/decode-ipv6.c | 6 ++--- src/decode.c | 5 ++-- src/decode.h | 2 ++ src/packet-queue.c | 38 ----------------------------- src/source-nfq.c | 9 +++++-- src/threads.h | 1 + src/tmqh-packetpool.c | 57 ++++++++++++++++++++++++++++++++++++++++--- src/vips.c | 4 +-- 9 files changed, 81 insertions(+), 52 deletions(-) diff --git a/src/decode-ipv4.c b/src/decode-ipv4.c index d99e536ab8..d5e7442808 100644 --- a/src/decode-ipv4.c +++ b/src/decode-ipv4.c @@ -96,17 +96,24 @@ void DecodeIPV4(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len) break; case IPPROTO_IPV6: { - //printf("DecodeIPV4: next layer is IPV6\n"); - //printf("DecodeIPV4: we are p %p\n", p); +// #if 0 + printf("DecodeIPV4: next layer is IPV6\n"); + printf("DecodeIPV4: we are p %p\n", p); /* spawn off tunnel packet */ Packet *tp = TunnelPktSetup(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p), IPV4_GET_IPPROTO(p)); + printf("DecodeIPV4: tunnel is tp %p\n", tp); + /* send that to the Tunnel decoder */ DecodeTunnel(t, tp, tp->pkt, tp->pktlen); + printf("DecodeIPV4: DecodeTunnel done, outputing\n"); + t->tmqh_out(t,tp); /* the current packet is now a tunnel packet */ SET_TUNNEL_PKT(p); + printf("DecodeIPV4: packet is now a tunnel (root) packet: %p\n", p); break; +// #endif } } diff --git a/src/decode-ipv6.c b/src/decode-ipv6.c index a43ae3933c..f33a4e44db 100644 --- a/src/decode-ipv6.c +++ b/src/decode-ipv6.c @@ -35,7 +35,7 @@ DecodeIPV6ExtHdrs(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len) case IPPROTO_UDP: IPV6_SET_L4PROTO(p,nh); - //DecodeUDP(t, p, pkt, plen); + DecodeUDP(t, p, pkt, plen); return; case IPPROTO_ICMPV6: @@ -365,12 +365,12 @@ void DecodeIPV6(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len) return; /* now process the L4 Layer */ - switch(IPV6_GET_L4PROTO(p)) { + switch(IPV6_GET_NH(p)) { case IPPROTO_TCP: return(DecodeTCP(t, p, pkt + IPV6_HEADER_LEN, len - IPV6_HEADER_LEN)); break; case IPPROTO_UDP: - //return(DecodeUDP(p, pkt + IPV6_HEADER_LEN, len - IPV6_HEADER_LEN)); + return(DecodeUDP(t, p, pkt + IPV6_HEADER_LEN, len - IPV6_HEADER_LEN)); break; case IPPROTO_ICMPV6: return(DecodeICMPV6(t, p, pkt + IPV6_HEADER_LEN, len - IPV6_HEADER_LEN)); diff --git a/src/decode.c b/src/decode.c index 20b88c30a6..76275bc994 100644 --- a/src/decode.c +++ b/src/decode.c @@ -8,10 +8,11 @@ void DecodeTunnel(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len) { switch (p->tunnel_proto) { case IPPROTO_IP: - return(DecodeIPV4(t, p, pkt, len)); + return DecodeIPV4(t, p, pkt, len); break; case IPPROTO_IPV6: - return(DecodeIPV6(t, p, pkt, len)); + printf("DecodeTunnel: IPv6 packet\n"); + return DecodeIPV6(t, p, pkt, len); break; default: printf("FIXME: DecodeTunnel: protocol %u not supported.\n", p->tunnel_proto); diff --git a/src/decode.h b/src/decode.h index 5d27d094be..a813c9ddbf 100644 --- a/src/decode.h +++ b/src/decode.h @@ -275,6 +275,8 @@ typedef struct _Packet (p)->action = 0; \ (p)->pktlen = 0; \ (p)->tunnel_pkt = 0; \ + (p)->tunnel_verdicted = 0; \ + pthread_mutex_init(&(p)->mutex_rtv_cnt,NULL); \ (p)->rtv_cnt = 0; \ (p)->tpr_cnt = 0; \ (p)->root = NULL; \ diff --git a/src/packet-queue.c b/src/packet-queue.c index 32effe860e..05111af0e8 100644 --- a/src/packet-queue.c +++ b/src/packet-queue.c @@ -6,44 +6,6 @@ #include "threads.h" void PacketEnqueue (PacketQueue *q, Packet *p) { - if (IS_TUNNEL_PKT(p)) { - /* get a lock */ - pthread_mutex_t *m = p->root ? &p->root->mutex_rtv_cnt : &p->mutex_rtv_cnt; - mutex_lock(m); - - if (IS_TUNNEL_ROOT_PKT(p)) { - if (TUNNEL_PKT_TPR(p) == 0) { - /* if this packet is the root and there are no - * more tunnel packets, enqueue it */ - - /* fall through */ - } else { - /* if this is the root and there are more tunnel - * packets, don't add this. It's still referenced - * by the tunnel packets, and we will enqueue it - * when we handle them */ - p->tunnel_verdicted = 1; - mutex_unlock(m); - return; - } - } else { - if (p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1) { - /* the root is ready and we are the last tunnel packet, - * lets enqueue them both. */ - TUNNEL_DECR_PKT_TPR_NOLOCK(p); - - /* handle the root */ - PacketEnqueue(q,p->root); - - /* fall through */ - } else { - TUNNEL_DECR_PKT_TPR_NOLOCK(p); - /* fall through */ - } - } - mutex_unlock(m); - } - /* more packets in queue */ if (q->top != NULL) { p->next = q->top; diff --git a/src/source-nfq.c b/src/source-nfq.c index 47f32a9e34..d4879ad63f 100644 --- a/src/source-nfq.c +++ b/src/source-nfq.c @@ -337,19 +337,24 @@ int VerdictNFQ(ThreadVars *tv, Packet *p, void *data) { * already. */ if (IS_TUNNEL_PKT(p)) { char verdict = 1; + printf("VerdictNFQ: tunnel pkt: %p %s\n", p, p->root ? "upper layer" : "root"); pthread_mutex_t *m = p->root ? &p->root->mutex_rtv_cnt : &p->mutex_rtv_cnt; mutex_lock(m); /* if there are more tunnel packets than ready to verdict packets, * we won't verdict this one */ - if ((TUNNEL_PKT_TPR(p)+1) > TUNNEL_PKT_RTV(p)) { + if (TUNNEL_PKT_TPR(p) > TUNNEL_PKT_RTV(p)) { + printf("VerdictNFQ: not ready to verdict yet: TUNNEL_PKT_TPR(p) > TUNNEL_PKT_RTV(p) = %d > %d\n", TUNNEL_PKT_TPR(p), TUNNEL_PKT_RTV(p)); verdict = 0; } mutex_unlock(m); /* don't verdict if we are not ready */ if (verdict == 1) { - NFQSetVerdict(ntv, p); + printf("VerdictNFQ: setting verdict\n"); + NFQSetVerdict(ntv, p->root ? p->root : p); + } else { + TUNNEL_INCR_PKT_RTV(p); } } else { /* no tunnel, verdict normally */ diff --git a/src/threads.h b/src/threads.h index 6a99c19eeb..c238bda19f 100644 --- a/src/threads.h +++ b/src/threads.h @@ -5,6 +5,7 @@ #ifdef DBG_THREADS +#include int mutex_lock_dbg (pthread_mutex_t *); int mutex_trylock_dbg (pthread_mutex_t *); int mutex_unlock_dbg (pthread_mutex_t *); diff --git a/src/tmqh-packetpool.c b/src/tmqh-packetpool.c index 510404fb27..c112ca73e9 100644 --- a/src/tmqh-packetpool.c +++ b/src/tmqh-packetpool.c @@ -22,23 +22,74 @@ Packet *TmqhInputPacketpool(ThreadVars *t) Packet *p = SetupPkt(); mutex_lock(&mutex_pending); - if (pending > MAX_PENDING) + if (pending > MAX_PENDING) { pthread_cond_wait(&cond_pending, &mutex_pending); + } mutex_unlock(&mutex_pending); - return p; } void TmqhOutputPacketpool(ThreadVars *t, Packet *p) { PacketQueue *q = &packet_q; + char proot = 0; + + if (IS_TUNNEL_PKT(p)) { + printf("TmqhOutputPacketpool: tunnel packet: %p %s\n", p,p->root ? "upper layer":"root"); + + /* get a lock */ + pthread_mutex_t *m = p->root ? &p->root->mutex_rtv_cnt : &p->mutex_rtv_cnt; + mutex_lock(m); + + if (IS_TUNNEL_ROOT_PKT(p)) { + printf("TmqhOutputPacketpool: IS_TUNNEL_ROOT_PKT\n"); + if (TUNNEL_PKT_TPR(p) == 0) { + printf("TmqhOutputPacketpool: TUNNEL_PKT_TPR(p) == 0\n"); + /* if this packet is the root and there are no + * more tunnel packets, enqueue it */ + + /* fall through */ + } else { + printf("TmqhOutputPacketpool: TUNNEL_PKT_TPR(p) > 0\n"); + /* if this is the root and there are more tunnel + * packets, don't add this. It's still referenced + * by the tunnel packets, and we will enqueue it + * when we handle them */ + p->tunnel_verdicted = 1; + mutex_unlock(m); + return; + } + } else { + printf("TmqhOutputPacketpool: NOT IS_TUNNEL_ROOT_PKT\n"); + if (p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1) { + printf("TmqhOutputPacketpool: p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1\n"); + /* the root is ready and we are the last tunnel packet, + * lets enqueue them both. */ + TUNNEL_DECR_PKT_TPR_NOLOCK(p); + + /* handle the root */ + printf("TmqhOutputPacketpool: calling PacketEnqueue for root pkt\n"); + proot = 1; + + /* fall through */ + } else { + printf("TmqhOutputPacketpool: NOT p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1 (%u)\n", TUNNEL_PKT_TPR(p)); + TUNNEL_DECR_PKT_TPR_NOLOCK(p); + + /* fall through */ + } + } + mutex_unlock(m); + printf("TmqhOutputPacketpool: tunnel stuff done, move on\n"); + } mutex_lock(&q->mutex_q); + if (proot) PacketEnqueue(q, p->root); PacketEnqueue(q, p); mutex_unlock(&q->mutex_q); mutex_lock(&mutex_pending); - pending--; + if (pending) pending--; if (pending <= MAX_PENDING) pthread_cond_signal(&cond_pending); mutex_unlock(&mutex_pending); diff --git a/src/vips.c b/src/vips.c index df4b623992..e3c03c1100 100644 --- a/src/vips.c +++ b/src/vips.c @@ -85,13 +85,13 @@ Packet *SetupPkt (void) mutex_unlock(&packet_q.mutex_q); CLEAR_PACKET(p); - - //printf("p %p\n", p); return p; } Packet *TunnelPktSetup(ThreadVars *t, Packet *parent, u_int8_t *pkt, u_int16_t len, u_int8_t proto) { + printf("TunnelPktSetup: pkt %p, len %u, proto %u\n", pkt, len, proto); + /* get us a packet */ mutex_lock(&packet_q.mutex_q); Packet *p = PacketDequeue(&packet_q);