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
This commit is contained in:
Alexander V. Chernikov 2023-02-23 17:38:18 +00:00
parent 98c666cf87
commit d2deebe21b
2 changed files with 43 additions and 8 deletions

View File

@ -823,6 +823,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;
}
}

View File

@ -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);
}