Fix nfq lockup due to improper handling of PKT_PSEUDO_STREAM_END packets.

remotes/origin/master-1.1.x
Victor Julien 15 years ago
parent c9f9e3f9a4
commit d424ac7c61

@ -746,6 +746,11 @@ void ReceiveNFQThreadExitStats(ThreadVars *tv, void *data) {
* \brief NFQ verdict function * \brief NFQ verdict function
*/ */
void NFQSetVerdict(Packet *p) { void NFQSetVerdict(Packet *p) {
/* can't verdict a "fake" packet */
if (p->flags & PKT_PSEUDO_STREAM_END) {
return;
}
int ret = 0; int ret = 0;
uint32_t verdict = NF_ACCEPT; uint32_t verdict = NF_ACCEPT;
NFQQueueVars *t = nfq_q + p->nfq_v.nfq_index; NFQQueueVars *t = nfq_q + p->nfq_v.nfq_index;
@ -771,19 +776,24 @@ void NFQSetVerdict(Packet *p) {
verdict = ((uint32_t) NF_QUEUE) | nfq_config.next_queue; verdict = ((uint32_t) NF_QUEUE) | nfq_config.next_queue;
break; break;
} }
if (p->flags & PKT_STREAM_MODIFIED) {
#ifdef COUNTERS
t->replaced++;
#endif /* COUNTERS */
}
#ifdef COUNTERS #ifdef COUNTERS
t->accepted++; t->accepted++;
#endif /* COUNTERS */ #endif /* COUNTERS */
} }
switch (nfq_config.mode) { switch (nfq_config.mode) {
default:
case NFQ_ACCEPT_MODE: case NFQ_ACCEPT_MODE:
case NFQ_ROUTE_MODE: case NFQ_ROUTE_MODE:
if (p->flags & PKT_STREAM_MODIFIED) { if (p->flags & PKT_STREAM_MODIFIED) {
ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, GET_PKT_LEN(p), GET_PKT_DATA(p)); ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, GET_PKT_LEN(p), GET_PKT_DATA(p));
#ifdef COUNTERS
t->replaced++;
#endif /* COUNTERS */
} else { } else {
ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, 0, NULL); ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, 0, NULL);
} }
@ -794,9 +804,6 @@ void NFQSetVerdict(Packet *p) {
ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict, ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict,
(nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask), (nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask),
GET_PKT_LEN(p), GET_PKT_DATA(p)); GET_PKT_LEN(p), GET_PKT_DATA(p));
#ifdef COUNTERS
t->replaced++;
#endif /* COUNTERS */
} else { } else {
ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict, ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict,
(nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask), (nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask),
@ -807,15 +814,13 @@ void NFQSetVerdict(Packet *p) {
ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict, ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict,
htonl((nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask)), htonl((nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask)),
GET_PKT_LEN(p), GET_PKT_DATA(p)); GET_PKT_LEN(p), GET_PKT_DATA(p));
#ifdef COUNTERS
t->replaced++;
#endif /* COUNTERS */
} else { } else {
ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict, ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict,
htonl((nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask)), htonl((nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask)),
0, NULL); 0, NULL);
} }
#endif /* HAVE_NFQ_SET_VERDICT2 */ #endif /* HAVE_NFQ_SET_VERDICT2 */
break;
} }
SCMutexUnlock(&t->mutex_qh); SCMutexUnlock(&t->mutex_qh);
@ -828,11 +833,6 @@ void NFQSetVerdict(Packet *p) {
* \brief NFQ verdict module packet entry function * \brief NFQ verdict module packet entry function
*/ */
TmEcode VerdictNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { TmEcode VerdictNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) {
/* can't verdict a "fake" packet */
if (p->flags & PKT_PSEUDO_STREAM_END) {
SCReturnInt(TM_ECODE_OK);
}
/* if this is a tunnel packet we check if we are ready to verdict /* if this is a tunnel packet we check if we are ready to verdict
* already. */ * already. */
if (IS_TUNNEL_PKT(p)) { if (IS_TUNNEL_PKT(p)) {

Loading…
Cancel
Save