@@ -1006,7 +1006,8 @@ int xlate_payload6_to4(nat46_instance_t *nat46, void *pv6, void *ptrans_hdr, int
1006
1006
if ((udp -> check == 0 ) && zero_csum_pass ) {
1007
1007
/* zero checksum and the config to pass it is set - do nothing with it */
1008
1008
break ;
1009
- }
1009
+ }
1010
+ /* pretend we have full payload */
1010
1011
sum1 = csum_ipv6_unmagic (nat46 , & ip6h -> saddr , & ip6h -> daddr , infrag_payload_len , NEXTHDR_UDP , udp -> check );
1011
1012
sum2 = csum_tcpudp_remagic (v4saddr , v4daddr , infrag_payload_len , NEXTHDR_UDP , sum1 ); /* add pseudoheader */
1012
1013
if (ul_sum ) {
@@ -1671,9 +1672,15 @@ int nat46_ipv6_input(struct sk_buff *old_skb) {
1671
1672
case NEXTHDR_UDP : {
1672
1673
struct udphdr * udp = add_offset (ip6h , v6packet_l3size );
1673
1674
u16 sum1 , sum2 ;
1674
- if ((udp -> check == 0 ) && zero_csum_pass ) {
1675
- /* zero checksum and the config to pass it is set - do nothing with it */
1676
- break ;
1675
+ if (udp -> check == 0 ) {
1676
+ if (zero_csum_pass ) {
1677
+ /* zero checksum and the config to pass it is set - do nothing with it */
1678
+ break ;
1679
+ }
1680
+ skb_set_transport_header (old_skb ,v6packet_l3size ); /* transport (TCP/UDP/ICMP/...) header starts after 40 bytes */
1681
+
1682
+ /* FIXME: what if we don't have full payload */
1683
+ ip6_update_csum (old_skb , ip6h , 0 );
1677
1684
}
1678
1685
sum1 = csum_ipv6_unmagic (nat46 , & ip6h -> saddr , & ip6h -> daddr , l3_infrag_payload_len , NEXTHDR_UDP , udp -> check );
1679
1686
sum2 = csum_tcpudp_remagic (v4saddr , v4daddr , l3_infrag_payload_len , NEXTHDR_UDP , sum1 );
@@ -1767,13 +1774,23 @@ void ip6_update_csum(struct sk_buff * skb, struct ipv6hdr * ip6hdr, int do_atomi
1767
1774
unsigned udplen = ntohs (ip6hdr -> payload_len ) - (do_atomic_frag ?8 :0 ); /* UDP hdr + payload */
1768
1775
1769
1776
if ((udp -> check == 0 ) && zero_csum_pass ) {
1770
- /* zero checksum and the config to pass it is set - do nothing with it */
1771
- break ;
1777
+ /* zero checksum and the config to pass it is set - do nothing with it */
1778
+ break ;
1772
1779
}
1773
1780
1774
1781
oldsum = udp -> check ;
1775
1782
udp -> check = 0 ;
1776
1783
1784
+ if (do_atomic_frag ) {
1785
+ if ((udp -> check == 0 ) && !zero_csum_pass ) {
1786
+ /*
1787
+ * FIXME:
1788
+ * checksum will still be broken if we don't have full payload
1789
+ * since we can't do the full calculation first in this case
1790
+ */
1791
+ }
1792
+ }
1793
+
1777
1794
sum1 = csum_partial ((char * )udp , udplen , 0 ); /* calculate checksum for UDP hdr+payload */
1778
1795
sum2 = csum_ipv6_magic (& ip6hdr -> saddr , & ip6hdr -> daddr , udplen , ip6hdr -> nexthdr , sum1 ); /* add pseudoheader */
1779
1796
0 commit comments