Page MenuHomeFreeBSD

Enforce net epoch in in6_selectsrc().
ClosedPublic

Authored by melifaro on Feb 13 2021, 2:40 PM.
Tags
None
Referenced Files
F102447061: D28647.diff
Tue, Nov 12, 9:56 AM
Unknown Object (File)
Mon, Nov 11, 9:22 AM
Unknown Object (File)
Sat, Oct 19, 7:25 AM
Unknown Object (File)
Sat, Oct 19, 7:24 AM
Unknown Object (File)
Sat, Oct 19, 7:24 AM
Unknown Object (File)
Sat, Oct 19, 7:24 AM
Unknown Object (File)
Sat, Oct 19, 7:07 AM
Unknown Object (File)
Wed, Oct 16, 10:13 AM
Subscribers

Details

Summary

in6_selectsrc() may call fib6_lookup() in some cases. The latter function requires epoch.
Some callers of in6_selectsrc() already call it under epoch.
Given the fact that it is preferable not to re-enter epoch multiple times, make the remaining in6_selectsrc() callers call it within net epoch.

Finally, mark it as requiring epoch by adding NET_EPOCH_ASSERT().

Note that in6_selectsrc() is used indirectly by 2 wrappers (socket/non-socket-based access): in6_selectsrc_socket() and inet6_selectsrc_addr().

The following callers currently exists in kernel:

sys/fs/nfsclient/nfs_clport.c: error = in6_selectsrc_addr(fibnum, &sin6->sin6_addr,
^ Wrapped

sys/netpfil/ipfw/nat64/nat64_translate.c: if (in6_selectsrc_addr(M_GETFIB(n), &ip6->ip6_src, 0,
^ Assume datapath is under epoch

sys/netinet6/raw_ip6.c: error = in6_selectsrc_socket(dstsock, optp, inp, so->so_cred,
^ Wrapped
sys/netinet6/raw_ip6.c: error = in6_selectsrc_socket(addr, inp->in6p_outputopts,
^ Wrapped

sys/netinet6/nd6_nbr.c: error = in6_selectsrc_addr(fibnum, &dst6,
^ Called in nd6_ns_output_fib().
It is used locally in nd6_dad_ns_output() which is called from nd6_dad_starttimer() which is already under epoch.
It is also used in nd6_llinfo_timer() and nd6_resolve_slow() - both are under epoch.
Given that, mark nd6_ns_output_fib () as requiring epoch by using NET_EPOCH_ASSERT.

sys/netinet6/nd6_nbr.c: error = in6_selectsrc_addr(fibnum, &dst6,
^ Called in nd6_na_output_fib().
It is used externally in carp_send_na() which already requires epoch.
It is used locally in nd6_ns_input(). The latter is used in icmp6_input() (already under epoch) and send_output() (added epoch calls).
Finally, nd6_na_output_fib() calls ip6_output() so it needs to be either under epoch or wrap ip6_output().
Given the above, mark nd6_na_output_fib() as requiring epoch.

sys/netinet6/icmp6.c: error = in6_selectsrc_addr(M_GETFIB(m), &dst6,
^^ Wrapped

sys/netinet6/in6_pcb.c: error = in6_selectsrc_socket(sin6, inp->in6p_outputopts,
^ Wrapped

sys/netinet6/udp6_usrreq.c: error = in6_selectsrc_socket(sin6, optp, inp,
^ already under epoch

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

melifaro added a reviewer: network.
donner added inline comments.
sys/netinet6/send.c
152

I assume, the other functions do not need epoch at the moment.
If they ever need it sometimes in the future, the scope can be extended to the whole switch.

This revision was not accepted when it landed; it landed in state Needs Review.Feb 15 2021, 10:33 PM
This revision was automatically updated to reflect the committed changes.