svn commit: r186708 - in head/sys: netinet netinet6

Qing Li qingli at FreeBSD.org
Fri Jan 2 16:27:30 PST 2009


Author: qingli
Date: Sat Jan  3 00:27:28 2009
New Revision: 186708
URL: http://svn.freebsd.org/changeset/base/186708

Log:
  Some modules such as SCTP supplies a valid route entry as an input argument
  to ip_output(). The destionation is represented in a sockaddr{} object
  that may contain other pieces of information, e.g., port number. This
  same destination sockaddr{} object may be passed into L2 code, which
  could be used to create a L2 entry. Since there exists a L2 table per
  address family, the L2 lookup function can make address family specific
  comparison instead of the generic bcmp() operation over the entire
  sockaddr{} structure.
  
  Note in the IPv6 case the sin6_scope_id is not compared because the
  address is currently stored in the embedded form inside the kernel.
  The in6_lltable_lookup() has to account for the scope-id if this
  storage format were to change in the future.

Modified:
  head/sys/netinet/in.c
  head/sys/netinet6/in6.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Fri Jan  2 23:39:29 2009	(r186707)
+++ head/sys/netinet/in.c	Sat Jan  3 00:27:28 2009	(r186708)
@@ -1106,9 +1106,10 @@ in_lltable_lookup(struct lltable *llt, u
 	hashkey = sin->sin_addr.s_addr;
 	lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
 	LIST_FOREACH(lle, lleh, lle_next) {
+		struct sockaddr_in *sa2 = (struct sockaddr_in *)L3_ADDR(lle);
 		if (lle->la_flags & LLE_DELETED)
 			continue;
-		if (bcmp(L3_ADDR(lle), l3addr, sizeof(struct sockaddr_in)) == 0)
+		if (sa2->sin_addr.s_addr == sin->sin_addr.s_addr)
 			break;
 	}
 	if (lle == NULL) {

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Fri Jan  2 23:39:29 2009	(r186707)
+++ head/sys/netinet6/in6.c	Sat Jan  3 00:27:28 2009	(r186708)
@@ -1533,52 +1533,29 @@ in6_ifinit(struct ifnet *ifp, struct in6
 	 * XXX: the logic below rejects assigning multiple addresses on a p2p
 	 * interface that share the same destination.
 	 */
-#if 0 /* QL - verify */
 	plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
-	if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 &&
-	    ia->ia_dstaddr.sin6_family == AF_INET6) {
+	if (!(ia->ia_flags & IFA_ROUTE) && plen == 128) {
+		struct sockaddr *dstaddr;
 		int rtflags = RTF_UP | RTF_HOST;
-		struct rtentry *rt = NULL, **rtp = NULL;
 
-		if (nd6_need_cache(ifp) != 0) {
-			rtp = &rt;
-		}
+		/* 
+		 * use the interface address if configuring an
+		 * interface address with a /128 prefix len
+		 */
+		if (ia->ia_dstaddr.sin6_family == AF_INET6)
+			dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
+		else
+			dstaddr = (struct sockaddr *)&ia->ia_addr;
 
 		error = rtrequest(RTM_ADD,
-		    (struct sockaddr *)&ia->ia_dstaddr,
+		    (struct sockaddr *)dstaddr,
 		    (struct sockaddr *)&ia->ia_addr,
 		    (struct sockaddr *)&ia->ia_prefixmask,
-		    ia->ia_flags | rtflags, rtp);
+		    ia->ia_flags | rtflags, NULL);
 		if (error != 0)
 			return (error);
-		if (rt != NULL) {
-			struct llinfo_nd6 *ln;
-
-			RT_LOCK(rt);
-			ln = (struct llinfo_nd6 *)rt->rt_llinfo;
-			if (ln != NULL) {
-				/*
-				 * Set the state to STALE because we don't
-				 * have to perform address resolution on this
-				 * link.
-				 */
-				ln->ln_state = ND6_LLINFO_STALE;
-			}
-			RT_REMREF(rt);
-			RT_UNLOCK(rt);
-		}
-		ia->ia_flags |= IFA_ROUTE;
-	}
-#else
-	plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
-	if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 &&
-	    ia->ia_dstaddr.sin6_family == AF_INET6) {
-		if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD,
-				    RTF_UP | RTF_HOST)) != 0)
-			return (error);
 		ia->ia_flags |= IFA_ROUTE;
 	}
-#endif
 
 	/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
 	if (newhost) {
@@ -2171,9 +2148,11 @@ in6_lltable_lookup(struct lltable *llt, 
 	hashkey = sin6->sin6_addr.s6_addr32[3];
 	lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
 	LIST_FOREACH(lle, lleh, lle_next) {
+		struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)L3_ADDR(lle);
 		if (lle->la_flags & LLE_DELETED)
 			continue;
-		if (bcmp(L3_ADDR(lle), l3addr, l3addr->sa_len) == 0)
+		if (bcmp(&sa6->sin6_addr, &sin6->sin6_addr, 
+			 sizeof(struct in6_addr)) == 0)
 			break;
 	}
 


More information about the svn-src-all mailing list