aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-03-16 10:28:09 -0400
committerPatrick McHardy <kaber@trash.net>2009-03-16 10:28:09 -0400
commitf0a3c0869f3b0ef93d9df044e9a41e40086d4c97 (patch)
tree2747803899c206b1c0dc1cd0ac1d3c9f51b7eb3b /net
parente098360f159b3358f085543eb6dc2eb500d6667c (diff)
netfilter: ctnetlink: move event reporting for new entries outside the lock
This patch moves the event reporting outside the lock section. With this patch, the creation and update of entries is homogeneous from the event reporting perspective. Moreover, as the event reporting is done outside the lock section, the netlink broadcast delivery can benefit of the yield() call under congestion. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_conntrack_netlink.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index b67db695d83c..9fb7cf7504fa 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1128,12 +1128,10 @@ ctnetlink_event_report(struct nf_conn *ct, u32 pid, int report)
1128 report); 1128 report);
1129} 1129}
1130 1130
1131static int 1131static struct nf_conn *
1132ctnetlink_create_conntrack(struct nlattr *cda[], 1132ctnetlink_create_conntrack(struct nlattr *cda[],
1133 struct nf_conntrack_tuple *otuple, 1133 struct nf_conntrack_tuple *otuple,
1134 struct nf_conntrack_tuple *rtuple, 1134 struct nf_conntrack_tuple *rtuple,
1135 u32 pid,
1136 int report,
1137 u8 u3) 1135 u8 u3)
1138{ 1136{
1139 struct nf_conn *ct; 1137 struct nf_conn *ct;
@@ -1142,7 +1140,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1142 1140
1143 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_ATOMIC); 1141 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_ATOMIC);
1144 if (IS_ERR(ct)) 1142 if (IS_ERR(ct))
1145 return -ENOMEM; 1143 return ERR_PTR(-ENOMEM);
1146 1144
1147 if (!cda[CTA_TIMEOUT]) 1145 if (!cda[CTA_TIMEOUT])
1148 goto err; 1146 goto err;
@@ -1265,18 +1263,14 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1265 ct->master = master_ct; 1263 ct->master = master_ct;
1266 } 1264 }
1267 1265
1268 nf_conntrack_get(&ct->ct_general);
1269 add_timer(&ct->timeout); 1266 add_timer(&ct->timeout);
1270 nf_conntrack_hash_insert(ct); 1267 nf_conntrack_hash_insert(ct);
1271 rcu_read_unlock(); 1268 rcu_read_unlock();
1272 ctnetlink_event_report(ct, pid, report);
1273 nf_ct_put(ct);
1274
1275 return 0;
1276 1269
1270 return ct;
1277err: 1271err:
1278 nf_conntrack_free(ct); 1272 nf_conntrack_free(ct);
1279 return err; 1273 return ERR_PTR(err);
1280} 1274}
1281 1275
1282static int 1276static int
@@ -1309,14 +1303,25 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1309 1303
1310 if (h == NULL) { 1304 if (h == NULL) {
1311 err = -ENOENT; 1305 err = -ENOENT;
1312 if (nlh->nlmsg_flags & NLM_F_CREATE) 1306 if (nlh->nlmsg_flags & NLM_F_CREATE) {
1313 err = ctnetlink_create_conntrack(cda, 1307 struct nf_conn *ct;
1314 &otuple, 1308
1315 &rtuple, 1309 ct = ctnetlink_create_conntrack(cda, &otuple,
1316 NETLINK_CB(skb).pid, 1310 &rtuple, u3);
1317 nlmsg_report(nlh), 1311 if (IS_ERR(ct)) {
1318 u3); 1312 err = PTR_ERR(ct);
1319 spin_unlock_bh(&nf_conntrack_lock); 1313 goto out_unlock;
1314 }
1315 err = 0;
1316 nf_conntrack_get(&ct->ct_general);
1317 spin_unlock_bh(&nf_conntrack_lock);
1318 ctnetlink_event_report(ct,
1319 NETLINK_CB(skb).pid,
1320 nlmsg_report(nlh));
1321 nf_ct_put(ct);
1322 } else
1323 spin_unlock_bh(&nf_conntrack_lock);
1324
1320 return err; 1325 return err;
1321 } 1326 }
1322 /* implicit 'else' */ 1327 /* implicit 'else' */