Skip to contentSkip to conversation

: kill struct nf_ct_info

PATCH In review Patrick McHardy 1 participant 1 message Sep 21, 2004

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

PATCH 5/12 : kill struct nf_ct_info

This patch might be controversial, it kills struct nf_ct_info and adds a new field to the skb to indicate the relationship of the skb to the conntrack. This saves 5 pointers per conntrack and removes an unnecessary level of pointer dereference. Currently nfct points to one of the five struct nf_ct_info embedded in struct ip_conntrack, each one containing a pointer to the struct ip_conntrack. The relationship is determined from the index of the struct nf_ct_info pointed to by the skb. There are usually alot more connection tracking entries than skbs in the system, so I thing it's worth it. To make up for the increased skb size I'm going to look at removing nfcache :)

[email protected], 2004-09-19 15:29:24+02:00, [email protected]
[NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack

The relationship of the skb to the conntrack is stored in a new field in the skb.

# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2004/09/19 15:29:24+02:00 [email protected]
# [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#
# The relationship of the skb to the conntrack is stored in a new field
# in the skb.
#
# Signed-off-by: Patrick McHardy <[email protected]>
#

# net/ipv6/ip6_output.c
#   2004/09/19 15:29:00+02:00 [email protected] +1 -0
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/ipv4/netfilter/ipt_state.c
#   2004/09/19 15:29:00+02:00 [email protected] +2 -2
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/ipv4/netfilter/ipt_conntrack.c
#   2004/09/19 15:29:00+02:00 [email protected] +1 -1
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/ipv4/netfilter/ipt_REJECT.c
#   2004/09/19 15:29:00+02:00 [email protected] +6 -6
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/ipv4/netfilter/ipt_NOTRACK.c
#   2004/09/19 15:28:59+02:00 [email protected] +2 -1
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/ipv4/netfilter/ip_fw_compat_masq.c
#   2004/09/19 15:28:59+02:00 [email protected] +3 -3
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/ipv4/netfilter/ip_conntrack_proto_icmp.c
#   2004/09/19 15:28:59+02:00 [email protected] +2 -1
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/ipv4/netfilter/ip_conntrack_core.c
#   2004/09/19 15:28:59+02:00 [email protected] +15 -47
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/ipv4/ip_output.c
#   2004/09/19 15:28:59+02:00 [email protected] +1 -0
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/core/skbuff.c
#   2004/09/19 15:28:59+02:00 [email protected] +2 -0
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# net/core/netfilter.c
#   2004/09/19 15:28:59+02:00 [email protected] +1 -1
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# include/linux/skbuff.h
#   2004/09/19 15:28:59+02:00 [email protected] +8 -10
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# include/linux/netfilter_ipv4/ip_conntrack_core.h
#   2004/09/19 15:28:59+02:00 [email protected] +3 -3
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# include/linux/netfilter_ipv4/ip_conntrack.h
#   2004/09/19 15:28:59+02:00 [email protected] +6 -7
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
# include/linux/netfilter.h
#   2004/09/19 15:28:59+02:00 [email protected] +1 -1
#   [NETFILTER]: kill struct nf_ct_info, saves five pointers per conntrack
#   
#   The relationship of the skb to the conntrack is stored in a new field
#   in the skb.
#   
#   Signed-off-by: Patrick McHardy <[email protected]>
# 
diff -Nru a/include/linux/netfilter.h b/include/linux/netfilter.h
--- a/include/linux/netfilter.h	2004-09-20 11:57:45 +02:00
+++ b/include/linux/netfilter.h	2004-09-20 11:57:45 +02:00
@@ -178,7 +178,7 @@
 ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex);
 extern inline struct arpt_target *
 arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
-extern void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *);
+extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);

#ifdef CONFIG_NETFILTER_DEBUG
extern void nf_dump_skb(int pf, struct sk_buff *skb);

include/linux/netfilter_ipv4/ip_conntrack.h +6 -7
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -196,12 +196,7 @@
 	/* Helper, if any. */
 	struct ip_conntrack_helper *helper;
 
-	/* Our various nf_ct_info structs specify *what* relation this
-           packet has to the conntrack */
-	struct nf_ct_info infos[IP_CT_NUMBER];
-
 	/* Storage reserved for other modules: */
-
 	union ip_conntrack_proto proto;
 
 	union ip_conntrack_help help;
@@ -238,8 +233,12 @@
 			 const struct ip_conntrack *ignored_conntrack);
 
 /* Return conntrack_info and tuple hash for given skb. */
-extern struct ip_conntrack *
-ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo);
+static inline struct ip_conntrack *
+ip_conntrack_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
+{
+	*ctinfo = skb->nfctinfo;
+	return (struct ip_conntrack *)skb->nfct;
+}
 
 /* decrement reference count on a conntrack */
 extern inline void ip_conntrack_put(struct ip_conntrack *ct);
