diff options
Diffstat (limited to 'net/netlabel/netlabel_domainhash.c')
-rw-r--r-- | net/netlabel/netlabel_domainhash.c | 37 |
1 files changed, 11 insertions, 26 deletions
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index b6c844b7e1c1..b3675bd7db33 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
@@ -178,11 +178,9 @@ int netlbl_domhsh_init(u32 size) | |||
178 | for (iter = 0; iter < hsh_tbl->size; iter++) | 178 | for (iter = 0; iter < hsh_tbl->size; iter++) |
179 | INIT_LIST_HEAD(&hsh_tbl->tbl[iter]); | 179 | INIT_LIST_HEAD(&hsh_tbl->tbl[iter]); |
180 | 180 | ||
181 | rcu_read_lock(); | ||
182 | spin_lock(&netlbl_domhsh_lock); | 181 | spin_lock(&netlbl_domhsh_lock); |
183 | rcu_assign_pointer(netlbl_domhsh, hsh_tbl); | 182 | rcu_assign_pointer(netlbl_domhsh, hsh_tbl); |
184 | spin_unlock(&netlbl_domhsh_lock); | 183 | spin_unlock(&netlbl_domhsh_lock); |
185 | rcu_read_unlock(); | ||
186 | 184 | ||
187 | return 0; | 185 | return 0; |
188 | } | 186 | } |
@@ -222,7 +220,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
222 | entry->valid = 1; | 220 | entry->valid = 1; |
223 | INIT_RCU_HEAD(&entry->rcu); | 221 | INIT_RCU_HEAD(&entry->rcu); |
224 | 222 | ||
225 | ret_val = 0; | ||
226 | rcu_read_lock(); | 223 | rcu_read_lock(); |
227 | if (entry->domain != NULL) { | 224 | if (entry->domain != NULL) { |
228 | bkt = netlbl_domhsh_hash(entry->domain); | 225 | bkt = netlbl_domhsh_hash(entry->domain); |
@@ -233,7 +230,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
233 | else | 230 | else |
234 | ret_val = -EEXIST; | 231 | ret_val = -EEXIST; |
235 | spin_unlock(&netlbl_domhsh_lock); | 232 | spin_unlock(&netlbl_domhsh_lock); |
236 | } else if (entry->domain == NULL) { | 233 | } else { |
237 | INIT_LIST_HEAD(&entry->list); | 234 | INIT_LIST_HEAD(&entry->list); |
238 | spin_lock(&netlbl_domhsh_def_lock); | 235 | spin_lock(&netlbl_domhsh_def_lock); |
239 | if (rcu_dereference(netlbl_domhsh_def) == NULL) | 236 | if (rcu_dereference(netlbl_domhsh_def) == NULL) |
@@ -241,9 +238,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
241 | else | 238 | else |
242 | ret_val = -EEXIST; | 239 | ret_val = -EEXIST; |
243 | spin_unlock(&netlbl_domhsh_def_lock); | 240 | spin_unlock(&netlbl_domhsh_def_lock); |
244 | } else | 241 | } |
245 | ret_val = -EINVAL; | ||
246 | |||
247 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info); | 242 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info); |
248 | if (audit_buf != NULL) { | 243 | if (audit_buf != NULL) { |
249 | audit_log_format(audit_buf, | 244 | audit_log_format(audit_buf, |
@@ -262,7 +257,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
262 | audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); | 257 | audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); |
263 | audit_log_end(audit_buf); | 258 | audit_log_end(audit_buf); |
264 | } | 259 | } |
265 | |||
266 | rcu_read_unlock(); | 260 | rcu_read_unlock(); |
267 | 261 | ||
268 | if (ret_val != 0) { | 262 | if (ret_val != 0) { |
@@ -313,38 +307,30 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) | |||
313 | struct audit_buffer *audit_buf; | 307 | struct audit_buffer *audit_buf; |
314 | 308 | ||
315 | rcu_read_lock(); | 309 | rcu_read_lock(); |
316 | if (domain != NULL) | 310 | entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1)); |
317 | entry = netlbl_domhsh_search(domain, 0); | ||
318 | else | ||
319 | entry = netlbl_domhsh_search(domain, 1); | ||
320 | if (entry == NULL) | 311 | if (entry == NULL) |
321 | goto remove_return; | 312 | goto remove_return; |
322 | switch (entry->type) { | 313 | switch (entry->type) { |
323 | case NETLBL_NLTYPE_UNLABELED: | ||
324 | break; | ||
325 | case NETLBL_NLTYPE_CIPSOV4: | 314 | case NETLBL_NLTYPE_CIPSOV4: |
326 | ret_val = cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, | 315 | cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, |
327 | entry->domain); | 316 | entry->domain); |
328 | if (ret_val != 0) | ||
329 | goto remove_return; | ||
330 | break; | 317 | break; |
331 | } | 318 | } |
332 | ret_val = 0; | ||
333 | if (entry != rcu_dereference(netlbl_domhsh_def)) { | 319 | if (entry != rcu_dereference(netlbl_domhsh_def)) { |
334 | spin_lock(&netlbl_domhsh_lock); | 320 | spin_lock(&netlbl_domhsh_lock); |
335 | if (entry->valid) { | 321 | if (entry->valid) { |
336 | entry->valid = 0; | 322 | entry->valid = 0; |
337 | list_del_rcu(&entry->list); | 323 | list_del_rcu(&entry->list); |
338 | } else | 324 | ret_val = 0; |
339 | ret_val = -ENOENT; | 325 | } |
340 | spin_unlock(&netlbl_domhsh_lock); | 326 | spin_unlock(&netlbl_domhsh_lock); |
341 | } else { | 327 | } else { |
342 | spin_lock(&netlbl_domhsh_def_lock); | 328 | spin_lock(&netlbl_domhsh_def_lock); |
343 | if (entry->valid) { | 329 | if (entry->valid) { |
344 | entry->valid = 0; | 330 | entry->valid = 0; |
345 | rcu_assign_pointer(netlbl_domhsh_def, NULL); | 331 | rcu_assign_pointer(netlbl_domhsh_def, NULL); |
346 | } else | 332 | ret_val = 0; |
347 | ret_val = -ENOENT; | 333 | } |
348 | spin_unlock(&netlbl_domhsh_def_lock); | 334 | spin_unlock(&netlbl_domhsh_def_lock); |
349 | } | 335 | } |
350 | 336 | ||
@@ -357,11 +343,10 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) | |||
357 | audit_log_end(audit_buf); | 343 | audit_log_end(audit_buf); |
358 | } | 344 | } |
359 | 345 | ||
360 | if (ret_val == 0) | ||
361 | call_rcu(&entry->rcu, netlbl_domhsh_free_entry); | ||
362 | |||
363 | remove_return: | 346 | remove_return: |
364 | rcu_read_unlock(); | 347 | rcu_read_unlock(); |
348 | if (ret_val == 0) | ||
349 | call_rcu(&entry->rcu, netlbl_domhsh_free_entry); | ||
365 | return ret_val; | 350 | return ret_val; |
366 | } | 351 | } |
367 | 352 | ||