• Wei Wang's avatar
    ipv6: update fn_sernum after route is inserted to tree · bbd63f06
    Wei Wang authored
    fib6_add() logic currently calls fib6_add_1() to figure out what node
    should be used for the newly added route and then call
    fib6_add_rt2node() to insert the route to the node.
    And during the call of fib6_add_1(), fn_sernum is updated for all nodes
    that share the same prefix as the new route.
    This does not have issue in the current code because reader thread will
    not be able to access the tree while writer thread is inserting new
    route to it. However, it is not the case once we transition to use RCU.
    Reader thread could potentially see the new fn_sernum before the new
    route is inserted. As a result, reader thread's route lookup will return
    a stale route with the new fn_sernum.
    
    In order to solve this issue, we remove all the update of fn_sernum in
    fib6_add_1(), and instead, introduce a new function that updates fn_sernum
    for all related nodes and call this functions once the route is
    successfully inserted to the tree.
    Also, smp_wmb() is used after a route is successfully inserted into the
    fib tree and right before the updated of fn->sernum. And smp_rmb() is
    used right after fn->sernum is accessed in rt6_get_cookie_safe(). This
    is to guarantee that when the reader thread sees the new fn->sernum, the
    new route is already inserted in the tree in memory.
    Signed-off-by: default avatarWei Wang <weiwan@google.com>
    Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
    Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    bbd63f06
ip6_fib.c 48.3 KB