aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2022-07-28 12:18:19 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2022-08-01 07:26:53 +0000
commit2717e958df537b2885fdf42635d7b9dc793719b2 (patch)
treeebace77eb9b568fc3be5eddf92e78710099b8505
parentd22531d5728298deda1ce9f7cdebcd4fd8d9ddb2 (diff)
downloadsrc-2717e958df537b2885fdf42635d7b9dc793719b2.tar.gz
src-2717e958df537b2885fdf42635d7b9dc793719b2.zip
routing: move route expiration time to its nexthop
Expiration time is actually a path property, not a route property. Move its storage to nexthop to simplify upcoming nhop(9) KPI changes and netlink introduction. Differential Revision: https://reviews.freebsd.org/D35970 MFC after: 2 weeks
-rw-r--r--sys/net/route/nhop.h2
-rw-r--r--sys/net/route/nhop_ctl.c25
-rw-r--r--sys/net/route/nhop_var.h2
-rw-r--r--sys/net/route/route_ctl.c23
-rw-r--r--sys/net/route/route_temporal.c20
-rw-r--r--sys/net/route/route_var.h3
-rw-r--r--sys/net/rtsock.c4
7 files changed, 48 insertions, 31 deletions
diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h
index 12bbe163788f..985e4c32ccd3 100644
--- a/sys/net/route/nhop.h
+++ b/sys/net/route/nhop.h
@@ -183,6 +183,8 @@ struct nhop_object *nhop_select_func(struct nhop_object *nh, uint32_t flowid);
int nhop_get_upper_family(const struct nhop_object *nh);
int nhop_get_neigh_family(const struct nhop_object *nh);
uint32_t nhop_get_fibnum(const struct nhop_object *nh);
+uint32_t nhop_get_expire(const struct nhop_object *nh);
+void nhop_set_expire(struct nhop_object *nh, uint32_t expire);
#endif /* _KERNEL */
diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index 4bf7bfb1b416..9f612e354fa6 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -272,6 +272,17 @@ convert_rt_to_nh_flags(int rt_flags)
return (res);
}
+static void
+set_nhop_expire_from_info(struct nhop_object *nh, const struct rt_addrinfo *info)
+{
+ uint32_t nh_expire = 0;
+
+ /* Kernel -> userland timebase conversion. */
+ if ((info->rti_mflags & RTV_EXPIRE) && (info->rti_rmx->rmx_expire > 0))
+ nh_expire = info->rti_rmx->rmx_expire - time_second + time_uptime;
+ nhop_set_expire(nh, nh_expire);
+}
+
static int
fill_nhop_from_info(struct nhop_priv *nh_priv, struct rt_addrinfo *info)
{
@@ -294,6 +305,7 @@ fill_nhop_from_info(struct nhop_priv *nh_priv, struct rt_addrinfo *info)
nh_priv->nh_neigh_family = nh_priv->nh_upper_family;
else
nh_priv->nh_neigh_family = nh->gw_sa.sa_family;
+ set_nhop_expire_from_info(nh, info);
nh->nh_ifp = (info->rti_ifp != NULL) ? info->rti_ifp : info->rti_ifa->ifa_ifp;
nh->nh_ifa = info->rti_ifa;
@@ -802,6 +814,19 @@ nhop_get_fibnum(const struct nhop_object *nh)
return (nh->nh_priv->nh_fibnum);
}
+uint32_t
+nhop_get_expire(const struct nhop_object *nh)
+{
+ return (nh->nh_priv->nh_expire);
+}
+
+void
+nhop_set_expire(struct nhop_object *nh, uint32_t expire)
+{
+ MPASS(!NH_IS_LINKED(nh));
+ nh->nh_priv->nh_expire = expire;
+}
+
void
nhops_update_ifmtu(struct rib_head *rh, struct ifnet *ifp, uint32_t mtu)
{
diff --git a/sys/net/route/nhop_var.h b/sys/net/route/nhop_var.h
index facf8a7a546b..516032cd3756 100644
--- a/sys/net/route/nhop_var.h
+++ b/sys/net/route/nhop_var.h
@@ -78,6 +78,7 @@ struct nhop_priv {
uint8_t nh_neigh_family;/* neighbor address family */
uint16_t nh_type; /* nexthop type */
uint32_t rt_flags; /* routing flags for the control plane */
+ uint32_t nh_expire; /* path expiration time */
/* nhop lookup comparison end */
uint32_t nh_idx; /* nexthop index */
uint32_t nh_fibnum; /* nexthop fib */
@@ -95,6 +96,7 @@ struct nhop_priv {
#define NH_IS_PINNED(_nh) ((!NH_IS_NHGRP(_nh)) && \
((_nh)->nh_priv->rt_flags & RTF_PINNED))
+#define NH_IS_LINKED(_nh) ((_nh)->nh_priv->nh_idx != 0)
/* nhop.c */
struct nhop_priv *find_nhop(struct nh_control *ctl,
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index f8b6a6eb4cd0..1127c504400e 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -416,16 +416,6 @@ rt_get_inet6_prefix_pmask(const struct rtentry *rt, struct in6_addr *paddr,
}
#endif
-static void
-rt_set_expire_info(struct rtentry *rt, const struct rt_addrinfo *info)
-{
-
- /* Kernel -> userland timebase conversion. */
- if (info->rti_mflags & RTV_EXPIRE)
- rt->rt_expire = info->rti_rmx->rmx_expire ?
- info->rti_rmx->rmx_expire - time_second + time_uptime : 0;
-}
-
/*
* Check if specified @gw matches gw data in the nexthop @nh.
*
@@ -702,7 +692,6 @@ create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info,
* examine the ifa and ifa->ifa_ifp if it so desires.
*/
rt->rt_weight = get_info_weight(info, RT_DEFAULT_WEIGHT);
- rt_set_expire_info(rt, info);
*prt = rt;
return (0);
@@ -1112,8 +1101,8 @@ add_route_nhop(struct rib_head *rnh, struct rtentry *rt,
rn = rnh->rnh_addaddr(ndst, netmask, &rnh->head, rt->rt_nodes);
if (rn != NULL) {
- if (rt->rt_expire > 0)
- tmproutes_update(rnh, rt);
+ if (!NH_IS_NHGRP(rnd->rnd_nhop) && nhop_get_expire(rnd->rnd_nhop))
+ tmproutes_update(rnh, rt, rnd->rnd_nhop);
/* Finalize notification */
rib_bump_gen(rnh);
@@ -1136,7 +1125,6 @@ add_route_nhop(struct rib_head *rnh, struct rtentry *rt,
/*
* Switch @rt nhop/weigh to the ones specified in @rnd.
- * Conditionally set rt_expire if set in @info.
* Returns 0 on success.
*/
int
@@ -1151,12 +1139,11 @@ change_route_nhop(struct rib_head *rnh, struct rtentry *rt,
nh_orig = rt->rt_nhop;
if (rnd->rnd_nhop != NULL) {
- /* Changing expiration & nexthop & weight to a new one */
- rt_set_expire_info(rt, info);
+ /* Changing nexthop & weight to a new one */
rt->rt_nhop = rnd->rnd_nhop;
rt->rt_weight = rnd->rnd_weight;
- if (rt->rt_expire > 0)
- tmproutes_update(rnh, rt);
+ if (!NH_IS_NHGRP(rnd->rnd_nhop) && nhop_get_expire(rnd->rnd_nhop))
+ tmproutes_update(rnh, rt, rnd->rnd_nhop);
} else {
/* Route deletion requested. */
struct sockaddr *ndst, *netmask;
diff --git a/sys/net/route/route_temporal.c b/sys/net/route/route_temporal.c
index 935b110db629..edb8ab769bbe 100644
--- a/sys/net/route/route_temporal.c
+++ b/sys/net/route/route_temporal.c
@@ -55,12 +55,13 @@ __FBSDID("$FreeBSD$");
static int
expire_route(const struct rtentry *rt, const struct nhop_object *nh, void *arg)
{
+ uint32_t nh_expire = nhop_get_expire(nh);
time_t *next_callout;
- if (rt->rt_expire == 0)
+ if (nh_expire == 0)
return (0);
- if (rt->rt_expire <= time_uptime)
+ if (nh_expire <= time_uptime)
return (1);
next_callout = (time_t *)arg;
@@ -69,8 +70,8 @@ expire_route(const struct rtentry *rt, const struct nhop_object *nh, void *arg)
* Update next_callout to determine the next ts to
* run the callback at.
*/
- if (*next_callout == 0 || *next_callout > rt->rt_expire)
- *next_callout = rt->rt_expire;
+ if (*next_callout == 0 || *next_callout > nh_expire)
+ *next_callout = nh_expire;
return (0);
}
@@ -78,7 +79,7 @@ expire_route(const struct rtentry *rt, const struct nhop_object *nh, void *arg)
/*
* Per-rnh callout function traversing the tree and deleting
* expired routes. Calculates next callout run by looking at
- * the rt_expire time for the remaining temporal routes.
+ * the nh_expire time for the remaining temporal routes.
*/
static void
expire_callout(void *arg)
@@ -123,26 +124,27 @@ expire_callout(void *arg)
* to the tree. RIB_WLOCK must be held.
*/
void
-tmproutes_update(struct rib_head *rnh, struct rtentry *rt)
+tmproutes_update(struct rib_head *rnh, struct rtentry *rt, struct nhop_object *nh)
{
int seconds;
+ uint32_t nh_expire = nhop_get_expire(nh);
RIB_WLOCK_ASSERT(rnh);
- if (rnh->next_expire == 0 || rnh->next_expire > rt->rt_expire) {
+ if (rnh->next_expire == 0 || rnh->next_expire > nh_expire) {
/*
* Callback is not scheduled, is executing,
* or is scheduled for a later time than we need.
*
* Schedule the one for the current @rt expiration time.
*/
- seconds = (rt->rt_expire - time_uptime);
+ seconds = (nh_expire - time_uptime);
if (seconds < 0)
seconds = 0;
callout_reset_sbt(&rnh->expire_callout, SBT_1S * seconds,
SBT_1MS * 500, expire_callout, rnh, 0);
- rnh->next_expire = rt->rt_expire;
+ rnh->next_expire = nh_expire;
}
}
diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h
index b29b79c88864..60891026c00a 100644
--- a/sys/net/route/route_var.h
+++ b/sys/net/route/route_var.h
@@ -183,7 +183,6 @@ struct rtentry {
int rte_flags; /* up/down?, host/net */
u_long rt_weight; /* absolute weight */
- u_long rt_expire; /* lifetime for route, e.g. redirect */
struct rtentry *rt_chain; /* pointer to next rtentry to delete */
struct epoch_context rt_epoch_ctx; /* net epoch tracker */
};
@@ -214,7 +213,7 @@ struct rtentry {
#define RTE_RT_FLAG_MASK (RTF_UP | RTF_HOST)
/* route_temporal.c */
-void tmproutes_update(struct rib_head *rnh, struct rtentry *rt);
+void tmproutes_update(struct rib_head *rnh, struct rtentry *rt, struct nhop_object *nh);
void tmproutes_init(struct rib_head *rh);
void tmproutes_destroy(struct rib_head *rh);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index bce43397f882..d189af761206 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1293,8 +1293,8 @@ rt_getmetrics(const struct rtentry *rt, const struct nhop_object *nh,
out->rmx_weight = rt->rt_weight;
out->rmx_nhidx = nhop_get_idx(nh);
/* Kernel -> userland timebase conversion. */
- out->rmx_expire = rt->rt_expire ?
- rt->rt_expire - time_uptime + time_second : 0;
+ out->rmx_expire = nhop_get_expire(nh) ?
+ nhop_get_expire(nh) - time_uptime + time_second : 0;
}
/*