Commit 53bc6b4d authored by Jamal Hadi Salim's avatar Jamal Hadi Salim Committed by David S. Miller

[IPSEC]: Sync series - SA expires

This patch allows a user to insert SA expires. This is useful to
do on an HA backup for the case of byte counts but may not be very
useful for the case of time based expiry.
Signed-off-by: default avatarJamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 980ebd25
...@@ -218,6 +218,9 @@ extern void km_state_notify(struct xfrm_state *x, struct km_event *c); ...@@ -218,6 +218,9 @@ extern void km_state_notify(struct xfrm_state *x, struct km_event *c);
struct xfrm_tmpl; struct xfrm_tmpl;
extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); 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);
struct xfrm_state_afinfo { struct xfrm_state_afinfo {
unsigned short family; unsigned short family;
rwlock_t lock; rwlock_t lock;
......
...@@ -52,13 +52,13 @@ static DEFINE_SPINLOCK(xfrm_state_gc_lock); ...@@ -52,13 +52,13 @@ static DEFINE_SPINLOCK(xfrm_state_gc_lock);
static int xfrm_state_gc_flush_bundles; static int xfrm_state_gc_flush_bundles;
static int __xfrm_state_delete(struct xfrm_state *x); int __xfrm_state_delete(struct xfrm_state *x);
static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
static void km_state_expired(struct xfrm_state *x, int hard); void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
static void xfrm_state_gc_destroy(struct xfrm_state *x) static void xfrm_state_gc_destroy(struct xfrm_state *x)
{ {
...@@ -157,7 +157,7 @@ static void xfrm_timer_handler(unsigned long data) ...@@ -157,7 +157,7 @@ static void xfrm_timer_handler(unsigned long data)
x->km.dying = warn; x->km.dying = warn;
if (warn) if (warn)
km_state_expired(x, 0); km_state_expired(x, 0, 0);
resched: resched:
if (next != LONG_MAX && if (next != LONG_MAX &&
!mod_timer(&x->timer, jiffies + make_jiffies(next))) !mod_timer(&x->timer, jiffies + make_jiffies(next)))
...@@ -172,7 +172,7 @@ static void xfrm_timer_handler(unsigned long data) ...@@ -172,7 +172,7 @@ static void xfrm_timer_handler(unsigned long data)
goto resched; goto resched;
} }
if (!__xfrm_state_delete(x) && x->id.spi) if (!__xfrm_state_delete(x) && x->id.spi)
km_state_expired(x, 1); km_state_expired(x, 1, 0);
out: out:
spin_unlock(&x->lock); spin_unlock(&x->lock);
...@@ -221,7 +221,7 @@ void __xfrm_state_destroy(struct xfrm_state *x) ...@@ -221,7 +221,7 @@ void __xfrm_state_destroy(struct xfrm_state *x)
} }
EXPORT_SYMBOL(__xfrm_state_destroy); EXPORT_SYMBOL(__xfrm_state_destroy);
static int __xfrm_state_delete(struct xfrm_state *x) int __xfrm_state_delete(struct xfrm_state *x)
{ {
int err = -ESRCH; int err = -ESRCH;
...@@ -260,6 +260,7 @@ static int __xfrm_state_delete(struct xfrm_state *x) ...@@ -260,6 +260,7 @@ static int __xfrm_state_delete(struct xfrm_state *x)
return err; return err;
} }
EXPORT_SYMBOL(__xfrm_state_delete);
int xfrm_state_delete(struct xfrm_state *x) int xfrm_state_delete(struct xfrm_state *x)
{ {
...@@ -595,7 +596,7 @@ int xfrm_state_check_expire(struct xfrm_state *x) ...@@ -595,7 +596,7 @@ int xfrm_state_check_expire(struct xfrm_state *x)
(x->curlft.bytes >= x->lft.soft_byte_limit || (x->curlft.bytes >= x->lft.soft_byte_limit ||
x->curlft.packets >= x->lft.soft_packet_limit)) { x->curlft.packets >= x->lft.soft_packet_limit)) {
x->km.dying = 1; x->km.dying = 1;
km_state_expired(x, 0); km_state_expired(x, 0, 0);
} }
return 0; return 0;
} }
...@@ -909,11 +910,12 @@ void km_state_notify(struct xfrm_state *x, struct km_event *c) ...@@ -909,11 +910,12 @@ void km_state_notify(struct xfrm_state *x, struct km_event *c)
EXPORT_SYMBOL(km_policy_notify); EXPORT_SYMBOL(km_policy_notify);
EXPORT_SYMBOL(km_state_notify); EXPORT_SYMBOL(km_state_notify);
void km_state_expired(struct xfrm_state *x, int hard) void km_state_expired(struct xfrm_state *x, int hard, u32 pid)
{ {
struct km_event c; struct km_event c;
c.data.hard = hard; c.data.hard = hard;
c.pid = pid;
c.event = XFRM_MSG_EXPIRE; c.event = XFRM_MSG_EXPIRE;
km_state_notify(x, &c); km_state_notify(x, &c);
...@@ -921,6 +923,7 @@ void km_state_expired(struct xfrm_state *x, int hard) ...@@ -921,6 +923,7 @@ void km_state_expired(struct xfrm_state *x, int hard)
wake_up(&km_waitq); wake_up(&km_waitq);
} }
EXPORT_SYMBOL(km_state_expired);
/* /*
* We send to all registered managers regardless of failure * We send to all registered managers regardless of failure
* We are happy with one success * We are happy with one success
......
...@@ -1232,6 +1232,34 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x ...@@ -1232,6 +1232,34 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x
return 0; return 0;
} }
static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
{
struct xfrm_state *x;
int err;
struct xfrm_user_expire *ue = NLMSG_DATA(nlh);
struct xfrm_usersa_info *p = &ue->state;
x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family);
err = -ENOENT;
if (x == NULL)
return err;
err = -EINVAL;
spin_lock_bh(&x->lock);
if (x->km.state != XFRM_STATE_VALID)
goto out;
km_state_expired(x, ue->hard, current->pid);
if (ue->hard)
__xfrm_state_delete(x);
out:
spin_unlock_bh(&x->lock);
xfrm_state_put(x);
return err;
}
static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
{ {
struct xfrm_policy *xp; struct xfrm_policy *xp;
...@@ -1296,6 +1324,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { ...@@ -1296,6 +1324,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
[XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
[XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info), [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info),
[XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire), [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire),
[XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire),
[XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
[XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
[XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
...@@ -1320,6 +1349,7 @@ static struct xfrm_link { ...@@ -1320,6 +1349,7 @@ static struct xfrm_link {
.dump = xfrm_dump_policy }, .dump = xfrm_dump_policy },
[XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
[XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire }, [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire },
[XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_sa_expire },
[XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy },
[XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa },
[XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment