Date: Thu, 17 Oct 2013 11:40:08 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r256675 - user/ae/inet6/sys/netinet6 Message-ID: <201310171140.r9HBe8s2040153@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Thu Oct 17 11:40:08 2013 New Revision: 256675 URL: http://svnweb.freebsd.org/changeset/base/256675 Log: Rework icmp6_reflect(): * sort variables declarations; * when incoming packet was addressed directly for us, use interface where it is configured as outgoing interface (XXX: is it correct?); * otherwise, use SAS Algorithm and keep route information, that it returns. Use this route in ip6_output(). * since we always know outgoing interface, use IPV6_USEROIF flag for ip6_output() Modified: user/ae/inet6/sys/netinet6/icmp6.c Modified: user/ae/inet6/sys/netinet6/icmp6.c ============================================================================== --- user/ae/inet6/sys/netinet6/icmp6.c Thu Oct 17 11:33:16 2013 (r256674) +++ user/ae/inet6/sys/netinet6/icmp6.c Thu Oct 17 11:40:08 2013 (r256675) @@ -227,7 +227,6 @@ void icmp6_error2(struct mbuf *m, int type, int code, int param, struct ifnet *ifp) { - struct ip6_hdr *ip6; if (ifp == NULL) return; @@ -2119,13 +2118,14 @@ icmp6_rip6_input(struct mbuf **mp, int o void icmp6_reflect(struct mbuf *m, size_t off) { + struct route_in6 *ro, ro6; + struct in6_addr src, *srcp = NULL; struct ip6_hdr *ip6; struct icmp6_hdr *icmp6; struct in6_ifaddr *ia = NULL; - int plen; - int type, code; struct ifnet *outif = NULL; - struct in6_addr origdst, src, *srcp = NULL; + uint32_t zoneid; + int type, code, plen, error; /* too short to reflect */ if (off < sizeof(struct ip6_hdr)) { @@ -2172,13 +2172,6 @@ icmp6_reflect(struct mbuf *m, size_t off type = icmp6->icmp6_type; /* keep type for statistics */ code = icmp6->icmp6_code; /* ditto. */ - origdst = ip6->ip6_dst; - /* - * ip6_input() drops a packet if its src is multicast. - * So, the src is never multicast. - */ - ip6->ip6_dst = ip6->ip6_src; - /* * If the incoming packet was addressed directly to us (i.e. unicast), * use dst as the src for the reply. @@ -2186,56 +2179,59 @@ icmp6_reflect(struct mbuf *m, size_t off * (for example) when we encounter an error while forwarding procedure * destined to a duplicated address of ours. */ + zoneid = in6_getscopezone(m->m_pkthdr.rcvif, + in6_addrscope(&ip6->ip6_dst)); if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { - ia = in6ifa_ifwithaddr(&ip6->ip6_dst, - in6_getscopezone(m->m_pkthdr.rcvif, - in6_addrscope(&ip6->ip6_dst))); + ia = in6ifa_ifwithaddr(&ip6->ip6_dst, zoneid); if (ia != NULL && !(ia->ia6_flags & - (IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) + (IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) { srcp = &ia->ia_addr.sin6_addr; + outif = ia->ia_ifp; /* XXX: is it correct? */ + } } + ro = NULL; if (srcp == NULL) { - int e; struct sockaddr_in6 sin6; - struct route_in6 ro; /* * This case matches to multicasts, our anycast, or unicasts * that we do not own. Select a source address based on the * source address of the erroneous packet. */ + ro = &ro6; + bzero(&ro6, sizeof(ro6)); + outif = m->m_pkthdr.rcvif; + bzero(&sin6, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_len = sizeof(sin6); - sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */ - - bzero(&ro, sizeof(ro)); - e = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, &outif, &src); - if (ro.ro_rt) - RTFREE(ro.ro_rt); /* XXX: we could use this */ - if (e) { + sin6.sin6_addr = ip6->ip6_src; + sin6.sin6_scope_id = zoneid; + error = in6_selectsrc(&sin6, NULL, NULL, ro, NULL, + &outif, &src); + if (error != 0) { char ip6buf[INET6_ADDRSTRLEN]; nd6log((LOG_DEBUG, "icmp6_reflect: source can't be determined: " "dst=%s, error=%d\n", - ip6_sprintf(ip6buf, &sin6.sin6_addr), e)); + ip6_sprintf(ip6buf, &sin6.sin6_addr), error)); + RO_RTFREE(ro); goto bad; } srcp = &src; } - + KASSERT(outif != NULL, ("%s: outif is NULL", __func__)); + /* + * ip6_input() drops a packet if its src is multicast. + * So, the src is never multicast. + */ + ip6->ip6_dst = ip6->ip6_src; ip6->ip6_src = *srcp; ip6->ip6_flow = 0; ip6->ip6_vfc &= ~IPV6_VERSION_MASK; ip6->ip6_vfc |= IPV6_VERSION; ip6->ip6_nxt = IPPROTO_ICMPV6; - if (outif) - ip6->ip6_hlim = ND_IFINFO(outif)->chlim; - else if (m->m_pkthdr.rcvif) { - /* XXX: This may not be the outgoing interface */ - ip6->ip6_hlim = ND_IFINFO(m->m_pkthdr.rcvif)->chlim; - } else - ip6->ip6_hlim = V_ip6_defhlim; + ip6->ip6_hlim = ND_IFINFO(outif)->chlim; icmp6->icmp6_cksum = 0; icmp6->icmp6_cksum = in6_cksum(m, IPPROTO_ICMPV6, @@ -2247,12 +2243,12 @@ icmp6_reflect(struct mbuf *m, size_t off m->m_flags &= ~(M_BCAST|M_MCAST); - ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL); - if (outif) - icmp6_ifoutstat_inc(outif, type, code); - + ip6_output(m, NULL, ro, IPV6_USEROIF, NULL, &outif, NULL); + icmp6_ifoutstat_inc(outif, type, code); if (ia != NULL) ifa_free(&ia->ia_ifa); + if (ro != NULL) + RO_RTFREE(ro); return; bad:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310171140.r9HBe8s2040153>