lkml.org 
[lkml]   [2014]   [Jun]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.12 017/181] vlan: more careful checksum features handling
    Date
    From: Michal Kubeček <mkubecek@suse.cz>

    3.12-stable review patch. If anyone has any objections, please let me know.

    ===============

    commit da08143b85203b581f4a6461b149186b0e9592df upstream.

    When combining real_dev's features and vlan_features, simple
    bitwise AND is used. This doesn't work well for checksum
    offloading features as if one set has NETIF_F_HW_CSUM and the
    other NETIF_F_IP_CSUM and/or NETIF_F_IPV6_CSUM, we end up with
    no checksum offloading. However, from the logical point of view
    (how can_checksum_protocol() works), NETIF_F_HW_CSUM contains
    the functionality of NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM so
    that the result should be IP/IPV6.

    Add helper function netdev_intersect_features() implementing
    this logic and use it in vlan_dev_fix_features().

    Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Jiri Slaby <jslaby@suse.cz>
    ---
    include/linux/netdevice.h | 14 ++++++++++++++
    net/8021q/vlan_dev.c | 4 ++--
    2 files changed, 16 insertions(+), 2 deletions(-)

    diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
    index 9f2a0cbc7d06..51bfd7a68272 100644
    --- a/include/linux/netdevice.h
    +++ b/include/linux/netdevice.h
    @@ -2892,6 +2892,20 @@ extern const char *netdev_drivername(const struct net_device *dev);

    extern void linkwatch_run_queue(void);

    +static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
    + netdev_features_t f2)
    +{
    + if (f1 & NETIF_F_GEN_CSUM)
    + f1 |= (NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
    + if (f2 & NETIF_F_GEN_CSUM)
    + f2 |= (NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
    + f1 &= f2;
    + if (f1 & NETIF_F_GEN_CSUM)
    + f1 &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
    +
    + return f1;
    +}
    +
    static inline netdev_features_t netdev_get_wanted_features(
    struct net_device *dev)
    {
    diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
    index 1b89bc7468de..0c21361fab30 100644
    --- a/net/8021q/vlan_dev.c
    +++ b/net/8021q/vlan_dev.c
    @@ -694,9 +694,9 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev,
    struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
    netdev_features_t old_features = features;

    - features &= real_dev->vlan_features;
    + features = netdev_intersect_features(features, real_dev->vlan_features);
    features |= NETIF_F_RXCSUM;
    - features &= real_dev->features;
    + features = netdev_intersect_features(features, real_dev->features);

    features |= old_features & NETIF_F_SOFT_FEATURES;
    features |= NETIF_F_LLTX;
    --
    2.0.0
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2014-06-30 14:41    [W:4.649 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site