1. 10 12月, 2009 1 次提交
    • D
      IPoIB: Clear ipoib_neigh.dgid in ipoib_neigh_alloc() · 0cd4d0fd
      David J. Wilder 提交于
      IPoIB can miss a change in destination GID under some conditions.  The
      problem is caused when ipoib_neigh->dgid contains a stale address.
      The fix is to set ipoib_neigh->dgid to zero in ipoib_neigh_alloc().
      
      This can happen when a system using bonding on its IPoIB interfaces
      has switched its active interface from interface A to B and back to A.
      The system that fails over will not correctly processes the 2nd
      address change, as described below.
      
      When an address has changed neighbor->ha is updated with the new
      address.  Each neighbor has an associated ipoib_neigh.
      ipoib_neigh->dgid also holds a copy of the remote node's hardware
      address.  When an address changes neighbor->ha is updated by the
      network layer (arp code) with the new address.  IPoIB detects this
      change in ipoib_start_xmit() by comparing neighbor->ha with
      ipoib_neigh->dgid.  The bug is that ipoib_neigh->dgid may already
      contain the new address (A) thus the change from B to A is missed by
      ipoib.  Here is the sequence of events:
      
          ipoib_neigh->dgid = A  and  neighbor->ha = A
      
      The address is switched to B (the first switch)
      
          neighbor->ha = B
      
      The change is seen in ipoib_start_xmit() -- neighbor->ha !=
      ipoib_neigh->dgid so ipoib_neigh is released, and a new one is
      allocated.
      
      The allocator may return the same chunk of memory that was just
      released, therefore ipoib_neigh->dgid still contains A at this point.
      
      ipoib_neigh->dgid should be updated in neigh_add_path(), but if the
      following conditions are true dgid is not updated:
      
              1) __path_find() returns a path
              2) path->ah is NULL
      
      The remote system now switches from address B to A, neighbor->ha is
      updated to A.
      
      Now we have again : ipoib_neigh->dgid = A  and  neighbor->ha = A
      
      Since the addresses are the same ipoib won't process the change in
      address.  Fix this by zeroing out the dgid field when allocating a new
      struct ipoib_neigh.
      Signed-off-by: NDavid Wilder <dwilder@us.ibm.com>
      Signed-off-by: NRoland Dreier <rolandd@cisco.com>
      0cd4d0fd
  2. 04 11月, 2009 14 次提交
  3. 03 11月, 2009 25 次提交