lkml.org 
[lkml]   [2018]   [May]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.16 016/161] net: dsa: bcm_sf2: Fix IPv6 rules and chain ID
    Date
    4.16-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Florian Fainelli <f.fainelli@gmail.com>

    [ Upstream commit 6c05561c541843b2bec2189f680bed6d20afc25b ]

    We had several issues that would make the programming of IPv6 rules both
    inconsistent and error prone:

    - the chain ID that we would be asking the hardware to put in the
    packet's Broadcom tag would be off by one, it would return one of the
    two indexes, but not the one user-space specified

    - when an user specified a particular location to insert a CFP rule at,
    we would not be returning the same index, which would be confusing if
    nothing else

    - finally, like IPv4, it would be possible to overflow the last entry by
    re-programming it

    Fix this by swapping the usage of rule_index[0] and rule_index[1] where
    relevant in order to return a consistent and correct user-space
    experience.

    Fixes: ba0696c22e7c ("net: dsa: bcm_sf2: Add support for IPv6 CFP rules")
    Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/dsa/bcm_sf2_cfp.c | 20 +++++++++++---------
    1 file changed, 11 insertions(+), 9 deletions(-)

    --- a/drivers/net/dsa/bcm_sf2_cfp.c
    +++ b/drivers/net/dsa/bcm_sf2_cfp.c
    @@ -565,19 +565,21 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
    * first half because the HW search is by incrementing addresses.
    */
    if (fs->location == RX_CLS_LOC_ANY)
    - rule_index[0] = find_first_zero_bit(priv->cfp.used,
    - bcm_sf2_cfp_rule_size(priv));
    + rule_index[1] = find_first_zero_bit(priv->cfp.used,
    + priv->num_cfp_rules);
    else
    - rule_index[0] = fs->location;
    + rule_index[1] = fs->location;
    + if (rule_index[1] > bcm_sf2_cfp_rule_size(priv))
    + return -ENOSPC;

    /* Flag it as used (cleared on error path) such that we can immediately
    * obtain a second one to chain from.
    */
    - set_bit(rule_index[0], priv->cfp.used);
    + set_bit(rule_index[1], priv->cfp.used);

    - rule_index[1] = find_first_zero_bit(priv->cfp.used,
    - bcm_sf2_cfp_rule_size(priv));
    - if (rule_index[1] > bcm_sf2_cfp_rule_size(priv)) {
    + rule_index[0] = find_first_zero_bit(priv->cfp.used,
    + priv->num_cfp_rules);
    + if (rule_index[0] > bcm_sf2_cfp_rule_size(priv)) {
    ret = -ENOSPC;
    goto out_err;
    }
    @@ -715,14 +717,14 @@ static int bcm_sf2_cfp_ipv6_rule_set(str
    /* Flag the second half rule as being used now, return it as the
    * location, and flag it as unique while dumping rules
    */
    - set_bit(rule_index[1], priv->cfp.used);
    + set_bit(rule_index[0], priv->cfp.used);
    set_bit(rule_index[1], priv->cfp.unique);
    fs->location = rule_index[1];

    return ret;

    out_err:
    - clear_bit(rule_index[0], priv->cfp.used);
    + clear_bit(rule_index[1], priv->cfp.used);
    return ret;
    }


    \
     
     \ /
      Last update: 2018-05-24 12:39    [W:4.103 / U:0.088 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site