diff options
author | Patrick McHardy <kaber@trash.net> | 2006-09-20 14:57:53 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:19:45 -0400 |
commit | df0933dcb027e156cb5253570ad694b81bd52b69 (patch) | |
tree | 48588f78dfda69f737b5ccfff02787ca0dad6036 | |
parent | 1bf38a36b6a0e810dafae048fdbb999e587f0f2f (diff) |
[NETFILTER]: kill listhelp.h
Kill listhelp.h and use the list.h functions instead.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netfilter/x_tables.h | 4 | ||||
-rw-r--r-- | include/linux/netfilter_ipv4/listhelp.h | 123 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 76 | ||||
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_core.c | 189 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_gre.c | 24 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_standalone.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_core.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_helper.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_rule.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 185 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_standalone.c | 1 | ||||
-rw-r--r-- | net/netfilter/x_tables.c | 17 |
15 files changed, 237 insertions, 404 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 03d1027fb0e8..c832295dbf61 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
@@ -138,10 +138,6 @@ struct xt_counters_info | |||
138 | 138 | ||
139 | #include <linux/netdevice.h> | 139 | #include <linux/netdevice.h> |
140 | 140 | ||
141 | #define ASSERT_READ_LOCK(x) | ||
142 | #define ASSERT_WRITE_LOCK(x) | ||
143 | #include <linux/netfilter_ipv4/listhelp.h> | ||
144 | |||
145 | #ifdef CONFIG_COMPAT | 141 | #ifdef CONFIG_COMPAT |
146 | #define COMPAT_TO_USER 1 | 142 | #define COMPAT_TO_USER 1 |
147 | #define COMPAT_FROM_USER -1 | 143 | #define COMPAT_FROM_USER -1 |
diff --git a/include/linux/netfilter_ipv4/listhelp.h b/include/linux/netfilter_ipv4/listhelp.h deleted file mode 100644 index 5d92cf044d91..000000000000 --- a/include/linux/netfilter_ipv4/listhelp.h +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | #ifndef _LISTHELP_H | ||
2 | #define _LISTHELP_H | ||
3 | #include <linux/list.h> | ||
4 | |||
5 | /* Header to do more comprehensive job than linux/list.h; assume list | ||
6 | is first entry in structure. */ | ||
7 | |||
8 | /* Return pointer to first true entry, if any, or NULL. A macro | ||
9 | required to allow inlining of cmpfn. */ | ||
10 | #define LIST_FIND(head, cmpfn, type, args...) \ | ||
11 | ({ \ | ||
12 | const struct list_head *__i, *__j = NULL; \ | ||
13 | \ | ||
14 | ASSERT_READ_LOCK(head); \ | ||
15 | list_for_each(__i, (head)) \ | ||
16 | if (cmpfn((const type)__i , ## args)) { \ | ||
17 | __j = __i; \ | ||
18 | break; \ | ||
19 | } \ | ||
20 | (type)__j; \ | ||
21 | }) | ||
22 | |||
23 | #define LIST_FIND_W(head, cmpfn, type, args...) \ | ||
24 | ({ \ | ||
25 | const struct list_head *__i, *__j = NULL; \ | ||
26 | \ | ||
27 | ASSERT_WRITE_LOCK(head); \ | ||
28 | list_for_each(__i, (head)) \ | ||
29 | if (cmpfn((type)__i , ## args)) { \ | ||
30 | __j = __i; \ | ||
31 | break; \ | ||
32 | } \ | ||
33 | (type)__j; \ | ||
34 | }) | ||
35 | |||
36 | /* Just like LIST_FIND but we search backwards */ | ||
37 | #define LIST_FIND_B(head, cmpfn, type, args...) \ | ||
38 | ({ \ | ||
39 | const struct list_head *__i, *__j = NULL; \ | ||
40 | \ | ||
41 | ASSERT_READ_LOCK(head); \ | ||
42 | list_for_each_prev(__i, (head)) \ | ||
43 | if (cmpfn((const type)__i , ## args)) { \ | ||
44 | __j = __i; \ | ||
45 | break; \ | ||
46 | } \ | ||
47 | (type)__j; \ | ||
48 | }) | ||
49 | |||
50 | static inline int | ||
51 | __list_cmp_same(const void *p1, const void *p2) { return p1 == p2; } | ||
52 | |||
53 | /* Is this entry in the list? */ | ||
54 | static inline int | ||
55 | list_inlist(struct list_head *head, const void *entry) | ||
56 | { | ||
57 | return LIST_FIND(head, __list_cmp_same, void *, entry) != NULL; | ||
58 | } | ||
59 | |||
60 | /* Delete from list. */ | ||
61 | #ifdef CONFIG_NETFILTER_DEBUG | ||
62 | #define LIST_DELETE(head, oldentry) \ | ||
63 | do { \ | ||
64 | ASSERT_WRITE_LOCK(head); \ | ||
65 | if (!list_inlist(head, oldentry)) \ | ||
66 | printk("LIST_DELETE: %s:%u `%s'(%p) not in %s.\n", \ | ||
67 | __FILE__, __LINE__, #oldentry, oldentry, #head); \ | ||
68 | else list_del((struct list_head *)oldentry); \ | ||
69 | } while(0) | ||
70 | #else | ||
71 | #define LIST_DELETE(head, oldentry) list_del((struct list_head *)oldentry) | ||
72 | #endif | ||
73 | |||
74 | /* Append. */ | ||
75 | static inline void | ||
76 | list_append(struct list_head *head, void *new) | ||
77 | { | ||
78 | ASSERT_WRITE_LOCK(head); | ||
79 | list_add((new), (head)->prev); | ||
80 | } | ||
81 | |||
82 | /* Prepend. */ | ||
83 | static inline void | ||
84 | list_prepend(struct list_head *head, void *new) | ||
85 | { | ||
86 | ASSERT_WRITE_LOCK(head); | ||
87 | list_add(new, head); | ||
88 | } | ||
89 | |||
90 | /* Insert according to ordering function; insert before first true. */ | ||
91 | #define LIST_INSERT(head, new, cmpfn) \ | ||
92 | do { \ | ||
93 | struct list_head *__i; \ | ||
94 | ASSERT_WRITE_LOCK(head); \ | ||
95 | list_for_each(__i, (head)) \ | ||
96 | if ((new), (typeof (new))__i) \ | ||
97 | break; \ | ||
98 | list_add((struct list_head *)(new), __i->prev); \ | ||
99 | } while(0) | ||
100 | |||
101 | /* If the field after the list_head is a nul-terminated string, you | ||
102 | can use these functions. */ | ||
103 | static inline int __list_cmp_name(const void *i, const char *name) | ||
104 | { | ||
105 | return strcmp(name, i+sizeof(struct list_head)) == 0; | ||
106 | } | ||
107 | |||
108 | /* Returns false if same name already in list, otherwise does insert. */ | ||
109 | static inline int | ||
110 | list_named_insert(struct list_head *head, void *new) | ||
111 | { | ||
112 | if (LIST_FIND(head, __list_cmp_name, void *, | ||
113 | new + sizeof(struct list_head))) | ||
114 | return 0; | ||
115 | list_prepend(head, new); | ||
116 | return 1; | ||
117 | } | ||
118 | |||
119 | /* Find this named element in the list. */ | ||
120 | #define list_named_find(head, name) \ | ||
121 | LIST_FIND(head, __list_cmp_name, void *, name) | ||
122 | |||
123 | #endif /*_LISTHELP_H*/ | ||
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index d06a5075b5f6..3df55b2bd91d 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/vmalloc.h> | 24 | #include <linux/vmalloc.h> |
25 | #include <linux/netfilter_bridge/ebtables.h> | 25 | #include <linux/netfilter_bridge/ebtables.h> |
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | #include <linux/smp.h> | 29 | #include <linux/smp.h> |
29 | #include <linux/cpumask.h> | 30 | #include <linux/cpumask.h> |
@@ -31,12 +32,6 @@ | |||
31 | /* needed for logical [in,out]-dev filtering */ | 32 | /* needed for logical [in,out]-dev filtering */ |
32 | #include "../br_private.h" | 33 | #include "../br_private.h" |
33 | 34 | ||
34 | /* list_named_find */ | ||
35 | #define ASSERT_READ_LOCK(x) | ||
36 | #define ASSERT_WRITE_LOCK(x) | ||
37 | #include <linux/netfilter_ipv4/listhelp.h> | ||
38 | #include <linux/mutex.h> | ||
39 | |||
40 | #define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ | 35 | #define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ |
41 | "report to author: "format, ## args) | 36 | "report to author: "format, ## args) |
42 | /* #define BUGPRINT(format, args...) */ | 37 | /* #define BUGPRINT(format, args...) */ |
@@ -278,18 +273,22 @@ static inline void * | |||
278 | find_inlist_lock_noload(struct list_head *head, const char *name, int *error, | 273 | find_inlist_lock_noload(struct list_head *head, const char *name, int *error, |
279 | struct mutex *mutex) | 274 | struct mutex *mutex) |
280 | { | 275 | { |
281 | void *ret; | 276 | struct { |
277 | struct list_head list; | ||
278 | char name[EBT_FUNCTION_MAXNAMELEN]; | ||
279 | } *e; | ||
282 | 280 | ||
283 | *error = mutex_lock_interruptible(mutex); | 281 | *error = mutex_lock_interruptible(mutex); |
284 | if (*error != 0) | 282 | if (*error != 0) |
285 | return NULL; | 283 | return NULL; |
286 | 284 | ||
287 | ret = list_named_find(head, name); | 285 | list_for_each_entry(e, head, list) { |
288 | if (!ret) { | 286 | if (strcmp(e->name, name) == 0) |
289 | *error = -ENOENT; | 287 | return e; |
290 | mutex_unlock(mutex); | ||
291 | } | 288 | } |
292 | return ret; | 289 | *error = -ENOENT; |
290 | mutex_unlock(mutex); | ||
291 | return NULL; | ||
293 | } | 292 | } |
294 | 293 | ||
295 | #ifndef CONFIG_KMOD | 294 | #ifndef CONFIG_KMOD |
@@ -1043,15 +1042,19 @@ free_newinfo: | |||
1043 | 1042 | ||
1044 | int ebt_register_target(struct ebt_target *target) | 1043 | int ebt_register_target(struct ebt_target *target) |
1045 | { | 1044 | { |
1045 | struct ebt_target *t; | ||
1046 | int ret; | 1046 | int ret; |
1047 | 1047 | ||
1048 | ret = mutex_lock_interruptible(&ebt_mutex); | 1048 | ret = mutex_lock_interruptible(&ebt_mutex); |
1049 | if (ret != 0) | 1049 | if (ret != 0) |
1050 | return ret; | 1050 | return ret; |
1051 | if (!list_named_insert(&ebt_targets, target)) { | 1051 | list_for_each_entry(t, &ebt_targets, list) { |
1052 | mutex_unlock(&ebt_mutex); | 1052 | if (strcmp(t->name, target->name) == 0) { |
1053 | return -EEXIST; | 1053 | mutex_unlock(&ebt_mutex); |
1054 | return -EEXIST; | ||
1055 | } | ||
1054 | } | 1056 | } |
1057 | list_add(&target->list, &ebt_targets); | ||
1055 | mutex_unlock(&ebt_mutex); | 1058 | mutex_unlock(&ebt_mutex); |
1056 | 1059 | ||
1057 | return 0; | 1060 | return 0; |
@@ -1060,21 +1063,25 @@ int ebt_register_target(struct ebt_target *target) | |||
1060 | void ebt_unregister_target(struct ebt_target *target) | 1063 | void ebt_unregister_target(struct ebt_target *target) |
1061 | { | 1064 | { |
1062 | mutex_lock(&ebt_mutex); | 1065 | mutex_lock(&ebt_mutex); |
1063 | LIST_DELETE(&ebt_targets, target); | 1066 | list_del(&target->list); |
1064 | mutex_unlock(&ebt_mutex); | 1067 | mutex_unlock(&ebt_mutex); |
1065 | } | 1068 | } |
1066 | 1069 | ||
1067 | int ebt_register_match(struct ebt_match *match) | 1070 | int ebt_register_match(struct ebt_match *match) |
1068 | { | 1071 | { |
1072 | struct ebt_match *m; | ||
1069 | int ret; | 1073 | int ret; |
1070 | 1074 | ||
1071 | ret = mutex_lock_interruptible(&ebt_mutex); | 1075 | ret = mutex_lock_interruptible(&ebt_mutex); |
1072 | if (ret != 0) | 1076 | if (ret != 0) |
1073 | return ret; | 1077 | return ret; |
1074 | if (!list_named_insert(&ebt_matches, match)) { | 1078 | list_for_each_entry(m, &ebt_matches, list) { |
1075 | mutex_unlock(&ebt_mutex); | 1079 | if (strcmp(m->name, match->name) == 0) { |
1076 | return -EEXIST; | 1080 | mutex_unlock(&ebt_mutex); |
1081 | return -EEXIST; | ||
1082 | } | ||
1077 | } | 1083 | } |
1084 | list_add(&match->list, &ebt_matches); | ||
1078 | mutex_unlock(&ebt_mutex); | 1085 | mutex_unlock(&ebt_mutex); |
1079 | 1086 | ||
1080 | return 0; | 1087 | return 0; |
@@ -1083,21 +1090,25 @@ int ebt_register_match(struct ebt_match *match) | |||
1083 | void ebt_unregister_match(struct ebt_match *match) | 1090 | void ebt_unregister_match(struct ebt_match *match) |
1084 | { | 1091 | { |
1085 | mutex_lock(&ebt_mutex); | 1092 | mutex_lock(&ebt_mutex); |
1086 | LIST_DELETE(&ebt_matches, match); | 1093 | list_del(&match->list); |
1087 | mutex_unlock(&ebt_mutex); | 1094 | mutex_unlock(&ebt_mutex); |
1088 | } | 1095 | } |
1089 | 1096 | ||
1090 | int ebt_register_watcher(struct ebt_watcher *watcher) | 1097 | int ebt_register_watcher(struct ebt_watcher *watcher) |
1091 | { | 1098 | { |
1099 | struct ebt_watcher *w; | ||
1092 | int ret; | 1100 | int ret; |
1093 | 1101 | ||
1094 | ret = mutex_lock_interruptible(&ebt_mutex); | 1102 | ret = mutex_lock_interruptible(&ebt_mutex); |
1095 | if (ret != 0) | 1103 | if (ret != 0) |
1096 | return ret; | 1104 | return ret; |
1097 | if (!list_named_insert(&ebt_watchers, watcher)) { | 1105 | list_for_each_entry(w, &ebt_watchers, list) { |
1098 | mutex_unlock(&ebt_mutex); | 1106 | if (strcmp(w->name, watcher->name) == 0) { |
1099 | return -EEXIST; | 1107 | mutex_unlock(&ebt_mutex); |
1108 | return -EEXIST; | ||
1109 | } | ||
1100 | } | 1110 | } |
1111 | list_add(&watcher->list, &ebt_watchers); | ||
1101 | mutex_unlock(&ebt_mutex); | 1112 | mutex_unlock(&ebt_mutex); |
1102 | 1113 | ||
1103 | return 0; | 1114 | return 0; |
@@ -1106,13 +1117,14 @@ int ebt_register_watcher(struct ebt_watcher *watcher) | |||
1106 | void ebt_unregister_watcher(struct ebt_watcher *watcher) | 1117 | void ebt_unregister_watcher(struct ebt_watcher *watcher) |
1107 | { | 1118 | { |
1108 | mutex_lock(&ebt_mutex); | 1119 | mutex_lock(&ebt_mutex); |
1109 | LIST_DELETE(&ebt_watchers, watcher); | 1120 | list_del(&watcher->list); |
1110 | mutex_unlock(&ebt_mutex); | 1121 | mutex_unlock(&ebt_mutex); |
1111 | } | 1122 | } |
1112 | 1123 | ||
1113 | int ebt_register_table(struct ebt_table *table) | 1124 | int ebt_register_table(struct ebt_table *table) |
1114 | { | 1125 | { |
1115 | struct ebt_table_info *newinfo; | 1126 | struct ebt_table_info *newinfo; |
1127 | struct ebt_table *t; | ||
1116 | int ret, i, countersize; | 1128 | int ret, i, countersize; |
1117 | 1129 | ||
1118 | if (!table || !table->table ||!table->table->entries || | 1130 | if (!table || !table->table ||!table->table->entries || |
@@ -1158,10 +1170,12 @@ int ebt_register_table(struct ebt_table *table) | |||
1158 | if (ret != 0) | 1170 | if (ret != 0) |
1159 | goto free_chainstack; | 1171 | goto free_chainstack; |
1160 | 1172 | ||
1161 | if (list_named_find(&ebt_tables, table->name)) { | 1173 | list_for_each_entry(t, &ebt_tables, list) { |
1162 | ret = -EEXIST; | 1174 | if (strcmp(t->name, table->name) == 0) { |
1163 | BUGPRINT("Table name already exists\n"); | 1175 | ret = -EEXIST; |
1164 | goto free_unlock; | 1176 | BUGPRINT("Table name already exists\n"); |
1177 | goto free_unlock; | ||
1178 | } | ||
1165 | } | 1179 | } |
1166 | 1180 | ||
1167 | /* Hold a reference count if the chains aren't empty */ | 1181 | /* Hold a reference count if the chains aren't empty */ |
@@ -1169,7 +1183,7 @@ int ebt_register_table(struct ebt_table *table) | |||
1169 | ret = -ENOENT; | 1183 | ret = -ENOENT; |
1170 | goto free_unlock; | 1184 | goto free_unlock; |
1171 | } | 1185 | } |
1172 | list_prepend(&ebt_tables, table); | 1186 | list_add(&table->list, &ebt_tables); |
1173 | mutex_unlock(&ebt_mutex); | 1187 | mutex_unlock(&ebt_mutex); |
1174 | return 0; | 1188 | return 0; |
1175 | free_unlock: | 1189 | free_unlock: |
@@ -1195,7 +1209,7 @@ void ebt_unregister_table(struct ebt_table *table) | |||
1195 | return; | 1209 | return; |
1196 | } | 1210 | } |
1197 | mutex_lock(&ebt_mutex); | 1211 | mutex_lock(&ebt_mutex); |
1198 | LIST_DELETE(&ebt_tables, table); | 1212 | list_del(&table->list); |
1199 | mutex_unlock(&ebt_mutex); | 1213 | mutex_unlock(&ebt_mutex); |
1200 | vfree(table->private->entries); | 1214 | vfree(table->private->entries); |
1201 | if (table->private->chainstack) { | 1215 | if (table->private->chainstack) { |
@@ -1465,7 +1479,7 @@ static int __init ebtables_init(void) | |||
1465 | int ret; | 1479 | int ret; |
1466 | 1480 | ||
1467 | mutex_lock(&ebt_mutex); | 1481 | mutex_lock(&ebt_mutex); |
1468 | list_named_insert(&ebt_targets, &ebt_standard_target); | 1482 | list_add(&ebt_standard_target.list, &ebt_targets); |
1469 | mutex_unlock(&ebt_mutex); | 1483 | mutex_unlock(&ebt_mutex); |
1470 | if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) | 1484 | if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) |
1471 | return ret; | 1485 | return ret; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 4f10b06413a1..aaeaa9ce0f28 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -56,8 +56,6 @@ do { \ | |||
56 | #define ARP_NF_ASSERT(x) | 56 | #define ARP_NF_ASSERT(x) |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #include <linux/netfilter_ipv4/listhelp.h> | ||
60 | |||
61 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, | 59 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, |
62 | char *hdr_addr, int len) | 60 | char *hdr_addr, int len) |
63 | { | 61 | { |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 5da25ad50309..2568d480e9a9 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> | 47 | #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> |
48 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 48 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
49 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | 49 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> |
50 | #include <linux/netfilter_ipv4/listhelp.h> | ||
51 | 50 | ||
52 | #define IP_CONNTRACK_VERSION "2.4" | 51 | #define IP_CONNTRACK_VERSION "2.4" |
53 | 52 | ||
@@ -294,15 +293,10 @@ void ip_ct_remove_expectations(struct ip_conntrack *ct) | |||
294 | static void | 293 | static void |
295 | clean_from_lists(struct ip_conntrack *ct) | 294 | clean_from_lists(struct ip_conntrack *ct) |
296 | { | 295 | { |
297 | unsigned int ho, hr; | ||
298 | |||
299 | DEBUGP("clean_from_lists(%p)\n", ct); | 296 | DEBUGP("clean_from_lists(%p)\n", ct); |
300 | ASSERT_WRITE_LOCK(&ip_conntrack_lock); | 297 | ASSERT_WRITE_LOCK(&ip_conntrack_lock); |
301 | 298 | list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); | |
302 | ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); | 299 | list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list); |
303 | hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); | ||
304 | LIST_DELETE(&ip_conntrack_hash[ho], &ct->tuplehash[IP_CT_DIR_ORIGINAL]); | ||
305 | LIST_DELETE(&ip_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]); | ||
306 | 300 | ||
307 | /* Destroy all pending expectations */ | 301 | /* Destroy all pending expectations */ |
308 | ip_ct_remove_expectations(ct); | 302 | ip_ct_remove_expectations(ct); |
@@ -367,16 +361,6 @@ static void death_by_timeout(unsigned long ul_conntrack) | |||
367 | ip_conntrack_put(ct); | 361 | ip_conntrack_put(ct); |
368 | } | 362 | } |
369 | 363 | ||
370 | static inline int | ||
371 | conntrack_tuple_cmp(const struct ip_conntrack_tuple_hash *i, | ||
372 | const struct ip_conntrack_tuple *tuple, | ||
373 | const struct ip_conntrack *ignored_conntrack) | ||
374 | { | ||
375 | ASSERT_READ_LOCK(&ip_conntrack_lock); | ||
376 | return tuplehash_to_ctrack(i) != ignored_conntrack | ||
377 | && ip_ct_tuple_equal(tuple, &i->tuple); | ||
378 | } | ||
379 | |||
380 | struct ip_conntrack_tuple_hash * | 364 | struct ip_conntrack_tuple_hash * |
381 | __ip_conntrack_find(const struct ip_conntrack_tuple *tuple, | 365 | __ip_conntrack_find(const struct ip_conntrack_tuple *tuple, |
382 | const struct ip_conntrack *ignored_conntrack) | 366 | const struct ip_conntrack *ignored_conntrack) |
@@ -386,7 +370,8 @@ __ip_conntrack_find(const struct ip_conntrack_tuple *tuple, | |||
386 | 370 | ||
387 | ASSERT_READ_LOCK(&ip_conntrack_lock); | 371 | ASSERT_READ_LOCK(&ip_conntrack_lock); |
388 | list_for_each_entry(h, &ip_conntrack_hash[hash], list) { | 372 | list_for_each_entry(h, &ip_conntrack_hash[hash], list) { |
389 | if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) { | 373 | if (tuplehash_to_ctrack(h) != ignored_conntrack && |
374 | ip_ct_tuple_equal(tuple, &h->tuple)) { | ||
390 | CONNTRACK_STAT_INC(found); | 375 | CONNTRACK_STAT_INC(found); |
391 | return h; | 376 | return h; |
392 | } | 377 | } |
@@ -417,10 +402,10 @@ static void __ip_conntrack_hash_insert(struct ip_conntrack *ct, | |||
417 | unsigned int repl_hash) | 402 | unsigned int repl_hash) |
418 | { | 403 | { |
419 | ct->id = ++ip_conntrack_next_id; | 404 | ct->id = ++ip_conntrack_next_id; |
420 | list_prepend(&ip_conntrack_hash[hash], | 405 | list_add(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list, |
421 | &ct->tuplehash[IP_CT_DIR_ORIGINAL].list); | 406 | &ip_conntrack_hash[hash]); |
422 | list_prepend(&ip_conntrack_hash[repl_hash], | 407 | list_add(&ct->tuplehash[IP_CT_DIR_REPLY].list, |
423 | &ct->tuplehash[IP_CT_DIR_REPLY].list); | 408 | &ip_conntrack_hash[repl_hash]); |
424 | } | 409 | } |
425 | 410 | ||
426 | void ip_conntrack_hash_insert(struct ip_conntrack *ct) | 411 | void ip_conntrack_hash_insert(struct ip_conntrack *ct) |
@@ -440,6 +425,7 @@ int | |||
440 | __ip_conntrack_confirm(struct sk_buff **pskb) | 425 | __ip_conntrack_confirm(struct sk_buff **pskb) |
441 | { | 426 | { |
442 | unsigned int hash, repl_hash; | 427 | unsigned int hash, repl_hash; |
428 | struct ip_conntrack_tuple_hash *h; | ||
443 | struct ip_conntrack *ct; | 429 | struct ip_conntrack *ct; |
444 | enum ip_conntrack_info ctinfo; | 430 | enum ip_conntrack_info ctinfo; |
445 | 431 | ||
@@ -470,43 +456,43 @@ __ip_conntrack_confirm(struct sk_buff **pskb) | |||
470 | /* See if there's one in the list already, including reverse: | 456 | /* See if there's one in the list already, including reverse: |
471 | NAT could have grabbed it without realizing, since we're | 457 | NAT could have grabbed it without realizing, since we're |
472 | not in the hash. If there is, we lost race. */ | 458 | not in the hash. If there is, we lost race. */ |
473 | if (!LIST_FIND(&ip_conntrack_hash[hash], | 459 | list_for_each_entry(h, &ip_conntrack_hash[hash], list) |
474 | conntrack_tuple_cmp, | 460 | if (ip_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, |
475 | struct ip_conntrack_tuple_hash *, | 461 | &h->tuple)) |
476 | &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, NULL) | 462 | goto out; |
477 | && !LIST_FIND(&ip_conntrack_hash[repl_hash], | 463 | list_for_each_entry(h, &ip_conntrack_hash[repl_hash], list) |
478 | conntrack_tuple_cmp, | 464 | if (ip_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, |
479 | struct ip_conntrack_tuple_hash *, | 465 | &h->tuple)) |
480 | &ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) { | 466 | goto out; |
481 | /* Remove from unconfirmed list */ | ||
482 | list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); | ||
483 | 467 | ||
484 | __ip_conntrack_hash_insert(ct, hash, repl_hash); | 468 | /* Remove from unconfirmed list */ |
485 | /* Timer relative to confirmation time, not original | 469 | list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); |
486 | setting time, otherwise we'd get timer wrap in | 470 | |
487 | weird delay cases. */ | 471 | __ip_conntrack_hash_insert(ct, hash, repl_hash); |
488 | ct->timeout.expires += jiffies; | 472 | /* Timer relative to confirmation time, not original |
489 | add_timer(&ct->timeout); | 473 | setting time, otherwise we'd get timer wrap in |
490 | atomic_inc(&ct->ct_general.use); | 474 | weird delay cases. */ |
491 | set_bit(IPS_CONFIRMED_BIT, &ct->status); | 475 | ct->timeout.expires += jiffies; |
492 | CONNTRACK_STAT_INC(insert); | 476 | add_timer(&ct->timeout); |
493 | write_unlock_bh(&ip_conntrack_lock); | 477 | atomic_inc(&ct->ct_general.use); |
494 | if (ct->helper) | 478 | set_bit(IPS_CONFIRMED_BIT, &ct->status); |
495 | ip_conntrack_event_cache(IPCT_HELPER, *pskb); | 479 | CONNTRACK_STAT_INC(insert); |
480 | write_unlock_bh(&ip_conntrack_lock); | ||
481 | if (ct->helper) | ||
482 | ip_conntrack_event_cache(IPCT_HELPER, *pskb); | ||
496 | #ifdef CONFIG_IP_NF_NAT_NEEDED | 483 | #ifdef CONFIG_IP_NF_NAT_NEEDED |
497 | if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) || | 484 | if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) || |
498 | test_bit(IPS_DST_NAT_DONE_BIT, &ct->status)) | 485 | test_bit(IPS_DST_NAT_DONE_BIT, &ct->status)) |
499 | ip_conntrack_event_cache(IPCT_NATINFO, *pskb); | 486 | ip_conntrack_event_cache(IPCT_NATINFO, *pskb); |
500 | #endif | 487 | #endif |
501 | ip_conntrack_event_cache(master_ct(ct) ? | 488 | ip_conntrack_event_cache(master_ct(ct) ? |
502 | IPCT_RELATED : IPCT_NEW, *pskb); | 489 | IPCT_RELATED : IPCT_NEW, *pskb); |
503 | 490 | ||
504 | return NF_ACCEPT; | 491 | return NF_ACCEPT; |
505 | } | ||
506 | 492 | ||
493 | out: | ||
507 | CONNTRACK_STAT_INC(insert_failed); | 494 | CONNTRACK_STAT_INC(insert_failed); |
508 | write_unlock_bh(&ip_conntrack_lock); | 495 | write_unlock_bh(&ip_conntrack_lock); |
509 | |||
510 | return NF_DROP; | 496 | return NF_DROP; |
511 | } | 497 | } |
512 | 498 | ||
@@ -527,23 +513,21 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple, | |||
527 | 513 | ||
528 | /* There's a small race here where we may free a just-assured | 514 | /* There's a small race here where we may free a just-assured |
529 | connection. Too bad: we're in trouble anyway. */ | 515 | connection. Too bad: we're in trouble anyway. */ |
530 | static inline int unreplied(const struct ip_conntrack_tuple_hash *i) | ||
531 | { | ||
532 | return !(test_bit(IPS_ASSURED_BIT, &tuplehash_to_ctrack(i)->status)); | ||
533 | } | ||
534 | |||
535 | static int early_drop(struct list_head *chain) | 516 | static int early_drop(struct list_head *chain) |
536 | { | 517 | { |
537 | /* Traverse backwards: gives us oldest, which is roughly LRU */ | 518 | /* Traverse backwards: gives us oldest, which is roughly LRU */ |
538 | struct ip_conntrack_tuple_hash *h; | 519 | struct ip_conntrack_tuple_hash *h; |
539 | struct ip_conntrack *ct = NULL; | 520 | struct ip_conntrack *ct = NULL, *tmp; |
540 | int dropped = 0; | 521 | int dropped = 0; |
541 | 522 | ||
542 | read_lock_bh(&ip_conntrack_lock); | 523 | read_lock_bh(&ip_conntrack_lock); |
543 | h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *); | 524 | list_for_each_entry_reverse(h, chain, list) { |
544 | if (h) { | 525 | tmp = tuplehash_to_ctrack(h); |
545 | ct = tuplehash_to_ctrack(h); | 526 | if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) { |
546 | atomic_inc(&ct->ct_general.use); | 527 | ct = tmp; |
528 | atomic_inc(&ct->ct_general.use); | ||
529 | break; | ||
530 | } | ||
547 | } | 531 | } |
548 | read_unlock_bh(&ip_conntrack_lock); | 532 | read_unlock_bh(&ip_conntrack_lock); |
549 | 533 | ||
@@ -559,18 +543,16 @@ static int early_drop(struct list_head *chain) | |||
559 | return dropped; | 543 | return dropped; |
560 | } | 544 | } |
561 | 545 | ||
562 | static inline int helper_cmp(const struct ip_conntrack_helper *i, | ||
563 | const struct ip_conntrack_tuple *rtuple) | ||
564 | { | ||
565 | return ip_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask); | ||
566 | } | ||
567 | |||
568 | static struct ip_conntrack_helper * | 546 | static struct ip_conntrack_helper * |
569 | __ip_conntrack_helper_find( const struct ip_conntrack_tuple *tuple) | 547 | __ip_conntrack_helper_find( const struct ip_conntrack_tuple *tuple) |
570 | { | 548 | { |
571 | return LIST_FIND(&helpers, helper_cmp, | 549 | struct ip_conntrack_helper *h; |
572 | struct ip_conntrack_helper *, | 550 | |
573 | tuple); | 551 | list_for_each_entry(h, &helpers, list) { |
552 | if (ip_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask)) | ||
553 | return h; | ||
554 | } | ||
555 | return NULL; | ||
574 | } | 556 | } |
575 | 557 | ||
576 | struct ip_conntrack_helper * | 558 | struct ip_conntrack_helper * |
@@ -1062,7 +1044,7 @@ int ip_conntrack_helper_register(struct ip_conntrack_helper *me) | |||
1062 | { | 1044 | { |
1063 | BUG_ON(me->timeout == 0); | 1045 | BUG_ON(me->timeout == 0); |
1064 | write_lock_bh(&ip_conntrack_lock); | 1046 | write_lock_bh(&ip_conntrack_lock); |
1065 | list_prepend(&helpers, me); | 1047 | list_add(&me->list, &helpers); |
1066 | write_unlock_bh(&ip_conntrack_lock); | 1048 | write_unlock_bh(&ip_conntrack_lock); |
1067 | 1049 | ||
1068 | return 0; | 1050 | return 0; |
@@ -1081,24 +1063,24 @@ __ip_conntrack_helper_find_byname(const char *name) | |||
1081 | return NULL; | 1063 | return NULL; |
1082 | } | 1064 | } |
1083 | 1065 | ||
1084 | static inline int unhelp(struct ip_conntrack_tuple_hash *i, | 1066 | static inline void unhelp(struct ip_conntrack_tuple_hash *i, |
1085 | const struct ip_conntrack_helper *me) | 1067 | const struct ip_conntrack_helper *me) |
1086 | { | 1068 | { |
1087 | if (tuplehash_to_ctrack(i)->helper == me) { | 1069 | if (tuplehash_to_ctrack(i)->helper == me) { |
1088 | ip_conntrack_event(IPCT_HELPER, tuplehash_to_ctrack(i)); | 1070 | ip_conntrack_event(IPCT_HELPER, tuplehash_to_ctrack(i)); |
1089 | tuplehash_to_ctrack(i)->helper = NULL; | 1071 | tuplehash_to_ctrack(i)->helper = NULL; |
1090 | } | 1072 | } |
1091 | return 0; | ||
1092 | } | 1073 | } |
1093 | 1074 | ||
1094 | void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) | 1075 | void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) |
1095 | { | 1076 | { |
1096 | unsigned int i; | 1077 | unsigned int i; |
1078 | struct ip_conntrack_tuple_hash *h; | ||
1097 | struct ip_conntrack_expect *exp, *tmp; | 1079 | struct ip_conntrack_expect *exp, *tmp; |
1098 | 1080 | ||
1099 | /* Need write lock here, to delete helper. */ | 1081 | /* Need write lock here, to delete helper. */ |
1100 | write_lock_bh(&ip_conntrack_lock); | 1082 | write_lock_bh(&ip_conntrack_lock); |
1101 | LIST_DELETE(&helpers, me); | 1083 | list_del(&me->list); |
1102 | 1084 | ||
1103 | /* Get rid of expectations */ | 1085 | /* Get rid of expectations */ |
1104 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) { | 1086 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) { |
@@ -1108,10 +1090,12 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) | |||
1108 | } | 1090 | } |
1109 | } | 1091 | } |
1110 | /* Get rid of expecteds, set helpers to NULL. */ | 1092 | /* Get rid of expecteds, set helpers to NULL. */ |
1111 | LIST_FIND_W(&unconfirmed, unhelp, struct ip_conntrack_tuple_hash*, me); | 1093 | list_for_each_entry(h, &unconfirmed, list) |
1112 | for (i = 0; i < ip_conntrack_htable_size; i++) | 1094 | unhelp(h, me); |
1113 | LIST_FIND_W(&ip_conntrack_hash[i], unhelp, | 1095 | for (i = 0; i < ip_conntrack_htable_size; i++) { |
1114 | struct ip_conntrack_tuple_hash *, me); | 1096 | list_for_each_entry(h, &ip_conntrack_hash[i], list) |
1097 | unhelp(h, me); | ||
1098 | } | ||
1115 | write_unlock_bh(&ip_conntrack_lock); | 1099 | write_unlock_bh(&ip_conntrack_lock); |
1116 | 1100 | ||
1117 | /* Someone could be still looking at the helper in a bh. */ | 1101 | /* Someone could be still looking at the helper in a bh. */ |
@@ -1237,46 +1221,43 @@ static void ip_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb) | |||
1237 | nf_conntrack_get(nskb->nfct); | 1221 | nf_conntrack_get(nskb->nfct); |
1238 | } | 1222 | } |
1239 | 1223 | ||
1240 | static inline int | ||
1241 | do_iter(const struct ip_conntrack_tuple_hash *i, | ||
1242 | int (*iter)(struct ip_conntrack *i, void *data), | ||
1243 | void *data) | ||
1244 | { | ||
1245 | return iter(tuplehash_to_ctrack(i), data); | ||
1246 | } | ||
1247 | |||
1248 | /* Bring out ya dead! */ | 1224 | /* Bring out ya dead! */ |
1249 | static struct ip_conntrack_tuple_hash * | 1225 | static struct ip_conntrack * |
1250 | get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data), | 1226 | get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data), |
1251 | void *data, unsigned int *bucket) | 1227 | void *data, unsigned int *bucket) |
1252 | { | 1228 | { |
1253 | struct ip_conntrack_tuple_hash *h = NULL; | 1229 | struct ip_conntrack_tuple_hash *h; |
1230 | struct ip_conntrack *ct; | ||
1254 | 1231 | ||
1255 | write_lock_bh(&ip_conntrack_lock); | 1232 | write_lock_bh(&ip_conntrack_lock); |
1256 | for (; *bucket < ip_conntrack_htable_size; (*bucket)++) { | 1233 | for (; *bucket < ip_conntrack_htable_size; (*bucket)++) { |
1257 | h = LIST_FIND_W(&ip_conntrack_hash[*bucket], do_iter, | 1234 | list_for_each_entry(h, &ip_conntrack_hash[*bucket], list) { |
1258 | struct ip_conntrack_tuple_hash *, iter, data); | 1235 | ct = tuplehash_to_ctrack(h); |
1259 | if (h) | 1236 | if (iter(ct, data)) |
1260 | break; | 1237 | goto found; |
1238 | } | ||
1239 | } | ||
1240 | list_for_each_entry(h, &unconfirmed, list) { | ||
1241 | ct = tuplehash_to_ctrack(h); | ||
1242 | if (iter(ct, data)) | ||
1243 | goto found; | ||
1261 | } | 1244 | } |
1262 | if (!h) | ||
1263 | h = LIST_FIND_W(&unconfirmed, do_iter, | ||
1264 | struct ip_conntrack_tuple_hash *, iter, data); | ||
1265 | if (h) | ||
1266 | atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use); | ||
1267 | write_unlock_bh(&ip_conntrack_lock); | 1245 | write_unlock_bh(&ip_conntrack_lock); |
1246 | return NULL; | ||
1268 | 1247 | ||
1269 | return h; | 1248 | found: |
1249 | atomic_inc(&ct->ct_general.use); | ||
1250 | write_unlock_bh(&ip_conntrack_lock); | ||
1251 | return ct; | ||
1270 | } | 1252 | } |
1271 | 1253 | ||
1272 | void | 1254 | void |
1273 | ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *), void *data) | 1255 | ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *), void *data) |
1274 | { | 1256 | { |
1275 | struct ip_conntrack_tuple_hash *h; | 1257 | struct ip_conntrack *ct; |
1276 | unsigned int bucket = 0; | 1258 | unsigned int bucket = 0; |
1277 | 1259 | ||
1278 | while ((h = get_next_corpse(iter, data, &bucket)) != NULL) { | 1260 | while ((ct = get_next_corpse(iter, data, &bucket)) != NULL) { |
1279 | struct ip_conntrack *ct = tuplehash_to_ctrack(h); | ||
1280 | /* Time to push up daises... */ | 1261 | /* Time to push up daises... */ |
1281 | if (del_timer(&ct->timeout)) | 1262 | if (del_timer(&ct->timeout)) |
1282 | death_by_timeout((unsigned long)ct); | 1263 | death_by_timeout((unsigned long)ct); |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_gre.c b/net/ipv4/netfilter/ip_conntrack_proto_gre.c index 4ee016c427b4..92c6d8b178c9 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_gre.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c | |||
@@ -37,7 +37,6 @@ static DEFINE_RWLOCK(ip_ct_gre_lock); | |||
37 | #define ASSERT_READ_LOCK(x) | 37 | #define ASSERT_READ_LOCK(x) |
38 | #define ASSERT_WRITE_LOCK(x) | 38 | #define ASSERT_WRITE_LOCK(x) |
39 | 39 | ||
40 | #include <linux/netfilter_ipv4/listhelp.h> | ||
41 | #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> | 40 | #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> |
42 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 41 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
43 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | 42 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> |
@@ -82,10 +81,12 @@ static __be16 gre_keymap_lookup(struct ip_conntrack_tuple *t) | |||
82 | __be16 key = 0; | 81 | __be16 key = 0; |
83 | 82 | ||
84 | read_lock_bh(&ip_ct_gre_lock); | 83 | read_lock_bh(&ip_ct_gre_lock); |
85 | km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn, | 84 | list_for_each_entry(km, &gre_keymap_list, list) { |
86 | struct ip_ct_gre_keymap *, t); | 85 | if (gre_key_cmpfn(km, t)) { |
87 | if (km) | 86 | key = km->tuple.src.u.gre.key; |
88 | key = km->tuple.src.u.gre.key; | 87 | break; |
88 | } | ||
89 | } | ||
89 | read_unlock_bh(&ip_ct_gre_lock); | 90 | read_unlock_bh(&ip_ct_gre_lock); |
90 | 91 | ||
91 | DEBUGP("lookup src key 0x%x up key for ", key); | 92 | DEBUGP("lookup src key 0x%x up key for ", key); |
@@ -99,7 +100,7 @@ int | |||
99 | ip_ct_gre_keymap_add(struct ip_conntrack *ct, | 100 | ip_ct_gre_keymap_add(struct ip_conntrack *ct, |
100 | struct ip_conntrack_tuple *t, int reply) | 101 | struct ip_conntrack_tuple *t, int reply) |
101 | { | 102 | { |
102 | struct ip_ct_gre_keymap **exist_km, *km, *old; | 103 | struct ip_ct_gre_keymap **exist_km, *km; |
103 | 104 | ||
104 | if (!ct->helper || strcmp(ct->helper->name, "pptp")) { | 105 | if (!ct->helper || strcmp(ct->helper->name, "pptp")) { |
105 | DEBUGP("refusing to add GRE keymap to non-pptp session\n"); | 106 | DEBUGP("refusing to add GRE keymap to non-pptp session\n"); |
@@ -113,13 +114,10 @@ ip_ct_gre_keymap_add(struct ip_conntrack *ct, | |||
113 | 114 | ||
114 | if (*exist_km) { | 115 | if (*exist_km) { |
115 | /* check whether it's a retransmission */ | 116 | /* check whether it's a retransmission */ |
116 | old = LIST_FIND(&gre_keymap_list, gre_key_cmpfn, | 117 | list_for_each_entry(km, &gre_keymap_list, list) { |
117 | struct ip_ct_gre_keymap *, t); | 118 | if (gre_key_cmpfn(km, t) && km == *exist_km) |
118 | if (old == *exist_km) { | 119 | return 0; |
119 | DEBUGP("retransmission\n"); | ||
120 | return 0; | ||
121 | } | 120 | } |
122 | |||
123 | DEBUGP("trying to override keymap_%s for ct %p\n", | 121 | DEBUGP("trying to override keymap_%s for ct %p\n", |
124 | reply? "reply":"orig", ct); | 122 | reply? "reply":"orig", ct); |
125 | return -EEXIST; | 123 | return -EEXIST; |
@@ -136,7 +134,7 @@ ip_ct_gre_keymap_add(struct ip_conntrack *ct, | |||
136 | DUMP_TUPLE_GRE(&km->tuple); | 134 | DUMP_TUPLE_GRE(&km->tuple); |
137 | 135 | ||
138 | write_lock_bh(&ip_ct_gre_lock); | 136 | write_lock_bh(&ip_ct_gre_lock); |
139 | list_append(&gre_keymap_list, km); | 137 | list_add_tail(&km->list, &gre_keymap_list); |
140 | write_unlock_bh(&ip_ct_gre_lock); | 138 | write_unlock_bh(&ip_ct_gre_lock); |
141 | 139 | ||
142 | return 0; | 140 | return 0; |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 3f5d495b853b..02135756562e 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> | 35 | #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> |
36 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | 36 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> |
37 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 37 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
38 | #include <linux/netfilter_ipv4/listhelp.h> | ||
39 | 38 | ||
40 | #if 0 | 39 | #if 0 |
41 | #define DEBUGP printk | 40 | #define DEBUGP printk |
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index 4c540d03d48e..71f3e09cbc84 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include <linux/udp.h> | 22 | #include <linux/udp.h> |
23 | #include <linux/jhash.h> | 23 | #include <linux/jhash.h> |
24 | 24 | ||
25 | #define ASSERT_READ_LOCK(x) | ||
26 | #define ASSERT_WRITE_LOCK(x) | ||
27 | |||
28 | #include <linux/netfilter_ipv4/ip_conntrack.h> | 25 | #include <linux/netfilter_ipv4/ip_conntrack.h> |
29 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | 26 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> |
30 | #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> | 27 | #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> |
@@ -33,7 +30,6 @@ | |||
33 | #include <linux/netfilter_ipv4/ip_nat_core.h> | 30 | #include <linux/netfilter_ipv4/ip_nat_core.h> |
34 | #include <linux/netfilter_ipv4/ip_nat_helper.h> | 31 | #include <linux/netfilter_ipv4/ip_nat_helper.h> |
35 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 32 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
36 | #include <linux/netfilter_ipv4/listhelp.h> | ||
37 | 33 | ||
38 | #if 0 | 34 | #if 0 |
39 | #define DEBUGP printk | 35 | #define DEBUGP printk |
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c index 021c3daae3ed..7f6a75984f6c 100644 --- a/net/ipv4/netfilter/ip_nat_helper.c +++ b/net/ipv4/netfilter/ip_nat_helper.c | |||
@@ -27,16 +27,12 @@ | |||
27 | #include <net/tcp.h> | 27 | #include <net/tcp.h> |
28 | #include <net/udp.h> | 28 | #include <net/udp.h> |
29 | 29 | ||
30 | #define ASSERT_READ_LOCK(x) | ||
31 | #define ASSERT_WRITE_LOCK(x) | ||
32 | |||
33 | #include <linux/netfilter_ipv4/ip_conntrack.h> | 30 | #include <linux/netfilter_ipv4/ip_conntrack.h> |
34 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 31 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
35 | #include <linux/netfilter_ipv4/ip_nat.h> | 32 | #include <linux/netfilter_ipv4/ip_nat.h> |
36 | #include <linux/netfilter_ipv4/ip_nat_protocol.h> | 33 | #include <linux/netfilter_ipv4/ip_nat_protocol.h> |
37 | #include <linux/netfilter_ipv4/ip_nat_core.h> | 34 | #include <linux/netfilter_ipv4/ip_nat_core.h> |
38 | #include <linux/netfilter_ipv4/ip_nat_helper.h> | 35 | #include <linux/netfilter_ipv4/ip_nat_helper.h> |
39 | #include <linux/netfilter_ipv4/listhelp.h> | ||
40 | 36 | ||
41 | #if 0 | 37 | #if 0 |
42 | #define DEBUGP printk | 38 | #define DEBUGP printk |
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index e59f5a8ecb6b..7b703839aa58 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c | |||
@@ -19,14 +19,10 @@ | |||
19 | #include <net/route.h> | 19 | #include <net/route.h> |
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | 21 | ||
22 | #define ASSERT_READ_LOCK(x) | ||
23 | #define ASSERT_WRITE_LOCK(x) | ||
24 | |||
25 | #include <linux/netfilter_ipv4/ip_tables.h> | 22 | #include <linux/netfilter_ipv4/ip_tables.h> |
26 | #include <linux/netfilter_ipv4/ip_nat.h> | 23 | #include <linux/netfilter_ipv4/ip_nat.h> |
27 | #include <linux/netfilter_ipv4/ip_nat_core.h> | 24 | #include <linux/netfilter_ipv4/ip_nat_core.h> |
28 | #include <linux/netfilter_ipv4/ip_nat_rule.h> | 25 | #include <linux/netfilter_ipv4/ip_nat_rule.h> |
29 | #include <linux/netfilter_ipv4/listhelp.h> | ||
30 | 26 | ||
31 | #if 0 | 27 | #if 0 |
32 | #define DEBUGP printk | 28 | #define DEBUGP printk |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index f3b778355432..9c577db62047 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -30,9 +30,6 @@ | |||
30 | #include <net/checksum.h> | 30 | #include <net/checksum.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | 32 | ||
33 | #define ASSERT_READ_LOCK(x) | ||
34 | #define ASSERT_WRITE_LOCK(x) | ||
35 | |||
36 | #include <linux/netfilter_ipv4/ip_nat.h> | 33 | #include <linux/netfilter_ipv4/ip_nat.h> |
37 | #include <linux/netfilter_ipv4/ip_nat_rule.h> | 34 | #include <linux/netfilter_ipv4/ip_nat_rule.h> |
38 | #include <linux/netfilter_ipv4/ip_nat_protocol.h> | 35 | #include <linux/netfilter_ipv4/ip_nat_protocol.h> |
@@ -40,7 +37,6 @@ | |||
40 | #include <linux/netfilter_ipv4/ip_nat_helper.h> | 37 | #include <linux/netfilter_ipv4/ip_nat_helper.h> |
41 | #include <linux/netfilter_ipv4/ip_tables.h> | 38 | #include <linux/netfilter_ipv4/ip_tables.h> |
42 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | 39 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> |
43 | #include <linux/netfilter_ipv4/listhelp.h> | ||
44 | 40 | ||
45 | #if 0 | 41 | #if 0 |
46 | #define DEBUGP printk | 42 | #define DEBUGP printk |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index d1c315364ee7..73d477ce216b 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -70,9 +70,6 @@ do { \ | |||
70 | #define IP_NF_ASSERT(x) | 70 | #define IP_NF_ASSERT(x) |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | |||
74 | #include <linux/netfilter_ipv4/listhelp.h> | ||
75 | |||
76 | #if 0 | 73 | #if 0 |
77 | /* All the better to debug you with... */ | 74 | /* All the better to debug you with... */ |
78 | #define static | 75 | #define static |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 3b64dbee6620..927137b8b3b5 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -57,7 +57,6 @@ | |||
57 | #include <net/netfilter/nf_conntrack_protocol.h> | 57 | #include <net/netfilter/nf_conntrack_protocol.h> |
58 | #include <net/netfilter/nf_conntrack_helper.h> | 58 | #include <net/netfilter/nf_conntrack_helper.h> |
59 | #include <net/netfilter/nf_conntrack_core.h> | 59 | #include <net/netfilter/nf_conntrack_core.h> |
60 | #include <linux/netfilter_ipv4/listhelp.h> | ||
61 | 60 | ||
62 | #define NF_CONNTRACK_VERSION "0.5.0" | 61 | #define NF_CONNTRACK_VERSION "0.5.0" |
63 | 62 | ||
@@ -539,15 +538,10 @@ void nf_ct_remove_expectations(struct nf_conn *ct) | |||
539 | static void | 538 | static void |
540 | clean_from_lists(struct nf_conn *ct) | 539 | clean_from_lists(struct nf_conn *ct) |
541 | { | 540 | { |
542 | unsigned int ho, hr; | ||
543 | |||
544 | DEBUGP("clean_from_lists(%p)\n", ct); | 541 | DEBUGP("clean_from_lists(%p)\n", ct); |
545 | ASSERT_WRITE_LOCK(&nf_conntrack_lock); | 542 | ASSERT_WRITE_LOCK(&nf_conntrack_lock); |
546 | 543 | list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); | |
547 | ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); | 544 | list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list); |
548 | hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); | ||
549 | LIST_DELETE(&nf_conntrack_hash[ho], &ct->tuplehash[IP_CT_DIR_ORIGINAL]); | ||
550 | LIST_DELETE(&nf_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]); | ||
551 | 545 | ||
552 | /* Destroy all pending expectations */ | 546 | /* Destroy all pending expectations */ |
553 | nf_ct_remove_expectations(ct); | 547 | nf_ct_remove_expectations(ct); |
@@ -617,16 +611,6 @@ static void death_by_timeout(unsigned long ul_conntrack) | |||
617 | nf_ct_put(ct); | 611 | nf_ct_put(ct); |
618 | } | 612 | } |
619 | 613 | ||
620 | static inline int | ||
621 | conntrack_tuple_cmp(const struct nf_conntrack_tuple_hash *i, | ||
622 | const struct nf_conntrack_tuple *tuple, | ||
623 | const struct nf_conn *ignored_conntrack) | ||
624 | { | ||
625 | ASSERT_READ_LOCK(&nf_conntrack_lock); | ||
626 | return nf_ct_tuplehash_to_ctrack(i) != ignored_conntrack | ||
627 | && nf_ct_tuple_equal(tuple, &i->tuple); | ||
628 | } | ||
629 | |||
630 | struct nf_conntrack_tuple_hash * | 614 | struct nf_conntrack_tuple_hash * |
631 | __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, | 615 | __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, |
632 | const struct nf_conn *ignored_conntrack) | 616 | const struct nf_conn *ignored_conntrack) |
@@ -636,7 +620,8 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, | |||
636 | 620 | ||
637 | ASSERT_READ_LOCK(&nf_conntrack_lock); | 621 | ASSERT_READ_LOCK(&nf_conntrack_lock); |
638 | list_for_each_entry(h, &nf_conntrack_hash[hash], list) { | 622 | list_for_each_entry(h, &nf_conntrack_hash[hash], list) { |
639 | if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) { | 623 | if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && |
624 | nf_ct_tuple_equal(tuple, &h->tuple)) { | ||
640 | NF_CT_STAT_INC(found); | 625 | NF_CT_STAT_INC(found); |
641 | return h; | 626 | return h; |
642 | } | 627 | } |
@@ -667,10 +652,10 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct, | |||
667 | unsigned int repl_hash) | 652 | unsigned int repl_hash) |
668 | { | 653 | { |
669 | ct->id = ++nf_conntrack_next_id; | 654 | ct->id = ++nf_conntrack_next_id; |
670 | list_prepend(&nf_conntrack_hash[hash], | 655 | list_add(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list, |
671 | &ct->tuplehash[IP_CT_DIR_ORIGINAL].list); | 656 | &nf_conntrack_hash[hash]); |
672 | list_prepend(&nf_conntrack_hash[repl_hash], | 657 | list_add(&ct->tuplehash[IP_CT_DIR_REPLY].list, |
673 | &ct->tuplehash[IP_CT_DIR_REPLY].list); | 658 | &nf_conntrack_hash[repl_hash]); |
674 | } | 659 | } |
675 | 660 | ||
676 | void nf_conntrack_hash_insert(struct nf_conn *ct) | 661 | void nf_conntrack_hash_insert(struct nf_conn *ct) |
@@ -690,7 +675,9 @@ int | |||
690 | __nf_conntrack_confirm(struct sk_buff **pskb) | 675 | __nf_conntrack_confirm(struct sk_buff **pskb) |
691 | { | 676 | { |
692 | unsigned int hash, repl_hash; | 677 | unsigned int hash, repl_hash; |
678 | struct nf_conntrack_tuple_hash *h; | ||
693 | struct nf_conn *ct; | 679 | struct nf_conn *ct; |
680 | struct nf_conn_help *help; | ||
694 | enum ip_conntrack_info ctinfo; | 681 | enum ip_conntrack_info ctinfo; |
695 | 682 | ||
696 | ct = nf_ct_get(*pskb, &ctinfo); | 683 | ct = nf_ct_get(*pskb, &ctinfo); |
@@ -720,41 +707,41 @@ __nf_conntrack_confirm(struct sk_buff **pskb) | |||
720 | /* See if there's one in the list already, including reverse: | 707 | /* See if there's one in the list already, including reverse: |
721 | NAT could have grabbed it without realizing, since we're | 708 | NAT could have grabbed it without realizing, since we're |
722 | not in the hash. If there is, we lost race. */ | 709 | not in the hash. If there is, we lost race. */ |
723 | if (!LIST_FIND(&nf_conntrack_hash[hash], | 710 | list_for_each_entry(h, &nf_conntrack_hash[hash], list) |
724 | conntrack_tuple_cmp, | 711 | if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, |
725 | struct nf_conntrack_tuple_hash *, | 712 | &h->tuple)) |
726 | &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, NULL) | 713 | goto out; |
727 | && !LIST_FIND(&nf_conntrack_hash[repl_hash], | 714 | list_for_each_entry(h, &nf_conntrack_hash[repl_hash], list) |
728 | conntrack_tuple_cmp, | 715 | if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, |
729 | struct nf_conntrack_tuple_hash *, | 716 | &h->tuple)) |
730 | &ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) { | 717 | goto out; |
731 | struct nf_conn_help *help; | ||
732 | /* Remove from unconfirmed list */ | ||
733 | list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); | ||
734 | 718 | ||
735 | __nf_conntrack_hash_insert(ct, hash, repl_hash); | 719 | /* Remove from unconfirmed list */ |
736 | /* Timer relative to confirmation time, not original | 720 | list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); |
737 | setting time, otherwise we'd get timer wrap in | 721 | |
738 | weird delay cases. */ | 722 | __nf_conntrack_hash_insert(ct, hash, repl_hash); |
739 | ct->timeout.expires += jiffies; | 723 | /* Timer relative to confirmation time, not original |
740 | add_timer(&ct->timeout); | 724 | setting time, otherwise we'd get timer wrap in |
741 | atomic_inc(&ct->ct_general.use); | 725 | weird delay cases. */ |
742 | set_bit(IPS_CONFIRMED_BIT, &ct->status); | 726 | ct->timeout.expires += jiffies; |
743 | NF_CT_STAT_INC(insert); | 727 | add_timer(&ct->timeout); |
744 | write_unlock_bh(&nf_conntrack_lock); | 728 | atomic_inc(&ct->ct_general.use); |
745 | help = nfct_help(ct); | 729 | set_bit(IPS_CONFIRMED_BIT, &ct->status); |
746 | if (help && help->helper) | 730 | NF_CT_STAT_INC(insert); |
747 | nf_conntrack_event_cache(IPCT_HELPER, *pskb); | 731 | write_unlock_bh(&nf_conntrack_lock); |
732 | help = nfct_help(ct); | ||
733 | if (help && help->helper) | ||
734 | nf_conntrack_event_cache(IPCT_HELPER, *pskb); | ||
748 | #ifdef CONFIG_NF_NAT_NEEDED | 735 | #ifdef CONFIG_NF_NAT_NEEDED |
749 | if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) || | 736 | if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) || |
750 | test_bit(IPS_DST_NAT_DONE_BIT, &ct->status)) | 737 | test_bit(IPS_DST_NAT_DONE_BIT, &ct->status)) |
751 | nf_conntrack_event_cache(IPCT_NATINFO, *pskb); | 738 | nf_conntrack_event_cache(IPCT_NATINFO, *pskb); |
752 | #endif | 739 | #endif |
753 | nf_conntrack_event_cache(master_ct(ct) ? | 740 | nf_conntrack_event_cache(master_ct(ct) ? |
754 | IPCT_RELATED : IPCT_NEW, *pskb); | 741 | IPCT_RELATED : IPCT_NEW, *pskb); |
755 | return NF_ACCEPT; | 742 | return NF_ACCEPT; |
756 | } | ||
757 | 743 | ||
744 | out: | ||
758 | NF_CT_STAT_INC(insert_failed); | 745 | NF_CT_STAT_INC(insert_failed); |
759 | write_unlock_bh(&nf_conntrack_lock); | 746 | write_unlock_bh(&nf_conntrack_lock); |
760 | return NF_DROP; | 747 | return NF_DROP; |
@@ -777,24 +764,21 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, | |||
777 | 764 | ||
778 | /* There's a small race here where we may free a just-assured | 765 | /* There's a small race here where we may free a just-assured |
779 | connection. Too bad: we're in trouble anyway. */ | 766 | connection. Too bad: we're in trouble anyway. */ |
780 | static inline int unreplied(const struct nf_conntrack_tuple_hash *i) | ||
781 | { | ||
782 | return !(test_bit(IPS_ASSURED_BIT, | ||
783 | &nf_ct_tuplehash_to_ctrack(i)->status)); | ||
784 | } | ||
785 | |||
786 | static int early_drop(struct list_head *chain) | 767 | static int early_drop(struct list_head *chain) |
787 | { | 768 | { |
788 | /* Traverse backwards: gives us oldest, which is roughly LRU */ | 769 | /* Traverse backwards: gives us oldest, which is roughly LRU */ |
789 | struct nf_conntrack_tuple_hash *h; | 770 | struct nf_conntrack_tuple_hash *h; |
790 | struct nf_conn *ct = NULL; | 771 | struct nf_conn *ct = NULL, *tmp; |
791 | int dropped = 0; | 772 | int dropped = 0; |
792 | 773 | ||
793 | read_lock_bh(&nf_conntrack_lock); | 774 | read_lock_bh(&nf_conntrack_lock); |
794 | h = LIST_FIND_B(chain, unreplied, struct nf_conntrack_tuple_hash *); | 775 | list_for_each_entry_reverse(h, chain, list) { |
795 | if (h) { | 776 | tmp = nf_ct_tuplehash_to_ctrack(h); |
796 | ct = nf_ct_tuplehash_to_ctrack(h); | 777 | if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) { |
797 | atomic_inc(&ct->ct_general.use); | 778 | ct = tmp; |
779 | atomic_inc(&ct->ct_general.use); | ||
780 | break; | ||
781 | } | ||
798 | } | 782 | } |
799 | read_unlock_bh(&nf_conntrack_lock); | 783 | read_unlock_bh(&nf_conntrack_lock); |
800 | 784 | ||
@@ -810,18 +794,16 @@ static int early_drop(struct list_head *chain) | |||
810 | return dropped; | 794 | return dropped; |
811 | } | 795 | } |
812 | 796 | ||
813 | static inline int helper_cmp(const struct nf_conntrack_helper *i, | ||
814 | const struct nf_conntrack_tuple *rtuple) | ||
815 | { | ||
816 | return nf_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask); | ||
817 | } | ||
818 | |||
819 | static struct nf_conntrack_helper * | 797 | static struct nf_conntrack_helper * |
820 | __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple) | 798 | __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple) |
821 | { | 799 | { |
822 | return LIST_FIND(&helpers, helper_cmp, | 800 | struct nf_conntrack_helper *h; |
823 | struct nf_conntrack_helper *, | 801 | |
824 | tuple); | 802 | list_for_each_entry(h, &helpers, list) { |
803 | if (nf_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask)) | ||
804 | return h; | ||
805 | } | ||
806 | return NULL; | ||
825 | } | 807 | } |
826 | 808 | ||
827 | struct nf_conntrack_helper * | 809 | struct nf_conntrack_helper * |
@@ -1323,7 +1305,7 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me) | |||
1323 | return ret; | 1305 | return ret; |
1324 | } | 1306 | } |
1325 | write_lock_bh(&nf_conntrack_lock); | 1307 | write_lock_bh(&nf_conntrack_lock); |
1326 | list_prepend(&helpers, me); | 1308 | list_add(&me->list, &helpers); |
1327 | write_unlock_bh(&nf_conntrack_lock); | 1309 | write_unlock_bh(&nf_conntrack_lock); |
1328 | 1310 | ||
1329 | return 0; | 1311 | return 0; |
@@ -1342,8 +1324,8 @@ __nf_conntrack_helper_find_byname(const char *name) | |||
1342 | return NULL; | 1324 | return NULL; |
1343 | } | 1325 | } |
1344 | 1326 | ||
1345 | static inline int unhelp(struct nf_conntrack_tuple_hash *i, | 1327 | static inline void unhelp(struct nf_conntrack_tuple_hash *i, |
1346 | const struct nf_conntrack_helper *me) | 1328 | const struct nf_conntrack_helper *me) |
1347 | { | 1329 | { |
1348 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i); | 1330 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i); |
1349 | struct nf_conn_help *help = nfct_help(ct); | 1331 | struct nf_conn_help *help = nfct_help(ct); |
@@ -1352,17 +1334,17 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i, | |||
1352 | nf_conntrack_event(IPCT_HELPER, ct); | 1334 | nf_conntrack_event(IPCT_HELPER, ct); |
1353 | help->helper = NULL; | 1335 | help->helper = NULL; |
1354 | } | 1336 | } |
1355 | return 0; | ||
1356 | } | 1337 | } |
1357 | 1338 | ||
1358 | void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) | 1339 | void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) |
1359 | { | 1340 | { |
1360 | unsigned int i; | 1341 | unsigned int i; |
1342 | struct nf_conntrack_tuple_hash *h; | ||
1361 | struct nf_conntrack_expect *exp, *tmp; | 1343 | struct nf_conntrack_expect *exp, *tmp; |
1362 | 1344 | ||
1363 | /* Need write lock here, to delete helper. */ | 1345 | /* Need write lock here, to delete helper. */ |
1364 | write_lock_bh(&nf_conntrack_lock); | 1346 | write_lock_bh(&nf_conntrack_lock); |
1365 | LIST_DELETE(&helpers, me); | 1347 | list_del(&me->list); |
1366 | 1348 | ||
1367 | /* Get rid of expectations */ | 1349 | /* Get rid of expectations */ |
1368 | list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) { | 1350 | list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) { |
@@ -1374,10 +1356,12 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) | |||
1374 | } | 1356 | } |
1375 | 1357 | ||
1376 | /* Get rid of expecteds, set helpers to NULL. */ | 1358 | /* Get rid of expecteds, set helpers to NULL. */ |
1377 | LIST_FIND_W(&unconfirmed, unhelp, struct nf_conntrack_tuple_hash*, me); | 1359 | list_for_each_entry(h, &unconfirmed, list) |
1378 | for (i = 0; i < nf_conntrack_htable_size; i++) | 1360 | unhelp(h, me); |
1379 | LIST_FIND_W(&nf_conntrack_hash[i], unhelp, | 1361 | for (i = 0; i < nf_conntrack_htable_size; i++) { |
1380 | struct nf_conntrack_tuple_hash *, me); | 1362 | list_for_each_entry(h, &nf_conntrack_hash[i], list) |
1363 | unhelp(h, me); | ||
1364 | } | ||
1381 | write_unlock_bh(&nf_conntrack_lock); | 1365 | write_unlock_bh(&nf_conntrack_lock); |
1382 | 1366 | ||
1383 | /* Someone could be still looking at the helper in a bh. */ | 1367 | /* Someone could be still looking at the helper in a bh. */ |
@@ -1510,37 +1494,40 @@ do_iter(const struct nf_conntrack_tuple_hash *i, | |||
1510 | } | 1494 | } |
1511 | 1495 | ||
1512 | /* Bring out ya dead! */ | 1496 | /* Bring out ya dead! */ |
1513 | static struct nf_conntrack_tuple_hash * | 1497 | static struct nf_conn * |
1514 | get_next_corpse(int (*iter)(struct nf_conn *i, void *data), | 1498 | get_next_corpse(int (*iter)(struct nf_conn *i, void *data), |
1515 | void *data, unsigned int *bucket) | 1499 | void *data, unsigned int *bucket) |
1516 | { | 1500 | { |
1517 | struct nf_conntrack_tuple_hash *h = NULL; | 1501 | struct nf_conntrack_tuple_hash *h; |
1502 | struct nf_conn *ct; | ||
1518 | 1503 | ||
1519 | write_lock_bh(&nf_conntrack_lock); | 1504 | write_lock_bh(&nf_conntrack_lock); |
1520 | for (; *bucket < nf_conntrack_htable_size; (*bucket)++) { | 1505 | for (; *bucket < nf_conntrack_htable_size; (*bucket)++) { |
1521 | h = LIST_FIND_W(&nf_conntrack_hash[*bucket], do_iter, | 1506 | list_for_each_entry(h, &nf_conntrack_hash[*bucket], list) { |
1522 | struct nf_conntrack_tuple_hash *, iter, data); | 1507 | ct = nf_ct_tuplehash_to_ctrack(h); |
1523 | if (h) | 1508 | if (iter(ct, data)) |
1524 | break; | 1509 | goto found; |
1510 | } | ||
1525 | } | 1511 | } |
1526 | if (!h) | 1512 | list_for_each_entry(h, &unconfirmed, list) { |
1527 | h = LIST_FIND_W(&unconfirmed, do_iter, | 1513 | ct = nf_ct_tuplehash_to_ctrack(h); |
1528 | struct nf_conntrack_tuple_hash *, iter, data); | 1514 | if (iter(ct, data)) |
1529 | if (h) | 1515 | goto found; |
1530 | atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use); | 1516 | } |
1517 | return NULL; | ||
1518 | found: | ||
1519 | atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use); | ||
1531 | write_unlock_bh(&nf_conntrack_lock); | 1520 | write_unlock_bh(&nf_conntrack_lock); |
1532 | 1521 | return ct; | |
1533 | return h; | ||
1534 | } | 1522 | } |
1535 | 1523 | ||
1536 | void | 1524 | void |
1537 | nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data) | 1525 | nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data) |
1538 | { | 1526 | { |
1539 | struct nf_conntrack_tuple_hash *h; | 1527 | struct nf_conn *ct; |
1540 | unsigned int bucket = 0; | 1528 | unsigned int bucket = 0; |
1541 | 1529 | ||
1542 | while ((h = get_next_corpse(iter, data, &bucket)) != NULL) { | 1530 | while ((ct = get_next_corpse(iter, data, &bucket)) != NULL) { |
1543 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); | ||
1544 | /* Time to push up daises... */ | 1531 | /* Time to push up daises... */ |
1545 | if (del_timer(&ct->timeout)) | 1532 | if (del_timer(&ct->timeout)) |
1546 | death_by_timeout((unsigned long)ct); | 1533 | death_by_timeout((unsigned long)ct); |
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 9a1de0ca475b..5954f6773810 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <net/netfilter/nf_conntrack_protocol.h> | 37 | #include <net/netfilter/nf_conntrack_protocol.h> |
38 | #include <net/netfilter/nf_conntrack_core.h> | 38 | #include <net/netfilter/nf_conntrack_core.h> |
39 | #include <net/netfilter/nf_conntrack_helper.h> | 39 | #include <net/netfilter/nf_conntrack_helper.h> |
40 | #include <linux/netfilter_ipv4/listhelp.h> | ||
41 | 40 | ||
42 | #if 0 | 41 | #if 0 |
43 | #define DEBUGP printk | 42 | #define DEBUGP printk |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 8037ba63d587..be7baf4f6846 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -81,7 +81,7 @@ xt_unregister_target(struct xt_target *target) | |||
81 | int af = target->family; | 81 | int af = target->family; |
82 | 82 | ||
83 | mutex_lock(&xt[af].mutex); | 83 | mutex_lock(&xt[af].mutex); |
84 | LIST_DELETE(&xt[af].target, target); | 84 | list_del(&target->list); |
85 | mutex_unlock(&xt[af].mutex); | 85 | mutex_unlock(&xt[af].mutex); |
86 | } | 86 | } |
87 | EXPORT_SYMBOL(xt_unregister_target); | 87 | EXPORT_SYMBOL(xt_unregister_target); |
@@ -138,7 +138,7 @@ xt_unregister_match(struct xt_match *match) | |||
138 | int af = match->family; | 138 | int af = match->family; |
139 | 139 | ||
140 | mutex_lock(&xt[af].mutex); | 140 | mutex_lock(&xt[af].mutex); |
141 | LIST_DELETE(&xt[af].match, match); | 141 | list_del(&match->list); |
142 | mutex_unlock(&xt[af].mutex); | 142 | mutex_unlock(&xt[af].mutex); |
143 | } | 143 | } |
144 | EXPORT_SYMBOL(xt_unregister_match); | 144 | EXPORT_SYMBOL(xt_unregister_match); |
@@ -575,15 +575,18 @@ int xt_register_table(struct xt_table *table, | |||
575 | { | 575 | { |
576 | int ret; | 576 | int ret; |
577 | struct xt_table_info *private; | 577 | struct xt_table_info *private; |
578 | struct xt_table *t; | ||
578 | 579 | ||
579 | ret = mutex_lock_interruptible(&xt[table->af].mutex); | 580 | ret = mutex_lock_interruptible(&xt[table->af].mutex); |
580 | if (ret != 0) | 581 | if (ret != 0) |
581 | return ret; | 582 | return ret; |
582 | 583 | ||
583 | /* Don't autoload: we'd eat our tail... */ | 584 | /* Don't autoload: we'd eat our tail... */ |
584 | if (list_named_find(&xt[table->af].tables, table->name)) { | 585 | list_for_each_entry(t, &xt[table->af].tables, list) { |
585 | ret = -EEXIST; | 586 | if (strcmp(t->name, table->name) == 0) { |
586 | goto unlock; | 587 | ret = -EEXIST; |
588 | goto unlock; | ||
589 | } | ||
587 | } | 590 | } |
588 | 591 | ||
589 | /* Simplifies replace_table code. */ | 592 | /* Simplifies replace_table code. */ |
@@ -598,7 +601,7 @@ int xt_register_table(struct xt_table *table, | |||
598 | /* save number of initial entries */ | 601 | /* save number of initial entries */ |
599 | private->initial_entries = private->number; | 602 | private->initial_entries = private->number; |
600 | 603 | ||
601 | list_prepend(&xt[table->af].tables, table); | 604 | list_add(&table->list, &xt[table->af].tables); |
602 | 605 | ||
603 | ret = 0; | 606 | ret = 0; |
604 | unlock: | 607 | unlock: |
@@ -613,7 +616,7 @@ void *xt_unregister_table(struct xt_table *table) | |||
613 | 616 | ||
614 | mutex_lock(&xt[table->af].mutex); | 617 | mutex_lock(&xt[table->af].mutex); |
615 | private = table->private; | 618 | private = table->private; |
616 | LIST_DELETE(&xt[table->af].tables, table); | 619 | list_del(&table->list); |
617 | mutex_unlock(&xt[table->af].mutex); | 620 | mutex_unlock(&xt[table->af].mutex); |
618 | 621 | ||
619 | return private; | 622 | return private; |