git: 000250be0d2d - main - routing: add abitity to set the protocol that installed route/nexthop.

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Thu, 08 Sep 2022 09:19:23 UTC
The branch main has been updated by melifaro:

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

commit 000250be0d2dc7a241f1c9b9c27d941af781ca46
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-09-08 09:05:53 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2022-09-08 09:18:32 +0000

    routing: add abitity to set the protocol that installed route/nexthop.
    
    Routing daemons such as bird need to know if they install certain route
     so they can clean it up on startup, as a form of achieving consistent
     state during the crash recovery.
    Currently they use combination of routing flags (RTF_PROTO1) to detect
     these routes when interacting via route(4) rtsock protocol.
    Netlink protocol has a special "rtm_protocol" field that is filled and
     checked by the route originator. To prepare for the upcoming netlink
     introduction, add ability to record origing to both nexthops and
     nexthop groups via <nhop|nhgrp>_<get|set>_origin() KPI. The actual
     calls will be used in the followup commits.
    
    MFC after:      1 month
---
 sys/net/route.c           |  1 +
 sys/net/route/nhgrp_ctl.c | 12 ++++++++++++
 sys/net/route/nhgrp_var.h |  3 ++-
 sys/net/route/nhop.h      | 10 ++++++++++
 sys/net/route/nhop_ctl.c  | 12 ++++++++++++
 sys/net/route/nhop_var.h  |  1 +
 sys/net/route/route_ctl.c |  1 +
 7 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/sys/net/route.c b/sys/net/route.c
index 08cee070847f..7d46ba2588ed 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -217,6 +217,7 @@ rib_add_redirect(u_int fibnum, struct sockaddr *dst, struct sockaddr *gateway,
 	nhop_set_pxtype_flag(nh, NHF_HOST);
 	nhop_set_expire(nh, lifetime_sec + time_uptime);
 	nhop_set_redirect(nh, true);
+	nhop_set_origin(nh, NH_ORIGIN_REDIRECT);
 	rnd.rnd_nhop = nhop_get_nhop(nh, &error);
 	if (error == 0) {
 		error = rib_add_route_px(fibnum, dst, -1,
diff --git a/sys/net/route/nhgrp_ctl.c b/sys/net/route/nhgrp_ctl.c
index ca9e01ed0077..06f46746be4b 100644
--- a/sys/net/route/nhgrp_ctl.c
+++ b/sys/net/route/nhgrp_ctl.c
@@ -852,6 +852,18 @@ nhgrp_get_idx(const struct nhgrp_object *nhg)
 	return (nhg_priv->nhg_idx);
 }
 
+uint8_t
+nhgrp_get_origin(struct nhgrp_object *nhg)
+{
+	return (NHGRP_PRIV(nhg)->nhg_origin);
+}
+
+void
+nhgrp_set_origin(struct nhgrp_object *nhg, uint8_t origin)
+{
+	NHGRP_PRIV(nhg)->nhg_origin = origin;
+}
+
 uint32_t
 nhgrp_get_count(struct rib_head *rh)
 {
diff --git a/sys/net/route/nhgrp_var.h b/sys/net/route/nhgrp_var.h
index 3d894857558d..c1540fbb33cf 100644
--- a/sys/net/route/nhgrp_var.h
+++ b/sys/net/route/nhgrp_var.h
@@ -49,7 +49,8 @@ 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];
+	uint8_t			nhg_origin;	/* protocol which created the group */
+	uint8_t			nhg_spare[2];
 	u_int			nhg_refcount;	/* use refcount */
 	u_int			nhg_linked;	/* refcount(9), == 2 if linked to the list */
 	struct nh_control	*nh_control;	/* parent control structure */
diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h
index 24ddb692efb8..669284e0ac62 100644
--- a/sys/net/route/nhop.h
+++ b/sys/net/route/nhop.h
@@ -199,6 +199,14 @@ void nhop_set_type(struct nhop_object *nh, enum nhop_type nh_type);
 void nhop_set_src(struct nhop_object *nh, struct ifaddr *ifa);
 void nhop_set_transmit_ifp(struct nhop_object *nh, struct ifnet *ifp);
 
+#define	NH_ORIGIN_UNSPEC	0 /* not set */
+#define	NH_ORIGIN_REDIRECT	1 /* kernel-originated redirect */
+#define	NH_ORIGIN_KERNEL	2 /* kernel (interface) routes */
+#define	NH_ORIGIN_BOOT		3 /* kernel-originated routes at boot */
+#define	NH_ORIGIN_STATIC	4 /* route(8) routes */
+void nhop_set_origin(struct nhop_object *nh, uint8_t origin);
+uint8_t nhop_get_origin(struct nhop_object *nh);
+
 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);
@@ -217,6 +225,8 @@ struct rib_head *nhop_get_rh(const struct nhop_object *nh);
 
 struct nhgrp_object;
 uint32_t nhgrp_get_uidx(const struct nhgrp_object *nhg);
+uint8_t nhgrp_get_origin(struct nhgrp_object *nhg);
+void nhgrp_set_origin(struct nhgrp_object *nhg, uint8_t origin);
 #endif /* _KERNEL */
 
 /* Kernel <> userland structures */
diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index e4195d106d01..033a99acab1b 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -1012,6 +1012,18 @@ nhop_get_rh(const struct nhop_object *nh)
 	return (rt_tables_get_rnh(fibnum, family));
 }
 
+uint8_t
+nhop_get_origin(struct nhop_object *nh)
+{
+	return (nh->nh_priv->nh_origin);
+}
+
+void
+nhop_set_origin(struct nhop_object *nh, uint8_t origin)
+{
+	nh->nh_priv->nh_origin = origin;
+}
+
 void
 nhops_update_ifmtu(struct rib_head *rh, struct ifnet *ifp, uint32_t mtu)
 {
diff --git a/sys/net/route/nhop_var.h b/sys/net/route/nhop_var.h
index c3c442a4bfa3..ace14556a14c 100644
--- a/sys/net/route/nhop_var.h
+++ b/sys/net/route/nhop_var.h
@@ -87,6 +87,7 @@ struct nhop_priv {
 	u_int			nh_refcnt;	/* number of references, refcount(9)  */
 	u_int			nh_linked;	/* refcount(9), == 2 if linked to the list */
 	int			nh_finalized;	/* non-zero if finalized() was called */
+	uint8_t			nh_origin;	/* protocol that originated the nexthop */
 	struct nhop_object	*nh;		/* backreference to the dataplane nhop */
 	struct nh_control	*nh_control;	/* backreference to the rnh */
 	struct nhop_priv	*nh_next;	/* hash table membership */
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index a9ea2ad49103..d6c382735902 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -622,6 +622,7 @@ rib_copy_route(struct rtentry *rt, const struct route_nhop_data *rnd_src,
 		return (ENOMEM);
 	}
 	nhop_copy(nh, rnd_src->rnd_nhop);
+	nhop_set_origin(nh, nhop_get_origin(rnd_src->rnd_nhop));
 	nhop_set_fibnum(nh, rh_dst->rib_fibnum);
 	nh = nhop_get_nhop_internal(rh_dst, nh, &error);
 	if (error != 0) {