@@ -94,14 +94,23 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_complete(struct sk_buff *skb, int thoff)
94
94
}
95
95
96
96
static void __tcpv6_gso_segment_csum (struct sk_buff * seg ,
97
+ struct in6_addr * oldip ,
98
+ const struct in6_addr * newip ,
97
99
__be16 * oldport , __be16 newport )
98
100
{
99
- struct tcphdr * th ;
101
+ struct tcphdr * th = tcp_hdr (seg );
102
+
103
+ if (!ipv6_addr_equal (oldip , newip )) {
104
+ inet_proto_csum_replace16 (& th -> check , seg ,
105
+ oldip -> s6_addr32 ,
106
+ newip -> s6_addr32 ,
107
+ true);
108
+ * oldip = * newip ;
109
+ }
100
110
101
111
if (* oldport == newport )
102
112
return ;
103
113
104
- th = tcp_hdr (seg );
105
114
inet_proto_csum_replace2 (& th -> check , seg , * oldport , newport , false);
106
115
* oldport = newport ;
107
116
}
@@ -129,10 +138,10 @@ static struct sk_buff *__tcpv6_gso_segment_list_csum(struct sk_buff *segs)
129
138
th2 = tcp_hdr (seg );
130
139
iph2 = ipv6_hdr (seg );
131
140
132
- iph2 -> saddr = iph -> saddr ;
133
- iph2 -> daddr = iph -> daddr ;
134
- __tcpv6_gso_segment_csum (seg , & th2 -> source , th -> source );
135
- __tcpv6_gso_segment_csum ( seg , & th2 -> dest , th -> dest );
141
+ __tcpv6_gso_segment_csum ( seg , & iph2 -> saddr , & iph -> saddr ,
142
+ & th2 -> source , th -> source ) ;
143
+ __tcpv6_gso_segment_csum (seg , & iph2 -> daddr , & iph -> daddr ,
144
+ & th2 -> dest , th -> dest );
136
145
}
137
146
138
147
return segs ;
0 commit comments