diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2007-09-28 17:43:53 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:53:37 -0400 |
commit | 5faa1f4cb5a1f124f76172d775467f4a9db5b452 (patch) | |
tree | 99b83bd823dd5676cf68d4010a663cbbc529dea6 /net | |
parent | 3583240249ef354760e04ae49bd7b462a638f40c (diff) |
[NETFILTER]: nf_conntrack_netlink: add support to related connections
This patch adds support to relate a connection to an existing master
connection. This patch is used by conntrackd to correctly replicate
related connections.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2abd648f7d6f..9be1826e6cdd 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * (C) 2001 by Jay Schulist <jschlst@samba.org> | 4 | * (C) 2001 by Jay Schulist <jschlst@samba.org> |
5 | * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org> | 5 | * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org> |
6 | * (C) 2003 by Patrick Mchardy <kaber@trash.net> | 6 | * (C) 2003 by Patrick Mchardy <kaber@trash.net> |
7 | * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net> | 7 | * (C) 2005-2007 by Pablo Neira Ayuso <pablo@netfilter.org> |
8 | * | 8 | * |
9 | * Initial connection tracking via netlink development funded and | 9 | * Initial connection tracking via netlink development funded and |
10 | * generally made possible by Network Robots, Inc. (www.networkrobots.com) | 10 | * generally made possible by Network Robots, Inc. (www.networkrobots.com) |
@@ -975,7 +975,8 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[]) | |||
975 | static int | 975 | static int |
976 | ctnetlink_create_conntrack(struct nlattr *cda[], | 976 | ctnetlink_create_conntrack(struct nlattr *cda[], |
977 | struct nf_conntrack_tuple *otuple, | 977 | struct nf_conntrack_tuple *otuple, |
978 | struct nf_conntrack_tuple *rtuple) | 978 | struct nf_conntrack_tuple *rtuple, |
979 | struct nf_conn *master_ct) | ||
979 | { | 980 | { |
980 | struct nf_conn *ct; | 981 | struct nf_conn *ct; |
981 | int err = -EINVAL; | 982 | int err = -EINVAL; |
@@ -1022,6 +1023,10 @@ ctnetlink_create_conntrack(struct nlattr *cda[], | |||
1022 | rcu_assign_pointer(help->helper, helper); | 1023 | rcu_assign_pointer(help->helper, helper); |
1023 | } | 1024 | } |
1024 | 1025 | ||
1026 | /* setup master conntrack: this is a confirmed expectation */ | ||
1027 | if (master_ct) | ||
1028 | ct->master = master_ct; | ||
1029 | |||
1025 | add_timer(&ct->timeout); | 1030 | add_timer(&ct->timeout); |
1026 | nf_conntrack_hash_insert(ct); | 1031 | nf_conntrack_hash_insert(ct); |
1027 | 1032 | ||
@@ -1064,10 +1069,37 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1064 | h = __nf_conntrack_find(&rtuple, NULL); | 1069 | h = __nf_conntrack_find(&rtuple, NULL); |
1065 | 1070 | ||
1066 | if (h == NULL) { | 1071 | if (h == NULL) { |
1072 | struct nf_conntrack_tuple master; | ||
1073 | struct nf_conntrack_tuple_hash *master_h = NULL; | ||
1074 | struct nf_conn *master_ct = NULL; | ||
1075 | |||
1076 | if (cda[CTA_TUPLE_MASTER]) { | ||
1077 | err = ctnetlink_parse_tuple(cda, | ||
1078 | &master, | ||
1079 | CTA_TUPLE_MASTER, | ||
1080 | u3); | ||
1081 | if (err < 0) | ||
1082 | return err; | ||
1083 | |||
1084 | master_h = __nf_conntrack_find(&master, NULL); | ||
1085 | if (master_h == NULL) { | ||
1086 | err = -ENOENT; | ||
1087 | goto out_unlock; | ||
1088 | } | ||
1089 | master_ct = nf_ct_tuplehash_to_ctrack(master_h); | ||
1090 | atomic_inc(&master_ct->ct_general.use); | ||
1091 | } | ||
1092 | |||
1067 | write_unlock_bh(&nf_conntrack_lock); | 1093 | write_unlock_bh(&nf_conntrack_lock); |
1068 | err = -ENOENT; | 1094 | err = -ENOENT; |
1069 | if (nlh->nlmsg_flags & NLM_F_CREATE) | 1095 | if (nlh->nlmsg_flags & NLM_F_CREATE) |
1070 | err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); | 1096 | err = ctnetlink_create_conntrack(cda, |
1097 | &otuple, | ||
1098 | &rtuple, | ||
1099 | master_ct); | ||
1100 | if (err < 0 && master_ct) | ||
1101 | nf_ct_put(master_ct); | ||
1102 | |||
1071 | return err; | 1103 | return err; |
1072 | } | 1104 | } |
1073 | /* implicit 'else' */ | 1105 | /* implicit 'else' */ |
@@ -1081,6 +1113,11 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1081 | err = -EINVAL; | 1113 | err = -EINVAL; |
1082 | goto out_unlock; | 1114 | goto out_unlock; |
1083 | } | 1115 | } |
1116 | /* can't link an existing conntrack to a master */ | ||
1117 | if (cda[CTA_TUPLE_MASTER]) { | ||
1118 | err = -EINVAL; | ||
1119 | goto out_unlock; | ||
1120 | } | ||
1084 | err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), | 1121 | err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), |
1085 | cda); | 1122 | cda); |
1086 | } | 1123 | } |