From owner-hackers+M63686=david=gwynne.id.au@openbsd.org Mon Feb 2 07:00:14 2015 Delivered-To: david@gwynne.id.au Received: by 10.216.49.9 with SMTP id w9csp901922web; Sun, 1 Feb 2015 13:00:15 -0800 (PST) X-Received: by 10.107.13.76 with SMTP id 73mr19173320ion.24.1422824414510; Sun, 01 Feb 2015 13:00:14 -0800 (PST) Return-Path: Received: from shear.ucar.edu (lists.openbsd.org. [192.43.244.163]) by mx.google.com with ESMTPS id c78si2520399ioe.76.2015.02.01.13.00.13 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 01 Feb 2015 13:00:14 -0800 (PST) Received-SPF: pass (google.com: manual fallback record for domain of owner-hackers+M63686=david=gwynne.id.au@openbsd.org designates 192.43.244.163 as permitted sender) client-ip=192.43.244.163; Authentication-Results: mx.google.com; spf=pass (google.com: manual fallback record for domain of owner-hackers+M63686=david=gwynne.id.au@openbsd.org designates 192.43.244.163 as permitted sender) smtp.mail=owner-hackers+M63686=david=gwynne.id.au@openbsd.org Received: from openbsd.org (localhost [127.0.0.1]) by shear.ucar.edu (8.14.8/8.14.5) with ESMTP id t11LE9jr003908 for ; Sun, 1 Feb 2015 14:14:09 -0700 (MST) Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by shear.ucar.edu (8.14.8/8.14.8) with ESMTP id t11LE5QH005220 (version=TLSv1/SSLv3 cipher=DHE-DSS-AES256-SHA bits=256 verify=NO) for ; Sun, 1 Feb 2015 14:14:07 -0700 (MST) Received: from mfilter26-d.gandi.net (mfilter26-d.gandi.net [217.70.178.154]) by relay4-d.mail.gandi.net (Postfix) with ESMTP id DEE0117208B for ; Sun, 1 Feb 2015 22:00:05 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at mfilter26-d.gandi.net Received: from relay4-d.mail.gandi.net ([217.70.183.196]) by mfilter26-d.gandi.net (mfilter26-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id MDlMyPKc2xFV for ; Sun, 1 Feb 2015 22:00:04 +0100 (CET) X-Originating-IP: 217.50.165.87 Received: from noz.nolizard.org (koln-d932a557.pool.mediaways.net [217.50.165.87]) (Authenticated sender: mpieuchot@nolizard.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id 08F55172098 for ; Sun, 1 Feb 2015 22:00:03 +0100 (CET) Received: from localhost (noz.nolizard.org [local]); by noz.nolizard.org (OpenSMTPD) with ESMTPA id 8644938d; for ; Sun, 1 Feb 2015 22:00:02 +0100 (CET) Date: Sun, 1 Feb 2015 22:00:02 +0100 From: Martin Pieuchot To: hackers@openbsd.org Subject: Re: enable pfctl to print scoped v6 addresses Message-ID: <20150201210002.GI32646@noz.nolizard.org> References: <20141224084406.GJ265@animata.net> <20141224111644.GA3177@dali.vantronix.net> <20150119000800.GB32054@dali.vantronix.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Loop: hackers@openbsd.org Precedence: list Sender: owner-hackers@openbsd.org Status: RO Content-Length: 6001 Lines: 164 On 19/01/15(Mon) 16:05, David Gwynne wrote: > [...] > i have the following rules: > > table persist { self } > lladdr6="fe80::/10" > > # default deny for ipv6 is INSANE > pass quick inet6 proto icmp6 to { ff02::1:ff00:0/104 } icmp6-type { nei > ghbrsol neighbradv } > block in quick on uqnet inet6 proto icmp6 to ff02::1 icmp6-type routeradv > block in quick on uqnet inet6 proto icmp6 from $lladdr6 to $lladdr6 icmp6-type > routeradv > block in log quick inet6 proto icmp6 to ff02::1 icmp6-type routeradv > > i cant even load these. i get output like this: > > /etc/pf.conf:503: address requires valid scope > /etc/pf.conf:503: skipping rule due to errors > /etc/pf.conf:503: skipping rule due to errors > /etc/pf.conf:503: address requires valid scope > /etc/pf.conf:503: skipping rule due to errors > /etc/pf.conf:504: interface uqnet not found > /etc/pf.conf:504: skipping rule due to errors > /etc/pf.conf:504: rule expands to no valid combination > /etc/pf.conf:505: interface uqnet not found > /etc/pf.conf:505: interface uqnet not found > /etc/pf.conf:505: skipping rule due to errors > /etc/pf.conf:505: rule expands to no valid combination > /etc/pf.conf:506: address requires valid scope > /etc/pf.conf:506: skipping rule due to errors > /etc/pf.conf:506: rule expands to no valid combination > > uqnet is an interface group made up of the two interfaces i peer with upstream with. > > my opinion is if a scope is not specified on a link local address, it should be considered a wildcard. it should match on packets coming in on any interface. > > with the code as it is now, if pf decides to log a packet in the kernel with link local addresses on it, tcpdump -ni pflog0 will see the embedded scope come off the "wire". the scope should be cleared before we give it to bpf. > > maybe i just dont understand v6 and pf. Here's a diff that restores the previous behavior. pf(4) does not see embedded scopes. It's a bit ugly do to a save & restore dance but I don't think there's a better solution as long as RTF_LOCAL routes are inserted with an embedded scope. With this diff I verified that the original issues are still fixed, in other words pinging link-local addresses even without "set skip on lo" works. Index: netinet6/ip6_input.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.135 diff -u -p -r1.135 ip6_input.c --- netinet6/ip6_input.c 19 Jan 2015 13:53:55 -0000 1.135 +++ netinet6/ip6_input.c 1 Feb 2015 20:38:13 -0000 @@ -190,8 +190,8 @@ ip6_input(struct mbuf *m) struct ifnet *ifp; struct ip6_hdr *ip6; int off, nest; - u_int32_t plen; - u_int32_t rtalert = ~0; + u_int16_t src_scope, dst_scope; + u_int32_t plen, rtalert = ~0; int nxt, ours = 0; struct ifnet *deliverifp = NULL; #if NPF > 0 @@ -324,11 +324,15 @@ ip6_input(struct mbuf *m) * can be destinated to any local address, not necessarily to * an address configured on `ifp'. */ - if ((ifp->if_flags & IFF_LOOPBACK) == 0) { - if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) - ip6->ip6_src.s6_addr16[1] = htons(ifp->if_index); - if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) - ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index); + if (ifp->if_flags & IFF_LOOPBACK) { + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) { + src_scope = ip6->ip6_src.s6_addr16[1]; + ip6->ip6_src.s6_addr16[1] = 0; + } + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) { + dst_scope = ip6->ip6_dst.s6_addr16[1]; + ip6->ip6_dst.s6_addr16[1] = 0; + } } #if NPF > 0 @@ -344,6 +348,22 @@ ip6_input(struct mbuf *m) ip6 = mtod(m, struct ip6_hdr *); srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); #endif + + /* + * Without embedded scope ID we cannot find link-local + * addresses in the routing table. + */ + if (ifp->if_flags & IFF_LOOPBACK) { + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) + ip6->ip6_src.s6_addr16[1] = src_scope; + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) + ip6->ip6_dst.s6_addr16[1] = dst_scope; + } else { + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) + ip6->ip6_src.s6_addr16[1] = htons(ifp->if_index); + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) + ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index); + } /* * Be more secure than RFC5095 and scan for type 0 routing headers. Index: netinet6/ip6_output.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_output.c,v retrieving revision 1.165 diff -u -p -r1.165 ip6_output.c --- netinet6/ip6_output.c 17 Dec 2014 09:57:13 -0000 1.165 +++ netinet6/ip6_output.c 1 Feb 2015 20:45:48 -0000 @@ -168,6 +168,7 @@ ip6_output(struct mbuf *m0, struct ip6_p int error = 0; u_long mtu; int alwaysfrag, dontfrag; + u_int16_t src_scope, dst_scope; u_int32_t optlen = 0, plen = 0, unfragpartlen = 0; struct ip6_exthdrs exthdrs; struct in6_addr finaldst; @@ -661,6 +662,21 @@ reroute: } /* + * If this packet is going trough a loopback interface we wont + * be able to restore its scope ID using the interface index. + */ + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) { + if (ifp->if_flags & IFF_LOOPBACK) + src_scope = ip6->ip6_src.s6_addr16[1]; + ip6->ip6_src.s6_addr16[1] = 0; + } + if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) { + if (ifp->if_flags & IFF_LOOPBACK) + dst_scope = ip6->ip6_dst.s6_addr16[1]; + ip6->ip6_dst.s6_addr16[1] = 0; + } + + /* * Fill the outgoing interface to tell the upper layer * to increment per-interface statistics. */ @@ -752,11 +768,11 @@ reroute: * to any local address. In this case do not clear its scopes * to let ip6_input() find a matching local route. */ - if ((ifp->if_flags & IFF_LOOPBACK) == 0) { + if (ifp->if_flags & IFF_LOOPBACK) { if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) - ip6->ip6_src.s6_addr16[1] = 0; + ip6->ip6_src.s6_addr16[1] = src_scope; if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) - ip6->ip6_dst.s6_addr16[1] = 0; + ip6->ip6_dst.s6_addr16[1] = dst_scope; } in6_proto_cksum_out(m, ifp);