mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
ipvs: add assured state for conn templates
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>
This commit is contained in:
parent
ec1b28ca96
commit
275411430f
@ -335,6 +335,11 @@ enum ip_vs_sctp_states {
|
|||||||
IP_VS_SCTP_S_LAST
|
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
|
/* Delta sequence info structure
|
||||||
* Each ip_vs_conn has 2 (output AND input seq. changes).
|
* Each ip_vs_conn has 2 (output AND input seq. changes).
|
||||||
* Only used in the VS/NAT.
|
* 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);
|
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 */
|
/* IPVS netns init & cleanup functions */
|
||||||
int ip_vs_estimator_net_init(struct netns_ipvs *ipvs);
|
int ip_vs_estimator_net_init(struct netns_ipvs *ipvs);
|
||||||
int ip_vs_control_net_init(struct netns_ipvs *ipvs);
|
int ip_vs_control_net_init(struct netns_ipvs *ipvs);
|
||||||
|
@ -42,6 +42,11 @@
|
|||||||
|
|
||||||
static struct ip_vs_protocol *ip_vs_proto_table[IP_VS_PROTO_TAB_SIZE];
|
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
|
* 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)
|
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)
|
if (pp == NULL || pp->state_name == NULL)
|
||||||
return (cp->protocol == IPPROTO_IP) ? "NONE" : "ERR!";
|
return (cp->protocol == IPPROTO_IP) ? "NONE" : "ERR!";
|
||||||
return pp->state_name(cp->state);
|
return pp->state_name(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
cp->flags &= ~IP_VS_CONN_F_INACTIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (next_state == IP_VS_SCTP_S_ESTABLISHED)
|
||||||
|
ip_vs_control_assure_ct(cp);
|
||||||
}
|
}
|
||||||
if (likely(pd))
|
if (likely(pd))
|
||||||
cp->timeout = pd->timeout_table[cp->state = next_state];
|
cp->timeout = pd->timeout_table[cp->state = next_state];
|
||||||
|
@ -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;
|
cp->flags &= ~IP_VS_CONN_F_INACTIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (new_state == IP_VS_TCP_S_ESTABLISHED)
|
||||||
|
ip_vs_control_assure_ct(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(pd))
|
if (likely(pd))
|
||||||
|
@ -460,6 +460,8 @@ udp_state_transition(struct ip_vs_conn *cp, int direction,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL];
|
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)
|
static int __udp_init(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd)
|
||||||
|
@ -1003,12 +1003,9 @@ static void ip_vs_process_message_v0(struct netns_ipvs *ipvs, const char *buffer
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* protocol in templates is not used for state/timeout */
|
if (state >= IP_VS_CTPL_S_LAST)
|
||||||
if (state > 0) {
|
IP_VS_DBG(7, "BACKUP v0, Invalid tpl state %u\n",
|
||||||
IP_VS_DBG(2, "BACKUP v0, Invalid template state %u\n",
|
state);
|
||||||
state);
|
|
||||||
state = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_vs_conn_fill_param(ipvs, AF_INET, s->protocol,
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* protocol in templates is not used for state/timeout */
|
if (state >= IP_VS_CTPL_S_LAST)
|
||||||
if (state > 0) {
|
IP_VS_DBG(7, "BACKUP, Invalid tpl state %u\n",
|
||||||
IP_VS_DBG(3, "BACKUP, Invalid template state %u\n",
|
state);
|
||||||
state);
|
|
||||||
state = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ip_vs_conn_fill_param_sync(ipvs, af, s, ¶m, pe_data,
|
if (ip_vs_conn_fill_param_sync(ipvs, af, s, ¶m, pe_data,
|
||||||
pe_data_len, pe_name, pe_name_len)) {
|
pe_data_len, pe_name, pe_name_len)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user