The branch main has been updated by melifaro:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=2717e958df537b2885fdf42635d7b9dc793719b2

commit 2717e958df537b2885fdf42635d7b9dc793719b2
Author:     Alexander V. Chernikov <[email protected]>
AuthorDate: 2022-07-28 12:18:19 +0000
Commit:     Alexander V. Chernikov <[email protected]>
CommitDate: 2022-08-01 07:26:53 +0000

    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
---
 sys/net/route/nhop.h           |  2 ++
 sys/net/route/nhop_ctl.c       | 25 +++++++++++++++++++++++++
 sys/net/route/nhop_var.h       |  2 ++
 sys/net/route/route_ctl.c      | 23 +++++------------------
 sys/net/route/route_temporal.c | 20 +++++++++++---------
 sys/net/route/route_var.h      |  3 +--
 sys/net/rtsock.c               |  4 ++--
 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;
 }
 
 /*

Reply via email to