ipv6: fix flowlabel issue for reset packet
Subsystems (4)
v4 cover ipv6: fix flowlabel issue for reset packet
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum 0x0529 (incorrect -> 0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel 0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum 0x0529 (incorrect -> 0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum 0x0521 (incorrect -> 0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum 0x053f (incorrect -> 0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel 0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum 0x0521 (incorrect -> 0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel 0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum 0x0539 (incorrect -> 0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum 0x0521 (incorrect -> 0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel 0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum 0x0521 (incorrect -> 0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum 0x0521 (incorrect -> 0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum 0x0539 (incorrect -> 0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel 0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum 0x0515 (incorrect -> 0x668c), seq 1923801599, win 0, length 0
The flowlabel of reset packet (0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.
Thanks,
Shaohua
Shaohua Li (2):
net: remove unnecessary rotation
net: fix tcp reset packet flowlabel for ipv6
include/net/ipv6.h | 15 ++++----------- net/ipv4/tcp_minisocks.c | 8 +++++++- net/ipv6/ip6_gre.c | 2 +- net/ipv6/ip6_output.c | 4 ++-- net/ipv6/ip6_tunnel.c | 2 +- net/ipv6/tcp_ipv6.c | 18 +++++++++++++++++- 6 files changed, 32 insertions(+), 17 deletions(-)
Signature · 1 line
2.9.3
PATCH v4 1/2 net: remove unnecessary rotation
From: Shaohua Li <[email protected]>
According to David Miller, the rotation doesn't really help avoid security problem, so delte it.
--- include/net/ipv6.h | 6 ------ 1 file changed, 6 deletions(-)
include/net/ipv6.h +0 -6
@@ -790,12 +790,6 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, hash =skb_get_hash_flowi6 (skb, fl6); -/* Since this is being sent on the wire obfuscate hash a bit -* to minimize possbility that any useful information to an -* attacker is leaked. Only lower 20 bits are relevant. -*/ -rol32 (hash,16 ); - flowlabel = (__force __be32 )hash &IPV6_FLOWLABEL_MASK ;if (net->ipv6.sysctl.flowlabel_state_ranges)
Signature · 1 line
2.9.3
PATCH v4 2/2 net: fix tcp reset packet flowlabel for ipv6
In reply to Shaohua LiFrom: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum 0x0529 (incorrect -> 0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel 0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum 0x0529 (incorrect -> 0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum 0x0521 (incorrect -> 0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum 0x053f (incorrect -> 0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel 0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum 0x0521 (incorrect -> 0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel 0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum 0x0539 (incorrect -> 0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum 0x0521 (incorrect -> 0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel 0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum 0x0521 (incorrect -> 0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum 0x0521 (incorrect -> 0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel 0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum 0x0539 (incorrect -> 0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel 0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum 0x0515 (incorrect -> 0x668c), seq 1923801599, win 0, length 0
The tcp reset packet has a different flowlabel, which causes our router doesn't correctly close tcp connection. The reason is the normal packet gets the skb->hash from sk->sk_txhash, which is generated randomly. ip6_make_flowlabel then uses the hash to create a flowlabel. The reset packet doesn't get assigned a hash, so the flowlabel is calculated with flowi6.
Since user can't change timewait sock flowlabel, we create a flowlabel for timewait socket with the random generated hash (sk->sk_txhash), then use it in reset packet. In this way, the reset packet will have the same flowlabel as normal packets.
This also fixes the flowlabel issue for reset packet if user configures flowlabel, which is ignored previously.
--- include/net/ipv6.h | 9 ++++----- net/ipv4/tcp_minisocks.c | 8 +++++++- net/ipv6/ip6_gre.c | 2 +- net/ipv6/ip6_output.c | 4 ++-- net/ipv6/ip6_tunnel.c | 2 +- net/ipv6/tcp_ipv6.c | 18 +++++++++++++++++- 6 files changed, 32 insertions(+), 11 deletions(-)
include/net/ipv6.h +4 -5
@@ -773,10 +773,8 @@ static inline void iph_to_flow_copy_v6addrs(struct flow_keys *flow,static inline __be32 ip6_make_flowlabel (struct net *net,struct sk_buff *skb,__be32 flowlabel,bool autolabel, -struct flowi6 *fl6) +struct flowi6 *fl6,u32 hash) { -u32 hash; -/* @flowlabel may include more than a flow label, eg, the traffic class. * Here we want only the flow label value. */
@@ -788,7 +786,8 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, net->ipv6.sysctl.auto_flowlabels != IP6_AUTO_FLOW_LABEL_FORCED))return flowlabel; - hash =skb_get_hash_flowi6 (skb, fl6); +if (skb) + hash =skb_get_hash_flowi6 (skb, fl6); flowlabel = (__force __be32 )hash &IPV6_FLOWLABEL_MASK ;
@@ -814,7 +813,7 @@ static inline int ip6_default_np_autolabel(struct net *net)static inline void ip6_set_txhash (struct sock *sk) { }static inline __be32 ip6_make_flowlabel (struct net *net,struct sk_buff *skb,__be32 flowlabel,bool autolabel, -struct flowi6 *fl6) +struct flowi6 *fl6,u32 hash) {return flowlabel; }
net/ipv4/tcp_minisocks.c +7 -1
@@ -276,11 +276,17 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)#if IS_ENABLED (CONFIG_IPV6 )if (tw->tw_family ==PF_INET6 ) {struct ipv6_pinfo *np =inet6_sk (sk); +__be32 flowlabel; tw->tw_v6_daddr = sk->sk_v6_daddr; tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr; tw->tw_tclass = np->tclass; - tw->tw_flowlabel =be32_to_cpu (np->flow_label &IPV6_FLOWLABEL_MASK ); + flowlabel = np->flow_label &IPV6_FLOWLABEL_MASK ; +if (flowlabel ==0 ) + flowlabel =ip6_make_flowlabel ( +sock_net (sk),NULL ,0 , np->autoflowlabel, +NULL , sk->sk_txhash); + tw->tw_flowlabel =be32_to_cpu (flowlabel); tw->tw_ipv6only = sk->sk_ipv6only; }#endif
net/ipv6/ip6_gre.c +1 -1
@@ -948,7 +948,7 @@ static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,ip6_flow_hdr (ipv6h,0 ,ip6_make_flowlabel (dev_net (dev), skb, t->fl.u.ip6.flowlabel, true, - &t->fl.u.ip6)); + &t->fl.u.ip6,0 )); ipv6h->hop_limit = t->parms.hop_limit; ipv6h->nexthdr =NEXTHDR_GRE ; ipv6h->saddr = t->parms.laddr;
net/ipv6/ip6_output.c +2 -2
@@ -230,7 +230,7 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, hlimit =ip6_dst_hoplimit (dst);ip6_flow_hdr (hdr, tclass,ip6_make_flowlabel (net, skb, fl6->flowlabel, - np->autoflowlabel, fl6)); + np->autoflowlabel, fl6,0 )); hdr->payload_len =htons (seg_len); hdr->nexthdr = proto;
@@ -1702,7 +1702,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,ip6_flow_hdr (hdr, v6_cork->tclass,ip6_make_flowlabel (net, skb, fl6->flowlabel, - np->autoflowlabel, fl6)); + np->autoflowlabel, fl6,0 )); hdr->hop_limit = v6_cork->hop_limit; hdr->nexthdr = proto; hdr->saddr = fl6->saddr;
net/ipv6/ip6_tunnel.c +1 -1
@@ -1201,7 +1201,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,skb_reset_network_header (skb); ipv6h =ipv6_hdr (skb);ip6_flow_hdr (ipv6h, dsfield, -ip6_make_flowlabel (net, skb, fl6->flowlabel, true, fl6)); +ip6_make_flowlabel (net, skb, fl6->flowlabel, true, fl6,0 )); ipv6h->hop_limit = hop_limit; ipv6h->nexthdr = proto; ipv6h->saddr = fl6->saddr;
net/ipv6/tcp_ipv6.c +17 -1
@@ -891,6 +891,8 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)struct sock *sk1 =NULL ;#endif int oif; +u8 tclass =0 ; +__be32 flowlabel =0 ;if (th->rst)return ;
@@ -939,7 +941,21 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) (th->doff <<2 ); oif = sk ? sk->sk_bound_dev_if :0 ; -tcp_v6_send_response (sk, skb, seq, ack_seq,0 ,0 ,0 , oif, key,1 ,0 ,0 ); +if (sk) { +if (sk_fullsock (sk)) { +struct ipv6_pinfo *np =inet6_sk (sk); + + tclass = np->tclass; + flowlabel = np->flow_label &IPV6_FLOWLABEL_MASK ; + }else { +struct inet_timewait_sock *tw =inet_twsk (sk); + + tclass = tw->tw_tclass; + flowlabel =cpu_to_be32 (tw->tw_flowlabel); + } + } +tcp_v6_send_response (sk, skb, seq, ack_seq,0 ,0 ,0 , oif, key,1 , + tclass, flowlabel);#ifdef CONFIG_TCP_MD5SIG out:
Signature · 1 line
2.9.3
Re: [PATCH V4 net 2/2] net: fix tcp reset packet flowlabel for ipv6
Quoted 11 lines · Shaohua Li
static inline
__be32ip6_make_flowlabel(struct net *net, structsk_buff*skb,
__be32flowlabel, bool autolabel,include/net/ipv6.h +1
-3- struct flowi6 *fl6) + struct flowi6 *fl6, u32 hash) { -u32 hash; -/* @flowlabel may include more than a flow label, eg, the traffic class. * Here we want only the flow label value. */
include/net/ipv6.h static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, · line 790
Quoted 6 lines
include/net/ipv6.h +2
-1@@ -788,7 +786,8 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, net->ipv6.sysctl.auto_flowlabels != IP6_AUTO_FLOW_LABEL_FORCED))return flowlabel; - hash =skb_get_hash_flowi6 (skb, fl6); +if (skb) + hash =skb_get_hash_flowi6 (skb, fl6);
Why not just move skb_get_hash_flowi6() to its caller? This check is not necessary. If you don't want to touch existing callers, you can just introduce a wrapper:
static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
__be32 flowlabel, bool autolabel, struct flowi6 *fl6)
{
u32 hash = skb_get_hash_flowi6(skb, fl6);
return __ip6_make_flowlabel(net, flowlabel, autolabel, hash);
}
And your code can just call:
__ip6_make_flowlabel(net, flowlabel, autolabel, sk->sk_txhash);
Re: [PATCH V4 net 2/2] net: fix tcp reset packet flowlabel for ipv6
Quoted 25 lines · Cong Wang
Quoted 11 lines · Shaohua Li
static inline
__be32ip6_make_flowlabel(struct net *net, structsk_buff*skb,
__be32flowlabel, bool autolabel,include/net/ipv6.h +1
-3- struct flowi6 *fl6) + struct flowi6 *fl6, u32 hash) { -u32 hash; -/* @flowlabel may include more than a flow label, eg, the traffic class. * Here we want only the flow label value. */ include/net/ipv6.h static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, · line 790
Quoted 6 lines
include/net/ipv6.h +2
-1@@ -788,7 +786,8 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, net->ipv6.sysctl.auto_flowlabels != IP6_AUTO_FLOW_LABEL_FORCED))return flowlabel; - hash =skb_get_hash_flowi6 (skb, fl6); +if (skb) + hash =skb_get_hash_flowi6 (skb, fl6);Why not just move
skb_get_hash_flowi6()to its caller? This check is not necessary. If you don't want to touch existing callers, you can just introduce a wrapper:
Quoted 7 lines
static inline
__be32ip6_make_flowlabel(struct net *net, structsk_buff*skb,
__be32flowlabel, bool autolabel, struct flowi6 *fl6)
{
u32 hash =skb_get_hash_flowi6(skb, fl6);
return__ip6_make_flowlabel(net, flowlabel, autolabel, hash);
}
this will always call skb_get_hash_flowi6 for the fast path even auto flowlabel is disabled. I thought we should avoid this.
Quoted 4 lines
And your code can just call:
__ip6_make_flowlabel(net, flowlabel, autolabel, sk->sk_txhash);
Re: [PATCH V4 net 2/2] net: fix tcp reset packet flowlabel for ipv6
Quoted 34 lines · Shaohua Li
Quoted 25 lines · Cong Wang
Quoted 11 lines · Shaohua Li
static inline
__be32ip6_make_flowlabel(struct net *net, structsk_buff*skb,
__be32flowlabel, bool autolabel,(quoted diff) +1
-3- struct flowi6 *fl6) + struct flowi6 *fl6, u32 hash) { - u32 hash; - /* @flowlabel may include more than a flow label, eg, the traffic class. * Here we want only the flow label value. */Review static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, · line 790
Quoted 6 lines
(quoted diff) +2
-1@@ -788,7 +786,8 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, net->ipv6.sysctl.auto_flowlabels != IP6_AUTO_FLOW_LABEL_FORCED)) return flowlabel; - hash = skb_get_hash_flowi6(skb, fl6); + if (skb) + hash = skb_get_hash_flowi6(skb, fl6);Why not just move
skb_get_hash_flowi6()to its caller? This check is not necessary. If you don't want to touch existing callers, you can just introduce a wrapper:Quoted 7 lines
static inline
__be32ip6_make_flowlabel(struct net *net, structsk_buff*skb,
__be32flowlabel, bool autolabel, struct flowi6 *fl6)
{
u32 hash =skb_get_hash_flowi6(skb, fl6);
return__ip6_make_flowlabel(net, flowlabel, autolabel, hash);
}
Quoted 2 lines
this will always call
skb_get_hash_flowi6for the fast path even auto flowlabel is disabled. I thought we should avoid this.
Yeah, but you can move the check out too,
something like:
include/net/ipv6.h +0 -0
@@ -771,31 +771,22 @@ static inline void
iph_to_flow_copy_v6addrs(struct flow_keys *flow,
#define IP6_DEFAULT_AUTO_FLOW_LABELS IP6_AUTO_FLOW_LABEL_OPTOUT
-static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
- __be32 flowlabel, bool autolabel,
- struct flowi6 *fl6)
+static inline bool ip6_need_flowlabel(struct net *net, __be32 flowlabel, bool autolabel)
{
- u32 hash;
-
/* @flowlabel may include more than a flow label, eg, the traffic class.
* Here we want only the flow label value.
*/- flowlabel &= IPV6_FLOWLABEL_MASK;
-
- if (flowlabel ||
+ if ((flowlabel & IPV6_FLOWLABEL_MASK) ||
net->ipv6.sysctl.auto_flowlabels == IP6_AUTO_FLOW_LABEL_OFF ||
(!autolabel &&
net->ipv6.sysctl.auto_flowlabels != IP6_AUTO_FLOW_LABEL_FORCED))- return flowlabel;
-
- hash = skb_get_hash_flowi6(skb, fl6);
+ return false;
- /* Since this is being sent on the wire obfuscate hash a bit
- * to minimize possbility that any useful information to an - * attacker is leaked. Only lower 20 bits are relevant. - */
- rol32(hash, 16);
+ return true;
+}
+static inline __be32 __ip6_make_flowlabel(struct net *net, __be32 flowlabel, u32 hash)
+{
flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK;
if (net->ipv6.sysctl.flowlabel_state_ranges)
@@ -804,6 +795,19 @@ static inline __be32 ip6_make_flowlabel(struct
net *net, struct sk_buff *skb,
return flowlabel;}
+static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
+ __be32 flowlabel, bool autolabel,
+ struct flowi6 *fl6)
+{
+ u32 hash;
+
+ if (!ip6_need_flowlabel(net, flowlabel, autolabel))
+ return flowlabel & IPV6_FLOWLABEL_MASK;
+
+ hash = skb_get_hash_flowi6(skb, fl6);
+ return __ip6_make_flowlabel(net, flowlabel, hash);
+}
+
static inline int ip6_default_np_autolabel(struct net *net)
{
switch (net->ipv6.sysctl.auto_flowlabels) {Re: [PATCH V4 net 2/2] net: fix tcp reset packet flowlabel for ipv6
Quoted 35 lines · Cong Wang
Quoted 34 lines · Shaohua Li
Quoted 32 lines · Cong Wang
Quoted 11 lines · Shaohua Li
static inline
__be32ip6_make_flowlabel(struct net *net, structsk_buff*skb,
__be32flowlabel, bool autolabel,(quoted diff) +1
-3- struct flowi6 *fl6) + struct flowi6 *fl6, u32 hash) { - u32 hash; - /* @flowlabel may include more than a flow label, eg, the traffic class. * Here we want only the flow label value. */Review static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, · line 790
Quoted 6 lines
(quoted diff) +2
-1@@ -788,7 +786,8 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, net->ipv6.sysctl.auto_flowlabels != IP6_AUTO_FLOW_LABEL_FORCED)) return flowlabel; - hash = skb_get_hash_flowi6(skb, fl6); + if (skb) + hash = skb_get_hash_flowi6(skb, fl6);Why not just move
skb_get_hash_flowi6()to its caller? This check is not necessary. If you don't want to touch existing callers, you can just introduce a wrapper:static inline
__be32ip6_make_flowlabel(struct net *net, structsk_buff*skb,
__be32flowlabel, bool autolabel, struct flowi6 *fl6)
{
u32 hash =skb_get_hash_flowi6(skb, fl6);
return__ip6_make_flowlabel(net, flowlabel, autolabel, hash);
}
Quoted 5 lines
Quoted 2 lines
this will always call
skb_get_hash_flowi6for the fast path even auto flowlabel is disabled. I thought we should avoid this.Yeah, but you can move the check out too,
something like:
Is this really better? I don't see any point. I'd use my original patch other than this one. that said, there are just several lines of code, brutally 'abstract' them into a function doesn't make the code better.
Quoted 67 lines
include/net/ipv6.h +7
-16@@ -771,31 +771,22 @@ static inline void iph_to_flow_copy_v6addrs(struct flow_keys *flow,#define IP6_DEFAULT_AUTO_FLOW_LABELS IP6_AUTO_FLOW_LABEL_OPTOUT -static inline __be32 ip6_make_flowlabel (struct net *net,struct sk_buff *skb, -__be32 flowlabel,bool autolabel, -struct flowi6 *fl6) +static inline bool ip6_need_flowlabel (struct net *net,__be32 flowlabel,bool autolabel) { -u32 hash; -/* @flowlabel may include more than a flow label, eg, the traffic class. * Here we want only the flow label value. */ - flowlabel &=IPV6_FLOWLABEL_MASK ; - -if (flowlabel || +if ((flowlabel &IPV6_FLOWLABEL_MASK ) || net->ipv6.sysctl.auto_flowlabels ==IP6_AUTO_FLOW_LABEL_OFF || (!autolabel && net->ipv6.sysctl.auto_flowlabels !=IP6_AUTO_FLOW_LABEL_FORCED )) -return flowlabel; - - hash =skb_get_hash_flowi6 (skb, fl6); +return false; -/* Since this is being sent on the wire obfuscate hash a bit -* to minimize possbility that any useful information to an -* attacker is leaked. Only lower 20 bits are relevant. -*/ -rol32 (hash,16 ); +return true; +} +static inline __be32 __ip6_make_flowlabel (struct net *net,__be32 flowlabel,u32 hash) +{flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK; if (net->ipv6.sysctl.flowlabel_state_ranges)include/net/ipv6.h +13
-0@@ -804,6 +795,19 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, return flowlabel; } +static inline __be32 ip6_make_flowlabel (struct net *net,struct sk_buff *skb, +__be32 flowlabel,bool autolabel, +struct flowi6 *fl6) +{ +u32 hash; + +if (!ip6_need_flowlabel (net, flowlabel, autolabel)) +return flowlabel &IPV6_FLOWLABEL_MASK ; + + hash =skb_get_hash_flowi6 (skb, fl6); +return __ip6_make_flowlabel (net, flowlabel, hash); +} +static inline int ip6_default_np_autolabel (struct net *net) {switch (net->ipv6.sysctl.auto_flowlabels) {
Re: [PATCH V4 net 2/2] net: fix tcp reset packet flowlabel for ipv6
Quoted 3 lines · Shaohua Li
Is this really better? I don't see any point. I'd use my original patch other than this one. that said, there are just several lines of code, brutally 'abstract' them into a function doesn't make the code better.
The current ip6_make_flowlabel() is already a mess, with your change you just make it worse to read. I just want to make it suck less.
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0
Quoted 3 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.
Hi Dave,
Could you please look at the patches?
Thanks,
Shaohua
Quoted 19 lines
Thanks,
ShaohuaShaohua Li (2):
net: remove unnecessary rotation
net: fix tcp reset packet flowlabel for ipv6include/net/ipv6.h | 15 ++++----------- net/ipv4/tcp_minisocks.c | 8 +++++++- net/ipv6/ip6_gre.c | 2 +- net/ipv6/ip6_output.c | 4 ++-- net/ipv6/ip6_tunnel.c | 2 +- net/ipv6/tcp_ipv6.c | 18 +++++++++++++++++- 6 files changed, 32 insertions(+), 17 deletions(-)Signature · 1 line
2.9.3
David Miller
maintainerFrom: Shaohua Li <[email protected]>
Date: Wed, 9 Aug 2017 07:59:53 -0700
Quoted 1 line
Could you please look at the patches?
If you actually looked in patchwork, the state of your patches is "changes requested".
This means that you were given feedback asking to change something about your patches, which means that a new submission is expected.
I think Cong Wang's function movement request is legitimate, so please do it.
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0
Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.
Shaohua,
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
Another consideration is that sk_txhash is also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might need sk_txhash saved also.
Tom
Quoted 18 lines
Thanks,
ShaohuaShaohua Li (2):
net: remove unnecessary rotation
net: fix tcp reset packet flowlabel for ipv6include/net/ipv6.h | 15 ++++----------- net/ipv4/tcp_minisocks.c | 8 +++++++- net/ipv6/ip6_gre.c | 2 +- net/ipv6/ip6_output.c | 4 ++-- net/ipv6/ip6_tunnel.c | 2 +- net/ipv6/tcp_ipv6.c | 18 +++++++++++++++++- 6 files changed, 32 insertions(+), 17 deletions(-)--
2.9.3
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.
As far as I understood, we don't use sk_txhash for routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel from skb->hash (which is from sk_txhash). The code always does routing selection first and then uses ip6_make_flowlabel to build packet data where we derive flowlabel from skb->hash.
Thanks,
Shaohua
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.
Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need tx_hash and make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to move tx_hash in skc_common so that it's available in TW state for this purpose. Then when moving to TW state just copy the tx_hash.
Tom
Quoted 2 lines
Thanks,
Shaohua
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.
Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.
Hi Tom,
My original implementation is to add a tx_hash in tw sock, we then copy sock's tx_hash to the tw tx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we move tx_hash to skc_common, all sock size will increase, is this acceptable?
Thanks,
Shaohua
Quoted 58 lines · Shaohua Li
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.
Quoted 6 lines
Hi Tom,
My original implementation is to add a
tx_hashin tw sock, we then copy sock'stx_hashto the twtx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we movetx_hashtoskc_common, all sock size will increase, is this acceptable?
I think that can only be measured by how critical it is to persistently route all packets the same exact way for every connection. Page one of the IP book clearly states that IP packets can be dropped, duplicated, or received out of order. Received OOO implies that packet for the same flow are allowed to take different paths. The requirement that packets for the same flow must always take the same path through the network was created by stateful middleboxes-- it's not inherent in the architecture of IP networking. Unfortunately, we're seeing this become more and more of a problem as more devices are multi-homed (like smart phones) and these network requirement cripple our ability to take advantage of features like that.
Personally, I wish the middleboxes fix the problem they created, but I suppose we need to be pragmatic at least in the short term.
Tom
Quoted 2 lines
Thanks,
Shaohua
Quoted 78 lines · Tom Herbert
Quoted 58 lines · Shaohua Li
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.Quoted 6 lines
Hi Tom,
My original implementation is to add a
tx_hashin tw sock, we then copy sock'stx_hashto the twtx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we movetx_hashtoskc_common, all sock size will increase, is this acceptable?I think that can only be measured by how critical it is to persistently route all packets the same exact way for every connection. Page one of the IP book clearly states that IP packets can be dropped, duplicated, or received out of order. Received OOO implies that packet for the same flow are allowed to take different paths. The requirement that packets for the same flow must always take the same path through the network was created by stateful middleboxes-- it's not inherent in the architecture of IP networking. Unfortunately, we're seeing this become more and more of a problem as more devices are multi-homed (like smart phones) and these network requirement cripple our ability to take advantage of features like that.
Quoted 2 lines
Personally, I wish the middleboxes fix the problem they created, but I suppose we need to be pragmatic at least in the short term.
Hmm, I still hesitate to add a new field in skc_common. Fixing current problem looks propriate in current stage. I'd defer fixing the generic issue till it's necessary.
Thanks,
Shaohua
Quoted 79 lines · Shaohua Li
Quoted 78 lines · Tom Herbert
Quoted 58 lines · Shaohua Li
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.Quoted 6 lines
Hi Tom,
My original implementation is to add a
tx_hashin tw sock, we then copy sock'stx_hashto the twtx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we movetx_hashtoskc_common, all sock size will increase, is this acceptable?I think that can only be measured by how critical it is to persistently route all packets the same exact way for every connection. Page one of the IP book clearly states that IP packets can be dropped, duplicated, or received out of order. Received OOO implies that packet for the same flow are allowed to take different paths. The requirement that packets for the same flow must always take the same path through the network was created by stateful middleboxes-- it's not inherent in the architecture of IP networking. Unfortunately, we're seeing this become more and more of a problem as more devices are multi-homed (like smart phones) and these network requirement cripple our ability to take advantage of features like that.
Quoted 7 lines
Quoted 2 lines
Personally, I wish the middleboxes fix the problem they created, but I suppose we need to be pragmatic at least in the short term.
Hmm, I still hesitate to add a new field in
skc_common. Fixing current problem looks propriate in current stage. I'd defer fixing the generic issue till it's necessary.
Shaohua,
An alternative would be to not initialize sk_txhash, but instead defer hash computation to use flow dissector in the TX path when the hash is needed (to get flow label, src port for UDP encap, route for multipath, etc.). At the first hash computation in TX path the result in sk_txhash. In TW state there is no socket so flow dissector is always used but that should yield the same hash. No extra fields would be needed and additional cost is negligible.
Tom
Quoted 2 lines
Thanks,
Shaohua
Quoted 89 lines · Tom Herbert
Quoted 79 lines · Shaohua Li
Quoted 78 lines · Tom Herbert
Quoted 58 lines · Shaohua Li
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.Quoted 6 lines
Hi Tom,
My original implementation is to add a
tx_hashin tw sock, we then copy sock'stx_hashto the twtx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we movetx_hashtoskc_common, all sock size will increase, is this acceptable?I think that can only be measured by how critical it is to persistently route all packets the same exact way for every connection. Page one of the IP book clearly states that IP packets can be dropped, duplicated, or received out of order. Received OOO implies that packet for the same flow are allowed to take different paths. The requirement that packets for the same flow must always take the same path through the network was created by stateful middleboxes-- it's not inherent in the architecture of IP networking. Unfortunately, we're seeing this become more and more of a problem as more devices are multi-homed (like smart phones) and these network requirement cripple our ability to take advantage of features like that.
Quoted 7 lines
Quoted 2 lines
Personally, I wish the middleboxes fix the problem they created, but I suppose we need to be pragmatic at least in the short term.
Hmm, I still hesitate to add a new field in
skc_common. Fixing current problem looks propriate in current stage. I'd defer fixing the generic issue till it's necessary.Shaohua,
Quoted 7 lines
An alternative would be to not initialize
sk_txhash, but instead defer hash computation to use flow dissector in the TX path when the hash is needed (to get flow label, src port for UDP encap, route for multipath, etc.). At the first hash computation in TX path the result insk_txhash. In TW state there is no socket so flow dissector is always used but that should yield the same hash. No extra fields would be needed and additional cost is negligible.
Hi Tom,
Did you mean revert 877d1f6291f8(net: Set sk_txhash from a random number)? This could fix the issue. So in normal case we calculate the sk_txhash using flow dissector but in negative routing case we use the random hash, is this what you want?
There seems to have other bug in this side. From my understanding, commit 265f94ff54d6(net: Recompute sk_txhash on negative routing advice) tries to select a different route. But the multipath selection code (rt6_multipath_select) doesn't use sk_txhash or skb->hash, it does use fl6.flowlabel, but that is the flowlabel user sets. So looks like the commit doesn't change anything.
What's the 'src port for UDP encap'? I can't find the code setting skb->hash to sk_txhash in UDP side.
Thanks,
Shaohua
Quoted 98 lines · Shaohua Li
Quoted 89 lines · Tom Herbert
Quoted 79 lines · Shaohua Li
Quoted 78 lines · Tom Herbert
Quoted 58 lines · Shaohua Li
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.Quoted 6 lines
Hi Tom,
My original implementation is to add a
tx_hashin tw sock, we then copy sock'stx_hashto the twtx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we movetx_hashtoskc_common, all sock size will increase, is this acceptable?I think that can only be measured by how critical it is to persistently route all packets the same exact way for every connection. Page one of the IP book clearly states that IP packets can be dropped, duplicated, or received out of order. Received OOO implies that packet for the same flow are allowed to take different paths. The requirement that packets for the same flow must always take the same path through the network was created by stateful middleboxes-- it's not inherent in the architecture of IP networking. Unfortunately, we're seeing this become more and more of a problem as more devices are multi-homed (like smart phones) and these network requirement cripple our ability to take advantage of features like that.
Quoted 7 lines
Quoted 2 lines
Personally, I wish the middleboxes fix the problem they created, but I suppose we need to be pragmatic at least in the short term.
Hmm, I still hesitate to add a new field in
skc_common. Fixing current problem looks propriate in current stage. I'd defer fixing the generic issue till it's necessary.Shaohua,
Quoted 7 lines
An alternative would be to not initialize
sk_txhash, but instead defer hash computation to use flow dissector in the TX path when the hash is needed (to get flow label, src port for UDP encap, route for multipath, etc.). At the first hash computation in TX path the result insk_txhash. TW state there is no socket so flow dissector is always used but that should yield the same hash. No extra fields would be needed and additional cost is negligible.
Quoted 7 lines
Hi Tom,
Did you mean revert 877d1f6291f8(net: Set
sk_txhashfrom a random number)? This could fix the issue. So in normal case we calculate thesk_txhashusing flow dissector but in negative routing case we use the random hash, is this what you want?
No. What you'd want is something like a sysctl that sets an alternate mode for sk_txhash processing. sk_txhash is derived from flow dissector for the first TX packet and then it's never allowed to change. Maybe this should be called persistent-hash mode.
Quoted 7 lines
There seems to have other bug in this side. From my understanding, commit 265f94ff54d6(net: Recompute
sk_txhashon negative routing advice) tries to select a different route. But the multipath selection code (rt6_multipath_select) doesn't usesk_txhashorskb->hash, it does use fl6.flowlabel, but that is the flowlabel user sets. So looks like the commit doesn't change anything.
The routing functions typically don't use sock of skbuff, but use flow structs instead. It may be reasonable to add a hash to those.
Quoted 3 lines
What's the 'src port for UDP encap'? I can't find the code setting
skb->hashtosk_txhashin UDP side.
udp_flow_src_port is function call by UDP encaps to set source port. This is call skb_get_hash. sk_set_txhash is function to set txhash right now to random value. skb_set_hash_from_sk set skb->hash when skbuff is owned by socket (skb_set_owner_w).
Thanks,
Tom
Quoted 2 lines
Thanks,
Shaohua
Quoted 106 lines · Tom Herbert
Quoted 98 lines · Shaohua Li
Quoted 89 lines · Tom Herbert
Quoted 79 lines · Shaohua Li
Quoted 78 lines · Tom Herbert
Quoted 58 lines · Shaohua Li
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.Quoted 6 lines
Hi Tom,
My original implementation is to add a
tx_hashin tw sock, we then copy sock'stx_hashto the twtx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we movetx_hashtoskc_common, all sock size will increase, is this acceptable?I think that can only be measured by how critical it is to persistently route all packets the same exact way for every connection. Page one of the IP book clearly states that IP packets can be dropped, duplicated, or received out of order. Received OOO implies that packet for the same flow are allowed to take different paths. The requirement that packets for the same flow must always take the same path through the network was created by stateful middleboxes-- it's not inherent in the architecture of IP networking. Unfortunately, we're seeing this become more and more of a problem as more devices are multi-homed (like smart phones) and these network requirement cripple our ability to take advantage of features like that.
Quoted 7 lines
Quoted 2 lines
Personally, I wish the middleboxes fix the problem they created, but I suppose we need to be pragmatic at least in the short term.
Hmm, I still hesitate to add a new field in
skc_common. Fixing current problem looks propriate in current stage. I'd defer fixing the generic issue till it's necessary.Shaohua,
Quoted 7 lines
An alternative would be to not initialize
sk_txhash, but instead defer hash computation to use flow dissector in the TX path when the hash is needed (to get flow label, src port for UDP encap, route for multipath, etc.). At the first hash computation in TX path the result insk_txhash. TW state there is no socket so flow dissector is always used but that should yield the same hash. No extra fields would be needed and additional cost is negligible.Quoted 7 lines
Hi Tom,
Did you mean revert 877d1f6291f8(net: Set
sk_txhashfrom a random number)? This could fix the issue. So in normal case we calculate thesk_txhashusing flow dissector but in negative routing case we use the random hash, is this what you want?
Quoted 4 lines
No. What you'd want is something like a sysctl that sets an alternate mode for
sk_txhashprocessing.sk_txhashis derived from flow dissector for the first TX packet and then it's never allowed to change. Maybe this should be called persistent-hash mode.
persistent-hash will almostly mean disabling auto flowlabel. We'd prefer disabling auto flowlabel rather than the persistent-hash. But I think we do want to use the auto flowlabel for load balancing, so the persistent-hash isn't a go for us.
Let's take the other way. Your main concern is the multipath selection. I think this can be fixed. We can still use the tw->tw_flowlabel to store the auto created flowlabel like what my patch does, but we use an extra bit in tw_pad of inet_timewait_sock to indicate this flowlabel is auto created. In the reset packet send path, we don't use the auto created flowlabel for route slection, but just for packet data. This will keep current multipath selection behavior and fix the reset packet flowlabel issue.
Quoted 9 lines
Quoted 7 lines
There seems to have other bug in this side. From my understanding, commit 265f94ff54d6(net: Recompute
sk_txhashon negative routing advice) tries to select a different route. But the multipath selection code (rt6_multipath_select) doesn't usesk_txhashorskb->hash, it does use fl6.flowlabel, but that is the flowlabel user sets. So looks like the commit doesn't change anything.The routing functions typically don't use sock of skbuff, but use flow structs instead. It may be reasonable to add a hash to those.
I'll look at this issue later. It's not related to current flowlabel problem.
Thanks,
Shaohua
Quoted 112 lines · Shaohua Li
Quoted 106 lines · Tom Herbert
Quoted 98 lines · Shaohua Li
Quoted 89 lines · Tom Herbert
Quoted 79 lines · Shaohua Li
Quoted 78 lines · Tom Herbert
Quoted 58 lines · Shaohua Li
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.Quoted 6 lines
Hi Tom,
My original implementation is to add a
tx_hashin tw sock, we then copy sock'stx_hashto the twtx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we movetx_hashtoskc_common, all sock size will increase, is this acceptable?I think that can only be measured by how critical it is to persistently route all packets the same exact way for every connection. Page one of the IP book clearly states that IP packets can be dropped, duplicated, or received out of order. Received OOO implies that packet for the same flow are allowed to take different paths. The requirement that packets for the same flow must always take the same path through the network was created by stateful middleboxes-- it's not inherent in the architecture of IP networking. Unfortunately, we're seeing this become more and more of a problem as more devices are multi-homed (like smart phones) and these network requirement cripple our ability to take advantage of features like that.
Quoted 7 lines
Quoted 2 lines
Personally, I wish the middleboxes fix the problem they created, but I suppose we need to be pragmatic at least in the short term.
Hmm, I still hesitate to add a new field in
skc_common. Fixing current problem looks propriate in current stage. I'd defer fixing the generic issue till it's necessary.Shaohua,
Quoted 7 lines
An alternative would be to not initialize
sk_txhash, but instead defer hash computation to use flow dissector in the TX path when the hash is needed (to get flow label, src port for UDP encap, route for multipath, etc.). At the first hash computation in TX path the result insk_txhash. TW state there is no socket so flow dissector is always used but that should yield the same hash. No extra fields would be needed and additional cost is negligible.Quoted 7 lines
Hi Tom,
Did you mean revert 877d1f6291f8(net: Set
sk_txhashfrom a random number)? This could fix the issue. So in normal case we calculate thesk_txhashusing flow dissector but in negative routing case we use the random hash, is this what you want?Quoted 4 lines
No. What you'd want is something like a sysctl that sets an alternate mode for
sk_txhashprocessing.sk_txhashis derived from flow dissector for the first TX packet and then it's never allowed to change. Maybe this should be called persistent-hash mode.
Quoted 5 lines
persistent-hash will almostly mean disabling auto flowlabel. We'd prefer disabling auto flowlabel rather than the persistent-hash. But I think we do want to use the auto flowlabel for load balancing, so the persistent-hash isn't a go for us.
Those are two separate features here. Auto flow label means automatically generating flow labels for packets based on some hash. A persistent hash means that once a hash is determined for a connection it never changes, so the flow label derived from the hash never changes.
Quoted 15 lines
Let's take the other way. Your main concern is the multipath selection. I think this can be fixed. We can still use the
tw->tw_flowlabelto store the auto created flowlabel like what my patch does, but we use an extra bit intw_padofinet_timewait_sockto indicate this flowlabel is auto created. In the reset packet send path, we don't use the auto created flowlabel for route slection, but just for packet data. This will keep current multipath selection behavior and fix the reset packet flowlabel issue.Quoted 7 lines
Quoted 7 lines
There seems to have other bug in this side. From my understanding, commit 265f94ff54d6(net: Recompute
sk_txhashon negative routing advice) tries to select a different route. But the multipath selection code (rt6_multipath_select) doesn't usesk_txhashorskb->hash, it does use fl6.flowlabel, but that is the flowlabel user sets. So looks like the commit doesn't change anything.
Quoted 5 lines
Quoted 2 lines
The routing functions typically don't use sock of skbuff, but use flow structs instead. It may be reasonable to add a hash to those.
I'll look at this issue later. It's not related to current flowlabel problem.
As I mentioned already, this is not a problem specific to flowlabels. This is a problem about getting all the elements of the system work together to ensure that all packets of flow are routed they same way in order to meet a requirement imposed by middleboxes. You can solve this problem just to make flow labels work, but IMO that's just kicking the can down the road for someone else to have to debug and solve when they hit the same underlying issue but in a different context.
Tom
Quoted 106 lines · Tom Herbert
Quoted 98 lines · Shaohua Li
Quoted 89 lines · Tom Herbert
Quoted 79 lines · Shaohua Li
Quoted 78 lines · Tom Herbert
Quoted 58 lines · Shaohua Li
Quoted 47 lines · Tom Herbert
Quoted 40 lines · Shaohua Li
Quoted 22 lines · Tom Herbert
Quoted 15 lines · Shaohua Li
From: Shaohua Li <[email protected]>
Please see below tcpdump output:
21:00:48.109122 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [S], cksum0x0529(incorrect ->0xf56c), seq 3282214508, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 0,nop,wscale 7], length 0 21:00:48.109381 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 40) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [S.], cksum0x0529(incorrect ->0x49ad), seq 1923801573, ack 3282214509, win 43690, options [mss 65476,sackOK,TS val 2500903437 ecr 2500903437,nop,wscale 7], length 0 21:00:48.109548 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1bdf), seq 1, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.109823 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 62) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x053f(incorrect ->0xb8b1), seq 1:31, ack 1, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 30 21:00:48.109910 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [.], cksum0x0521(incorrect ->0x1bc1), seq 1, ack 31, win 342, options [nop,nop,TS val 2500903437 ecr 2500903437], length 0 21:00:48.110043 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [P.], cksum0x0539(incorrect ->0xb726), seq 1:25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 24 21:00:48.110173 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba7), seq 31, ack 25, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:48.110211 IP6 (flowlabel0xd827f, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [F.], cksum0x0521(incorrect ->0x1ba7), seq 25, ack 31, win 342, options [nop,nop,TS val 2500903438 ecr 2500903437], length 0 21:00:48.151099 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 32) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [.], cksum0x0521(incorrect ->0x1ba6), seq 31, ack 26, win 342, options [nop,nop,TS val 2500903438 ecr 2500903438], length 0 21:00:49.110524 IP6 (flowlabel0x43304, hlim 64, next-header TCP (6) payload length: 56) fec0::5054:ff:fe12:3456.55804 > fec0::5054:ff:fe12:3456.5555: Flags [P.], cksum0x0539(incorrect ->0xb324), seq 31:55, ack 26, win 342, options [nop,nop,TS val 2500904438 ecr 2500903438], length 24 21:00:49.110637 IP6 (flowlabel0xb34d5, hlim 64, next-header TCP (6) payload length: 20) fec0::5054:ff:fe12:3456.5555 > fec0::5054:ff:fe12:3456.55804: Flags [R], cksum0x0515(incorrect ->0x668c), seq 1923801599, win 0, length 0Quoted 4 lines
The flowlabel of reset packet (
0xb34d5) and flowlabel of normal packet (0xd827f) are different. This causes our router doesn't correctly close tcp connection. The patches try to fix the issue.Shaohua,
Quoted 9 lines
Can you give some more detail about what the router doesn't close the TCP connection means? I'm guessing the problem is either: 1) the router is maintaining connection state that includes the flow label in a connection tuple. 2) some router in the path is maintaining connection state, but when the flow label changes the flow's packet are routed through a different router that doesn't have a state for the flow it drops the packet. #1 should be easily fix in the router, flow labels cannot be used as state. #2 is the known problem that stateful firewalls have killed our ability to use multihoming.
The #2 is exactly the problem we saw.
Quoted 4 lines
Another consideration is that
sk_txhashis also used in routing decisions by the local host (flow label is normally derived from txhash). If you want to ensure that connections are routed consistently for timewait state you might needsk_txhashsaved also.Quoted 6 lines
As far as I understood, we don't use
sk_txhashfor routing selection. The code does routing selection with flowlabel user configured, at that time we don't derive fl6.flowlabel fromskb->hash(which is fromsk_txhash). The code always does routing selection first and then usesip6_make_flowlabelto build packet data where we derive flowlabel fromskb->hash.Quoted 9 lines
That is assuming one particular use case. Generally, if you want to ensure all packets for a flow take the same path you'll need
tx_hashand make it persistent (disable flow bender). For instance, if you were doing UDP encapsulation like in VXLAN the UDP source port selection is unaffected by saved flow label for the lifetime of the flow. So we would still hit #2 in that case and the stateful device doesn't see whole flow. It might be just as easy to movetx_hashinskc_commonso that it's available in TW state for this purpose. Then when moving to TW state just copy thetx_hash.Quoted 6 lines
Hi Tom,
My original implementation is to add a
tx_hashin tw sock, we then copy sock'stx_hashto the twtx_hash. This does makes things simplier. One concern from Eric is this will increase the size of tw sock. If we movetx_hashtoskc_common, all sock size will increase, is this acceptable?I think that can only be measured by how critical it is to persistently route all packets the same exact way for every connection. Page one of the IP book clearly states that IP packets can be dropped, duplicated, or received out of order. Received OOO implies that packet for the same flow are allowed to take different paths. The requirement that packets for the same flow must always take the same path through the network was created by stateful middleboxes-- it's not inherent in the architecture of IP networking. Unfortunately, we're seeing this become more and more of a problem as more devices are multi-homed (like smart phones) and these network requirement cripple our ability to take advantage of features like that.
Quoted 7 lines
Quoted 2 lines
Personally, I wish the middleboxes fix the problem they created, but I suppose we need to be pragmatic at least in the short term.
Hmm, I still hesitate to add a new field in
skc_common. Fixing current problem looks propriate in current stage. I'd defer fixing the generic issue till it's necessary.Shaohua,
Quoted 7 lines
An alternative would be to not initialize
sk_txhash, but instead defer hash computation to use flow dissector in the TX path when the hash is needed (to get flow label, src port for UDP encap, route for multipath, etc.). At the first hash computation in TX path the result insk_txhash. TW state there is no socket so flow dissector is always used but that should yield the same hash. No extra fields would be needed and additional cost is negligible.Quoted 7 lines
Hi Tom,
Did you mean revert 877d1f6291f8(net: Set
sk_txhashfrom a random number)? This could fix the issue. So in normal case we calculate thesk_txhashusing flow dissector but in negative routing case we use the random hash, is this what you want?
Quoted 4 lines
No. What you'd want is something like a sysctl that sets an alternate mode for
sk_txhashprocessing.sk_txhashis derived from flow dissector for the first TX packet and then it's never allowed to change. Maybe this should be called persistent-hash mode.
Hi Tom,
We had been using the auto_flowlabels=1 (i.e. essentially enable flowlabel) mainly because we want to take the benefit of dst_negative_advice() when tcp_write_timeout() happens.
During our test, our system handles quite well with changing flowlabel. The only exception we have hit is the TCP_RST sent from an inet_timewait_sock.
If we keep the flowlabel consistent (or persistent sk_txhash), there is no practical usage for us to turn on flowlabel and the problem also goes away. We have it off for now.
Quoted 10 lines
Quoted 8 lines
There seems to have other bug in this side. From my understanding, commit 265f94ff54d6(net: Recompute
sk_txhashon negative routing advice) tries to select a different route. But the multipath selection code (rt6_multipath_select) doesn't usesk_txhashorskb->hash, it does use fl6.flowlabel, but that is the flowlabel user sets. So looks like the commit doesn't change anything.The routing functions typically don't use sock of skbuff, but use flow structs instead. It may be reasonable to add a hash to those.
The localhost's mutlipath selection is another existing issue. AFAICT, it does not take the sk_txhash (or skb->hash) into account and the following dst_negative_advice() will also have no effect in the route selction. It is another issue to be fixed and to be figured out how to pass the sk_txhash down. (1)
Shaohua is proposing to record the 20 bits of the sk_txhash in the tw_flowlabel of the 'struct inet_timewait_sock'. The tw_flowlabel could potentially be used to do the multipath selection once we figured out how to tackle (1).
Thanks,
Martin
Quoted 15 lines
Quoted 4 lines
What's the 'src port for UDP encap'? I can't find the code setting
skb->hashtosk_txhashin UDP side.
udp_flow_src_portis function call by UDP encaps to set source port. This is callskb_get_hash.sk_set_txhashis function to set txhash right now to random value.skb_set_hash_from_sksetskb->hashwhen skbuff is owned by socket (skb_set_owner_w).Thanks,
TomQuoted 2 lines
Thanks,
Shaohua
Quoted 7 lines
We had been using the auto_flowlabels=1 (i.e. essentially enable flowlabel) mainly because we want to take the benefit of
dst_negative_advice()whentcp_write_timeout()happens.During our test, our system handles quite well with changing flowlabel. The only exception we have hit is the
TCP_RSTsent from aninet_timewait_sock.
Martin,
That is interesting data. Have you determined why the middlebox has a problem with flow label change in TW state but not other states?
Tom
Quoted 44 lines
If we keep the flowlabel consistent (or persistent
sk_txhash), there is no practical usage for us to turn on flowlabel and the problem also goes away. We have it off for now.Quoted 10 lines
Quoted 8 lines
There seems to have other bug in this side. From my understanding, commit 265f94ff54d6(net: Recompute
sk_txhashon negative routing advice) tries to select a different route. But the multipath selection code (rt6_multipath_select) doesn't usesk_txhashorskb->hash, it does use fl6.flowlabel, but that is the flowlabel user sets. So looks like the commit doesn't change anything.The routing functions typically don't use sock of skbuff, but use flow structs instead. It may be reasonable to add a hash to those.
The localhost's mutlipath selection is another existing issue. AFAICT, it does not take the
sk_txhash(orskb->hash) into account and the followingdst_negative_advice()will also have no effect in the route selction. It is another issue to be fixed and to be figured out how to pass thesk_txhashdown. (1)Shaohua is proposing to record the 20 bits of the
sk_txhashin thetw_flowlabelof the 'structinet_timewait_sock'. Thetw_flowlabelcould potentially be used to do the multipath selection once we figured out how to tackle (1).Thanks,
MartinQuoted 15 lines
Quoted 4 lines
What's the 'src port for UDP encap'? I can't find the code setting
skb->hashtosk_txhashin UDP side.
udp_flow_src_portis function call by UDP encaps to set source port. This is callskb_get_hash.sk_set_txhashis function to set txhash right now to random value.skb_set_hash_from_sksetskb->hashwhen skbuff is owned by socket (skb_set_owner_w).Thanks,
TomQuoted 2 lines
Thanks,
Shaohua
Quoted 11 lines · Tom Herbert
Quoted 7 lines
We had been using the auto_flowlabels=1 (i.e. essentially enable flowlabel) mainly because we want to take the benefit of
dst_negative_advice()whentcp_write_timeout()happens.During our test, our system handles quite well with changing flowlabel. The only exception we have hit is the
TCP_RSTsent from aninet_timewait_sock.Martin,
That is interesting data. Have you determined why the middlebox has a problem with flow label change in TW state but not other states?
Tom,
The problem of this middle box is specific to TCP_RST with a different flowlabel from its previous packets. Sending TCP_RST from TW state hits this pain point.
It seems like that middle box specifically drops TCP_RST if it does not know anything about this flow. Since the flowlabel of the TCP_RST (sent in TW state) is always different, it always lands to a different middle box. All of these TCP_RST cannot be delivered.
We are resilience to a small number of TCP_RST drop. However, this guarantee flowlabel change on TCP_RST and then dropped is too much.
This flowlabel change does not look like intentional either when transitioning from full sk to tw sk (tw->tw_flowlabel is inheriting the np->flow_label in tcp_time_wait()). Currently, the tw_flowlabel is used in tcp_v6_timewait_ack() but not in tcp_v6_send_reset(). Hence, shaohua is looking for a solution to solve them together.
Thanks,
Martin
Quoted 47 lines
Tom
Quoted 44 lines
If we keep the flowlabel consistent (or persistent
sk_txhash), there is no practical usage for us to turn on flowlabel and the problem also goes away. We have it off for now.Quoted 10 lines
Quoted 8 lines
There seems to have other bug in this side. From my understanding, commit 265f94ff54d6(net: Recompute
sk_txhashon negative routing advice) tries to select a different route. But the multipath selection code (rt6_multipath_select) doesn't usesk_txhashorskb->hash, it does use fl6.flowlabel, but that is the flowlabel user sets. So looks like the commit doesn't change anything.The routing functions typically don't use sock of skbuff, but use flow structs instead. It may be reasonable to add a hash to those.
The localhost's mutlipath selection is another existing issue. AFAICT, it does not take the
sk_txhash(orskb->hash) into account and the followingdst_negative_advice()will also have no effect in the route selction. It is another issue to be fixed and to be figured out how to pass thesk_txhashdown. (1)Shaohua is proposing to record the 20 bits of the
sk_txhashin thetw_flowlabelof the 'structinet_timewait_sock'. Thetw_flowlabelcould potentially be used to do the multipath selection once we figured out how to tackle (1).Thanks,
MartinQuoted 15 lines
Quoted 4 lines
What's the 'src port for UDP encap'? I can't find the code setting
skb->hashtosk_txhashin UDP side.
udp_flow_src_portis function call by UDP encaps to set source port. This is callskb_get_hash.sk_set_txhashis function to set txhash right now to random value.skb_set_hash_from_sksetskb->hashwhen skbuff is owned by socket (skb_set_owner_w).Thanks,
TomQuoted 2 lines
Thanks,
Shaohua
David Miller
maintainerFrom: Martin KaFai Lau <[email protected]>
Date: Fri, 18 Aug 2017 13:51:36 -0700
Quoted 4 lines
It seems like that middle box specifically drops
TCP_RSTif it does not know anything about this flow. Since the flowlabel of theTCP_RST(sent in TW state) is always different, it always lands to a different middle box. All of theseTCP_RSTcannot be delivered.
This really is illegal behavior. The flow label is not a flow _KEY_ by any definition whatsoever.
Flow labels are an optimization, not a determinant for flow matching particularly for proper TCP state processing.
I'd rather you invest all of this energy getting that vendor to fix their kit.
Thank you.
Quoted 8 lines · David Miller
From: Martin KaFai Lau <[email protected]>
Date: Fri, 18 Aug 2017 13:51:36 -0700Quoted 4 lines
It seems like that middle box specifically drops
TCP_RSTif it does not know anything about this flow. Since the flowlabel of theTCP_RST(sent in TW state) is always different, it always lands to a different middle box. All of theseTCP_RSTcannot be delivered.
Quoted 9 lines
This really is illegal behavior. The flow label is not a flow _KEY_ by any definition whatsoever.
Flow labels are an optimization, not a determinant for flow matching particularly for proper TCP state processing.
I'd rather you invest all of this energy getting that vendor to fix their kit.
We're now seeing several router vendors recommending people to not use flow labels for ECMP hashing. This is precisely because when a flow label changes, network devices that maintain state (firewalls, NAT, load balancers) can't deal with packets being rerouted so connections are dropped. Unfortunately, the need for packets of a flow to always follow the same path has become an implicit requirement that I think we need follow at least as the default behavior.
Martin: is there any change you could resurrect these patches? In order to solve the general problem of making routing consistent, I believe we want to keep sk_tx_hash consistent for the connection from which a consistent flow label can be derived. To avoid the overhead of a hash field in sk_common, maybe we could initially set a connection hash to a five-tuple hash for a flow instead of a random value? So in TW state the consistent hash can be computed on the fly.
Tom
Quoted 26 lines · Tom Herbert
Quoted 8 lines · David Miller
From: Martin KaFai Lau <[email protected]>
Date: Fri, 18 Aug 2017 13:51:36 -0700Quoted 4 lines
It seems like that middle box specifically drops
TCP_RSTif it does not know anything about this flow. Since the flowlabel of theTCP_RST(sent in TW state) is always different, it always lands to a different middle box. All of theseTCP_RSTcannot be delivered.Quoted 9 lines
This really is illegal behavior. The flow label is not a flow _KEY_ by any definition whatsoever.
Flow labels are an optimization, not a determinant for flow matching particularly for proper TCP state processing.
I'd rather you invest all of this energy getting that vendor to fix their kit.
We're now seeing several router vendors recommending people to not use flow labels for ECMP hashing. This is precisely because when a flow label changes, network devices that maintain state (firewalls, NAT, load balancers) can't deal with packets being rerouted so connections are dropped. Unfortunately, the need for packets of a flow to always follow the same path has become an implicit requirement that I think we need follow at least as the default behavior.
Quoted 8 lines
Martin: is there any change you could resurrect these patches? In order to solve the general problem of making routing consistent, I believe we want to keep
sk_tx_hashconsistent for the connection from which a consistent flow label can be derived. To avoid the overhead of a hash field insk_common, maybe we could initially set a connection hash to a five-tuple hash for a flow instead of a random value? So in TW state the consistent hash can be computed on the fly.
Sorry, I failed to give credit to Shaohua for submitting the initial patch. Please take look!
Quoted 1 line
Tom
Quoted 18 lines · Tom Herbert
Quoted 9 lines · Tom Herbert
Quoted 1 line
We're now seeing several router vendors recommending people to not use flow labels for ECMP hashing. This is precisely because when a flow label changes, network devices that maintain state (firewalls, NAT, load balancers) can't deal with packets being rerouted so connections are dropped. Unfortunately, the need for packets of a flow to always follow the same path has become an implicit requirement that I think we need follow at least as the default behavior.
Quoted 8 lines
Martin: is there any change you could resurrect these patches? In order to solve the general problem of making routing consistent, I believe we want to keep
sk_tx_hashconsistent for the connection from which a consistent flow label can be derived. To avoid the overhead of a hash field insk_common, maybe we could initially set a connection hash to a five-tuple hash for a flow instead of a random value? So in TW state the consistent hash can be computed on the fly.
Quoted 2 lines
Sorry, I failed to give credit to Shaohua for submitting the initial patch. Please take look!
Hi Tom, thanks for the info. Shaohua will revisit this when he returns next week.
Martin
Quoted 26 lines · Tom Herbert
Quoted 8 lines · David Miller
From: Martin KaFai Lau <[email protected]>
Date: Fri, 18 Aug 2017 13:51:36 -0700Quoted 4 lines
It seems like that middle box specifically drops
TCP_RSTif it does not know anything about this flow. Since the flowlabel of theTCP_RST(sent in TW state) is always different, it always lands to a different middle box. All of theseTCP_RSTcannot be delivered.Quoted 9 lines
This really is illegal behavior. The flow label is not a flow _KEY_ by any definition whatsoever.
Flow labels are an optimization, not a determinant for flow matching particularly for proper TCP state processing.
I'd rather you invest all of this energy getting that vendor to fix their kit.
We're now seeing several router vendors recommending people to not use flow labels for ECMP hashing. This is precisely because when a flow label changes, network devices that maintain state (firewalls, NAT, load balancers) can't deal with packets being rerouted so connections are dropped. Unfortunately, the need for packets of a flow to always follow the same path has become an implicit requirement that I think we need follow at least as the default behavior.
Quoted 7 lines
Martin: is there any change you could resurrect these patches? In order to solve the general problem of making routing consistent, I believe we want to keep
sk_tx_hashconsistent for the connection from which a consistent flow label can be derived. To avoid the overhead of a hash field insk_common, maybe we could initially set a connection hash to a five-tuple hash for a flow instead of a random value? So in TW state the consistent hash can be computed on the fly.
Hi Tom,
Do we really need to use the five-tupe hash? There are several places using current random hash, which looks more lightweight. To fix issue, we only need to make sure reset packet include the correct flowlabel. Like what my previous patch did, we can set tw->tw_flowlabel in tcp_time_wait based on txhash and use it reset packet. In this way we can use the random hash and not add extra field in sock.
Thanks,
Shaohua
Quoted 35 lines · Shaohua Li
Quoted 26 lines · Tom Herbert
Quoted 8 lines · David Miller
From: Martin KaFai Lau <[email protected]>
Date: Fri, 18 Aug 2017 13:51:36 -0700Quoted 4 lines
It seems like that middle box specifically drops
TCP_RSTif it does not know anything about this flow. Since the flowlabel of theTCP_RST(sent in TW state) is always different, it always lands to a different middle box. All of theseTCP_RSTcannot be delivered.Quoted 9 lines
This really is illegal behavior. The flow label is not a flow _KEY_ by any definition whatsoever.
Flow labels are an optimization, not a determinant for flow matching particularly for proper TCP state processing.
I'd rather you invest all of this energy getting that vendor to fix their kit.
We're now seeing several router vendors recommending people to not use flow labels for ECMP hashing. This is precisely because when a flow label changes, network devices that maintain state (firewalls, NAT, load balancers) can't deal with packets being rerouted so connections are dropped. Unfortunately, the need for packets of a flow to always follow the same path has become an implicit requirement that I think we need follow at least as the default behavior.
Quoted 7 lines
Martin: is there any change you could resurrect these patches? In order to solve the general problem of making routing consistent, I believe we want to keep
sk_tx_hashconsistent for the connection from which a consistent flow label can be derived. To avoid the overhead of a hash field insk_common, maybe we could initially set a connection hash to a five-tuple hash for a flow instead of a random value? So in TW state the consistent hash can be computed on the fly.
Quoted 8 lines
Hi Tom,
Do we really need to use the five-tupe hash? There are several places using current random hash, which looks more lightweight. To fix issue, we only need to make sure reset packet include the correct flowlabel. Like what my previous patch did, we can settw->tw_flowlabelintcp_time_waitbased on txhash and use it reset packet. In this way we can use the random hash and not add extra field in sock.
Shaohua,
But that patch discards the full txhash in TW. So it's not just a problem with the flow label. sk_tx_hash can also be used for route selection in ECMP, port selection we're doing tunneling, etc. The general solution should maintains tx_hash or be able to reconstruct it in any state, flow label fix is a point solution.
Thanks,
Tom
Quoted 2 lines
Thanks,
Shaohua
Quoted 44 lines · Tom Herbert
Quoted 35 lines · Shaohua Li
Quoted 26 lines · Tom Herbert
Quoted 8 lines · David Miller
From: Martin KaFai Lau <[email protected]>
Date: Fri, 18 Aug 2017 13:51:36 -0700Quoted 4 lines
It seems like that middle box specifically drops
TCP_RSTif it does not know anything about this flow. Since the flowlabel of theTCP_RST(sent in TW state) is always different, it always lands to a different middle box. All of theseTCP_RSTcannot be delivered.Quoted 9 lines
This really is illegal behavior. The flow label is not a flow _KEY_ by any definition whatsoever.
Flow labels are an optimization, not a determinant for flow matching particularly for proper TCP state processing.
I'd rather you invest all of this energy getting that vendor to fix their kit.
We're now seeing several router vendors recommending people to not use flow labels for ECMP hashing. This is precisely because when a flow label changes, network devices that maintain state (firewalls, NAT, load balancers) can't deal with packets being rerouted so connections are dropped. Unfortunately, the need for packets of a flow to always follow the same path has become an implicit requirement that I think we need follow at least as the default behavior.
Quoted 7 lines
Martin: is there any change you could resurrect these patches? In order to solve the general problem of making routing consistent, I believe we want to keep
sk_tx_hashconsistent for the connection from which a consistent flow label can be derived. To avoid the overhead of a hash field insk_common, maybe we could initially set a connection hash to a five-tuple hash for a flow instead of a random value? So in TW state the consistent hash can be computed on the fly.Quoted 8 lines
Hi Tom,
Do we really need to use the five-tupe hash? There are several places using current random hash, which looks more lightweight. To fix issue, we only need to make sure reset packet include the correct flowlabel. Like what my previous patch did, we can settw->tw_flowlabelintcp_time_waitbased on txhash and use it reset packet. In this way we can use the random hash and not add extra field in sock.
Quoted 7 lines
Shaohua,
But that patch discards the full txhash in TW. So it's not just a problem with the flow label.
sk_tx_hashcan also be used for route selection in ECMP, port selection we're doing tunneling, etc. The general solution should maintainstx_hashor be able to reconstruct it in any state, flow label fix is a point solution.
Hi Tom,
do you want to keep sk_rethink_txhash() then? If we changed the hash to random number, we can't reconstruct it for sure.
Thanks,
Shaohua
Quoted 53 lines · Shaohua Li
Quoted 44 lines · Tom Herbert
Quoted 35 lines · Shaohua Li
Quoted 26 lines · Tom Herbert
Quoted 8 lines · David Miller
From: Martin KaFai Lau <[email protected]>
Date: Fri, 18 Aug 2017 13:51:36 -0700Quoted 4 lines
It seems like that middle box specifically drops
TCP_RSTif it does not know anything about this flow. Since the flowlabel of theTCP_RST(sent in TW state) is always different, it always lands to a different middle box. All of theseTCP_RSTcannot be delivered.Quoted 9 lines
This really is illegal behavior. The flow label is not a flow _KEY_ by any definition whatsoever.
Flow labels are an optimization, not a determinant for flow matching particularly for proper TCP state processing.
I'd rather you invest all of this energy getting that vendor to fix their kit.
We're now seeing several router vendors recommending people to not use flow labels for ECMP hashing. This is precisely because when a flow label changes, network devices that maintain state (firewalls, NAT, load balancers) can't deal with packets being rerouted so connections are dropped. Unfortunately, the need for packets of a flow to always follow the same path has become an implicit requirement that I think we need follow at least as the default behavior.
Quoted 7 lines
Martin: is there any change you could resurrect these patches? In order to solve the general problem of making routing consistent, I believe we want to keep
sk_tx_hashconsistent for the connection from which a consistent flow label can be derived. To avoid the overhead of a hash field insk_common, maybe we could initially set a connection hash to a five-tuple hash for a flow instead of a random value? So in TW state the consistent hash can be computed on the fly.Quoted 8 lines
Hi Tom,
Do we really need to use the five-tupe hash? There are several places using current random hash, which looks more lightweight. To fix issue, we only need to make sure reset packet include the correct flowlabel. Like what my previous patch did, we can settw->tw_flowlabelintcp_time_waitbased on txhash and use it reset packet. In this way we can use the random hash and not add extra field in sock.Quoted 7 lines
Shaohua,
But that patch discards the full txhash in TW. So it's not just a problem with the flow label.
sk_tx_hashcan also be used for route selection in ECMP, port selection we're doing tunneling, etc. The general solution should maintainstx_hashor be able to reconstruct it in any state, flow label fix is a point solution.
Quoted 4 lines
Hi Tom,
do you want to keep
sk_rethink_txhash()then? If we changed the hash to random number, we can't reconstruct it for sure.
A followup question on rethink. Does it mean we need
a new sysctl (persistent_txhash) to avoid sk_rethink_txhash() together such that it keeps the routing decision consistent (e.g. flowlabel) ?
Quoted 3 lines
Thanks,
Shaohua