Skip to content

Commit

Permalink
xfrm: Allow user space manipulation of SPD mark
Browse files Browse the repository at this point in the history
Add ability for netlink userspace to manipulate the SPD
and manipulate the mark, retrieve it and get events with a defined
mark, etc.

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jamal Hadi Salim authored and David S. Miller committed Feb 23, 2010
1 parent 6f26b61 commit 295fae5
Showing 1 changed file with 25 additions and 6 deletions.
31 changes: 25 additions & 6 deletions net/xfrm/xfrm_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
#include <linux/in6.h>
#endif

#define DUMMY_MARK 0

static inline int aead_len(struct xfrm_algo_aead *alg)
{
return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
Expand Down Expand Up @@ -1234,6 +1232,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us
if (err)
goto error;

xfrm_mark_get(attrs, &xp->mark);

return xp;
error:
*errp = err;
Expand Down Expand Up @@ -1380,10 +1380,13 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
goto nlmsg_failure;
if (copy_to_user_policy_type(xp->type, skb) < 0)
goto nlmsg_failure;
if (xfrm_mark_put(skb, &xp->mark))
goto nla_put_failure;

nlmsg_end(skb, nlh);
return 0;

nla_put_failure:
nlmsg_failure:
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
Expand Down Expand Up @@ -1455,6 +1458,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
int err;
struct km_event c;
int delete;
struct xfrm_mark m;
u32 mark = xfrm_mark_get(attrs, &m);

p = nlmsg_data(nlh);
delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
Expand All @@ -1468,7 +1473,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
return err;

if (p->index)
xp = xfrm_policy_byid(net, DUMMY_MARK, type, p->dir, p->index, delete, &err);
xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, delete, &err);
else {
struct nlattr *rt = attrs[XFRMA_SEC_CTX];
struct xfrm_sec_ctx *ctx;
Expand All @@ -1485,7 +1490,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err)
return err;
}
xp = xfrm_policy_bysel_ctx(net, DUMMY_MARK, type, p->dir, &p->sel,
xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, &p->sel,
ctx, delete, &err);
security_xfrm_policy_free(ctx);
}
Expand Down Expand Up @@ -1729,13 +1734,15 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
struct xfrm_userpolicy_info *p = &up->pol;
u8 type = XFRM_POLICY_TYPE_MAIN;
int err = -ENOENT;
struct xfrm_mark m;
u32 mark = xfrm_mark_get(attrs, &m);

err = copy_from_user_policy_type(&type, attrs);
if (err)
return err;

if (p->index)
xp = xfrm_policy_byid(net, DUMMY_MARK, type, p->dir, p->index, 0, &err);
xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, 0, &err);
else {
struct nlattr *rt = attrs[XFRMA_SEC_CTX];
struct xfrm_sec_ctx *ctx;
Expand All @@ -1752,7 +1759,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err)
return err;
}
xp = xfrm_policy_bysel_ctx(net, DUMMY_MARK, type, p->dir,
xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir,
&p->sel, ctx, 0, &err);
security_xfrm_policy_free(ctx);
}
Expand Down Expand Up @@ -2424,9 +2431,12 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
goto nlmsg_failure;
if (copy_to_user_policy_type(xp->type, skb) < 0)
goto nlmsg_failure;
if (xfrm_mark_put(skb, &xp->mark))
goto nla_put_failure;

return nlmsg_end(skb, nlh);

nla_put_failure:
nlmsg_failure:
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
Expand Down Expand Up @@ -2513,6 +2523,7 @@ static inline size_t xfrm_polexpire_msgsize(struct xfrm_policy *xp)
return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire))
+ nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr)
+ nla_total_size(xfrm_user_sec_ctx_size(xp->security))
+ nla_total_size(sizeof(struct xfrm_mark))
+ userpolicy_type_attrsize();
}

Expand All @@ -2535,10 +2546,13 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
goto nlmsg_failure;
if (copy_to_user_policy_type(xp->type, skb) < 0)
goto nlmsg_failure;
if (xfrm_mark_put(skb, &xp->mark))
goto nla_put_failure;
upe->hard = !!hard;

return nlmsg_end(skb, nlh);

nla_put_failure:
nlmsg_failure:
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
Expand Down Expand Up @@ -2575,6 +2589,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
headlen = sizeof(*id);
}
len += userpolicy_type_attrsize();
len += nla_total_size(sizeof(struct xfrm_mark));
len += NLMSG_ALIGN(headlen);

skb = nlmsg_new(len, GFP_ATOMIC);
Expand Down Expand Up @@ -2610,10 +2625,14 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
if (copy_to_user_policy_type(xp->type, skb) < 0)
goto nlmsg_failure;

if (xfrm_mark_put(skb, &xp->mark))
goto nla_put_failure;

nlmsg_end(skb, nlh);

return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);

nla_put_failure:
nlmsg_failure:
kfree_skb(skb);
return -1;
Expand Down

0 comments on commit 295fae5

Please sign in to comment.