Commit 27541143 authored by Julian Anastasov's avatar Julian Anastasov Committed by Pablo Neira Ayuso
Browse files

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: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent ec1b28ca
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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);
+15 −2
Original line number Diff line number Diff line
@@ -42,6 +42,11 @@

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);
}


+2 −0
Original line number Diff line number Diff line
@@ -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];
+2 −0
Original line number Diff line number Diff line
@@ -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))
+2 −0
Original line number Diff line number Diff line
@@ -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)
Loading