diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 91 |
1 files changed, 46 insertions, 45 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index cbd4020cc84d..4b178b4a2a95 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #define ASSERT_READ_LOCK(x) | 35 | #define ASSERT_READ_LOCK(x) |
36 | #define ASSERT_WRITE_LOCK(x) | 36 | #define ASSERT_WRITE_LOCK(x) |
37 | #include <linux/netfilter_ipv4/listhelp.h> | 37 | #include <linux/netfilter_ipv4/listhelp.h> |
38 | #include <linux/mutex.h> | ||
38 | 39 | ||
39 | #if 0 | 40 | #if 0 |
40 | /* use this for remote debugging | 41 | /* use this for remote debugging |
@@ -81,7 +82,7 @@ static void print_string(char *str) | |||
81 | 82 | ||
82 | 83 | ||
83 | 84 | ||
84 | static DECLARE_MUTEX(ebt_mutex); | 85 | static DEFINE_MUTEX(ebt_mutex); |
85 | static LIST_HEAD(ebt_tables); | 86 | static LIST_HEAD(ebt_tables); |
86 | static LIST_HEAD(ebt_targets); | 87 | static LIST_HEAD(ebt_targets); |
87 | static LIST_HEAD(ebt_matches); | 88 | static LIST_HEAD(ebt_matches); |
@@ -296,18 +297,18 @@ letscontinue: | |||
296 | /* If it succeeds, returns element and locks mutex */ | 297 | /* If it succeeds, returns element and locks mutex */ |
297 | static inline void * | 298 | static inline void * |
298 | find_inlist_lock_noload(struct list_head *head, const char *name, int *error, | 299 | find_inlist_lock_noload(struct list_head *head, const char *name, int *error, |
299 | struct semaphore *mutex) | 300 | struct mutex *mutex) |
300 | { | 301 | { |
301 | void *ret; | 302 | void *ret; |
302 | 303 | ||
303 | *error = down_interruptible(mutex); | 304 | *error = mutex_lock_interruptible(mutex); |
304 | if (*error != 0) | 305 | if (*error != 0) |
305 | return NULL; | 306 | return NULL; |
306 | 307 | ||
307 | ret = list_named_find(head, name); | 308 | ret = list_named_find(head, name); |
308 | if (!ret) { | 309 | if (!ret) { |
309 | *error = -ENOENT; | 310 | *error = -ENOENT; |
310 | up(mutex); | 311 | mutex_unlock(mutex); |
311 | } | 312 | } |
312 | return ret; | 313 | return ret; |
313 | } | 314 | } |
@@ -317,7 +318,7 @@ find_inlist_lock_noload(struct list_head *head, const char *name, int *error, | |||
317 | #else | 318 | #else |
318 | static void * | 319 | static void * |
319 | find_inlist_lock(struct list_head *head, const char *name, const char *prefix, | 320 | find_inlist_lock(struct list_head *head, const char *name, const char *prefix, |
320 | int *error, struct semaphore *mutex) | 321 | int *error, struct mutex *mutex) |
321 | { | 322 | { |
322 | void *ret; | 323 | void *ret; |
323 | 324 | ||
@@ -331,25 +332,25 @@ find_inlist_lock(struct list_head *head, const char *name, const char *prefix, | |||
331 | #endif | 332 | #endif |
332 | 333 | ||
333 | static inline struct ebt_table * | 334 | static inline struct ebt_table * |
334 | find_table_lock(const char *name, int *error, struct semaphore *mutex) | 335 | find_table_lock(const char *name, int *error, struct mutex *mutex) |
335 | { | 336 | { |
336 | return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); | 337 | return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); |
337 | } | 338 | } |
338 | 339 | ||
339 | static inline struct ebt_match * | 340 | static inline struct ebt_match * |
340 | find_match_lock(const char *name, int *error, struct semaphore *mutex) | 341 | find_match_lock(const char *name, int *error, struct mutex *mutex) |
341 | { | 342 | { |
342 | return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex); | 343 | return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex); |
343 | } | 344 | } |
344 | 345 | ||
345 | static inline struct ebt_watcher * | 346 | static inline struct ebt_watcher * |
346 | find_watcher_lock(const char *name, int *error, struct semaphore *mutex) | 347 | find_watcher_lock(const char *name, int *error, struct mutex *mutex) |
347 | { | 348 | { |
348 | return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex); | 349 | return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex); |
349 | } | 350 | } |
350 | 351 | ||
351 | static inline struct ebt_target * | 352 | static inline struct ebt_target * |
352 | find_target_lock(const char *name, int *error, struct semaphore *mutex) | 353 | find_target_lock(const char *name, int *error, struct mutex *mutex) |
353 | { | 354 | { |
354 | return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex); | 355 | return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex); |
355 | } | 356 | } |
@@ -369,10 +370,10 @@ ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, | |||
369 | return ret; | 370 | return ret; |
370 | m->u.match = match; | 371 | m->u.match = match; |
371 | if (!try_module_get(match->me)) { | 372 | if (!try_module_get(match->me)) { |
372 | up(&ebt_mutex); | 373 | mutex_unlock(&ebt_mutex); |
373 | return -ENOENT; | 374 | return -ENOENT; |
374 | } | 375 | } |
375 | up(&ebt_mutex); | 376 | mutex_unlock(&ebt_mutex); |
376 | if (match->check && | 377 | if (match->check && |
377 | match->check(name, hookmask, e, m->data, m->match_size) != 0) { | 378 | match->check(name, hookmask, e, m->data, m->match_size) != 0) { |
378 | BUGPRINT("match->check failed\n"); | 379 | BUGPRINT("match->check failed\n"); |
@@ -398,10 +399,10 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, | |||
398 | return ret; | 399 | return ret; |
399 | w->u.watcher = watcher; | 400 | w->u.watcher = watcher; |
400 | if (!try_module_get(watcher->me)) { | 401 | if (!try_module_get(watcher->me)) { |
401 | up(&ebt_mutex); | 402 | mutex_unlock(&ebt_mutex); |
402 | return -ENOENT; | 403 | return -ENOENT; |
403 | } | 404 | } |
404 | up(&ebt_mutex); | 405 | mutex_unlock(&ebt_mutex); |
405 | if (watcher->check && | 406 | if (watcher->check && |
406 | watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) { | 407 | watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) { |
407 | BUGPRINT("watcher->check failed\n"); | 408 | BUGPRINT("watcher->check failed\n"); |
@@ -638,11 +639,11 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
638 | if (!target) | 639 | if (!target) |
639 | goto cleanup_watchers; | 640 | goto cleanup_watchers; |
640 | if (!try_module_get(target->me)) { | 641 | if (!try_module_get(target->me)) { |
641 | up(&ebt_mutex); | 642 | mutex_unlock(&ebt_mutex); |
642 | ret = -ENOENT; | 643 | ret = -ENOENT; |
643 | goto cleanup_watchers; | 644 | goto cleanup_watchers; |
644 | } | 645 | } |
645 | up(&ebt_mutex); | 646 | mutex_unlock(&ebt_mutex); |
646 | 647 | ||
647 | t->u.target = target; | 648 | t->u.target = target; |
648 | if (t->u.target == &ebt_standard_target) { | 649 | if (t->u.target == &ebt_standard_target) { |
@@ -1015,7 +1016,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1015 | 1016 | ||
1016 | t->private = newinfo; | 1017 | t->private = newinfo; |
1017 | write_unlock_bh(&t->lock); | 1018 | write_unlock_bh(&t->lock); |
1018 | up(&ebt_mutex); | 1019 | mutex_unlock(&ebt_mutex); |
1019 | /* so, a user can change the chains while having messed up her counter | 1020 | /* so, a user can change the chains while having messed up her counter |
1020 | allocation. Only reason why this is done is because this way the lock | 1021 | allocation. Only reason why this is done is because this way the lock |
1021 | is held only once, while this doesn't bring the kernel into a | 1022 | is held only once, while this doesn't bring the kernel into a |
@@ -1045,7 +1046,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1045 | return ret; | 1046 | return ret; |
1046 | 1047 | ||
1047 | free_unlock: | 1048 | free_unlock: |
1048 | up(&ebt_mutex); | 1049 | mutex_unlock(&ebt_mutex); |
1049 | free_iterate: | 1050 | free_iterate: |
1050 | EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, | 1051 | EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, |
1051 | ebt_cleanup_entry, NULL); | 1052 | ebt_cleanup_entry, NULL); |
@@ -1068,69 +1069,69 @@ int ebt_register_target(struct ebt_target *target) | |||
1068 | { | 1069 | { |
1069 | int ret; | 1070 | int ret; |
1070 | 1071 | ||
1071 | ret = down_interruptible(&ebt_mutex); | 1072 | ret = mutex_lock_interruptible(&ebt_mutex); |
1072 | if (ret != 0) | 1073 | if (ret != 0) |
1073 | return ret; | 1074 | return ret; |
1074 | if (!list_named_insert(&ebt_targets, target)) { | 1075 | if (!list_named_insert(&ebt_targets, target)) { |
1075 | up(&ebt_mutex); | 1076 | mutex_unlock(&ebt_mutex); |
1076 | return -EEXIST; | 1077 | return -EEXIST; |
1077 | } | 1078 | } |
1078 | up(&ebt_mutex); | 1079 | mutex_unlock(&ebt_mutex); |
1079 | 1080 | ||
1080 | return 0; | 1081 | return 0; |
1081 | } | 1082 | } |
1082 | 1083 | ||
1083 | void ebt_unregister_target(struct ebt_target *target) | 1084 | void ebt_unregister_target(struct ebt_target *target) |
1084 | { | 1085 | { |
1085 | down(&ebt_mutex); | 1086 | mutex_lock(&ebt_mutex); |
1086 | LIST_DELETE(&ebt_targets, target); | 1087 | LIST_DELETE(&ebt_targets, target); |
1087 | up(&ebt_mutex); | 1088 | mutex_unlock(&ebt_mutex); |
1088 | } | 1089 | } |
1089 | 1090 | ||
1090 | int ebt_register_match(struct ebt_match *match) | 1091 | int ebt_register_match(struct ebt_match *match) |
1091 | { | 1092 | { |
1092 | int ret; | 1093 | int ret; |
1093 | 1094 | ||
1094 | ret = down_interruptible(&ebt_mutex); | 1095 | ret = mutex_lock_interruptible(&ebt_mutex); |
1095 | if (ret != 0) | 1096 | if (ret != 0) |
1096 | return ret; | 1097 | return ret; |
1097 | if (!list_named_insert(&ebt_matches, match)) { | 1098 | if (!list_named_insert(&ebt_matches, match)) { |
1098 | up(&ebt_mutex); | 1099 | mutex_unlock(&ebt_mutex); |
1099 | return -EEXIST; | 1100 | return -EEXIST; |
1100 | } | 1101 | } |
1101 | up(&ebt_mutex); | 1102 | mutex_unlock(&ebt_mutex); |
1102 | 1103 | ||
1103 | return 0; | 1104 | return 0; |
1104 | } | 1105 | } |
1105 | 1106 | ||
1106 | void ebt_unregister_match(struct ebt_match *match) | 1107 | void ebt_unregister_match(struct ebt_match *match) |
1107 | { | 1108 | { |
1108 | down(&ebt_mutex); | 1109 | mutex_lock(&ebt_mutex); |
1109 | LIST_DELETE(&ebt_matches, match); | 1110 | LIST_DELETE(&ebt_matches, match); |
1110 | up(&ebt_mutex); | 1111 | mutex_unlock(&ebt_mutex); |
1111 | } | 1112 | } |
1112 | 1113 | ||
1113 | int ebt_register_watcher(struct ebt_watcher *watcher) | 1114 | int ebt_register_watcher(struct ebt_watcher *watcher) |
1114 | { | 1115 | { |
1115 | int ret; | 1116 | int ret; |
1116 | 1117 | ||
1117 | ret = down_interruptible(&ebt_mutex); | 1118 | ret = mutex_lock_interruptible(&ebt_mutex); |
1118 | if (ret != 0) | 1119 | if (ret != 0) |
1119 | return ret; | 1120 | return ret; |
1120 | if (!list_named_insert(&ebt_watchers, watcher)) { | 1121 | if (!list_named_insert(&ebt_watchers, watcher)) { |
1121 | up(&ebt_mutex); | 1122 | mutex_unlock(&ebt_mutex); |
1122 | return -EEXIST; | 1123 | return -EEXIST; |
1123 | } | 1124 | } |
1124 | up(&ebt_mutex); | 1125 | mutex_unlock(&ebt_mutex); |
1125 | 1126 | ||
1126 | return 0; | 1127 | return 0; |
1127 | } | 1128 | } |
1128 | 1129 | ||
1129 | void ebt_unregister_watcher(struct ebt_watcher *watcher) | 1130 | void ebt_unregister_watcher(struct ebt_watcher *watcher) |
1130 | { | 1131 | { |
1131 | down(&ebt_mutex); | 1132 | mutex_lock(&ebt_mutex); |
1132 | LIST_DELETE(&ebt_watchers, watcher); | 1133 | LIST_DELETE(&ebt_watchers, watcher); |
1133 | up(&ebt_mutex); | 1134 | mutex_unlock(&ebt_mutex); |
1134 | } | 1135 | } |
1135 | 1136 | ||
1136 | int ebt_register_table(struct ebt_table *table) | 1137 | int ebt_register_table(struct ebt_table *table) |
@@ -1178,7 +1179,7 @@ int ebt_register_table(struct ebt_table *table) | |||
1178 | 1179 | ||
1179 | table->private = newinfo; | 1180 | table->private = newinfo; |
1180 | rwlock_init(&table->lock); | 1181 | rwlock_init(&table->lock); |
1181 | ret = down_interruptible(&ebt_mutex); | 1182 | ret = mutex_lock_interruptible(&ebt_mutex); |
1182 | if (ret != 0) | 1183 | if (ret != 0) |
1183 | goto free_chainstack; | 1184 | goto free_chainstack; |
1184 | 1185 | ||
@@ -1194,10 +1195,10 @@ int ebt_register_table(struct ebt_table *table) | |||
1194 | goto free_unlock; | 1195 | goto free_unlock; |
1195 | } | 1196 | } |
1196 | list_prepend(&ebt_tables, table); | 1197 | list_prepend(&ebt_tables, table); |
1197 | up(&ebt_mutex); | 1198 | mutex_unlock(&ebt_mutex); |
1198 | return 0; | 1199 | return 0; |
1199 | free_unlock: | 1200 | free_unlock: |
1200 | up(&ebt_mutex); | 1201 | mutex_unlock(&ebt_mutex); |
1201 | free_chainstack: | 1202 | free_chainstack: |
1202 | if (newinfo->chainstack) { | 1203 | if (newinfo->chainstack) { |
1203 | for_each_cpu(i) | 1204 | for_each_cpu(i) |
@@ -1218,9 +1219,9 @@ void ebt_unregister_table(struct ebt_table *table) | |||
1218 | BUGPRINT("Request to unregister NULL table!!!\n"); | 1219 | BUGPRINT("Request to unregister NULL table!!!\n"); |
1219 | return; | 1220 | return; |
1220 | } | 1221 | } |
1221 | down(&ebt_mutex); | 1222 | mutex_lock(&ebt_mutex); |
1222 | LIST_DELETE(&ebt_tables, table); | 1223 | LIST_DELETE(&ebt_tables, table); |
1223 | up(&ebt_mutex); | 1224 | mutex_unlock(&ebt_mutex); |
1224 | vfree(table->private->entries); | 1225 | vfree(table->private->entries); |
1225 | if (table->private->chainstack) { | 1226 | if (table->private->chainstack) { |
1226 | for_each_cpu(i) | 1227 | for_each_cpu(i) |
@@ -1281,7 +1282,7 @@ static int update_counters(void __user *user, unsigned int len) | |||
1281 | write_unlock_bh(&t->lock); | 1282 | write_unlock_bh(&t->lock); |
1282 | ret = 0; | 1283 | ret = 0; |
1283 | unlock_mutex: | 1284 | unlock_mutex: |
1284 | up(&ebt_mutex); | 1285 | mutex_unlock(&ebt_mutex); |
1285 | free_tmp: | 1286 | free_tmp: |
1286 | vfree(tmp); | 1287 | vfree(tmp); |
1287 | return ret; | 1288 | return ret; |
@@ -1328,7 +1329,7 @@ static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase) | |||
1328 | return 0; | 1329 | return 0; |
1329 | } | 1330 | } |
1330 | 1331 | ||
1331 | /* called with ebt_mutex down */ | 1332 | /* called with ebt_mutex locked */ |
1332 | static int copy_everything_to_user(struct ebt_table *t, void __user *user, | 1333 | static int copy_everything_to_user(struct ebt_table *t, void __user *user, |
1333 | int *len, int cmd) | 1334 | int *len, int cmd) |
1334 | { | 1335 | { |
@@ -1440,7 +1441,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1440 | case EBT_SO_GET_INIT_INFO: | 1441 | case EBT_SO_GET_INIT_INFO: |
1441 | if (*len != sizeof(struct ebt_replace)){ | 1442 | if (*len != sizeof(struct ebt_replace)){ |
1442 | ret = -EINVAL; | 1443 | ret = -EINVAL; |
1443 | up(&ebt_mutex); | 1444 | mutex_unlock(&ebt_mutex); |
1444 | break; | 1445 | break; |
1445 | } | 1446 | } |
1446 | if (cmd == EBT_SO_GET_INFO) { | 1447 | if (cmd == EBT_SO_GET_INFO) { |
@@ -1452,7 +1453,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1452 | tmp.entries_size = t->table->entries_size; | 1453 | tmp.entries_size = t->table->entries_size; |
1453 | tmp.valid_hooks = t->table->valid_hooks; | 1454 | tmp.valid_hooks = t->table->valid_hooks; |
1454 | } | 1455 | } |
1455 | up(&ebt_mutex); | 1456 | mutex_unlock(&ebt_mutex); |
1456 | if (copy_to_user(user, &tmp, *len) != 0){ | 1457 | if (copy_to_user(user, &tmp, *len) != 0){ |
1457 | BUGPRINT("c2u Didn't work\n"); | 1458 | BUGPRINT("c2u Didn't work\n"); |
1458 | ret = -EFAULT; | 1459 | ret = -EFAULT; |
@@ -1464,11 +1465,11 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1464 | case EBT_SO_GET_ENTRIES: | 1465 | case EBT_SO_GET_ENTRIES: |
1465 | case EBT_SO_GET_INIT_ENTRIES: | 1466 | case EBT_SO_GET_INIT_ENTRIES: |
1466 | ret = copy_everything_to_user(t, user, len, cmd); | 1467 | ret = copy_everything_to_user(t, user, len, cmd); |
1467 | up(&ebt_mutex); | 1468 | mutex_unlock(&ebt_mutex); |
1468 | break; | 1469 | break; |
1469 | 1470 | ||
1470 | default: | 1471 | default: |
1471 | up(&ebt_mutex); | 1472 | mutex_unlock(&ebt_mutex); |
1472 | ret = -EINVAL; | 1473 | ret = -EINVAL; |
1473 | } | 1474 | } |
1474 | 1475 | ||
@@ -1484,9 +1485,9 @@ static int __init init(void) | |||
1484 | { | 1485 | { |
1485 | int ret; | 1486 | int ret; |
1486 | 1487 | ||
1487 | down(&ebt_mutex); | 1488 | mutex_lock(&ebt_mutex); |
1488 | list_named_insert(&ebt_targets, &ebt_standard_target); | 1489 | list_named_insert(&ebt_targets, &ebt_standard_target); |
1489 | up(&ebt_mutex); | 1490 | mutex_unlock(&ebt_mutex); |
1490 | if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) | 1491 | if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) |
1491 | return ret; | 1492 | return ret; |
1492 | 1493 | ||