aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2020-07-17 10:35:32 +0200
committerSteffen Klassert <steffen.klassert@secunet.com>2020-07-21 08:34:44 +0200
commitb328ecc468f8f92433c9ad82675c0ce9f99b10cf (patch)
tree6e74a4c8b50746ebb7a53d40d027081af3d21385 /net/xfrm/xfrm_policy.c
parentip6_vti: use IS_REACHABLE to avoid some compile errors (diff)
downloadlinux-dev-b328ecc468f8f92433c9ad82675c0ce9f99b10cf.tar.xz
linux-dev-b328ecc468f8f92433c9ad82675c0ce9f99b10cf.zip
xfrm: Make the policy hold queue work with VTI.
We forgot to support the xfrm policy hold queue when VTI was implemented. This patch adds everything we need so that we can use the policy hold queue together with VTI interfaces. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 564aa6492e7c..be150475b28b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2758,6 +2758,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 +2768,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 +2805,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)) {