From owner-dev-commits-src-all@freebsd.org Thu Apr 29 09:17:22 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 7C8A15FEF04; Thu, 29 Apr 2021 09:17:22 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FW8z56RFBz4VLk; Thu, 29 Apr 2021 09:17:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AD5831AA48; Thu, 29 Apr 2021 09:17:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 13T9HLDR032695; Thu, 29 Apr 2021 09:17:21 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 13T9HL6u032694; Thu, 29 Apr 2021 09:17:21 GMT (envelope-from git) Date: Thu, 29 Apr 2021 09:17:21 GMT Message-Id: <202104290917.13T9HL6u032694@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: "Alexander V. Chernikov" Subject: git: 1899138d5ad5 - stable/13 - Fix rib generation count for fib algo. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: melifaro X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 1899138d5ad54a878435b503df8953afe8ab451d Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Apr 2021 09:17:22 -0000 The branch stable/13 has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=1899138d5ad54a878435b503df8953afe8ab451d commit 1899138d5ad54a878435b503df8953afe8ab451d Author: Alexander V. Chernikov AuthorDate: 2021-04-17 18:58:12 +0000 Commit: Alexander V. Chernikov CommitDate: 2021-04-29 08:47:32 +0000 Fix rib generation count for fib algo. Currently, PCB caching mechanism relies on the rib generation counter (rnh_gen) to invalidate cached nhops/LLE entries. With certain fib algorithms, it is now possible that the datapath lookup state applies RIB changes with some delay. In that scenario, PCB cache will invalidate on the RIB change, but the new lookup may result in the same nexthop being returned. When fib algo finally gets in sync with the RIB changes, PCB cache will not receive any notification and will end up caching the stale data. To fix this, introduce additional counter, rnh_gen_rib, which is used only when FIB_ALGO is enabled. This counter is incremented by the control plane. Each time when fib algo synchronises with the RIB, it updates rnh_gen to the current rnh_gen_rib value. Differential Revision: https://reviews.freebsd.org/D29812 Reviewed by: donner MFC after: 2 weeks (cherry picked from commit 33cb3cb2e3212705b10e7885b37f70a3c2987c9e) --- sys/net/route/fib_algo.c | 13 ++++++++++++- sys/net/route/route_ctl.c | 6 +++--- sys/net/route/route_var.h | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/sys/net/route/fib_algo.c b/sys/net/route/fib_algo.c index 171fa2cfb2dd..43db482d73da 100644 --- a/sys/net/route/fib_algo.c +++ b/sys/net/route/fib_algo.c @@ -527,6 +527,13 @@ schedule_fd_rebuild(struct fib_data *fd, const char *reason) } } +static void +sync_rib_gen(struct fib_data *fd) +{ + FD_PRINTF(LOG_DEBUG, fd, "Sync gen %u -> %u", fd->fd_rh->rnh_gen, fd->fd_rh->rnh_gen_rib); + fd->fd_rh->rnh_gen = fd->fd_rh->rnh_gen_rib; +} + static int64_t get_tv_diff_ms(const struct timeval *old_tv, const struct timeval *new_tv) { @@ -682,6 +689,7 @@ apply_rtable_changes(struct fib_data *fd) result = fd->fd_flm->flm_change_rib_items_cb(fd->fd_rh, q, fd->fd_algo_data); if (result == FLM_SUCCESS) { + sync_rib_gen(fd); for (int i = 0; i < q->count; i++) if (q->entries[i].nh_old) fib_unref_nhop(fd, q->entries[i].nh_old); @@ -813,6 +821,7 @@ handle_rtable_change_cb(struct rib_head *rnh, struct rib_cmd_info *rc, switch (result) { case FLM_SUCCESS: + sync_rib_gen(fd); /* Unref old nexthop on success */ if (rc->rc_nh_old != NULL) fib_unref_nhop(fd, rc->rc_nh_old); @@ -1238,7 +1247,9 @@ setup_fd_instance(struct fib_lookup_module *flm, struct rib_head *rh, result = try_setup_fd_instance(flm, rh, prev_fd, &new_fd); if ((result == FLM_SUCCESS) && attach) { - if (!fib_set_datapath_ptr(new_fd, &new_fd->fd_dp)) + if (fib_set_datapath_ptr(new_fd, &new_fd->fd_dp)) + sync_rib_gen(new_fd); + else result = FLM_REBUILD; } diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index af3853041ac6..2ec25c94299d 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -811,7 +811,7 @@ rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info, struct rib_cmd_info rt->rte_flags &= ~RTF_UP; /* Finalize notification */ - rnh->rnh_gen++; + rib_bump_gen(rnh); rnh->rnh_prefixes--; rc->rc_cmd = RTM_DELETE; @@ -1073,7 +1073,7 @@ add_route_nhop(struct rib_head *rnh, struct rtentry *rt, tmproutes_update(rnh, rt); /* Finalize notification */ - rnh->rnh_gen++; + rib_bump_gen(rnh); rnh->rnh_prefixes++; rc->rc_cmd = RTM_ADD; @@ -1129,7 +1129,7 @@ change_route_nhop(struct rib_head *rnh, struct rtentry *rt, } /* Finalize notification */ - rnh->rnh_gen++; + rib_bump_gen(rnh); if (rnd->rnd_nhop == NULL) rnh->rnh_prefixes--; diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h index 427c286a5090..f12931476fd3 100644 --- a/sys/net/route/route_var.h +++ b/sys/net/route/route_var.h @@ -60,7 +60,7 @@ struct rib_head { rn_walktree_t *rnh_walktree; /* traverse tree */ rn_walktree_from_t *rnh_walktree_from; /* traverse tree below a */ rnh_preadd_entry_f_t *rnh_preadd; /* hook to alter record prior to insertion */ - rt_gen_t rnh_gen; /* generation counter */ + rt_gen_t rnh_gen; /* datapath generation counter */ int rnh_multipath; /* multipath capable ? */ struct radix_node rnh_nodes[3]; /* empty tree for common case */ struct rmlock rib_lock; /* config/data path lock */ @@ -71,6 +71,9 @@ struct rib_head { struct callout expire_callout; /* Callout for expiring dynamic routes */ time_t next_expire; /* Next expire run ts */ uint32_t rnh_prefixes; /* Number of prefixes */ +#ifdef FIB_ALGO + rt_gen_t rnh_gen_rib; /* rib generation counter */ +#endif uint32_t rib_dying:1; /* rib is detaching */ uint32_t rib_algo_fixed:1;/* fixed algorithm */ struct nh_control *nh_control; /* nexthop subsystem data */ @@ -116,6 +119,16 @@ CHK_STRUCT_ROUTE_FIELDS(_ro_new); \ _Static_assert(__offsetof(struct route, ro_dst) == __offsetof(_ro_new, _dst_new),\ "ro_dst and " #_dst_new " are at different offset") +static inline void +rib_bump_gen(struct rib_head *rnh) +{ +#ifdef FIB_ALGO + rnh->rnh_gen_rib++; +#else + rnh->rnh_gen++; +#endif +} + struct rib_head *rt_tables_get_rnh(uint32_t table, sa_family_t family); int rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum); struct rib_cmd_info;