source-nfq: support queue range

If one needs to use multiple sequential Netfilter queues,
it can be done with a new '-q' option's syntax: "start:end"
(just like it's done with iptables '--queue-balance' option).
pull/3641/head
Alexander Gozman 6 years ago committed by Victor Julien
parent 93c956ebdf
commit bdd69d13e0

@ -816,25 +816,18 @@ TmEcode VerdictNFQThreadDeinit(ThreadVars *tv, void *data)
}
/**
* \brief Add a Netfilter queue
* \brief Add a single Netfilter queue
*
* \param string with the queue name
* \param string with the queue number
*
* \retval 0 on success.
* \retval -1 on failure.
*/
int NFQRegisterQueue(char *queue)
int NFQRegisterQueue(const uint16_t number)
{
NFQThreadVars *ntv = NULL;
NFQQueueVars *nq = NULL;
/* Extract the queue number from the specified command line argument */
uint16_t queue_num = 0;
if ((ByteExtractStringUint16(&queue_num, 10, strlen(queue), queue)) < 0)
{
SCLogError(SC_ERR_INVALID_ARGUMENT, "specified queue number %s is not "
"valid", queue);
return -1;
}
char queue[6] = { 0 };
SCMutexLock(&nfq_init_lock);
if (receive_queue_num >= NFQ_MAX_QUEUE) {
@ -853,16 +846,60 @@ int NFQRegisterQueue(char *queue)
ntv->nfq_index = receive_queue_num;
nq = &g_nfq_q[receive_queue_num];
nq->queue_num = queue_num;
nq->queue_num = number;
receive_queue_num++;
SCMutexUnlock(&nfq_init_lock);
snprintf(queue, sizeof(queue) - 1, "%hu", number);
LiveRegisterDeviceName(queue);
SCLogDebug("Queue \"%s\" registered.", queue);
SCLogDebug("Queue %d registered.", number);
return 0;
}
/**
* \brief Parses and adds Netfilter queue(s).
*
* \param string with the queue number or range
*
* \retval 0 on success.
* \retval -1 on failure.
*/
int NFQParseAndRegisterQueues(const char *queues)
{
uint16_t queue_start = 0;
uint16_t queue_end = 0;
// Either "id" or "start:end" format (e.g., "12" or "0:5")
int count = sscanf(queues, "%hu:%hu", &queue_start, &queue_end);
if (count < 1) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "specified queue(s) argument '%s' is not "
"valid (allowed queue numbers are 0-65535)", queues);
return -1;
}
// Do we have a range?
if (count == 2) {
// Sanity check
if (queue_start > queue_end) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "start queue's number %d is greater than "
"ending number %d", queue_start, queue_end);
return -1;
}
for (uint16_t i = queue_start; i <= queue_end; i++) {
if (NFQRegisterQueue(i) != 0) {
return -1;
}
}
} else if (NFQRegisterQueue(queue_start) != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "queue(s) argument '%s' is not "
"valid", queues);
return -1;
}
return 0;
}
/**
* \brief Get a pointer to the NFQ queue at index

@ -89,7 +89,8 @@ typedef struct NFQGlobalVars_
} NFQGlobalVars;
void NFQInitConfig(char quiet);
int NFQRegisterQueue(char *queue);
int NFQRegisterQueue(const uint16_t number);
int NFQParseAndRegisterQueues(const char *queues);
int NFQGetQueueCount(void);
void *NFQGetQueue(int number);
int NFQGetQueueNum(int number);

@ -582,7 +582,7 @@ static void PrintUsage(const char *progname)
printf("\t-F <bpf filter file> : bpf filter file\n");
printf("\t-r <path> : run in pcap file/offline mode\n");
#ifdef NFQ
printf("\t-q <qid> : run in inline nfqueue mode\n");
printf("\t-q <qid[:qid]> : run in inline nfqueue mode (use colon to specify a range of queues)\n");
#endif /* NFQ */
#ifdef IPFW
printf("\t-d <divert port> : run in inline ipfw divert mode\n");
@ -1974,10 +1974,10 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_NFQ;
EngineModeSetIPS();
if (NFQRegisterQueue(optarg) == -1)
if (NFQParseAndRegisterQueues(optarg) == -1)
return TM_ECODE_FAILED;
} else if (suri->run_mode == RUNMODE_NFQ) {
if (NFQRegisterQueue(optarg) == -1)
if (NFQParseAndRegisterQueues(optarg) == -1)
return TM_ECODE_FAILED;
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "

Loading…
Cancel
Save