Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/
ipsec-next Steffen Klassert says: ==================== pull request (net-next): ipsec-next 2022-03-19 1) Delete duplicated functions that calls same xfrm_api_check. From Leon Romanovsky. 2) Align userland API of the default policy structure to the internal structures. From Nicolas Dichtel. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
62f65554f5
|
@ -66,11 +66,7 @@ struct netns_xfrm {
|
||||||
int sysctl_larval_drop;
|
int sysctl_larval_drop;
|
||||||
u32 sysctl_acq_expires;
|
u32 sysctl_acq_expires;
|
||||||
|
|
||||||
u8 policy_default;
|
u8 policy_default[XFRM_POLICY_MAX];
|
||||||
#define XFRM_POL_DEFAULT_IN 1
|
|
||||||
#define XFRM_POL_DEFAULT_OUT 2
|
|
||||||
#define XFRM_POL_DEFAULT_FWD 4
|
|
||||||
#define XFRM_POL_DEFAULT_MASK 7
|
|
||||||
|
|
||||||
#ifdef CONFIG_SYSCTL
|
#ifdef CONFIG_SYSCTL
|
||||||
struct ctl_table_header *sysctl_hdr;
|
struct ctl_table_header *sysctl_hdr;
|
||||||
|
|
|
@ -1081,25 +1081,18 @@ xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, un
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_XFRM
|
#ifdef CONFIG_XFRM
|
||||||
static inline bool
|
|
||||||
xfrm_default_allow(struct net *net, int dir)
|
|
||||||
{
|
|
||||||
u8 def = net->xfrm.policy_default;
|
|
||||||
|
|
||||||
switch (dir) {
|
|
||||||
case XFRM_POLICY_IN:
|
|
||||||
return def & XFRM_POL_DEFAULT_IN ? false : true;
|
|
||||||
case XFRM_POLICY_OUT:
|
|
||||||
return def & XFRM_POL_DEFAULT_OUT ? false : true;
|
|
||||||
case XFRM_POLICY_FWD:
|
|
||||||
return def & XFRM_POL_DEFAULT_FWD ? false : true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
|
int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
|
||||||
unsigned short family);
|
unsigned short family);
|
||||||
|
|
||||||
|
static inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb,
|
||||||
|
int dir)
|
||||||
|
{
|
||||||
|
if (!net->xfrm.policy_count[dir] && !secpath_exists(skb))
|
||||||
|
return net->xfrm.policy_default[dir] == XFRM_USERPOLICY_ACCEPT;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int __xfrm_policy_check2(struct sock *sk, int dir,
|
static inline int __xfrm_policy_check2(struct sock *sk, int dir,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
unsigned int family, int reverse)
|
unsigned int family, int reverse)
|
||||||
|
@ -1110,13 +1103,9 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
|
||||||
if (sk && sk->sk_policy[XFRM_POLICY_IN])
|
if (sk && sk->sk_policy[XFRM_POLICY_IN])
|
||||||
return __xfrm_policy_check(sk, ndir, skb, family);
|
return __xfrm_policy_check(sk, ndir, skb, family);
|
||||||
|
|
||||||
if (xfrm_default_allow(net, dir))
|
return __xfrm_check_nopolicy(net, skb, dir) ||
|
||||||
return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
|
(skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
|
||||||
(skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
|
__xfrm_policy_check(sk, ndir, skb, family);
|
||||||
__xfrm_policy_check(sk, ndir, skb, family);
|
|
||||||
else
|
|
||||||
return (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
|
|
||||||
__xfrm_policy_check(sk, ndir, skb, family);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
|
static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
|
||||||
|
@ -1168,13 +1157,12 @@ static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
|
||||||
{
|
{
|
||||||
struct net *net = dev_net(skb->dev);
|
struct net *net = dev_net(skb->dev);
|
||||||
|
|
||||||
if (xfrm_default_allow(net, XFRM_POLICY_OUT))
|
if (!net->xfrm.policy_count[XFRM_POLICY_OUT] &&
|
||||||
return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
|
net->xfrm.policy_default[XFRM_POLICY_OUT] == XFRM_USERPOLICY_ACCEPT)
|
||||||
(skb_dst(skb)->flags & DST_NOXFRM) ||
|
return true;
|
||||||
__xfrm_route_forward(skb, family);
|
|
||||||
else
|
return (skb_dst(skb)->flags & DST_NOXFRM) ||
|
||||||
return (skb_dst(skb)->flags & DST_NOXFRM) ||
|
__xfrm_route_forward(skb, family);
|
||||||
__xfrm_route_forward(skb, family);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int xfrm4_route_forward(struct sk_buff *skb)
|
static inline int xfrm4_route_forward(struct sk_buff *skb)
|
||||||
|
|
|
@ -384,16 +384,6 @@ static int xfrm_api_check(struct net_device *dev)
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xfrm_dev_register(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return xfrm_api_check(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xfrm_dev_feat_change(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return xfrm_api_check(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xfrm_dev_down(struct net_device *dev)
|
static int xfrm_dev_down(struct net_device *dev)
|
||||||
{
|
{
|
||||||
if (dev->features & NETIF_F_HW_ESP)
|
if (dev->features & NETIF_F_HW_ESP)
|
||||||
|
@ -408,10 +398,10 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NETDEV_REGISTER:
|
case NETDEV_REGISTER:
|
||||||
return xfrm_dev_register(dev);
|
return xfrm_api_check(dev);
|
||||||
|
|
||||||
case NETDEV_FEAT_CHANGE:
|
case NETDEV_FEAT_CHANGE:
|
||||||
return xfrm_dev_feat_change(dev);
|
return xfrm_api_check(dev);
|
||||||
|
|
||||||
case NETDEV_DOWN:
|
case NETDEV_DOWN:
|
||||||
case NETDEV_UNREGISTER:
|
case NETDEV_UNREGISTER:
|
||||||
|
|
|
@ -3158,7 +3158,7 @@ ok:
|
||||||
|
|
||||||
nopol:
|
nopol:
|
||||||
if (!(dst_orig->dev->flags & IFF_LOOPBACK) &&
|
if (!(dst_orig->dev->flags & IFF_LOOPBACK) &&
|
||||||
!xfrm_default_allow(net, dir)) {
|
net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) {
|
||||||
err = -EPERM;
|
err = -EPERM;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -3569,7 +3569,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pol) {
|
if (!pol) {
|
||||||
if (!xfrm_default_allow(net, dir)) {
|
if (net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) {
|
||||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
|
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3629,7 +3629,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
xfrm_nr = ti;
|
xfrm_nr = ti;
|
||||||
|
|
||||||
if (!xfrm_default_allow(net, dir) && !xfrm_nr) {
|
if (net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK &&
|
||||||
|
!xfrm_nr) {
|
||||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
|
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
|
||||||
goto reject;
|
goto reject;
|
||||||
}
|
}
|
||||||
|
@ -4118,6 +4119,9 @@ static int __net_init xfrm_net_init(struct net *net)
|
||||||
spin_lock_init(&net->xfrm.xfrm_policy_lock);
|
spin_lock_init(&net->xfrm.xfrm_policy_lock);
|
||||||
seqcount_spinlock_init(&net->xfrm.xfrm_policy_hash_generation, &net->xfrm.xfrm_policy_lock);
|
seqcount_spinlock_init(&net->xfrm.xfrm_policy_hash_generation, &net->xfrm.xfrm_policy_lock);
|
||||||
mutex_init(&net->xfrm.xfrm_cfg_mutex);
|
mutex_init(&net->xfrm.xfrm_cfg_mutex);
|
||||||
|
net->xfrm.policy_default[XFRM_POLICY_IN] = XFRM_USERPOLICY_ACCEPT;
|
||||||
|
net->xfrm.policy_default[XFRM_POLICY_FWD] = XFRM_USERPOLICY_ACCEPT;
|
||||||
|
net->xfrm.policy_default[XFRM_POLICY_OUT] = XFRM_USERPOLICY_ACCEPT;
|
||||||
|
|
||||||
rv = xfrm_statistics_init(net);
|
rv = xfrm_statistics_init(net);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
|
|
|
@ -1994,12 +1994,9 @@ static int xfrm_notify_userpolicy(struct net *net)
|
||||||
}
|
}
|
||||||
|
|
||||||
up = nlmsg_data(nlh);
|
up = nlmsg_data(nlh);
|
||||||
up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
|
up->in = net->xfrm.policy_default[XFRM_POLICY_IN];
|
||||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
up->fwd = net->xfrm.policy_default[XFRM_POLICY_FWD];
|
||||||
up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
|
up->out = net->xfrm.policy_default[XFRM_POLICY_OUT];
|
||||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
|
||||||
up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
|
|
||||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
|
||||||
|
|
||||||
nlmsg_end(skb, nlh);
|
nlmsg_end(skb, nlh);
|
||||||
|
|
||||||
|
@ -2010,26 +2007,26 @@ static int xfrm_notify_userpolicy(struct net *net)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool xfrm_userpolicy_is_valid(__u8 policy)
|
||||||
|
{
|
||||||
|
return policy == XFRM_USERPOLICY_BLOCK ||
|
||||||
|
policy == XFRM_USERPOLICY_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
struct nlattr **attrs)
|
struct nlattr **attrs)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
if (up->in == XFRM_USERPOLICY_BLOCK)
|
if (xfrm_userpolicy_is_valid(up->in))
|
||||||
net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN;
|
net->xfrm.policy_default[XFRM_POLICY_IN] = up->in;
|
||||||
else if (up->in == XFRM_USERPOLICY_ACCEPT)
|
|
||||||
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN;
|
|
||||||
|
|
||||||
if (up->fwd == XFRM_USERPOLICY_BLOCK)
|
if (xfrm_userpolicy_is_valid(up->fwd))
|
||||||
net->xfrm.policy_default |= XFRM_POL_DEFAULT_FWD;
|
net->xfrm.policy_default[XFRM_POLICY_FWD] = up->fwd;
|
||||||
else if (up->fwd == XFRM_USERPOLICY_ACCEPT)
|
|
||||||
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_FWD;
|
|
||||||
|
|
||||||
if (up->out == XFRM_USERPOLICY_BLOCK)
|
if (xfrm_userpolicy_is_valid(up->out))
|
||||||
net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT;
|
net->xfrm.policy_default[XFRM_POLICY_OUT] = up->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);
|
||||||
|
|
||||||
|
@ -2059,13 +2056,9 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
}
|
}
|
||||||
|
|
||||||
r_up = nlmsg_data(r_nlh);
|
r_up = nlmsg_data(r_nlh);
|
||||||
|
r_up->in = net->xfrm.policy_default[XFRM_POLICY_IN];
|
||||||
r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
|
r_up->fwd = net->xfrm.policy_default[XFRM_POLICY_FWD];
|
||||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
r_up->out = net->xfrm.policy_default[XFRM_POLICY_OUT];
|
||||||
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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче