diff options
author | qingli <qingli@FreeBSD.org> | 2009-01-03 00:27:28 +0000 |
---|---|---|
committer | qingli <qingli@FreeBSD.org> | 2009-01-03 00:27:28 +0000 |
commit | efe3f87721e5c915985776d2d88cb173737e8258 (patch) | |
tree | fc0a5a77b2b2d0cb0e6f2e3281d36db90f96bcf5 /sys/netinet6/in6.c | |
parent | fa1537b9485c0b99a15acc74fd9f508e9e393d53 (diff) | |
download | FreeBSD-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/in6.c')
-rw-r--r-- | sys/netinet6/in6.c | 51 |
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; } |