• Benjamin Thery's avatar
    ipv6: fix run pending DAD when interface becomes ready · e3ec6cfc
    Benjamin Thery authored
    With some net devices types, an IPv6 address configured while the
    interface was down can stay 'tentative' forever, even after the interface
    is set up. In some case, pending IPv6 DADs are not executed when the
    device becomes ready.
    
    I observed this while doing some tests with kvm. If I assign an IPv6 
    address to my interface eth0 (kvm driver rtl8139) when it is still down
    then the address is flagged tentative (IFA_F_TENTATIVE). Then, I set
    eth0 up, and to my surprise, the address stays 'tentative', no DAD is
    executed and the address can't be pinged.
    
    I also observed the same behaviour, without kvm, with virtual interfaces
    types macvlan and veth.
    
    Some easy steps to reproduce the issue with macvlan:
    
    1. ip link add link eth0 type macvlan
    2. ip -6 addr add 2003::ab32/64 dev macvlan0
    3. ip addr show dev macvlan0
       ... 
       inet6 2003::ab32/64 scope global tentative
       ...
    4. ip link set macvlan0 up
    5. ip addr show dev macvlan0
       ...
       inet6 2003::ab32/64 scope global tentative
       ...
       Address is still tentative
    
    I think there's a bug in net/ipv6/addrconf.c, addrconf_notify():
    addrconf_dad_run() is not always run when the interface is flagged IF_READY.
    Currently it is only run when receiving NETDEV_CHANGE event. Looks like
    some (virtual) devices doesn't send this event when becoming up.
    
    For both NETDEV_UP and NETDEV_CHANGE events, when the interface becomes
    ready, run_pending should be set to 1. Patch below.
    
    'run_pending = 1' could be moved below the if/else block but it makes 
    the code less readable.
    Signed-off-by: default avatarBenjamin Thery <benjamin.thery@bull.net>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    e3ec6cfc
addrconf.c 110 KB