There are quite a few places where vimage context is not being properly set.
We believe this relates to FreeNAS #11012.
Details
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
The changes itself seems to be fine.
However, I'm not quite sure on how could we get a crash in sa6_recoverscope() due to misplaced VNET pointer:
in6_sockaddr() allocates new memory block, properly zeroed. We can get some garbage in both address/scopeid field, but it should not crash.
ifnet_byindex() should simply return NULL in worst case.
Btw, we could probably consider using some sort of VNET_ macro to simplify all similar calls
#define SO_VOID_VNET_METHOD(so, _method, ...) \ CURVNET_SET((so)->so_vnet); \ (*(so)->so_proto->pr_usrreqs->_method)(__VA_ARGS__); \ CURVNET_RESTORE(); #define SO_VNET_METHOD(so, _method, _ret, ...) \ CURVNET_SET((so)->so_vnet); \ _ret = (*(so)->so_proto->pr_usrreqs->_method)(__VA_ARGS__); \ CURVNET_RESTORE();
I would prefer if we would not start conflating so/pr/pru callouts with the curvnet things.
It'll make grep-ing a lot harder and sounds more like we'll introduce more bugs and also current recursions we don't want.
The cause of the panic is that sa6_recoverscope() uses V_if_index in a sanity checking when the address is link-local. Probably the reporter has used an LLA for NFS over IPv6.
I think setting curvnet around in6_sockaddr() to make it possible to be called from a thread with no default vnet is more reasonable than doing around every pru_sockaddr() call, because guaranteeing pru_xxx methods be robust prevents similar bugs from being introduced again in the future. How about the patch at http://people.allbsd.org/~hrs/FreeBSD/in6_sockaddr_vnet.20150820-1.diff ?