include/linux/netfilter_ipv4/ip_conntrack_core.h +3 -3
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_core.h b/include/linux/netfilter_ipv4/ip_conntrack_core.h
@@ -38,14 +38,14 @@
 ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
 		      const struct ip_conntrack *ignored_conntrack);
 
-extern int __ip_conntrack_confirm(struct nf_ct_info *nfct);
+extern int __ip_conntrack_confirm(struct sk_buff *skb);
 
 /* Confirm a connection: returns NF_DROP if packet must be dropped. */
 static inline int ip_conntrack_confirm(struct sk_buff *skb)
 {
 	if (skb->nfct
-	    && !is_confirmed((struct ip_conntrack *)skb->nfct->master))
-		return __ip_conntrack_confirm(skb->nfct);
+	    && !is_confirmed((struct ip_conntrack *)skb->nfct))
+		return __ip_conntrack_confirm(skb);
 	return NF_ACCEPT;
 }
 
include/linux/skbuff.h +8 -10
diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h
@@ -97,10 +97,6 @@
 	void (*destroy)(struct nf_conntrack *);
 };
 
-struct nf_ct_info {
-	struct nf_conntrack *master;
-};
-
 #ifdef CONFIG_BRIDGE_NETFILTER
 struct nf_bridge_info {
 	atomic_t use;
@@ -186,6 +182,7 @@
  *	@nfmark: Can be used for communication between hooks
  *	@nfcache: Cache info
  *	@nfct: Associated connection, if any
+ *	@nfctinfo: Relationship of this skb to the connection
  *	@nf_debug: Netfilter debugging
  *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
  *      @private: Data which is private to the HIPPI implementation
@@ -253,7 +250,8 @@
 #ifdef CONFIG_NETFILTER
         unsigned long		nfmark;
 	__u32			nfcache;
-	struct nf_ct_info	*nfct;
+	struct nf_conntrack	*nfct;
+	__u32			nfctinfo;
 #ifdef CONFIG_NETFILTER_DEBUG
         unsigned int		nf_debug;
 #endif
@@ -1141,15 +1139,15 @@
 extern void skb_iter_abort(const struct sk_buff *skb, struct skb_iter *i);
 
 #ifdef CONFIG_NETFILTER
-static inline void nf_conntrack_put(struct nf_ct_info *nfct)
+static inline void nf_conntrack_put(struct nf_conntrack *nfct)
 {
-	if (nfct && atomic_dec_and_test(&nfct->master->use))
-		nfct->master->destroy(nfct->master);
+	if (nfct && atomic_dec_and_test(&nfct->use))
+		nfct->destroy(nfct);
 }
-static inline void nf_conntrack_get(struct nf_ct_info *nfct)
+static inline void nf_conntrack_get(struct nf_conntrack *nfct)
 {
 	if (nfct)
-		atomic_inc(&nfct->master->use);
+		atomic_inc(&nfct->use);
 }
 static inline void nf_reset(struct sk_buff *skb)
 {
net/core/netfilter.c +1 -1
diff -Nru a/net/core/netfilter.c b/net/core/netfilter.c
@@ -806,7 +806,7 @@
    tracking in use: without this, connection may not be in hash table,
    and hence manufactured ICMP or RST packets will not be associated
    with it. */
-void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *);
+void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
 
 void __init netfilter_init(void)
 {
net/core/skbuff.c +2 -0
diff -Nru a/net/core/skbuff.c b/net/core/skbuff.c
@@ -311,6 +311,7 @@
 	C(nfcache);
 	C(nfct);
 	nf_conntrack_get(skb->nfct);
+	C(nfctinfo);
 #ifdef CONFIG_NETFILTER_DEBUG
 	C(nf_debug);
 #endif
@@ -377,6 +378,7 @@
 	new->nfcache	= old->nfcache;
 	new->nfct	= old->nfct;
 	nf_conntrack_get(old->nfct);
+	new->nfctinfo	= old->nfctinfo;
 #ifdef CONFIG_NETFILTER_DEBUG
 	new->nf_debug	= old->nf_debug;
 #endif
net/ipv4/ip_output.c +1 -0
diff -Nru a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
@@ -422,6 +422,7 @@
 	nf_conntrack_put(to->nfct);
 	to->nfct = from->nfct;
 	nf_conntrack_get(to->nfct);
+	to->nfctinfo = from->nfctinfo;
 #ifdef CONFIG_BRIDGE_NETFILTER
 	nf_bridge_put(to->nf_bridge);
 	to->nf_bridge = from->nf_bridge;
net/ipv4/netfilter/ip_conntrack_core.c +15 -47

125 lines not on this page · raw message

net/ipv4/netfilter/ip_conntrack_proto_icmp.c +2 -1
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -195,7 +195,8 @@
 	}
 
 	/* Update skb to refer to this connection */
-	skb->nfct = &h->ctrack->infos[*ctinfo];
+	skb->nfct = &h->ctrack->ct_general;
+	skb->nfctinfo = *ctinfo;
 	return -NF_ACCEPT;
 }
 
