networkd: add RouteDenyList

Allow configuration for IPv6 discovered routes to be ignored instead of
adding them as a route. This can be used to block unwanted routes, for
example, you may wish to not receive some set of routes on an interface
if they are causing issues.
This commit is contained in:
Devon Pringle 2020-12-14 16:23:17 +10:00 committed by Yu Watanabe
parent af42881bf9
commit 16c89e649d
6 changed files with 43 additions and 14 deletions

View File

@ -2095,7 +2095,16 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<varlistentry>
<term><varname>DenyList=</varname></term>
<listitem>
<para>A whitespace-separated list of IPv6 prefixes. IPv6 prefixes supplied via router advertisements in the list are ignored.</para>
<para>A whitespace-separated list of IPv6 prefixes. IPv6 prefixes supplied via router
advertisements in the list are ignored.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteDenyList=</varname></term>
<listitem>
<para>A whitespace-separated list of IPv6 route prefixes. IPv6 route prefixes supplied via
router advertisements in the list are ignored.</para>
</listitem>
</varlistentry>

View File

@ -839,6 +839,16 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
if (r < 0)
return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
if (set_contains(link->network->ndisc_deny_listed_route_prefix, &gateway.in6)) {
if (DEBUG_LOGGING) {
_cleanup_free_ char *buf = NULL;
(void) in_addr_to_string(AF_INET6, &gateway, &buf);
log_link_debug(link, "Route Prefix '%s' is deny-listed, ignoring", strnull(buf));
}
return 0;
}
if (link_has_ipv6_address(link, &gateway.in6) == 0) {
if (DEBUG_LOGGING) {
_cleanup_free_ char *buf = NULL;
@ -1378,8 +1388,8 @@ int config_parse_ndisc_deny_listed_prefix(
void *data,
void *userdata) {
Network *network = data;
const char *p;
Set **list = data;
bool is_route;
int r;
assert(filename);
@ -1388,11 +1398,13 @@ int config_parse_ndisc_deny_listed_prefix(
assert(data);
if (isempty(rvalue)) {
network->ndisc_deny_listed_prefix = set_free_free(network->ndisc_deny_listed_prefix);
*list = set_free_free(*list);
return 0;
}
for (p = rvalue;;) {
is_route = streq_ptr(lvalue, "RouteDenyList");
for (const char *p = rvalue;;) {
_cleanup_free_ char *n = NULL;
_cleanup_free_ struct in6_addr *a = NULL;
union in_addr_union ip;
@ -1402,8 +1414,8 @@ int config_parse_ndisc_deny_listed_prefix(
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse NDisc deny-listed prefix, ignoring assignment: %s",
rvalue);
"Failed to parse NDisc deny-listed %sprefix, ignoring assignment: %s",
is_route ? "route " : "", rvalue);
return 0;
}
if (r == 0)
@ -1412,20 +1424,24 @@ int config_parse_ndisc_deny_listed_prefix(
r = in_addr_from_string(AF_INET6, n, &ip);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"NDisc deny-listed prefix is invalid, ignoring assignment: %s", n);
"NDisc deny-listed %sprefix is invalid, ignoring assignment: %s",
is_route ? "route " : "", n);
continue;
}
if (set_contains(network->ndisc_deny_listed_prefix, &ip.in6))
continue;
a = newdup(struct in6_addr, &ip.in6, 1);
if (!a)
return log_oom();
r = set_ensure_consume(&network->ndisc_deny_listed_prefix, &in6_addr_hash_ops, TAKE_PTR(a));
r = set_ensure_consume(list, &in6_addr_hash_ops, TAKE_PTR(a));
if (r < 0)
return log_oom();
if (r == 0)
log_syntax(unit, LOG_WARNING, filename, line, 0,
"NDisc deny-listed %sprefix entry %s is duplicated, ignoring assignment.",
is_route ? "route " : "", n);
if (r > 0)
TAKE_PTR(a);
}
}

View File

@ -237,8 +237,9 @@ IPv6AcceptRA.UseDNS, config_parse_bool,
IPv6AcceptRA.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains)
IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
IPv6AcceptRA.RouteTable, config_parse_section_route_table, 0, 0
IPv6AcceptRA.DenyList, config_parse_ndisc_deny_listed_prefix, 0, 0
IPv6AcceptRA.BlackList, config_parse_ndisc_deny_listed_prefix, 0, 0
IPv6AcceptRA.DenyList, config_parse_ndisc_deny_listed_prefix, 0, offsetof(Network, ndisc_deny_listed_prefix)
IPv6AcceptRA.BlackList, config_parse_ndisc_deny_listed_prefix, 0, offsetof(Network, ndisc_deny_listed_prefix)
IPv6AcceptRA.RouteDenyList, config_parse_ndisc_deny_listed_prefix, 0, offsetof(Network, ndisc_deny_listed_route_prefix)
DHCPServer.MaxLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_max_lease_time_usec)
DHCPServer.DefaultLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_default_lease_time_usec)
DHCPServer.EmitDNS, config_parse_bool, 0, offsetof(Network, dhcp_server_emit[SD_DHCP_LEASE_DNS].emit)

View File

@ -607,6 +607,7 @@ static Network *network_free(Network *network) {
ordered_set_free(network->router_search_domains);
free(network->router_dns);
set_free_free(network->ndisc_deny_listed_prefix);
set_free_free(network->ndisc_deny_listed_route_prefix);
free(network->bridge_name);
free(network->bond_name);

View File

@ -257,6 +257,7 @@ struct Network {
IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client;
uint32_t ipv6_accept_ra_route_table;
Set *ndisc_deny_listed_prefix;
Set *ndisc_deny_listed_route_prefix;
OrderedSet *ipv6_tokens;
/* LLDP support */

View File

@ -312,6 +312,7 @@ UseAutonomousPrefix=
UseOnLinkPrefix=
DenyList=
BlackList=
RouteDenyList=
[DHCPServer]
EmitNTP=
PoolSize=