This code adds auditing to IPSec. An audit message gets logged whenever
an ipsec policy or security association is added or deleted from the
kernel's Security Policy Database and/or Security Association Database.
IPSec policies and SAs can be added  and/or deleted via the pfkey api or
the netlink api, which was extended to accomodate key management.
PFKEYv2 is a socket protocol for key management defined in RFC 2367.
I added auditing for both key management protocols. Both protocols
utilize the same code in some places. 
Please let me know if this patch is acceptable.
Regards,
Joy Latten
---------------------------------------------------------------------------------
diff -urpN linux-2.6.18.ppc64/include/linux/audit.h
linux-2.6.18.ppc64.patch/include/linux/audit.h
--- linux-2.6.18.ppc64/include/linux/audit.h	2006-10-26
03:10:10.000000000 -0500
+++ linux-2.6.18.ppc64.patch/include/linux/audit.h	2006-10-26
07:04:08.000000000 -0500
@@ -100,6 +100,10 @@
 #define AUDIT_MAC_CIPSOV4_DEL	1408	/* NetLabel: del CIPSOv4 DOI entry
*/
 #define AUDIT_MAC_MAP_ADD	1409	/* NetLabel: add LSM domain mapping */
 #define AUDIT_MAC_MAP_DEL	1410	/* NetLabel: del LSM domain mapping */
+#define AUDIT_MAC_IPSEC_ADDSA   1411	/* Add a XFRM state */
+#define AUDIT_MAC_IPSEC_DELSA   1412	/* Delete a XFRM state */ 
+#define AUDIT_MAC_IPSEC_ADDSPD  1413	/* Add a XFRM policy */
+#define AUDIT_MAC_IPSEC_DELSPD  1414	/* Delete a XFRM policy */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
diff -urpN linux-2.6.18.ppc64/include/net/xfrm.h
linux-2.6.18.ppc64.patch/include/net/xfrm.h
--- linux-2.6.18.ppc64/include/net/xfrm.h	2006-10-26 03:10:11.000000000
-0500
+++ linux-2.6.18.ppc64.patch/include/net/xfrm.h	2006-10-26
07:04:08.000000000 -0500
@@ -18,6 +18,7 @@
 #include <net/route.h>
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
+#include <linux/audit.h>
 
 #define XFRM_ALIGN8(len)	(((len) + 7) & ~7)
 #define MODULE_ALIAS_XFRM_MODE(family, encap) \
@@ -231,7 +232,7 @@ extern void km_state_notify(struct xfrm_
 struct xfrm_tmpl;
 extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct
xfrm_policy *pol);
 extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
-extern int __xfrm_state_delete(struct xfrm_state *x);
+extern int __xfrm_state_delete(struct xfrm_state *x, uid_t auid);
 
 struct xfrm_state_afinfo {
 	unsigned short		family;
@@ -737,16 +738,17 @@ static inline int xfrm_sk_clone_policy(s
 	return 0;
 }
 
-extern int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
+extern int xfrm_policy_delete(struct xfrm_policy *pol, int dir, uid_t
auid);
 
 static inline void xfrm_sk_free_policy(struct sock *sk)
 {
+	uid_t auid = audit_get_loginuid(current->audit_context);
 	if (unlikely(sk->sk_policy[0] != NULL)) {
-		xfrm_policy_delete(sk->sk_policy[0], XFRM_POLICY_MAX);
+		xfrm_policy_delete(sk->sk_policy[0], XFRM_POLICY_MAX, auid);
 		sk->sk_policy[0] = NULL;
 	}
 	if (unlikely(sk->sk_policy[1] != NULL)) {
-		xfrm_policy_delete(sk->sk_policy[1], XFRM_POLICY_MAX+1);
+		xfrm_policy_delete(sk->sk_policy[1], XFRM_POLICY_MAX+1, auid);
 		sk->sk_policy[1] = NULL;
 	}
 }
@@ -898,13 +900,13 @@ extern struct xfrm_state *xfrm_state_fin
 					  struct xfrm_policy *pol, int *err,
 					  unsigned short family);
 extern int xfrm_state_check_expire(struct xfrm_state *x);
-extern void xfrm_state_insert(struct xfrm_state *x);
-extern int xfrm_state_add(struct xfrm_state *x);
-extern int xfrm_state_update(struct xfrm_state *x);
+extern void xfrm_state_insert(struct xfrm_state *x, uid_t auid);
+extern int xfrm_state_add(struct xfrm_state *x, uid_t auid);
+extern int xfrm_state_update(struct xfrm_state *x, uid_t auid);
 extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32
