Skip to content

Commit 047a749

Browse files
committed
Merge branch 'xfrm: fix uapi for the default policy'
Nicolas Dichtel says: ==================== This feature has just been merged after the last release, thus it's still time to fix the uapi. As stated in the thread, the uapi is based on some magic values (from the userland POV). Here is a proposal to simplify this uapi and make it clear how to use it. The other problem was the notification: changing the default policy may radically change the packets flows. v2 -> v3: rebase on top of ipsec tree v1 -> v2: fix warnings reported by the kernel test robot ==================== Signed-off-by: Steffen Klassert <[email protected]>
2 parents 844f7ea + 88d0adb commit 047a749

File tree

2 files changed

+56
-20
lines changed

2 files changed

+56
-20
lines changed

include/uapi/linux/xfrm.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -514,9 +514,12 @@ struct xfrm_user_offload {
514514
#define XFRM_OFFLOAD_INBOUND 2
515515

516516
struct xfrm_userpolicy_default {
517-
#define XFRM_USERPOLICY_DIRMASK_MAX (sizeof(__u8) * 8)
518-
__u8 dirmask;
519-
__u8 action;
517+
#define XFRM_USERPOLICY_UNSPEC 0
518+
#define XFRM_USERPOLICY_BLOCK 1
519+
#define XFRM_USERPOLICY_ACCEPT 2
520+
__u8 in;
521+
__u8 fwd;
522+
__u8 out;
520523
};
521524

522525
#ifndef __KERNEL__

net/xfrm/xfrm_user.c

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,24 +1961,60 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
19611961
return skb;
19621962
}
19631963

1964+
static int xfrm_notify_userpolicy(struct net *net)
1965+
{
1966+
struct xfrm_userpolicy_default *up;
1967+
int len = NLMSG_ALIGN(sizeof(*up));
1968+
struct nlmsghdr *nlh;
1969+
struct sk_buff *skb;
1970+
1971+
skb = nlmsg_new(len, GFP_ATOMIC);
1972+
if (skb == NULL)
1973+
return -ENOMEM;
1974+
1975+
nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_GETDEFAULT, sizeof(*up), 0);
1976+
if (nlh == NULL) {
1977+
kfree_skb(skb);
1978+
return -EMSGSIZE;
1979+
}
1980+
1981+
up = nlmsg_data(nlh);
1982+
up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
1983+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
1984+
up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
1985+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
1986+
up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
1987+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
1988+
1989+
nlmsg_end(skb, nlh);
1990+
1991+
return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_POLICY);
1992+
}
1993+
19641994
static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
19651995
struct nlattr **attrs)
19661996
{
19671997
struct net *net = sock_net(skb->sk);
19681998
struct xfrm_userpolicy_default *up = nlmsg_data(nlh);
1969-
u8 dirmask;
1970-
u8 old_default = net->xfrm.policy_default;
19711999

1972-
if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX)
1973-
return -EINVAL;
2000+
if (up->in == XFRM_USERPOLICY_BLOCK)
2001+
net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN;
2002+
else if (up->in == XFRM_USERPOLICY_ACCEPT)
2003+
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN;
19742004

1975-
dirmask = (1 << up->dirmask) & XFRM_POL_DEFAULT_MASK;
2005+
if (up->fwd == XFRM_USERPOLICY_BLOCK)
2006+
net->xfrm.policy_default |= XFRM_POL_DEFAULT_FWD;
2007+
else if (up->fwd == XFRM_USERPOLICY_ACCEPT)
2008+
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_FWD;
19762009

1977-
net->xfrm.policy_default = (old_default & (0xff ^ dirmask))
1978-
| (up->action << up->dirmask);
2010+
if (up->out == XFRM_USERPOLICY_BLOCK)
2011+
net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT;
2012+
else if (up->out == XFRM_USERPOLICY_ACCEPT)
2013+
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_OUT;
19792014

19802015
rt_genid_bump_all(net);
19812016

2017+
xfrm_notify_userpolicy(net);
19822018
return 0;
19832019
}
19842020

@@ -1988,13 +2024,11 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
19882024
struct sk_buff *r_skb;
19892025
struct nlmsghdr *r_nlh;
19902026
struct net *net = sock_net(skb->sk);
1991-
struct xfrm_userpolicy_default *r_up, *up;
2027+
struct xfrm_userpolicy_default *r_up;
19922028
int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default));
19932029
u32 portid = NETLINK_CB(skb).portid;
19942030
u32 seq = nlh->nlmsg_seq;
19952031

1996-
up = nlmsg_data(nlh);
1997-
19982032
r_skb = nlmsg_new(len, GFP_ATOMIC);
19992033
if (!r_skb)
20002034
return -ENOMEM;
@@ -2005,15 +2039,14 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
20052039
return -EMSGSIZE;
20062040
}
20072041

2008-
if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX) {
2009-
kfree_skb(r_skb);
2010-
return -EINVAL;
2011-
}
2012-
20132042
r_up = nlmsg_data(r_nlh);
20142043

2015-
r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask);
2016-
r_up->dirmask = up->dirmask;
2044+
r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
2045+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
2046+
r_up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
2047+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
2048+
r_up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
2049+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
20172050
nlmsg_end(r_skb, r_nlh);
20182051

20192052
return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);

0 commit comments

Comments
 (0)