Date: Wed, 20 Feb 2013 14:20:00 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r247038 - user/ae/inet6/sys/netinet6 Message-ID: <201302201420.r1KEK07K001331@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Wed Feb 20 14:19:59 2013 New Revision: 247038 URL: http://svnweb.freebsd.org/changeset/base/247038 Log: Do not use embedded zone ids. Modified: user/ae/inet6/sys/netinet6/ip6_forward.c Modified: user/ae/inet6/sys/netinet6/ip6_forward.c ============================================================================== --- user/ae/inet6/sys/netinet6/ip6_forward.c Wed Feb 20 14:19:09 2013 (r247037) +++ user/ae/inet6/sys/netinet6/ip6_forward.c Wed Feb 20 14:19:59 2013 (r247038) @@ -357,6 +357,14 @@ again: dst->sin6_len = sizeof(struct sockaddr_in6); dst->sin6_family = AF_INET6; dst->sin6_addr = ip6->ip6_dst; + /* + * The next-hop interface is chosen by looking up the destination + * address in a routing table specific to that zone. + * That routing table is restricted to refer to interfaces belonging + * to that zone. + */ + dst->sin6_scope_id = in6_getscopezone(m->m_pkthdr.rcvif, + in6_addrscope(&ip6->ip6_dst)); again2: rin6.ro_rt = in6_rtalloc1((struct sockaddr *)dst, 0, 0, M_GETFIB(m)); if (rin6.ro_rt != NULL) @@ -376,27 +384,25 @@ skip_routing: #endif /* - * Source scope check: if a packet can't be delivered to its - * destination for the reason that the destination is beyond the scope - * of the source address, discard the packet and return an icmp6 - * destination unreachable error with Code 2 (beyond scope of source - * address). We use a local copy of ip6_src, since in6_setscope() - * will possibly modify its first argument. - * [draft-ietf-ipngwg-icmp-v3-04.txt, Section 3.1] + * RFC 4007: + * If transmitting the packet on the chosen next-hop interface + * would cause the packet to leave the zone of the source address, + * i.e., cross a zone boundary of the scope of the source address, + * then the packet is discarded. Additionally, if the packet's + * destination address is a unicast address, an ICMP destination + * Unreachable message with Code 2 ("beyond scope of source address") + * is sent to the source of the original packet. + * + * If a router receives a packet with a link-local destination + * address that is not one of the router's own link-local addresses + * on the arrival link, the router is expected to try to forward + * the packet to the destination on that link. */ - src_in6 = ip6->ip6_src; - if (in6_setscope(&src_in6, rt->rt_ifp, &outzone)) { - /* XXX: this should not happen */ - V_ip6stat.ip6s_cantforward++; - V_ip6stat.ip6s_badscope++; - goto bad; - } - if (in6_setscope(&src_in6, m->m_pkthdr.rcvif, &inzone)) { - V_ip6stat.ip6s_cantforward++; - V_ip6stat.ip6s_badscope++; - goto bad; - } - if (inzone != outzone + srcscope = in6_addrscope(&ip6->ip6_src); + dstscope = in6_addrscope(&ip6->ip6_dst); + if (dstscope != IPV6_ADDR_SCOPE_LINKLOCAL && + in6_getscopezone(m->m_pkthdr.rcvif, srcscope) != + in6_getscopezone(rt->rt_ifp, dstscope) #ifdef IPSEC && !ipsecrt #endif @@ -421,22 +427,6 @@ skip_routing: goto bad; } - /* - * Destination scope check: if a packet is going to break the scope - * zone of packet's destination address, discard it. This case should - * usually be prevented by appropriately-configured routing table, but - * we need an explicit check because we may mistakenly forward the - * packet to a different zone by (e.g.) a default route. - */ - dst_in6 = ip6->ip6_dst; - if (in6_setscope(&dst_in6, m->m_pkthdr.rcvif, &inzone) != 0 || - in6_setscope(&dst_in6, rt->rt_ifp, &outzone) != 0 || - inzone != outzone) { - V_ip6stat.ip6s_cantforward++; - V_ip6stat.ip6s_badscope++; - goto bad; - } - if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) { in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig); if (mcopy) { @@ -549,12 +539,6 @@ skip_routing: } else origifp = rt->rt_ifp; - /* - * clear embedded scope identifiers if necessary. - * in6_clearscope will touch the addresses only when necessary. - */ - in6_clearscope(&ip6->ip6_src); - in6_clearscope(&ip6->ip6_dst); /* Jump over all PFIL processing if hooks are not active. */ if (!PFIL_HOOKED(&V_inet6_pfil_hook))
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302201420.r1KEK07K001331>