]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ipvs: add assured state for conn templates
authorJulian Anastasov <ja@ssi.bg>
Fri, 6 Jul 2018 05:25:53 +0000 (08:25 +0300)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 18 Jul 2018 09:26:40 +0000 (11:26 +0200)
cp->state was not used for templates. Add support for state bits
and for the first "assured" bit which indicates that some
connection controlled by this template was established or assured
by the real server. In a followup patch we will use it to drop
templates under SYN attack.

Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/ip_vs.h
net/netfilter/ipvs/ip_vs_proto.c
net/netfilter/ipvs/ip_vs_proto_sctp.c
net/netfilter/ipvs/ip_vs_proto_tcp.c
net/netfilter/ipvs/ip_vs_proto_udp.c
net/netfilter/ipvs/ip_vs_sync.c

index 4d76abcf1c4115d8dbb07dd14dfc2129467028cf..a0d2e0bb9a94b90da24b22a327253dc6e9c0e8ff 100644 (file)
@@ -335,6 +335,11 @@ enum ip_vs_sctp_states {
        IP_VS_SCTP_S_LAST
 };
 
+/* Connection templates use bits from state */
+#define IP_VS_CTPL_S_NONE              0x0000
+#define IP_VS_CTPL_S_ASSURED           0x0001
+#define IP_VS_CTPL_S_LAST              0x0002
+
 /* Delta sequence info structure
  * Each ip_vs_conn has 2 (output AND input seq. changes).
  * Only used in the VS/NAT.
@@ -1289,6 +1294,17 @@ ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
        atomic_inc(&ctl_cp->n_control);
 }
 
+/* Mark our template as assured */
+static inline void
+ip_vs_control_assure_ct(struct ip_vs_conn *cp)
+{
+       struct ip_vs_conn *ct = cp->control;
+
+       if (ct && !(ct->state & IP_VS_CTPL_S_ASSURED) &&
+           (ct->flags & IP_VS_CONN_F_TEMPLATE))
+               ct->state |= IP_VS_CTPL_S_ASSURED;
+}
+
 /* IPVS netns init & cleanup functions */
 int ip_vs_estimator_net_init(struct netns_ipvs *ipvs);
 int ip_vs_control_net_init(struct netns_ipvs *ipvs);
index 85c446621758e2fdba9ec4d7b0bd4f0333423df0..54ee84adf0bdea67428b124a54d9820fa33361ba 100644 (file)
 
 static struct ip_vs_protocol *ip_vs_proto_table[IP_VS_PROTO_TAB_SIZE];
 
+/* States for conn templates: NONE or words separated with ",", max 15 chars */
+static const char *ip_vs_ctpl_state_name_table[IP_VS_CTPL_S_LAST] = {
+       [IP_VS_CTPL_S_NONE]                     = "NONE",
+       [IP_VS_CTPL_S_ASSURED]                  = "ASSURED",
+};
 
 /*
  *     register an ipvs protocol
@@ -195,11 +200,19 @@ ip_vs_create_timeout_table(int *table, int size)
 
 const char *ip_vs_state_name(const struct ip_vs_conn *cp)
 {
-       struct ip_vs_protocol *pp = ip_vs_proto_get(cp->protocol);
+       unsigned int state = cp->state;
+       struct ip_vs_protocol *pp;
+
+       if (cp->flags & IP_VS_CONN_F_TEMPLATE) {
 
+               if (state >= IP_VS_CTPL_S_LAST)
+                       return "ERR!";
+               return ip_vs_ctpl_state_name_table[state] ? : "?";
+       }
+       pp = ip_vs_proto_get(cp->protocol);
        if (pp == NULL || pp->state_name == NULL)
                return (cp->protocol == IPPROTO_IP) ? "NONE" : "ERR!";
-       return pp->state_name(cp->state);
+       return pp->state_name(state);
 }
 
 
index 3250c4a1111e27046c797c703524e80166c80a34..b0cd7d08f2a7a2692657dd751ae655576a37a81d 100644 (file)
@@ -461,6 +461,8 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
                                cp->flags &= ~IP_VS_CONN_F_INACTIVE;
                        }
                }
+               if (next_state == IP_VS_SCTP_S_ESTABLISHED)
+                       ip_vs_control_assure_ct(cp);
        }
        if (likely(pd))
                cp->timeout = pd->timeout_table[cp->state = next_state];
index 80d10ad12a15f686a68e0457ac3701b605a764c9..1770fc6ce960e4a69e09d29573a3df753a013441 100644 (file)
@@ -569,6 +569,8 @@ set_tcp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
                                cp->flags &= ~IP_VS_CONN_F_INACTIVE;
                        }
                }
+               if (new_state == IP_VS_TCP_S_ESTABLISHED)
+                       ip_vs_control_assure_ct(cp);
        }
 
        if (likely(pd))
index e0ef11c3691e49deebd7ae4204cc4ad8bce53cc7..0f53c49025f8799da71bb1a41dc407435a27013e 100644 (file)
@@ -460,6 +460,8 @@ udp_state_transition(struct ip_vs_conn *cp, int direction,
        }
 
        cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL];
+       if (direction == IP_VS_DIR_OUTPUT)
+               ip_vs_control_assure_ct(cp);
 }
 
 static int __udp_init(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd)
index 001501e25625fcd3f87a22fec4c4e013c90b3b8d..d4020c5e831d3020a6e412ead6d1895f81b5a124 100644 (file)
@@ -1003,12 +1003,9 @@ static void ip_vs_process_message_v0(struct netns_ipvs *ipvs, const char *buffer
                                continue;
                        }
                } else {
-                       /* protocol in templates is not used for state/timeout */
-                       if (state > 0) {
-                               IP_VS_DBG(2, "BACKUP v0, Invalid template state %u\n",
-                                       state);
-                               state = 0;
-                       }
+                       if (state >= IP_VS_CTPL_S_LAST)
+                               IP_VS_DBG(7, "BACKUP v0, Invalid tpl state %u\n",
+                                         state);
                }
 
                ip_vs_conn_fill_param(ipvs, AF_INET, s->protocol,
@@ -1166,12 +1163,9 @@ static inline int ip_vs_proc_sync_conn(struct netns_ipvs *ipvs, __u8 *p, __u8 *m
                        goto out;
                }
        } else {
-               /* protocol in templates is not used for state/timeout */
-               if (state > 0) {
-                       IP_VS_DBG(3, "BACKUP, Invalid template state %u\n",
-                               state);
-                       state = 0;
-               }
+               if (state >= IP_VS_CTPL_S_LAST)
+                       IP_VS_DBG(7, "BACKUP, Invalid tpl state %u\n",
+                                 state);
        }
        if (ip_vs_conn_fill_param_sync(ipvs, af, s, &param, pe_data,
                                       pe_data_len, pe_name, pe_name_len)) {