Hi Subash, Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net-next/master] url: https://github.com/0day-ci/linux/commits/Subash-Abhinov-Kasiviswanathan/net-qualcomm-rmnet-Enable-csum-offloads/20171228-041216 reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) vim +30 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c 26 27 static u16 *rmnet_map_get_csum_field(unsigned char protocol, 28 const void *txporthdr) 29 { > 30 u16 *check = 0; 31 32 switch (protocol) { 33 case IPPROTO_TCP: > 34 check = &(((struct tcphdr *)txporthdr)->check); 35 break; 36 37 case IPPROTO_UDP: > 38 check = &(((struct udphdr *)txporthdr)->check); 39 break; 40 41 default: 42 check = 0; 43 break; 44 } 45 46 return check; 47 } 48 49 static int 50 rmnet_map_ipv4_dl_csum_trailer(struct sk_buff *skb, 51 struct rmnet_map_dl_csum_trailer *csum_trailer) 52 { 53 u16 ip_pseudo_payload_csum, pseudo_csum, ip_hdr_csum, *csum_field; 54 u16 csum_value, ip_payload_csum, csum_value_final; 55 struct iphdr *ip4h; 56 void *txporthdr; 57 58 ip4h = (struct iphdr *)(skb->data); 59 if ((ntohs(ip4h->frag_off) & IP_MF) || 60 ((ntohs(ip4h->frag_off) & IP_OFFSET) > 0)) 61 return -EOPNOTSUPP; 62 63 txporthdr = skb->data + ip4h->ihl * 4; 64 65 csum_field = rmnet_map_get_csum_field(ip4h->protocol, txporthdr); 66 67 if (!csum_field) 68 return -EPROTONOSUPPORT; 69 70 /* RFC 768 - Skip IPv4 UDP packets where sender checksum field is 0 */ 71 if (*csum_field == 0 && ip4h->protocol == IPPROTO_UDP) 72 return 0; 73 > 74 csum_value = ~ntohs(csum_trailer->csum_value); > 75 ip_hdr_csum = ~ip_fast_csum(ip4h, (int)ip4h->ihl); > 76 ip_payload_csum = csum16_sub(csum_value, ip_hdr_csum); 77 > 78 pseudo_csum = ~ntohs(csum_tcpudp_magic(ip4h->saddr, ip4h->daddr, 79 (u16)(ntohs(ip4h->tot_len) - ip4h->ihl * 4), 80 (u16)ip4h->protocol, 0)); > 81 ip_pseudo_payload_csum = csum16_add(ip_payload_csum, pseudo_csum); 82 > 83 csum_value_final = ~csum16_sub(ip_pseudo_payload_csum, > 84 ntohs(*csum_field)); 85 86 if (unlikely(csum_value_final == 0)) { 87 switch (ip4h->protocol) { 88 case IPPROTO_UDP: 89 /* RFC 768 - DL4 1's complement rule for UDP csum 0 */ 90 csum_value_final = ~csum_value_final; 91 break; 92 93 case IPPROTO_TCP: 94 /* DL4 Non-RFC compliant TCP checksum found */ 95 if (*csum_field == 0xFFFF) 96 csum_value_final = ~csum_value_final; 97 break; 98 } 99 } 100 101 if (csum_value_final == ntohs(*csum_field)) 102 return 0; 103 else 104 return -EINVAL; 105 } 106 107 #if IS_ENABLED(CONFIG_IPV6) 108 static int 109 rmnet_map_ipv6_dl_csum_trailer(struct sk_buff *skb, 110 struct rmnet_map_dl_csum_trailer *csum_trailer) 111 { 112 u16 ip_pseudo_payload_csum, pseudo_csum, ip6_hdr_csum, *csum_field; 113 u16 csum_value, ip6_payload_csum, csum_value_final; 114 struct ipv6hdr *ip6h; 115 void *txporthdr; 116 u32 length; 117 118 ip6h = (struct ipv6hdr *)(skb->data); 119 120 txporthdr = skb->data + sizeof(struct ipv6hdr); 121 csum_field = rmnet_map_get_csum_field(ip6h->nexthdr, txporthdr); 122 123 if (!csum_field) 124 return -EPROTONOSUPPORT; 125 126 csum_value = ~ntohs(csum_trailer->csum_value); > 127 ip6_hdr_csum = ~ntohs(ip_compute_csum(ip6h, 128 (int)(txporthdr - (void *)(skb->data)))); > 129 ip6_payload_csum = csum16_sub(csum_value, ip6_hdr_csum); 130 131 length = (ip6h->nexthdr == IPPROTO_UDP) ? 132 ntohs(((struct udphdr *)txporthdr)->len) : 133 ntohs(ip6h->payload_len); 134 pseudo_csum = ~ntohs(csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, 135 length, ip6h->nexthdr, 0)); 136 ip_pseudo_payload_csum = csum16_add(ip6_payload_csum, pseudo_csum); 137 138 csum_value_final = ~csum16_sub(ip_pseudo_payload_csum, 139 ntohs(*csum_field)); 140 141 if (unlikely(csum_value_final == 0)) { 142 switch (ip6h->nexthdr) { 143 case IPPROTO_UDP: 144 /* RFC 2460 section 8.1 145 * DL6 One's complement rule for UDP checksum 0 146 */ 147 csum_value_final = ~csum_value_final; 148 break; 149 150 case IPPROTO_TCP: 151 /* DL6 Non-RFC compliant TCP checksum found */ 152 if (*csum_field == 0xFFFF) 153 csum_value_final = ~csum_value_final; 154 break; 155 } 156 } 157 158 if (csum_value_final == ntohs(*csum_field)) 159 return 0; 160 else 161 return -EINVAL; 162 } 163 #endif 164 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation