The branch stable/13 has been updated by melifaro:

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

commit f054a56ef3e8dc30ba0904d43cf7ec7b3e6e0ed4
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2023-02-23 17:38:18 +0000
Commit:     Alexander V. Chernikov <melif...@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 <zarych...@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);
        }
 

Reply via email to