ip_vti: receive ipip packet by calling ip_tunnel_rcv
In Commitdd9ee34440
("vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel"), it tries to receive IPIP packets in vti by calling xfrm_input(). This case happens when a small packet or frag sent by peer is too small to get compressed. However, xfrm_input() will still get to the IPCOMP path where skb sec_path is set, but never dropped while it should have been done in vti_ipcomp4_protocol.cb_handler(vti_rcv_cb), as it's not an ipcomp4 packet. This will cause that the packet can never pass xfrm4_policy_check() in the upper protocol rcv functions. So this patch is to call ip_tunnel_rcv() to process IPIP packets instead. Fixes:dd9ee34440
("vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel") Reported-by: Xiumei Mu <xmu@redhat.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
a204aef9fd
commit
976eba8ab5
|
@ -93,7 +93,28 @@ static int vti_rcv_proto(struct sk_buff *skb)
|
||||||
|
|
||||||
static int vti_rcv_tunnel(struct sk_buff *skb)
|
static int vti_rcv_tunnel(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return vti_rcv(skb, ip_hdr(skb)->saddr, true);
|
struct ip_tunnel_net *itn = net_generic(dev_net(skb->dev), vti_net_id);
|
||||||
|
const struct iphdr *iph = ip_hdr(skb);
|
||||||
|
struct ip_tunnel *tunnel;
|
||||||
|
|
||||||
|
tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
|
||||||
|
iph->saddr, iph->daddr, 0);
|
||||||
|
if (tunnel) {
|
||||||
|
struct tnl_ptk_info tpi = {
|
||||||
|
.proto = htons(ETH_P_IP),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
|
||||||
|
goto drop;
|
||||||
|
if (iptunnel_pull_header(skb, 0, tpi.proto, false))
|
||||||
|
goto drop;
|
||||||
|
return ip_tunnel_rcv(tunnel, skb, &tpi, NULL, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
drop:
|
||||||
|
kfree_skb(skb);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vti_rcv_cb(struct sk_buff *skb, int err)
|
static int vti_rcv_cb(struct sk_buff *skb, int err)
|
||||||
|
|
Loading…
Reference in New Issue