LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

Re: [PATCH] ipvs: make drop_entry protection effective for SIP-pe

To: Marco Angaroni <marcoangaroni@xxxxxxxxx>
Subject: Re: [PATCH] ipvs: make drop_entry protection effective for SIP-pe
Cc: lvs-devel@xxxxxxxxxxxxxxx, Simon Horman <horms@xxxxxxxxxxxx>
From: Julian Anastasov <ja@xxxxxx>
Date: Wed, 27 Apr 2016 10:27:41 +0300 (EEST)
        Hello,

On Tue, 26 Apr 2016, Marco Angaroni wrote:

> DoS protection policy that deletes connections to avoid out of memory is
> currently not effective for SIP-pe plus OPS-mode for two reasons:
>   1) connection templates (holding SIP call-id) are always skipped in
>      ip_vs_random_dropentry()
>   2) in_pkts counter (used by drop_entry algorithm) is not incremented
>      for connection templates
> 
> This patch addresses such problems with the following changes:
>   a) connection templates associated (via their dest) to virtual-services 
>      configured in OPS mode are included in ip_vs_random_dropentry()
>      monitoring. This applies to SIP-pe over UDP (which requires OPS mode),
>      but is more general principle: when OPS is controlled by templates
>      memory can be used only by templates themselves, since OPS conns are
>      deleted after packet is forwarded.
>   b) OPS connections, if controlled by a template, cause increment of 
>      in_pkts counter of their template. This is already happening but only
>      in case director is in master-slave mode (see ip_vs_sync_conn()).
> 
> Signed-off-by: Marco Angaroni <marcoangaroni@xxxxxxxxx>

        Looks good to me. Simon, please apply to -next.

Acked-by: Julian Anastasov <ja@xxxxxx>

> ---
>  net/netfilter/ipvs/ip_vs_conn.c | 22 +++++++++++++++++++---
>  net/netfilter/ipvs/ip_vs_core.c |  8 +++++++-
>  2 files changed, 26 insertions(+), 4 deletions(-)
> 
> diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
> index 292365f..2cb3c62 100644
> --- a/net/netfilter/ipvs/ip_vs_conn.c
> +++ b/net/netfilter/ipvs/ip_vs_conn.c
> @@ -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;
>                       }
> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index 398ccb5..a97de51 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -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);
>               /* 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);
>               return ret;
>       }
> @@ -1971,6 +1974,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;
> -- 
> 1.8.3.1

Regards

--
Julian Anastasov <ja@xxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

<Prev in Thread] Current Thread [Next in Thread>