Merge tag 'ipvs2-for-v4.7' of https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next
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: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
commit
bbe848ec1a
2 changed files with 26 additions and 4 deletions
|
@ -1261,6 +1261,16 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
|
||||||
return 1;
|
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 */
|
/* Called from keventd and must protect itself from softirqs */
|
||||||
void ip_vs_random_dropentry(struct netns_ipvs *ipvs)
|
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;
|
unsigned int hash = prandom_u32() & ip_vs_conn_tab_mask;
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[hash], c_list) {
|
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)
|
if (cp->ipvs != ipvs)
|
||||||
continue;
|
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) {
|
if (cp->protocol == IPPROTO_TCP) {
|
||||||
switch(cp->state) {
|
switch(cp->state) {
|
||||||
case IP_VS_TCP_S_SYN_RECV:
|
case IP_VS_TCP_S_SYN_RECV:
|
||||||
|
@ -1307,6 +1322,7 @@ void ip_vs_random_dropentry(struct netns_ipvs *ipvs)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
try_drop:
|
||||||
if (!todrop_entry(cp))
|
if (!todrop_entry(cp))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -612,7 +612,10 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
|
||||||
ret = cp->packet_xmit(skb, cp, pd->pp, iph);
|
ret = cp->packet_xmit(skb, cp, pd->pp, iph);
|
||||||
/* do not touch skb anymore */
|
/* do not touch skb anymore */
|
||||||
|
|
||||||
atomic_inc(&cp->in_pkts);
|
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);
|
ip_vs_conn_put(cp);
|
||||||
return ret;
|
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)
|
if (ipvs->sync_state & IP_VS_STATE_MASTER)
|
||||||
ip_vs_sync_conn(ipvs, cp, pkts);
|
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);
|
ip_vs_conn_put(cp);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue