Pullup svn source to p4 top of tree:

* Fix LOR in MLDv2 query input path.
 * Strip embedded KAME scope IDs for on-wire IPv6 address comparisons.
This commit is contained in:
Bruce M Simpson 2009-05-21 17:01:38 +00:00
parent 52f542a8e4
commit 0ed39d3ec4

View File

@ -629,8 +629,8 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
#endif
IN6_MULTI_LOCK();
IF_ADDR_LOCK(ifp);
MLD_LOCK();
IF_ADDR_LOCK(ifp);
mli = MLD_IFINFO(ifp);
KASSERT(mli != NULL, ("%s: no mld_ifinfo for ifp %p", __func__, ifp));
@ -661,12 +661,12 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
/*
* MLDv1 General Query.
* If this was not sent to the all-nodes group, ignore it.
*
* XXX Do we need to check for a scope ID in the destination
* address on input and strip it?
*/
if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
&in6addr_linklocal_allnodes)) {
struct in6_addr dst;
dst = ip6->ip6_dst;
in6_clearscope(&dst);
if (IN6_ARE_ADDR_EQUAL(&dst, &in6addr_linklocal_allnodes)) {
/*
* For each reporting group joined on this
* interface, kick the report timer.
@ -685,8 +685,8 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
}
}
MLD_UNLOCK();
IF_ADDR_UNLOCK(ifp);
MLD_UNLOCK();
IN6_MULTI_UNLOCK();
return (0);
@ -807,8 +807,8 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
return (EMSGSIZE);
IN6_MULTI_LOCK();
IF_ADDR_LOCK(ifp);
MLD_LOCK();
IF_ADDR_LOCK(ifp);
mli = MLD_IFINFO(ifp);
KASSERT(mli != NULL, ("%s: no mld_ifinfo for ifp %p", __func__, ifp));
@ -819,17 +819,25 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
mli->mli_qi = qqi;
mli->mli_qri = maxdelay;
CTR4(KTR_MLD, "%s: qrv %d qi %d qri %d", __func__, qrv, qqi,
CTR4(KTR_MLD, "%s: qrv %d qi %d maxdelay %d", __func__, qrv, qqi,
maxdelay);
if (IN6_IS_ADDR_UNSPECIFIED(&mld->mld_addr)) {
/*
* MLDv2 General Query.
*
* Schedule a current-state report on this ifp for
* all groups, possibly containing source lists.
*
* Strip scope ID embedded by ip6_input(). We do not need
* to do this for the MLD payload.
*/
if (!IN6_ARE_ADDR_EQUAL(&in6addr_linklocal_allnodes,
&ip6->ip6_dst) || nsrc > 0) {
struct in6_addr dst;
dst = ip6->ip6_dst;
in6_clearscope(&dst);
if (!IN6_ARE_ADDR_EQUAL(&dst, &in6addr_linklocal_allnodes) ||
nsrc > 0) {
/*
* General Queries SHOULD be directed to ff02::1.
* A general query with a source list has undefined
@ -885,8 +893,8 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
}
out_locked:
MLD_UNLOCK();
IF_ADDR_UNLOCK(ifp);
MLD_UNLOCK();
IN6_MULTI_UNLOCK();
return (0);
@ -1016,15 +1024,19 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6,
{
struct in6_ifaddr *ia;
struct in6_multi *inm;
struct in6_addr src, dst;
#ifdef KTR
char ip6tbuf[INET6_ADDRSTRLEN];
#endif
if (ifp->if_flags & IFF_LOOPBACK)
return (0);
if (!IN6_IS_ADDR_MULTICAST(&mld->mld_addr))
return (EINVAL);
if (!IN6_IS_ADDR_MULTICAST(&mld->mld_addr) ||
!IN6_ARE_ADDR_EQUAL(&mld->mld_addr, &ip6->ip6_dst))
dst = ip6->ip6_dst;
in6_clearscope(&dst);
if (!IN6_ARE_ADDR_EQUAL(&mld->mld_addr, &dst))
return (EINVAL);
/*
@ -1032,16 +1044,23 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6,
* leave requires knowing that we are the only member of a
* group. Assume we used the link-local address if available,
* otherwise look for ::.
*
* XXX Note that scope ID comparison is needed for the address
* returned by in6ifa_ifpforlinklocal(), but SHOULD NOT be
* performed for the on-wire address.
*/
ia = in6ifa_ifpforlinklocal(ifp, IN6_IFF_NOTREADY|IN6_IFF_ANYCAST);
src = ip6->ip6_src;
in6_clearscope(&src);
if ((ia && IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, IA6_IN6(ia))) ||
(ia == NULL && IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)))
(ia == NULL && IN6_IS_ADDR_UNSPECIFIED(&src)))
return (0);
CTR3(KTR_MLD, "process v1 report %s on ifp %p(%s)",
ip6_sprintf(ip6tbuf, &mld->mld_addr), ifp, ifp->if_xname);
IN6_MULTI_LOCK();
MLD_LOCK();
IF_ADDR_LOCK(ifp);
/*
@ -1090,6 +1109,7 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6,
}
out_locked:
MLD_UNLOCK();
IF_ADDR_UNLOCK(ifp);
IN6_MULTI_UNLOCK();