svn commit: r226224 - head/sys/netinet

Qing Li qingli at FreeBSD.org
Mon Oct 10 17:41:12 UTC 2011


Author: qingli
Date: Mon Oct 10 17:41:11 2011
New Revision: 226224
URL: http://svn.freebsd.org/changeset/base/226224

Log:
  All indirect routes will fail the rtcheck, except for a special host
  route where the destination IP and the gateway IP is the same. This
  special case handling is only meant for backward compatibility reason.
  The last commit introduced a bug in the route check logic, where a
  valid special case is treated as an error. This patch fixes that bug
  along with some code cleanup.
  
  Suggested by:	gleb
  Reviewed by:	kmacy, discussed with gleb
  MFC after:	1 day

Modified:
  head/sys/netinet/in.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Mon Oct 10 17:39:58 2011	(r226223)
+++ head/sys/netinet/in.c	Mon Oct 10 17:41:11 2011	(r226224)
@@ -1414,8 +1414,6 @@ static int
 in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
 {
 	struct rtentry *rt;
-	struct ifnet *xifp;
-	int error = 0;
 
 	KASSERT(l3addr->sa_family == AF_INET,
 	    ("sin_family %d", l3addr->sa_family));
@@ -1432,21 +1430,16 @@ in_lltable_rtcheck(struct ifnet *ifp, u_
 	 * such as MANET, and the interface is of the correct type, then
 	 * allow for ARP to proceed.
 	 */
-	if (rt->rt_flags & (RTF_GATEWAY | RTF_HOST)) {
-		xifp = rt->rt_ifp;
-		
-		if (xifp && (xifp->if_type != IFT_ETHER ||
-		     (xifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0))
-			error = EINVAL;
-
-		if (memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
-		    sizeof(in_addr_t)) != 0)
-			error = EINVAL;
-	}
-
 	if (rt->rt_flags & RTF_GATEWAY) {
-		RTFREE_LOCKED(rt);
-		return (EINVAL);
+		if (!(rt->rt_flags & RTF_HOST) || !rt->rt_ifp ||
+			rt->rt_ifp->if_type != IFT_ETHER ||
+			  (rt->rt_ifp->if_flags & 
+			   (IFF_NOARP | IFF_STATICARP)) != 0 ||
+			  memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
+				 sizeof(in_addr_t)) != 0) {
+			RTFREE_LOCKED(rt);
+			return (EINVAL);
+		}
 	}
 
 	/*
@@ -1455,32 +1448,31 @@ in_lltable_rtcheck(struct ifnet *ifp, u_
 	 * interfaces have the same prefix. An incoming packet arrives
 	 * on one interface and the corresponding outgoing packet leaves
 	 * another interface.
-	 * 
 	 */
 	if (rt->rt_ifp != ifp) {
-		char *sa, *mask, *addr, *lim;
+		const char *sa, *mask, *addr, *lim;
 		int len;
 
-		sa = (char *)rt_key(rt);
-		mask = (char *)rt_mask(rt);
-		addr = (char *)__DECONST(struct sockaddr *, l3addr);
-		len = ((struct sockaddr_in *)__DECONST(struct sockaddr *, l3addr))->sin_len;
+		sa = (const char *)rt_key(rt);
+		mask = (const char *)rt_mask(rt);
+		addr = (const char *)l3addr;
+		len = ((const struct sockaddr_in *)l3addr)->sin_len;
 		lim = addr + len;
 
 		for ( ; addr < lim; sa++, mask++, addr++) {
 			if ((*sa ^ *addr) & *mask) {
-				error = EINVAL;
 #ifdef DIAGNOSTIC
 				log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
 				    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
 #endif
-				break;
+				RTFREE_LOCKED(rt);
+				return (EINVAL);
 			}
 		}
 	}
 
 	RTFREE_LOCKED(rt);
-	return (error);
+	return (0);
 }
 
 /*


More information about the svn-src-all mailing list