spi, u8 proto, unsigned short family);
 extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
-extern int xfrm_state_delete(struct xfrm_state *x);
-extern void xfrm_state_flush(u8 proto);
+extern int xfrm_state_delete(struct xfrm_state *x, uid_t auid);
+extern void xfrm_state_flush(u8 proto, uid_t auid);
 extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
 extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
 extern void xfrm_replay_notify(struct xfrm_state *x, int event);
@@ -948,17 +950,18 @@ static inline int xfrm_dst_lookup(struct
 
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
 extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int,
void*), void *);
-int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
+int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl,
uid_t auid);
 struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector
*sel,
-					  struct xfrm_sec_ctx *ctx, int delete);
-struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
-void xfrm_policy_flush(void);
+					  struct xfrm_sec_ctx *ctx, int delete,
+					  uid_t auid);
+struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete, uid_t
auid);
+void xfrm_policy_flush(uid_t auid);
 u32 xfrm_get_acqseq(void);
 void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
 struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, 
 				  xfrm_address_t *daddr, xfrm_address_t *saddr, 
 				  int create, unsigned short family);
-extern void xfrm_policy_flush(void);
+extern void xfrm_policy_flush(uid_t auid);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct
xfrm_policy *pol);
 extern int xfrm_flush_bundles(void);
 extern void xfrm_flush_all_bundles(void);
