Message ID | 20230619105738.117733-2-hengqi@linux.alibaba.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | virtio-net: avoid XDP and _F_GUEST_CSUM | expand |
Hi Heng, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] url: https://github.com/intel-lab-lkp/linux/commits/Heng-Qi/virtio-net-a-helper-for-probing-the-pseudo-header-checksum/20230619-190212 base: net-next/main patch link: https://lore.kernel.org/r/20230619105738.117733-2-hengqi%40linux.alibaba.com patch subject: [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum config: x86_64-randconfig-r014-20230619 (https://download.01.org/0day-ci/archive/20230619/202306192049.8y7DR5F1-lkp@intel.com/config) compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a) reproduce: (https://download.01.org/0day-ci/archive/20230619/202306192049.8y7DR5F1-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202306192049.8y7DR5F1-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/net/virtio_net.c:1648:17: error: call to undeclared function 'csum_ipv6_magic'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration] uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, ^ drivers/net/virtio_net.c:1648:17: note: did you mean 'csum_tcpudp_magic'? include/asm-generic/checksum.h:52:1: note: 'csum_tcpudp_magic' declared here csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, ^ drivers/net/virtio_net.c:1657:17: error: call to undeclared function 'csum_ipv6_magic'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration] th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, ^ 2 errors generated. vim +/csum_ipv6_magic +1648 drivers/net/virtio_net.c 1572 1573 static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff *skb) 1574 { 1575 struct net_device *dev = vi->dev; 1576 struct flow_keys_basic keys; 1577 struct udphdr *uh; 1578 struct tcphdr *th; 1579 int len, offset; 1580 1581 /* The flow dissector needs this information. */ 1582 skb->dev = dev; 1583 skb_reset_mac_header(skb); 1584 skb->protocol = dev_parse_header_protocol(skb); 1585 /* virtio-net does not need to resolve VLAN. */ 1586 skb_set_network_header(skb, ETH_HLEN); 1587 if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, 1588 NULL, 0, 0, 0, 0)) 1589 return -EINVAL; 1590 1591 /* 1. Pseudo-header checksum calculation requires: 1592 * (1) saddr/daddr (2) IP_PROTO (3) length of transport payload 1593 * 2. We don't parse SCTP because virtio-net currently doesn't 1594 * support CRC offloading for SCTP. 1595 */ 1596 if (keys.basic.n_proto == htons(ETH_P_IP)) { 1597 struct iphdr *iph; 1598 1599 /* Flow dissector has verified that there is an IP header. */ 1600 iph = ip_hdr(skb); 1601 if (iph->version != 4 || !pskb_may_pull(skb, iph->ihl * 4)) 1602 return -EINVAL; 1603 1604 skb->transport_header = skb->mac_header + keys.control.thoff; 1605 offset = skb_transport_offset(skb); 1606 len = skb->len - offset; 1607 if (keys.basic.ip_proto == IPPROTO_UDP) { 1608 if (!pskb_may_pull(skb, offset + sizeof(struct udphdr))) 1609 return -EINVAL; 1610 1611 uh = udp_hdr(skb); 1612 skb->csum_offset = offsetof(struct udphdr, check); 1613 /* Although uh->len is already the 3rd parameter for the calculation 1614 * of the pseudo-header checksum, we have already calculated the 1615 * length of the transport layer, so use 'len' here directly. 1616 */ 1617 uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len, 1618 IPPROTO_UDP, 0); 1619 } else if (keys.basic.ip_proto == IPPROTO_TCP) { 1620 if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr))) 1621 return -EINVAL; 1622 1623 th = tcp_hdr(skb); 1624 skb->csum_offset = offsetof(struct tcphdr, check); 1625 th->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len, 1626 IPPROTO_TCP, 0); 1627 } /* virtio-net doesn't support checksums for SCTP hw offloading.*/ 1628 } else if (keys.basic.n_proto == htons(ETH_P_IPV6)) { 1629 struct ipv6hdr *ip6h; 1630 1631 ip6h = ipv6_hdr(skb); 1632 if (ip6h->version != 6) 1633 return -EINVAL; 1634 1635 /* We have skipped the possible extension headers for IPv6. 1636 * If there is a Routing Header, the tx's check value is calculated by 1637 * final_dst, and that value is the rx's daddr. 1638 */ 1639 skb->transport_header = skb->mac_header + keys.control.thoff; 1640 offset = skb_transport_offset(skb); 1641 len = skb->len - offset; 1642 if (keys.basic.ip_proto == IPPROTO_UDP) { 1643 if (!pskb_may_pull(skb, offset + sizeof(struct udphdr))) 1644 return -EINVAL; 1645 1646 uh = udp_hdr(skb); 1647 skb->csum_offset = offsetof(struct udphdr, check); > 1648 uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, 1649 (const struct in6_addr *)&ip6h->daddr, 1650 len, IPPROTO_UDP, 0); 1651 } else if (keys.basic.ip_proto == IPPROTO_TCP) { 1652 if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr))) 1653 return -EINVAL; 1654 1655 th = tcp_hdr(skb); 1656 skb->csum_offset = offsetof(struct tcphdr, check); 1657 th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, 1658 (const struct in6_addr *)&ip6h->daddr, 1659 len, IPPROTO_TCP, 0); 1660 } 1661 } 1662 1663 skb->csum_start = skb->transport_header; 1664 1665 return 0; 1666 } 1667
Hi Heng, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] url: https://github.com/intel-lab-lkp/linux/commits/Heng-Qi/virtio-net-a-helper-for-probing-the-pseudo-header-checksum/20230619-190212 base: net-next/main patch link: https://lore.kernel.org/r/20230619105738.117733-2-hengqi%40linux.alibaba.com patch subject: [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum config: m68k-randconfig-r021-20230619 (https://download.01.org/0day-ci/archive/20230619/202306192049.l2eaZ7od-lkp@intel.com/config) compiler: m68k-linux-gcc (GCC) 12.3.0 reproduce: (https://download.01.org/0day-ci/archive/20230619/202306192049.l2eaZ7od-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202306192049.l2eaZ7od-lkp@intel.com/ All errors (new ones prefixed by >>): drivers/net/virtio_net.c: In function 'virtnet_flow_dissect_udp_tcp': >> drivers/net/virtio_net.c:1648:38: error: implicit declaration of function 'csum_ipv6_magic'; did you mean 'csum_tcpudp_magic'? [-Werror=implicit-function-declaration] 1648 | uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, | ^~~~~~~~~~~~~~~ | csum_tcpudp_magic drivers/net/virtio_net.c: At top level: drivers/net/virtio_net.c:1573:12: warning: 'virtnet_flow_dissect_udp_tcp' defined but not used [-Wunused-function] 1573 | static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff *skb) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +1648 drivers/net/virtio_net.c 1572 1573 static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff *skb) 1574 { 1575 struct net_device *dev = vi->dev; 1576 struct flow_keys_basic keys; 1577 struct udphdr *uh; 1578 struct tcphdr *th; 1579 int len, offset; 1580 1581 /* The flow dissector needs this information. */ 1582 skb->dev = dev; 1583 skb_reset_mac_header(skb); 1584 skb->protocol = dev_parse_header_protocol(skb); 1585 /* virtio-net does not need to resolve VLAN. */ 1586 skb_set_network_header(skb, ETH_HLEN); 1587 if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, 1588 NULL, 0, 0, 0, 0)) 1589 return -EINVAL; 1590 1591 /* 1. Pseudo-header checksum calculation requires: 1592 * (1) saddr/daddr (2) IP_PROTO (3) length of transport payload 1593 * 2. We don't parse SCTP because virtio-net currently doesn't 1594 * support CRC offloading for SCTP. 1595 */ 1596 if (keys.basic.n_proto == htons(ETH_P_IP)) { 1597 struct iphdr *iph; 1598 1599 /* Flow dissector has verified that there is an IP header. */ 1600 iph = ip_hdr(skb); 1601 if (iph->version != 4 || !pskb_may_pull(skb, iph->ihl * 4)) 1602 return -EINVAL; 1603 1604 skb->transport_header = skb->mac_header + keys.control.thoff; 1605 offset = skb_transport_offset(skb); 1606 len = skb->len - offset; 1607 if (keys.basic.ip_proto == IPPROTO_UDP) { 1608 if (!pskb_may_pull(skb, offset + sizeof(struct udphdr))) 1609 return -EINVAL; 1610 1611 uh = udp_hdr(skb); 1612 skb->csum_offset = offsetof(struct udphdr, check); 1613 /* Although uh->len is already the 3rd parameter for the calculation 1614 * of the pseudo-header checksum, we have already calculated the 1615 * length of the transport layer, so use 'len' here directly. 1616 */ 1617 uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len, 1618 IPPROTO_UDP, 0); 1619 } else if (keys.basic.ip_proto == IPPROTO_TCP) { 1620 if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr))) 1621 return -EINVAL; 1622 1623 th = tcp_hdr(skb); 1624 skb->csum_offset = offsetof(struct tcphdr, check); 1625 th->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len, 1626 IPPROTO_TCP, 0); 1627 } /* virtio-net doesn't support checksums for SCTP hw offloading.*/ 1628 } else if (keys.basic.n_proto == htons(ETH_P_IPV6)) { 1629 struct ipv6hdr *ip6h; 1630 1631 ip6h = ipv6_hdr(skb); 1632 if (ip6h->version != 6) 1633 return -EINVAL; 1634 1635 /* We have skipped the possible extension headers for IPv6. 1636 * If there is a Routing Header, the tx's check value is calculated by 1637 * final_dst, and that value is the rx's daddr. 1638 */ 1639 skb->transport_header = skb->mac_header + keys.control.thoff; 1640 offset = skb_transport_offset(skb); 1641 len = skb->len - offset; 1642 if (keys.basic.ip_proto == IPPROTO_UDP) { 1643 if (!pskb_may_pull(skb, offset + sizeof(struct udphdr))) 1644 return -EINVAL; 1645 1646 uh = udp_hdr(skb); 1647 skb->csum_offset = offsetof(struct udphdr, check); > 1648 uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, 1649 (const struct in6_addr *)&ip6h->daddr, 1650 len, IPPROTO_UDP, 0); 1651 } else if (keys.basic.ip_proto == IPPROTO_TCP) { 1652 if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr))) 1653 return -EINVAL; 1654 1655 th = tcp_hdr(skb); 1656 skb->csum_offset = offsetof(struct tcphdr, check); 1657 th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, 1658 (const struct in6_addr *)&ip6h->daddr, 1659 len, IPPROTO_TCP, 0); 1660 } 1661 } 1662 1663 skb->csum_start = skb->transport_header; 1664 1665 return 0; 1666 } 1667
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 5a7f7a76b920..36cae78f6311 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1568,6 +1568,101 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash, skb_set_hash(skb, __le32_to_cpu(hdr_hash->hash_value), rss_hash_type); } +static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff *skb) +{ + struct net_device *dev = vi->dev; + struct flow_keys_basic keys; + struct udphdr *uh; + struct tcphdr *th; + int len, offset; + + /* The flow dissector needs this information. */ + skb->dev = dev; + skb_reset_mac_header(skb); + skb->protocol = dev_parse_header_protocol(skb); + /* virtio-net does not need to resolve VLAN. */ + skb_set_network_header(skb, ETH_HLEN); + if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, + NULL, 0, 0, 0, 0)) + return -EINVAL; + + /* 1. Pseudo-header checksum calculation requires: + * (1) saddr/daddr (2) IP_PROTO (3) length of transport payload + * 2. We don't parse SCTP because virtio-net currently doesn't + * support CRC offloading for SCTP. + */ + if (keys.basic.n_proto == htons(ETH_P_IP)) { + struct iphdr *iph; + + /* Flow dissector has verified that there is an IP header. */ + iph = ip_hdr(skb); + if (iph->version != 4 || !pskb_may_pull(skb, iph->ihl * 4)) + return -EINVAL; + + skb->transport_header = skb->mac_header + keys.control.thoff; + offset = skb_transport_offset(skb); + len = skb->len - offset; + if (keys.basic.ip_proto == IPPROTO_UDP) { + if (!pskb_may_pull(skb, offset + sizeof(struct udphdr))) + return -EINVAL; + + uh = udp_hdr(skb); + skb->csum_offset = offsetof(struct udphdr, check); + /* Although uh->len is already the 3rd parameter for the calculation + * of the pseudo-header checksum, we have already calculated the + * length of the transport layer, so use 'len' here directly. + */ + uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len, + IPPROTO_UDP, 0); + } else if (keys.basic.ip_proto == IPPROTO_TCP) { + if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr))) + return -EINVAL; + + th = tcp_hdr(skb); + skb->csum_offset = offsetof(struct tcphdr, check); + th->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len, + IPPROTO_TCP, 0); + } /* virtio-net doesn't support checksums for SCTP hw offloading.*/ + } else if (keys.basic.n_proto == htons(ETH_P_IPV6)) { + struct ipv6hdr *ip6h; + + ip6h = ipv6_hdr(skb); + if (ip6h->version != 6) + return -EINVAL; + + /* We have skipped the possible extension headers for IPv6. + * If there is a Routing Header, the tx's check value is calculated by + * final_dst, and that value is the rx's daddr. + */ + skb->transport_header = skb->mac_header + keys.control.thoff; + offset = skb_transport_offset(skb); + len = skb->len - offset; + if (keys.basic.ip_proto == IPPROTO_UDP) { + if (!pskb_may_pull(skb, offset + sizeof(struct udphdr))) + return -EINVAL; + + uh = udp_hdr(skb); + skb->csum_offset = offsetof(struct udphdr, check); + uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, + (const struct in6_addr *)&ip6h->daddr, + len, IPPROTO_UDP, 0); + } else if (keys.basic.ip_proto == IPPROTO_TCP) { + if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr))) + return -EINVAL; + + th = tcp_hdr(skb); + skb->csum_offset = offsetof(struct tcphdr, check); + th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr, + (const struct in6_addr *)&ip6h->daddr, + len, IPPROTO_TCP, 0); + } + } + + skb->csum_start = skb->transport_header; + + return 0; +} + static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, void *buf, unsigned int len, void **ctx, unsigned int *xdp_xmit,