|
@@ -88,6 +88,7 @@ static int vti_rcv_cb(struct sk_buff *skb, int err)
|
|
struct net_device *dev;
|
|
struct net_device *dev;
|
|
struct pcpu_sw_netstats *tstats;
|
|
struct pcpu_sw_netstats *tstats;
|
|
struct xfrm_state *x;
|
|
struct xfrm_state *x;
|
|
|
|
+ struct xfrm_mode *inner_mode;
|
|
struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4;
|
|
struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4;
|
|
u32 orig_mark = skb->mark;
|
|
u32 orig_mark = skb->mark;
|
|
int ret;
|
|
int ret;
|
|
@@ -105,7 +106,19 @@ static int vti_rcv_cb(struct sk_buff *skb, int err)
|
|
}
|
|
}
|
|
|
|
|
|
x = xfrm_input_state(skb);
|
|
x = xfrm_input_state(skb);
|
|
- family = x->inner_mode->afinfo->family;
|
|
|
|
|
|
+
|
|
|
|
+ inner_mode = x->inner_mode;
|
|
|
|
+
|
|
|
|
+ if (x->sel.family == AF_UNSPEC) {
|
|
|
|
+ inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
|
|
|
|
+ if (inner_mode == NULL) {
|
|
|
|
+ XFRM_INC_STATS(dev_net(skb->dev),
|
|
|
|
+ LINUX_MIB_XFRMINSTATEMODEERROR);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ family = inner_mode->afinfo->family;
|
|
|
|
|
|
skb->mark = be32_to_cpu(tunnel->parms.i_key);
|
|
skb->mark = be32_to_cpu(tunnel->parms.i_key);
|
|
ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
|
|
ret = xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family);
|