git: 66230639ce31 - main - routing: split nexthop creation and rtentry creation.

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Wed, 10 Aug 2022 19:04:23 UTC
The branch main has been updated by melifaro:

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

commit 66230639ce311c9fbc3a92e7039b8577a7577b6e
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-08-04 12:35:31 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2022-08-10 18:27:13 +0000

    routing: split nexthop creation and rtentry creation.
    
    This change is required for the upcoming introduction of the next
     nexhop-based operations KPI, as it will create rtentry and nexthops
     at different stages of route table modification.
    
    Differential Revision: https://reviews.freebsd.org/D36072
    MFC after:      2 weeks
---
 sys/net/route.c           |  7 ++--
 sys/net/route.h           |  3 +-
 sys/net/route/route_ctl.c | 95 ++++++++++++++++++-----------------------------
 3 files changed, 42 insertions(+), 63 deletions(-)

diff --git a/sys/net/route.c b/sys/net/route.c
index 0cf56fc18364..8198bc0883be 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -727,11 +727,12 @@ rt_print(char *buf, int buflen, struct rtentry *rt)
 #endif
 
 void
-rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
+rt_maskedcopy(const struct sockaddr *src, struct sockaddr *dst,
+    const struct sockaddr *netmask)
 {
-	u_char *cp1 = (u_char *)src;
+	const u_char *cp1 = (const u_char *)src;
 	u_char *cp2 = (u_char *)dst;
-	u_char *cp3 = (u_char *)netmask;
+	const u_char *cp3 = (const u_char *)netmask;
 	u_char *cplim = cp2 + *cp3;
 	u_char *cplim2 = cp2 + *cp1;
 
diff --git a/sys/net/route.h b/sys/net/route.h
index 46dc0c555218..931b284b664d 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -423,7 +423,8 @@ int	 rt_addrmsg(int, struct ifaddr *, int);
 int	 rt_routemsg(int, struct rtentry *, struct nhop_object *, int);
 int	 rt_routemsg_info(int, struct rt_addrinfo *, int);
 void	 rt_newmaddrmsg(int, struct ifmultiaddr *);
-void 	 rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);
+void 	 rt_maskedcopy(const struct sockaddr *, struct sockaddr *,
+	    const struct sockaddr *);
 struct rib_head *rt_table_init(int, int, u_int);
 void	rt_table_destroy(struct rib_head *);
 u_int	rt_tables_get_gen(uint32_t table, sa_family_t family);
diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index 34a029746fa1..8f116cd65aa9 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -626,13 +626,38 @@ check_gateway(struct rib_head *rnh, struct sockaddr *dst,
  *  to be stable till the end of the operation (radix rt insertion/change/removal).
  * return errno otherwise.
  */
+static struct rtentry *
+create_rtentry(struct rib_head *rnh, const struct sockaddr *dst,
+    struct sockaddr *netmask)
+{
+	MPASS(dst->sa_len <= sizeof(((struct rtentry *)NULL)->rt_dstb));
+
+	struct rtentry *rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
+	if (rt == NULL)
+		return (NULL);
+	rt->rte_flags = RTF_UP | (netmask == NULL ? RTF_HOST : 0);
+
+	/* Fill in dst, ensuring it's masked if needed. */
+	if (netmask != NULL) {
+		rt_maskedcopy(dst, &rt->rt_dst, netmask);
+	} else
+		bcopy(dst, &rt->rt_dst, dst->sa_len);
+	rt_key(rt) = &rt->rt_dst;
+	/* Set netmask to the storage from info. It will be updated upon insertion */
+	rt_mask(rt) = netmask;
+
+	return (rt);
+}
+
 static int
-create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info,
-    struct rtentry **prt)
+add_route_byinfo(struct rib_head *rnh, struct rt_addrinfo *info,
+    struct rib_cmd_info *rc)
 {
-	struct sockaddr *dst, *ndst, *gateway, *netmask;
-	struct rtentry *rt;
+	struct nhop_object *nh_orig;
+	struct route_nhop_data rnd_orig, rnd_add;
 	struct nhop_object *nh;
+	struct rtentry *rt, *rt_orig;
+	struct sockaddr *dst, *gateway, *netmask;
 	int error, flags;
 
 	dst = info->rti_info[RTAX_DST];
@@ -663,65 +688,17 @@ create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info,
 			return (error);
 	}
 
-	error = nhop_create_from_info(rnh, info, &nh);
-	if (error != 0)
-		return (error);
-
-	rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
-	if (rt == NULL) {
-		nhop_free(nh);
+	if ((rt = create_rtentry(rnh, dst, netmask)) == NULL)
 		return (ENOBUFS);
-	}
-	rt->rte_flags = (RTF_UP | flags) & RTE_RT_FLAG_MASK;
-	rt->rt_nhop = nh;
-
-	/* Fill in dst */
-	memcpy(&rt->rt_dst, dst, dst->sa_len);
-	rt_key(rt) = &rt->rt_dst;
 
-	/*
-	 * point to the (possibly newly malloc'd) dest address.
-	 */
-	ndst = (struct sockaddr *)rt_key(rt);
-
-	/*
-	 * make sure it contains the value we want (masked if needed).
-	 */
-	if (netmask) {
-		rt_maskedcopy(dst, ndst, netmask);
-	} else
-		bcopy(dst, ndst, dst->sa_len);
-	/* Set netmask to the storage from info. It will be updated upon insertion */
-	rt_mask(rt) = netmask;
-
-	/*
-	 * We use the ifa reference returned by rt_getifa_fib().
-	 * This moved from below so that rnh->rnh_addaddr() can
-	 * examine the ifa and  ifa->ifa_ifp if it so desires.
-	 */
-	rt->rt_weight = get_info_weight(info, RT_DEFAULT_WEIGHT);
-
-	*prt = rt;
-	return (0);
-}
-
-static int
-add_route_byinfo(struct rib_head *rnh, struct rt_addrinfo *info,
-    struct rib_cmd_info *rc)
-{
-	struct nhop_object *nh_orig;
-	struct route_nhop_data rnd_orig, rnd_add;
-	struct nhop_object *nh;
-	struct rtentry *rt, *rt_orig;
-	int error;
-
-	error = create_rtentry(rnh, info, &rt);
-	if (error != 0)
+	error = nhop_create_from_info(rnh, info, &nh);
+	if (error != 0) {
+		uma_zfree(V_rtzone, rt);
 		return (error);
+	}
 
-	rnd_add.rnd_nhop = rt->rt_nhop;
-	rnd_add.rnd_weight = rt->rt_weight;
-	nh = rt->rt_nhop;
+	rnd_add.rnd_nhop = nh;
+	rnd_add.rnd_weight = get_info_weight(info, RT_DEFAULT_WEIGHT);
 
 	RIB_WLOCK(rnh);
 	error = add_route(rnh, rt, &rnd_add, rc);