• Rasmus Villemoes's avatar
    net: switchdev: don't set port_obj_info->handled true when -EOPNOTSUPP · 20776b46
    Rasmus Villemoes authored
    It's not true that switchdev_port_obj_notify() only inspects the
    ->handled field of "struct switchdev_notifier_port_obj_info" if
    call_switchdev_blocking_notifiers() returns 0 - there's a WARN_ON()
    triggering for a non-zero return combined with ->handled not being
    true. But the real problem here is that -EOPNOTSUPP is not being
    properly handled.
    
    The wrapper functions switchdev_handle_port_obj_add() et al change a
    return value of -EOPNOTSUPP to 0, and the treatment of ->handled in
    switchdev_port_obj_notify() seems to be designed to change that back
    to -EOPNOTSUPP in case nobody actually acted on the notifier (i.e.,
    everybody returned -EOPNOTSUPP).
    
    Currently, as soon as some device down the stack passes the check_cb()
    check, ->handled gets set to true, which means that
    switchdev_port_obj_notify() cannot actually ever return -EOPNOTSUPP.
    
    This, for example, means that the detection of hardware offload
    support in the MRP code is broken: switchdev_port_obj_add() used by
    br_mrp_switchdev_send_ring_test() always returns 0, so since the MRP
    code thinks the generation of MRP test frames has been offloaded, no
    such frames are actually put on the wire. Similarly,
    br_mrp_switchdev_set_ring_role() also always returns 0, causing
    mrp->ring_role_offloaded to be set to 1.
    
    To fix this, continue to set ->handled true if any callback returns
    success or any error distinct from -EOPNOTSUPP. But if all the
    callbacks return -EOPNOTSUPP, make sure that ->handled stays false, so
    the logic in switchdev_port_obj_notify() can propagate that
    information.
    
    Fixes: 9a9f26e8 ("bridge: mrp: Connect MRP API with the switchdev API")
    Fixes: f30f0601 ("switchdev: Add helpers to aid traversal through lower devices")
    Reviewed-by: default avatarPetr Machata <petrm@nvidia.com>
    Signed-off-by: default avatarRasmus Villemoes <rasmus.villemoes@prevas.dk>
    Link: https://lore.kernel.org/r/20210125124116.102928-1-rasmus.villemoes@prevas.dkSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    20776b46
switchdev.c 16.6 KB