Commit 62f65554 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents d5f497b8 b58b1f56
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -66,11 +66,7 @@ struct netns_xfrm {
	int			sysctl_larval_drop;
	u32			sysctl_acq_expires;

	u8			policy_default;
#define XFRM_POL_DEFAULT_IN	1
#define XFRM_POL_DEFAULT_OUT	2
#define XFRM_POL_DEFAULT_FWD	4
#define XFRM_POL_DEFAULT_MASK	7
	u8			policy_default[XFRM_POLICY_MAX];

#ifdef CONFIG_SYSCTL
	struct ctl_table_header	*sysctl_hdr;
+18 −30
Original line number Diff line number Diff line
@@ -1081,25 +1081,18 @@ xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, un
}

#ifdef CONFIG_XFRM
static inline bool
xfrm_default_allow(struct net *net, int dir)
int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
			unsigned short family);

static inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb,
					 int dir)
{
	u8 def = net->xfrm.policy_default;
	if (!net->xfrm.policy_count[dir] && !secpath_exists(skb))
		return net->xfrm.policy_default[dir] == XFRM_USERPOLICY_ACCEPT;

	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,
			unsigned short family);

static inline int __xfrm_policy_check2(struct sock *sk, int dir,
				       struct sk_buff *skb,
				       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])
		return __xfrm_policy_check(sk, ndir, skb, family);

	if (xfrm_default_allow(net, dir))
		return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
	return __xfrm_check_nopolicy(net, skb, dir) ||
	       (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
	       __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)
@@ -1168,11 +1157,10 @@ static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
	struct net *net = dev_net(skb->dev);

	if (xfrm_default_allow(net, XFRM_POLICY_OUT))
		return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
			(skb_dst(skb)->flags & DST_NOXFRM) ||
			__xfrm_route_forward(skb, family);
	else
	if (!net->xfrm.policy_count[XFRM_POLICY_OUT] &&
	    net->xfrm.policy_default[XFRM_POLICY_OUT] == XFRM_USERPOLICY_ACCEPT)
		return true;

	return (skb_dst(skb)->flags & DST_NOXFRM) ||
	       __xfrm_route_forward(skb, family);
}
+2 −12
Original line number Diff line number Diff line
@@ -384,16 +384,6 @@ static int xfrm_api_check(struct net_device *dev)
	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)
{
	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) {
	case NETDEV_REGISTER:
		return xfrm_dev_register(dev);
		return xfrm_api_check(dev);

	case NETDEV_FEAT_CHANGE:
		return xfrm_dev_feat_change(dev);
		return xfrm_api_check(dev);

	case NETDEV_DOWN:
	case NETDEV_UNREGISTER:
+7 −3
Original line number Diff line number Diff line
@@ -3158,7 +3158,7 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net,

nopol:
	if (!(dst_orig->dev->flags & IFF_LOOPBACK) &&
	    !xfrm_default_allow(net, dir)) {
	    net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) {
		err = -EPERM;
		goto error;
	}
@@ -3569,7 +3569,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
	}

	if (!pol) {
		if (!xfrm_default_allow(net, dir)) {
		if (net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) {
			XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
			return 0;
		}
@@ -3629,7 +3629,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
		}
		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);
			goto reject;
		}
@@ -4118,6 +4119,9 @@ static int __net_init xfrm_net_init(struct net *net)
	spin_lock_init(&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);
	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);
	if (rv < 0)
+18 −25
Original line number Diff line number Diff line
@@ -1994,12 +1994,9 @@ static int xfrm_notify_userpolicy(struct net *net)
	}

	up = nlmsg_data(nlh);
	up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
			XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
	up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
			XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
	up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
			XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
	up->in = net->xfrm.policy_default[XFRM_POLICY_IN];
	up->fwd = net->xfrm.policy_default[XFRM_POLICY_FWD];
	up->out = net->xfrm.policy_default[XFRM_POLICY_OUT];

	nlmsg_end(skb, nlh);

@@ -2010,26 +2007,26 @@ static int xfrm_notify_userpolicy(struct net *net)
	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,
			    struct nlattr **attrs)
{
	struct net *net = sock_net(skb->sk);
	struct xfrm_userpolicy_default *up = nlmsg_data(nlh);

	if (up->in == XFRM_USERPOLICY_BLOCK)
		net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN;
	else if (up->in == XFRM_USERPOLICY_ACCEPT)
		net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN;
	if (xfrm_userpolicy_is_valid(up->in))
		net->xfrm.policy_default[XFRM_POLICY_IN] = up->in;

	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;
	if (xfrm_userpolicy_is_valid(up->fwd))
		net->xfrm.policy_default[XFRM_POLICY_FWD] = up->fwd;

	if (up->out == XFRM_USERPOLICY_BLOCK)
		net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT;
	else if (up->out == XFRM_USERPOLICY_ACCEPT)
		net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_OUT;
	if (xfrm_userpolicy_is_valid(up->out))
		net->xfrm.policy_default[XFRM_POLICY_OUT] = up->out;

	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->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
			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;
	r_up->in = net->xfrm.policy_default[XFRM_POLICY_IN];
	r_up->fwd = net->xfrm.policy_default[XFRM_POLICY_FWD];
	r_up->out = net->xfrm.policy_default[XFRM_POLICY_OUT];
	nlmsg_end(r_skb, r_nlh);

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