Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Apr 2023 13:50:45 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: c35a43b261f8 - main - netlink: allow exact-match route lookups via RTM_GETROUTE.
Message-ID:  <202304021350.332Dojpt012472@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by melifaro:

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

commit c35a43b261f807fd85b8cc30306112eee9dd62ce
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-04-02 13:47:10 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-04-02 13:47:10 +0000

    netlink: allow exact-match route lookups via RTM_GETROUTE.
    
    Use already-existing RTM_F_PREFIX rtm_flag to indicate that the
     request assumes exact-prefix lookup instead of the
     longest-prefix-match.
    
    MFC after:      2 weeks
---
 sys/net/route/route_ctl.c | 14 ++++++++++++++
 sys/net/route/route_ctl.h |  6 ++----
 sys/netlink/route/rt.c    | 13 ++++++++++---
 3 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index 755765869e84..db3728c3cd88 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -96,6 +96,8 @@ static int delete_route(struct rib_head *rnh, struct rtentry *rt,
 static int rt_delete_conditional(struct rib_head *rnh, struct rtentry *rt,
     int prio, rib_filter_f_t *cb, void *cbdata, struct rib_cmd_info *rc);
 
+static bool fill_pxmask_family(int family, int plen, struct sockaddr *_dst,
+    struct sockaddr **pmask);
 static int get_prio_from_info(const struct rt_addrinfo *info);
 static int nhop_get_prio(const struct nhop_object *nh);
 
@@ -391,6 +393,18 @@ lookup_prefix(struct rib_head *rnh, const struct rt_addrinfo *info,
 	return (rt);
 }
 
+const struct rtentry *
+rib_lookup_prefix_plen(struct rib_head *rnh, struct sockaddr *dst, int plen,
+    struct route_nhop_data *rnd)
+{
+	union sockaddr_union mask_storage;
+	struct sockaddr *netmask = &mask_storage.sa;
+
+	if (fill_pxmask_family(dst->sa_family, plen, dst, &netmask))
+		return (lookup_prefix_bysa(rnh, dst, netmask, rnd));
+	return (NULL);
+}
+
 static bool
 fill_pxmask_family(int family, int plen, struct sockaddr *_dst,
     struct sockaddr **pmask)
diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h
index b65b64fcdaa0..7a4ed804feb7 100644
--- a/sys/net/route/route_ctl.h
+++ b/sys/net/route/route_ctl.h
@@ -123,11 +123,9 @@ struct nhop_object;
 struct nhgrp_object;
 struct ucred;
 
-const struct rtentry *rib_lookup_prefix(uint32_t fibnum, int family,
-    const struct sockaddr *dst, const struct sockaddr *netmask,
+const struct rtentry *
+rib_lookup_prefix_plen(struct rib_head *rnh, struct sockaddr *dst, int plen,
     struct route_nhop_data *rnd);
-const struct rtentry *rib_lookup_lpm(uint32_t fibnum, int family,
-    const struct sockaddr *dst, struct route_nhop_data *rnd);
 
 /* rtentry accessors */
 bool rt_is_host(const struct rtentry *rt);
diff --git a/sys/netlink/route/rt.c b/sys/netlink/route/rt.c
index 6d76390016dd..288ff111a038 100644
--- a/sys/netlink/route/rt.c
+++ b/sys/netlink/route/rt.c
@@ -461,6 +461,7 @@ struct nl_parsed_route {
 	uint8_t			rtm_dst_len;
 	uint8_t			rtm_protocol;
 	uint8_t			rtm_type;
+	uint32_t		rtm_flags;
 };
 
 #define	_IN(_field)	offsetof(struct rtmsg, _field)
@@ -488,6 +489,7 @@ static const struct nlfield_parser nlf_p_rtmsg[] = {
 	{ .off_in = _IN(rtm_dst_len), .off_out = _OUT(rtm_dst_len), .cb = nlf_get_u8 },
 	{ .off_in = _IN(rtm_protocol), .off_out = _OUT(rtm_protocol), .cb = nlf_get_u8 },
 	{ .off_in = _IN(rtm_type), .off_out = _OUT(rtm_type), .cb = nlf_get_u8 },
+	{ .off_in = _IN(rtm_flags), .off_out = _OUT(rtm_flags), .cb = nlf_get_u32 },
 };
 #undef _IN
 #undef _OUT
@@ -581,7 +583,8 @@ handle_rtm_getroute(struct nlpcb *nlp, struct nl_parsed_route *attrs,
 {
 	RIB_RLOCK_TRACKER;
 	struct rib_head *rnh;
-	struct rtentry *rt;
+	const struct rtentry *rt;
+	struct route_nhop_data rnd;
 	uint32_t fibnum = attrs->rta_table;
 	sa_family_t family = attrs->rtm_family;
 
@@ -596,13 +599,17 @@ handle_rtm_getroute(struct nlpcb *nlp, struct nl_parsed_route *attrs,
 
 	RIB_RLOCK(rnh);
 
-	rt = (struct rtentry *)rnh->rnh_matchaddr(attrs->rta_dst, &rnh->head);
+	struct sockaddr *dst = attrs->rta_dst;
+
+	if (attrs->rtm_flags & RTM_F_PREFIX)
+		rt = rib_lookup_prefix_plen(rnh, dst, attrs->rtm_dst_len, &rnd);
+	else
+		rt = (const struct rtentry *)rnh->rnh_matchaddr(dst, &rnh->head);
 	if (rt == NULL) {
 		RIB_RUNLOCK(rnh);
 		return (ESRCH);
 	}
 
-	struct route_nhop_data rnd;
 	rt_get_rnd(rt, &rnd);
 	rnd.rnd_nhop = nhop_select_func(rnd.rnd_nhop, 0);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202304021350.332Dojpt012472>