aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2006-03-20 20:15:11 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 20:15:11 -0500
commit0af5f6c1eba4a18e6b2ed518b589927d778c6c16 (patch)
treeea905a47e7ce2dc2d5076076edc0bf641cf3691c /net
parent5ee956125a780baf15f2c1d09f2cbf8adcf598fe (diff)
[NETFILTER] nfnetlink_log: add sequence numbers for log events
By using a sequence number for every logged netfilter event, we can determine from userspace whether logging information was lots somewhere downstream. The user has a choice of either having per-instance local sequence counters, or using a global sequence counter, or both. Signed-off-by: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nfnetlink_log.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 3b3c781b40c0..54cbbaa712dc 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -11,6 +11,10 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 * 13 *
14 * 2006-01-26 Harald Welte <laforge@netfilter.org>
15 * - Add optional local and global sequence number to detect lost
16 * events from userspace
17 *
14 */ 18 */
15#include <linux/module.h> 19#include <linux/module.h>
16#include <linux/skbuff.h> 20#include <linux/skbuff.h>
@@ -68,11 +72,14 @@ struct nfulnl_instance {
68 unsigned int nlbufsiz; /* netlink buffer allocation size */ 72 unsigned int nlbufsiz; /* netlink buffer allocation size */
69 unsigned int qthreshold; /* threshold of the queue */ 73 unsigned int qthreshold; /* threshold of the queue */
70 u_int32_t copy_range; 74 u_int32_t copy_range;
75 u_int32_t seq; /* instance-local sequential counter */
71 u_int16_t group_num; /* number of this queue */ 76 u_int16_t group_num; /* number of this queue */
77 u_int16_t flags;
72 u_int8_t copy_mode; 78 u_int8_t copy_mode;
73}; 79};
74 80
75static DEFINE_RWLOCK(instances_lock); 81static DEFINE_RWLOCK(instances_lock);
82static atomic_t global_seq;
76 83
77#define INSTANCE_BUCKETS 16 84#define INSTANCE_BUCKETS 16
78static struct hlist_head instance_table[INSTANCE_BUCKETS]; 85static struct hlist_head instance_table[INSTANCE_BUCKETS];
@@ -310,6 +317,16 @@ nfulnl_set_qthresh(struct nfulnl_instance *inst, u_int32_t qthresh)
310 return 0; 317 return 0;
311} 318}
312 319
320static int
321nfulnl_set_flags(struct nfulnl_instance *inst, u_int16_t flags)
322{
323 spin_lock_bh(&inst->lock);
324 inst->flags = ntohs(flags);
325 spin_unlock_bh(&inst->lock);
326
327 return 0;
328}
329
313static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size, 330static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size,
314 unsigned int pkt_size) 331 unsigned int pkt_size)
315{ 332{
@@ -377,6 +394,8 @@ static void nfulnl_timer(unsigned long data)
377 spin_unlock_bh(&inst->lock); 394 spin_unlock_bh(&inst->lock);
378} 395}
379 396
397/* This is an inline function, we don't really care about a long
398 * list of arguments */
380static inline int 399static inline int
381__build_packet_message(struct nfulnl_instance *inst, 400__build_packet_message(struct nfulnl_instance *inst,
382 const struct sk_buff *skb, 401 const struct sk_buff *skb,
@@ -515,6 +534,17 @@ __build_packet_message(struct nfulnl_instance *inst,
515 read_unlock_bh(&skb->sk->sk_callback_lock); 534 read_unlock_bh(&skb->sk->sk_callback_lock);
516 } 535 }
517 536
537 /* local sequence number */
538 if (inst->flags & NFULNL_CFG_F_SEQ) {
539 tmp_uint = htonl(inst->seq++);
540 NFA_PUT(inst->skb, NFULA_SEQ, sizeof(tmp_uint), &tmp_uint);
541 }
542 /* global sequence number */
543 if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) {
544 tmp_uint = atomic_inc_return(&global_seq);
545 NFA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint);
546 }
547
518 if (data_len) { 548 if (data_len) {
519 struct nfattr *nfa; 549 struct nfattr *nfa;
520 int size = NFA_LENGTH(data_len); 550 int size = NFA_LENGTH(data_len);
@@ -607,6 +637,11 @@ nfulnl_log_packet(unsigned int pf,
607 637
608 spin_lock_bh(&inst->lock); 638 spin_lock_bh(&inst->lock);
609 639
640 if (inst->flags & NFULNL_CFG_F_SEQ)
641 size += NFA_SPACE(sizeof(u_int32_t));
642 if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
643 size += NFA_SPACE(sizeof(u_int32_t));
644
610 qthreshold = inst->qthreshold; 645 qthreshold = inst->qthreshold;
611 /* per-rule qthreshold overrides per-instance */ 646 /* per-rule qthreshold overrides per-instance */
612 if (qthreshold > li->u.ulog.qthreshold) 647 if (qthreshold > li->u.ulog.qthreshold)
@@ -736,10 +771,14 @@ static const int nfula_min[NFULA_MAX] = {
736 [NFULA_TIMESTAMP-1] = sizeof(struct nfulnl_msg_packet_timestamp), 771 [NFULA_TIMESTAMP-1] = sizeof(struct nfulnl_msg_packet_timestamp),
737 [NFULA_IFINDEX_INDEV-1] = sizeof(u_int32_t), 772 [NFULA_IFINDEX_INDEV-1] = sizeof(u_int32_t),
738 [NFULA_IFINDEX_OUTDEV-1]= sizeof(u_int32_t), 773 [NFULA_IFINDEX_OUTDEV-1]= sizeof(u_int32_t),
774 [NFULA_IFINDEX_PHYSINDEV-1] = sizeof(u_int32_t),
775 [NFULA_IFINDEX_PHYSOUTDEV-1] = sizeof(u_int32_t),
739 [NFULA_HWADDR-1] = sizeof(struct nfulnl_msg_packet_hw), 776 [NFULA_HWADDR-1] = sizeof(struct nfulnl_msg_packet_hw),
740 [NFULA_PAYLOAD-1] = 0, 777 [NFULA_PAYLOAD-1] = 0,
741 [NFULA_PREFIX-1] = 0, 778 [NFULA_PREFIX-1] = 0,
742 [NFULA_UID-1] = sizeof(u_int32_t), 779 [NFULA_UID-1] = sizeof(u_int32_t),
780 [NFULA_SEQ-1] = sizeof(u_int32_t),
781 [NFULA_SEQ_GLOBAL-1] = sizeof(u_int32_t),
743}; 782};
744 783
745static const int nfula_cfg_min[NFULA_CFG_MAX] = { 784static const int nfula_cfg_min[NFULA_CFG_MAX] = {
@@ -748,6 +787,7 @@ static const int nfula_cfg_min[NFULA_CFG_MAX] = {
748 [NFULA_CFG_TIMEOUT-1] = sizeof(u_int32_t), 787 [NFULA_CFG_TIMEOUT-1] = sizeof(u_int32_t),
749 [NFULA_CFG_QTHRESH-1] = sizeof(u_int32_t), 788 [NFULA_CFG_QTHRESH-1] = sizeof(u_int32_t),
750 [NFULA_CFG_NLBUFSIZ-1] = sizeof(u_int32_t), 789 [NFULA_CFG_NLBUFSIZ-1] = sizeof(u_int32_t),
790 [NFULA_CFG_FLAGS-1] = sizeof(u_int16_t),
751}; 791};
752 792
753static int 793static int
@@ -859,6 +899,12 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
859 nfulnl_set_qthresh(inst, ntohl(qthresh)); 899 nfulnl_set_qthresh(inst, ntohl(qthresh));
860 } 900 }
861 901
902 if (nfula[NFULA_CFG_FLAGS-1]) {
903 u_int16_t flags =
904 *(u_int16_t *)NFA_DATA(nfula[NFULA_CFG_FLAGS-1]);
905 nfulnl_set_flags(inst, ntohl(flags));
906 }
907
862out_put: 908out_put:
863 instance_put(inst); 909 instance_put(inst);
864 return ret; 910 return ret;