While hardware device use either NETIF_F_(IP|IPV6)_CSUM or NETIF_F_HW_CSUM, all of the software devices use HW_CSUM. This results in an interesting situation when the software device is configured on top of hw device using (IP|IPV6)_CSUM. In this situation, the user can't turn off checksum offloading features on the software device.
This patch resolves that by adding NETIF_F_HW_CSUM to the mask if a feature set includes only IP|IPV6 csum. This allows the user to control the upper (software) device checksum, while at the same time correctly propagating lower device changes up. CC: Michal Kubecek <mkube...@suse.cz> CC: Alexander Duyck <alexander.du...@gmail.com> CC: Tom Herbert <t...@herbertland.com> Signed-off-by: Vladislav Yasevich <vyase...@redhat.com> --- V2: Addressed comments from Alex Duyck. I tested this with hacked virtio device that set IP|IPV6 checksums instead of HW. Configuring a vlan on top gave the vlan device with 'ip-generic: on' setting (using HW checksum). This allows me to change vlan checksum offloads independent of virt-io nic. Changes to virtio-nic propagated up to vlan, turning off the offloading correctly. include/linux/netdevice.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b0aa089..81aed2f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4009,10 +4009,10 @@ static inline netdev_features_t netdev_intersect_features(netdev_features_t f1, netdev_features_t f2) { if ((f1 ^ f2) & NETIF_F_HW_CSUM) { - if (f1 & NETIF_F_HW_CSUM) - f1 |= (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); - else - f2 |= (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); + if (f1 & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) + f1 |= NETIF_F_HW_CSUM; + if(f2 & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) + f2 |= NETIF_F_HW_CSUM; } return f1 & f2; -- 2.7.4