Skip to contentSkip to conversation

nfnetlink updates

PATCH In review Pablo Neira 3 participants 3 messages Jul 12, 2005 – Jul 17, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nfnetlink updates

Hi,

This patch introduces the following changes to nfnetlink:

a) nfnetlink groups: Up to 32 maximum.

+#define NF_NETLINK_CONNTRACK_NEW       0x1
+#define NF_NETLINK_CONNTRACK_UPDATE    0x2
+#define NF_NETLINK_CONNTRACK_DESTROY   0x4
+#define NF_NETLINK_CONNTRACK_EXPECT    0x8

I think that those four groups are enough to group events.

b) NFA_NEST and NFA_NEST_END. As it was discussed, it's time to move this netlink stuff to a generic file, otherwise we could use RTA_* instead since all this NFA_* stuff is a copy and paste from the original RTA_*. Anyway

c) We don't need this, that is defined in netlink.h.

-#ifndef NETLINK_NETFILTER
-#define NETLINK_NETFILTER 10
-#endif

d) NFNL_SUBSYS_CTNETLINK_EXP has been killed. This is superseded by the group NF_NETLINK_CONNTRACK_EXPECT.

e) nfnetlink_subsystem internal list isn't used, the array is enough.

f) Fixed nfnl_shunlock.

g) nfnetlink_subsys_alloc isn't useful anymore. Now we store the nfnetlink_subsystem in the BSS section. Please see ip_conntrack_netlink.c for an example.

h) nfnetlink_check_attributes is called from nfnetlink, so we pass the attributes parsed to as parameter to the callback.

See for more info: http://patchwork.netfilter.org/netfilter-devel/patch.pl?id=2671

i) Killed redundant check for unknown message.

include/linux/netfilter/nfnetlink.h +38 -24
Index: linux-2.6/include/linux/netfilter/nfnetlink.h
===================================================================
@@ -2,6 +2,12 @@
 #define _NFNETLINK_H
 #include <linux/types.h>
 
+/* nfnetlink groups: Up to 32 maximum */
+#define NF_NETLINK_CONNTRACK_NEW 	0x1
+#define NF_NETLINK_CONNTRACK_UPDATE	0x2
+#define NF_NETLINK_CONNTRACK_DESTROY	0x4
+#define NF_NETLINK_CONNTRACK_EXPECT	0x8
+
 /* Generic structure for encapsulation optional netfilter information.
  * It is reminiscent of sockaddr, but with sa_family replaced
  * with attribute type. 
@@ -15,6 +21,9 @@
 	unsigned short  nfa_type;
 };
 
+/* FIXME: Shamelessly copy and pasted from rtnetlink.h, it's time
+ * 	  to put this in a generic file */
+
 #define NFA_ALIGNTO     4
 #define NFA_ALIGN(len)	(((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1))
 #define NFA_OK(nfa,len)	((len) > 0 && (nfa)->nfa_len >= sizeof(struct nfattr) \
@@ -25,6 +34,17 @@
 #define NFA_SPACE(len)	NFA_ALIGN(NFA_LENGTH(len))
 #define NFA_DATA(nfa)   ((void *)(((char *)(nfa)) + NFA_LENGTH(0)))
 #define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0))
+#define NFA_NEST(skb, type) \
+({	struct nfattr *__start = (struct nfattr *) (skb)->tail; \
+	NFA_PUT(skb, type, 0, NULL); \
+	__start;  })
+#define NFA_NEST_END(skb, start) \
+({      (start)->nfa_len = ((skb)->tail - (unsigned char *) (start)); \
+        (skb)->len; })
+#define NFA_NEST_CANCEL(skb, start) \
+({      if (start) \
+                skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
+        -1; })
 
 /* General form of address family dependent message.
  */
@@ -36,11 +56,6 @@
         + NLMSG_ALIGN(sizeof(struct nfgenmsg))))
 #define NFM_PAYLOAD(n)  NLMSG_PAYLOAD(n, sizeof(struct nfgenmsg))
 
-
-#ifndef NETLINK_NETFILTER
-#define NETLINK_NETFILTER	10
-#endif
-
 /* netfilter netlink message types are split in two pieces:
  * 8 bit subsystem, 8bit operation.
  */
@@ -51,7 +66,6 @@
 enum nfnl_subsys_id {
 	NFNL_SUBSYS_NONE = 0,
 	NFNL_SUBSYS_CTNETLINK,
-	NFNL_SUBSYS_CTNETLINK_EXP,
 	NFNL_SUBSYS_IPTNETLINK,
 	NFNL_SUBSYS_QUEUE,
 	NFNL_SUBSYS_ULOG,
@@ -66,19 +80,16 @@
 {
 	kernel_cap_t cap_required; /* capabilities required for this msg */
 	int (*call)(struct sock *nl, struct sk_buff *skb, 
-		struct nlmsghdr *nlh, int *errp);
+		struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
 };
 
 struct nfnetlink_subsystem
 {
-	/* Internal use. */
-	struct list_head list;
-	
 	const char *name;
 	__u8 subsys_id;		/* nfnetlink subsystem ID */
 	__u8 cb_count;		/* number of callbacks */
 	u_int32_t attr_count;	/* number of nfattr's */
-	struct nfnl_callback cb[0]; /* callback for individual types */
+	struct nfnl_callback *cb; /* callback for individual types */
 };
 
 extern void __nfa_fill(struct sk_buff *skb, int attrtype,
@@ -88,34 +99,37 @@
    __nfa_fill(skb, attrtype, attrlen, data); })
 
 extern struct semaphore nfnl_sem;
