On Mon, Apr 17, 2023 at 04:32:13PM +0200, Alexander Bluhm wrote: > On Mon, Apr 17, 2023 at 02:36:57AM +0300, Vitaliy Makkoveev wrote: > > It seems rt_setsource() needs some attention, but sysctl_source() could > > be called with shared netlock just now. > > I think rtable_setsource() is not MP safe. It is documented as [K] > kernel lock. But that is not true and makes no sense. It should > be exclusive netlock. in_pcbselsrc() calls rtable_getsource() with > netlock. We should rename source to ar_source so we can grep for > its users. >
rtable_*source() locking should be reworked. The data pointed by ar->source actually belong to `ifa'. So we need to use netlock, as I propose in the "Remove kernel lock from ifa_ifwithaddr" diff. However, the renaming of `source' to `ar_source' diff is pretty small. We use 'art_root' structure in regress/sys/net/rtable/delete and in usr.bin/netstat/ but we don't touch `source'. Index: sys/net/art.h =================================================================== RCS file: /cvs/src/sys/net/art.h,v retrieving revision 1.21 diff -u -p -r1.21 art.h --- sys/net/art.h 2 Mar 2021 17:50:41 -0000 1.21 +++ sys/net/art.h 17 Apr 2023 15:32:43 -0000 @@ -41,7 +41,7 @@ struct art_root { uint8_t ar_nlvl; /* [I] Number of levels */ uint8_t ar_alen; /* [I] Address length in bits */ uint8_t ar_off; /* [I] Offset of key in bytes */ - struct sockaddr *source; /* [K] optional src addr to use */ + struct sockaddr *ar_source; /* [K] optional src addr to use */ }; #define ISLEAF(e) (((unsigned long)(e) & 1) == 0) Index: sys/net/rtable.c =================================================================== RCS file: /cvs/src/sys/net/rtable.c,v retrieving revision 1.80 diff -u -p -r1.80 rtable.c --- sys/net/rtable.c 29 Jun 2022 22:20:47 -0000 1.80 +++ sys/net/rtable.c 17 Apr 2023 15:32:43 -0000 @@ -379,7 +379,7 @@ rtable_setsource(unsigned int rtableid, if ((ar = rtable_get(rtableid, af)) == NULL) return (EAFNOSUPPORT); - ar->source = src; + ar->ar_source = src; return (0); } @@ -393,7 +393,7 @@ rtable_getsource(unsigned int rtableid, if (ar == NULL) return (NULL); - return (ar->source); + return (ar->ar_source); } void