net/ipv4/netfilter/ip_fw_compat_masq.c +3 -3
diff -Nru a/net/ipv4/netfilter/ip_fw_compat_masq.c b/net/ipv4/netfilter/ip_fw_compat_masq.c
@@ -146,7 +146,7 @@
 	case IPPROTO_ICMP:
 		/* ICMP errors. */
 		protocol->error(*pskb, &ctinfo, NF_IP_PRE_ROUTING);
-		ct = (struct ip_conntrack *)(*pskb)->nfct->master;
+		ct = (struct ip_conntrack *)(*pskb)->nfct;
 		if (ct) {
 			/* We only do SNAT in the compatibility layer.
 			   So we can manipulate ICMP errors from
@@ -187,7 +187,7 @@
 				      NULL, NULL, NULL);
 
 		/* Put back the reference gained from find_get */
-		nf_conntrack_put(&h->ctrack->infos[0]);
+		nf_conntrack_put(&h->ctrack->ct_general);
 		if (ret == NF_ACCEPT) {
 			struct ip_conntrack *ct;
 			ct = ip_conntrack_get(*pskb, &ctinfo);
@@ -206,7 +206,7 @@
 	} else {
 		if (h)
 			/* Put back the reference gained from find_get */
-			nf_conntrack_put(&h->ctrack->infos[0]);
+			nf_conntrack_put(&h->ctrack->ct_general);
 		ret = NF_ACCEPT;
 	}
 
net/ipv4/netfilter/ipt_NOTRACK.c +2 -1
diff -Nru a/net/ipv4/netfilter/ipt_NOTRACK.c b/net/ipv4/netfilter/ipt_NOTRACK.c
@@ -23,7 +23,8 @@
 	   If there is a real ct entry correspondig to this packet, 
 	   it'll hang aroun till timing out. We don't deal with it
 	   for performance reasons. JK */
-	(*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW];
+	(*pskb)->nfct = &ip_conntrack_untracked.ct_general;
+	(*pskb)->nfctinfo = IP_CT_NEW;
 	nf_conntrack_get((*pskb)->nfct);
 
 	return IPT_CONTINUE;
net/ipv4/netfilter/ipt_REJECT.c +6 -6
diff -Nru a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
@@ -41,14 +41,14 @@
 /* If the original packet is part of a connection, but the connection
    is not confirmed, our manufactured reply will not be associated
    with it, so we need to do this manually. */
-static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
+static void connection_attach(struct sk_buff *new_skb, struct sk_buff *skb)
 {
-	void (*attach)(struct sk_buff *, struct nf_ct_info *);
+	void (*attach)(struct sk_buff *, struct sk_buff *);
 
 	/* Avoid module unload race with ip_ct_attach being NULLed out */
-	if (nfct && (attach = ip_ct_attach) != NULL) {
+	if (skb->nfct && (attach = ip_ct_attach) != NULL) {
 		mb(); /* Just to be sure: must be read before executing this */
-		attach(new_skb, nfct);
+		attach(new_skb, skb);
 	}
 }
 
@@ -209,7 +209,7 @@
 	if (nskb->len > dst_pmtu(nskb->dst))
 		goto free_nskb;
 
-	connection_attach(nskb, oldskb->nfct);
+	connection_attach(nskb, oldskb);
 
 	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
 		ip_finish_output);
@@ -360,7 +360,7 @@
 	icmph->checksum = ip_compute_csum((unsigned char *)icmph,
 					  length - sizeof(struct iphdr));
 
-	connection_attach(nskb, skb_in->nfct);
+	connection_attach(nskb, skb_in);
 
 	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
 		ip_finish_output);
net/ipv4/netfilter/ipt_conntrack.c +1 -1
diff -Nru a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c
@@ -35,7 +35,7 @@
 
 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
 
-	if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
+	if (ct == &ip_conntrack_untracked)
 		statebit = IPT_CONNTRACK_STATE_UNTRACKED;
 	else if (ct)
  		statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
net/ipv4/netfilter/ipt_state.c +2 -2
diff -Nru a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c
@@ -30,9 +30,9 @@
 	enum ip_conntrack_info ctinfo;
 	unsigned int statebit;
 
-	if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
+	if (skb->nfct == &ip_conntrack_untracked.ct_general)
 		statebit = IPT_STATE_UNTRACKED;
-	else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
+	else if (!ip_conntrack_get(skb, &ctinfo))
 		statebit = IPT_STATE_INVALID;
 	else
 		statebit = IPT_STATE_BIT(ctinfo);
net/ipv6/ip6_output.c +1 -0
diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
@@ -477,6 +477,7 @@
 	/* Connection association is same as pre-frag packet */
 	to->nfct = from->nfct;
 	nf_conntrack_get(to->nfct);
+	to->nfctinfo = from->nfctinfo;
 #ifdef CONFIG_BRIDGE_NETFILTER
 	nf_bridge_put(to->nf_bridge);
 	to->nf_bridge = from->nf_bridge;