Merge tag 'locking-urgent-2020-08-10' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / net / xfrm / xfrm_policy.c
index 732a940..d5280fd 100644 (file)
@@ -39,7 +39,7 @@
 #ifdef CONFIG_XFRM_STATISTICS
 #include <net/snmp.h>
 #endif
-#ifdef CONFIG_INET_ESPINTCP
+#ifdef CONFIG_XFRM_ESPINTCP
 #include <net/espintcp.h>
 #endif
 
@@ -1433,14 +1433,10 @@ static void xfrm_policy_requeue(struct xfrm_policy *old,
        spin_unlock_bh(&pq->hold_queue.lock);
 }
 
-static bool xfrm_policy_mark_match(struct xfrm_policy *policy,
-                                  struct xfrm_policy *pol)
+static inline bool xfrm_policy_mark_match(const struct xfrm_mark *mark,
+                                         struct xfrm_policy *pol)
 {
-       if (policy->mark.v == pol->mark.v &&
-           policy->priority == pol->priority)
-               return true;
-
-       return false;
+       return mark->v == pol->mark.v && mark->m == pol->mark.m;
 }
 
 static u32 xfrm_pol_bin_key(const void *data, u32 len, u32 seed)
@@ -1503,7 +1499,7 @@ static void xfrm_policy_insert_inexact_list(struct hlist_head *chain,
                if (pol->type == policy->type &&
                    pol->if_id == policy->if_id &&
                    !selector_cmp(&pol->selector, &policy->selector) &&
-                   xfrm_policy_mark_match(policy, pol) &&
+                   xfrm_policy_mark_match(&policy->mark, pol) &&
                    xfrm_sec_ctx_match(pol->security, policy->security) &&
                    !WARN_ON(delpol)) {
                        delpol = pol;
@@ -1538,7 +1534,7 @@ static struct xfrm_policy *xfrm_policy_insert_list(struct hlist_head *chain,
                if (pol->type == policy->type &&
                    pol->if_id == policy->if_id &&
                    !selector_cmp(&pol->selector, &policy->selector) &&
-                   xfrm_policy_mark_match(policy, pol) &&
+                   xfrm_policy_mark_match(&policy->mark, pol) &&
                    xfrm_sec_ctx_match(pol->security, policy->security) &&
                    !WARN_ON(delpol)) {
                        if (excl)
@@ -1610,9 +1606,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 EXPORT_SYMBOL(xfrm_policy_insert);
 
 static struct xfrm_policy *
-__xfrm_policy_bysel_ctx(struct hlist_head *chain, u32 mark, u32 if_id,
-                       u8 type, int dir,
-                       struct xfrm_selector *sel,
+__xfrm_policy_bysel_ctx(struct hlist_head *chain, const struct xfrm_mark *mark,
+                       u32 if_id, u8 type, int dir, struct xfrm_selector *sel,
                        struct xfrm_sec_ctx *ctx)
 {
        struct xfrm_policy *pol;
@@ -1623,7 +1618,7 @@ __xfrm_policy_bysel_ctx(struct hlist_head *chain, u32 mark, u32 if_id,
        hlist_for_each_entry(pol, chain, bydst) {
                if (pol->type == type &&
                    pol->if_id == if_id &&
-                   (mark & pol->mark.m) == pol->mark.v &&
+                   xfrm_policy_mark_match(mark, pol) &&
                    !selector_cmp(sel, &pol->selector) &&
                    xfrm_sec_ctx_match(ctx, pol->security))
                        return pol;
@@ -1632,11 +1627,10 @@ __xfrm_policy_bysel_ctx(struct hlist_head *chain, u32 mark, u32 if_id,
        return NULL;
 }
 
-struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id,
-                                         u8 type, int dir,
-                                         struct xfrm_selector *sel,
-                                         struct xfrm_sec_ctx *ctx, int delete,
-                                         int *err)
+struct xfrm_policy *
+xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+                     u8 type, int dir, struct xfrm_selector *sel,
+                     struct xfrm_sec_ctx *ctx, int delete, int *err)
 {
        struct xfrm_pol_inexact_bin *bin = NULL;
        struct xfrm_policy *pol, *ret = NULL;
@@ -1703,9 +1697,9 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id,
 }
 EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
-struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id,
-                                    u8 type, int dir, u32 id, int delete,
-                                    int *err)
+struct xfrm_policy *
+xfrm_policy_byid(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+                u8 type, int dir, u32 id, int delete, int *err)
 {
        struct xfrm_policy *pol, *ret;
        struct hlist_head *chain;
@@ -1720,8 +1714,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id,
        ret = NULL;
        hlist_for_each_entry(pol, chain, byidx) {
                if (pol->type == type && pol->index == id &&
-                   pol->if_id == if_id &&
-                   (mark & pol->mark.m) == pol->mark.v) {
+                   pol->if_id == if_id && xfrm_policy_mark_match(mark, pol)) {
                        xfrm_pol_hold(pol);
                        if (delete) {
                                *err = security_xfrm_policy_delete(
@@ -2758,6 +2751,7 @@ static void xfrm_policy_queue_process(struct timer_list *t)
        struct xfrm_policy_queue *pq = &pol->polq;
        struct flowi fl;
        struct sk_buff_head list;
+       __u32 skb_mark;
 
        spin_lock(&pq->hold_queue.lock);
        skb = skb_peek(&pq->hold_queue);
@@ -2767,7 +2761,12 @@ static void xfrm_policy_queue_process(struct timer_list *t)
        }
        dst = skb_dst(skb);
        sk = skb->sk;
+
+       /* Fixup the mark to support VTI. */
+       skb_mark = skb->mark;
+       skb->mark = pol->mark.v;
        xfrm_decode_session(skb, &fl, dst->ops->family);
+       skb->mark = skb_mark;
        spin_unlock(&pq->hold_queue.lock);
 
        dst_hold(xfrm_dst_path(dst));
@@ -2799,7 +2798,12 @@ static void xfrm_policy_queue_process(struct timer_list *t)
        while (!skb_queue_empty(&list)) {
                skb = __skb_dequeue(&list);
 
+               /* Fixup the mark to support VTI. */
+               skb_mark = skb->mark;
+               skb->mark = pol->mark.v;
                xfrm_decode_session(skb, &fl, skb_dst(skb)->ops->family);
+               skb->mark = skb_mark;
+
                dst_hold(xfrm_dst_path(skb_dst(skb)));
                dst = xfrm_lookup(net, xfrm_dst_path(skb_dst(skb)), &fl, skb->sk, 0);
                if (IS_ERR(dst)) {
@@ -4156,7 +4160,7 @@ void __init xfrm_init(void)
        seqcount_mutex_init(&xfrm_policy_hash_generation, &hash_resize_mutex);
        xfrm_input_init();
 
-#ifdef CONFIG_INET_ESPINTCP
+#ifdef CONFIG_XFRM_ESPINTCP
        espintcp_init();
 #endif