git: db4ca19002c0 - main - routing: add ability to store opaque indentifiers in nhops/nhgs

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Mon, 29 Aug 2022 12:59:36 UTC
The branch main has been updated by melifaro:

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

commit db4ca19002c05d0bf83e85a5402005c9162aeee9
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-08-29 12:20:24 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2022-08-29 12:20:28 +0000

    routing: add ability to store opaque indentifiers in nhops/nhgs
    
    This is a pre-requisite for the direct nexthop/nexhop group operations
     via netlink.
    
    MFC after:      2 weeks
---
 sys/net/route/nhgrp.c     |  2 +-
 sys/net/route/nhgrp_ctl.c | 26 +++++++++++++++++++-------
 sys/net/route/nhgrp_var.h |  1 +
 sys/net/route/nhop.h      |  4 ++++
 sys/net/route/nhop_ctl.c  | 12 ++++++++++++
 sys/net/route/nhop_var.h  |  1 +
 sys/net/route/route_ctl.c |  2 +-
 sys/net/route/route_ctl.h |  2 ++
 sys/net/route/route_var.h |  2 --
 9 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/sys/net/route/nhgrp.c b/sys/net/route/nhgrp.c
index f565842bb7d4..358e5d1eaace 100644
--- a/sys/net/route/nhgrp.c
+++ b/sys/net/route/nhgrp.c
@@ -115,7 +115,7 @@ cmp_nhgrp(const struct nhgrp_priv *a, const struct nhgrp_priv *b)
 	 * different set of "data plane" nexthops.
 	 * For now, ignore the data plane and focus on the control plane list.
 	 */
-	if (a->nhg_nh_count != b->nhg_nh_count)
+	if (a->nhg_nh_count != b->nhg_nh_count || a->nhg_uidx != b->nhg_uidx)
 		return (0);
 	return !memcmp(a->nhg_nh_weights, b->nhg_nh_weights,
 	    sizeof(struct weightened_nhop) * a->nhg_nh_count);
diff --git a/sys/net/route/nhgrp_ctl.c b/sys/net/route/nhgrp_ctl.c
index 3a7ebee8def2..90cd5b1e45a0 100644
--- a/sys/net/route/nhgrp_ctl.c
+++ b/sys/net/route/nhgrp_ctl.c
@@ -80,7 +80,7 @@ static int wn_cmp_idx(const void *a, const void *b);
 static void sort_weightened_nhops(struct weightened_nhop *wn, int num_nhops);
 
 static struct nhgrp_priv *get_nhgrp(struct nh_control *ctl,
-    struct weightened_nhop *wn, int num_nhops, int *perror);
+    struct weightened_nhop *wn, int num_nhops, uint32_t uidx, int *perror);
 static void destroy_nhgrp(struct nhgrp_priv *nhg_priv);
 static void destroy_nhgrp_epoch(epoch_context_t ctx);
 static void free_nhgrp_nhops(struct nhgrp_priv *nhg_priv);
