Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ibmveth: Fix checksum offload failure handling

Fix a number of issues in ibmveth_set_csum_offload:

- set_attr6 and clr_attr6 may be used uninitialised

- We store the result of the IPV4 checksum change in ret but overwrite
it in a couple of places before checking it again later. Add ret4
to make it obvious what we are doing.

- We weren't clearing the NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM flags
if the enable of that hypervisor feature failed.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Anton Blanchard and committed by
David S. Miller
fb82fd20 91aae1e5

+20 -11
+20 -11
drivers/net/ibmveth.c
··· 757 757 struct ibmveth_adapter *adapter = netdev_priv(dev); 758 758 unsigned long set_attr, clr_attr, ret_attr; 759 759 unsigned long set_attr6, clr_attr6; 760 - long ret, ret6; 760 + long ret, ret4, ret6; 761 761 int rc1 = 0, rc2 = 0; 762 762 int restart = 0; 763 763 ··· 770 770 771 771 set_attr = 0; 772 772 clr_attr = 0; 773 + set_attr6 = 0; 774 + clr_attr6 = 0; 773 775 774 776 if (data) { 775 777 set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; ··· 786 784 if (ret == H_SUCCESS && !(ret_attr & IBMVETH_ILLAN_ACTIVE_TRUNK) && 787 785 !(ret_attr & IBMVETH_ILLAN_TRUNK_PRI_MASK) && 788 786 (ret_attr & IBMVETH_ILLAN_PADDED_PKT_CSUM)) { 789 - ret = h_illan_attributes(adapter->vdev->unit_address, clr_attr, 787 + ret4 = h_illan_attributes(adapter->vdev->unit_address, clr_attr, 790 788 set_attr, &ret_attr); 791 789 792 - if (ret != H_SUCCESS) { 790 + if (ret4 != H_SUCCESS) { 793 791 netdev_err(dev, "unable to change IPv4 checksum " 794 792 "offload settings. %d rc=%ld\n", 795 - data, ret); 793 + data, ret4); 796 794 797 - ret = h_illan_attributes(adapter->vdev->unit_address, 798 - set_attr, clr_attr, &ret_attr); 795 + h_illan_attributes(adapter->vdev->unit_address, 796 + set_attr, clr_attr, &ret_attr); 797 + 798 + if (data == 1) 799 + dev->features &= ~NETIF_F_IP_CSUM; 800 + 799 801 } else { 800 802 adapter->fw_ipv4_csum_support = data; 801 803 } ··· 810 804 if (ret6 != H_SUCCESS) { 811 805 netdev_err(dev, "unable to change IPv6 checksum " 812 806 "offload settings. %d rc=%ld\n", 813 - data, ret); 807 + data, ret6); 814 808 815 - ret = h_illan_attributes(adapter->vdev->unit_address, 816 - set_attr6, clr_attr6, 817 - &ret_attr); 809 + h_illan_attributes(adapter->vdev->unit_address, 810 + set_attr6, clr_attr6, &ret_attr); 811 + 812 + if (data == 1) 813 + dev->features &= ~NETIF_F_IPV6_CSUM; 814 + 818 815 } else 819 816 adapter->fw_ipv6_csum_support = data; 820 817 821 - if (ret == H_SUCCESS || ret6 == H_SUCCESS) 818 + if (ret4 == H_SUCCESS || ret6 == H_SUCCESS) 822 819 adapter->rx_csum = data; 823 820 else 824 821 rc1 = -EIO;