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;
        }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to