-/*
+/*
* xfrm_policy.c
*
* Changes:
return type;
}
-int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
+int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
unsigned short family)
{
struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ)
return MAX_SCHEDULE_TIMEOUT-1;
else
- return secs*HZ;
+ return secs*HZ;
}
static void xfrm_policy_timer(unsigned long data)
struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
struct xfrm_selector *sel,
- struct xfrm_sec_ctx *ctx, int delete)
+ struct xfrm_sec_ctx *ctx, int delete,
+ int *err)
{
struct xfrm_policy *pol, *ret;
struct hlist_head *chain;
struct hlist_node *entry;
+ *err = 0;
write_lock_bh(&xfrm_policy_lock);
chain = policy_hash_bysel(sel, sel->family, dir);
ret = NULL;
xfrm_sec_ctx_match(ctx, pol->security)) {
xfrm_pol_hold(pol);
if (delete) {
+ *err = security_xfrm_policy_delete(pol);
+ if (*err) {
+ write_unlock_bh(&xfrm_policy_lock);
+ return pol;
+ }
hlist_del(&pol->bydst);
hlist_del(&pol->byidx);
xfrm_policy_count[dir]--;
}
EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
-struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete)
+struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
+ int *err)
{
struct xfrm_policy *pol, *ret;
struct hlist_head *chain;
struct hlist_node *entry;
+ *err = 0;
write_lock_bh(&xfrm_policy_lock);
chain = xfrm_policy_byidx + idx_hash(id);
ret = NULL;
if (pol->type == type && pol->index == id) {
xfrm_pol_hold(pol);
if (delete) {
+ *err = security_xfrm_policy_delete(pol);
+ if (*err) {
+ write_unlock_bh(&xfrm_policy_lock);
+ return pol;
+ }
hlist_del(&pol->bydst);
hlist_del(&pol->byidx);
xfrm_policy_count[dir]--;
static inline int policy_to_flow_dir(int dir)
{
if (XFRM_POLICY_IN == FLOW_DIR_IN &&
- XFRM_POLICY_OUT == FLOW_DIR_OUT &&
- XFRM_POLICY_FWD == FLOW_DIR_FWD)
- return dir;
- switch (dir) {
- default:
- case XFRM_POLICY_IN:
- return FLOW_DIR_IN;
- case XFRM_POLICY_OUT:
- return FLOW_DIR_OUT;
- case XFRM_POLICY_FWD:
- return FLOW_DIR_FWD;
+ XFRM_POLICY_OUT == FLOW_DIR_OUT &&
+ XFRM_POLICY_FWD == FLOW_DIR_FWD)
+ return dir;
+ switch (dir) {
+ default:
+ case XFRM_POLICY_IN:
+ return FLOW_DIR_IN;
+ case XFRM_POLICY_OUT:
+ return FLOW_DIR_OUT;
+ case XFRM_POLICY_FWD:
+ return FLOW_DIR_FWD;
};
}
read_lock_bh(&xfrm_policy_lock);
if ((pol = sk->sk_policy[dir]) != NULL) {
- int match = xfrm_selector_match(&pol->selector, fl,
+ int match = xfrm_selector_match(&pol->selector, fl,
sk->sk_family);
- int err = 0;
+ int err = 0;
if (match) {
err = security_xfrm_policy_lookup(pol, fl->secid,
}
*dst_p = dst;
dst_release(dst_orig);
- xfrm_pols_put(pols, npols);
+ xfrm_pols_put(pols, npols);
return 0;
error:
*/
static inline int
-xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
+xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
unsigned short family)
{
if (xfrm_state_kern(x))
- return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, family);
+ return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, tmpl->encap_family);
return x->id.proto == tmpl->id.proto &&
(x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
(x->props.reqid == tmpl->reqid || !tmpl->reqid) &&
return 0;
}
-int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
+int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
unsigned short family)
{
struct xfrm_policy *pol;
if (audit_enabled == 0)
return;
+ BUG_ON((type == AUDIT_MAC_IPSEC_ADDSA ||
+ type == AUDIT_MAC_IPSEC_DELSA) && !x);
+ BUG_ON((type == AUDIT_MAC_IPSEC_ADDSPD ||
+ type == AUDIT_MAC_IPSEC_DELSPD) && !xp);
+
audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type);
if (audit_buf == NULL)
- return;
+ return;
switch(type) {
case AUDIT_MAC_IPSEC_ADDSA:
if (sel_cmp->proto == IPSEC_ULPROTO_ANY) {
if (sel_tgt->family == sel_cmp->family &&
xfrm_addr_cmp(&sel_tgt->daddr, &sel_cmp->daddr,
- sel_cmp->family) == 0 &&
+ sel_cmp->family) == 0 &&
xfrm_addr_cmp(&sel_tgt->saddr, &sel_cmp->saddr,
sel_cmp->family) == 0 &&
sel_tgt->prefixlen_d == sel_cmp->prefixlen_d &&