xfrm: make user policy API complete
>From a userland POV, this API was based on some magic values:
- dirmask and action were bitfields but meaning of bits
(XFRM_POL_DEFAULT_*) are not exported;
- action is confusing, if a bit is set, does it mean drop or accept?
Let's try to simplify this uapi by using explicit field and macros.
Fixes: 2d151d3907
("xfrm: Add possibility to set the default to block if we have no policy")
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
844f7eaaed
commit
f8d858e607
|
@ -514,9 +514,12 @@ struct xfrm_user_offload {
|
||||||
#define XFRM_OFFLOAD_INBOUND 2
|
#define XFRM_OFFLOAD_INBOUND 2
|
||||||
|
|
||||||
struct xfrm_userpolicy_default {
|
struct xfrm_userpolicy_default {
|
||||||
#define XFRM_USERPOLICY_DIRMASK_MAX (sizeof(__u8) * 8)
|
#define XFRM_USERPOLICY_UNSPEC 0
|
||||||
__u8 dirmask;
|
#define XFRM_USERPOLICY_BLOCK 1
|
||||||
__u8 action;
|
#define XFRM_USERPOLICY_ACCEPT 2
|
||||||
|
__u8 in;
|
||||||
|
__u8 fwd;
|
||||||
|
__u8 out;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef __KERNEL__
|
#ifndef __KERNEL__
|
||||||
|
|
|
@ -1966,16 +1966,21 @@ static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
{
|
{
|
||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
struct xfrm_userpolicy_default *up = nlmsg_data(nlh);
|
struct xfrm_userpolicy_default *up = nlmsg_data(nlh);
|
||||||
u8 dirmask;
|
|
||||||
u8 old_default = net->xfrm.policy_default;
|
|
||||||
|
|
||||||
if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX)
|
if (up->in == XFRM_USERPOLICY_BLOCK)
|
||||||
return -EINVAL;
|
net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN;
|
||||||
|
else if (up->in == XFRM_USERPOLICY_ACCEPT)
|
||||||
|
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN;
|
||||||
|
|
||||||
dirmask = (1 << up->dirmask) & XFRM_POL_DEFAULT_MASK;
|
if (up->fwd == XFRM_USERPOLICY_BLOCK)
|
||||||
|
net->xfrm.policy_default |= XFRM_POL_DEFAULT_FWD;
|
||||||
|
else if (up->fwd == XFRM_USERPOLICY_ACCEPT)
|
||||||
|
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_FWD;
|
||||||
|
|
||||||
net->xfrm.policy_default = (old_default & (0xff ^ dirmask))
|
if (up->out == XFRM_USERPOLICY_BLOCK)
|
||||||
| (up->action << up->dirmask);
|
net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT;
|
||||||
|
else if (up->out == XFRM_USERPOLICY_ACCEPT)
|
||||||
|
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_OUT;
|
||||||
|
|
||||||
rt_genid_bump_all(net);
|
rt_genid_bump_all(net);
|
||||||
|
|
||||||
|
@ -1988,13 +1993,11 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
struct sk_buff *r_skb;
|
struct sk_buff *r_skb;
|
||||||
struct nlmsghdr *r_nlh;
|
struct nlmsghdr *r_nlh;
|
||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
struct xfrm_userpolicy_default *r_up, *up;
|
struct xfrm_userpolicy_default *r_up;
|
||||||
int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default));
|
int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default));
|
||||||
u32 portid = NETLINK_CB(skb).portid;
|
u32 portid = NETLINK_CB(skb).portid;
|
||||||
u32 seq = nlh->nlmsg_seq;
|
u32 seq = nlh->nlmsg_seq;
|
||||||
|
|
||||||
up = nlmsg_data(nlh);
|
|
||||||
|
|
||||||
r_skb = nlmsg_new(len, GFP_ATOMIC);
|
r_skb = nlmsg_new(len, GFP_ATOMIC);
|
||||||
if (!r_skb)
|
if (!r_skb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -2005,15 +2008,14 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX) {
|
|
||||||
kfree_skb(r_skb);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_up = nlmsg_data(r_nlh);
|
r_up = nlmsg_data(r_nlh);
|
||||||
|
|
||||||
r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask);
|
r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
|
||||||
r_up->dirmask = up->dirmask;
|
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||||
|
r_up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
|
||||||
|
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||||
|
r_up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
|
||||||
|
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||||
nlmsg_end(r_skb, r_nlh);
|
nlmsg_end(r_skb, r_nlh);
|
||||||
|
|
||||||
return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);
|
return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);
|
||||||
|
|
Loading…
Reference in New Issue