git: 34066d0008b6 - main - routing: add iterator-based nhop traversal KPI.

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Tue, 25 Apr 2023 11:15:29 UTC
The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=34066d0008b6b5f0c7f9fbef8d82e468aaf3f7cf

commit 34066d0008b6b5f0c7f9fbef8d82e468aaf3f7cf
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-04-25 10:55:16 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-04-25 10:55:16 +0000

    routing: add iterator-based nhop traversal KPI.
    
    MFC after:      2 weeks
---
 sys/net/route/nhop_ctl.c  | 50 +++++++++++++++++++++++++++++++++++++++++++++++
 sys/net/route/route_ctl.h | 13 ++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index d99b78351952..3b7cab0cdd35 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -1076,6 +1076,56 @@ nhops_update_ifmtu(struct rib_head *rh, struct ifnet *ifp, uint32_t mtu)
 
 }
 
+struct nhop_object *
+nhops_iter_start(struct nhop_iter *iter)
+{
+	if (iter->rh == NULL)
+		iter->rh = rt_tables_get_rnh_safe(iter->fibnum, iter->family);
+	if (iter->rh != NULL) {
+		struct nh_control *ctl = iter->rh->nh_control;
+
+		NHOPS_RLOCK(ctl);
+
+		iter->_i = 0;
+		iter->_next = CHT_FIRST(&ctl->nh_head, iter->_i);
+
+		return (nhops_iter_next(iter));
+	} else
+		return (NULL);
+}
+
+struct nhop_object *
+nhops_iter_next(struct nhop_iter *iter)
+{
+	struct nhop_priv *nh_priv = iter->_next;
+
+	if (nh_priv != NULL) {
+		iter->_next = nh_priv->nh_next;
+		return (nh_priv->nh);
+	}
+
+	struct nh_control *ctl = iter->rh->nh_control;
+	while (++iter->_i < ctl->nh_head.hash_size) {
+		nh_priv = CHT_FIRST(&ctl->nh_head, iter->_i);
+		if (nh_priv != NULL) {
+			iter->_next = nh_priv->nh_next;
+			return (nh_priv->nh);
+		}
+	}
+
+	return (NULL);
+}
+
+void
+nhops_iter_stop(struct nhop_iter *iter)
+{
+	if (iter->rh != NULL) {
+		struct nh_control *ctl = iter->rh->nh_control;
+
+		NHOPS_RUNLOCK(ctl);
+	}
+}
+
 /*
  * Prints nexthop @nh data in the provided @buf.
  * Example: nh#33/inet/em0/192.168.0.1
diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h
index d3c457cdeaae..4e4444296a9c 100644
--- a/sys/net/route/route_ctl.h
+++ b/sys/net/route/route_ctl.h
@@ -159,6 +159,19 @@ void ip6_writemask(struct in6_addr *addr6, uint8_t mask);
 /* Nexthops */
 uint32_t nhops_get_count(struct rib_head *rh);
 
+struct nhop_priv;
+struct nhop_iter {
+	uint32_t		fibnum;
+	uint8_t			family;
+	struct rib_head		*rh;
+	int			_i;
+	struct nhop_priv	*_next;
+};
+
+struct nhop_object *nhops_iter_start(struct nhop_iter *iter);
+struct nhop_object *nhops_iter_next(struct nhop_iter *iter);
+void nhops_iter_stop(struct nhop_iter *iter);
+
 /* Multipath */
 struct weightened_nhop;