Module Name:    src
Committed By:   bouyer
Date:           Sun Sep 12 21:19:07 UTC 2010

Modified Files:
        src/sys/dist/ipf/netinet [netbsd-4]: ip_fil_netbsd.c

Log Message:
Pull up following revision(s) (requested by mlelstv in ticket #1405):
        sys/dist/ipf/netinet/ip_fil_netbsd.c: revision 1.56
Fix mbuf corruption when sending ICMP errors for blocked IPv6
packets due to wrong buffer size computations. The corrupted
mbufs could lead to a panic.
Fix computation of link mtu where the link mtu itself is unspecified.
Limit ICMP error packets for IPv6 to MMTU as required by RFC4443. This
also avoids dropped errors when the length exceeds the link mtu.


To generate a diff of this commit:
cvs rdiff -u -r1.28.2.5 -r1.28.2.6 src/sys/dist/ipf/netinet/ip_fil_netbsd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dist/ipf/netinet/ip_fil_netbsd.c
diff -u src/sys/dist/ipf/netinet/ip_fil_netbsd.c:1.28.2.5 src/sys/dist/ipf/netinet/ip_fil_netbsd.c:1.28.2.6
--- src/sys/dist/ipf/netinet/ip_fil_netbsd.c:1.28.2.5	Thu Sep 27 13:58:20 2007
+++ src/sys/dist/ipf/netinet/ip_fil_netbsd.c	Sun Sep 12 21:19:07 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_fil_netbsd.c,v 1.28.2.5 2007/09/27 13:58:20 xtraeme Exp $	*/
+/*	$NetBSD: ip_fil_netbsd.c,v 1.28.2.6 2010/09/12 21:19:07 bouyer Exp $	*/
 
 /*
  * Copyright (C) 1993-2003 by Darren Reed.
@@ -954,6 +954,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
@@ -964,12 +965,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;
@@ -980,7 +981,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) {
@@ -996,7 +1004,6 @@
 		return -1;
 	}
 
-	iclen = hlen + sizeof(*icmp);
 	avail -= (max_linkhdr + iclen);
 	if (avail < 0) {
 		FREE_MB_T(m);
@@ -1464,9 +1471,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
@@ -1485,8 +1490,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

Reply via email to