--- sys/netinet/tcp_syncache.c (svn+ssh://svn.freebsd.org/base/head) (revision 261548) +++ sys/netinet/tcp_syncache.c (working copy) @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #endif #include #include @@ -712,6 +713,7 @@ syncache_socket(struct syncache *sc, struct socket #ifdef INET6 if (sc->sc_inc.inc_flags & INC_ISIPV6) { inp->in6p_laddr = sc->sc_inc.inc6_laddr; + inp->in6p_zoneid = sc->sc_inc.inc6_zoneid; } else { inp->inp_vflag &= ~INP_IPV6; inp->inp_vflag |= INP_IPV4; @@ -786,7 +788,9 @@ syncache_socket(struct syncache *sc, struct socket sin6.sin6_len = sizeof(sin6); sin6.sin6_addr = sc->sc_inc.inc6_faddr; sin6.sin6_port = sc->sc_inc.inc_fport; - sin6.sin6_flowinfo = sin6.sin6_scope_id = 0; + sin6.sin6_flowinfo = 0; + sin6.sin6_scope_id = IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) ? + sc->sc_inc.inc6_zoneid: 0; laddr6 = inp->in6p_laddr; if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) inp->in6p_laddr = sc->sc_inc.inc6_laddr; @@ -1534,7 +1538,7 @@ syncache_respond(struct syncache *sc) #ifdef TCP_SIGNATURE if (sc->sc_flags & SCF_SIGNATURE) - tcp_signature_compute(m, 0, 0, optlen, + tcp_signature_compute(m, &sc->sc_inc, 0, optlen, to.to_signature, IPSEC_DIR_OUTBOUND); #endif #ifdef INET6 @@ -1550,10 +1554,16 @@ syncache_respond(struct syncache *sc) m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); #ifdef INET6 if (sc->sc_inc.inc_flags & INC_ISIPV6) { + struct ifnet *ifp; + m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; th->th_sum = in6_cksum_pseudo(ip6, tlen + optlen - hlen, IPPROTO_TCP, 0); - ip6->ip6_hlim = in6_selecthlim(NULL, NULL); + if (sc->sc_inc.inc6_zoneid != 0) + ifp = in6_getlinkifnet(sc->sc_inc.inc6_zoneid); + else + ifp = NULL; + ip6->ip6_hlim = in6_selecthlim(NULL, ifp); #ifdef TCP_OFFLOAD if (ADDED_BY_TOE(sc)) { struct toedev *tod = sc->sc_tod; @@ -1563,7 +1573,8 @@ syncache_respond(struct syncache *sc) return (error); } #endif - error = ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); + error = ip6_output(m, NULL, NULL, ifp ? IPV6_USEROIF: 0, + NULL, &ifp, NULL); } #endif #if defined(INET6) && defined(INET)