Re: prison_flag() check in hot path of in_pcblookup()

From: Bjoern A. Zeeb <bz_at_freebsd.org>
Date: Tue, 13 Dec 2022 23:54:17 UTC
On Tue, 13 Dec 2022, Andrew Gallatin wrote:

> [ I added pjd, since the original patch came from him ]
>
> Just to make sure I understand, I have a simple yes/no question:
>
> Can  jails and the host ever share the same (local) port and the same IP?

Can they currently (I tested only for TCP)?

- local binds can overlap like they can with just the base system.
   so bind(... {AF_INET, laddr, lport} ... ) works fine (REUSEPORT).

- tcp connect of a 2nd socket to the same {faddr, fport} from the above
   bind will fail with 'Address already in use'  [currently]
   [I believe that would mean your patch could go in? Where does the error come from [%]?] [*]

- tcp listen will work on {laddr, lport} if run in paralllel (REUSEPORT)
   or in base and jail at the same time.

[%] likely in_pcbconnect_setup() ?  Also one should check the other
     order (jail first then base);  also we assume no other race
     conditions in this rather simple testing...

[*] Now someone should run this on a FreeBSD 7.3 / 8.x or later and see how it behaves as the stack might have behaved differently.
Also if you have two physical machines or two VMs connected remove the VNET layer and just (manually) test the two parts firing up one extra jail on each base system.
I just used vnets for simplicity of my testing.

(sorry vnet cleanup currently screwed as it seems 15 years of working also have changed due to other changes; you cal always run jail -r jl jr manually).

I haven't done user space socket programming in a while so this was fun (and hopefully does what it should for this test case).
I put the simple sources (shell script and C file) up at:
  https://people.freebsd.org/~bz/tmp/jail-in_pcblookup/

HTH /bz

+ pwd
+ STESTBIN=/home/test/socket
+ PORT=7
+ jail -i -c -n jl 'host.hostname=server.example.net' vnet persist 'children.max=1'
+ js=211
+ jail -i -c -n jr 'host.hostname=base.example.net' vnet persist 'children.max=1'
+ jb=212
+ jexec 211 ifconfig lo0 inet 127.0.0.1/8 alias up
+ jexec 211 ifconfig lo0 inet6 ::1/128 alias
+ jexec 212 ifconfig lo0 inet 127.0.0.1/8 alias up
+ jexec 212 ifconfig lo0 inet6 ::1/128 alias
+ ifconfig epair create
+ sed -e 's/a$//'
+ ep=epair102
+ ifconfig epair102a vnet 211
+ ifconfig epair102b vnet 212
+ jexec 211 ifconfig epair102a inet 192.0.2.1/24
+ jexec 212 ifconfig epair102b inet 192.0.2.2/24
+ jexec 211 jail -i -c -n jsj 'host.hostname=jails.example.net' 'ip4.addr=192.0.2.1' persist
+ jexec 211 /home/test/socket 192.0.2.1 7
/home/test/socket pid 23254 listening on [192.0.2.1 7]
+ jsj=213
+ echo 'Listing listening connections from the server (base) system'
+ jexec 213 /home/test/socket 192.0.2.1 7
Listing listening connections from the server (base) system
+ jexec 211 netstat -an
/home/test/socket pid 23257 listening on [192.0.2.1 7]
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address          Foreign Address        (state) 
tcp4       0      0 192.0.2.1.7            *.*                    LISTEN 
tcp4       0      0 192.0.2.1.7            *.*                    LISTEN 
+ jexec 212 jail -i -c -n jbj 'host.hostname=jailb.example.net' 'ip4.addr=192.0.2.2' persist
+ jbj=214
+ sleep 1
+ echo 'Starting connection from base jail'
Starting connection from base jail
+ sleep 1
+ jexec 212 /home/test/socket 192.0.2.2 12345 192.0.2.1 7
/home/test/socket pid 23257 accepted [192.0.2.2 12345]
/home/test/socket pid 23261 [192.0.2.2 12345] sleeping 60.
+ echo 'Starting connection from plain-old IP jail'
Starting connection from plain-old IP jail
+ sleep 1
+ jexec 214 /home/test/socket 192.0.2.2 12345 192.0.2.1 7
socket: connect
: Address already in use
+ echo 'Listing server connections from the server (base) system'
Listing server connections from the server (base) system
+ jexec 211 netstat -an
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address          Foreign Address        (state) 
tcp4       0      0 192.0.2.1.7            192.0.2.2.12345        ESTABLISHED
tcp4       0      0 192.0.2.1.7            *.*                    LISTEN 
tcp4       0      0 192.0.2.1.7            *.*                    LISTEN 
+ echo 'Listing client connections from the base system'
Listing client connections from the base system
+ jexec 212 netstat -an
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address          Foreign Address        (state) 
tcp4       0      0 192.0.2.2.12345        192.0.2.1.7            ESTABLISHED
+ sleep 60
^C

-- 
Bjoern A. Zeeb                                                     r15:7