#include <linux/cache.h>
#include <asm/uaccess.h>
#include <linux/audit.h>
+#include <linux/cache.h>
#include "xfrm_hash.h"
struct sock *xfrm_nl;
EXPORT_SYMBOL(xfrm_nl);
-u32 sysctl_xfrm_aevent_etime = XFRM_AE_ETIME;
+u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME;
EXPORT_SYMBOL(sysctl_xfrm_aevent_etime);
-u32 sysctl_xfrm_aevent_rseqth = XFRM_AE_SEQT_SIZE;
+u32 sysctl_xfrm_aevent_rseqth __read_mostly = XFRM_AE_SEQT_SIZE;
EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth);
+u32 sysctl_xfrm_acq_expires __read_mostly = 30;
+
/* Each xfrm_state may be linked to two tables:
1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
}
EXPORT_SYMBOL(xfrm_state_delete);
-void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static inline int
+xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
{
- int i;
- int err = 0;
+ int i, err = 0;
+
+ for (i = 0; i <= xfrm_state_hmask; i++) {
+ struct hlist_node *entry;
+ struct xfrm_state *x;
+
+ hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
+ if (xfrm_id_proto_match(x->id.proto, proto) &&
+ (err = security_xfrm_state_delete(x)) != 0) {
+ xfrm_audit_log(audit_info->loginuid,
+ audit_info->secid,
+ AUDIT_MAC_IPSEC_DELSA,
+ 0, NULL, x);
+
+ return err;
+ }
+ }
+ }
+
+ return err;
+}
+#else
+static inline int
+xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
+{
+ return 0;
+}
+#endif
+
+int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
+{
+ int i, err = 0;
spin_lock_bh(&xfrm_state_lock);
+ err = xfrm_state_flush_secctx_check(proto, audit_info);
+ if (err)
+ goto out;
+
for (i = 0; i <= xfrm_state_hmask; i++) {
struct hlist_node *entry;
struct xfrm_state *x;
}
}
}
+ err = 0;
+
+out:
spin_unlock_bh(&xfrm_state_lock);
wake_up(&km_waitq);
+ return err;
}
EXPORT_SYMBOL(xfrm_state_flush);
+void xfrm_sad_getinfo(struct xfrmk_sadinfo *si)
+{
+ spin_lock_bh(&xfrm_state_lock);
+ si->sadcnt = xfrm_state_num;
+ si->sadhcnt = xfrm_state_hmask;
+ si->sadhmcnt = xfrm_state_hashmax;
+ spin_unlock_bh(&xfrm_state_lock);
+}
+EXPORT_SYMBOL(xfrm_sad_getinfo);
+
static int
xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
struct xfrm_tmpl *tmpl,
h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
hlist_add_head(&x->byspi, xfrm_state_byspi+h);
}
- x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
- x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
+ x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
+ x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
add_timer(&x->timer);
xfrm_state_num++;
xfrm_hash_grow_check(x->bydst.next != NULL);
x->props.family = family;
x->props.mode = mode;
x->props.reqid = reqid;
- x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
+ x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
xfrm_state_hold(x);
- x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
+ x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
add_timer(&x->timer);
hlist_add_head(&x->bydst, xfrm_state_bydst+h);
h = xfrm_src_hash(daddr, saddr, family);
x->type && x->type->get_mtu)
res = x->type->get_mtu(x, mtu);
else
- res = mtu;
+ res = mtu - x->props.header_len;
spin_unlock_bh(&x->lock);
return res;
}