Date: Sat, 3 Jan 2009 00:27:29 +0000 (UTC) From: Qing Li <qingli@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r186708 - in head/sys: netinet netinet6 Message-ID: <200901030027.n030RT1e011521@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901030027.n030RT1e011521>