• Paolo Abeni's avatar
    ipv4: fix route update on metric change. · 0b834ba0
    Paolo Abeni authored
    Since commit af4d768a ("net/ipv4: Add support for specifying metric
    of connected routes"), when updating an IP address with a different metric,
    the associated connected route is updated, too.
    
    Still, the mentioned commit doesn't handle properly some corner cases:
    
    $ ip addr add dev eth0 192.168.1.0/24
    $ ip addr add dev eth0 192.168.2.1/32 peer 192.168.2.2
    $ ip addr add dev eth0 192.168.3.1/24
    $ ip addr change dev eth0 192.168.1.0/24 metric 10
    $ ip addr change dev eth0 192.168.2.1/32 peer 192.168.2.2 metric 10
    $ ip addr change dev eth0 192.168.3.1/24 metric 10
    $ ip -4 route
    192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.0
    192.168.2.2 dev eth0 proto kernel scope link src 192.168.2.1
    192.168.3.0/24 dev eth0 proto kernel scope link src 192.168.2.1 metric 10
    
    Only the last route is correctly updated.
    
    The problem is the current test in fib_modify_prefix_metric():
    
    	if (!(dev->flags & IFF_UP) ||
    	    ifa->ifa_flags & (IFA_F_SECONDARY | IFA_F_NOPREFIXROUTE) ||
    	    ipv4_is_zeronet(prefix) ||
    	    prefix == ifa->ifa_local || ifa->ifa_prefixlen == 32)
    
    Which should be the logical 'not' of the pre-existing test in
    fib_add_ifaddr():
    
    	if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) &&
    	    (prefix != addr || ifa->ifa_prefixlen < 32))
    
    To properly negate the original expression, we need to change the last
    logical 'or' to a logical 'and'.
    
    Fixes: af4d768a ("net/ipv4: Add support for specifying metric of connected routes")
    Reported-and-suggested-by: default avatarBeniamino Galvani <bgalvani@redhat.com>
    Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
    Reviewed-by: default avatarDavid Ahern <dsahern@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    0b834ba0
fib_frontend.c 38.7 KB