aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/nfnetlink_log.h6
-rw-r--r--net/netfilter/nfnetlink_log.c46
2 files changed, 52 insertions, 0 deletions
diff --git a/include/linux/netfilter/nfnetlink_log.h b/include/linux/netfilter/nfnetlink_log.h
index b04b03880595..a7497c7436df 100644
--- a/include/linux/netfilter/nfnetlink_log.h
+++ b/include/linux/netfilter/nfnetlink_log.h
@@ -47,6 +47,8 @@ enum nfulnl_attr_type {
47 NFULA_PAYLOAD, /* opaque data payload */ 47 NFULA_PAYLOAD, /* opaque data payload */
48 NFULA_PREFIX, /* string prefix */ 48 NFULA_PREFIX, /* string prefix */
49 NFULA_UID, /* user id of socket */ 49 NFULA_UID, /* user id of socket */
50 NFULA_SEQ, /* instance-local sequence number */
51 NFULA_SEQ_GLOBAL, /* global sequence number */
50 52
51 __NFULA_MAX 53 __NFULA_MAX
52}; 54};
@@ -77,6 +79,7 @@ enum nfulnl_attr_config {
77 NFULA_CFG_NLBUFSIZ, /* u_int32_t buffer size */ 79 NFULA_CFG_NLBUFSIZ, /* u_int32_t buffer size */
78 NFULA_CFG_TIMEOUT, /* u_int32_t in 1/100 s */ 80 NFULA_CFG_TIMEOUT, /* u_int32_t in 1/100 s */
79 NFULA_CFG_QTHRESH, /* u_int32_t */ 81 NFULA_CFG_QTHRESH, /* u_int32_t */
82 NFULA_CFG_FLAGS, /* u_int16_t */
80 __NFULA_CFG_MAX 83 __NFULA_CFG_MAX
81}; 84};
82#define NFULA_CFG_MAX (__NFULA_CFG_MAX -1) 85#define NFULA_CFG_MAX (__NFULA_CFG_MAX -1)
@@ -85,4 +88,7 @@ enum nfulnl_attr_config {
85#define NFULNL_COPY_META 0x01 88#define NFULNL_COPY_META 0x01
86#define NFULNL_COPY_PACKET 0x02 89#define NFULNL_COPY_PACKET 0x02
87 90
91#define NFULNL_CFG_F_SEQ 0x0001
92#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
93
88#endif /* _NFNETLINK_LOG_H */ 94#endif /* _NFNETLINK_LOG_H */
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;