> On 27 Apr 2023, at 15:40, Alexander Bluhm <alexander.bl...@gmx.net> wrote:
> 
> On Thu, Apr 27, 2023 at 03:22:10PM +0300, Vitaliy Makkoveev wrote:
>>> On 27 Apr 2023, at 15:16, Alexander Bluhm <alexander.bl...@gmx.net> wrote:
>>> 
>>> On Wed, Apr 26, 2023 at 11:17:37PM +0300, Vitaliy Makkoveev wrote:
>>>> Route timers and route labels protected by corresponding mutexes. `ifa'
>>>> uses references counting for protection. No protection required for `rt'
>>>> passed to rt_mpls_clear() because only current thread owns it.
>>>> 
>>>> ok?
>>> 
>>> I have tested your diff and it works for me.  But I don't have a
>>> MPLS setup.  And there is a rt_mpls_clear(rt) which your diff does
>>> not show.
>>> 
>>> if (rt->rt_llinfo != NULL)
>>>     free(rt->rt_llinfo);
>>>     rt->rt_llinfo = NULL;
>>> 
>>> and rt->rt_flags &= ~RTF_MPLS are not mpsafe.
>>> 
>>> What about this?  Compile tested only due to lacking MPLS setup.
>> 
>> This is not required. We hold the last reference of this dying `rt???.
> 
> You are right.  OK bluhm@ for rtfree unlocking.
> 
> But I am still not convinced with rt_mpls_clear().
> 
> What about htis call path?  soreceive -> pru_send -> route_send ->
> route_output -> rtm_output -> rt_mpls_clear
> 
> Since solock() takes rw_enter_write(&so->so_lock) for route sockets,
> we don't have the kernel lock anymore.  I would feel safer with
> this kenrel lock hammer for mpls.  Of course rt_mpls_set() would
> need something simmilar.

This path is netlock protected.

 911 rtm_output(struct rt_msghdr *rtm, struct rtentry **prt,
 912     struct rt_addrinfo *info, uint8_t prio, unsigned int tableid)
 913 {
        /* skip */
1132 #ifdef MPLS
1133                 if (rtm->rtm_flags & RTF_MPLS) {
1134                         NET_LOCK();
1135                         error = rt_mpls_set(rt,
1136                             info->rti_info[RTAX_SRC], info->rti_mpls);
1137                         NET_UNLOCK();
1138                         if (error)
1139                                 break;
1140                 } else if (newgate || (rtm->rtm_fmask & RTF_MPLS)) {
1141                         NET_LOCK();
1142                         /* if gateway changed remove MPLS information */
1143                         rt_mpls_clear(rt);
1144                         NET_UNLOCK();
1145                 }
1146 #endif

Reply via email to