LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

Re: [PATCH net-next 2/3] ipvs: add function to find tunnels

To: Julian Anastasov <ja@xxxxxx>
Subject: Re: [PATCH net-next 2/3] ipvs: add function to find tunnels
Cc: lvs-devel@xxxxxxxxxxxxxxx, Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>, netfilter-devel@xxxxxxxxxxxxxxx, Jacky Hu <hengqing.hu@xxxxxxxxx>, jacky.hu@xxxxxxxxxxx, jason.niesz@xxxxxxxxxxx
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Wed, 3 Apr 2019 09:56:46 +0200
On Sun, Mar 31, 2019 at 01:26:20PM +0300, Julian Anastasov wrote:
> Add ip_vs_find_tunnel() to match tunnel headers
> by family, address and optional port. Use it to
> properly find the tunnel real server used in
> received ICMP errors.
> 
> Signed-off-by: Julian Anastasov <ja@xxxxxx>
> ---
>  include/net/ip_vs.h             |  3 +++
>  net/netfilter/ipvs/ip_vs_core.c |  8 ++++++++
>  net/netfilter/ipvs/ip_vs_ctl.c  | 29 +++++++++++++++++++++++++++++
>  3 files changed, 40 insertions(+)
> 
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index 9a8ac8997e34..b01a94ebfc0e 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -1404,6 +1404,9 @@ bool ip_vs_has_real_service(struct netns_ipvs *ipvs, 
> int af, __u16 protocol,
>  struct ip_vs_dest *
>  ip_vs_find_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol,
>                       const union nf_inet_addr *daddr, __be16 dport);
> +struct ip_vs_dest *ip_vs_find_tunnel(struct netns_ipvs *ipvs, int af,
> +                                  const union nf_inet_addr *daddr,
> +                                  __be16 tun_port);
>  
>  int ip_vs_use_count_inc(void);
>  void ip_vs_use_count_dec(void);

> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index 14457551bcb4..4447ee512b88 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -1598,6 +1598,7 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff 
> *skb, int *related,
>       struct ip_vs_proto_data *pd;
>       unsigned int offset, offset2, ihl, verdict;
>       bool ipip, new_cp = false;
> +     union nf_inet_addr *raddr;
>  
>       *related = 1;
>  
> @@ -1636,15 +1637,22 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff 
> *skb, int *related,
>       cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
>       if (cih == NULL)
>               return NF_ACCEPT; /* The packet looks wrong, ignore */
> +     raddr = (union nf_inet_addr *)&cih->daddr;

Hi Julian,

        Could we consider the following instead of casting?

        union nf_inet_addr raddr;

        ...

        raddr.ip = cih->daddr;

        ...

        est = ip_vs_find_tunnel(ipvs, AF_INET, &raddr, 0);

>  
>       /* Special case for errors for IPIP packets */
>       ipip = false;
>       if (cih->protocol == IPPROTO_IPIP) {
> +             struct ip_vs_dest *dest;
> +
>               if (unlikely(cih->frag_off & htons(IP_OFFSET)))
>                       return NF_ACCEPT;
>               /* Error for our IPIP must arrive at LOCAL_IN */
>               if (!(skb_rtable(skb)->rt_flags & RTCF_LOCAL))
>                       return NF_ACCEPT;
> +             dest = ip_vs_find_tunnel(ipvs, AF_INET, raddr, 0);
> +             /* Only for known tunnel */
> +             if (!dest || dest->tun_type != IP_VS_CONN_F_TUNNEL_TYPE_IPIP)
> +                     return NF_ACCEPT;
>               offset += cih->ihl * 4;
>               cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
>               if (cih == NULL)

...

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