Page MenuHomeFreeBSD

D28837.diff
No OneTemporary

D28837.diff

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

Mime Type
text/plain
Expires
Tue, Sep 24, 9:58 AM (4 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12654111
Default Alt Text
D28837.diff (7 KB)

Event Timeline