Index: sys/dist/ipf/netinet/ip_fil_netbsd.c =================================================================== RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_fil_netbsd.c,v retrieving revision 1.55 diff -u -r1.55 ip_fil_netbsd.c --- sys/dist/ipf/netinet/ip_fil_netbsd.c 1 Jun 2010 08:53:20 -0000 1.55 +++ sys/dist/ipf/netinet/ip_fil_netbsd.c 5 Sep 2010 12:16:04 -0000 @@ -1076,6 +1076,7 @@ hlen = sizeof(ip_t); ohlen = fin->fin_hlen; + iclen = hlen + offsetof(struct icmp, icmp_ip) + ohlen; if (fin->fin_hlen < fin->fin_plen) xtra = MIN(fin->fin_dlen, 8); else @@ -1086,12 +1087,12 @@ else if (fin->fin_v == 6) { hlen = sizeof(ip6_t); ohlen = sizeof(ip6_t); + iclen = hlen + offsetof(struct icmp, icmp_ip) + ohlen; type = icmptoicmp6types[type]; if (type == ICMP6_DST_UNREACH) code = icmptoicmp6unreach[code]; - if (hlen + sizeof(*icmp) + max_linkhdr + - fin->fin_plen > avail) { + if (iclen + max_linkhdr + fin->fin_plen > avail) { MCLGET(m, M_DONTWAIT); if (m == NULL) return -1; @@ -1102,7 +1103,14 @@ avail = MCLBYTES; } xtra = MIN(fin->fin_plen, - avail - hlen - sizeof(*icmp) - max_linkhdr); + avail - iclen - max_linkhdr); + /* RFC4443 asks for 'as much of invoking packet + * as possible without the ICMPv6 packet exceeding + * the minimum IPv6 MTU' + * fr_send_ip also drops packets larger than the + * link mtu + */ + xtra = MIN(xtra, IPV6_MMTU - iclen); if (dst == 0) { if (fr_ifpaddr(6, FRI_NORMAL, ifp, (struct in_addr *)&dst6, NULL) == -1) { @@ -1118,7 +1126,6 @@ return -1; } - iclen = hlen + sizeof(*icmp); avail -= (max_linkhdr + iclen); if (avail < 0) { FREE_MB_T(m); @@ -1584,9 +1591,7 @@ { # if (__NetBSD_Version__ >= 106010000) -# if (__NetBSD_Version__ >= 399001400) - struct in6_ifextra *ife; -# else +# if (__NetBSD_Version__ < 399001400) struct in6_addr finaldst = fin->fin_dst6; int frag; # endif @@ -1605,8 +1610,7 @@ mtu = nd_ifinfo[ifp->if_index].linkmtu; # else # if (__NetBSD_Version__ >= 399001400) - ife = (struct in6_ifextra *)(ifp)->if_afdata[AF_INET6]; - mtu = ife->nd_ifinfo[ifp->if_index].linkmtu; + mtu = IN6_LINKMTU(ifp); # else error = ip6_getpmtu(ro, ro, ifp, &finaldst, &mtu, &frag); # endif .