diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 76 |
1 files changed, 45 insertions, 31 deletions
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; |