|
|
|
/* Copyright (C) 2007-2010 Open Information Security Foundation
|
|
|
|
*
|
|
|
|
* You can copy, redistribute or modify this Program under the terms of
|
|
|
|
* the GNU General Public License version 2 as published by the Free
|
|
|
|
* Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* version 2 along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
* 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \file
|
|
|
|
*
|
|
|
|
* \author Victor Julien <victor@inliniac.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __SOURCE_NFQ_H__
|
|
|
|
#define __SOURCE_NFQ_H__
|
|
|
|
|
|
|
|
#ifdef NFQ
|
|
|
|
|
|
|
|
#include "threads.h"
|
|
|
|
#include <linux/netfilter.h> /* for NF_ACCEPT */
|
|
|
|
#include <libnetfilter_queue/libnetfilter_queue.h>
|
|
|
|
|
|
|
|
// Netfilter's limit
|
|
|
|
#define NFQ_MAX_QUEUE 65535
|
|
|
|
|
|
|
|
/* idea: set the recv-thread id in the packet to
|
|
|
|
* select an verdict-queue */
|
|
|
|
|
|
|
|
typedef struct NFQPacketVars_
|
|
|
|
{
|
|
|
|
int id; /* this nfq packets id */
|
|
|
|
uint16_t nfq_index; /* index in NFQ array */
|
|
|
|
uint8_t verdicted;
|
|
|
|
|
|
|
|
uint32_t mark;
|
|
|
|
uint32_t ifi;
|
|
|
|
uint32_t ifo;
|
|
|
|
uint16_t hw_protocol;
|
|
|
|
} NFQPacketVars;
|
|
|
|
|
|
|
|
typedef struct NFQQueueVars_
|
|
|
|
{
|
|
|
|
struct nfq_handle *h;
|
|
|
|
struct nfnl_handle *nh;
|
|
|
|
int fd;
|
|
|
|
uint8_t use_mutex;
|
|
|
|
/* 2 threads deal with the queue handle, so add a mutex */
|
|
|
|
struct nfq_q_handle *qh;
|
|
|
|
SCMutex mutex_qh;
|
|
|
|
/* this one should be not changing after init */
|
|
|
|
uint16_t queue_num;
|
|
|
|
/* position into the NFQ queue var array */
|
|
|
|
uint16_t nfq_index;
|
|
|
|
|
|
|
|
#ifdef DBG_PERF
|
|
|
|
int dbg_maxreadsize;
|
|
|
|
#endif /* DBG_PERF */
|
|
|
|
|
|
|
|
/* counters */
|
|
|
|
uint32_t pkts;
|
|
|
|
uint64_t bytes;
|
|
|
|
uint32_t errs;
|
|
|
|
uint32_t accepted;
|
|
|
|
uint32_t dropped;
|
|
|
|
uint32_t replaced;
|
nfq: add support for batch verdicts
Normally, there is one verdict per packet, i.e., we receive a packet,
process it, and then tell the kernel what to do with that packet (eg.
DROP or ACCEPT).
recv(), packet id x
send verdict v, packet id x
recv(), packet id x+1
send verdict v, packet id x+1
[..]
recv(), packet id x+n
send verdict v, packet id x+n
An alternative is to process several packets from the queue, and then send
a batch-verdict.
recv(), packet id x
recv(), packet id x+1
[..]
recv(), packet id x+n
send batch verdict v, packet id x+n
A batch verdict affects all previous packets (packet_id <= x+n),
we thus only need to remember the last packet_id seen.
Caveats:
- can't modify payload
- verdict is applied to all packets
- nfmark (if set) will be set for all packets
- increases latency (packets remain queued by the kernel
until batch verdict is sent).
To solve this, we only defer verdict for up to 20 packets and
send pending batch-verdict immediately if:
- no packets are currently queue
- current packet should be dropped
- current packet has different nfmark
- payload of packet was modified
This patch adds a configurable batch verdict support for workers runmode.
The batch verdicts are turned off by default.
Problem is that batch verdicts only work with kernels >= 3.1, i.e.
using newer libnetfilter_queue with an old kernel means non-working
suricata. So the functionnality has to be disabled by default.
12 years ago
|
|
|
struct {
|
|
|
|
uint32_t packet_id; /* id of last processed packet */
|
|
|
|
uint32_t verdict;
|
|
|
|
uint32_t mark;
|
|
|
|
uint8_t mark_valid:1;
|
|
|
|
uint8_t len;
|
|
|
|
uint8_t maxlen;
|
|
|
|
} verdict_cache;
|
|
|
|
|
|
|
|
} NFQQueueVars;
|
|
|
|
|
|
|
|
typedef struct NFQGlobalVars_
|
|
|
|
{
|
|
|
|
char unbind;
|
|
|
|
} NFQGlobalVars;
|
|
|
|
|
|
|
|
void NFQInitConfig(char quiet);
|
|
|
|
int NFQRegisterQueue(const uint16_t number);
|
|
|
|
int NFQParseAndRegisterQueues(const char *queues);
|
|
|
|
int NFQGetQueueCount(void);
|
|
|
|
void *NFQGetQueue(int number);
|
|
|
|
int NFQGetQueueNum(int number);
|
|
|
|
void *NFQGetThread(int number);
|
|
|
|
void NFQContextsClean(void);
|
|
|
|
#endif /* NFQ */
|
|
|
|
#endif /* __SOURCE_NFQ_H__ */
|
|
|
|
|