nfq: introduce bypass function

pull/2302/head
Giuseppe Longo 9 years ago committed by Victor Julien
parent 285b4dd981
commit 97783f8142

@ -132,7 +132,6 @@ typedef struct NFQThreadVars_
int datalen; /** Length of per function and thread data */ int datalen; /** Length of per function and thread data */
CaptureStats stats; CaptureStats stats;
} NFQThreadVars; } NFQThreadVars;
/* shared vars for all for nfq queues and threads */ /* shared vars for all for nfq queues and threads */
static NFQGlobalVars nfq_g; static NFQGlobalVars nfq_g;
@ -169,6 +168,8 @@ typedef struct NFQCnf_ {
NFQMode mode; NFQMode mode;
uint32_t mark; uint32_t mark;
uint32_t mask; uint32_t mask;
uint32_t bypass_mark;
uint32_t bypass_mask;
uint32_t next_queue; uint32_t next_queue;
uint32_t flags; uint32_t flags;
uint8_t batchcount; uint8_t batchcount;
@ -263,6 +264,14 @@ void NFQInitConfig(char quiet)
nfq_config.mask = (uint32_t)value; nfq_config.mask = (uint32_t)value;
} }
if ((ConfGetInt("nfq.bypass-mark", &value)) == 1) {
nfq_config.bypass_mark = (uint32_t)value;
}
if ((ConfGetInt("nfq.bypass-mask", &value)) == 1) {
nfq_config.bypass_mask = (uint32_t)value;
}
if ((ConfGetInt("nfq.route-queue", &value)) == 1) { if ((ConfGetInt("nfq.route-queue", &value)) == 1) {
nfq_config.next_queue = ((uint32_t)value) << 16; nfq_config.next_queue = ((uint32_t)value) << 16;
} }
@ -492,6 +501,26 @@ static void NFQReleasePacket(Packet *p)
PacketFreeOrRelease(p); PacketFreeOrRelease(p);
} }
static int NFQBypassCallback(Packet *p)
{
if (IS_TUNNEL_PKT(p)) {
SCMutex *m = p->root ? &p->root->tunnel_mutex : &p->tunnel_mutex;
SCMutexLock(m);
p->root->nfq_v.mark = (nfq_config.bypass_mark & nfq_config.bypass_mask)
| (p->nfq_v.mark & ~nfq_config.bypass_mask);
p->root->flags |= PKT_MARK_MODIFIED;
SCMutexUnlock(m);
} else {
p->nfq_v.mark = (nfq_config.bypass_mark & nfq_config.bypass_mask)
| (p->nfq_v.mark & ~nfq_config.bypass_mask);
p->flags |= PKT_MARK_MODIFIED;
}
return 1;
}
static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
struct nfq_data *nfa, void *data) struct nfq_data *nfa, void *data)
{ {
@ -507,6 +536,10 @@ static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
PKT_SET_SRC(p, PKT_SRC_WIRE); PKT_SET_SRC(p, PKT_SRC_WIRE);
p->nfq_v.nfq_index = ntv->nfq_index; p->nfq_v.nfq_index = ntv->nfq_index;
/* if bypass mask is set then we may want to bypass so set pointer */
if (nfq_config.bypass_mask) {
p->BypassPacketsFlow = NFQBypassCallback;
}
ret = NFQSetupPkt(p, qh, (void *)nfa); ret = NFQSetupPkt(p, qh, (void *)nfa);
if (ret == -1) { if (ret == -1) {
#ifdef COUNTERS #ifdef COUNTERS

@ -1417,10 +1417,16 @@ profiling:
# by processing several packets before sending a verdict (worker runmode only). # by processing several packets before sending a verdict (worker runmode only).
# On linux >= 3.6, you can set the fail-open option to yes to have the kernel # On linux >= 3.6, you can set the fail-open option to yes to have the kernel
# accept the packet if suricata is not able to keep pace. # accept the packet if suricata is not able to keep pace.
# bypass mark and mask can be used to implement NFQ bypass. If bypass mark is
# set then the NFQ bypass is activated. Suricata will set the bypass mark/mask
# on packet of a flow that need to be bypassed. The Nefilter ruleset has to
# directly accept all packets of a flow once a packet has been marked.
nfq: nfq:
# mode: accept # mode: accept
# repeat-mark: 1 # repeat-mark: 1
# repeat-mask: 1 # repeat-mask: 1
# bypass-mark: 1
# bypass-mask: 1
# route-queue: 2 # route-queue: 2
# batchcount: 20 # batchcount: 20
# fail-open: yes # fail-open: yes

Loading…
Cancel
Save