diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c --- a/sys/netinet/tcp_lro.c +++ b/sys/netinet/tcp_lro.c @@ -670,8 +670,29 @@ return (TCP_LRO_CANNOT); } } + if (__predict_false(ip4->ip_src.s_addr == INADDR_ANY || + ip4->ip_dst.s_addr == INADDR_ANY)) { + IPSTAT_INC(ips_badaddr); + return (TCP_LRO_CANNOT); + } + return (0); +} +#endif + +#ifdef INET6 +static int +tcp_lro_rx_ipv6(struct lro_ctrl *lc, struct mbuf *m, struct ip6_hdr *ip6) +{ + + if (__predict_false(IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) || + IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst))) { + IP6STAT_INC(ip6s_badscope); /* XXX */ + return (TCP_LRO_CANNOT); + } + return (0); } + #endif #ifdef TCPHPTS @@ -1881,17 +1902,24 @@ if (__predict_false(error != 0)) return (error); -#ifdef INET switch (pa->data.lro_type) { +#ifdef INET case LRO_TYPE_IPV4_TCP: error = tcp_lro_rx_ipv4(lc, m, pa->ip4); if (__predict_false(error != 0)) return (error); break; +#endif +#ifdef INET6 + case LRO_TYPE_IPV6_TCP: + error = tcp_lro_rx_ipv6(lc, m, pa->ip6); + if (__predict_false(error != 0)) + return (error); + break; +#endif default: break; } -#endif /* If no hardware or arrival stamp on the packet add timestamp */ if ((m->m_flags & (M_TSTMP_LRO | M_TSTMP)) == 0) { m->m_pkthdr.rcv_tstmp = bintime2ns(&lc->lro_last_queue_time);