Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/
authorDavid S. Miller <davem@davemloft.net>
Sat, 19 Mar 2022 14:49:08 +0000 (14:49 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 19 Mar 2022 14:49:08 +0000 (14:49 +0000)
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>
include/net/netns/xfrm.h
include/net/xfrm.h
net/xfrm/xfrm_device.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c

index 947733a..bd7c3be 100644 (file)
@@ -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;
index 76aa6f1..6fb899f 100644 (file)
@@ -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)
-{
-       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,
                        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,
                                       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)) ||
-                      (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);
+       return __xfrm_check_nopolicy(net, skb, dir) ||
+              (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,13 +1157,12 @@ 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
-               return (skb_dst(skb)->flags & DST_NOXFRM) ||
-                       __xfrm_route_forward(skb, family);
+       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);
 }
 
 static inline int xfrm4_route_forward(struct sk_buff *skb)
index 3e3448a..36aa01d 100644 (file)
@@ -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:
index 8825261..19aa994 100644 (file)
@@ -3158,7 +3158,7 @@ ok:
 
 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)
index 72b2f17..64fa8fd 100644 (file)
@@ -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);