Commit 497e5221 authored by Herbert Xu's avatar Herbert Xu Committed by Christoph Hellwig

[XFRM_USER]: Allow del policy by id and get policy by selector.

parent 921a5004
......@@ -790,7 +790,8 @@ void xfrm6_policy_init(void);
struct xfrm_policy *xfrm_policy_alloc(int 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);
struct xfrm_policy *xfrm_policy_delete(int dir, struct xfrm_selector *sel);
struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
int delete);
struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
void xfrm_policy_flush(void);
u32 xfrm_get_acqseq(void);
......
......@@ -1990,7 +1990,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
if (sel.dport)
sel.dport_mask = ~0;
xp = xfrm_policy_delete(pol->sadb_x_policy_dir-1, &sel);
xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1);
if (xp == NULL)
return -ENOENT;
......
......@@ -337,7 +337,7 @@ EXPORT_SYMBOL(xfrm_find_acq);
EXPORT_SYMBOL(xfrm_alloc_spi);
EXPORT_SYMBOL(xfrm_state_flush);
EXPORT_SYMBOL(xfrm_policy_kill);
EXPORT_SYMBOL(xfrm_policy_delete);
EXPORT_SYMBOL(xfrm_policy_bysel);
EXPORT_SYMBOL(xfrm_policy_insert);
EXPORT_SYMBOL(xfrm_policy_walk);
EXPORT_SYMBOL(xfrm_policy_flush);
......
......@@ -297,19 +297,25 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
return 0;
}
struct xfrm_policy *xfrm_policy_delete(int dir, struct xfrm_selector *sel)
struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
int delete)
{
struct xfrm_policy *pol, **p;
write_lock_bh(&xfrm_policy_lock);
for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) {
*p = pol->next;
if (delete)
*p = pol->next;
break;
}
}
if (pol)
atomic_inc(&flow_cache_genid);
if (pol) {
if (delete)
atomic_inc(&flow_cache_genid);
else
xfrm_pol_hold(pol);
}
write_unlock_bh(&xfrm_policy_lock);
return pol;
}
......
......@@ -656,26 +656,6 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
return 0;
}
static int xfrm_del_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
{
struct xfrm_policy *xp;
struct xfrm_userpolicy_id *p;
int err;
p = NLMSG_DATA(nlh);
err = verify_policy_dir(p->dir);
if (err)
return err;
xp = xfrm_policy_delete(p->dir, &p->sel);
if (xp == NULL)
return -ENOENT;
xfrm_policy_kill(xp);
xfrm_pol_put(xp);
return 0;
}
static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
{
struct xfrm_dump_info *sp = ptr;
......@@ -774,20 +754,36 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
{
struct xfrm_policy *xp;
struct xfrm_userpolicy_id *p;
struct sk_buff *resp_skb;
int err;
int delete;
p = NLMSG_DATA(nlh);
xp = xfrm_policy_byid(p->dir, p->index, 0);
delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
err = verify_policy_dir(p->dir);
if (err)
return err;
if (p->index)
xp = xfrm_policy_byid(p->dir, p->index, delete);
else
xp = xfrm_policy_bysel(p->dir, &p->sel, delete);
if (xp == NULL)
return -ENOENT;
resp_skb = xfrm_policy_netlink(skb, xp, p->dir, nlh->nlmsg_seq);
if (IS_ERR(resp_skb)) {
err = PTR_ERR(resp_skb);
} else {
err = netlink_unicast(xfrm_nl, resp_skb,
NETLINK_CB(skb).pid, MSG_DONTWAIT);
if (delete)
xfrm_policy_kill(xp);
else {
struct sk_buff *resp_skb;
resp_skb = xfrm_policy_netlink(skb, xp, p->dir, nlh->nlmsg_seq);
if (IS_ERR(resp_skb)) {
err = PTR_ERR(resp_skb);
} else {
err = netlink_unicast(xfrm_nl, resp_skb,
NETLINK_CB(skb).pid,
MSG_DONTWAIT);
}
}
xfrm_pol_put(xp);
......@@ -819,7 +815,7 @@ static struct xfrm_link {
.dump = xfrm_dump_sa,
},
{ .doit = xfrm_add_policy },
{ .doit = xfrm_del_policy },
{ .doit = xfrm_get_policy },
{
.doit = xfrm_get_policy,
.dump = xfrm_dump_policy,
......
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