diff --git a/sys/netinet/tcp_lro_hpts.c b/sys/netinet/tcp_lro_hpts.c --- a/sys/netinet/tcp_lro_hpts.c +++ b/sys/netinet/tcp_lro_hpts.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -424,7 +426,7 @@ { struct inpcb *inp; - CURVNET_SET(ifp->if_vnet); + CURVNET_ASSERT_SET(); switch (pa->data.lro_type) { #ifdef INET6 case LRO_TYPE_IPV6_TCP: @@ -449,10 +451,8 @@ break; #endif default: - CURVNET_RESTORE(); return (NULL); } - CURVNET_RESTORE(); return (intotcpcb(inp)); } @@ -488,9 +488,28 @@ IN6_IS_ADDR_UNSPECIFIED(&le->inner.data.s_addr.v6))) return (TCP_LRO_CANNOT); #endif + + CURVNET_SET(lc->ifp->if_vnet); + /* + * Ensure that there are no packet filter hooks which would normally + * being triggered in ether_demux(), ip_input(), or ip6_input(). + */ + if ( +#ifdef INET + PFIL_HOOKED_IN(V_inet_pfil_head) || +#endif +#ifdef INET6 + PFIL_HOOKED_IN(V_inet6_pfil_head) || +#endif + PFIL_HOOKED_IN(V_link_pfil_head)) { + CURVNET_RESTORE(); + return (TCP_LRO_CANNOT); + } + /* Lookup inp, if any. Returns locked TCP inpcb. */ tp = tcp_lro_lookup(lc->ifp, (le->inner.data.lro_type == LRO_TYPE_NONE) ? &le->outer : &le->inner); + CURVNET_RESTORE(); if (tp == NULL) return (TCP_LRO_CANNOT);