diff mbox

Implement full-functionality option for ECN encapsulation in tunnel

Message ID 1487165636-10157-1-git-send-email-vfedorenko@yandex-team.ru
State Awaiting Upstream, archived
Delegated to: David Miller
Headers show

Commit Message

Vadim Fedorenko Feb. 15, 2017, 1:33 p.m. UTC
IPVS tunnel mode works as simple tunnel (see RFC 3168) copying ECN field
to outer header. That's result in packet drops on egress tunnels in case
the egress tunnel operates as ECN-capable with Full-functionality option
(like ip_tunnel and ip6_tunnel kernel modules), according to RFC 3168
section 9.1.1 recommendation.

This patch implements ECN full-functionality option into ipvs xmit code.

Cc: netdev@vger.kernel.org
Cc: lvs-devel@vger.kernel.org
Signed-off-by: Vadim Fedorenko <vfedorenko@yandex-team.ru>
Reviewed-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 net/netfilter/ipvs/ip_vs_xmit.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Comments

Julian Anastasov Feb. 15, 2017, 8:39 p.m. UTC | #1
Hello,

On Wed, 15 Feb 2017, Vadim Fedorenko wrote:

> IPVS tunnel mode works as simple tunnel (see RFC 3168) copying ECN field
> to outer header. That's result in packet drops on egress tunnels in case
> the egress tunnel operates as ECN-capable with Full-functionality option
> (like ip_tunnel and ip6_tunnel kernel modules), according to RFC 3168
> section 9.1.1 recommendation.
> 
> This patch implements ECN full-functionality option into ipvs xmit code.
> 
> Cc: netdev@vger.kernel.org
> Cc: lvs-devel@vger.kernel.org
> Signed-off-by: Vadim Fedorenko <vfedorenko@yandex-team.ru>
> Reviewed-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>

	Looks good to me, thanks!

Acked-by: Julian Anastasov <ja@ssi.bg>

> ---
>  net/netfilter/ipvs/ip_vs_xmit.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
> index 01d3d89..b3286f3 100644
> --- a/net/netfilter/ipvs/ip_vs_xmit.c
> +++ b/net/netfilter/ipvs/ip_vs_xmit.c
> @@ -879,6 +879,7 @@ static inline int ip_vs_send_or_cont(int pf, struct sk_buff *skb,
>  {
>  	struct sk_buff *new_skb = NULL;
>  	struct iphdr *old_iph = NULL;
> +	__u8 old_dsfield;
>  #ifdef CONFIG_IP_VS_IPV6
>  	struct ipv6hdr *old_ipv6h = NULL;
>  #endif
> @@ -903,7 +904,7 @@ static inline int ip_vs_send_or_cont(int pf, struct sk_buff *skb,
>  			*payload_len =
>  				ntohs(old_ipv6h->payload_len) +
>  				sizeof(*old_ipv6h);
> -		*dsfield = ipv6_get_dsfield(old_ipv6h);
> +		old_dsfield = ipv6_get_dsfield(old_ipv6h);
>  		*ttl = old_ipv6h->hop_limit;
>  		if (df)
>  			*df = 0;
> @@ -918,12 +919,15 @@ static inline int ip_vs_send_or_cont(int pf, struct sk_buff *skb,
>  
>  		/* fix old IP header checksum */
>  		ip_send_check(old_iph);
> -		*dsfield = ipv4_get_dsfield(old_iph);
> +		old_dsfield = ipv4_get_dsfield(old_iph);
>  		*ttl = old_iph->ttl;
>  		if (payload_len)
>  			*payload_len = ntohs(old_iph->tot_len);
>  	}
>  
> +	/* Implement full-functionality option for ECN encapsulation */
> +	*dsfield = INET_ECN_encapsulate(old_dsfield, old_dsfield);
> +
>  	return skb;
>  error:
>  	kfree_skb(skb);
> -- 
> 1.9.1

Regards

--
Julian Anastasov <ja@ssi.bg>
Pablo Neira Ayuso Sept. 26, 2017, 12:07 p.m. UTC | #2
On Tue, Sep 26, 2017 at 11:09:54AM +0300, Vadim Fedorenko wrote:
> Hello,
>   this patch seems to be lost somewhere in upstream. Please, merge it

Applied to nf.git.

Thanks.
diff mbox

Patch

diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 01d3d89..b3286f3 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -879,6 +879,7 @@  static inline int ip_vs_send_or_cont(int pf, struct sk_buff *skb,
 {
 	struct sk_buff *new_skb = NULL;
 	struct iphdr *old_iph = NULL;
+	__u8 old_dsfield;
 #ifdef CONFIG_IP_VS_IPV6
 	struct ipv6hdr *old_ipv6h = NULL;
 #endif
@@ -903,7 +904,7 @@  static inline int ip_vs_send_or_cont(int pf, struct sk_buff *skb,
 			*payload_len =
 				ntohs(old_ipv6h->payload_len) +
 				sizeof(*old_ipv6h);
-		*dsfield = ipv6_get_dsfield(old_ipv6h);
+		old_dsfield = ipv6_get_dsfield(old_ipv6h);
 		*ttl = old_ipv6h->hop_limit;
 		if (df)
 			*df = 0;
@@ -918,12 +919,15 @@  static inline int ip_vs_send_or_cont(int pf, struct sk_buff *skb,
 
 		/* fix old IP header checksum */
 		ip_send_check(old_iph);
-		*dsfield = ipv4_get_dsfield(old_iph);
+		old_dsfield = ipv4_get_dsfield(old_iph);
 		*ttl = old_iph->ttl;
 		if (payload_len)
 			*payload_len = ntohs(old_iph->tot_len);
 	}
 
+	/* Implement full-functionality option for ECN encapsulation */
+	*dsfield = INET_ECN_encapsulate(old_dsfield, old_dsfield);
+
 	return skb;
 error:
 	kfree_skb(skb);