nfq: Add iterator on nfq_set_verdict

This patch adds retry to nfq_set_verdict in case of error.
remotes/origin/master-1.1.x
Eric Leblond 14 years ago committed by Victor Julien
parent a8b21066df
commit 2ffcef0a8e

@ -98,6 +98,7 @@ TmEcode NoNFQSupportExit(ThreadVars *tv, void *initdata, void **data)
extern int max_pending_packets; extern int max_pending_packets;
#define MAX_ALREADY_TREATED 5 #define MAX_ALREADY_TREATED 5
#define NFQ_VERDICT_RETRY_TIME 3
int already_seen_warning; int already_seen_warning;
#define NFQ_BURST_FACTOR 4 #define NFQ_BURST_FACTOR 4
@ -251,10 +252,18 @@ int NFQSetupPkt (Packet *p, struct nfq_q_handle *qh, void *data)
if (nfq_config.mode == NFQ_REPEAT_MODE) { if (nfq_config.mode == NFQ_REPEAT_MODE) {
if ((nfq_config.mark & nfq_config.mask) == if ((nfq_config.mark & nfq_config.mask) ==
(p->nfq_v.mark & nfq_config.mask)) { (p->nfq_v.mark & nfq_config.mask)) {
int iter = 0;
if (already_seen_warning < MAX_ALREADY_TREATED) if (already_seen_warning < MAX_ALREADY_TREATED)
SCLogInfo("Packet seems already treated by suricata"); SCLogInfo("Packet seems already treated by suricata");
already_seen_warning++; already_seen_warning++;
ret = nfq_set_verdict(qh, p->nfq_v.id, NF_ACCEPT, 0, NULL); do {
ret = nfq_set_verdict(qh, p->nfq_v.id, NF_ACCEPT, 0, NULL);
} while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME));
if (ret < 0) {
SCLogWarning(SC_ERR_NFQ_SET_VERDICT,
"nfq_set_verdict of %p failed %" PRId32 "",
p, ret);
}
return -1 ; return -1 ;
} }
} }
@ -773,15 +782,16 @@ void ReceiveNFQThreadExitStats(ThreadVars *tv, void *data) {
* \brief NFQ verdict function * \brief NFQ verdict function
*/ */
void NFQSetVerdict(Packet *p) { void NFQSetVerdict(Packet *p) {
int iter = 0;
int ret = 0;
uint32_t verdict = NF_ACCEPT;
NFQQueueVars *t = nfq_q + p->nfq_v.nfq_index;
/* can't verdict a "fake" packet */ /* can't verdict a "fake" packet */
if (p->flags & PKT_PSEUDO_STREAM_END) { if (p->flags & PKT_PSEUDO_STREAM_END) {
return; return;
} }
int ret = 0;
uint32_t verdict = NF_ACCEPT;
NFQQueueVars *t = nfq_q + p->nfq_v.nfq_index;
//printf("%p verdicting on queue %" PRIu32 "\n", t, t->queue_num); //printf("%p verdicting on queue %" PRIu32 "\n", t, t->queue_num);
SCMutexLock(&t->mutex_qh); SCMutexLock(&t->mutex_qh);
@ -815,66 +825,69 @@ void NFQSetVerdict(Packet *p) {
#endif /* COUNTERS */ #endif /* COUNTERS */
} }
switch (nfq_config.mode) { do {
default: switch (nfq_config.mode) {
case NFQ_ACCEPT_MODE: default:
case NFQ_ROUTE_MODE: case NFQ_ACCEPT_MODE:
if (p->flags & PKT_MARK_MODIFIED) { case NFQ_ROUTE_MODE:
if (p->flags & PKT_MARK_MODIFIED) {
#ifdef HAVE_NFQ_SET_VERDICT2
if (p->flags & PKT_STREAM_MODIFIED) {
ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict,
p->nfq_v.mark,
GET_PKT_LEN(p), GET_PKT_DATA(p));
} else {
ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict,
p->nfq_v.mark,
0, NULL);
}
#else /* fall back to old function */
if (p->flags & PKT_STREAM_MODIFIED) {
ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict,
htonl(p->nfq_v.mark),
GET_PKT_LEN(p), GET_PKT_DATA(p));
} else {
ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict,
htonl(p->nfq_v.mark),
0, NULL);
}
#endif /* HAVE_NFQ_SET_VERDICT2 */
} else {
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));
} else {
ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, 0, NULL);
}
}
break;
case NFQ_REPEAT_MODE:
#ifdef HAVE_NFQ_SET_VERDICT2 #ifdef HAVE_NFQ_SET_VERDICT2
if (p->flags & PKT_STREAM_MODIFIED) { if (p->flags & PKT_STREAM_MODIFIED) {
ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict, ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict,
p->nfq_v.mark, (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));
} else { } else {
ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict, ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict,
p->nfq_v.mark, (nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask),
0, NULL); 0, NULL);
} }
#else /* fall back to old function */ #else /* fall back to old function */
if (p->flags & PKT_STREAM_MODIFIED) { if (p->flags & PKT_STREAM_MODIFIED) {
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(p->nfq_v.mark), 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));
} 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(p->nfq_v.mark), 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 */
} else { break;
if (p->flags & PKT_STREAM_MODIFIED) { }
ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, } while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME));
GET_PKT_LEN(p), GET_PKT_DATA(p));
} else {
ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, 0, NULL);
}
}
break;
case NFQ_REPEAT_MODE:
#ifdef HAVE_NFQ_SET_VERDICT2
if (p->flags & PKT_STREAM_MODIFIED) {
ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict,
(nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask),
GET_PKT_LEN(p), GET_PKT_DATA(p));
} else {
ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict,
(nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask),
0, NULL);
}
#else /* fall back to old function */
if (p->flags & PKT_STREAM_MODIFIED) {
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)),
GET_PKT_LEN(p), GET_PKT_DATA(p));
} else {
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)),
0, NULL);
}
#endif /* HAVE_NFQ_SET_VERDICT2 */
break;
}
SCMutexUnlock(&t->mutex_qh); SCMutexUnlock(&t->mutex_qh);
if (ret < 0) { if (ret < 0) {

Loading…
Cancel
Save