-#define nfnl_exlock()		do { } while(0)
-#define nfnl_exunlock()		do { } while(0)
-#define nfnl_exlock_nowait()	(0)
 
 #define nfnl_shlock()		down(&nfnl_sem)
 #define nfnl_shlock_nowait()	down_trylock(&nfnl_sem)
 
-#ifndef CONFIG_NF_NETLINK
-#define nfnl_shunlock()		up(&nfnl_sem)
-#else
 #define nfnl_shunlock()		do { up(&nfnl_sem); \
-                             		if(nfnl && nfnl->receive_queue.qlen) \
-                                     		nfnl->data_ready(nfnl, 0); \
+				     if(nfnl && nfnl->sk_receive_queue.qlen) \
+					    nfnl->sk_data_ready(nfnl, 0); \
                         	} while(0)
-#endif
 
 extern void nfnl_lock(void);
 extern void nfnl_unlock(void);
 
-extern struct nfnetlink_subsystem *nfnetlink_subsys_alloc(int cb_count);
 extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
 extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
 
-extern int nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
-				      struct nlmsghdr *nlh, 
-				      struct nfattr *cda[]);
 extern int nfattr_parse(struct nfattr *tb[], int maxattr, 
 			struct nfattr *nfa, int len);
+
+#define nfattr_parse_nested(tb, max, nfa) \
+	nfattr_parse((tb), (max), NFA_DATA((nfa)), NFA_PAYLOAD((nfa)))
+
+#define nfattr_bad_size(tb, max, cta_min)				\
+({	int __i, __res = 0;						\
+ 	for (__i=0; __i<max; __i++) 					\
+ 		if (tb[__i] && NFA_PAYLOAD(tb[__i]) < cta_min[__i]){	\
+ 			__res = 1;					\
+ 			break;						\
+ 		}							\
+ 	__res;								\
+})
+
 extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, 
 			  int echo);
 
net/netfilter/nfnetlink.c +35 -48

194 lines not on this page · raw message

#1 lore raw
Quoted 11 lines · Pablo Neira

Hi,

This patch introduces the following changes to nfnetlink:

a) nfnetlink groups: Up to 32 maximum.

include/linux/netfilter/nfnetlink.h +4 -0
+#define NF_NETLINK_CONNTRACK_NEW       0x1
+#define NF_NETLINK_CONNTRACK_UPDATE    0x2
+#define NF_NETLINK_CONNTRACK_DESTROY   0x4
+#define NF_NETLINK_CONNTRACK_EXPECT    0x8
Quoted 1 line

I think that those four groups are enough to group events.

Currently there are about 3 netlink packets sent when a connection comes up and three when it goes down.

I wonder if it is worth being able to filter on the ctstate as well, under heavy load it is quite a benefit to reduce the netlink throughput by 3 times. An application might be interested in ESTABLISHED and CLOSE or TIMEOUT states.

These are subsets of CONNTRACK_UPDATE

I don't feel _very_ strongly about this, but I do think it is worth mentioning.

Amin

#2 lore raw
In reply to Pablo Neira

Hi Pablo, thanks for your patches.

Quoted 7 lines · Pablo Neira

a) nfnetlink groups: Up to 32 maximum.

include/linux/netfilter/nfnetlink.h +4 -0
+#define NF_NETLINK_CONNTRACK_NEW       0x1
+#define NF_NETLINK_CONNTRACK_UPDATE    0x2
+#define NF_NETLINK_CONNTRACK_DESTROY   0x4
+#define NF_NETLINK_CONNTRACK_EXPECT    0x8
Quoted 5 lines

I think that those four groups are enough to group events.

d) NFNL_SUBSYS_CTNETLINK_EXP has been killed. This is superseded by the group NF_NETLINK_CONNTRACK_EXPECT.

Patrick and me have just discussed this subject, and we thought it would be better to only have the first three groups and keep the expectations in their own subsys. This seems more orthogonal, so the group tells you the kind of event (new/update/destroy), and the subsystem indicates conntrack/expect.

Quoted 1 line

e) nfnetlink_subsystem internal list isn't used, the array is enough.

great.

Ok, so with the minor change above, I think all of the changes are fine.

I've just reworked the conntrack event cache to work without requiring skb->nfcache. I'll try to merge all the code and produce some working version which I'll put in svn.

Signature · 5 lines
- Harald Welte <[email protected]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie