• Tuong Lien's avatar
    tipc: fix name table rbtree issues · d5162f34
    Tuong Lien authored
    The current rbtree for service ranges in the name table is built based
    on the 'lower' & 'upper' range values resulting in a flaw in the rbtree
    searching. Some issues have been observed in case of range overlapping:
    
    Case #1: unable to withdraw a name entry:
    After some name services are bound, all of them are withdrawn by user
    but one remains in the name table forever. This corrupts the table and
    that service becomes dummy i.e. no real port.
    E.g.
    
                    /
               {22, 22}
                  /
                 /
       --->  {10, 50}
               /  \
              /    \
        {10, 30}  {20, 60}
    
    The node {10, 30} cannot be removed since the rbtree searching stops at
    the node's ancestor i.e. {10, 50}, so starting from it will never reach
    the finding node.
    
    Case #2: failed to send data in some cases:
    E.g. Two service ranges: {20, 60}, {10, 50} are bound. The rbtree for
    this service will be one of the two cases below depending on the order
    of the bindings:
    
            {20, 60}             {10, 50} <--
              /  \                 /  \
             /    \               /    \
        {10, 50}  NIL <--       NIL  {20, 60}
    
              (a)                    (b)
    
    Now, try to send some data to service {30}, there will be two results:
    (a): Failed, no route to host.
    (b): Ok.
    
    The reason is that the rbtree searching will stop at the pointing node
    as shown above.
    
    Case #3: Same as case #2b above but if the data sending's scope is
    local and the {10, 50} is published by a peer node, then it will result
    in 'no route to host' even though the other {20, 60} is for example on
    the local node which should be able to get the data.
    
    The issues are actually due to the way we built the rbtree. This commit
    fixes it by introducing an additional field to each node - named 'max',
    which is the largest 'upper' of that node subtree. The 'max' value for
    each subtrees will be propagated correctly whenever a node is inserted/
    removed or the tree is rebalanced by the augmented rbtree callbacks.
    
    By this way, we can change the rbtree searching appoarch to solve the
    issues above. Another benefit from this is that we can now improve the
    searching for a next range matching e.g. in case of multicast, so get
    rid of the unneeded looping over all nodes in the tree.
    Acked-by: default avatarJon Maloy <jon.maloy@ericsson.com>
    Signed-off-by: default avatarTuong Lien <tuong.t.lien@dektech.com.au>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    d5162f34
name_table.c 30.2 KB