git: df7001bad094 - stable/14 - netlink/route: provide pre-2.6.19 Linux compat shim

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Tue, 25 Jun 2024 12:47:34 UTC
The branch stable/14 has been updated by glebius:

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

commit df7001bad09474da00885ed853bc6708019fb292
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2024-06-20 23:10:39 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2024-06-25 12:47:24 +0000

    netlink/route: provide pre-2.6.19 Linux compat shim
    
    The old Linux used 8-bit rtm_table field of the RTM_NEWROUTE message to
    specify routing table id.  Modern netlink uses RTA_TABLE 32-bit attribute.
    
    Unfortunately, there is modern software (namely bird) that would prefer
    the old API as long as the routing table id fits into 8-bit.
    
    PR:             279662
    (cherry picked from commit f34aca55adef1e28cd68b2e6705a0cac03f0238e)
---
 sys/netlink/route/rt.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/sys/netlink/route/rt.c b/sys/netlink/route/rt.c
index ed09748995dc..7379d49b96a9 100644
--- a/sys/netlink/route/rt.c
+++ b/sys/netlink/route/rt.c
@@ -475,6 +475,7 @@ struct nl_parsed_route {
 	uint32_t		rta_nh_id;
 	uint32_t		rta_weight;
 	uint32_t		rtax_mtu;
+	uint8_t			rtm_table;
 	uint8_t			rtm_family;
 	uint8_t			rtm_dst_len;
 	uint8_t			rtm_protocol;
@@ -507,6 +508,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_table), .off_out = _OUT(rtm_table), .cb = nlf_get_u8 },
 	{ .off_in = _IN(rtm_flags), .off_out = _OUT(rtm_flags), .cb = nlf_get_u32 },
 };
 #undef _IN
@@ -939,7 +941,10 @@ rtnl_handle_newroute(struct nlmsghdr *hdr, struct nlpcb *nlp,
 		return (EINVAL);
 	}
 
-	if (attrs.rta_table >= V_rt_numfibs) {
+	if (attrs.rtm_table > 0 && attrs.rta_table == 0) {
+		/* pre-2.6.19 Linux API compatibility */
+		attrs.rta_table = attrs.rtm_table;
+	} else if (attrs.rta_table >= V_rt_numfibs) {
 		NLMSG_REPORT_ERR_MSG(npt, "invalid fib");
 		return (EINVAL);
 	}