@@ -465,7 +465,7 @@ free_nhgrp_nhops(struct nhgrp_priv *nhg_priv)
  */
 struct nhgrp_priv *
 get_nhgrp(struct nh_control *ctl, struct weightened_nhop *wn, int num_nhops,
-    int *perror)
+    uint32_t uidx, int *perror)
 {
 	struct nhgrp_priv *key, *nhg_priv;
 
@@ -497,6 +497,7 @@ get_nhgrp(struct nh_control *ctl, struct weightened_nhop *wn, int num_nhops,
 		*perror = ENOMEM;
 		return (NULL);
 	}
+	key->nhg_uidx = uidx;
 
 	nhg_priv = find_nhgrp(ctl, key);
 	if (nhg_priv != NULL) {
@@ -577,7 +578,7 @@ append_nhops(struct nh_control *ctl, const struct nhgrp_object *gr_orig,
 	memcpy(&pnhops[curr_nhops], wn, num_nhops * sizeof(struct weightened_nhop));
 	curr_nhops += num_nhops;
 
-	nhg_priv = get_nhgrp(ctl, pnhops, curr_nhops, perror);
+	nhg_priv = get_nhgrp(ctl, pnhops, curr_nhops, 0, perror);
 
 	if (pnhops != (struct weightened_nhop *)&storage[0])
 		free(pnhops, M_TEMP);
@@ -598,13 +599,13 @@ append_nhops(struct nh_control *ctl, const struct nhgrp_object *gr_orig,
  */
 int
 nhgrp_get_group(struct rib_head *rh, struct weightened_nhop *wn, int num_nhops,
-    struct nhgrp_object **pnhg)
+    uint32_t uidx, struct nhgrp_object **pnhg)
 {
 	struct nh_control *ctl = rh->nh_control;
 	struct nhgrp_priv *nhg_priv;
 	int error;
 
-	nhg_priv = get_nhgrp(ctl, wn, num_nhops, &error);
+	nhg_priv = get_nhgrp(ctl, wn, num_nhops, uidx, &error);
 	if (nhg_priv != NULL)
 		*pnhg = nhg_priv->nhg;
 
@@ -658,7 +659,7 @@ nhgrp_get_filtered_group(struct rib_head *rh, const struct rtentry *rt,
 		if (nhop_try_ref_object(rnd->rnd_nhop) == 0)
 			error = EAGAIN;
 	} else {
-		mp_priv = get_nhgrp(ctl, pnhops, num_nhops, &error);
+		mp_priv = get_nhgrp(ctl, pnhops, num_nhops, 0, &error);
 		if (mp_priv != NULL)
 			rnd->rnd_nhgrp = mp_priv->nhg;
 		rnd->rnd_weight = 0;
@@ -699,7 +700,7 @@ nhgrp_get_addition_group(struct rib_head *rh, struct route_nhop_data *rnd_orig,
 		/* Simple merge of 2 non-multipath nexthops */
 		wn[1].nh = rnd_orig->rnd_nhop;
 		wn[1].weight = rnd_orig->rnd_weight;
-		nhg_priv = get_nhgrp(ctl, wn, 2, &error);
+		nhg_priv = get_nhgrp(ctl, wn, 2, 0, &error);
 	} else {
 		/* Get new nhop group with @rt->rt_nhop as an additional nhop */
 		nhg_priv = append_nhops(ctl, rnd_orig->rnd_nhgrp, &wn[0], 1,
@@ -731,6 +732,17 @@ nhgrp_get_nhops(const struct nhgrp_object *nhg, uint32_t *pnum_nhops)
 	return (nhg_priv->nhg_nh_weights);
 }
 
+uint32_t
+nhgrp_get_uidx(const struct nhgrp_object *nhg)
+{
+	const struct nhgrp_priv *nhg_priv;
+
+	KASSERT(((nhg->nhg_flags & MPF_MULTIPATH) != 0), ("nhop is not mpath"));
+
+	nhg_priv = NHGRP_PRIV_CONST(nhg);
+	return (nhg_priv->nhg_uidx);
+}
+
 /*
  * Prints nexhop group @nhg data in the provided @buf.
  * Example: nhg#33/sz=3:[#1:100,#2:100,#3:100]
diff --git a/sys/net/route/nhgrp_var.h b/sys/net/route/nhgrp_var.h
index ba90a3feedc8..3d894857558d 100644
--- a/sys/net/route/nhgrp_var.h
+++ b/sys/net/route/nhgrp_var.h
@@ -47,6 +47,7 @@
 
 struct nhgrp_priv {
 	uint32_t		nhg_idx;
+	uint32_t		nhg_uidx;
 	uint8_t			nhg_nh_count;	/* number of items in nh_weights */
 	uint8_t			nhg_spare[3];
 	u_int			nhg_refcount;	/* use refcount */
diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h
index ee4f79d2bb47..9d0891c5b978 100644
--- a/sys/net/route/nhop.h
+++ b/sys/net/route/nhop.h
@@ -199,6 +199,8 @@ void nhop_set_src(struct nhop_object *nh, struct ifaddr *ifa);
 void nhop_set_transmit_ifp(struct nhop_object *nh, struct ifnet *ifp);
 
 uint32_t nhop_get_idx(const struct nhop_object *nh);
+uint32_t nhop_get_uidx(const struct nhop_object *nh);
+void nhop_set_uidx(struct nhop_object *nh, uint32_t uidx);
 enum nhop_type nhop_get_type(const struct nhop_object *nh);
 int nhop_get_rtflags(const struct nhop_object *nh);
 struct vnet *nhop_get_vnet(const struct nhop_object *nh);
@@ -210,6 +212,8 @@ void nhop_set_fibnum(struct nhop_object *nh, uint32_t fibnum);
 uint32_t nhop_get_expire(const struct nhop_object *nh);
 void nhop_set_expire(struct nhop_object *nh, uint32_t expire);
 
+struct nhgrp_object;
+uint32_t nhgrp_get_uidx(const struct nhgrp_object *nhg);
 #endif /* _KERNEL */
 
 /* Kernel <> userland structures */
diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index 46a5c7befd65..4af57d766ab7 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -780,6 +780,18 @@ nhop_get_idx(const struct nhop_object *nh)
 	return (nh->nh_priv->nh_idx);
 }
 
+uint32_t
+nhop_get_uidx(const struct nhop_object *nh)
+{
+	return (nh->nh_priv->nh_uidx);
+}
+
+void
+nhop_set_uidx(struct nhop_object *nh, uint32_t uidx)
+{
+	nh->nh_priv->nh_uidx = uidx;
+}
+
 enum nhop_type
 nhop_get_type(const struct nhop_object *nh)
 {
diff --git a/sys/net/route/nhop_var.h b/sys/net/route/nhop_var.h
index 3cc7da4649a5..c3c442a4bfa3 100644
--- a/sys/net/route/nhop_var.h
+++ b/sys/net/route/nhop_var.h
@@ -79,6 +79,7 @@ struct nhop_priv {
 	uint16_t		nh_type;	/* nexthop type */
 	uint32_t		rt_flags;	/* routing flags for the control plane */
 	uint32_t		nh_expire;	/* path expiration time */
+	uint32_t		nh_uidx;	/* userland-provided index */
 	/* nhop lookup comparison end */
 	uint32_t		nh_idx;		/* nexthop index */
 	uint32_t		nh_fibnum;	/* nexthop fib */
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index dbfa25500df4..8256fa0c7162 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -1181,7 +1181,7 @@ change_mpath_route(struct rib_head *rnh, struct rtentry *rt,
 	wn_new[found_idx].nh = nh_new;
 	wn_new[found_idx].weight = get_info_weight(info, wn[found_idx].weight);
 
-	error = nhgrp_get_group(rnh, wn_new, num_nhops, &rnd_new.rnd_nhgrp);
+	error = nhgrp_get_group(rnh, wn_new, num_nhops, 0, &rnd_new.rnd_nhgrp);
 	nhop_free(nh_new);
 	free(wn_new, M_TEMP);
 
diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h
index 530a8fb5c8f0..1fc67591c2e8 100644
--- a/sys/net/route/route_ctl.h
+++ b/sys/net/route/route_ctl.h
@@ -166,6 +166,8 @@ struct weightened_nhop;
 const struct weightened_nhop *nhgrp_get_nhops(const struct nhgrp_object *nhg,
     uint32_t *pnum_nhops);
 uint32_t nhgrp_get_count(struct rib_head *rh);
+int nhgrp_get_group(struct rib_head *rh, struct weightened_nhop *wn, int num_nhops,
+    uint32_t uidx, struct nhgrp_object **pnhg);
 
 /* Route subscriptions */
 enum rib_subscription_type {
diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h
index 2f21d959387b..51a4285e673e 100644
--- a/sys/net/route/route_var.h
+++ b/sys/net/route/route_var.h
@@ -304,8 +304,6 @@ void nhgrp_ctl_unlink_all(struct nh_control *ctl);
 /* nhgrp_ctl.c */
 int nhgrp_dump_sysctl(struct rib_head *rh, struct sysctl_req *w);
 
-int nhgrp_get_group(struct rib_head *rh, struct weightened_nhop *wn,
-    int num_nhops, struct nhgrp_object **pnhg);
 int nhgrp_get_filtered_group(struct rib_head *rh, const struct rtentry *rt,
     const struct nhgrp_object *src, rib_filter_f_t flt_func, void *flt_data,
     struct route_nhop_data *rnd);