summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorqingli <qingli@FreeBSD.org>2009-01-03 00:27:28 +0000
committerqingli <qingli@FreeBSD.org>2009-01-03 00:27:28 +0000
commitefe3f87721e5c915985776d2d88cb173737e8258 (patch)
treefc0a5a77b2b2d0cb0e6f2e3281d36db90f96bcf5 /sys/netinet6
parentfa1537b9485c0b99a15acc74fd9f508e9e393d53 (diff)
downloadFreeBSD-src-efe3f87721e5c915985776d2d88cb173737e8258.zip
FreeBSD-src-efe3f87721e5c915985776d2d88cb173737e8258.tar.gz
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.
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c51
1 files changed, 15 insertions, 36 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 0d0c951..4c97999 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1533,52 +1533,29 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia,
* 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, u_int flags,
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;
}
OpenPOWER on IntegriCloud