+       return ret;
+}
+
+boolean_t
+tcp_heuristic_do_ecn(struct tcpcb *tp)
+{
+       struct tcp_cache_key_src tcks;
+
+       tcp_cache_key_src_create(tp, &tcks);
+       return tcp_heuristic_do_ecn_common(&tcks);
+}
+
+boolean_t
+tcp_heuristic_do_ecn_with_address(struct ifnet *ifp,
+    union sockaddr_in_4_6 *local_address)
+{
+       struct tcp_cache_key_src tcks;
+
+       memset(&tcks, 0, sizeof(tcks));
+       tcks.ifp = ifp;
+
+       calculate_tcp_clock();
+
+       if (local_address->sa.sa_family == AF_INET6) {
+               memcpy(&tcks.laddr.addr6, &local_address->sin6.sin6_addr, sizeof(struct in6_addr));
+               tcks.af = AF_INET6;
+       } else if (local_address->sa.sa_family == AF_INET) {
+               memcpy(&tcks.laddr.addr, &local_address->sin.sin_addr, sizeof(struct in_addr));
+               tcks.af = AF_INET;
+       }
+
+       return tcp_heuristic_do_ecn_common(&tcks);
+}
+
+void
+tcp_heuristics_ecn_update(struct necp_tcp_ecn_cache *necp_buffer,
+    struct ifnet *ifp, union sockaddr_in_4_6 *local_address)
+{
+       struct tcp_cache_key_src tcks;
+
+       memset(&tcks, 0, sizeof(tcks));
+       tcks.ifp = ifp;
+
+       calculate_tcp_clock();
+
+       if (local_address->sa.sa_family == AF_INET6) {
+               memcpy(&tcks.laddr.addr6, &local_address->sin6.sin6_addr, sizeof(struct in6_addr));
+               tcks.af = AF_INET6;
+       } else if (local_address->sa.sa_family == AF_INET) {
+               memcpy(&tcks.laddr.addr, &local_address->sin.sin_addr, sizeof(struct in_addr));
+               tcks.af = AF_INET;
+       }
+
+       if (necp_buffer->necp_tcp_ecn_heuristics_success) {
+               tcp_heuristic_reset_counters(&tcks, TCPCACHE_F_ECN);
+       } else if (necp_buffer->necp_tcp_ecn_heuristics_loss) {
+               tcp_heuristic_inc_counters(&tcks, TCPCACHE_F_ECN);
+       } else if (necp_buffer->necp_tcp_ecn_heuristics_drop_rst) {
+               tcp_heuristic_inc_counters(&tcks, TCPCACHE_F_ECN_DROPRST);
+       } else if (necp_buffer->necp_tcp_ecn_heuristics_drop_rxmt) {
+               tcp_heuristic_inc_counters(&tcks, TCPCACHE_F_ECN_DROPRXMT);
+       } else if (necp_buffer->necp_tcp_ecn_heuristics_syn_rst) {
+               tcp_heuristic_inc_counters(&tcks, TCPCACHE_F_ECN_SYNRST);
+       } else if (necp_buffer->necp_tcp_ecn_heuristics_aggressive) {
+               tcp_heuristic_ecn_aggressive_common(&tcks);
+       }
+
+       return;
+}
+
+boolean_t
+tcp_heuristic_do_tfo_with_address(struct ifnet *ifp,
+    union sockaddr_in_4_6 *local_address, union sockaddr_in_4_6 *remote_address,
+    uint8_t *cookie, uint8_t *cookie_len)
+{
+       struct tcp_cache_key_src tcks;
+
+       memset(&tcks, 0, sizeof(tcks));
+       tcks.ifp = ifp;
+
+       calculate_tcp_clock();
+
+       if (remote_address->sa.sa_family == AF_INET6) {
+               memcpy(&tcks.laddr.addr6, &local_address->sin6.sin6_addr, sizeof(struct in6_addr));
+               memcpy(&tcks.faddr.addr6, &remote_address->sin6.sin6_addr, sizeof(struct in6_addr));
+               tcks.af = AF_INET6;
+       } else if (remote_address->sa.sa_family == AF_INET) {
+               memcpy(&tcks.laddr.addr, &local_address->sin.sin_addr, sizeof(struct in_addr));
+               memcpy(&tcks.faddr.addr, &remote_address->sin.sin_addr, sizeof(struct in_addr));
+               tcks.af = AF_INET;
+       }
+
+       if (tcp_heuristic_do_tfo_common(&tcks)) {
+               if (!tcp_cache_get_cookie_common(&tcks, cookie, cookie_len)) {
+                       *cookie_len = 0;
+               }
+               return TRUE;
+       }
+
+       return FALSE;