diff options
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r-- | net/xfrm/xfrm_state.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index da54a64ccfa3..fdb08d9f34aa 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/cache.h> | 21 | #include <linux/cache.h> |
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <linux/audit.h> | ||
23 | 24 | ||
24 | #include "xfrm_hash.h" | 25 | #include "xfrm_hash.h" |
25 | 26 | ||
@@ -238,6 +239,7 @@ static void xfrm_timer_handler(unsigned long data) | |||
238 | unsigned long now = (unsigned long)xtime.tv_sec; | 239 | unsigned long now = (unsigned long)xtime.tv_sec; |
239 | long next = LONG_MAX; | 240 | long next = LONG_MAX; |
240 | int warn = 0; | 241 | int warn = 0; |
242 | int err = 0; | ||
241 | 243 | ||
242 | spin_lock(&x->lock); | 244 | spin_lock(&x->lock); |
243 | if (x->km.state == XFRM_STATE_DEAD) | 245 | if (x->km.state == XFRM_STATE_DEAD) |
@@ -295,9 +297,14 @@ expired: | |||
295 | next = 2; | 297 | next = 2; |
296 | goto resched; | 298 | goto resched; |
297 | } | 299 | } |
298 | if (!__xfrm_state_delete(x) && x->id.spi) | 300 | |
301 | err = __xfrm_state_delete(x); | ||
302 | if (!err && x->id.spi) | ||
299 | km_state_expired(x, 1, 0); | 303 | km_state_expired(x, 1, 0); |
300 | 304 | ||
305 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | ||
306 | AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x); | ||
307 | |||
301 | out: | 308 | out: |
302 | spin_unlock(&x->lock); | 309 | spin_unlock(&x->lock); |
303 | } | 310 | } |
@@ -384,9 +391,10 @@ int xfrm_state_delete(struct xfrm_state *x) | |||
384 | } | 391 | } |
385 | EXPORT_SYMBOL(xfrm_state_delete); | 392 | EXPORT_SYMBOL(xfrm_state_delete); |
386 | 393 | ||
387 | void xfrm_state_flush(u8 proto) | 394 | void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) |
388 | { | 395 | { |
389 | int i; | 396 | int i; |
397 | int err = 0; | ||
390 | 398 | ||
391 | spin_lock_bh(&xfrm_state_lock); | 399 | spin_lock_bh(&xfrm_state_lock); |
392 | for (i = 0; i <= xfrm_state_hmask; i++) { | 400 | for (i = 0; i <= xfrm_state_hmask; i++) { |
@@ -399,7 +407,11 @@ restart: | |||
399 | xfrm_state_hold(x); | 407 | xfrm_state_hold(x); |
400 | spin_unlock_bh(&xfrm_state_lock); | 408 | spin_unlock_bh(&xfrm_state_lock); |
401 | 409 | ||
402 | xfrm_state_delete(x); | 410 | err = xfrm_state_delete(x); |
411 | xfrm_audit_log(audit_info->loginuid, | ||
412 | audit_info->secid, | ||
413 | AUDIT_MAC_IPSEC_DELSA, | ||
414 | err ? 0 : 1, NULL, x); | ||
403 | xfrm_state_put(x); | 415 | xfrm_state_put(x); |
404 | 416 | ||
405 | spin_lock_bh(&xfrm_state_lock); | 417 | spin_lock_bh(&xfrm_state_lock); |
@@ -1099,7 +1111,7 @@ int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), | |||
1099 | void *data) | 1111 | void *data) |
1100 | { | 1112 | { |
1101 | int i; | 1113 | int i; |
1102 | struct xfrm_state *x; | 1114 | struct xfrm_state *x, *last = NULL; |
1103 | struct hlist_node *entry; | 1115 | struct hlist_node *entry; |
1104 | int count = 0; | 1116 | int count = 0; |
1105 | int err = 0; | 1117 | int err = 0; |
@@ -1107,24 +1119,22 @@ int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), | |||
1107 | spin_lock_bh(&xfrm_state_lock); | 1119 | spin_lock_bh(&xfrm_state_lock); |
1108 | for (i = 0; i <= xfrm_state_hmask; i++) { | 1120 | for (i = 0; i <= xfrm_state_hmask; i++) { |
1109 | hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { | 1121 | hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { |
1110 | if (xfrm_id_proto_match(x->id.proto, proto)) | 1122 | if (!xfrm_id_proto_match(x->id.proto, proto)) |
1111 | count++; | 1123 | continue; |
1124 | if (last) { | ||
1125 | err = func(last, count, data); | ||
1126 | if (err) | ||
1127 | goto out; | ||
1128 | } | ||
1129 | last = x; | ||
1130 | count++; | ||
1112 | } | 1131 | } |
1113 | } | 1132 | } |
1114 | if (count == 0) { | 1133 | if (count == 0) { |
1115 | err = -ENOENT; | 1134 | err = -ENOENT; |
1116 | goto out; | 1135 | goto out; |
1117 | } | 1136 | } |
1118 | 1137 | err = func(last, 0, data); | |
1119 | for (i = 0; i <= xfrm_state_hmask; i++) { | ||
1120 | hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { | ||
1121 | if (!xfrm_id_proto_match(x->id.proto, proto)) | ||
1122 | continue; | ||
1123 | err = func(x, --count, data); | ||
1124 | if (err) | ||
1125 | goto out; | ||
1126 | } | ||
1127 | } | ||
1128 | out: | 1138 | out: |
1129 | spin_unlock_bh(&xfrm_state_lock); | 1139 | spin_unlock_bh(&xfrm_state_lock); |
1130 | return err; | 1140 | return err; |