git: 0b381e393d40 - stable/13 - routing: add rib_add_default_route() wrapper

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Fri, 13 Jan 2023 21:25:45 UTC
The branch stable/13 has been updated by melifaro:

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

commit 0b381e393d40db2254ea2212c86ad02aeb2d4406
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-08-09 13:34:28 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-01-13 21:24:11 +0000

    routing: add rib_add_default_route() wrapper
    
    Multiple consumers in the kernel space want to install IPv4 or IPv6
     default route. Provide convenient wrapper to simplify the code
     inside the customers.
    
    MFC after:              1 month
    Differential Revision:  https://reviews.freebsd.org/D36167
    
    (cherry picked from commit d8b2693414ae5cebdbd4c64c9559275c4baff11e)
---
 sys/net/route/route_ctl.h     |  4 ++--
 sys/net/route/route_helpers.c | 56 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h
index 5cb7e67120ae..bfd769c3d524 100644
--- a/sys/net/route/route_ctl.h
+++ b/sys/net/route/route_ctl.h
@@ -79,8 +79,8 @@ int rib_match_gw(const struct rtentry *rt, const struct nhop_object *nh,
     void *_data);
 int rib_handle_ifaddr_info(uint32_t fibnum, int cmd, struct rt_addrinfo *info);
 
-int rib_match_gw(const struct rtentry *rt, const struct nhop_object *nh,
-    void *gw_sa);
+int rib_add_default_route(uint32_t fibnum, int family, struct ifnet *ifp,
+    struct sockaddr *gw, struct rib_cmd_info *rc);
 
 typedef void route_notification_t(struct rib_cmd_info *rc, void *);
 void rib_decompose_notification(struct rib_cmd_info *rc,
diff --git a/sys/net/route/route_helpers.c b/sys/net/route/route_helpers.c
index 9f18b9bfcc63..a9d21ebfb507 100644
--- a/sys/net/route/route_helpers.c
+++ b/sys/net/route/route_helpers.c
@@ -409,6 +409,62 @@ rib_decompose_notification(struct rib_cmd_info *rc, route_notification_t *cb,
 }
 #endif
 
+union sockaddr_union {
+	struct sockaddr		sa;
+	struct sockaddr_in	sin;
+	struct sockaddr_in6	sin6;
+	char			_buf[32];
+};
+
+/*
+ * Creates nexhops suitable for using as a default route nhop.
+ * Helper for the various kernel subsystems adding/changing default route.
+ */
+int
+rib_add_default_route(uint32_t fibnum, int family, struct ifnet *ifp,
+    struct sockaddr *gw, struct rib_cmd_info *rc)
+{
+	struct route_nhop_data rnd = { .rnd_weight = RT_DEFAULT_WEIGHT };
+	union sockaddr_union saun = {};
+	struct sockaddr *dst = &saun.sa;
+	int error;
+
+	switch (family) {
+#ifdef INET
+	case AF_INET:
+		saun.sin.sin_family = AF_INET;
+		saun.sin.sin_len = sizeof(struct sockaddr_in);
+		break;
+#endif
+#ifdef INET6
+	case AF_INET6:
+		saun.sin6.sin6_family = AF_INET6;
+		saun.sin6.sin6_len = sizeof(struct sockaddr_in6);
+		break;
+#endif
+	default:
+		return (EAFNOSUPPORT);
+	}
+
+	struct ifaddr *ifa = ifaof_ifpforaddr(gw, ifp);
+	if (ifa == NULL)
+		return (ENOENT);
+
+	struct nhop_object *nh = nhop_alloc(fibnum, family);
+	if (nh == NULL)
+		return (ENOMEM);
+
+	nhop_set_gw(nh, gw, true);
+	nhop_set_transmit_ifp(nh, ifp);
+	nhop_set_src(nh, ifa);
+	nhop_set_pxtype_flag(nh, NHF_DEFAULT);
+	rnd.rnd_nhop = nhop_get_nhop(nh, &error);
+
+	if (error == 0)
+		error = rib_add_route_px(fibnum, dst, 0, &rnd, RTM_F_CREATE, rc);
+	return (error);
+}
+
 #ifdef INET
 /*
  * Checks if the found key in the trie contains (<=) a prefix covering