Push kernel lock within rtable_add(9) and rework it to return 0 in the
authormvs <mvs@openbsd.org>
Fri, 26 Mar 2021 22:41:06 +0000 (22:41 +0000)
committermvs <mvs@openbsd.org>
Fri, 26 Mar 2021 22:41:06 +0000 (22:41 +0000)
commit51772eb6ca0378a11bd1f4965abf57cb7fb874bc
tree9e7db48d4e2be83af76fdbc10455aaf871ffa612
parent6ea313b170319aed9e423222b5dfacede227785c
Push kernel lock within rtable_add(9) and rework it to return 0 in the
case when requested table is already exists.

Except initialization time, route_output() and if_createrdomain() are the
only paths where we call rtable_add(9). We check requested table existence
by rtable_exists(9) and it's not the error condition if the table exists.
Otherwise we are trying to create requested table by rtable_add(9). Those
paths are kernel locked so concurrent thread can't create requested table
just after rtable_exists(9) check. Also rtable_add(9) has internal
rtable_exists(9) check and in this case the table existence assumed as
EEXIST error. This error path is never reached.

We are going to unlock PF_ROUTE sockets. This means route_output() will
not be serialized with if_createrdomain() and concurrent thread could
create requested table. Table existence check and creation should be
serialized and it makes sense to do this within rtable_add(9). This time
kernel lock is used for this so it pushed down to rtable_add(9). The
internal rtable_exists(9) check was modified and table existence is not
error now.

Since the external rtable_exists(9) check is useless it was removed from
if_createrdomain(). It still exists in route_output() path because the
logic is more complicated here.

ok mpi@
share/man/man9/rtable_add.9
sys/net/if.c
sys/net/rtable.c