On Wed, Jul 27, 2011 at 12:44:21AM +0200, Alexander Bluhm wrote:
> On Fri, May 20, 2011 at 11:54:09AM +0200, Camiel Dobbelaar wrote:
> > I'll spend some more time on this, but maybe there's an IPv6 guru that
> > can lend a hand? :-)
>
> Just removing the check seems wrong to me. This would allow ::1
> addresses from the wire. Also the goto hbhcheck would get lost.
I have reconsidered the existing loopback check in ip6_input(). It
is wrong. The check that ::1 is not allowed from the wire must be
before pf_test(). Otherwise pf could reroute or redirect such a
packet.
KAME moved the check in rev 1.189 of their ip6_input.c. They also
removed the special goto ours logic for ::1. I do not change that
now before release so leave the goto where it is.
Redirect or nat to ::1 should work with this diff. But I still
believe that divert-to is more suitable for that.
ok?
bluhm
Index: netinet6/ip6_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.101
diff -u -p -r1.101 ip6_input.c
--- netinet6/ip6_input.c 6 Jul 2011 02:42:28 -0000 1.101
+++ netinet6/ip6_input.c 1 Aug 2011 19:18:18 -0000
@@ -270,7 +270,13 @@ ip6_input(struct mbuf *m)
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
goto bad;
}
-
+ if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
+ IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) &&
+ (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
+ ip6stat.ip6s_badscope++;
+ in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
+ goto bad;
+ }
if (IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) &&
!(m->m_flags & M_LOOP)) {
/*
@@ -343,15 +349,9 @@ ip6_input(struct mbuf *m)
if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) {
- if (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) {
- ours = 1;
- deliverifp = m->m_pkthdr.rcvif;
- goto hbhcheck;
- } else {
- ip6stat.ip6s_badscope++;
- in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);
- goto bad;
- }
+ ours = 1;
+ deliverifp = m->m_pkthdr.rcvif;
+ goto hbhcheck;
}
/* drop packets if interface ID portion is already filled */