diff -urpN linux-2.6.18.ppc64/kernel/auditsc.c
linux-2.6.18.ppc64.patch/kernel/auditsc.c
--- linux-2.6.18.ppc64/kernel/auditsc.c	2006-10-26 03:10:35.000000000
-0500
+++ linux-2.6.18.ppc64.patch/kernel/auditsc.c	2006-10-26
07:04:49.000000000 -0500
@@ -1488,6 +1488,7 @@ uid_t audit_get_loginuid(struct audit_co
 {
 	return ctx ? ctx->loginuid : -1;
 }
+EXPORT_SYMBOL(audit_get_loginuid);
 
 /**
  * __audit_mq_open - record audit data for a POSIX MQ open
diff -urpN linux-2.6.18.ppc64/net/ipv4/ipcomp.c
linux-2.6.18.ppc64.patch/net/ipv4/ipcomp.c
--- linux-2.6.18.ppc64/net/ipv4/ipcomp.c	2006-09-19 22:42:06.000000000
-0500
+++ linux-2.6.18.ppc64.patch/net/ipv4/ipcomp.c	2006-10-26
07:04:08.000000000 -0500
@@ -29,6 +29,7 @@
 #include <net/icmp.h>
 #include <net/ipcomp.h>
 #include <net/protocol.h>
+#include <linux/audit.h>
 
 struct ipcomp_tfms {
 	struct list_head list;
@@ -251,7 +252,7 @@ static int ipcomp_tunnel_attach(struct x
 			err = -EINVAL;
 			goto out;
 		}
-		xfrm_state_insert(t);
+		xfrm_state_insert(t,audit_get_loginuid(current->audit_context));
 		xfrm_state_hold(t);
 	}
 	x->tunnel = t;
diff -urpN linux-2.6.18.ppc64/net/ipv6/ipcomp6.c
linux-2.6.18.ppc64.patch/net/ipv6/ipcomp6.c
--- linux-2.6.18.ppc64/net/ipv6/ipcomp6.c	2006-09-19 22:42:06.000000000
-0500
+++ linux-2.6.18.ppc64.patch/net/ipv6/ipcomp6.c	2006-10-26
07:04:08.000000000 -0500
@@ -50,6 +50,7 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/mutex.h>
+#include <linux/audit.h>
 
 struct ipcomp6_tfms {
 	struct list_head list;
@@ -246,7 +247,7 @@ static int ipcomp6_tunnel_attach(struct 
 			err = -EINVAL;
 			goto out;
 		}
-		xfrm_state_insert(t);
+		xfrm_state_insert(t,audit_get_loginuid(current->audit_context));
 		xfrm_state_hold(t);
 	}
 	x->tunnel = t;
diff -urpN linux-2.6.18.ppc64/net/key/af_key.c
linux-2.6.18.ppc64.patch/net/key/af_key.c
--- linux-2.6.18.ppc64/net/key/af_key.c	2006-10-26 03:10:11.000000000
-0500
+++ linux-2.6.18.ppc64.patch/net/key/af_key.c	2006-10-26
07:04:08.000000000 -0500
@@ -29,6 +29,7 @@
 #include <net/xfrm.h>
 
 #include <net/sock.h>
+#include <linux/audit.h>
 
 #define _X2KEY(x) ((x) == XFRM_INF ? 0 : (x))
 #define _KEY2X(x) ((x) == 0 ? XFRM_INF : (x))
@@ -1416,9 +1417,9 @@ static int pfkey_add(struct sock *sk, st
 
 	xfrm_state_hold(x);
 	if (hdr->sadb_msg_type == SADB_ADD)
-		err = xfrm_state_add(x);
+		err = xfrm_state_add(x, audit_get_loginuid(current->audit_context));
 	else
-		err = xfrm_state_update(x);
+		err = xfrm_state_update(x,
audit_get_loginuid(current->audit_context));
 
 	if (err < 0) {
 		x->km.state = XFRM_STATE_DEAD;
@@ -1461,7 +1462,7 @@ static int pfkey_delete(struct sock *sk,
 		goto out;
 	}
 	
-	err = xfrm_state_delete(x);
+	err = xfrm_state_delete(x,
audit_get_loginuid(current->audit_context));
 	if (err < 0)
 		goto out;
 
@@ -1642,7 +1643,7 @@ static int pfkey_flush(struct sock *sk, 
 	if (proto == 0)
 		return -EINVAL;
 
-	xfrm_state_flush(proto);
+	xfrm_state_flush(proto, audit_get_loginuid(current->audit_context));
 	c.data.proto = proto;
 	c.seq = hdr->sadb_msg_seq;
 	c.pid = hdr->sadb_msg_pid;
@@ -2192,7 +2193,8 @@ static int pfkey_spdadd(struct sock *sk,
 		goto out;
 
 	err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
-				 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
+				 hdr->sadb_msg_type != SADB_X_SPDUPDATE,
+				 audit_get_loginuid(current->audit_context));
 
 	if (err)
 		goto out;
@@ -2268,7 +2270,7 @@ static int pfkey_spddelete(struct sock *
 			return err;
 	}
 
-	xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel,
tmp.security, 1);
+	xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel,
tmp.security, 1, audit_get_loginuid(current->audit_context));
 	security_xfrm_policy_free(&tmp);
 	if (xp == NULL)
 		return -ENOENT;
@@ -2331,7 +2333,8 @@ static int pfkey_spdget(struct sock *sk,
 		return -EINVAL;
 
 	xp = xfrm_policy_byid(dir, pol->sadb_x_policy_id,
-			      hdr->sadb_msg_type == SADB_X_SPDDELETE2);
+			      hdr->sadb_msg_type == SADB_X_SPDDELETE2,
+			      audit_get_loginuid(current->audit_context));
 	if (xp == NULL)
 		return -ENOENT;
 
@@ -2405,7 +2408,7 @@ static int pfkey_spdflush(struct sock *s
 {
 	struct km_event c;
 
-	xfrm_policy_flush();
+	xfrm_policy_flush(audit_get_loginuid(current->audit_context));
 	c.event = XFRM_MSG_FLUSHPOLICY;
 	c.pid = hdr->sadb_msg_pid;
 	c.seq = hdr->sadb_msg_seq;
diff -urpN linux-2.6.18.ppc64/net/xfrm/xfrm_policy.c
linux-2.6.18.ppc64.patch/net/xfrm/xfrm_policy.c
--- linux-2.6.18.ppc64/net/xfrm/xfrm_policy.c	2006-10-26
03:10:11.000000000 -0500
+++ linux-2.6.18.ppc64.patch/net/xfrm/xfrm_policy.c	2006-10-26
07:04:08.000000000 -0500
@@ -293,7 +293,7 @@ out:
 
 expired:
 	read_unlock(&xp->lock);
-	if (!xfrm_policy_delete(xp, dir))
+	if (!xfrm_policy_delete(xp, dir,
audit_get_loginuid(current->audit_context)))
 		km_policy_expired(xp, dir, 1, 0);
 	xfrm_pol_put(xp);
 }
@@ -374,13 +374,21 @@ static void xfrm_policy_gc_task(void *da
  * entry dead. The rule must be unlinked from lists to the moment.
  */
 
-static void xfrm_policy_kill(struct xfrm_policy *policy)
+static void xfrm_policy_kill(struct xfrm_policy *policy, uid_t auid)
 {
 	int dead;
 
 	write_lock_bh(&policy->lock);
 	dead = policy->dead;
 	policy->dead = 1;
+
+	if (policy->security)
+		audit_log(current->audit_context, GFP_ATOMIC,
+			  AUDIT_MAC_IPSEC_DELSPD,
+			  "spd delete: auid=%u ctx_alg=%d ctx_doi=%d ctx=%s",
+			  auid, policy->security->ctx_alg,
+			  policy->security->ctx_doi, policy->security->ctx_str);
+
 	write_unlock_bh(&policy->lock);
 
 	if (unlikely(dead)) {
@@ -417,7 +425,7 @@ static u32 xfrm_gen_index(int dir)
 	}
 }
 
-int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
+int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl,
uid_t auid)
 {
 	struct xfrm_policy *pol, **p;
 	struct xfrm_policy *delpol = NULL;
@@ -460,10 +468,18 @@ int xfrm_policy_insert(int dir, struct x
 	write_unlock_bh(&xfrm_policy_lock);
 
 	if (delpol)
-		xfrm_policy_kill(delpol);
+		xfrm_policy_kill(delpol, auid);
 
 	read_lock_bh(&xfrm_policy_lock);
 	gc_list = NULL;
+
+	if (policy->security)
+		audit_log(current->audit_context, GFP_ATOMIC,
+			  AUDIT_MAC_IPSEC_ADDSPD,
+			  "spd add: auid=%u ctx_alg=%d ctx_doi=%d ctx=%s",
+			  auid, policy->security->ctx_alg,
+			  policy->security->ctx_doi, policy->security->ctx_str);
+
 	for (policy = policy->next; policy; policy = policy->next) {
 		struct dst_entry *dst;
 
@@ -480,6 +496,7 @@ int xfrm_policy_insert(int dir, struct x
 		}
 		write_unlock(&policy->lock);
 	}
+
 	read_unlock_bh(&xfrm_policy_lock);
 
 	while (gc_list) {
@@ -494,7 +511,8 @@ int xfrm_policy_insert(int dir, struct x
 EXPORT_SYMBOL(xfrm_policy_insert);
 
 struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector
*sel,
-					  struct xfrm_sec_ctx *ctx, int delete)
+					  struct xfrm_sec_ctx *ctx, int delete,
+					  uid_t auid)
 {
 	struct xfrm_policy *pol, **p;
 
@@ -512,13 +530,13 @@ struct xfrm_policy *xfrm_policy_bysel_ct
 
 	if (pol && delete) {
 		atomic_inc(&flow_cache_genid);
-		xfrm_policy_kill(pol);
+		xfrm_policy_kill(pol, auid);
 	}
 	return pol;
 }
 EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
-struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
+struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete, uid_t
auid)
 {
 	struct xfrm_policy *pol, **p;
 
@@ -535,13 +553,13 @@ struct xfrm_policy *xfrm_policy_byid(int
 
 	if (pol && delete) {
 		atomic_inc(&flow_cache_genid);
-		xfrm_policy_kill(pol);
+		xfrm_policy_kill(pol, auid);
 	}
 	return pol;
 }
 EXPORT_SYMBOL(xfrm_policy_byid);
 
-void xfrm_policy_flush(void)
+void xfrm_policy_flush(uid_t auid)
 {
 	struct xfrm_policy *xp;
 	int dir;
@@ -552,7 +570,7 @@ void xfrm_policy_flush(void)
 			xfrm_policy_list[dir] = xp->next;
 			write_unlock_bh(&xfrm_policy_lock);
 
-			xfrm_policy_kill(xp);
+			xfrm_policy_kill(xp, auid);
 
 			write_lock_bh(&xfrm_policy_lock);
 		}
@@ -696,7 +714,7 @@ static struct xfrm_policy *__xfrm_policy
 	return NULL;
 }
 
-int xfrm_policy_delete(struct xfrm_policy *pol, int dir)
+int xfrm_policy_delete(struct xfrm_policy *pol, int dir, uid_t auid)
 {
 	write_lock_bh(&xfrm_policy_lock);
 	pol = __xfrm_policy_unlink(pol, dir);
@@ -704,7 +722,7 @@ int xfrm_policy_delete(struct xfrm_polic
 	if (pol) {
 		if (dir < XFRM_POLICY_MAX)
 			atomic_inc(&flow_cache_genid);
-		xfrm_policy_kill(pol);
+		xfrm_policy_kill(pol, auid);
 		return 0;
 	}
 	return -ENOENT;
@@ -728,7 +746,7 @@ int xfrm_sk_policy_insert(struct sock *s
 	write_unlock_bh(&xfrm_policy_lock);
 
 	if (old_pol) {
-		xfrm_policy_kill(old_pol);
+		xfrm_policy_kill(old_pol,
audit_get_loginuid(current->audit_context));
 	}
 	return 0;
 }
diff -urpN linux-2.6.18.ppc64/net/xfrm/xfrm_state.c
linux-2.6.18.ppc64.patch/net/xfrm/xfrm_state.c
--- linux-2.6.18.ppc64/net/xfrm/xfrm_state.c	2006-10-26
03:10:09.000000000 -0500
+++ linux-2.6.18.ppc64.patch/net/xfrm/xfrm_state.c	2006-10-26
07:04:08.000000000 -0500
@@ -59,7 +59,7 @@ static DEFINE_SPINLOCK(xfrm_state_gc_loc
 
 static int xfrm_state_gc_flush_bundles;
 
-int __xfrm_state_delete(struct xfrm_state *x);
+int __xfrm_state_delete(struct xfrm_state *x, uid_t auid);
 
 static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short
family);
 static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
@@ -180,7 +180,8 @@ expired:
 		next = 2;
 		goto resched;
 	}
-	if (!__xfrm_state_delete(x) && x->id.spi)
+	if (!__xfrm_state_delete(x,
audit_get_loginuid(current->audit_context)) 
+	    && x->id.spi)
 		km_state_expired(x, 1, 0);
 
 out:
@@ -231,7 +232,7 @@ void __xfrm_state_destroy(struct xfrm_st
 }
 EXPORT_SYMBOL(__xfrm_state_destroy);
 
-int __xfrm_state_delete(struct xfrm_state *x)
+int __xfrm_state_delete(struct xfrm_state *x, uid_t auid)
 {
 	int err = -ESRCH;
 
@@ -244,6 +245,13 @@ int __xfrm_state_delete(struct xfrm_stat
 			list_del(&x->byspi);
 			__xfrm_state_put(x);
 		}
+		if (x->security)
+			audit_log(current->audit_context, GFP_ATOMIC,
+				  AUDIT_MAC_IPSEC_ADDSA,
+				  "SAD delete: auid=%u ctx_alg=%d ctx_doi=%d ctx=%s",
+				  auid, x->security->ctx_alg, 
+				  x->security->ctx_doi, x->security->ctx_str);
+
 		spin_unlock(&xfrm_state_lock);
 		if (del_timer(&x->timer))
 			__xfrm_state_put(x);
@@ -272,19 +280,19 @@ int __xfrm_state_delete(struct xfrm_stat
 }
 EXPORT_SYMBOL(__xfrm_state_delete);
 
-int xfrm_state_delete(struct xfrm_state *x)
+int xfrm_state_delete(struct xfrm_state *x, uid_t auid)
 {
 	int err;
 
 	spin_lock_bh(&x->lock);
-	err = __xfrm_state_delete(x);
+	err = __xfrm_state_delete(x, auid);
 	spin_unlock_bh(&x->lock);
 
 	return err;
 }
 EXPORT_SYMBOL(xfrm_state_delete);
 
-void xfrm_state_flush(u8 proto)
+void xfrm_state_flush(u8 proto, uid_t auid)
 {
 	int i;
 	struct xfrm_state *x;
@@ -298,7 +306,7 @@ restart:
 				xfrm_state_hold(x);
 				spin_unlock_bh(&xfrm_state_lock);
 
-				xfrm_state_delete(x);
+				xfrm_state_delete(x, auid);
 				xfrm_state_put(x);
 
 				spin_lock_bh(&xfrm_state_lock);
@@ -441,7 +449,7 @@ out:
 	return x;
 }
 
-static void __xfrm_state_insert(struct xfrm_state *x)
+static void __xfrm_state_insert(struct xfrm_state *x, uid_t auid)
 {
 	unsigned h = xfrm_dst_hash(&x->id.daddr, x->props.family);
 
@@ -461,12 +469,20 @@ static void __xfrm_state_insert(struct x
 		xfrm_state_hold(x);
 
 	wake_up(&km_waitq);
+
+	if (x->security)
+		audit_log(current->audit_context, GFP_ATOMIC,
+			  AUDIT_MAC_IPSEC_ADDSA,
+			  "SAD add: auid=%u ctx_alg=%d ctx_doi=%d, ctx=%s",
+			  auid, x->security->ctx_alg, x->security->ctx_doi,
+			  x->security->ctx_str);
+
 }
 
-void xfrm_state_insert(struct xfrm_state *x)
+void xfrm_state_insert(struct xfrm_state *x, uid_t auid)
 {
 	spin_lock_bh(&xfrm_state_lock);
-	__xfrm_state_insert(x);
+	__xfrm_state_insert(x, auid);
 	spin_unlock_bh(&xfrm_state_lock);
 
 	xfrm_flush_all_bundles();
@@ -475,7 +491,7 @@ EXPORT_SYMBOL(xfrm_state_insert);
 
 static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq);
 
-int xfrm_state_add(struct xfrm_state *x)
+int xfrm_state_add(struct xfrm_state *x, uid_t auid)
 {
 	struct xfrm_state_afinfo *afinfo;
 	struct xfrm_state *x1;
@@ -510,7 +526,7 @@ int xfrm_state_add(struct xfrm_state *x)
 			x->props.mode, x->props.reqid, x->id.proto,
 			&x->id.daddr, &x->props.saddr, 0);
 
-	__xfrm_state_insert(x);
+	__xfrm_state_insert(x, auid);
 	err = 0;
 
 out:
@@ -521,7 +537,7 @@ out:
 		xfrm_flush_all_bundles();
 
 	if (x1) {
-		xfrm_state_delete(x1);
+		xfrm_state_delete(x1, auid);
 		xfrm_state_put(x1);
 	}
 
@@ -529,7 +545,7 @@ out:
 }
 EXPORT_SYMBOL(xfrm_state_add);
 
-int xfrm_state_update(struct xfrm_state *x)
+int xfrm_state_update(struct xfrm_state *x, uid_t auid)
 {
 	struct xfrm_state_afinfo *afinfo;
 	struct xfrm_state *x1;
@@ -553,7 +569,7 @@ int xfrm_state_update(struct xfrm_state 
 	}
 
 	if (x1->km.state == XFRM_STATE_ACQ) {
-		__xfrm_state_insert(x);
+		__xfrm_state_insert(x, auid);
 		x = NULL;
 	}
 	err = 0;
@@ -566,7 +582,7 @@ out:
 		return err;
 
 	if (!x) {
-		xfrm_state_delete(x1);
+		xfrm_state_delete(x1, auid);
 		xfrm_state_put(x1);
 		return 0;
 	}
@@ -1125,11 +1141,15 @@ static void xfrm_state_put_afinfo(struct
 /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
 void xfrm_state_delete_tunnel(struct xfrm_state *x)
 {
+	uid_t auid;
+
+	auid = audit_get_loginuid(current->audit_context);
+
 	if (x->tunnel) {
 		struct xfrm_state *t = x->tunnel;
 
 		if (atomic_read(&t->tunnel_users) == 2)
-			xfrm_state_delete(t);
+			xfrm_state_delete(t, auid);
 		atomic_dec(&t->tunnel_users);
 		xfrm_state_put(t);
 		x->tunnel = NULL;
diff -urpN linux-2.6.18.ppc64/net/xfrm/xfrm_user.c
linux-2.6.18.ppc64.patch/net/xfrm/xfrm_user.c
--- linux-2.6.18.ppc64/net/xfrm/xfrm_user.c	2006-10-26
03:10:11.000000000 -0500
+++ linux-2.6.18.ppc64.patch/net/xfrm/xfrm_user.c	2006-10-26
07:04:08.000000000 -0500
@@ -27,6 +27,7 @@
 #include <net/xfrm.h>
 #include <net/netlink.h>
 #include <asm/uaccess.h>
+#include <linux/audit.h>
 
 static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t
type)
 {
@@ -396,9 +397,9 @@ static int xfrm_add_sa(struct sk_buff *s
 
 	xfrm_state_hold(x);
 	if (nlh->nlmsg_type == XFRM_MSG_NEWSA)
-		err = xfrm_state_add(x);
+		err = xfrm_state_add(x, NETLINK_CB(skb).loginuid);
 	else
-		err = xfrm_state_update(x);
+		err = xfrm_state_update(x, NETLINK_CB(skb).loginuid);
 
 	if (err < 0) {
 		x->km.state = XFRM_STATE_DEAD;
@@ -435,7 +436,7 @@ static int xfrm_del_sa(struct sk_buff *s
 		goto out;
 	}
 
-	err = xfrm_state_delete(x);
+	err = xfrm_state_delete(x, NETLINK_CB(skb).loginuid);
 	if (err < 0)
 		goto out;
 
@@ -859,7 +860,7 @@ static int xfrm_add_policy(struct sk_buf
 	 * in netlink excl is a flag and you wouldnt need
 	 * a type XFRM_MSG_UPDPOLICY - JHS */
 	excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
-	err = xfrm_policy_insert(p->dir, xp, excl);
+	err = xfrm_policy_insert(p->dir, xp, excl, NETLINK_CB(skb).loginuid);
 	if (err) {
 		security_xfrm_policy_free(xp);
 		kfree(xp);
@@ -1026,6 +1027,7 @@ static int xfrm_get_policy(struct sk_buf
 	int err;
 	struct km_event c;
 	int delete;
+	uid_t auid;
 
 	p = NLMSG_DATA(nlh);
 	delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
@@ -1034,8 +1036,9 @@ static int xfrm_get_policy(struct sk_buf
 	if (err)
 		return err;
 
+	auid = NETLINK_CB(skb).loginuid;
 	if (p->index)
-		xp = xfrm_policy_byid(p->dir, p->index, delete);
+		xp = xfrm_policy_byid(p->dir, p->index, delete, auid);
 	else {
 		struct rtattr **rtattrs = (struct rtattr **)xfrma;
 		struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
@@ -1052,7 +1055,7 @@ static int xfrm_get_policy(struct sk_buf
 			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete);
+		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete,
auid);
 		security_xfrm_policy_free(&tmp);
 	}
 	if (xp == NULL)
@@ -1090,7 +1093,7 @@ static int xfrm_flush_sa(struct sk_buff 
 	struct km_event c;
 	struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
 
-	xfrm_state_flush(p->proto);
+	xfrm_state_flush(p->proto, NETLINK_CB(skb).loginuid);
 	c.data.proto = p->proto;
 	c.event = nlh->nlmsg_type;
 	c.seq = nlh->nlmsg_seq;
@@ -1237,7 +1240,7 @@ static int xfrm_flush_policy(struct sk_b
 {
 struct km_event c;
 
-	xfrm_policy_flush();
+	xfrm_policy_flush(NETLINK_CB(skb).loginuid);
 	c.event = nlh->nlmsg_type;
 	c.seq = nlh->nlmsg_seq;
 	c.pid = nlh->nlmsg_pid;
@@ -1251,9 +1254,12 @@ static int xfrm_add_pol_expire(struct sk
 	struct xfrm_user_polexpire *up = NLMSG_DATA(nlh);
 	struct xfrm_userpolicy_info *p = &up->pol;
 	int err = -ENOENT;
+	uid_t auid;
+
+	auid = NETLINK_CB(skb).loginuid;
 
 	if (p->index)
-		xp = xfrm_policy_byid(p->dir, p->index, 0);
+		xp = xfrm_policy_byid(p->dir, p->index, 0, auid);
 	else {
 		struct rtattr **rtattrs = (struct rtattr **)xfrma;
 		struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
@@ -1270,7 +1276,7 @@ static int xfrm_add_pol_expire(struct sk
 			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, 0);
+		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, 0, auid);
 		security_xfrm_policy_free(&tmp);
 	}
 
@@ -1285,7 +1291,7 @@ static int xfrm_add_pol_expire(struct sk
 	read_unlock(&xp->lock);
 	err = 0;
 	if (up->hard) {
-		xfrm_policy_delete(xp, p->dir);
+		xfrm_policy_delete(xp, p->dir, auid);
 	} else {
 		// reset the timers here?
 		printk("Dont know what to do with soft policy expire\n");
@@ -1318,7 +1324,7 @@ static int xfrm_add_sa_expire(struct sk_
 	km_state_expired(x, ue->hard, current->pid);
 
 	if (ue->hard)
-		__xfrm_state_delete(x);
+		__xfrm_state_delete(x, NETLINK_CB(skb).loginuid);
 out:
 	spin_unlock_bh(&x->lock);
 	xfrm_state_put(x);