aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r--net/xfrm/xfrm_state.c42
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
301out: 308out:
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}
385EXPORT_SYMBOL(xfrm_state_delete); 392EXPORT_SYMBOL(xfrm_state_delete);
386 393
387void xfrm_state_flush(u8 proto) 394void 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 }
1128out: 1138out:
1129 spin_unlock_bh(&xfrm_state_lock); 1139 spin_unlock_bh(&xfrm_state_lock);
1130 return err; 1140 return err;