Subject: kern/22579: ipfilter should use linklocal address in ipfr_fastroute6()
To: None <gnats-bugs@gnats.netbsd.org>
From: KOZUKA Masahiro <ma-kun@kozuka.jp>
List: netbsd-bugs
Date: 08/23/2003 13:20:07
>Number: 22579
>Category: kern
>Synopsis: ipfilter should use linklocal address in ipfr_fastroute6()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Aug 23 06:43:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: KOZUKA Masahiro
>Release: NetBSD 1.6.1
>Organization:
Kyoto University
>Environment:
System: NetBSD no30 1.6.1 NetBSD 1.6.1 (GENERIC) #45: Sat Aug 23 09:31:06 JST 2003 kozuka@no30:/usr/home/kozuka/netbsd/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
By PR#22157 return-rst works with IPv6 in --current. But
in repliying RST packet to linklocal address, rtalloc() in
ipfr_fastroute6 fails because in the case of linklocal address,
interface index must be set in second dst6->sin6_addr's short
(dst6->sin6_addr.s6_addr16[1]).
>How-To-Repeat:
ipf6.conf
block return-rst in log on pcn0 proto tcp from fe80::2 to fe80::1
Try to connect from fe80::2 to fe80::1(host working ipfilter),
the packet will be dropped, but RST not sent to fe80::2.
>Fix:
See the diff below.
First part already fixed by PR#22157.
diff -u -r netinet.orig/ip_fil.c netinet/ip_fil.c
--- netinet.orig/ip_fil.c Thu Oct 24 18:33:45 2002
+++ netinet/ip_fil.c Sat Aug 23 10:01:59 2003
@@ -1942,10 +1950,12 @@
dst6 = (struct sockaddr_in6 *)&ro->ro_dst;
dst6->sin6_family = AF_INET6;
dst6->sin6_len = sizeof(struct sockaddr_in6);
- dst6->sin6_addr = fin->fin_fi.fi_src.in6;
+ dst6->sin6_addr = fin->fin_fi.fi_dst.in6;
if (fdp != NULL)
ifp = fdp->fd_ifp;
+ else
+ ifp = fin->fin_ifp;
if ((fr != NULL) && (fin->fin_rev != 0)) {
if ((ifp != NULL) && (fdp == &fr->fr_tif))
@@ -1957,6 +1967,11 @@
if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE)))
return -2;
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ /* KAME */
+ if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr))
+ dst6->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+#endif
rtalloc((struct route *)ro);
if ((ifp == NULL) && (ro->ro_rt != NULL))
>Release-Note:
>Audit-Trail:
>Unformatted: