• Vladimir Oltean's avatar
    net: dsa: targeted MTU notifiers should only match on one port · 88faba20
    Vladimir Oltean authored
    dsa_slave_change_mtu() calls dsa_port_mtu_change() twice:
    - it sends a cross-chip notifier with the MTU of the CPU port which is
      used to update the DSA links.
    - it sends one targeted MTU notifier which is supposed to only match the
      user port on which we are changing the MTU. The "propagate_upstream"
      variable is used here to bypass the cross-chip notifier system from
      switch.c
    
    But due to a mistake, the second, targeted notifier matches not only on
    the user port, but also on the DSA link which is a member of the same
    switch, if that exists.
    
    And because the DSA links of the entire dst were programmed in a
    previous round to the largest_mtu via a "propagate_upstream == true"
    notification, then the dsa_port_mtu_change(propagate_upstream == false)
    call that is immediately upcoming will break the MTU on the one DSA link
    which is chip-wise local to the dp whose MTU is changing right now.
    
    Example given this daisy chain topology:
    
       sw0p0     sw0p1     sw0p2     sw0p3     sw0p4
    [  cpu  ] [  user ] [  user ] [  dsa  ] [  user ]
    [   x   ] [       ] [       ] [   x   ] [       ]
                                      |
                                      +---------+
                                                |
       sw1p0     sw1p1     sw1p2     sw1p3     sw1p4
    [  user ] [  user ] [  user ] [  dsa  ] [  dsa  ]
    [       ] [       ] [       ] [       ] [   x   ]
    
    ip link set sw0p1 mtu 9000
    ip link set sw1p1 mtu 9000 # at this stage, sw0p1 and sw1p1 can talk
                               # to one another using jumbo frames
    ip link set sw0p2 mtu 1500 # this programs the sw0p3 DSA link first to
                               # the largest_mtu of 9000, then reprograms it to
                               # 1500 with the "propagate_upstream == false"
                               # notifier, breaking communication between
                               # sw0p1 and sw1p1
    
    To escape from this situation, make the targeted match really match on a
    single port - the user port, and rename the "propagate_upstream"
    variable to "targeted_match" to clarify the intention and avoid future
    issues.
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    88faba20
port.c 25.8 KB