aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-07-08 01:35:21 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:18:01 -0400
commit31f15875c5ad98a13b528aaf19c839e22b43dc9a (patch)
tree3ede173710f42917ed228a2494af3b891a7ff4cf /net
parent5d08ad440feae11b8d6e7599147a8a20ac60f99a (diff)
[NETFILTER]: nf_conntrack_helper/nf_conntrack_netlink: convert to expectation hash
Convert from the global expectation list to the hash table. 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_helper.c21
-rw-r--r--net/netfilter/nf_conntrack_netlink.c79
2 files changed, 58 insertions, 42 deletions
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index fdabf823f8cd..cc8ae7404ac4 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -114,22 +114,25 @@ EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
114 114
115void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) 115void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
116{ 116{
117 unsigned int i;
118 struct nf_conntrack_tuple_hash *h; 117 struct nf_conntrack_tuple_hash *h;
119 struct nf_conntrack_expect *exp, *tmp; 118 struct nf_conntrack_expect *exp;
120 struct hlist_node *n; 119 struct hlist_node *n, *next;
120 unsigned int i;
121 121
122 /* Need write lock here, to delete helper. */ 122 /* Need write lock here, to delete helper. */
123 write_lock_bh(&nf_conntrack_lock); 123 write_lock_bh(&nf_conntrack_lock);
124 list_del(&me->list); 124 list_del(&me->list);
125 125
126 /* Get rid of expectations */ 126 /* Get rid of expectations */
127 list_for_each_entry_safe(exp, tmp, &nf_ct_expect_list, list) { 127 for (i = 0; i < nf_ct_expect_hsize; i++) {
128 struct nf_conn_help *help = nfct_help(exp->master); 128 hlist_for_each_entry_safe(exp, n, next,
129 if ((help->helper == me || exp->helper == me) && 129 &nf_ct_expect_hash[i], hnode) {
130 del_timer(&exp->timeout)) { 130 struct nf_conn_help *help = nfct_help(exp->master);
131 nf_ct_unlink_expect(exp); 131 if ((help->helper == me || exp->helper == me) &&
132 nf_ct_expect_put(exp); 132 del_timer(&exp->timeout)) {
133 nf_ct_unlink_expect(exp);
134 nf_ct_expect_put(exp);
135 }
133 } 136 }
134 } 137 }
135 138
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 65a7ebcf86f6..60af9b6b9e00 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1237,8 +1237,8 @@ nfattr_failure:
1237#endif 1237#endif
1238static int ctnetlink_exp_done(struct netlink_callback *cb) 1238static int ctnetlink_exp_done(struct netlink_callback *cb)
1239{ 1239{
1240 if (cb->args[0]) 1240 if (cb->args[1])
1241 nf_ct_expect_put((struct nf_conntrack_expect *)cb->args[0]); 1241 nf_ct_expect_put((struct nf_conntrack_expect *)cb->args[1]);
1242 return 0; 1242 return 0;
1243} 1243}
1244 1244
@@ -1246,35 +1246,37 @@ static int
1246ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 1246ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1247{ 1247{
1248 struct nf_conntrack_expect *exp, *last; 1248 struct nf_conntrack_expect *exp, *last;
1249 struct list_head *i;
1250 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 1249 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
1250 struct hlist_node *n;
1251 u_int8_t l3proto = nfmsg->nfgen_family; 1251 u_int8_t l3proto = nfmsg->nfgen_family;
1252 1252
1253 read_lock_bh(&nf_conntrack_lock); 1253 read_lock_bh(&nf_conntrack_lock);
1254 last = (struct nf_conntrack_expect *)cb->args[0]; 1254 last = (struct nf_conntrack_expect *)cb->args[1];
1255 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
1255restart: 1256restart:
1256 list_for_each_prev(i, &nf_ct_expect_list) { 1257 hlist_for_each_entry(exp, n, &nf_ct_expect_hash[cb->args[0]],
1257 exp = (struct nf_conntrack_expect *) i; 1258 hnode) {
1258 if (l3proto && exp->tuple.src.l3num != l3proto) 1259 if (l3proto && exp->tuple.src.l3num != l3proto)
1259 continue;
1260 if (cb->args[0]) {
1261 if (exp != last)
1262 continue; 1260 continue;
1263 cb->args[0] = 0; 1261 if (cb->args[1]) {
1262 if (exp != last)
1263 continue;
1264 cb->args[1] = 0;
1265 }
1266 if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
1267 cb->nlh->nlmsg_seq,
1268 IPCTNL_MSG_EXP_NEW,
1269 1, exp) < 0) {
1270 atomic_inc(&exp->use);
1271 cb->args[1] = (unsigned long)exp;
1272 goto out;
1273 }
1264 } 1274 }
1265 if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid, 1275 if (cb->args[1]) {
1266 cb->nlh->nlmsg_seq, 1276 cb->args[1] = 0;
1267 IPCTNL_MSG_EXP_NEW, 1277 goto restart;
1268 1, exp) < 0) {
1269 atomic_inc(&exp->use);
1270 cb->args[0] = (unsigned long)exp;
1271 goto out;
1272 } 1278 }
1273 } 1279 }
1274 if (cb->args[0]) {
1275 cb->args[0] = 0;
1276 goto restart;
1277 }
1278out: 1280out:
1279 read_unlock_bh(&nf_conntrack_lock); 1281 read_unlock_bh(&nf_conntrack_lock);
1280 if (last) 1282 if (last)
@@ -1354,11 +1356,13 @@ static int
1354ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, 1356ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1355 struct nlmsghdr *nlh, struct nfattr *cda[]) 1357 struct nlmsghdr *nlh, struct nfattr *cda[])
1356{ 1358{
1357 struct nf_conntrack_expect *exp, *tmp; 1359 struct nf_conntrack_expect *exp;
1358 struct nf_conntrack_tuple tuple; 1360 struct nf_conntrack_tuple tuple;
1359 struct nf_conntrack_helper *h; 1361 struct nf_conntrack_helper *h;
1360 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 1362 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
1363 struct hlist_node *n, *next;
1361 u_int8_t u3 = nfmsg->nfgen_family; 1364 u_int8_t u3 = nfmsg->nfgen_family;
1365 unsigned int i;
1362 int err; 1366 int err;
1363 1367
1364 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) 1368 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
@@ -1390,6 +1394,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1390 nf_ct_expect_put(exp); 1394 nf_ct_expect_put(exp);
1391 } else if (cda[CTA_EXPECT_HELP_NAME-1]) { 1395 } else if (cda[CTA_EXPECT_HELP_NAME-1]) {
1392 char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]); 1396 char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
1397 struct nf_conn_help *m_help;
1393 1398
1394 /* delete all expectations for this helper */ 1399 /* delete all expectations for this helper */
1395 write_lock_bh(&nf_conntrack_lock); 1400 write_lock_bh(&nf_conntrack_lock);
@@ -1398,22 +1403,30 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1398 write_unlock_bh(&nf_conntrack_lock); 1403 write_unlock_bh(&nf_conntrack_lock);
1399 return -EINVAL; 1404 return -EINVAL;
1400 } 1405 }
1401 list_for_each_entry_safe(exp, tmp, &nf_ct_expect_list, list) { 1406 for (i = 0; i < nf_ct_expect_hsize; i++) {
1402 struct nf_conn_help *m_help = nfct_help(exp->master); 1407 hlist_for_each_entry_safe(exp, n, next,
1403 if (m_help->helper == h 1408 &nf_ct_expect_hash[i],
1404 && del_timer(&exp->timeout)) { 1409 hnode) {
1405 nf_ct_unlink_expect(exp); 1410 m_help = nfct_help(exp->master);
1406 nf_ct_expect_put(exp); 1411 if (m_help->helper == h
1412 && del_timer(&exp->timeout)) {
1413 nf_ct_unlink_expect(exp);
1414 nf_ct_expect_put(exp);
1415 }
1407 } 1416 }
1408 } 1417 }
1409 write_unlock_bh(&nf_conntrack_lock); 1418 write_unlock_bh(&nf_conntrack_lock);
1410 } else { 1419 } else {
1411 /* This basically means we have to flush everything*/ 1420 /* This basically means we have to flush everything*/
1412 write_lock_bh(&nf_conntrack_lock); 1421 write_lock_bh(&nf_conntrack_lock);
1413 list_for_each_entry_safe(exp, tmp, &nf_ct_expect_list, list) { 1422 for (i = 0; i < nf_ct_expect_hsize; i++) {
1414 if (del_timer(&exp->timeout)) { 1423 hlist_for_each_entry_safe(exp, n, next,
1415 nf_ct_unlink_expect(exp); 1424 &nf_ct_expect_hash[i],
1416 nf_ct_expect_put(exp); 1425 hnode) {
1426 if (del_timer(&exp->timeout)) {
1427 nf_ct_unlink_expect(exp);
1428 nf_ct_expect_put(exp);
1429 }
1417 } 1430 }
1418 } 1431 }
1419 write_unlock_bh(&nf_conntrack_lock); 1432 write_unlock_bh(&nf_conntrack_lock);