aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_netlink.c49
1 files changed, 20 insertions, 29 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index cb78aa00399e..cca22d553826 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1128,9 +1128,9 @@ static int
1128ctnetlink_create_conntrack(struct nlattr *cda[], 1128ctnetlink_create_conntrack(struct nlattr *cda[],
1129 struct nf_conntrack_tuple *otuple, 1129 struct nf_conntrack_tuple *otuple,
1130 struct nf_conntrack_tuple *rtuple, 1130 struct nf_conntrack_tuple *rtuple,
1131 struct nf_conn *master_ct,
1132 u32 pid, 1131 u32 pid,
1133 int report) 1132 int report,
1133 u8 u3)
1134{ 1134{
1135 struct nf_conn *ct; 1135 struct nf_conn *ct;
1136 int err = -EINVAL; 1136 int err = -EINVAL;
@@ -1241,7 +1241,22 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1241#endif 1241#endif
1242 1242
1243 /* setup master conntrack: this is a confirmed expectation */ 1243 /* setup master conntrack: this is a confirmed expectation */
1244 if (master_ct) { 1244 if (cda[CTA_TUPLE_MASTER]) {
1245 struct nf_conntrack_tuple master;
1246 struct nf_conntrack_tuple_hash *master_h;
1247 struct nf_conn *master_ct;
1248
1249 err = ctnetlink_parse_tuple(cda, &master, CTA_TUPLE_MASTER, u3);
1250 if (err < 0)
1251 goto err;
1252
1253 master_h = __nf_conntrack_find(&init_net, &master);
1254 if (master_h == NULL) {
1255 err = -ENOENT;
1256 goto err;
1257 }
1258 master_ct = nf_ct_tuplehash_to_ctrack(master_h);
1259 nf_conntrack_get(&master_ct->ct_general);
1245 __set_bit(IPS_EXPECTED_BIT, &ct->status); 1260 __set_bit(IPS_EXPECTED_BIT, &ct->status);
1246 ct->master = master_ct; 1261 ct->master = master_ct;
1247 } 1262 }
@@ -1289,39 +1304,15 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1289 h = __nf_conntrack_find(&init_net, &rtuple); 1304 h = __nf_conntrack_find(&init_net, &rtuple);
1290 1305
1291 if (h == NULL) { 1306 if (h == NULL) {
1292 struct nf_conntrack_tuple master;
1293 struct nf_conntrack_tuple_hash *master_h = NULL;
1294 struct nf_conn *master_ct = NULL;
1295
1296 if (cda[CTA_TUPLE_MASTER]) {
1297 err = ctnetlink_parse_tuple(cda,
1298 &master,
1299 CTA_TUPLE_MASTER,
1300 u3);
1301 if (err < 0)
1302 goto out_unlock;
1303
1304 master_h = __nf_conntrack_find(&init_net, &master);
1305 if (master_h == NULL) {
1306 err = -ENOENT;
1307 goto out_unlock;
1308 }
1309 master_ct = nf_ct_tuplehash_to_ctrack(master_h);
1310 nf_conntrack_get(&master_ct->ct_general);
1311 }
1312
1313 err = -ENOENT; 1307 err = -ENOENT;
1314 if (nlh->nlmsg_flags & NLM_F_CREATE) 1308 if (nlh->nlmsg_flags & NLM_F_CREATE)
1315 err = ctnetlink_create_conntrack(cda, 1309 err = ctnetlink_create_conntrack(cda,
1316 &otuple, 1310 &otuple,
1317 &rtuple, 1311 &rtuple,
1318 master_ct,
1319 NETLINK_CB(skb).pid, 1312 NETLINK_CB(skb).pid,
1320 nlmsg_report(nlh)); 1313 nlmsg_report(nlh),
1314 u3);
1321 spin_unlock_bh(&nf_conntrack_lock); 1315 spin_unlock_bh(&nf_conntrack_lock);
1322 if (err < 0 && master_ct)
1323 nf_ct_put(master_ct);
1324
1325 return err; 1316 return err;
1326 } 1317 }
1327 /* implicit 'else' */ 1318 /* implicit 'else' */