Commit b328ecc4 authored by Steffen Klassert's avatar Steffen Klassert

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: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 96a20829
...@@ -218,12 +218,15 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, ...@@ -218,12 +218,15 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
} }
dst_hold(dst); dst_hold(dst);
dst = xfrm_lookup(tunnel->net, dst, fl, NULL, 0); dst = xfrm_lookup_route(tunnel->net, dst, fl, NULL, 0);
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
dev->stats.tx_carrier_errors++; dev->stats.tx_carrier_errors++;
goto tx_error_icmp; goto tx_error_icmp;
} }
if (dst->flags & DST_XFRM_QUEUE)
goto queued;
if (!vti_state_check(dst->xfrm, parms->iph.daddr, parms->iph.saddr)) { if (!vti_state_check(dst->xfrm, parms->iph.daddr, parms->iph.saddr)) {
dev->stats.tx_carrier_errors++; dev->stats.tx_carrier_errors++;
dst_release(dst); dst_release(dst);
...@@ -255,6 +258,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, ...@@ -255,6 +258,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
goto tx_error; goto tx_error;
} }
queued:
skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev))); skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev)));
skb_dst_set(skb, dst); skb_dst_set(skb, dst);
skb->dev = skb_dst(skb)->dev; skb->dev = skb_dst(skb)->dev;
......
...@@ -491,13 +491,16 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) ...@@ -491,13 +491,16 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
} }
dst_hold(dst); dst_hold(dst);
dst = xfrm_lookup(t->net, dst, fl, NULL, 0); dst = xfrm_lookup_route(t->net, dst, fl, NULL, 0);
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
err = PTR_ERR(dst); err = PTR_ERR(dst);
dst = NULL; dst = NULL;
goto tx_err_link_failure; goto tx_err_link_failure;
} }
if (dst->flags & DST_XFRM_QUEUE)
goto queued;
x = dst->xfrm; x = dst->xfrm;
if (!vti6_state_check(x, &t->parms.raddr, &t->parms.laddr)) if (!vti6_state_check(x, &t->parms.raddr, &t->parms.laddr))
goto tx_err_link_failure; goto tx_err_link_failure;
...@@ -533,6 +536,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) ...@@ -533,6 +536,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
goto tx_err_dst_release; goto tx_err_dst_release;
} }
queued:
skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev))); skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev)));
skb_dst_set(skb, dst); skb_dst_set(skb, dst);
skb->dev = skb_dst(skb)->dev; skb->dev = skb_dst(skb)->dev;
......
...@@ -2758,6 +2758,7 @@ static void xfrm_policy_queue_process(struct timer_list *t) ...@@ -2758,6 +2758,7 @@ static void xfrm_policy_queue_process(struct timer_list *t)
struct xfrm_policy_queue *pq = &pol->polq; struct xfrm_policy_queue *pq = &pol->polq;
struct flowi fl; struct flowi fl;
struct sk_buff_head list; struct sk_buff_head list;
__u32 skb_mark;
spin_lock(&pq->hold_queue.lock); spin_lock(&pq->hold_queue.lock);
skb = skb_peek(&pq->hold_queue); skb = skb_peek(&pq->hold_queue);
...@@ -2767,7 +2768,12 @@ static void xfrm_policy_queue_process(struct timer_list *t) ...@@ -2767,7 +2768,12 @@ static void xfrm_policy_queue_process(struct timer_list *t)
} }
dst = skb_dst(skb); dst = skb_dst(skb);
sk = skb->sk; 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); xfrm_decode_session(skb, &fl, dst->ops->family);
skb->mark = skb_mark;
spin_unlock(&pq->hold_queue.lock); spin_unlock(&pq->hold_queue.lock);
dst_hold(xfrm_dst_path(dst)); dst_hold(xfrm_dst_path(dst));
...@@ -2799,7 +2805,12 @@ static void xfrm_policy_queue_process(struct timer_list *t) ...@@ -2799,7 +2805,12 @@ static void xfrm_policy_queue_process(struct timer_list *t)
while (!skb_queue_empty(&list)) { while (!skb_queue_empty(&list)) {
skb = __skb_dequeue(&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); xfrm_decode_session(skb, &fl, skb_dst(skb)->ops->family);
skb->mark = skb_mark;
dst_hold(xfrm_dst_path(skb_dst(skb))); dst_hold(xfrm_dst_path(skb_dst(skb)));
dst = xfrm_lookup(net, xfrm_dst_path(skb_dst(skb)), &fl, skb->sk, 0); dst = xfrm_lookup(net, xfrm_dst_path(skb_dst(skb)), &fl, skb->sk, 0);
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment