@@ -653,6 +653,7 @@ rtredirect_fib(struct sockaddr *dst,
653
653
info .rti_info [RTAX_DST ] = dst ;
654
654
info .rti_info [RTAX_GATEWAY ] = gateway ;
655
655
info .rti_info [RTAX_NETMASK ] = netmask ;
656
+ ifa_ref (ifa );
656
657
info .rti_ifa = ifa ;
657
658
info .rti_flags = flags ;
658
659
error = rtrequest1_fib (RTM_ADD , & info , & rt , fibnum );
@@ -899,7 +900,7 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
899
900
info -> rti_flags = rt -> rt_flags ;
900
901
info -> rti_ifp = rt -> rt_ifp ;
901
902
info -> rti_ifa = rt -> rt_ifa ;
902
-
903
+ ifa_ref ( info -> rti_ifa );
903
904
if (flags & NHR_REF ) {
904
905
/* Do 'traditional' refcouting */
905
906
if_ref (info -> rti_ifp );
@@ -1275,12 +1276,14 @@ int
1275
1276
rt_getifa_fib (struct rt_addrinfo * info , u_int fibnum )
1276
1277
{
1277
1278
struct ifaddr * ifa ;
1278
- int error = 0 ;
1279
+ int needref , error ;
1279
1280
1280
1281
/*
1281
1282
* ifp may be specified by sockaddr_dl
1282
1283
* when protocol address is ambiguous.
1283
1284
*/
1285
+ error = 0 ;
1286
+ needref = (info -> rti_ifa == NULL );
1284
1287
NET_EPOCH_ENTER ();
1285
1288
if (info -> rti_ifp == NULL && ifpaddr != NULL &&
1286
1289
ifpaddr -> sa_family == AF_LINK &&
@@ -1303,7 +1306,7 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
1303
1306
info -> rti_ifa = ifa_ifwithroute (flags , sa , sa ,
1304
1307
fibnum );
1305
1308
}
1306
- if (( ifa = info -> rti_ifa ) != NULL ) {
1309
+ if (needref && info -> rti_ifa != NULL ) {
1307
1310
if (info -> rti_ifp == NULL )
1308
1311
info -> rti_ifp = ifa -> ifa_ifp ;
1309
1312
ifa_ref (info -> rti_ifa );
@@ -1785,6 +1788,7 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info,
1785
1788
if (rt -> rt_ifa -> ifa_rtrequest != NULL )
1786
1789
rt -> rt_ifa -> ifa_rtrequest (RTM_DELETE , rt , info );
1787
1790
ifa_free (rt -> rt_ifa );
1791
+ rt -> rt_ifa = NULL ;
1788
1792
}
1789
1793
/* Update gateway address */
1790
1794
if (info -> rti_info [RTAX_GATEWAY ] != NULL ) {
@@ -1836,8 +1840,10 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info,
1836
1840
}
1837
1841
bad :
1838
1842
RT_UNLOCK (rt );
1839
- if (free_ifa != 0 )
1843
+ if (free_ifa != 0 ) {
1840
1844
ifa_free (info -> rti_ifa );
1845
+ info -> rti_ifa = NULL ;
1846
+ }
1841
1847
return (error );
1842
1848
}
1843
1849
@@ -2052,6 +2058,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
2052
2058
* Do the actual request
2053
2059
*/
2054
2060
bzero ((caddr_t )& info , sizeof (info ));
2061
+ ifa_ref (ifa );
2055
2062
info .rti_ifa = ifa ;
2056
2063
info .rti_flags = flags |
2057
2064
(ifa -> ifa_flags & ~IFA_RTSELF ) | RTF_PINNED ;
0 commit comments