aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/netfilter/ebtables.c91
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
84static DECLARE_MUTEX(ebt_mutex); 85static DEFINE_MUTEX(ebt_mutex);
85static LIST_HEAD(ebt_tables); 86static LIST_HEAD(ebt_tables);
86static LIST_HEAD(ebt_targets); 87static LIST_HEAD(ebt_targets);
87static LIST_HEAD(ebt_matches); 88static 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 */
297static inline void * 298static inline void *
298find_inlist_lock_noload(struct list_head *head, const char *name, int *error, 299find_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
318static void * 319static void *
319find_inlist_lock(struct list_head *head, const char *name, const char *prefix, 320find_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
333static inline struct ebt_table * 334static inline struct ebt_table *
334find_table_lock(const char *name, int *error, struct semaphore *mutex) 335find_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
339static inline struct ebt_match * 340static inline struct ebt_match *
340find_match_lock(const char *name, int *error, struct semaphore *mutex) 341find_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
345static inline struct ebt_watcher * 346static inline struct ebt_watcher *
346find_watcher_lock(const char *name, int *error, struct semaphore *mutex) 347find_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
351static inline struct ebt_target * 352static inline struct ebt_target *
352find_target_lock(const char *name, int *error, struct semaphore *mutex) 353find_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
1047free_unlock: 1048free_unlock:
1048 up(&ebt_mutex); 1049 mutex_unlock(&ebt_mutex);
1049free_iterate: 1050free_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
1083void ebt_unregister_target(struct ebt_target *target) 1084void 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
1090int ebt_register_match(struct ebt_match *match) 1091int 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
1106void ebt_unregister_match(struct ebt_match *match) 1107void 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
1113int ebt_register_watcher(struct ebt_watcher *watcher) 1114int 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
1129void ebt_unregister_watcher(struct ebt_watcher *watcher) 1130void 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
1136int ebt_register_table(struct ebt_table *table) 1137int 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;
1199free_unlock: 1200free_unlock:
1200 up(&ebt_mutex); 1201 mutex_unlock(&ebt_mutex);
1201free_chainstack: 1202free_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;
1283unlock_mutex: 1284unlock_mutex:
1284 up(&ebt_mutex); 1285 mutex_unlock(&ebt_mutex);
1285free_tmp: 1286free_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 */
1332static int copy_everything_to_user(struct ebt_table *t, void __user *user, 1333static 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