: netfilter: CT target/conntrack zones
Subsystems (4)
cover : netfilter: CT target/conntrack zones
The following patches contain a new version of the conntrack zones patchset, including a new xtables target to (among other things) assign conntracks to a specific zone, replacing the device attribute used in the previous version.
Quick overview:
- Patch 1 adds a struct net * parameter to the xtables target parameter structures as preparation for the CT target, which needs to allocate a conntrack entry in the proper namespace
- Patch 2 splits up the IPCT_STATUS event as requested by Jozsef. The CT target can be used for selective conntrack event delivery, this allows more fine grained control over the delivered events.
- Patch 3 adds selective conntrack event delivery by adding two masks for conntrack and expectation events to struct nf_conntrack_ecache, which are used to filter out events.
- Patch 4 fixes ctnetlink to only assign helpers for matching protocols to conntrack entries and fixes expectation deletion by helper name. This is also preparation for the CT target, which can also assign helpers to new connections.
- Patch 5 adds support for conntrack templates, which are specially marked conntrack entries attached to the skb that are used to initialize specific parameters of new connections.
- Patch 6 adds the CT target
- Patch 7 contains preparatory work for assigning conntracks to zones:
the template needs to be passed to L4 ->error handlers for ICMP and ICMPv6 to perform the conntrack lookup in the correct zone
- Patch 8 adds zone support to nf_conntrack and the CT target. This works by incorporating a numerical "zone" identifier into the conntrack/NAT hashes and comparing it during lookups.
- Patch 9 adds zone support to ctnetlink by dumping and parsing a new CTA_ZONE attribute that contains the zone ID.
Comments welcome.
include/linux/netfilter/nf_conntrack_common.h | 22 +++ include/linux/netfilter/nfnetlink_conntrack.h | 2 + include/linux/netfilter/x_tables.h | 2 + include/linux/netfilter/xt_CT.h | 14 ++ include/net/ip.h | 3 + include/net/ipv6.h | 3 + include/net/netfilter/nf_conntrack.h | 5 +- include/net/netfilter/nf_conntrack_core.h | 3 +- include/net/netfilter/nf_conntrack_ecache.h | 58 ++++----- include/net/netfilter/nf_conntrack_expect.h | 9 +- include/net/netfilter/nf_conntrack_extend.h | 2 + include/net/netfilter/nf_conntrack_helper.h | 8 +- include/net/netfilter/nf_conntrack_l4proto.h | 4 +- include/net/netfilter/nf_conntrack_zones.h | 21 +++ net/bridge/netfilter/ebtables.c | 10 +- net/ipv4/netfilter/ip_tables.c | 8 +- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 +- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 11 +- net/ipv4/netfilter/nf_defrag_ipv4.c | 9 +- net/ipv4/netfilter/nf_nat_core.c | 23 ++-- net/ipv4/netfilter/nf_nat_pptp.c | 3 +- net/ipv6/netfilter/ip6_tables.c | 8 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 9 +- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 11 +- net/netfilter/Kconfig | 15 ++ net/netfilter/Makefile | 1 + net/netfilter/nf_conntrack_core.c | 164 +++++++++++++++++------- net/netfilter/nf_conntrack_expect.c | 21 ++- net/netfilter/nf_conntrack_h323_main.c | 3 +- net/netfilter/nf_conntrack_helper.c | 44 ++++++- net/netfilter/nf_conntrack_netlink.c | 125 +++++++++++++----- net/netfilter/nf_conntrack_pptp.c | 14 +- net/netfilter/nf_conntrack_proto_dccp.c | 5 +- net/netfilter/nf_conntrack_proto_gre.c | 2 +- net/netfilter/nf_conntrack_proto_sctp.c | 2 +- net/netfilter/nf_conntrack_proto_tcp.c | 4 +- net/netfilter/nf_conntrack_proto_udp.c | 6 +- net/netfilter/nf_conntrack_proto_udplite.c | 4 +- net/netfilter/nf_conntrack_sip.c | 3 +- net/netfilter/nf_conntrack_standalone.c | 6 + net/netfilter/xt_CT.c | 147 +++++++++++++++++++++ net/netfilter/xt_connlimit.c | 2 +- 42 files changed, 628 insertions(+), 190 deletions(-) create mode 100644 include/linux/netfilter/xt_CT.h create mode 100644 include/net/netfilter/nf_conntrack_zones.h create mode 100644 net/netfilter/xt_CT.c
Patrick McHardy (9):
netfilter: add struct net * to target parameters
netfilter: nf_conntrack: split up IPCT_STATUS event
netfilter: ctnetlink: support selective event delivery
netfilter: ctnetlink: only assign helpers for matching protocols
netfilter: nf_conntrack: support conntrack templates
netfilter: xtables: add CT target
netfilter: nf_conntrack: pass template to l4proto ->error handler
netfilter: nf_conntrack: add support for "conntrack zones"
netfilter: ctnetlink: add zone support
PATCH 1/9 : netfilter: add struct net * to target parameters
commit 22bb6f4df0068c56f0f68c7af3f0bb46415fb425
Author: Patrick McHardy <[email protected]> Date: Wed Jan 20 10:53:52 2010 +0100
netfilter: add struct net * to target parameters
include/linux/netfilter/x_tables.h +2 -0
@@ -249,6 +249,7 @@ struct xt_target_param {* Other fields see above. */ struct xt_tgchk_param { +struct net *net;const char *table;const void *entryinfo;const struct xt_target *target;
@@ -259,6 +260,7 @@ struct xt_tgchk_param {/* Target destructor parameters */ struct xt_tgdtor_param { +struct net *net;const struct xt_target *target;void *targinfo;u_int8_t family;
net/bridge/netfilter/ebtables.c +6 -4
@@ -579,13 +579,14 @@ ebt_cleanup_match(struct ebt_entry_match *m, struct net *net, unsigned int *i) }static inline int -ebt_cleanup_watcher (struct ebt_entry_watcher *w,unsigned int *i) +ebt_cleanup_watcher (struct ebt_entry_watcher *w,struct net *net,unsigned int *i) {struct xt_tgdtor_param par;if (i && (*i)-- ==0 )return 1 ; + par.net = net; par.target = w->u.watcher; par.targinfo = w->data; par.family =NFPROTO_BRIDGE ;
@@ -606,10 +607,11 @@ ebt_cleanup_entry(struct ebt_entry *e, struct net *net, unsigned int *cnt)/* we're done */ if (cnt && (*cnt)-- ==0 )return 1 ; -EBT_WATCHER_ITERATE (e, ebt_cleanup_watcher,NULL ); +EBT_WATCHER_ITERATE (e, ebt_cleanup_watcher, net,NULL );EBT_MATCH_ITERATE (e, ebt_cleanup_match, net,NULL ); t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); + par.net = net; par.target = t->u.target; par.targinfo = t->data; par.family =NFPROTO_BRIDGE ;
@@ -674,7 +676,7 @@ ebt_check_entry(struct ebt_entry *e, } i =0 ; - mtpar.net = net; + mtpar.net = tgpar.net = net; mtpar.table = tgpar.table = name; mtpar.entryinfo = tgpar.entryinfo = e; mtpar.hook_mask = tgpar.hook_mask = hookmask;
@@ -730,7 +732,7 @@ ebt_check_entry(struct ebt_entry *e, (*cnt)++;return 0 ; cleanup_watchers: -EBT_WATCHER_ITERATE (e, ebt_cleanup_watcher, &j); +EBT_WATCHER_ITERATE (e, ebt_cleanup_watcher, net, &j); cleanup_matches:EBT_MATCH_ITERATE (e, ebt_cleanup_match, net, &i);return ret;
net/ipv4/netfilter/ip_tables.c +5 -3
@@ -638,10 +638,11 @@ err:return ret; } -static int check_target (struct ipt_entry *e,const char *name) +static int check_target (struct ipt_entry *e,struct net *net,const char *name) {struct ipt_entry_target *t =ipt_get_target (e);struct xt_tgchk_param par = { + .net = net, .table = name, .entryinfo = e, .target = t->u.kernel.target,
@@ -697,7 +698,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, } t->u.kernel.target = target; - ret =check_target (e, name); + ret =check_target (e, net, name);if (ret) goto err;
@@ -788,6 +789,7 @@ cleanup_entry(struct ipt_entry *e, struct net *net, unsigned int *i)IPT_MATCH_ITERATE (e, cleanup_match, net,NULL ); t =ipt_get_target (e); + par.net = net; par.target = t->u.kernel.target; par.targinfo = t->data; par.family =NFPROTO_IPV4 ;
@@ -1675,7 +1677,7 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name,if (ret) goto cleanup_matches; - ret =check_target (e, name); + ret =check_target (e, net, name);if (ret) goto cleanup_matches;
net/ipv6/netfilter/ip6_tables.c +5 -3
@@ -669,10 +669,11 @@ err:return ret; } -static int check_target (struct ip6t_entry *e,const char *name) +static int check_target (struct ip6t_entry *e,struct net *net,const char *name) {struct ip6t_entry_target *t =ip6t_get_target (e);struct xt_tgchk_param par = { + .net = net, .table = name, .entryinfo = e, .target = t->u.kernel.target,
@@ -729,7 +730,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, } t->u.kernel.target = target; - ret =check_target (e, name); + ret =check_target (e, net, name);if (ret) goto err;
@@ -820,6 +821,7 @@ cleanup_entry(struct ip6t_entry *e, struct net *net, unsigned int *i)IP6T_MATCH_ITERATE (e, cleanup_match, net,NULL ); t =ip6t_get_target (e); + par.net = net; par.target = t->u.kernel.target; par.targinfo = t->data; par.family =NFPROTO_IPV6 ;
@@ -1710,7 +1712,7 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net,if (ret) goto cleanup_matches; - ret =check_target (e, name); + ret =check_target (e, net, name);if (ret) goto cleanup_matches;
PATCH 2/9 : netfilter: nf_conntrack: split up IPCT_STATUS event
In reply to Patrick McHardycommit 036e308d769fb3191253e954ec17da5455da5420
Author: Patrick McHardy <[email protected]> Date: Wed Jan 20 11:38:28 2010 +0100
netfilter: nf_conntrack: split up IPCT_STATUS event
Split up the IPCT_STATUS event into an IPCT_REPLY event, which is generated when the IPS_SEEN_REPLY bit is set, and an IPCT_ASSURED event, which is generated when the IPS_ASSURED bit is set.
In combination with a following patch to support selective event delivery, this can be used for "sparse" conntrack replication: start replicating the conntrack entry after it reached the ASSURED state and that way it's SYN-flood resistant.
include/net/netfilter/nf_conntrack_ecache.h +11 -10
@@ -14,19 +14,20 @@/* Connection tracking event types */ enum ip_conntrack_events { -IPCT_NEW =0 ,/* new conntrack */ -IPCT_RELATED =1 ,/* related conntrack */ -IPCT_DESTROY =2 ,/* destroyed conntrack */ -IPCT_STATUS =3 ,/* status has changed */ -IPCT_PROTOINFO =4 ,/* protocol information has changed */ -IPCT_HELPER =5 ,/* new helper has been set */ -IPCT_MARK =6 ,/* new mark has been set */ -IPCT_NATSEQADJ =7 ,/* NAT is doing sequence adjustment */ -IPCT_SECMARK =8 ,/* new security mark has been set */ +IPCT_NEW ,/* new conntrack */ +IPCT_RELATED ,/* related conntrack */ +IPCT_DESTROY ,/* destroyed conntrack */ +IPCT_REPLY ,/* connection has seen two-way traffic */ +IPCT_ASSURED ,/* connection status has changed to assured */ +IPCT_PROTOINFO ,/* protocol information has changed */ +IPCT_HELPER ,/* new helper has been set */ +IPCT_MARK ,/* new mark has been set */ +IPCT_NATSEQADJ ,/* NAT is doing sequence adjustment */ +IPCT_SECMARK ,/* new security mark has been set */ };enum ip_conntrack_expect_events { -IPEXP_NEW =0 ,/* new expectation */ +IPEXP_NEW ,/* new expectation */ };struct nf_conntrack_ecache {
net/netfilter/nf_conntrack_core.c +1 -1
@@ -825,7 +825,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, }if (set_reply && !test_and_set_bit (IPS_SEEN_REPLY_BIT , &ct->status)) -nf_conntrack_event_cache (IPCT_STATUS , ct); +nf_conntrack_event_cache (IPCT_REPLY , ct);return ret; }
net/netfilter/nf_conntrack_netlink.c +4 -2
@@ -1366,7 +1366,8 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,else events =IPCT_NEW ; - nf_conntrack_eventmask_report((1 << IPCT_STATUS) | + nf_conntrack_eventmask_report((1 << IPCT_REPLY) | + (1 << IPCT_ASSURED) | (1 << IPCT_HELPER) | (1 << IPCT_PROTOINFO) | (1 << IPCT_NATSEQADJ) |
@@ -1391,7 +1392,8 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,if (err ==0 ) {nf_conntrack_get (&ct->ct_general);spin_unlock_bh (&nf_conntrack_lock); - nf_conntrack_eventmask_report((1 << IPCT_STATUS) | + nf_conntrack_eventmask_report((1 << IPCT_REPLY) | + (1 << IPCT_ASSURED) | (1 << IPCT_HELPER) | (1 << IPCT_PROTOINFO) | (1 << IPCT_NATSEQADJ) |
net/netfilter/nf_conntrack_proto_gre.c +1 -1
@@ -241,7 +241,7 @@ static int gre_packet(struct nf_conn *ct, ct->proto.gre.stream_timeout);/* Also, more likely to be important, and not a probe. */ set_bit (IPS_ASSURED_BIT , &ct->status); -nf_conntrack_event_cache (IPCT_STATUS , ct); +nf_conntrack_event_cache (IPCT_ASSURED , ct); }else nf_ct_refresh_acct (ct, ctinfo, skb, ct->proto.gre.timeout);
net/netfilter/nf_conntrack_proto_sctp.c +1 -1
@@ -377,7 +377,7 @@ static int sctp_packet(struct nf_conn *ct, new_state == SCTP_CONNTRACK_ESTABLISHED) {pr_debug ("Setting assured bit\n" );set_bit (IPS_ASSURED_BIT , &ct->status); -nf_conntrack_event_cache (IPCT_STATUS , ct); +nf_conntrack_event_cache (IPCT_ASSURED , ct); }return NF_ACCEPT ;
net/netfilter/nf_conntrack_proto_tcp.c +1 -1
@@ -1045,7 +1045,7 @@ static int tcp_packet(struct nf_conn *ct,after SYN_RECV or a valid answer for a picked up connection. */ set_bit (IPS_ASSURED_BIT , &ct->status); -nf_conntrack_event_cache (IPCT_STATUS , ct); +nf_conntrack_event_cache (IPCT_ASSURED , ct); }nf_ct_refresh_acct (ct, ctinfo, skb, timeout);
net/netfilter/nf_conntrack_proto_udp.c +1 -1
@@ -77,7 +77,7 @@ static int udp_packet(struct nf_conn *ct,nf_ct_refresh_acct (ct, ctinfo, skb, nf_ct_udp_timeout_stream);/* Also, more likely to be important, and not a probe */ if (!test_and_set_bit (IPS_ASSURED_BIT , &ct->status)) -nf_conntrack_event_cache (IPCT_STATUS , ct); +nf_conntrack_event_cache (IPCT_ASSURED , ct); }else nf_ct_refresh_acct (ct, ctinfo, skb, nf_ct_udp_timeout);
net/netfilter/nf_conntrack_proto_udplite.c +1 -1
@@ -75,7 +75,7 @@ static int udplite_packet(struct nf_conn *ct, nf_ct_udplite_timeout_stream);/* Also, more likely to be important, and not a probe */ if (!test_and_set_bit (IPS_ASSURED_BIT , &ct->status)) -nf_conntrack_event_cache (IPCT_STATUS , ct); +nf_conntrack_event_cache (IPCT_ASSURED , ct); }else nf_ct_refresh_acct (ct, ctinfo, skb, nf_ct_udplite_timeout);
PATCH 3/9 : netfilter: ctnetlink: support selective event delivery
In reply to Patrick McHardycommit 1ffde83b6b84de4e07676878f3e9f9ee9d257054
Author: Patrick McHardy <[email protected]> Date: Mon Jan 25 15:25:03 2010 +0100
netfilter: ctnetlink: support selective event delivery
Add two masks for conntrack end expectation events to struct nf_conntrack_ecache and use them to filter events. Their default value is "all events" when the event sysctl is on and "no events" when it is off. A following patch will add specific initializations. Expectation events depend on the ecache struct of their master conntrack.
include/linux/netfilter/nf_conntrack_common.h +18 -0
@@ -74,6 +74,24 @@ enum ip_conntrack_status { IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT), }; +/* Connection tracking event types */ +enum ip_conntrack_events { +IPCT_NEW ,/* new conntrack */ +IPCT_RELATED ,/* related conntrack */ +IPCT_DESTROY ,/* destroyed conntrack */ +IPCT_REPLY ,/* connection has seen two-way traffic */ +IPCT_ASSURED ,/* connection status has changed to assured */ +IPCT_PROTOINFO ,/* protocol information has changed */ +IPCT_HELPER ,/* new helper has been set */ +IPCT_MARK ,/* new mark has been set */ +IPCT_NATSEQADJ ,/* NAT is doing sequence adjustment */ +IPCT_SECMARK ,/* new security mark has been set */ +}; + +enum ip_conntrack_expect_events { +IPEXP_NEW ,/* new expectation */ +}; +#ifdef __KERNEL__ struct ip_conntrack_stat { unsigned int searched;
include/net/netfilter/nf_conntrack_ecache.h +28 -31
116 lines not on this page · raw message
net/netfilter/nf_conntrack_core.c +1 -1
@@ -648,7 +648,7 @@ init_conntrack(struct net *net, }nf_ct_acct_ext_add (ct,GFP_ATOMIC ); -nf_ct_ecache_ext_add (ct,GFP_ATOMIC ); +nf_ct_ecache_ext_add (ct,0 ,0 ,GFP_ATOMIC );spin_lock_bh (&nf_conntrack_lock); exp =nf_ct_find_expectation (net, tuple);
net/netfilter/nf_conntrack_netlink.c +1 -1
@@ -1276,7 +1276,7 @@ ctnetlink_create_conntrack(struct net *net, }nf_ct_acct_ext_add (ct,GFP_ATOMIC ); -nf_ct_ecache_ext_add (ct,GFP_ATOMIC ); +nf_ct_ecache_ext_add (ct,0 ,0 ,GFP_ATOMIC );#if defined(CONFIG_NF_CONNTRACK_MARK )if (cda[CTA_MARK ])
PATCH 4/9 : netfilter: ctnetlink: only assign helpers for matching protocols
In reply to Patrick McHardycommit 60fe6090ad2193a24263a6366675f2d96608a798
Author: Patrick McHardy <[email protected]> Date: Mon Jan 25 15:25:03 2010 +0100
netfilter: ctnetlink: only assign helpers for matching protocols
Make sure not to assign a helper for a different network or transport layer protocol to a connection.
Additionally change expectation deletion by helper to compare the name directly - there might be multiple helper registrations using the same name, currently one of them is chosen in an unpredictable manner and only those expectations are removed.
include/net/netfilter/nf_conntrack_helper.h +1 -1
@@ -40,7 +40,7 @@ struct nf_conntrack_helper { };extern struct nf_conntrack_helper * -__nf_conntrack_helper_find_byname (const char *name); +__nf_conntrack_helper_find (const char *name,u16 l3num,u8 protonum);extern int nf_conntrack_helper_register (struct nf_conntrack_helper *);extern void nf_conntrack_helper_unregister (struct nf_conntrack_helper *);
net/netfilter/nf_conntrack_helper.c +5 -3
@@ -65,7 +65,7 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple) }struct nf_conntrack_helper * -__nf_conntrack_helper_find_byname (const char *name) +__nf_conntrack_helper_find (const char *name,u16 l3num,u8 protonum) {struct nf_conntrack_helper *h;struct hlist_node *n;
@@ -73,13 +73,15 @@ __nf_conntrack_helper_find_byname(const char *name)for (i =0 ; i < nf_ct_helper_hsize; i++) {hlist_for_each_entry_rcu (h, n, &nf_ct_helper_hash[i], hnode) { -if (!strcmp (h->name, name)) +if (!strcmp (h->name, name) && + h->tuple.src.l3num == l3num && + h->tuple.dst.protonum == protonum)return h; } }return NULL ; } -EXPORT_SYMBOL_GPL (__nf_conntrack_helper_find_byname); +EXPORT_SYMBOL_GPL (__nf_conntrack_helper_find);struct nf_conn_help *nf_ct_helper_ext_add (struct nf_conn *ct,gfp_t gfp) {
net/netfilter/nf_conntrack_netlink.c +11 -12
@@ -1001,7 +1001,8 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])return 0 ; } - helper =__nf_conntrack_helper_find_byname (helpname); + helper =__nf_conntrack_helper_find (helpname,nf_ct_l3num (ct), +nf_ct_protonum (ct));if (helper ==NULL ) {#ifdef CONFIG_MODULES spin_unlock_bh (&nf_conntrack_lock);
@@ -1012,7 +1013,8 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) }spin_lock_bh (&nf_conntrack_lock); - helper =__nf_conntrack_helper_find_byname (helpname); + helper =__nf_conntrack_helper_find (helpname,nf_ct_l3num (ct), +nf_ct_protonum (ct));if (helper)return -EAGAIN ;#endif
@@ -1211,7 +1213,8 @@ ctnetlink_create_conntrack(struct net *net,if (err <0 ) goto err2; - helper =__nf_conntrack_helper_find_byname (helpname); + helper =__nf_conntrack_helper_find (helpname,nf_ct_l3num (ct), +nf_ct_protonum (ct));if (helper ==NULL ) {rcu_read_unlock ();#ifdef CONFIG_MODULES
@@ -1221,7 +1224,9 @@ ctnetlink_create_conntrack(struct net *net, }rcu_read_lock (); - helper =__nf_conntrack_helper_find_byname (helpname); + helper =__nf_conntrack_helper_find (helpname, +nf_ct_l3num (ct), +nf_ct_protonum (ct));if (helper) { err = -EAGAIN ; goto err2;
@@ -1716,7 +1721,6 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,struct net *net =sock_net (ctnl);struct nf_conntrack_expect *exp;struct nf_conntrack_tuple tuple; -struct nf_conntrack_helper *h;struct nfgenmsg *nfmsg =nlmsg_data (nlh);struct hlist_node *n, *next;u_int8_t u3 = nfmsg->nfgen_family;
@@ -1753,18 +1757,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,/* delete all expectations for this helper */ spin_lock_bh (&nf_conntrack_lock); - h =__nf_conntrack_helper_find_byname (name); -if (!h) { -spin_unlock_bh (&nf_conntrack_lock); -return -EOPNOTSUPP ; - }for (i =0 ; i < nf_ct_expect_hsize; i++) {hlist_for_each_entry_safe (exp, n, next, &net->ct.expect_hash[i], hnode) { m_help =nfct_help (exp->master); -if (m_help->helper == h - &&del_timer (&exp->timeout)) { +if (!strcmp (m_help->helper->name, name) && +del_timer (&exp->timeout)) {nf_ct_unlink_expect (exp);nf_ct_expect_put (exp); }
PATCH 5/9 : netfilter: nf_conntrack: support conntrack templates
In reply to Patrick McHardycommit 5c403d5f04276db8f1288cf1a7ad6e675234e31f
Author: Patrick McHardy <[email protected]> Date: Mon Jan 25 15:25:04 2010 +0100
netfilter: nf_conntrack: support conntrack templates
Support initializing selected parameters of new conntrack entries from a "conntrack template", which is a specially marked conntrack entry attached to the skb.
Currently the helper and the event delivery masks can be initialized this way.
include/linux/netfilter/nf_conntrack_common.h +4 -0
@@ -72,6 +72,10 @@ enum ip_conntrack_status {/* Connection has fixed timeout. */ IPS_FIXED_TIMEOUT_BIT =10 ,IPS_FIXED_TIMEOUT = (1 <<IPS_FIXED_TIMEOUT_BIT ), + +/* Conntrack is a template */ +IPS_TEMPLATE_BIT =11 , + IPS_TEMPLATE = (1 << IPS_TEMPLATE_BIT), };/* Connection tracking event types */
include/net/netfilter/nf_conntrack_helper.h +2 -1
@@ -47,7 +47,8 @@ extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);extern struct nf_conn_help *nf_ct_helper_ext_add (struct nf_conn *ct,gfp_t gfp); -extern int __nf_ct_try_assign_helper (struct nf_conn *ct,gfp_t flags); +extern int __nf_ct_try_assign_helper (struct nf_conn *ct,struct nf_conn *tmpl, +gfp_t flags);extern void nf_ct_helper_destroy (struct nf_conn *ct);
net/netfilter/nf_conntrack_core.c +34 -16
139 lines not on this page · raw message
net/netfilter/nf_conntrack_helper.c +13 -4
@@ -96,13 +96,22 @@ struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp) }EXPORT_SYMBOL_GPL (nf_ct_helper_ext_add); -int __nf_ct_try_assign_helper (struct nf_conn *ct,gfp_t flags) +int __nf_ct_try_assign_helper (struct nf_conn *ct,struct nf_conn *tmpl, +gfp_t flags) { +struct nf_conntrack_helper *helper =NULL ; +struct nf_conn_help *help;int ret =0 ; -struct nf_conntrack_helper *helper; -struct nf_conn_help *help =nfct_help (ct); - helper =__nf_ct_helper_find (&ct->tuplehash[IP_CT_DIR_REPLY ].tuple); +if (tmpl !=NULL ) { + help =nfct_help (tmpl); +if (help !=NULL ) + helper = help->helper; + } + + help =nfct_help (ct); +if (helper ==NULL ) + helper =__nf_ct_helper_find (&ct->tuplehash[IP_CT_DIR_REPLY ].tuple);if (helper ==NULL ) {if (help)rcu_assign_pointer (help->helper,NULL );
net/netfilter/nf_conntrack_netlink.c +1 -1
@@ -1249,7 +1249,7 @@ ctnetlink_create_conntrack(struct net *net, } }else {/* try an implicit helper assignation */ - err =__nf_ct_try_assign_helper (ct,GFP_ATOMIC ); + err =__nf_ct_try_assign_helper (ct,NULL ,GFP_ATOMIC );if (err <0 ) goto err2; }
PATCH 6/9 : netfilter: xtables: add CT target
In reply to Patrick McHardycommit b5d677bfd7e8a26652c83df29c2375161cecd958
Author: Patrick McHardy <[email protected]> Date: Mon Jan 25 15:25:04 2010 +0100
netfilter: xtables: add CT target
Add a new target for the raw table, which can be used to specify conntrack parameters for specific connections, f.i. the conntrack helper.
The target attaches a "template" connection tracking entry to the skb, which is used by the conntrack core when initializing the new conntrack.
include/linux/netfilter/xt_CT.h new file +13 -0
@@ -0,0 +1,13 @@ +#ifndef _XT_CT_H +#define _XT_CT_H + +struct xt_ct_target_info { +u_int32_t ct_events; +u_int32_t exp_events; +char helper[16 ]; + +/* Used internally by the kernel */ +struct nf_conn *ct __attribute__((aligned (8 ))); +}; + +#endif /* _XT_CT_H */
include/net/netfilter/nf_conntrack_helper.h +3 -0
@@ -42,6 +42,9 @@ struct nf_conntrack_helper {extern struct nf_conntrack_helper *__nf_conntrack_helper_find (const char *name,u16 l3num,u8 protonum); +extern struct nf_conntrack_helper * +nf_conntrack_helper_try_module_get (const char *name,u16 l3num,u8 protonum); +extern int nf_conntrack_helper_register (struct nf_conntrack_helper *);extern void nf_conntrack_helper_unregister (struct nf_conntrack_helper *);
net/netfilter/Kconfig +6 -0
@@ -341,6 +341,12 @@ config NETFILTER_XT_TARGET_CONNSECMARK To compile it as a module, choose M here. If unsure, say N. +config NETFILTER_XT_TARGET_CT + tristate '"CT" target support' + depends on NF_CONNTRACK + depends on IP_NF_RAW || IP6_NF_RAW + depends on NETFILTER_ADVANCED + config NETFILTER_XT_TARGET_DSCP tristate '"DSCP" and "TOS" target support' depends on IP_NF_MANGLE || IP6_NF_MANGLE
net/netfilter/Makefile +1 -0
@@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o +obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
net/netfilter/nf_conntrack_helper.c +19 -0
@@ -83,6 +83,25 @@ __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum) }EXPORT_SYMBOL_GPL (__nf_conntrack_helper_find); +struct nf_conntrack_helper * +nf_conntrack_helper_try_module_get (const char *name,u16 l3num,u8 protonum) +{ +struct nf_conntrack_helper *h; + + h =__nf_conntrack_helper_find (name, l3num, protonum); +#ifdef CONFIG_MODULES +if (h ==NULL ) { +if (request_module ("nfct-helper-%s" , name) ==0 ) + h =__nf_conntrack_helper_find (name, l3num, protonum); + } +#endif +if (h !=NULL && !try_module_get (h->me)) + h =NULL ; + +return h; +} +EXPORT_SYMBOL_GPL (nf_conntrack_helper_try_module_get); +struct nf_conn_help *nf_ct_helper_ext_add (struct nf_conn *ct,gfp_t gfp) {struct nf_conn_help *help;
net/netfilter/xt_CT.c new file +142 -0
142 lines not on this page · raw message
Re: [PATCH 06/09]: netfilter: xtables: add CT target
Quoted 8 lines · Patrick McHardy
netfilter: xtables: add CT target
Add a new target for the raw table, which can be used to specify conntrack parameters for specific connections, f.i. the conntrack helper.
The target attaches a "template" connection tracking entry to the skb, which is used by the conntrack core when initializing the new conntrack.
Quoted 7 lines
include/linux/netfilter/xt_CT.h | 13 ++ include/net/netfilter/nf_conntrack_helper.h | 3 net/netfilter/Kconfig | 6 + net/netfilter/Makefile | 1 net/netfilter/nf_conntrack_helper.c | 19 +++ net/netfilter/xt_CT.c | 142 ++++++++++++++++++++++++++++ 6 files changed, 184 insertions(+)
Is it perhaps feasible to put the xt_CT code into an already existing .c file (e.g. xt_conntrack.c) to cut on module overhead?
Re: [PATCH 06/09]: netfilter: xtables: add CT target
Quoted 18 lines · Jan Engelhardt
Quoted 8 lines · Patrick McHardy
netfilter: xtables: add CT target
Add a new target for the raw table, which can be used to specify conntrack parameters for specific connections, f.i. the conntrack helper.
The target attaches a "template" connection tracking entry to the skb, which is used by the conntrack core when initializing the new conntrack.
Quoted 7 lines
include/linux/netfilter/xt_CT.h | 13 ++ include/net/netfilter/nf_conntrack_helper.h | 3 net/netfilter/Kconfig | 6 + net/netfilter/Makefile | 1 net/netfilter/nf_conntrack_helper.c | 19 +++ net/netfilter/xt_CT.c | 142 ++++++++++++++++++++++++++++ 6 files changed, 184 insertions(+)
Quoted 2 lines
Is it perhaps feasible to put the
xt_CTcode into an already existing .c file (e.g.xt_conntrack.c) to cut on module overhead?
They're quite different, so those two don't fit together very well. We could add NOTRACK support to xt_CT and deprecate the NOTRACK module.
Re: [PATCH 06/09]: netfilter: xtables: add CT target
Quoted 19 lines · Patrick McHardy
Quoted 18 lines · Jan Engelhardt
Quoted 15 lines · Patrick McHardy
netfilter: xtables: add CT target
Add a new target for the raw table, which can be used to specify conntrack parameters for specific connections, f.i. the conntrack helper.
The target attaches a "template" connection tracking entry to the skb, which is used by the conntrack core when initializing the new conntrack.
include/linux/netfilter/xt_CT.h | 13 ++ include/net/netfilter/nf_conntrack_helper.h | 3 net/netfilter/Kconfig | 6 + net/netfilter/Makefile | 1 net/netfilter/nf_conntrack_helper.c | 19 +++ net/netfilter/xt_CT.c | 142 ++++++++++++++++++++++++++++ 6 files changed, 184 insertions(+)
Quoted 6 lines
Quoted 2 lines
Is it perhaps feasible to put the
xt_CTcode into an already existing .c file (e.g.xt_conntrack.c) to cut on module overhead?They're quite different, so those two don't fit together very well. We could add NOTRACK support to
xt_CTand deprecate the NOTRACK module.
Sounds like a plan. Will you take care of that, or should I add it to my list?
Re: [PATCH 06/09]: netfilter: xtables: add CT target
Quoted 18 lines · Jan Engelhardt
Quoted 17 lines · Patrick McHardy
Quoted 16 lines · Jan Engelhardt
Quoted 14 lines · Patrick McHardy
netfilter: xtables: add CT target
Add a new target for the raw table, which can be used to specify conntrack parameters for specific connections, f.i. the conntrack helper.
The target attaches a "template" connection tracking entry to the skb, which is used by the conntrack core when initializing the new conntrack.
include/linux/netfilter/xt_CT.h | 13 ++ include/net/netfilter/nf_conntrack_helper.h | 3 net/netfilter/Kconfig | 6 + net/netfilter/Makefile | 1 net/netfilter/nf_conntrack_helper.c | 19 +++ net/netfilter/xt_CT.c | 142 ++++++++++++++++++++++++++++ 6 files changed, 184 insertions(+)
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Is it perhaps feasible to put the
xt_CTcode into an already existing .c file (e.g.xt_conntrack.c) to cut on module overhead?They're quite different, so those two don't fit together very well. We could add NOTRACK support to
xt_CTand deprecate the NOTRACK module.Sounds like a plan. Will you take care of that, or should I add it to my list?
I'll take care of it and will include it in the next submission.
Does anyone have an opinion on supporting specifying helper parameters? I'm considering adding something like 5 generically usable u32s and have helpers initialize parameters like FTP "loose" or SIP "direct_media" based on those.
Re: [PATCH 06/09]: netfilter: xtables: add CT target
Quoted 6 lines · Patrick McHardy
Does anyone have an opinion on supporting specifying helper parameters? I'm considering adding something like 5 generically usable u32s and have helpers initialize parameters like FTP "loose" or SIP "
direct_media" based on those.
Is there a case where someone wants to loosen just half of their FTP connections? Well yes maybe there is, but anyone ever request it?
Re: [PATCH 06/09]: netfilter: xtables: add CT target
Quoted 9 lines · Jan Engelhardt
Quoted 5 lines · Patrick McHardy
Does anyone have an opinion on supporting specifying helper parameters? I'm considering adding something like 5 generically usable u32s and have helpers initialize parameters like FTP "loose" or SIP "
direct_media" based on those.Is there a case where someone wants to loosen just half of their FTP connections? Well yes maybe there is, but anyone ever request it?
Not FTP specifically, SIP and H.323 would be the primary use cases. But if the infrastructure is there anyways, we might as well add support for FTP.
PATCH 7/9 : netfilter: nf_conntrack: pass template to l4proto ->error handler
In reply to Patrick McHardycommit 1ce077bf1a71309d206b29a02be326013735faca
Author: Patrick McHardy <[email protected]> Date: Mon Jan 25 15:25:04 2010 +0100
netfilter: nf_conntrack: pass template to l4proto ->error handler
The error handlers might need the template to get the conntrack zone introduced in the next patches to perform a conntrack lookup.
include/net/netfilter/nf_conntrack_l4proto.h +2 -2
@@ -49,8 +49,8 @@ struct nf_conntrack_l4proto {/* Called when a conntrack entry is destroyed */ void (*destroy)(struct nf_conn *ct); -int (*error)(struct net *net,struct sk_buff *skb,unsigned int dataoff, -enum ip_conntrack_info *ctinfo, +int (*error)(struct net *net,struct nf_conn *tmpl,struct sk_buff *skb, +unsigned int dataoff,enum ip_conntrack_info *ctinfo,u_int8_t pf,unsigned int hooknum);/* Print out the per-protocol part of the tuple. Return like seq_* */
net/ipv4/netfilter/nf_conntrack_proto_icmp.c +2 -1
@@ -163,7 +163,8 @@ icmp_error_message(struct net *net, struct sk_buff *skb,/* Small and modified version of icmp_rcv */ static int -icmp_error (struct net *net,struct sk_buff *skb,unsigned int dataoff, +icmp_error (struct net *net,struct nf_conn *tmpl, +struct sk_buff *skb,unsigned int dataoff,enum ip_conntrack_info *ctinfo,u_int8_t pf,unsigned int hooknum) {const struct icmphdr *icmph;
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +2 -1
@@ -179,7 +179,8 @@ icmpv6_error_message(struct net *net, }static int -icmpv6_error (struct net *net,struct sk_buff *skb,unsigned int dataoff, +icmpv6_error (struct net *net,struct nf_conn *tmpl, +struct sk_buff *skb,unsigned int dataoff,enum ip_conntrack_info *ctinfo,u_int8_t pf,unsigned int hooknum) {const struct icmp6hdr *icmp6h;
net/netfilter/nf_conntrack_core.c +2 -1
@@ -798,7 +798,8 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,* inverse of the return code tells to the netfilter * core what to do with the packet. */ if (l4proto->error !=NULL ) { - ret = l4proto->error (net, skb, dataoff, &ctinfo, pf, hooknum); + ret = l4proto->error (net, tmpl, skb, dataoff, &ctinfo, + pf, hooknum);if (ret <=0 ) {NF_CT_STAT_INC_ATOMIC (net, error);NF_CT_STAT_INC_ATOMIC (net, invalid);
net/netfilter/nf_conntrack_proto_dccp.c +3 -2
@@ -561,8 +561,9 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,return NF_ACCEPT ; } -static int dccp_error (struct net *net,struct sk_buff *skb, -unsigned int dataoff,enum ip_conntrack_info *ctinfo, +static int dccp_error (struct net *net,struct nf_conn *tmpl, +struct sk_buff *skb,unsigned int dataoff, +enum ip_conntrack_info *ctinfo,u_int8_t pf,unsigned int hooknum) {struct dccp_hdr _dh, *dh;
net/netfilter/nf_conntrack_proto_tcp.c +1 -1
@@ -760,7 +760,7 @@ static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] = };/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */ -static int tcp_error(struct net *net, +static int tcp_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info *ctinfo,
net/netfilter/nf_conntrack_proto_udp.c +2 -2
@@ -91,8 +91,8 @@ static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,return true; } -static int udp_error (struct net *net,struct sk_buff *skb,unsigned int dataoff, -enum ip_conntrack_info *ctinfo, +static int udp_error (struct net *net,struct nf_conn *tmpl,struct sk_buff *skb, +unsigned int dataoff,enum ip_conntrack_info *ctinfo,u_int8_t pf,unsigned int hooknum) {
net/netfilter/nf_conntrack_proto_udplite.c +1 -1
@@ -89,7 +89,7 @@ static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb,return true; } -static int udplite_error(struct net *net, +static int udplite_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info *ctinfo,
PATCH 8/9 : netfilter: nf_conntrack: add support for "conntrack zones"
In reply to Patrick McHardycommit 9a53ed59344fe3874d157257c80d7fb1c949a316
Author: Patrick McHardy <[email protected]> Date: Mon Jan 25 16:21:52 2010 +0100
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:
# assign connections between veth0 and veth1 to conntrack zone 1:
iptables -t raw -I PREROUTING -i veth0 -j CT --zone 1 iptables -t raw -I PREROUTING -i veth1 -j CT --zone 1
include/linux/netfilter/xt_CT.h +1 -0
@@ -5,6 +5,7 @@ struct xt_ct_target_info {u_int32_t ct_events;u_int32_t exp_events;char helper[16 ]; +u_int16_t zone;/* Used internally by the kernel */ struct nf_conn *ct __attribute__((aligned(8)));
include/net/ip.h +3 -0
@@ -336,8 +336,11 @@ enum ip_defrag_users {IP_DEFRAG_LOCAL_DELIVER ,IP_DEFRAG_CALL_RA_CHAIN ,IP_DEFRAG_CONNTRACK_IN , + __IP_DEFRAG_CONNTRACK_IN_END =IP_DEFRAG_CONNTRACK_IN +0xffff ,IP_DEFRAG_CONNTRACK_OUT , + __IP_DEFRAG_CONNTRACK_OUT_END =IP_DEFRAG_CONNTRACK_OUT +0xffff ,IP_DEFRAG_CONNTRACK_BRIDGE_IN , + __IP_DEFRAG_CONNTRACK_BRIDGE_IN =IP_DEFRAG_CONNTRACK_BRIDGE_IN +0xffff ,IP_DEFRAG_VS_IN ,IP_DEFRAG_VS_OUT ,IP_DEFRAG_VS_FWD
include/net/ipv6.h +3 -0
@@ -355,8 +355,11 @@ struct inet_frag_queue;enum ip6_defrag_users {IP6_DEFRAG_LOCAL_DELIVER ,IP6_DEFRAG_CONNTRACK_IN , + __IP6_DEFRAG_CONNTRACK_IN =IP6_DEFRAG_CONNTRACK_IN +0xffff ,IP6_DEFRAG_CONNTRACK_OUT , + __IP6_DEFRAG_CONNTRACK_OUT =IP6_DEFRAG_CONNTRACK_OUT +0xffff ,IP6_DEFRAG_CONNTRACK_BRIDGE_IN , + __IP6_DEFRAG_CONNTRACK_BRIDGE_IN =IP6_DEFRAG_CONNTRACK_BRIDGE_IN +0xffff , };struct ip6_create_arg {
include/net/netfilter/nf_conntrack.h +3 -2
@@ -198,7 +198,8 @@ extern void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nullextern void nf_ct_free_hashtable (void *hash,int vmalloced,unsigned int size);extern struct nf_conntrack_tuple_hash * -__nf_conntrack_find (struct net *net,const struct nf_conntrack_tuple *tuple); +__nf_conntrack_find (struct net *net,u16 zone, +const struct nf_conntrack_tuple *tuple);extern void nf_conntrack_hash_insert (struct nf_conn *ct);extern void nf_ct_delete_from_lists (struct nf_conn *ct);
@@ -267,7 +268,7 @@ extern void nf_ct_iterate_cleanup(struct net *net, int (*iter)(struct nf_conn *i, void *data), void *data);extern void nf_conntrack_free (struct nf_conn *ct);extern struct nf_conn * -nf_conntrack_alloc (struct net *net, +nf_conntrack_alloc (struct net *net,u16 zone,const struct nf_conntrack_tuple *orig,const struct nf_conntrack_tuple *repl,gfp_t gfp);
include/net/netfilter/nf_conntrack_core.h +2 -1
@@ -49,7 +49,8 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,/* Find a connection corresponding to a tuple. */ extern struct nf_conntrack_tuple_hash * -nf_conntrack_find_get (struct net *net,const struct nf_conntrack_tuple *tuple); +nf_conntrack_find_get (struct net *net,u16 zone, +const struct nf_conntrack_tuple *tuple);extern int __nf_conntrack_confirm (struct sk_buff *skb);
include/net/netfilter/nf_conntrack_expect.h +6 -3
@@ -77,13 +77,16 @@ int nf_conntrack_expect_init(struct net *net);void nf_conntrack_expect_fini (struct net *net);struct nf_conntrack_expect * -__nf_ct_expect_find (struct net *net,const struct nf_conntrack_tuple *tuple); +__nf_ct_expect_find (struct net *net,u16 zone, +const struct nf_conntrack_tuple *tuple);struct nf_conntrack_expect * -nf_ct_expect_find_get (struct net *net,const struct nf_conntrack_tuple *tuple); +nf_ct_expect_find_get (struct net *net,u16 zone, +const struct nf_conntrack_tuple *tuple);struct nf_conntrack_expect * -nf_ct_find_expectation (struct net *net,const struct nf_conntrack_tuple *tuple); +nf_ct_find_expectation (struct net *net,u16 zone, +const struct nf_conntrack_tuple *tuple);void nf_ct_unlink_expect (struct nf_conntrack_expect *exp);void nf_ct_remove_expectations (struct nf_conn *ct);
include/net/netfilter/nf_conntrack_extend.h +2 -0
@@ -8,6 +8,7 @@ enum nf_ct_ext_id {NF_CT_EXT_NAT ,NF_CT_EXT_ACCT ,NF_CT_EXT_ECACHE , +NF_CT_EXT_ZONE , NF_CT_EXT_NUM, };
@@ -15,6 +16,7 @@ enum nf_ct_ext_id {#define NF_CT_EXT_NAT_TYPE struct nf_conn_nat#define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter#define NF_CT_EXT_ECACHE_TYPE struct nf_conntrack_ecache +#define NF_CT_EXT_ZONE_TYPE struct nf_conntrack_zone/* Extensions: optional stuff which isn't permanently in struct. */ struct nf_ct_ext {
include/net/netfilter/nf_conntrack_zones.h new file +21 -0
@@ -0,0 +1,21 @@ +#ifndef _NF_CONNTRACK_ZONES_H +#define _NF_CONNTRACK_ZONES_H + +#include <net/netfilter/nf_conntrack_extend.h> + +struct nf_conntrack_zone { +u16 id; +}; + +static inline u16 nf_ct_zone (const struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_ZONES +struct nf_conntrack_zone *nf_ct_zone; + nf_ct_zone =nf_ct_ext_find (ct,NF_CT_EXT_ZONE ); +if (nf_ct_zone) +return nf_ct_zone->id; +#endif +return 0 ; +} + +#endif /* _NF_CONNTRACK_ZONES_H */
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +1 -1
@@ -266,7 +266,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)return -EINVAL ; } - h =nf_conntrack_find_get (sock_net (sk), &tuple); + h =nf_conntrack_find_get (sock_net (sk),0 , &tuple);if (h) {struct sockaddr_in sin;struct nf_conn *ct =nf_ct_tuplehash_to_ctrack (h);
net/ipv4/netfilter/nf_conntrack_proto_icmp.c +5 -3
@@ -18,6 +18,7 @@#include <net/netfilter/nf_conntrack_tuple.h> #include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack_core.h> +#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/nf_log.h> static unsigned int nf_ct_icmp_timeout__read_mostly =30 *HZ ;
@@ -114,13 +115,14 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,/* Returns conntrack if it dealt with ICMP, and filled in skb fields */ static int -icmp_error_message (struct net *net,struct sk_buff *skb, +icmp_error_message (struct net *net,struct nf_conn *tmpl,struct sk_buff *skb,enum ip_conntrack_info *ctinfo,unsigned int hooknum) {struct nf_conntrack_tuple innertuple, origtuple;const struct nf_conntrack_l4proto *innerproto;const struct nf_conntrack_tuple_hash *h; +u16 zone = tmpl ?nf_ct_zone (tmpl) :0 ;NF_CT_ASSERT (skb->nfct ==NULL );
@@ -146,7 +148,7 @@ icmp_error_message(struct net *net, struct sk_buff *skb, *ctinfo =IP_CT_RELATED ; - h =nf_conntrack_find_get (net, &innertuple); + h =nf_conntrack_find_get (net, zone, &innertuple);if (!h) {pr_debug ("icmp_error_message: no match\n" );return -NF_ACCEPT ;
@@ -209,7 +211,7 @@ icmp_error(struct net *net, struct nf_conn *tmpl, icmph->type != ICMP_REDIRECT)return NF_ACCEPT ; -return icmp_error_message (net, skb, ctinfo, hooknum); +return icmp_error_message (net, tmpl, skb, ctinfo, hooknum); }#if defined(CONFIG_NF_CT_NETLINK ) || defined(CONFIG_NF_CT_NETLINK_MODULE )
net/ipv4/netfilter/nf_defrag_ipv4.c +6 -3
@@ -16,6 +16,7 @@#include <linux/netfilter_bridge.h> #include <linux/netfilter_ipv4.h> +#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/ipv4/nf_defrag_ipv4.h> /* Returns new sk_buff, or NULL */
@@ -38,15 +39,17 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)static enum ip_defrag_users nf_ct_defrag_user (unsigned int hooknum,struct sk_buff *skb) { +u16 zone =0 ; +#ifdef CONFIG_BRIDGE_NETFILTER if (skb->nf_bridge && skb->nf_bridge->mask &BRNF_NF_BRIDGE_PREROUTING ) -return IP_DEFRAG_CONNTRACK_BRIDGE_IN ; +return IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone;#endif if (hooknum ==NF_INET_PRE_ROUTING ) -return IP_DEFRAG_CONNTRACK_IN ; +return IP_DEFRAG_CONNTRACK_IN + zone;else -return IP_DEFRAG_CONNTRACK_OUT ; +return IP_DEFRAG_CONNTRACK_OUT + zone; } static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
net/ipv4/netfilter/nf_nat_core.c +13 -10
@@ -30,6 +30,7 @@#include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_l3proto.h> #include <net/netfilter/nf_conntrack_l4proto.h> +#include <net/netfilter/nf_conntrack_zones.h> static DEFINE_SPINLOCK (nf_nat_lock);
@@ -72,13 +73,13 @@ EXPORT_SYMBOL_GPL(nf_nat_proto_put);/* We keep an extra hash for each conntrack, for fast searching. */ static inline unsigned int -hash_by_src (const struct nf_conntrack_tuple *tuple) +hash_by_src (const struct nf_conntrack_tuple *tuple,u16 zone) {unsigned int hash;/* Original src, to ensure we map it consistently if poss. */ hash =jhash_3words ((__force u32 )tuple->src.u3.ip, - (__force u32 )tuple->src.u.all, + (__force u32 )tuple->src.u.all ^ zone, tuple->dst.protonum,0 );return ((u64 )hash * nf_nat_htable_size) >>32 ; }
@@ -142,12 +143,12 @@ same_src(const struct nf_conn *ct,/* Only called for SRC manip */ static int -find_appropriate_src (struct net *net, +find_appropriate_src (struct net *net,u16 zone,const struct nf_conntrack_tuple *tuple,struct nf_conntrack_tuple *result,const struct nf_nat_range *range) { -unsigned int h =hash_by_src (tuple); +unsigned int h =hash_by_src (tuple, zone);const struct nf_conn_nat *nat;const struct nf_conn *ct;const struct hlist_node *n;
@@ -155,7 +156,7 @@ find_appropriate_src(struct net *net,rcu_read_lock ();hlist_for_each_entry_rcu (nat, n, &net->ipv4.nat_bysource[h], bysource) { ct = nat->ct; -if (same_src (ct, tuple)) { +if (same_src (ct, tuple) &&nf_ct_zone (ct) == zone) {/* Copy source part from reply tuple. */ nf_ct_invert_tuplepr (result, &ct->tuplehash[IP_CT_DIR_REPLY ].tuple);
@@ -178,7 +179,7 @@ find_appropriate_src(struct net *net,the ip with the lowest src-ip/dst-ip/proto usage. */ static void -find_best_ips_proto (struct nf_conntrack_tuple *tuple, +find_best_ips_proto (u16 zone,struct nf_conntrack_tuple *tuple,const struct nf_nat_range *range,const struct nf_conn *ct,enum nf_nat_manip_type maniptype)
@@ -212,7 +213,7 @@ find_best_ips_proto(struct nf_conntrack_tuple *tuple, maxip =ntohl (range->max_ip); j =jhash_2words ((__force u32 )tuple->src.u3.ip, range->flags &IP_NAT_RANGE_PERSISTENT ? -0 : (__force u32 )tuple->dst.u3.ip,0 ); +0 : (__force u32 )tuple->dst.u3.ip ^ zone,0 ); j = ((u64 )j * (maxip - minip +1 )) >>32 ; *var_ipp =htonl (minip + j); }
@@ -232,6 +233,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, {struct net *net =nf_ct_net (ct);const struct nf_nat_protocol *proto; +u16 zone =nf_ct_zone (ct);/* 1) If this srcip/proto/src-proto-part is currently mapped, and that same mapping gives a unique tuple within the given
@@ -242,7 +244,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,manips not an issue. */ if (maniptype ==IP_NAT_MANIP_SRC && !(range->flags &IP_NAT_RANGE_PROTO_RANDOM )) { -if (find_appropriate_src (net, orig_tuple, tuple, range)) { +if (find_appropriate_src (net, zone, orig_tuple, tuple, range)) {pr_debug ("get_unique_tuple: Found current src map\n" );if (!nf_nat_used_tuple (tuple, ct))return ;
@@ -252,7 +254,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,/* 2) Select the least-used IP/proto combination in the given range. */ *tuple = *orig_tuple; -find_best_ips_proto (tuple, range, ct, maniptype); +find_best_ips_proto (zone, tuple, range, ct, maniptype);/* 3) The per-protocol part of the manip is made to map into the range to make a unique tuple. */
@@ -330,7 +332,8 @@ nf_nat_setup_info(struct nf_conn *ct,if (have_to_hash) {unsigned int srchash; - srchash =hash_by_src (&ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple); + srchash =hash_by_src (&ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple, +nf_ct_zone (ct));spin_lock_bh (&nf_nat_lock);/* nf_conntrack_alter_reply might re-allocate exntension aera */ nat =nfct_nat (ct);
net/ipv4/netfilter/nf_nat_pptp.c +2 -1
@@ -25,6 +25,7 @@#include <net/netfilter/nf_nat_rule.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_expect.h> +#include <net/netfilter/nf_conntrack_zones.h> #include <linux/netfilter/nf_conntrack_proto_gre.h> #include <linux/netfilter/nf_conntrack_pptp.h>
@@ -74,7 +75,7 @@ static void pptp_nat_expected(struct nf_conn *ct,pr_debug ("trying to unexpect other dir: " );nf_ct_dump_tuple_ip (&t); - other_exp =nf_ct_expect_find_get (net, &t); + other_exp =nf_ct_expect_find_get (net,nf_ct_zone (ct), &t);if (other_exp) {nf_ct_unexpect_related (other_exp);nf_ct_expect_put (other_exp);
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +6 -3
@@ -27,6 +27,7 @@#include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack_l3proto.h> #include <net/netfilter/nf_conntrack_core.h> +#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> #include <net/netfilter/nf_log.h>
@@ -191,15 +192,17 @@ out:static enum ip6_defrag_users nf_ct6_defrag_user (unsigned int hooknum,struct sk_buff *skb) { +u16 zone =0 ; +#ifdef CONFIG_BRIDGE_NETFILTER if (skb->nf_bridge && skb->nf_bridge->mask &BRNF_NF_BRIDGE_PREROUTING ) -return IP6_DEFRAG_CONNTRACK_BRIDGE_IN ; +return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;#endif if (hooknum ==NF_INET_PRE_ROUTING ) -return IP6_DEFRAG_CONNTRACK_IN ; +return IP6_DEFRAG_CONNTRACK_IN + zone;else -return IP6_DEFRAG_CONNTRACK_OUT ; +return IP6_DEFRAG_CONNTRACK_OUT + zone; }
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +5 -3
@@ -23,6 +23,7 @@#include <net/netfilter/nf_conntrack_tuple.h> #include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack_core.h> +#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> #include <net/netfilter/nf_log.h>
@@ -128,7 +129,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, } static int -icmpv6_error_message(struct net *net, +icmpv6_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, unsigned int icmp6off, enum ip_conntrack_info *ctinfo,
@@ -137,6 +138,7 @@ icmpv6_error_message(struct net *net,struct nf_conntrack_tuple intuple, origtuple;const struct nf_conntrack_tuple_hash *h;const struct nf_conntrack_l4proto *inproto; +u16 zone = tmpl ?nf_ct_zone (tmpl) :0 ;NF_CT_ASSERT (skb->nfct ==NULL );
@@ -163,7 +165,7 @@ icmpv6_error_message(struct net *net, *ctinfo =IP_CT_RELATED ; - h =nf_conntrack_find_get (net, &intuple); + h =nf_conntrack_find_get (net, zone, &intuple);if (!h) {pr_debug ("icmpv6_error: no match\n" );return -NF_ACCEPT ;
@@ -216,7 +218,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl,if (icmp6h->icmp6_type >=128 )return NF_ACCEPT ; -return icmpv6_error_message (net, skb, dataoff, ctinfo, hooknum); +return icmpv6_error_message (net, tmpl, skb, dataoff, ctinfo, hooknum); }#if defined(CONFIG_NF_CT_NETLINK ) || defined(CONFIG_NF_CT_NETLINK_MODULE )
net/netfilter/Kconfig +9 -0
@@ -83,6 +83,15 @@ config NF_CONNTRACK_SECMARK If unsure, say 'N'. +config NF_CONNTRACK_ZONES + bool 'Connection tracking zones' + help + This option enables support for connection tracking zones. + Normally, each connection needs to have a unique identity. + Connection tracking zones allow to have multiple connections + using the same identity, as long as they are contained in + different zones. + config NF_CONNTRACK_EVENTS bool "Connection tracking events" depends on NETFILTER_ADVANCED
net/netfilter/nf_conntrack_core.c +82 -27
298 lines not on this page · raw message
net/netfilter/nf_conntrack_expect.c +14 -7
@@ -27,6 +27,7 @@#include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_tuple.h> +#include <net/netfilter/nf_conntrack_zones.h> unsigned int nf_ct_expect_hsize__read_mostly ;EXPORT_SYMBOL_GPL (nf_ct_expect_hsize);
@@ -84,7 +85,8 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple }struct nf_conntrack_expect * -__nf_ct_expect_find (struct net *net,const struct nf_conntrack_tuple *tuple) +__nf_ct_expect_find (struct net *net,u16 zone, +const struct nf_conntrack_tuple *tuple) {struct nf_conntrack_expect *i;struct hlist_node *n;
@@ -95,7 +97,8 @@ __nf_ct_expect_find(struct net *net, const struct nf_conntrack_tuple *tuple) h =nf_ct_expect_dst_hash (tuple);hlist_for_each_entry_rcu (i, n, &net->ct.expect_hash[h], hnode) { -if (nf_ct_tuple_mask_cmp (tuple, &i->tuple, &i->mask)) +if (nf_ct_tuple_mask_cmp (tuple, &i->tuple, &i->mask) && +nf_ct_zone (i->master) == zone)return i; }return NULL ;
@@ -104,12 +107,13 @@ EXPORT_SYMBOL_GPL(__nf_ct_expect_find);/* Just find a expectation corresponding to a tuple. */ struct nf_conntrack_expect * -nf_ct_expect_find_get (struct net *net,const struct nf_conntrack_tuple *tuple) +nf_ct_expect_find_get (struct net *net,u16 zone, +const struct nf_conntrack_tuple *tuple) {struct nf_conntrack_expect *i;rcu_read_lock (); - i =__nf_ct_expect_find (net, tuple); + i =__nf_ct_expect_find (net, zone, tuple);if (i && !atomic_inc_not_zero (&i->use)) i =NULL ;rcu_read_unlock ();
@@ -121,7 +125,8 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);/* If an expectation for this connection is found, it gets delete from * global list then returned. */ struct nf_conntrack_expect * -nf_ct_find_expectation (struct net *net,const struct nf_conntrack_tuple *tuple) +nf_ct_find_expectation (struct net *net,u16 zone, +const struct nf_conntrack_tuple *tuple) {struct nf_conntrack_expect *i, *exp =NULL ;struct hlist_node *n;
@@ -133,7 +138,8 @@ nf_ct_find_expectation(struct net *net, const struct nf_conntrack_tuple *tuple) h =nf_ct_expect_dst_hash (tuple);hlist_for_each_entry (i, n, &net->ct.expect_hash[h], hnode) {if (!(i->flags &NF_CT_EXPECT_INACTIVE ) && -nf_ct_tuple_mask_cmp (tuple, &i->tuple, &i->mask)) { +nf_ct_tuple_mask_cmp (tuple, &i->tuple, &i->mask) && +nf_ct_zone (i->master) == zone) { exp = i;break ; }
@@ -204,7 +210,8 @@ static inline int expect_matches(const struct nf_conntrack_expect *a, {return a->master == b->master && a->class == b->class &&nf_ct_tuple_equal (&a->tuple, &b->tuple) && -nf_ct_tuple_mask_equal (&a->mask, &b->mask); +nf_ct_tuple_mask_equal (&a->mask, &b->mask) && +nf_ct_zone (a->master) ==nf_ct_zone (b->master); }/* Generally a bad idea to call this: could have matched already. */
net/netfilter/nf_conntrack_h323_main.c +2 -1
@@ -29,6 +29,7 @@#include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_ecache.h> #include <net/netfilter/nf_conntrack_helper.h> +#include <net/netfilter/nf_conntrack_zones.h> #include <linux/netfilter/nf_conntrack_h323.h> /* Parameters */
@@ -1216,7 +1217,7 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, tuple.dst.u.tcp.port = port; tuple.dst.protonum =IPPROTO_TCP ; - exp =__nf_ct_expect_find (net, &tuple); + exp =__nf_ct_expect_find (net,nf_ct_zone (ct), &tuple);if (exp && exp->master == ct)return exp;return NULL ;
net/netfilter/nf_conntrack_netlink.c +10 -10
@@ -796,7 +796,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,if (err <0 )return err; - h =nf_conntrack_find_get (net, &tuple); + h =nf_conntrack_find_get (net,0 , &tuple);if (!h)return -ENOENT ;
@@ -857,7 +857,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,if (err <0 )return err; - h =nf_conntrack_find_get (net, &tuple); + h =nf_conntrack_find_get (net,0 , &tuple);if (!h)return -ENOENT ;
@@ -1194,7 +1194,7 @@ ctnetlink_create_conntrack(struct net *net,int err = -EINVAL ;struct nf_conntrack_helper *helper; - ct =nf_conntrack_alloc (net, otuple, rtuple,GFP_ATOMIC ); + ct =nf_conntrack_alloc (net,0 , otuple, rtuple,GFP_ATOMIC );if (IS_ERR (ct))return ERR_PTR (-ENOMEM );
@@ -1298,7 +1298,7 @@ ctnetlink_create_conntrack(struct net *net,if (err <0 ) goto err2; - master_h =nf_conntrack_find_get (net, &master); + master_h =nf_conntrack_find_get (net,0 , &master);if (master_h ==NULL ) { err = -ENOENT ; goto err2;
@@ -1347,9 +1347,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,spin_lock_bh (&nf_conntrack_lock);if (cda[CTA_TUPLE_ORIG ]) - h =__nf_conntrack_find (net, &otuple); + h =__nf_conntrack_find (net,0 , &otuple);else if (cda[CTA_TUPLE_REPLY ]) - h =__nf_conntrack_find (net, &rtuple); + h =__nf_conntrack_find (net,0 , &rtuple);if (h ==NULL ) { err = -ENOENT ;
@@ -1678,7 +1678,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,if (err <0 )return err; - exp =nf_ct_expect_find_get (net, &tuple); + exp =nf_ct_expect_find_get (net,0 , &tuple);if (!exp)return -ENOENT ;
@@ -1734,7 +1734,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,return err;/* bump usage count to 2 */ - exp =nf_ct_expect_find_get (net, &tuple); + exp =nf_ct_expect_find_get (net,0 , &tuple);if (!exp)return -ENOENT ;
@@ -1819,7 +1819,7 @@ ctnetlink_create_expect(struct net *net, const struct nlattr * const cda[],return err;/* Look for master conntrack of this expectation */ - h =nf_conntrack_find_get (net, &master_tuple); + h =nf_conntrack_find_get (net,0 , &master_tuple);if (!h)return -ENOENT ; ct =nf_ct_tuplehash_to_ctrack (h);
@@ -1876,7 +1876,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,return err;spin_lock_bh (&nf_conntrack_lock); - exp =__nf_ct_expect_find (net, &tuple); + exp =__nf_ct_expect_find (net,0 , &tuple);if (!exp) {spin_unlock_bh (&nf_conntrack_lock);
net/netfilter/nf_conntrack_pptp.c +8 -6
@@ -28,6 +28,7 @@#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_helper.h> +#include <net/netfilter/nf_conntrack_zones.h> #include <linux/netfilter/nf_conntrack_proto_gre.h> #include <linux/netfilter/nf_conntrack_pptp.h>
@@ -123,7 +124,7 @@ static void pptp_expectfn(struct nf_conn *ct,pr_debug ("trying to unexpect other dir: " );nf_ct_dump_tuple (&inv_t); - exp_other =nf_ct_expect_find_get (net, &inv_t); + exp_other =nf_ct_expect_find_get (net,nf_ct_zone (ct), &inv_t);if (exp_other) {/* delete other expectation. */ pr_debug ("found\n" );
@@ -136,17 +137,18 @@ static void pptp_expectfn(struct nf_conn *ct,rcu_read_unlock (); } -static int destroy_sibling_or_exp (struct net *net, +static int destroy_sibling_or_exp (struct net *net,struct nf_conn *ct,const struct nf_conntrack_tuple *t) {const struct nf_conntrack_tuple_hash *h;struct nf_conntrack_expect *exp;struct nf_conn *sibling; +u16 zone =nf_ct_zone (ct);pr_debug ("trying to timeout ct or exp for tuple " );nf_ct_dump_tuple (t); - h =nf_conntrack_find_get (net, t); + h =nf_conntrack_find_get (net, zone, t);if (h) { sibling =nf_ct_tuplehash_to_ctrack (h);pr_debug ("setting timeout of conntrack %p to 0\n" , sibling);
@@ -157,7 +159,7 @@ static int destroy_sibling_or_exp(struct net *net,nf_ct_put (sibling);return 1 ; }else { - exp =nf_ct_expect_find_get (net, t); + exp =nf_ct_expect_find_get (net, zone, t);if (exp) {pr_debug ("unexpect_related of expect %p\n" , exp);nf_ct_unexpect_related (exp);
@@ -182,7 +184,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct) t.dst.protonum =IPPROTO_GRE ; t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id; t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id; -if (!destroy_sibling_or_exp (net, &t)) +if (!destroy_sibling_or_exp (net, ct, &t))pr_debug ("failed to timeout original pns->pac ct/exp\n" );/* try reply (pac->pns) tuple */
@@ -190,7 +192,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct) t.dst.protonum =IPPROTO_GRE ; t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id; t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id; -if (!destroy_sibling_or_exp (net, &t)) +if (!destroy_sibling_or_exp (net, ct, &t))pr_debug ("failed to timeout reply pac->pns ct/exp\n" ); }
net/netfilter/nf_conntrack_sip.c +2 -1
@@ -22,6 +22,7 @@#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_helper.h> +#include <net/netfilter/nf_conntrack_zones.h> #include <linux/netfilter/nf_conntrack_sip.h> MODULE_LICENSE ("GPL" );
@@ -777,7 +778,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,rcu_read_lock (); do { - exp = __nf_ct_expect_find(net, &tuple); + exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); if (!exp || exp->master == ct || nfct_help(exp->master)->helper != nfct_help(ct)->helper ||
net/netfilter/nf_conntrack_standalone.c +6 -0
@@ -26,6 +26,7 @@#include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_acct.h> +#include <net/netfilter/nf_conntrack_zones.h> MODULE_LICENSE ("GPL" );
@@ -171,6 +172,11 @@ static int ct_seq_show(struct seq_file *s, void *v) goto release;#endif +#ifdef CONFIG_NF_CONNTRACK_ZONES +if (seq_printf (s,"zone=%u " ,nf_ct_zone (ct))) + goto release; +#endif +if (seq_printf (s,"use=%u\n" ,atomic_read (&ct->ct_general.use))) goto release;
net/netfilter/xt_CT.c +6 -1
@@ -16,6 +16,7 @@#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_ecache.h> +#include <net/netfilter/nf_conntrack_zones.h> static unsigned int xt_ct_target (struct sk_buff *skb,const struct xt_target_param *par)
@@ -57,11 +58,15 @@ static bool xt_ct_tg_check(const struct xt_tgchk_param *par)struct nf_conn *ct;u8 proto; +#ifndef CONFIG_NF_CONNTRACK_ZONES +if (info->zone) + goto err1; +#endif if (nf_ct_l3proto_try_module_get (par->family) <0 ) goto err1;memset (&t,0 ,sizeof (t)); - ct =nf_conntrack_alloc (par->net, &t, &t,GFP_KERNEL ); + ct =nf_conntrack_alloc (par->net, info->zone, &t, &t,GFP_KERNEL );if (IS_ERR (ct)) goto err2;
net/netfilter/xt_connlimit.c +1 -1
@@ -114,7 +114,7 @@ static int count_them(struct net *net,/* check the saved connections */ list_for_each_entry_safe (conn, tmp, hash, list) { - found =nf_conntrack_find_get (net, &conn->tuple); + found =nf_conntrack_find_get (net,0 , &conn->tuple); found_ct =NULL ;if (found !=NULL )
Re: [PATCH 08/09]: netfilter: nf_conntrack: add support for "conntrack zones"
Quoted 18 lines · Patrick McHardy
include/linux/netfilter/xt_CT.h +1
-0@@ -5,6 +5,7 @@ struct xt_ct_target_info {u_int32_t ct_events;u_int32_t exp_events;char helper[16 ]; +u_int16_t zone;/* Used internally by the kernel */ struct nf_conn *ct __attribute__((aligned(8)));net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +0
-0
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c getorigdst(struct sock *sk, int optval, void __user *user, int *len) · line 269
Quoted 5 lines
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +1
-1@@ -266,7 +266,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)return -EINVAL ; } - h =nf_conntrack_find_get (sock_net (sk), &tuple); + h =nf_conntrack_find_get (sock_net (sk),0 , &tuple);
I would prefer to avoid literal numbers where doing so meaningful; perhaps we can introduce a symbolic constant NF_CT_GLOBAL_ZONE or similar here.
Re: [PATCH 08/09]: netfilter: nf_conntrack: add support for "conntrack zones"
Quoted 22 lines · Jan Engelhardt
Quoted 21 lines · Patrick McHardy
include/linux/netfilter/xt_CT.h +1
-0@@ -5,6 +5,7 @@ struct xt_ct_target_info {u_int32_t ct_events;u_int32_t exp_events;char helper[16 ]; +u_int16_t zone;/* Used internally by the kernel */ struct nf_conn *ct __attribute__((aligned(8)));net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +0
-0@@ -266,7 +266,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)return -EINVAL ; }
Quoted 6 lines
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c getorigdst(struct sock *sk, int optval, void __user *user, int *len) · line 269
Quoted 2 lines
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +1
-1- h =nf_conntrack_find_get (sock_net (sk), &tuple); + h =nf_conntrack_find_get (sock_net (sk),0 , &tuple);I would prefer to avoid literal numbers where doing so meaningful; perhaps we can introduce a symbolic constant
NF_CT_GLOBAL_ZONEor similar here.
Sure, I'll add that.
PATCH 9/9 : netfilter: ctnetlink: add zone support
In reply to Patrick McHardycommit f38b9023022d819503465f9e74dcfad12d85c8b2
Author: Patrick McHardy <[email protected]> Date: Mon Jan 25 16:21:58 2010 +0100
netfilter: ctnetlink: add zone support
Parse and dump the conntrack zone in ctnetlink.
include/linux/netfilter/nfnetlink_conntrack.h +2 -0
@@ -40,6 +40,7 @@ enum ctattr_type {CTA_NAT_SEQ_ADJ_ORIG ,CTA_NAT_SEQ_ADJ_REPLY ,CTA_SECMARK , +CTA_ZONE , __CTA_MAX };#define CTA_MAX (__CTA_MAX - 1)
@@ -159,6 +160,7 @@ enum ctattr_expect {CTA_EXPECT_TIMEOUT ,CTA_EXPECT_ID ,CTA_EXPECT_HELP_NAME , +CTA_EXPECT_ZONE , __CTA_EXPECT_MAX };#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
net/netfilter/nf_conntrack_netlink.c +73 -19
255 lines not on this page · raw message
Quoted 5 lines · Patrick McHardy
include/linux/netfilter/nf_conntrack_common.h | 22 +++ include/linux/netfilter/nfnetlink_conntrack.h | 2 + include/linux/netfilter/x_tables.h | 2 + include/linux/netfilter/xt_CT.h | 14 ++
Is there anything that prohibits using a little-more descriptive name, like xt_CONNTRACK?
That btw reminds me that, perhaps, we could/should avoid same-name different-case (cf. xt_conntrack) in future, so xt_CONNTRACK would not fly too well.
Quoted 11 lines · Jan Engelhardt
Quoted 4 lines · Patrick McHardy
include/linux/netfilter/nf_conntrack_common.h | 22 +++ include/linux/netfilter/nfnetlink_conntrack.h | 2 + include/linux/netfilter/x_tables.h | 2 + include/linux/netfilter/xt_CT.h | 14 ++Is there anything that prohibits using a little-more descriptive name, like
xt_CONNTRACK?
That btw reminds me that, perhaps, we could/should avoid same-name different-case (cf.xt_conntrack) in future, soxt_CONNTRACKwould not fly too well.
I thought CT is an established term for connection tracking. I don't care much, but I prefer a short name like CT.
Quoted 7 lines · Patrick McHardy
Quoted 6 lines · Jan Engelhardt
Quoted 4 lines · Patrick McHardy
include/linux/netfilter/nf_conntrack_common.h | 22 +++ include/linux/netfilter/nfnetlink_conntrack.h | 2 + include/linux/netfilter/x_tables.h | 2 + include/linux/netfilter/xt_CT.h | 14 ++
Quoted 8 lines
Quoted 5 lines
Is there anything that prohibits using a little-more descriptive name, like
xt_CONNTRACK?
That btw reminds me that, perhaps, we could/should avoid same-name different-case (cf.xt_conntrack) in future, soxt_CONNTRACKwould not fly too well.I thought CT is an established term for connection tracking. I don't care much, but I prefer a short name like CT.
If you go by the "established" argument, I'd point out "counter-terrorists", but ok ;-)
Pablo Neira Ayuso
maintainerHi Patrick,
Sorry for the silence, we're in the exams season since last week and that nuts a lot.
Quoted 7 lines · Patrick McHardy
The following patches contain a new version of the conntrack zones patchset, including a new xtables target to (among other things) assign conntracks to a specific zone, replacing the device attribute used in the previous version.
Quick overview:
Quoted 7 lines
- Patch 1 adds a struct net * parameter to the xtables target parameter structures as preparation for the CT target, which needs to allocate a conntrack entry in the proper namespace
- Patch 2 splits up the
IPCT_STATUSevent as requested by Jozsef. The CT target can be used for selective conntrack event delivery, this allows more fine grained control over the delivered events.
This is indeed interesting.
Quoted 3 lines
- Patch 3 adds selective conntrack event delivery by adding two masks for conntrack and expectation events to struct
nf_conntrack_ecache, which are used to filter out events.
This feature is something that I wanted since time ago. We can reduce the CPU consumption by reducing the amount of events. This is particularly good for ulogd2 and conntrackd.
My experiments showed that the BSF-based filtering does not provide any significant gain from filtering Netlink message in user-space. The problem is that we have to spend cycles building the message which seems to be costly.
AFAICS, this approach has one minor threat since it applies to all processes (I'm sure you're aware of it). I'm fine with this anyway, but maybe we should think of some way to make it per-process at some point? Some netlink unicast-based reporting similar to what NFLOG and NFQUEUE would solve this issue although they are implementing multicast over netlink unicast.
Quoted 15 lines
- Patch 4 fixes ctnetlink to only assign helpers for matching protocols to conntrack entries and fixes expectation deletion by helper name. This is also preparation for the CT target, which can also assign helpers to new connections.
- Patch 5 adds support for conntrack templates, which are specially marked conntrack entries attached to the skb that are used to initialize specific parameters of new connections.
- Patch 6 adds the CT target
- Patch 7 contains preparatory work for assigning conntracks to zones:
the template needs to be passed to L4 ->error handlers for ICMP and ICMPv6 to perform the conntrack lookup in the correct zone
Quoted 6 lines
- Patch 8 adds zone support to
nf_conntrackand the CT target. This works by incorporating a numerical "zone" identifier into the conntrack/NAT hashes and comparing it during lookups.- Patch 9 adds zone support to ctnetlink by dumping and parsing a new
CTA_ZONEattribute that contains the zone ID.
This conntrack zone stuff seems interesting. I'll add support for this to libnetfilter_conntrack. Kudos on you.
Quoted 36 lines · Pablo Neira Ayuso
Hi Patrick,
Sorry for the silence, we're in the exams season since last week and that nuts a lot.
Quoted 7 lines · Patrick McHardy
The following patches contain a new version of the conntrack zones patchset, including a new xtables target to (among other things) assign conntracks to a specific zone, replacing the device attribute used in the previous version.
Quick overview:
Quoted 7 lines
- Patch 1 adds a struct net * parameter to the xtables target parameter structures as preparation for the CT target, which needs to allocate a conntrack entry in the proper namespace
- Patch 2 splits up the
IPCT_STATUSevent as requested by Jozsef. The CT target can be used for selective conntrack event delivery, this allows more fine grained control over the delivered events.This is indeed interesting.
Quoted 3 lines
- Patch 3 adds selective conntrack event delivery by adding two masks for conntrack and expectation events to struct
nf_conntrack_ecache, which are used to filter out events.This feature is something that I wanted since time ago. We can reduce the CPU consumption by reducing the amount of events. This is particularly good for ulogd2 and conntrackd.
My experiments showed that the BSF-based filtering does not provide any significant gain from filtering Netlink message in user-space. The problem is that we have to spend cycles building the message which seems to be costly.
Quoted 6 lines
AFAICS, this approach has one minor threat since it applies to all processes (I'm sure you're aware of it). I'm fine with this anyway, but maybe we should think of some way to make it per-process at some point? Some netlink unicast-based reporting similar to what NFLOG and NFQUEUE would solve this issue although they are implementing multicast over netlink unicast.
The question is whether that would really reduce overhead since we'd like would have to construct messages multiple times ourselves in that case. But yes, it might help.
Quoted 19 lines
Quoted 19 lines
- Patch 4 fixes ctnetlink to only assign helpers for matching protocols to conntrack entries and fixes expectation deletion by helper name. This is also preparation for the CT target, which can also assign helpers to new connections.
- Patch 5 adds support for conntrack templates, which are specially marked conntrack entries attached to the skb that are used to initialize specific parameters of new connections.
- Patch 6 adds the CT target
- Patch 7 contains preparatory work for assigning conntracks to zones:
the template needs to be passed to L4 ->error handlers for ICMP and ICMPv6 to perform the conntrack lookup in the correct zone- Patch 8 adds zone support to
nf_conntrackand the CT target. This works by incorporating a numerical "zone" identifier into the conntrack/NAT hashes and comparing it during lookups.
Quoted 5 lines
Quoted 2 lines
- Patch 9 adds zone support to ctnetlink by dumping and parsing a new
CTA_ZONEattribute that contains the zone ID.This conntrack zone stuff seems interesting. I'll add support for this to
libnetfilter_conntrack. Kudos on you.
Great, thanks. I'll probably post a final version within the next two days.
Quoted 21 lines · Patrick McHardy
Quoted 13 lines · Pablo Neira Ayuso
Quoted 3 lines
- Patch 3 adds selective conntrack event delivery by adding two masks for conntrack and expectation events to struct
nf_conntrack_ecache, which are used to filter out events.This feature is something that I wanted since time ago. We can reduce the CPU consumption by reducing the amount of events. This is particularly good for ulogd2 and conntrackd.
My experiments showed that the BSF-based filtering does not provide any significant gain from filtering Netlink message in user-space. The problem is that we have to spend cycles building the message which seems to be costly.
Quoted 6 lines
AFAICS, this approach has one minor threat since it applies to all processes (I'm sure you're aware of it). I'm fine with this anyway, but maybe we should think of some way to make it per-process at some point? Some netlink unicast-based reporting similar to what NFLOG and NFQUEUE would solve this issue although they are implementing multicast over netlink unicast.
Quoted 3 lines
The question is whether that would really reduce overhead since we'd like would have to construct messages multiple times ourselves in that case. But yes, it might help.
I think the current way is one of the best: the interesting events are selected by CT, sent to userspace and the userspace processes pick the ones they are interested in. Or do I miss something?
Best regards,
Jozsef
-
E-mail : [email protected], [email protected] PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
H-1525 Budapest 114, POB. 49, Hungary