mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
networkd: Ability to selectively ignore IPv6 prefixes supplied via router advertisement
Closes https://github.com/systemd/systemd/issues/10647
This commit is contained in:
parent
cdd22d5129
commit
e520ce6440
@ -1606,6 +1606,13 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>BlackList=</varname></term>
|
||||
<listitem>
|
||||
<para>A whitespace-separated list of IPv6 prefixes. IPv6 prefixes supplied via router advertisements in the list are ignored.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -557,6 +557,46 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ndisc_prefix_is_black_listed(Link *link, sd_ndisc_router *rt) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
assert(rt);
|
||||
|
||||
for (r = sd_ndisc_router_option_rewind(rt); ; r = sd_ndisc_router_option_next(rt)) {
|
||||
union in_addr_union a;
|
||||
uint8_t type;
|
||||
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to iterate through options: %m");
|
||||
if (r == 0) /* EOF */
|
||||
return false;
|
||||
|
||||
r = sd_ndisc_router_option_get_type(rt, &type);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get RA option type: %m");
|
||||
|
||||
if (type != SD_NDISC_OPTION_PREFIX_INFORMATION)
|
||||
continue;
|
||||
|
||||
r = sd_ndisc_router_prefix_get_address(rt, &a.in6);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to get prefix address: %m");
|
||||
|
||||
if (set_contains(link->network->ndisc_black_listed_prefix, &a.in6)) {
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
|
||||
(void) in_addr_to_string(AF_INET6, &a, &b);
|
||||
log_link_debug(link, "Prefix '%s' is black listed, ignoring", strna(b));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
uint64_t flags;
|
||||
int r;
|
||||
@ -581,8 +621,10 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
}
|
||||
}
|
||||
|
||||
(void) ndisc_router_process_default(link, rt);
|
||||
(void) ndisc_router_process_options(link, rt);
|
||||
if (ndisc_prefix_is_black_listed(link, rt) == 0) {
|
||||
(void) ndisc_router_process_default(link, rt);
|
||||
(void) ndisc_router_process_options(link, rt);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -672,3 +714,76 @@ void ndisc_flush(Link *link) {
|
||||
link->ndisc_rdnss = set_free_free(link->ndisc_rdnss);
|
||||
link->ndisc_dnssl = set_free_free(link->ndisc_dnssl);
|
||||
}
|
||||
|
||||
int config_parse_ndisc_black_listed_prefix(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Network *network = data;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
network->ndisc_black_listed_prefix = set_free_free(network->ndisc_black_listed_prefix);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = rvalue;;) {
|
||||
_cleanup_free_ char *n = NULL;
|
||||
_cleanup_free_ struct in6_addr *a = NULL;
|
||||
union in_addr_union ip;
|
||||
|
||||
r = extract_first_word(&p, &n, NULL, 0);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse NDISC black listed prefix, ignoring assignment: %s",
|
||||
rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
r = in_addr_from_string(AF_INET6, n, &ip);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"NDISC black listed prefix is invalid, ignoring assignment: %s", n);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = set_ensure_allocated(&network->ndisc_black_listed_prefix, &in6_addr_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
a = newdup(struct in6_addr, &ip.in6, 1);
|
||||
if (!a)
|
||||
return log_oom();
|
||||
|
||||
r = set_put(network->ndisc_black_listed_prefix, a);
|
||||
if (r < 0) {
|
||||
if (r == -EEXIST)
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"NDISC black listed prefixs is duplicated, ignoring assignment: %s", n);
|
||||
else
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store NDISC black listed prefix '%s', ignoring assignment: %m", n);
|
||||
continue;
|
||||
}
|
||||
|
||||
TAKE_PTR(a);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "networkd-link.h"
|
||||
#include "time-util.h"
|
||||
|
||||
@ -21,3 +22,5 @@ static inline char* NDISC_DNSSL_DOMAIN(const NDiscDNSSL *n) {
|
||||
int ndisc_configure(Link *link);
|
||||
void ndisc_vacuum(Link *link);
|
||||
void ndisc_flush(Link *link);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ndisc_black_listed_prefix);
|
||||
|
@ -6,6 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
|
||||
#include "conf-parser.h"
|
||||
#include "network-internal.h"
|
||||
#include "networkd-conf.h"
|
||||
#include "networkd-ndisc.h"
|
||||
#include "networkd-network.h"
|
||||
#include "vlan-util.h"
|
||||
%}
|
||||
@ -162,6 +163,7 @@ IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool,
|
||||
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
|
||||
IPv6AcceptRA.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains)
|
||||
IPv6AcceptRA.RouteTable, config_parse_section_route_table, 0, 0
|
||||
IPv6AcceptRA.BlackList, config_parse_ndisc_black_listed_prefix, 0, 0
|
||||
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_dns)
|
||||
|
@ -505,6 +505,7 @@ static Network *network_free(Network *network) {
|
||||
|
||||
ordered_set_free_free(network->router_search_domains);
|
||||
free(network->router_dns);
|
||||
set_free_free(network->ndisc_black_listed_prefix);
|
||||
|
||||
free(network->bridge_name);
|
||||
free(network->bond_name);
|
||||
|
@ -214,6 +214,7 @@ struct Network {
|
||||
DHCPUseDomains ipv6_accept_ra_use_domains;
|
||||
uint32_t ipv6_accept_ra_route_table;
|
||||
bool ipv6_accept_ra_route_table_set;
|
||||
Set *ndisc_black_listed_prefix;
|
||||
|
||||
union in_addr_union ipv6_token;
|
||||
IPv6PrivacyExtensions ipv6_privacy_extensions;
|
||||
|
@ -198,6 +198,7 @@ RouteTable=
|
||||
UseDNS=
|
||||
UseAutonomousPrefix=
|
||||
UseOnLinkPrefix=
|
||||
BlackList=
|
||||
[DHCPServer]
|
||||
EmitNTP=
|
||||
PoolSize=
|
||||
|
Loading…
Reference in New Issue
Block a user