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

Reply via email to