+static inline void
+tcp_update_ecn_perf_stats(struct tcpcb *tp,
+ struct if_tcp_ecn_perf_stat *stat)
+{
+ u_int64_t curval, oldval;
+ struct inpcb *inp = tp->t_inpcb;
+ stat->total_txpkts += inp->inp_stat->txpackets;
+ stat->total_rxpkts += inp->inp_stat->rxpackets;
+ stat->total_rxmitpkts += tp->t_stat.rxmitpkts;
+ stat->total_oopkts += tp->t_rcvoopack;
+ stat->total_reorderpkts += (tp->t_reordered_pkts + tp->t_pawsdrop +
+ tp->t_dsack_sent + tp->t_dsack_recvd);
+
+ /* Average RTT */
+ curval = (tp->t_srtt >> TCP_RTT_SHIFT);
+ if (curval > 0 && tp->t_rttupdated >= 16) {
+ if (stat->rtt_avg == 0) {
+ stat->rtt_avg = curval;
+ } else {
+ oldval = stat->rtt_avg;
+ stat->rtt_avg =
+ ((oldval << 4) - oldval + curval) >> 4;
+ }
+ }
+
+ /* RTT variance */
+ curval = tp->t_rttvar >> TCP_RTTVAR_SHIFT;
+ if (curval > 0 && tp->t_rttupdated >= 16) {
+ if (stat->rtt_var == 0) {
+ stat->rtt_var = curval;
+ } else {
+ oldval = stat->rtt_var;
+ stat->rtt_var =
+ ((oldval << 4) - oldval + curval) >> 4;
+ }
+ }
+
+ /* Total number of SACK recovery episodes */
+ stat->sack_episodes += tp->t_sack_recovery_episode;
+
+ if (inp->inp_socket->so_error == ECONNRESET)
+ stat->rst_drop++;
+ return;
+}
+