[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190111144357.9700-1-nicolas.dichtel@6wind.com>
Date: Fri, 11 Jan 2019 15:43:57 +0100
From: Nicolas Dichtel <nicolas.dichtel@...nd.com>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org,
Nicolas Dichtel <nicolas.dichtel@...nd.com>,
Willem de Bruijn <willemb@...gle.com>
Subject: [PATCH net] af_packet: fix raw sockets over 6in4 tunnel
Since commit cb9f1b783850, scapy (which uses an AF_PACKET socket in
SOCK_RAW mode) is unable to send a basic icmp packet over a sit tunnel:
Here is a example of the setup:
$ ip link set ntfp2 up
$ ip addr add 10.125.0.1/24 dev ntfp2
$ ip tunnel add tun1 mode sit ttl 64 local 10.125.0.1 remote 10.125.0.2 dev ntfp2
$ ip addr add fd00:cafe:cafe::1/128 dev tun1
$ ip link set dev tun1 up
$ ip route add fd00:200::/64 dev tun1
$ scapy
>>> p = []
>>> p += IPv6(src='fd00:100::1', dst='fd00:200::1')/ICMPv6EchoRequest()
>>> send(p, count=1, inter=0.1)
>>> quit()
$ ip -s link ls dev tun1 | grep -A1 "TX.*errors"
TX: bytes packets errors dropped carrier collsns
0 0 1 0 0 0
The problem is that the network offset is set to the hard_header_len of the
output device (tun1, ie 14 + 20) and in our case, because the packet is
small (48 bytes) the pskb_inet_may_pull() fails (it tries to pull 40 bytes
(ipv6 header) starting from the network offset). Let's reset the network
offset so that it points to the beginning of the L3 data, ie skb->data.
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=993675a3100b1
Fixes: cb9f1b783850 ("ip: validate header length on virtual device xmit")
CC: Willem de Bruijn <willemb@...gle.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@...nd.com>
---
net/packet/af_packet.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index d0945253f43b..911c3870e66d 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2887,8 +2887,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
goto out_free;
} else if (reserve) {
skb_reserve(skb, -reserve);
- if (len < reserve)
- skb_reset_network_header(skb);
+ skb_reset_network_header(skb);
}
/* Returns -EFAULT on error */
--
2.18.0
Powered by blists - more mailing lists