Re: 5.6 Icmp6 checksum / pf

2014-11-10 Thread Mike Belopuhov
On Sun, Nov 09, 2014 at 10:17 +0100, Bastien Durel wrote:
 Hi,
 
 I recently upgraded to 5.6, and got problems with icmpv6
 
 I have a gif tunnel for IPv6:
 [root@fremen root]# ifconfig gif0 
   
   
   
 gif0: flags=8051UP,POINTOPOINT,RUNNING,MULTICAST mtu 1280
 description: Sixxs
 priority: 0
 groups: gif egress
 tunnel: inet 78.194.94.73 - 212.100.184.146
 inet6 fe80::200:24ff:fecf:42ac%gif0 - prefixlen 64 scopeid 0x10
 inet6 2001:6f8:202:19c::2 - 2001:6f8:202:19c::1 prefixlen 128
 
 When I initiate a ping from this interface, it works as intended:
 
 08:59:38.376107 2001:6f8:202:19c::2  2001:41d0:8:91a::1: icmp6: echo request 
 (id:392e seq:0) [icmp6 cksum ok] (len 16, hlim 64)
 08:59:38.410385 2001:41d0:8:91a::1  2001:6f8:202:19c::2: icmp6: echo reply 
 (id:392e seq:0) [icmp6 cksum ok] (len 16, hlim 57)
 08:59:39.389383 2001:6f8:202:19c::2  2001:41d0:8:91a::1: icmp6: echo request 
 (id:392e seq:1) [icmp6 cksum ok] (len 16, hlim 64)
 08:59:39.421397 2001:41d0:8:91a::1  2001:6f8:202:19c::2: icmp6: echo reply 
 (id:392e seq:1) [icmp6 cksum ok] (len 16, hlim 57)
 
 But when a ping from outside reached it, the echo reply is sent with a
 bad (0) checksum, and the packet is dropped by te other side:
 
 09:40:28.852102 2001:41d0:8:91a::1  2001:6f8:202:19c::2: icmp6: echo request 
 (id:6c10 seq:1) [icmp6 cksum ok] (len 64, hlim 57)
 09:40:28.852251 2001:6f8:202:19c::2  2001:41d0:8:91a::1: icmp6: echo reply 
 (id:6c10 seq:1) [bad icmp6 cksum 0! - 2d93] (len 64, hlim 64)
 09:40:29.860327 2001:41d0:8:91a::1  2001:6f8:202:19c::2: icmp6: echo request 
 (id:6c10 seq:2) [icmp6 cksum ok] (len 64, hlim 57)
 09:40:29.860432 2001:6f8:202:19c::2  2001:41d0:8:91a::1: icmp6: echo reply 
 (id:6c10 seq:2) [bad icmp6 cksum 0! - 8a71] (len 64, hlim 64)
 
 It works correctly with this pf rule disabled:
 pass in on gif0 reply-to ( gif0 2001:6f8:202:19c::1 ) keep state
 
 What's the correct way to handle correct return-path ?
 
 Regards,
 
 -- 
 Bastien Durel
 

hi,

looks like it's caused by the forgotten in6_proto_cksum_out call
in the pf_route6 after possible pf_map_addr/PF_ACPY manipulations.

bastien, can you please verify that the diff below fixes your
issue?

diff --git sys/net/pf.c sys/net/pf.c
index 979f44d..4c934db 100644
--- sys/net/pf.c
+++ sys/net/pf.c
@@ -5777,20 +5777,22 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, 
struct ifnet *oifp,
goto bad;
else if (m0 == NULL)
goto done;
if (m0-m_len  sizeof(struct ip6_hdr)) {
DPFPRINTF(LOG_ERR,
pf_route6: m0-m_len  sizeof(struct ip6_hdr));
goto bad;
}
}
 
+   in6_proto_cksum_out(m0, ifp);
+
/*
 * If the packet is too large for the outgoing interface,
 * send back an icmp6 error.
 */
