Page MenuHomeFreeBSD

Refactor if_purgeaddrs().
AcceptedPublic

Authored by melifaro on Sat, Jan 9, 11:22 PM.

Details

Reviewers
bz
glebius
Group Reviewers
network
Summary

Factor out actual ifaddr removal logic from if_purgeaddrs().
This simplifies code a bit.

Switch addrhead traversal to ifaddr wlock from epoch.
Current epoch code has the following problem: after end of traversal we exit epoch.
If another thread runs IPv4 ifa deletion code, at the moment when we call in_control(), ifa could have been deleted by epoch callback, resulting in use-after-free. We cannot fix it by extending epoch b/c in_control() uses SX lock.

Do not fallback to CK_STAILQ_REMOVE() if in_control() call fails.
With the current code, if in_control() fails and we don't delete ifaddr from the if_addrhead, we end up in infinite loop in if_purgeaddrs(). However, if we delete it just from this list, as we currently do, we end up in negative refcount once we call in_difaddr_ioctl().

XXX: in6_purgeaddr() has no locking around it, so it is possible
to crash the system by removing addresses from multiple threads.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Skipped
Unit
Unit Tests Skipped
Build Status
Buildable 36074
Build 32963: arc lint + arc unit

Event Timeline

melifaro retitled this revision from Factor out actual ifaddr removal logic from if_purgeaddrs(). This simplifies code logic a bit. to Refactor if_purgeaddrs()..Sat, Jan 9, 11:28 PM
melifaro edited the summary of this revision. (Show Details)
This revision is now accepted and ready to land.Tue, Jan 12, 4:32 PM