diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-11-17 10:00:40 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2008-11-17 10:00:40 -0500 |
commit | 528a3a6f67d4fbe708b9f306be194e78b29e8d7a (patch) | |
tree | 7699b945859a1c2f2457687aabbd6aefea24b7a3 | |
parent | bfe2967735e0e0f650bf698a5683db2b6cf4cfd7 (diff) |
netfilter: ctnetlink: get rid of module refcounting in ctnetlink
This patch replaces the unnecessary module refcounting with
the read-side locks. With this patch, all the dump and fill_info
function are called under the RCU read lock.
Based on a patch from Fabian Hugelshofer.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index d87a9398a781..49a04fa0becc 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -105,16 +105,14 @@ ctnetlink_dump_tuples(struct sk_buff *skb, | |||
105 | struct nf_conntrack_l3proto *l3proto; | 105 | struct nf_conntrack_l3proto *l3proto; |
106 | struct nf_conntrack_l4proto *l4proto; | 106 | struct nf_conntrack_l4proto *l4proto; |
107 | 107 | ||
108 | l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); | 108 | l3proto = __nf_ct_l3proto_find(tuple->src.l3num); |
109 | ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto); | 109 | ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto); |
110 | nf_ct_l3proto_put(l3proto); | ||
111 | 110 | ||
112 | if (unlikely(ret < 0)) | 111 | if (unlikely(ret < 0)) |
113 | return ret; | 112 | return ret; |
114 | 113 | ||
115 | l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); | 114 | l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum); |
116 | ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto); | 115 | ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto); |
117 | nf_ct_l4proto_put(l4proto); | ||
118 | 116 | ||
119 | return ret; | 117 | return ret; |
120 | } | 118 | } |
@@ -151,11 +149,9 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) | |||
151 | struct nlattr *nest_proto; | 149 | struct nlattr *nest_proto; |
152 | int ret; | 150 | int ret; |
153 | 151 | ||
154 | l4proto = nf_ct_l4proto_find_get(nf_ct_l3num(ct), nf_ct_protonum(ct)); | 152 | l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); |
155 | if (!l4proto->to_nlattr) { | 153 | if (!l4proto->to_nlattr) |
156 | nf_ct_l4proto_put(l4proto); | ||
157 | return 0; | 154 | return 0; |
158 | } | ||
159 | 155 | ||
160 | nest_proto = nla_nest_start(skb, CTA_PROTOINFO | NLA_F_NESTED); | 156 | nest_proto = nla_nest_start(skb, CTA_PROTOINFO | NLA_F_NESTED); |
161 | if (!nest_proto) | 157 | if (!nest_proto) |
@@ -163,14 +159,11 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) | |||
163 | 159 | ||
164 | ret = l4proto->to_nlattr(skb, nest_proto, ct); | 160 | ret = l4proto->to_nlattr(skb, nest_proto, ct); |
165 | 161 | ||
166 | nf_ct_l4proto_put(l4proto); | ||
167 | |||
168 | nla_nest_end(skb, nest_proto); | 162 | nla_nest_end(skb, nest_proto); |
169 | 163 | ||
170 | return ret; | 164 | return ret; |
171 | 165 | ||
172 | nla_put_failure: | 166 | nla_put_failure: |
173 | nf_ct_l4proto_put(l4proto); | ||
174 | return -1; | 167 | return -1; |
175 | } | 168 | } |
176 | 169 | ||
@@ -184,7 +177,6 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) | |||
184 | if (!help) | 177 | if (!help) |
185 | return 0; | 178 | return 0; |
186 | 179 | ||
187 | rcu_read_lock(); | ||
188 | helper = rcu_dereference(help->helper); | 180 | helper = rcu_dereference(help->helper); |
189 | if (!helper) | 181 | if (!helper) |
190 | goto out; | 182 | goto out; |
@@ -199,11 +191,9 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) | |||
199 | 191 | ||
200 | nla_nest_end(skb, nest_helper); | 192 | nla_nest_end(skb, nest_helper); |
201 | out: | 193 | out: |
202 | rcu_read_unlock(); | ||
203 | return 0; | 194 | return 0; |
204 | 195 | ||
205 | nla_put_failure: | 196 | nla_put_failure: |
206 | rcu_read_unlock(); | ||
207 | return -1; | 197 | return -1; |
208 | } | 198 | } |
209 | 199 | ||
@@ -461,6 +451,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, | |||
461 | nfmsg->version = NFNETLINK_V0; | 451 | nfmsg->version = NFNETLINK_V0; |
462 | nfmsg->res_id = 0; | 452 | nfmsg->res_id = 0; |
463 | 453 | ||
454 | rcu_read_lock(); | ||
464 | nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); | 455 | nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); |
465 | if (!nest_parms) | 456 | if (!nest_parms) |
466 | goto nla_put_failure; | 457 | goto nla_put_failure; |
@@ -517,13 +508,15 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, | |||
517 | && ctnetlink_dump_mark(skb, ct) < 0) | 508 | && ctnetlink_dump_mark(skb, ct) < 0) |
518 | goto nla_put_failure; | 509 | goto nla_put_failure; |
519 | #endif | 510 | #endif |
511 | rcu_read_unlock(); | ||
520 | 512 | ||
521 | nlh->nlmsg_len = skb->tail - b; | 513 | nlh->nlmsg_len = skb->tail - b; |
522 | nfnetlink_send(skb, 0, group, 0); | 514 | nfnetlink_send(skb, 0, group, 0); |
523 | return NOTIFY_DONE; | 515 | return NOTIFY_DONE; |
524 | 516 | ||
525 | nlmsg_failure: | ||
526 | nla_put_failure: | 517 | nla_put_failure: |
518 | rcu_read_unlock(); | ||
519 | nlmsg_failure: | ||
527 | kfree_skb(skb); | 520 | kfree_skb(skb); |
528 | return NOTIFY_DONE; | 521 | return NOTIFY_DONE; |
529 | } | 522 | } |
@@ -795,8 +788,10 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
795 | return -ENOMEM; | 788 | return -ENOMEM; |
796 | } | 789 | } |
797 | 790 | ||
791 | rcu_read_lock(); | ||
798 | err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, | 792 | err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, |
799 | IPCTNL_MSG_CT_NEW, 1, ct); | 793 | IPCTNL_MSG_CT_NEW, 1, ct); |
794 | rcu_read_unlock(); | ||
800 | nf_ct_put(ct); | 795 | nf_ct_put(ct); |
801 | if (err <= 0) | 796 | if (err <= 0) |
802 | goto free; | 797 | goto free; |
@@ -1292,16 +1287,14 @@ ctnetlink_exp_dump_mask(struct sk_buff *skb, | |||
1292 | if (!nest_parms) | 1287 | if (!nest_parms) |
1293 | goto nla_put_failure; | 1288 | goto nla_put_failure; |
1294 | 1289 | ||
1295 | l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); | 1290 | l3proto = __nf_ct_l3proto_find(tuple->src.l3num); |
1296 | ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto); | 1291 | ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto); |
1297 | nf_ct_l3proto_put(l3proto); | ||
1298 | 1292 | ||
1299 | if (unlikely(ret < 0)) | 1293 | if (unlikely(ret < 0)) |
1300 | goto nla_put_failure; | 1294 | goto nla_put_failure; |
1301 | 1295 | ||
1302 | l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); | 1296 | l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum); |
1303 | ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto); | 1297 | ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto); |
1304 | nf_ct_l4proto_put(l4proto); | ||
1305 | if (unlikely(ret < 0)) | 1298 | if (unlikely(ret < 0)) |
1306 | goto nla_put_failure; | 1299 | goto nla_put_failure; |
1307 | 1300 | ||
@@ -1408,15 +1401,18 @@ static int ctnetlink_expect_event(struct notifier_block *this, | |||
1408 | nfmsg->version = NFNETLINK_V0; | 1401 | nfmsg->version = NFNETLINK_V0; |
1409 | nfmsg->res_id = 0; | 1402 | nfmsg->res_id = 0; |
1410 | 1403 | ||
1404 | rcu_read_lock(); | ||
1411 | if (ctnetlink_exp_dump_expect(skb, exp) < 0) | 1405 | if (ctnetlink_exp_dump_expect(skb, exp) < 0) |
1412 | goto nla_put_failure; | 1406 | goto nla_put_failure; |
1407 | rcu_read_unlock(); | ||
1413 | 1408 | ||
1414 | nlh->nlmsg_len = skb->tail - b; | 1409 | nlh->nlmsg_len = skb->tail - b; |
1415 | nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); | 1410 | nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); |
1416 | return NOTIFY_DONE; | 1411 | return NOTIFY_DONE; |
1417 | 1412 | ||
1418 | nlmsg_failure: | ||
1419 | nla_put_failure: | 1413 | nla_put_failure: |
1414 | rcu_read_unlock(); | ||
1415 | nlmsg_failure: | ||
1420 | kfree_skb(skb); | 1416 | kfree_skb(skb); |
1421 | return NOTIFY_DONE; | 1417 | return NOTIFY_DONE; |
1422 | } | 1418 | } |
@@ -1520,9 +1516,11 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1520 | if (!skb2) | 1516 | if (!skb2) |
1521 | goto out; | 1517 | goto out; |
1522 | 1518 | ||
1519 | rcu_read_lock(); | ||
1523 | err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, | 1520 | err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, |
1524 | nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, | 1521 | nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, |
1525 | 1, exp); | 1522 | 1, exp); |
1523 | rcu_read_unlock(); | ||
1526 | if (err <= 0) | 1524 | if (err <= 0) |
1527 | goto free; | 1525 | goto free; |
1528 | 1526 | ||