From db4ca19002c05d0bf83e85a5402005c9162aeee9 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Mon, 29 Aug 2022 12:20:24 +0000 Subject: [PATCH] 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);