Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108694901
D28837.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D28837.diff
View Options
diff --git a/sys/net/route.c b/sys/net/route.c
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -207,7 +207,6 @@
/* Get the best ifa for the given interface and gateway. */
if ((ifa = ifaof_ifpforaddr(gateway, ifp)) == NULL)
return (ENETUNREACH);
- ifa_ref(ifa);
bzero(&info, sizeof(info));
info.rti_info[RTAX_DST] = dst;
@@ -224,7 +223,6 @@
info.rti_rmx = &rti_rmx;
error = rib_action(fibnum, RTM_ADD, &info, &rc);
- ifa_free(ifa);
if (error != 0) {
/* TODO: add per-fib redirect stats. */
@@ -518,8 +516,7 @@
}
/*
- * Look up rt_addrinfo for a specific fib. Note that if rti_ifa is defined,
- * it will be referenced so the caller must free it.
+ * Look up rt_addrinfo for a specific fib.
*
* Assume basic consistency checks are executed by callers:
* RTAX_DST exists, if RTF_GATEWAY is set, RTAX_GATEWAY exists as well.
@@ -528,8 +525,7 @@
rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
{
const struct sockaddr *dst, *gateway, *ifpaddr, *ifaaddr;
- struct epoch_tracker et;
- int needref, error, flags;
+ int error, flags;
dst = info->rti_info[RTAX_DST];
gateway = info->rti_info[RTAX_GATEWAY];
@@ -542,8 +538,6 @@
* when protocol address is ambiguous.
*/
error = 0;
- needref = (info->rti_ifa == NULL);
- NET_EPOCH_ENTER(et);
/* If we have interface specified by the ifindex in the address, use it */
if (info->rti_ifp == NULL && ifpaddr != NULL &&
@@ -598,13 +592,11 @@
info->rti_ifa = ifa_ifwithroute(flags, sa, sa,
fibnum);
}
- if (needref && info->rti_ifa != NULL) {
+ if (info->rti_ifa != NULL) {
if (info->rti_ifp == NULL)
info->rti_ifp = info->rti_ifa->ifa_ifp;
- ifa_ref(info->rti_ifa);
} else
error = ENETUNREACH;
- NET_EPOCH_EXIT(et);
return (error);
}
diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -84,7 +84,7 @@
struct nhop_priv **pnh_priv);
static int finalize_nhop(struct nh_control *ctl, struct rt_addrinfo *info,
struct nhop_priv *nh_priv);
-static struct ifnet *get_aifp(const struct nhop_object *nh, int reference);
+static struct ifnet *get_aifp(const struct nhop_object *nh);
static void fill_sdl_from_ifp(struct sockaddr_dl_short *sdl, const struct ifnet *ifp);
static void destroy_nhop_epoch(epoch_context_t ctx);
@@ -120,12 +120,10 @@
* this interface ifp instead of loopback. This is needed to support
* link-local IPv6 loopback communications.
*
- * If @reference is non-zero, found ifp is referenced.
- *
* Returns found ifp.
*/
static struct ifnet *
-get_aifp(const struct nhop_object *nh, int reference)
+get_aifp(const struct nhop_object *nh)
{
struct ifnet *aifp = NULL;
@@ -138,21 +136,15 @@
*/
if ((nh->nh_ifp->if_flags & IFF_LOOPBACK) &&
nh->gw_sa.sa_family == AF_LINK) {
- if (reference)
- aifp = ifnet_byindex_ref(nh->gwl_sa.sdl_index);
- else
- aifp = ifnet_byindex(nh->gwl_sa.sdl_index);
+ aifp = ifnet_byindex(nh->gwl_sa.sdl_index);
if (aifp == NULL) {
DPRINTF("unable to get aifp for %s index %d",
if_name(nh->nh_ifp), nh->gwl_sa.sdl_index);
}
}
- if (aifp == NULL) {
+ if (aifp == NULL)
aifp = nh->nh_ifp;
- if (reference)
- if_ref(aifp);
- }
return (aifp);
}
@@ -297,7 +289,7 @@
nh->nh_ifp = info->rti_ifa->ifa_ifp;
nh->nh_ifa = info->rti_ifa;
/* depends on the gateway */
- nh->nh_aifp = get_aifp(nh, 0);
+ nh->nh_aifp = get_aifp(nh);
/*
* Note some of the remaining data is set by the
@@ -438,7 +430,7 @@
nh->nh_ifa = info->rti_ifa;
if (info->rti_ifp != NULL)
nh->nh_ifp = info->rti_ifp;
- nh->nh_aifp = get_aifp(nh, 0);
+ nh->nh_aifp = get_aifp(nh);
return (0);
}
@@ -512,6 +504,26 @@
return (nh_priv);
}
+static bool
+reference_nhop_deps(struct nhop_object *nh)
+{
+ if (!ifa_try_ref(nh->nh_ifa))
+ return (false);
+ nh->nh_aifp = get_aifp(nh);
+ if (!if_try_ref(nh->nh_aifp)) {
+ ifa_free(nh->nh_ifa);
+ return (false);
+ }
+ DPRINTF("AIFP: %p nh_ifp %p", nh->nh_aifp, nh->nh_ifp);
+ if (!if_try_ref(nh->nh_ifp)) {
+ ifa_free(nh->nh_ifa);
+ if_rele(nh->nh_aifp);
+ return (false);
+ }
+
+ return (true);
+}
+
/*
* Alocates/references the remaining bits of nexthop data and links
* it to the hash table.
@@ -522,9 +534,7 @@
finalize_nhop(struct nh_control *ctl, struct rt_addrinfo *info,
struct nhop_priv *nh_priv)
{
- struct nhop_object *nh;
-
- nh = nh_priv->nh;
+ struct nhop_object *nh = nh_priv->nh;
/* Allocate per-cpu packet counter */
nh->nh_pksent = counter_u64_alloc(M_NOWAIT);
@@ -535,15 +545,17 @@
return (ENOMEM);
}
+ if (!reference_nhop_deps(nh)) {
+ counter_u64_free(nh->nh_pksent);
+ uma_zfree(nhops_zone, nh);
+ RTSTAT_INC(rts_nh_alloc_failure);
+ DPRINTF("nh_alloc_finalize failed - reference failure");
+ return (EAGAIN);
+ }
+
/* Save vnet to ease destruction */
nh_priv->nh_vnet = curvnet;
- /* Reference external objects and calculate (referenced) ifa */
- if_ref(nh->nh_ifp);
- ifa_ref(nh->nh_ifa);
- nh->nh_aifp = get_aifp(nh, 1);
- DPRINTF("AIFP: %p nh_ifp %p", nh->nh_aifp, nh->nh_ifp);
-
refcount_init(&nh_priv->nh_refcnt, 1);
/* Please see nhop_free() comments on the initial value */
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -589,12 +589,9 @@
error = rt_getifa_fib(info, rnh->rib_fibnum);
if (error)
return (error);
- } else {
- ifa_ref(info->rti_ifa);
}
error = nhop_create_from_info(rnh, info, &nh);
- ifa_free(info->rti_ifa);
if (error != 0)
return (error);
@@ -912,7 +909,6 @@
change_nhop(struct rib_head *rnh, struct rt_addrinfo *info,
struct nhop_object *nh_orig, struct nhop_object **nh_new)
{
- int free_ifa = 0;
int error;
/*
@@ -926,24 +922,15 @@
(info->rti_info[RTAX_IFA] != NULL &&
!sa_equal(info->rti_info[RTAX_IFA], nh_orig->nh_ifa->ifa_addr))) {
error = rt_getifa_fib(info, rnh->rib_fibnum);
- if (info->rti_ifa != NULL)
- free_ifa = 1;
if (error != 0) {
- if (free_ifa) {
- ifa_free(info->rti_ifa);
- info->rti_ifa = NULL;
- }
-
+ info->rti_ifa = NULL;
return (error);
}
}
error = nhop_create_from_nhop(rnh, nh_orig, info, nh_new);
- if (free_ifa) {
- ifa_free(info->rti_ifa);
- info->rti_ifa = NULL;
- }
+ info->rti_ifa = NULL;
return (error);
}
diff --git a/sys/net/route/route_ifaddrs.c b/sys/net/route/route_ifaddrs.c
--- a/sys/net/route/route_ifaddrs.c
+++ b/sys/net/route/route_ifaddrs.c
@@ -143,7 +143,6 @@
struct rt_addrinfo info;
struct sockaddr_dl null_sdl;
struct ifnet *ifp;
- struct ifaddr *rti_ifa = NULL;
ifp = ifa->ifa_ifp;
@@ -153,12 +152,8 @@
info.rti_ifp = V_loif;
if (cmd == RTM_ADD) {
/* explicitly specify (loopback) ifa */
- if (info.rti_ifp != NULL) {
- rti_ifa = ifaof_ifpforaddr(ifa->ifa_addr, info.rti_ifp);
- if (rti_ifa != NULL)
- ifa_ref(rti_ifa);
- info.rti_ifa = rti_ifa;
- }
+ if (info.rti_ifp != NULL)
+ info.rti_ifa = ifaof_ifpforaddr(ifa->ifa_addr, info.rti_ifp);
}
info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC | RTF_PINNED;
info.rti_info[RTAX_DST] = ia;
@@ -168,9 +163,6 @@
error = rib_action(ifp->if_fib, cmd, &info, &rc);
NET_EPOCH_EXIT(et);
- if (rti_ifa != NULL)
- ifa_free(rti_ifa);
-
if (error == 0 ||
(cmd == RTM_ADD && error == EEXIST) ||
(cmd == RTM_DELETE && (error == ENOENT || error == ESRCH)))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 28, 9:06 AM (5 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16213674
Default Alt Text
D28837.diff (7 KB)
Attached To
Mode
D28837: Simplify ifa/ifp refcounting in the routing stack.
Attached
Detach File
Event Timeline
Log In to Comment