Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbe848ec authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files


Simon Horman says:

====================
Second Round of IPVS Updates for v4.7

please consider these enhancements to the IPVS. They allow its DoS
mitigation strategy effective in conjunction with the SIP persistence
engine.
====================

Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parents 0a93aaed 698e2a8d
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -1261,6 +1261,16 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
	return 1;
}

static inline bool ip_vs_conn_ops_mode(struct ip_vs_conn *cp)
{
	struct ip_vs_service *svc;

	if (!cp->dest)
		return false;
	svc = rcu_dereference(cp->dest->svc);
	return svc && (svc->flags & IP_VS_SVC_F_ONEPACKET);
}

/* Called from keventd and must protect itself from softirqs */
void ip_vs_random_dropentry(struct netns_ipvs *ipvs)
{
@@ -1275,11 +1285,16 @@ void ip_vs_random_dropentry(struct netns_ipvs *ipvs)
		unsigned int hash = prandom_u32() & ip_vs_conn_tab_mask;

		hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[hash], c_list) {
			if (cp->flags & IP_VS_CONN_F_TEMPLATE)
				/* connection template */
				continue;
			if (cp->ipvs != ipvs)
				continue;
			if (cp->flags & IP_VS_CONN_F_TEMPLATE) {
				if (atomic_read(&cp->n_control) ||
				    !ip_vs_conn_ops_mode(cp))
					continue;
				else
					/* connection template of OPS */
					goto try_drop;
			}
			if (cp->protocol == IPPROTO_TCP) {
				switch(cp->state) {
				case IP_VS_TCP_S_SYN_RECV:
@@ -1307,6 +1322,7 @@ void ip_vs_random_dropentry(struct netns_ipvs *ipvs)
					continue;
				}
			} else {
try_drop:
				if (!todrop_entry(cp))
					continue;
			}
+7 −1
Original line number Diff line number Diff line
@@ -612,6 +612,9 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
		ret = cp->packet_xmit(skb, cp, pd->pp, iph);
		/* do not touch skb anymore */

		if ((cp->flags & IP_VS_CONN_F_ONE_PACKET) && cp->control)
			atomic_inc(&cp->control->in_pkts);
		else
			atomic_inc(&cp->in_pkts);
		ip_vs_conn_put(cp);
		return ret;
@@ -1991,6 +1994,9 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int

	if (ipvs->sync_state & IP_VS_STATE_MASTER)
		ip_vs_sync_conn(ipvs, cp, pkts);
	else if ((cp->flags & IP_VS_CONN_F_ONE_PACKET) && cp->control)
		/* increment is done inside ip_vs_sync_conn too */
		atomic_inc(&cp->control->in_pkts);

	ip_vs_conn_put(cp);
	return ret;