aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-03-20 22:23:05 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 22:23:05 -0500
commita193a4abdd1f742a57f3f70b6a83c3e536876e97 (patch)
tree1b77f9f388ae153815248e8ef30b0297943c7016 /include
parent6ffd30fbbb1b4a01a9f56049521693375a864d3e (diff)
[NETFILTER]: Fix skb->nf_bridge lifetime issues
The bridge netfilter code simulates the NF_IP_PRE_ROUTING hook and skips the real hook by registering with high priority and returning NF_STOP if skb->nf_bridge is present and the BRNF_NF_BRIDGE_PREROUTING flag is not set. The flag is only set during the simulated hook. Because skb->nf_bridge is only freed when the packet is destroyed, the packet will not only skip the first invocation of NF_IP_PRE_ROUTING, but in the case of tunnel devices on top of the bridge also all further ones. Forwarded packets from a bridge encapsulated by a tunnel device and sent as locally outgoing packet will also still have the incorrect bridge information from the input path attached. We already have nf_reset calls on all RX/TX paths of tunnel devices, so simply reset the nf_bridge field there too. As an added bonus, the bridge information for locally delivered packets is now also freed when the packet is queued to a socket. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/skbuff.h24
1 files changed, 14 insertions, 10 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 838ce0fdcef7..1a2611030d36 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1351,16 +1351,6 @@ static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
1351 kfree_skb(skb); 1351 kfree_skb(skb);
1352} 1352}
1353#endif 1353#endif
1354static inline void nf_reset(struct sk_buff *skb)
1355{
1356 nf_conntrack_put(skb->nfct);
1357 skb->nfct = NULL;
1358#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
1359 nf_conntrack_put_reasm(skb->nfct_reasm);
1360 skb->nfct_reasm = NULL;
1361#endif
1362}
1363
1364#ifdef CONFIG_BRIDGE_NETFILTER 1354#ifdef CONFIG_BRIDGE_NETFILTER
1365static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) 1355static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
1366{ 1356{
@@ -1373,6 +1363,20 @@ static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge)
1373 atomic_inc(&nf_bridge->use); 1363 atomic_inc(&nf_bridge->use);
1374} 1364}
1375#endif /* CONFIG_BRIDGE_NETFILTER */ 1365#endif /* CONFIG_BRIDGE_NETFILTER */
1366static inline void nf_reset(struct sk_buff *skb)
1367{
1368 nf_conntrack_put(skb->nfct);
1369 skb->nfct = NULL;
1370#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
1371 nf_conntrack_put_reasm(skb->nfct_reasm);
1372 skb->nfct_reasm = NULL;
1373#endif
1374#ifdef CONFIG_BRIDGE_NETFILTER
1375 nf_bridge_put(skb->nf_bridge);
1376 skb->nf_bridge = NULL;
1377#endif
1378}
1379
1376#else /* CONFIG_NETFILTER */ 1380#else /* CONFIG_NETFILTER */
1377static inline void nf_reset(struct sk_buff *skb) {} 1381static inline void nf_reset(struct sk_buff *skb) {}
1378#endif /* CONFIG_NETFILTER */ 1382#endif /* CONFIG_NETFILTER */