]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/netfilter/ipvs/ip_vs_proto_tcp.c
Merge tag 'platform-drivers-x86-v4.9-1' of git://git.infradead.org/users/dvhart/linux...
[karo-tx-linux.git] / net / netfilter / ipvs / ip_vs_proto_tcp.c
index d7024b2ed769a274ec8320ef9650c777a1d7dcd4..5117bcb7d2f00604d5ab73f0610246a7d4fef755 100644 (file)
@@ -395,6 +395,20 @@ static const char *const tcp_state_name_table[IP_VS_TCP_S_LAST+1] = {
        [IP_VS_TCP_S_LAST]              =       "BUG!",
 };
 
+static const bool tcp_state_active_table[IP_VS_TCP_S_LAST] = {
+       [IP_VS_TCP_S_NONE]              =       false,
+       [IP_VS_TCP_S_ESTABLISHED]       =       true,
+       [IP_VS_TCP_S_SYN_SENT]          =       true,
+       [IP_VS_TCP_S_SYN_RECV]          =       true,
+       [IP_VS_TCP_S_FIN_WAIT]          =       false,
+       [IP_VS_TCP_S_TIME_WAIT]         =       false,
+       [IP_VS_TCP_S_CLOSE]             =       false,
+       [IP_VS_TCP_S_CLOSE_WAIT]        =       false,
+       [IP_VS_TCP_S_LAST_ACK]          =       false,
+       [IP_VS_TCP_S_LISTEN]            =       false,
+       [IP_VS_TCP_S_SYNACK]            =       true,
+};
+
 #define sNO IP_VS_TCP_S_NONE
 #define sES IP_VS_TCP_S_ESTABLISHED
 #define sSS IP_VS_TCP_S_SYN_SENT
@@ -418,6 +432,13 @@ static const char * tcp_state_name(int state)
        return tcp_state_name_table[state] ? tcp_state_name_table[state] : "?";
 }
 
+static bool tcp_state_active(int state)
+{
+       if (state >= IP_VS_TCP_S_LAST)
+               return false;
+       return tcp_state_active_table[state];
+}
+
 static struct tcp_states_t tcp_states [] = {
 /*     INPUT */
 /*        sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA        */
@@ -540,12 +561,12 @@ set_tcp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
 
                if (dest) {
                        if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
-                           (new_state != IP_VS_TCP_S_ESTABLISHED)) {
+                           !tcp_state_active(new_state)) {
                                atomic_dec(&dest->activeconns);
                                atomic_inc(&dest->inactconns);
                                cp->flags |= IP_VS_CONN_F_INACTIVE;
                        } else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
-                                  (new_state == IP_VS_TCP_S_ESTABLISHED)) {
+                                  tcp_state_active(new_state)) {
                                atomic_inc(&dest->activeconns);
                                atomic_dec(&dest->inactconns);
                                cp->flags &= ~IP_VS_CONN_F_INACTIVE;