if (IN6_IS_SCOPE_EMBED(dst-sin6_addr))
dst-sin6_addr.s6_addr16[1] = htons(ifp-if_index);
if ((u_long)m0-m_pkthdr.len = ifp-if_mtu) {
nd6_output(ifp, ifp, m0, dst, NULL);
} else {
in6_ifstat_inc(ifp, ifs6_in_toobig);



Re: 5.6 Icmp6 checksum / pf

2014-11-10 Thread Bastien Durel

Le 10/11/2014 14:54, Mike Belopuhov a écrit :

On Sun, Nov 09, 2014 at 10:17 +0100, Bastien Durel wrote:

Hi,

I recently upgraded to 5.6, and got problems with icmpv6

I have a gif tunnel for IPv6:
[root@fremen root]# ifconfig gif0
gif0: flags=8051UP,POINTOPOINT,RUNNING,MULTICAST mtu 1280
 description: Sixxs
 priority: 0
 groups: gif egress
 tunnel: inet 78.194.94.73 - 212.100.184.146
 inet6 fe80::200:24ff:fecf:42ac%gif0 - prefixlen 64 scopeid 0x10
 inet6 2001:6f8:202:19c::2 - 2001:6f8:202:19c::1 prefixlen 128

When I initiate a ping from this interface, it works as intended:

08:59:38.376107 2001:6f8:202:19c::2  2001:41d0:8:91a::1: icmp6: echo request 
(id:392e seq:0) [icmp6 cksum ok] (len 16, hlim 64)
08:59:38.410385 2001:41d0:8:91a::1  2001:6f8:202:19c::2: icmp6: echo reply 
(id:392e seq:0) [icmp6 cksum ok] (len 16, hlim 57)
08:59:39.389383 2001:6f8:202:19c::2  2001:41d0:8:91a::1: icmp6: echo request 
(id:392e seq:1) [icmp6 cksum ok] (len 16, hlim 64)
08:59:39.421397 2001:41d0:8:91a::1  2001:6f8:202:19c::2: icmp6: echo reply 
(id:392e seq:1) [icmp6 cksum ok] (len 16, hlim 57)

But when a ping from outside reached it, the echo reply is sent with a
bad (0) checksum, and the packet is dropped by te other side:

09:40:28.852102 2001:41d0:8:91a::1  2001:6f8:202:19c::2: icmp6: echo request 
(id:6c10 seq:1) [icmp6 cksum ok] (len 64, hlim 57)
09:40:28.852251 2001:6f8:202:19c::2  2001:41d0:8:91a::1: icmp6: echo reply 
(id:6c10 seq:1) [bad icmp6 cksum 0! - 2d93] (len 64, hlim 64)
09:40:29.860327 2001:41d0:8:91a::1  2001:6f8:202:19c::2: icmp6: echo request 
(id:6c10 seq:2) [icmp6 cksum ok] (len 64, hlim 57)
09:40:29.860432 2001:6f8:202:19c::2  2001:41d0:8:91a::1: icmp6: echo reply 
(id:6c10 seq:2) [bad icmp6 cksum 0! - 8a71] (len 64, hlim 64)

It works correctly with this pf rule disabled:
pass in on gif0 reply-to ( gif0 2001:6f8:202:19c::1 ) keep state

What's the correct way to handle correct return-path ?

Regards,

--
Bastien Durel



hi,

looks like it's caused by the forgotten in6_proto_cksum_out call
in the pf_route6 after possible pf_map_addr/PF_ACPY manipulations.

bastien, can you please verify that the diff below fixes your
issue?

diff --git sys/net/pf.c sys/net/pf.c
index 979f44d..4c934db 100644
--- sys/net/pf.c
+++ sys/net/pf.c
@@ -5777,20 +5777,22 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, 
struct ifnet *oifp,
goto bad;
else if (m0 == NULL)
goto done;
if (m0-m_len  sizeof(struct ip6_hdr)) {
DPFPRINTF(LOG_ERR,
pf_route6: m0-m_len  sizeof(struct ip6_hdr));
goto bad;
}
}

+   in6_proto_cksum_out(m0, ifp);
+
/*
 * If the packet is too large for the outgoing interface,
 * send back an icmp6 error.
 */
if (IN6_IS_SCOPE_EMBED(dst-sin6_addr))
dst-sin6_addr.s6_addr16[1] = htons(ifp-if_index);
if ((u_long)m0-m_pkthdr.len = ifp-if_mtu) {
nd6_output(ifp, ifp, m0, dst, NULL);
} else {
in6_ifstat_inc(ifp, ifs6_in_toobig);


Hello,

This works, thanks.

--
Bastien