From nobody Mon Jul 13 14:58:00 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gzQXs5CPJz6lLpf; Mon, 13 Jul 2026 14:58:05 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (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 "smtp.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gzQXs3xWwz3prT; Mon, 13 Jul 2026 14:58:05 +0000 (UTC) (envelope-from bz@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1783954685; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=3BB5QCU5CIQcWtWrCKJ0ohqB5bXnJ22MVBcu7CWbfyc=; b=XPSYB64fdkQuODeFoqnUmZqonZJ86MneWNZxZktZ43rLiIoFB1UO89Tf+N7CU/Ws8Umn0o zvxoiVep1eYOpRLBftNL0IlrybO3+G1FQm24I1Z+ltKvITAoUP7YClJhPHjB5G3dgPD2Vh gkBTLhZsiOiPrLhWwd/eQO1XrWC44bRSSISrUv65WPynN3i58sziDEH+Kl4Uig3WwoiQ4/ 41lRotZCKKRavjBvMMe1oGdv/jeYoObGgXO0FzVpT/w9gktH2kF0AEWKWidnczK620NKDn 8HGKH1KFgzQMe7KgK92pCeQNB9GK+7QOSboijVMpIS6bg9WVnB+eVwhZivyZzQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1783954685; a=rsa-sha256; cv=none; b=E+iiK5HIqaNGQkIABAPZuAhoxMRstbw8821HJZUOQOkDTraB07eFMsGFHxQaHKti/PxJVM 8K8vl8Bk+Ktv/U9kzCAZuuAq2VEkuHOuk3CZ78gLoUZpinwHaVw+0kx8xUQosdo3xeQLIv suNQ/YCLaaOFbJ5wa8sFPUMzx2MNOrBzocyWCBqGDrCFIYK/8V9n7TKty+YM7KIlh7JGby H5XCrMD0g/v4/mseihKjf2xK2o+yQKLizOeNWT+gMFA+22Kk9nqTTTYofOJXbA1TX7XOdv s+U/VeiVJo0f7xMY64M9x1oBskYBFpNVKfH2zAZMXlyU+OTPJzhMPo5YVYnWYg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1783954685; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=3BB5QCU5CIQcWtWrCKJ0ohqB5bXnJ22MVBcu7CWbfyc=; b=U5WHTuxnxB1MEu1hUelmcKESl25X5+pDOeFu4pd8jfu5K1U31GL0GSLn5O6HD/spQ29MdN RZXZfvU/GPFUzFOdR4/o627J1uUNnaRFKL4p4Dd99KA96Bs4p81WM2VEUwff9DrSATVyov mNSgegZTPPrfPR4bXOX9Ef3y8uKQv3C16rQIvctlmYqd/q12tKFb/tSpJJJfs82UR4OY8g 4zCv700jBFPEKVRcEUUbzpL8HLkZgnYyPBPCa53RKSrK6HdxcynX1MiWkSIucMHkOUgHE9 I/mSQEZQ2GG07sXe58ml3WLSM7s+RADRjjlWTFhk94l0b4EWPJHtOSLekkONPg== Received: from mx-01.divo.sbone.de (mx-01.divo.sbone.de [IPv6:2003:a:140a:2200:6:594:fffe:19]) (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 ECDSA (prime256v1) client-digest SHA256) (Client CN "mx-01.divo.sbone.de", Issuer "YE2" (not verified)) (Authenticated sender: bz/mail) by smtp.freebsd.org (Postfix) with ESMTPSA id 4gzQXs1P4HzBG5; Mon, 13 Jul 2026 14:58:05 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from mail.sbone.de (mail.sbone.de [IPv6:fde9:577b:c1a9:4902:0:7404:2:1025]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by mx-01.divo.sbone.de (Postfix) with ESMTPS id E0971A64805; Mon, 13 Jul 2026 14:57:33 +0000 (UTC) Received: from content-filter.t4-02.sbone.de (content-filter.t4-02.sbone.de [IPv6:fde9:577b:c1a9:4902:0:7404:2:2742]) (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) (No client certificate requested) by mail.sbone.de (Postfix) with ESMTPS id CF9822D029E9; Mon, 13 Jul 2026 14:58:02 +0000 (UTC) X-Virus-Scanned: amavisd-new at sbone.de Received: from mail.sbone.de ([IPv6:fde9:577b:c1a9:4902:0:7404:2:1025]) by content-filter.t4-02.sbone.de (content-filter.t4-02.sbone.de [IPv6:fde9:577b:c1a9:4902:0:7404:2:2742]) (amavisd-new, port 10024) with ESMTP id bl2ZtpCtGkAD; Mon, 13 Jul 2026 14:58:00 +0000 (UTC) Received: from nv.t4-02.sbone.de (nv.t4-02.sbone.de [IPv6:fde9:577b:c1a9:4902:0:7404:2:22]) (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) (No client certificate requested) by mail.sbone.de (Postfix) with ESMTPSA id D39A32D029D8; Mon, 13 Jul 2026 14:58:00 +0000 (UTC) Date: Mon, 13 Jul 2026 14:58:00 +0000 (UTC) From: "Bjoern A. Zeeb" To: Pouria Mousavizadeh Tehrani cc: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: Re: git: d05d1f256082 - main - routing: Subscribe nhops to ifnet link events In-Reply-To: <6a5298de.25070.b0bcc3b@gitrepo.freebsd.org> Message-ID: <3p674769-n07-n27p-o386-531r93405499@mnoonqbm.arg> References: <6a5298de.25070.b0bcc3b@gitrepo.freebsd.org> X-OpenPGP-Key-Id: 0x14003F198FEFA3E77207EE8D2B58B8F83CCF1842 List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed On Sat, 11 Jul 2026, Pouria Mousavizadeh Tehrani wrote: > The branch main has been updated by pouria: > > URL: https://cgit.FreeBSD.org/src/commit/?id=d05d1f25608230edd300d59b96da6521b409d4f3 > > commit d05d1f25608230edd300d59b96da6521b409d4f3 > Author: Pouria Mousavizadeh Tehrani > AuthorDate: 2026-07-08 19:55:46 +0000 > Commit: Pouria Mousavizadeh Tehrani > CommitDate: 2026-07-11 18:23:05 +0000 > > routing: Subscribe nhops to ifnet link events > > Update nexthop flags with interface link status events and > instead of checking link status of interface for every packet > only check the reachability flag of the final nexthop. > > Reviewed by: glebius > Discussed with: markj > Differential Revision: https://reviews.freebsd.org/D57375 > --- > sys/net/route.h | 4 +-- > sys/net/route/nhop.h | 8 +----- > sys/net/route/nhop_ctl.c | 68 +++++++++++++++++++++++++++++++++++++++++++++-- > sys/net/route/route_ctl.h | 1 + > sys/netinet/in_fib.c | 6 ++--- > sys/netinet6/in6_fib.c | 6 ++--- > 6 files changed, 75 insertions(+), 18 deletions(-) > > diff --git a/sys/net/route.h b/sys/net/route.h > index d8cc12a39c61..b4440de19d96 100644 > --- a/sys/net/route.h > +++ b/sys/net/route.h > @@ -205,6 +205,7 @@ EVENTHANDLER_DECLARE(rtnumfibs_change, rtnumfibs_change_t); > #define NHF_BROADCAST 0x0100 /* RTF_BROADCAST */ > #define NHF_GATEWAY 0x0200 /* RTF_GATEWAY */ > #define NHF_HOST 0x0400 /* RTF_HOST */ > +#define NHF_INVALID 0x0800 /* Nexthop is unreachable */ > > /* Nexthop request flags */ > #define NHR_NONE 0x00 /* empty flags field */ > @@ -368,9 +369,6 @@ struct rt_addrinfo { > > #ifdef _KERNEL > > -#define RT_LINK_IS_UP(ifp) (!((ifp)->if_capabilities & IFCAP_LINKSTATE) \ > - || (ifp)->if_link_state == LINK_STATE_UP) > - > #define RO_NHFREE(_ro) do { \ > if ((_ro)->ro_nh) { \ > NH_FREE((_ro)->ro_nh); \ > diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h > index 6c62ae2f2f5f..0ae41cbf8292 100644 > --- a/sys/net/route/nhop.h > +++ b/sys/net/route/nhop.h > @@ -145,14 +145,8 @@ struct nhop_object { > > /* > * Nhop validness. > - * > - * Currently we verify whether link is up or not on every packet, which can be > - * quite costy. > - * TODO: subscribe for the interface notifications and update the nexthops > - * with NHF_INVALID flag. > */ > - > -#define NH_IS_VALID(_nh) RT_LINK_IS_UP((_nh)->nh_ifp) > +#define NH_IS_VALID(_nh) (!((_nh)->nh_flags & NHF_INVALID)) > #define NH_IS_NHGRP(_nh) ((_nh)->nh_flags & NHF_MULTIPATH) > > #define NH_FREE(_nh) do { \ > diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c > index 9ef5bbc74a92..4f013908b338 100644 > --- a/sys/net/route/nhop_ctl.c > +++ b/sys/net/route/nhop_ctl.c You need to include eventhandler.h or what it is (as it's currently only leaked in through vnet code): 24 /sys/net/route/nhop_ctl.c:114:2: error: call to undeclared function 'EVENTHANDLER_REGISTER'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration] 25 114 | EVENTHANDLER_REGISTER(ifnet_event, nhops_ifnet_event, NULL, 26 | ^ 27 /sys/net/route/nhop_ctl.c:114:24: error: use of undeclared identifier 'ifnet_event' 28 114 | EVENTHANDLER_REGISTER(ifnet_event, nhops_ifnet_event, NULL, 29 | ^~~~~~~~~~~ 30 /sys/net/route/nhop_ctl.c:115:6: error: use of undeclared identifier 'EVENTHANDLER_PRI_ANY' 31 115 | EVENTHANDLER_PRI_ANY); 32 | ^~~~~~~~~~~~~~~~~~~~ 33 /sys/net/route/nhop_ctl.c:116:24: error: use of undeclared identifier 'ifnet_link_event' 34 116 | EVENTHANDLER_REGISTER(ifnet_link_event, nhops_ifnet_link_event, NULL, 35 | ^~~~~~~~~~~~~~~~ 36 /sys/net/route/nhop_ctl.c:117:6: error: use of undeclared identifier 'EVENTHANDLER_PRI_ANY' 37 117 | EVENTHANDLER_PRI_ANY); 38 | ^~~~~~~~~~~~~~~~~~~~ 39 5 errors generated. 40 --- nhop_ctl.o --- 41 *** [nhop_ctl.o] Error code 1 > @@ -90,6 +90,8 @@ static void fill_sdl_from_ifp(struct sockaddr_dl_short *sdl, const struct ifnet > > static void destroy_nhop_epoch(epoch_context_t ctx); > static void destroy_nhop(struct nhop_object *nh); > +static void nhops_ifnet_event(void *arg, struct ifnet *ifp, int state); > +static void nhops_ifnet_link_event(void *arg, struct ifnet *ifp, int state); > > _Static_assert(__offsetof(struct nhop_object, nh_ifp) == 32, > "nhop_object: wrong nh_ifp offset"); > @@ -109,6 +111,10 @@ nhops_init(void) > nhops_zone = uma_zcreate("routing nhops", > NHOP_OBJECT_ALIGNED_SIZE + NHOP_PRIV_ALIGNED_SIZE, > NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); > + EVENTHANDLER_REGISTER(ifnet_event, nhops_ifnet_event, NULL, > + EVENTHANDLER_PRI_ANY); > + EVENTHANDLER_REGISTER(ifnet_link_event, nhops_ifnet_link_event, NULL, > + EVENTHANDLER_PRI_ANY); > } > > /* > @@ -1109,7 +1115,10 @@ nhops_iter_start(struct nhop_iter *iter) > if (iter->rh != NULL) { > struct nh_control *ctl = iter->rh->nh_control; > > - NHOPS_RLOCK(ctl); > + if (iter->wlock) > + NHOPS_WLOCK(ctl); > + else > + NHOPS_RLOCK(ctl); > > iter->_i = 0; > iter->_next = CHT_FIRST(&ctl->nh_head, iter->_i); > @@ -1147,7 +1156,10 @@ nhops_iter_stop(struct nhop_iter *iter) > if (iter->rh != NULL) { > struct nh_control *ctl = iter->rh->nh_control; > > - NHOPS_RUNLOCK(ctl); > + if (iter->wlock) > + NHOPS_WUNLOCK(ctl); > + else > + NHOPS_RUNLOCK(ctl); > } > } > > @@ -1317,3 +1329,55 @@ nhops_dump_sysctl(struct rib_head *rh, struct sysctl_req *w) > > return (0); > } > + > +static void > +nhops_ifnet_state_changed(struct ifnet *ifp, bool status) > +{ > + struct nhop_object *nh; > + struct nhop_iter iter = { .fibnum = ifp->if_fib, .wlock = true }; > + > + for (iter.family = 1; iter.family <= AF_MAX; iter.family++) { > + iter.rh = rt_tables_get_rnh_safe(iter.fibnum, iter.family); > + for (nh = nhops_iter_start(&iter); nh != NULL; > + nh = nhops_iter_next(&iter)) { > + if (nh->nh_ifp != ifp) > + continue; > + > + if (status) > + nh->nh_flags &= ~NHF_INVALID; > + else > + nh->nh_flags |= NHF_INVALID; > + } > + nhops_iter_stop(&iter); > + } > +} > + > +static void > +nhops_ifnet_event(void *arg __unused, struct ifnet *ifp, int state) > +{ > + > + if ((ifp->if_flags & IFF_DYING) != 0 || > + (state != IFNET_EVENT_UP && state != IFNET_EVENT_DOWN)) > + return; > + > + nhops_ifnet_state_changed(ifp, state == IFNET_EVENT_UP); > +} > + > +static void > +nhops_ifnet_link_event(void *arg __unused, struct ifnet *ifp, int state) > +{ > +#ifdef VIMAGE > + /* > + * rib_head will be calculated from V_tables in rt_tables_get_rnh > + * and the VNET is destroyed. > + */ > + if (VNET_IS_SHUTTING_DOWN(ifp->if_vnet)) > + return; > +#endif > + > + if ((ifp->if_flags & IFF_DYING) != 0 || > + (state != LINK_STATE_UP && state != LINK_STATE_DOWN)) > + return; > + > + nhops_ifnet_state_changed(ifp, state == LINK_STATE_UP); > +} > diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h > index 845df8ce1fbe..2e34b2a35c25 100644 > --- a/sys/net/route/route_ctl.h > +++ b/sys/net/route/route_ctl.h > @@ -164,6 +164,7 @@ struct nhop_iter { > struct rib_head *rh; > int _i; > struct nhop_priv *_next; > + const bool wlock; > }; > > struct nhop_object *nhops_iter_start(struct nhop_iter *iter); > diff --git a/sys/netinet/in_fib.c b/sys/netinet/in_fib.c > index d8e373bf3dc2..d864bce07315 100644 > --- a/sys/netinet/in_fib.c > +++ b/sys/netinet/in_fib.c > @@ -117,7 +117,7 @@ fib4_lookup(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, > if (nh != NULL) { > nh = nhop_select(nh, flowid); > /* Ensure route & ifp is UP */ > - if (RT_LINK_IS_UP(nh->nh_ifp)) { > + if (NH_IS_VALID(nh)) { > if (flags & NHR_REF) > nhop_ref_object(nh); > return (nh); > @@ -154,7 +154,7 @@ fib4_lookup(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, > if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { > nh = nhop_select((RNTORT(rn))->rt_nhop, flowid); > /* Ensure route & ifp is UP */ > - if (RT_LINK_IS_UP(nh->nh_ifp)) { > + if (NH_IS_VALID(nh)) { > if (flags & NHR_REF) > nhop_ref_object(nh); > RIB_RUNLOCK(rh); > @@ -320,7 +320,7 @@ fib4_lookup_debugnet(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, > if (rt != NULL) { > struct nhop_object *nh = nhop_select(rnd.rnd_nhop, 0); > /* Ensure route & ifp is UP */ > - if (RT_LINK_IS_UP(nh->nh_ifp)) > + if (NH_IS_VALID(nh)) > return (nh); > } > > diff --git a/sys/netinet6/in6_fib.c b/sys/netinet6/in6_fib.c > index c851a5bd14c5..594a9dc0a24e 100644 > --- a/sys/netinet6/in6_fib.c > +++ b/sys/netinet6/in6_fib.c > @@ -125,7 +125,7 @@ fib6_lookup(uint32_t fibnum, const struct in6_addr *dst6, > if (nh != NULL) { > nh = nhop_select(nh, flowid); > /* Ensure route & ifp is UP */ > - if (RT_LINK_IS_UP(nh->nh_ifp)) { > + if (NH_IS_VALID(nh)) { > if (flags & NHR_REF) > nhop_ref_object(nh); > return (nh); > @@ -163,7 +163,7 @@ fib6_lookup(uint32_t fibnum, const struct in6_addr *dst6, > if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { > nh = nhop_select((RNTORT(rn))->rt_nhop, flowid); > /* Ensure route & ifp is UP */ > - if (RT_LINK_IS_UP(nh->nh_ifp)) { > + if (NH_IS_VALID(nh)) { > if (flags & NHR_REF) > nhop_ref_object(nh); > RIB_RUNLOCK(rh); > @@ -335,7 +335,7 @@ fib6_lookup_debugnet(uint32_t fibnum, const struct in6_addr *dst6, > if (rt != NULL) { > struct nhop_object *nh = nhop_select(rnd.rnd_nhop, 0); > /* Ensure route & ifp is UP */ > - if (RT_LINK_IS_UP(nh->nh_ifp)) > + if (NH_IS_VALID(nh)) > return (nh); > } > > > -- Bjoern A. Zeeb r15:7