diff options
author | Patrick McHardy <kaber@trash.net> | 2010-02-15 12:13:33 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-02-15 12:13:33 -0500 |
commit | 5d0aa2ccd4699a01cfdf14886191c249d7b45a01 (patch) | |
tree | 6ea81b5eede26bd6a04bcc3cd79770c334139381 /net/ipv6 | |
parent | 8fea97ec1772bbf553d89187340ef624d548e115 (diff) |
netfilter: nf_conntrack: add support for "conntrack zones"
Normally, each connection needs a unique identity. Conntrack zones allow
to specify a numerical zone using the CT target, connections in different
zones can use the same identity.
Example:
iptables -t raw -A PREROUTING -i veth0 -j CT --zone 1
iptables -t raw -A OUTPUT -o veth1 -j CT --zone 1
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 12 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 8 |
2 files changed, 14 insertions, 6 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 55ce22e5de49..996c3f41fecd 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <net/netfilter/nf_conntrack_l4proto.h> | 27 | #include <net/netfilter/nf_conntrack_l4proto.h> |
28 | #include <net/netfilter/nf_conntrack_l3proto.h> | 28 | #include <net/netfilter/nf_conntrack_l3proto.h> |
29 | #include <net/netfilter/nf_conntrack_core.h> | 29 | #include <net/netfilter/nf_conntrack_core.h> |
30 | #include <net/netfilter/nf_conntrack_zones.h> | ||
30 | #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> | 31 | #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> |
31 | #include <net/netfilter/nf_log.h> | 32 | #include <net/netfilter/nf_log.h> |
32 | 33 | ||
@@ -191,15 +192,20 @@ out: | |||
191 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, | 192 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, |
192 | struct sk_buff *skb) | 193 | struct sk_buff *skb) |
193 | { | 194 | { |
195 | u16 zone = NF_CT_DEFAULT_ZONE; | ||
196 | |||
197 | if (skb->nfct) | ||
198 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); | ||
199 | |||
194 | #ifdef CONFIG_BRIDGE_NETFILTER | 200 | #ifdef CONFIG_BRIDGE_NETFILTER |
195 | if (skb->nf_bridge && | 201 | if (skb->nf_bridge && |
196 | skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) | 202 | skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) |
197 | return IP6_DEFRAG_CONNTRACK_BRIDGE_IN; | 203 | return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; |
198 | #endif | 204 | #endif |
199 | if (hooknum == NF_INET_PRE_ROUTING) | 205 | if (hooknum == NF_INET_PRE_ROUTING) |
200 | return IP6_DEFRAG_CONNTRACK_IN; | 206 | return IP6_DEFRAG_CONNTRACK_IN + zone; |
201 | else | 207 | else |
202 | return IP6_DEFRAG_CONNTRACK_OUT; | 208 | return IP6_DEFRAG_CONNTRACK_OUT + zone; |
203 | 209 | ||
204 | } | 210 | } |
205 | 211 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index d772dc21857f..9be81776415e 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <net/netfilter/nf_conntrack_tuple.h> | 23 | #include <net/netfilter/nf_conntrack_tuple.h> |
24 | #include <net/netfilter/nf_conntrack_l4proto.h> | 24 | #include <net/netfilter/nf_conntrack_l4proto.h> |
25 | #include <net/netfilter/nf_conntrack_core.h> | 25 | #include <net/netfilter/nf_conntrack_core.h> |
26 | #include <net/netfilter/nf_conntrack_zones.h> | ||
26 | #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> | 27 | #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> |
27 | #include <net/netfilter/nf_log.h> | 28 | #include <net/netfilter/nf_log.h> |
28 | 29 | ||
@@ -128,7 +129,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, | |||
128 | } | 129 | } |
129 | 130 | ||
130 | static int | 131 | static int |
131 | icmpv6_error_message(struct net *net, | 132 | icmpv6_error_message(struct net *net, struct nf_conn *tmpl, |
132 | struct sk_buff *skb, | 133 | struct sk_buff *skb, |
133 | unsigned int icmp6off, | 134 | unsigned int icmp6off, |
134 | enum ip_conntrack_info *ctinfo, | 135 | enum ip_conntrack_info *ctinfo, |
@@ -137,6 +138,7 @@ icmpv6_error_message(struct net *net, | |||
137 | struct nf_conntrack_tuple intuple, origtuple; | 138 | struct nf_conntrack_tuple intuple, origtuple; |
138 | const struct nf_conntrack_tuple_hash *h; | 139 | const struct nf_conntrack_tuple_hash *h; |
139 | const struct nf_conntrack_l4proto *inproto; | 140 | const struct nf_conntrack_l4proto *inproto; |
141 | u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE; | ||
140 | 142 | ||
141 | NF_CT_ASSERT(skb->nfct == NULL); | 143 | NF_CT_ASSERT(skb->nfct == NULL); |
142 | 144 | ||
@@ -163,7 +165,7 @@ icmpv6_error_message(struct net *net, | |||
163 | 165 | ||
164 | *ctinfo = IP_CT_RELATED; | 166 | *ctinfo = IP_CT_RELATED; |
165 | 167 | ||
166 | h = nf_conntrack_find_get(net, &intuple); | 168 | h = nf_conntrack_find_get(net, zone, &intuple); |
167 | if (!h) { | 169 | if (!h) { |
168 | pr_debug("icmpv6_error: no match\n"); | 170 | pr_debug("icmpv6_error: no match\n"); |
169 | return -NF_ACCEPT; | 171 | return -NF_ACCEPT; |
@@ -216,7 +218,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl, | |||
216 | if (icmp6h->icmp6_type >= 128) | 218 | if (icmp6h->icmp6_type >= 128) |
217 | return NF_ACCEPT; | 219 | return NF_ACCEPT; |
218 | 220 | ||
219 | return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum); | 221 | return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum); |
220 | } | 222 | } |
221 | 223 | ||
222 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 224 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |