From 1154021c599257edf2c3dcb4d29f6b4dcb67643a Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 6 Sep 2011 13:47:43 +0200 Subject: src: add NFQNL_MSG_VERDICT_BATCH support add nfq_set_verdict_batch() and nfq_set_verdict_batch2 (to also set the nfmark of all packets). verdicts sent by the _batch variant will affect all queued skbs whose id is smaller or equal to the given id. This facility is available from Linux 3.1 onwards. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- src/libnetfilter_queue.c | 50 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/libnetfilter_queue.c b/src/libnetfilter_queue.c index 08c4039..358e9b1 100644 --- a/src/libnetfilter_queue.c +++ b/src/libnetfilter_queue.c @@ -632,7 +632,8 @@ int nfq_set_queue_maxlen(struct nfq_q_handle *qh, static int __set_verdict(struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict, u_int32_t mark, int set_mark, - u_int32_t data_len, const unsigned char *data) + u_int32_t data_len, const unsigned char *data, + enum nfqnl_msg_types type) { struct nfqnl_msg_verdict_hdr vh; union { @@ -655,7 +656,7 @@ static int __set_verdict(struct nfq_q_handle *qh, u_int32_t id, vh.id = htonl(id); nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id, - NFQNL_MSG_VERDICT, NLM_F_REQUEST); + type, NLM_F_REQUEST); /* add verdict header */ nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_VERDICT_HDR, &vh, sizeof(vh)); @@ -705,7 +706,8 @@ static int __set_verdict(struct nfq_q_handle *qh, u_int32_t id, * * Notifies netfilter of the userspace verdict for the given packet. Every * queued packet _must_ have a verdict specified by userspace, either by - * calling this function, or by calling the nfq_set_verdict2() function. + * calling this function, the nfq_set_verdict2() function, or the _batch + * versions of these functions. * * \return -1 on error; >= 0 otherwise. */ @@ -713,7 +715,8 @@ int nfq_set_verdict(struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict, u_int32_t data_len, const unsigned char *buf) { - return __set_verdict(qh, id, verdict, 0, 0, data_len, buf); + return __set_verdict(qh, id, verdict, 0, 0, data_len, buf, + NFQNL_MSG_VERDICT); } /** @@ -729,7 +732,41 @@ int nfq_set_verdict2(struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict, u_int32_t mark, u_int32_t data_len, const unsigned char *buf) { - return __set_verdict(qh, id, verdict, htonl(mark), 1, data_len, buf); + return __set_verdict(qh, id, verdict, htonl(mark), 1, data_len, + buf, NFQNL_MSG_VERDICT); +} + +/** + * nfq_set_verdict_batch - issue verdicts on several packets at once + * \param qh Netfilter queue handle obtained by call to nfq_create_queue(). + * \param id maximum ID of the packets that the verdict should be applied to. + * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP) + * + * Unlike nfq_set_verdict, the verdict is applied to all queued packets + * whose packet id is smaller or equal to #id. + * + * batch support was added in Linux 3.1. + * These functions will fail silently on older kernels. + */ +int nfq_set_verdict_batch(struct nfq_q_handle *qh, u_int32_t id, + u_int32_t verdict) +{ + return __set_verdict(qh, id, verdict, 0, 0, 0, NULL, + NFQNL_MSG_VERDICT_BATCH); +} + +/** + * nfq_set_verdict_batch2 - like nfq_set_verdict_batch, but you can set a mark. + * \param qh Netfilter queue handle obtained by call to nfq_create_queue(). + * \param id maximum ID of the packets that the verdict should be applied to. + * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP) + * \param mark mark to put on packet + */ +int nfq_set_verdict_batch2(struct nfq_q_handle *qh, u_int32_t id, + u_int32_t verdict, u_int32_t mark) +{ + return __set_verdict(qh, id, verdict, htonl(mark), 1, 0, + NULL, NFQNL_MSG_VERDICT_BATCH); } /** @@ -750,7 +787,8 @@ int nfq_set_verdict_mark(struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict, u_int32_t mark, u_int32_t data_len, const unsigned char *buf) { - return __set_verdict(qh, id, verdict, mark, 1, data_len, buf); + return __set_verdict(qh, id, verdict, mark, 1, data_len, buf, + NFQNL_MSG_VERDICT); } /** -- cgit v1.2.3