git: f054a56ef3e8 - stable/13 - netlink: fix addition of blackhole/reject routes.

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
Date: Mon, 27 Feb 2023 10:36:08 UTC
The branch stable/13 has been updated by melifaro:

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

commit f054a56ef3e8dc30ba0904d43cf7ec7b3e6e0ed4
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-02-23 17:38:18 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-02-27 10:29:53 +0000

    netlink: fix addition of blackhole/reject routes.
    
    * Make nhop_set_blackhole() set all necessary properties for the
     nexthop
    * Make nexthops blackhole/reject based on the rtm_type netlink
     property instead of using rtflags.
    
    Reported by:    Marek Zarychta <zarychtam@plan-b.pwste.edu.pl>
    MFC after:      3 days
    
    (cherry picked from commit d2deebe21b591336fbd8915b37d409b25da54d4d)
---
 sys/net/route/nhop_ctl.c | 23 +++++++++++++++++++++++
 sys/netlink/route/rt.c   | 28 ++++++++++++++++++++--------
 2 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index d042d9519f6b..390e5eddd496 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -822,6 +822,29 @@ nhop_set_blackhole(struct nhop_object *nh, int blackhole_rt_flag)
 		nh->nh_flags |= NHF_REJECT;
 		nh->nh_priv->rt_flags |= RTF_REJECT;
 		break;
+	default:
+		/* Not a blackhole nexthop */
+		return;
+	}
+
+	nh->nh_ifp = V_loif;
+	nh->nh_flags &= ~NHF_GATEWAY;
+	nh->nh_priv->rt_flags &= ~RTF_GATEWAY;
+	nh->nh_priv->nh_neigh_family = nh->nh_priv->nh_upper_family;
+
+	bzero(&nh->gw_sa, sizeof(nh->gw_sa));
+
+	switch (nh->nh_priv->nh_upper_family) {
+	case AF_INET:
+		nh->gw4_sa.sin_family = AF_INET;
+		nh->gw4_sa.sin_len = sizeof(struct sockaddr_in);
+		nh->gw4_sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+		break;
+	case AF_INET6:
+		nh->gw6_sa.sin6_family = AF_INET6;
+		nh->gw6_sa.sin6_len = sizeof(struct sockaddr_in6);
+		nh->gw6_sa.sin6_addr = in6addr_loopback;
+		break;
 	}
 }
 
diff --git a/sys/netlink/route/rt.c b/sys/netlink/route/rt.c
index dabdaea3e03b..badd8d937be2 100644
--- a/sys/netlink/route/rt.c
+++ b/sys/netlink/route/rt.c
@@ -458,6 +458,7 @@ struct nl_parsed_route {
 	uint8_t			rtm_family;
 	uint8_t			rtm_dst_len;
 	uint8_t			rtm_protocol;
+	uint8_t			rtm_type;
 };
 
 #define	_IN(_field)	offsetof(struct rtmsg, _field)
@@ -481,9 +482,10 @@ static const struct nlattr_parser nla_p_rtmsg[] = {
 };
 
 static const struct nlfield_parser nlf_p_rtmsg[] = {
-	{.off_in = _IN(rtm_family), .off_out = _OUT(rtm_family), .cb = nlf_get_u8 },
-	{.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_family), .off_out = _OUT(rtm_family), .cb = nlf_get_u8 },
+	{ .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 },
 };
 #undef _IN
 #undef _OUT
@@ -828,13 +830,23 @@ create_nexthop_from_attrs(struct nl_parsed_route *attrs,
 			nhop_set_mtu(nh, attrs->rtax_mtu, true);
 		if (attrs->rta_rtflags & RTF_BROADCAST)
 			nhop_set_broadcast(nh, true);
-		if (attrs->rta_rtflags & RTF_BLACKHOLE)
-			nhop_set_blackhole(nh, NHF_BLACKHOLE);
-		if (attrs->rta_rtflags & RTF_REJECT)
-			nhop_set_blackhole(nh, NHF_REJECT);
-		nhop_set_rtflags(nh, attrs->rta_rtflags);
 		if (attrs->rtm_protocol > RTPROT_STATIC)
 			nhop_set_origin(nh, attrs->rtm_protocol);
+		nhop_set_rtflags(nh, attrs->rta_rtflags);
+
+		switch (attrs->rtm_type) {
+		case RTN_UNICAST:
+			break;
+		case RTN_BLACKHOLE:
+			nhop_set_blackhole(nh, RTF_BLACKHOLE);
+			break;
+		case RTN_PROHIBIT:
+		case RTN_UNREACHABLE:
+			nhop_set_blackhole(nh, RTF_REJECT);
+			break;
+		/* TODO: return ENOTSUP for other types if strict option is set */
+		}
+
 		nh = finalize_nhop(nh, perror);
 	}