For simple protocols the new KPI is as simple as it was in FreeBSD 4. The
protocol method just does protocol specific stuff and doesn't need to call
back into the socket layer. However, there is an option to acquire the
socket lock in the pr_listen and return with it locked, as well as set
SO_ACCEPTCONN early, using protocol locks for synchronization.
The historical design here is that socket layer calls into protocol and
protocol calls back into socket layer. This originates from the early
SMPng, see 0daccb9c94393. Main motivation for this added complexity was
of course TCP, where the socket state and the pcb state need to change
atomically. Once tcp_input() finds a tcpcb that is in TCPS_LISTEN, it
must point at SO_ACCEPTCONN socket. With new KPI this is achieved by
interlocking socket lock and pcb lock and using both to protect raising of
SO_ACCEPTCONN.
One other long standing bug was that consecutive listen(2) syscalls, that
just change the backlog would also enter pr_listen. This was mostly
harmless bug until 7cbb6b6e28db. Now handling of reconfiguring listen(2)s
is fully handled by solisten() and this bug no longer exists.
While here, merge tcp_usr_listen() and tcp6_usr_listen() into one. They
have more similarities than differencies.