mirror of
https://github.com/systemd/systemd
synced 2026-03-24 15:55:00 +01:00
Compare commits
8 Commits
57777c9e61
...
801cf85935
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
801cf85935 | ||
|
|
b176d4d377 | ||
|
|
4a906586f8 | ||
|
|
63295b42ae | ||
|
|
a254fab20d | ||
|
|
2b24292692 | ||
|
|
cca07d910a | ||
|
|
74c1ab841f |
@ -2382,12 +2382,12 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>UplinkInterface=</varname></term>
|
<term><varname>UplinkInterface=</varname></term>
|
||||||
<listitem><para>Specifies name or index of uplink interface, or one of the special values
|
<listitem><para>Specifies the name or the index of the uplink interface, or one of the special
|
||||||
<literal>:none</literal> and <literal>:auto</literal>. When emitting DNS, NTP, or SIP servers
|
values <literal>:none</literal> and <literal>:auto</literal>. When emitting DNS, NTP, or SIP
|
||||||
are enabled but no servers are specified, the servers configured in the uplink interface will
|
servers is enabled but no servers are specified, the servers configured in the uplink interface
|
||||||
be emitted. When <literal>:auto</literal>, the link which has default gateway with higher
|
will be emitted. When <literal>:auto</literal>, the link which has a default gateway with the
|
||||||
priority will be automatically selected. When <literal>:none</literal>, no uplink interface
|
highest priority will be automatically selected. When <literal>:none</literal>, no uplink
|
||||||
will be selected. Defaults to <literal>:auto</literal>.</para></listitem>
|
interface will be selected. Defaults to <literal>:auto</literal>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -2586,18 +2586,28 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
for details. Defaults to <literal>medium</literal>.</para></listitem>
|
for details. Defaults to <literal>medium</literal>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>UplinkInterface=</varname></term>
|
||||||
|
<listitem><para>Specifies the name or the index of the uplink interface, or one of the special
|
||||||
|
values <literal>:none</literal> and <literal>:auto</literal>. When emitting DNS servers or
|
||||||
|
search domains is enabled but no servers are specified, the servers configured in the uplink
|
||||||
|
interface will be emitted. When <literal>:auto</literal>, the link which has a default gateway
|
||||||
|
with the highest priority will be automatically selected. When <literal>:none</literal>, no
|
||||||
|
uplink interface will be selected. Defaults to <literal>:auto</literal>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>EmitDNS=</varname></term>
|
<term><varname>EmitDNS=</varname></term>
|
||||||
<term><varname>DNS=</varname></term>
|
<term><varname>DNS=</varname></term>
|
||||||
|
|
||||||
<listitem><para><varname>DNS=</varname> specifies a list of recursive DNS server IPv6 addresses that
|
<listitem><para><varname>DNS=</varname> specifies a list of recursive DNS server IPv6 addresses
|
||||||
are distributed via Router Advertisement messages when <varname>EmitDNS=</varname> is
|
that are distributed via Router Advertisement messages when <varname>EmitDNS=</varname> is true.
|
||||||
true. <varname>DNS=</varname> also takes special value <literal>_link_local</literal>; in that case
|
<varname>DNS=</varname> also takes special value <literal>_link_local</literal>; in that case
|
||||||
the IPv6 link local address is distributed. If <varname>DNS=</varname> is empty, DNS servers are read
|
the IPv6 link local address is distributed. If <varname>DNS=</varname> is empty, DNS servers are
|
||||||
from the [Network] section. If the [Network] section does not contain any DNS servers either, DNS
|
read from the [Network] section. If the [Network] section does not contain any DNS servers
|
||||||
servers from the uplink with the highest priority default route are used. When
|
either, DNS servers from the uplink interface specified in <varname>UplinkInterface=</varname>
|
||||||
<varname>EmitDNS=</varname> is false, no DNS server information is sent in Router Advertisement
|
will be used. When <varname>EmitDNS=</varname> is false, no DNS server information is sent in
|
||||||
messages. <varname>EmitDNS=</varname> defaults to true.</para></listitem>
|
Router Advertisement messages. <varname>EmitDNS=</varname> defaults to true.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -2605,11 +2615,12 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
<term><varname>Domains=</varname></term>
|
<term><varname>Domains=</varname></term>
|
||||||
|
|
||||||
<listitem><para>A list of DNS search domains distributed via Router Advertisement messages when
|
<listitem><para>A list of DNS search domains distributed via Router Advertisement messages when
|
||||||
<varname>EmitDomains=</varname> is true. If <varname>Domains=</varname> is empty, DNS search domains
|
<varname>EmitDomains=</varname> is true. If <varname>Domains=</varname> is empty, DNS search
|
||||||
are read from the [Network] section. If the [Network] section does not contain any DNS search domains
|
domains are read from the [Network] section. If the [Network] section does not contain any DNS
|
||||||
either, DNS search domains from the uplink with the highest priority default route are used. When
|
search domains either, DNS search domains from the uplink interface specified in
|
||||||
<varname>EmitDomains=</varname> is false, no DNS search domain information is sent in Router
|
<varname>UplinkInterface=</varname> will be used. When <varname>EmitDomains=</varname> is false,
|
||||||
Advertisement messages. <varname>EmitDomains=</varname> defaults to true.</para></listitem>
|
no DNS search domain information is sent in Router Advertisement messages.
|
||||||
|
<varname>EmitDomains=</varname> defaults to true.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|||||||
@ -443,8 +443,12 @@ int sd_rtnl_message_new_neigh(sd_netlink *rtnl, sd_netlink_message **ret, uint16
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (nlmsg_type == RTM_NEWNEIGH)
|
if (nlmsg_type == RTM_NEWNEIGH) {
|
||||||
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
|
if (ndm_family == AF_BRIDGE)
|
||||||
|
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
|
||||||
|
else
|
||||||
|
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
|
||||||
|
}
|
||||||
|
|
||||||
ndm = NLMSG_DATA((*ret)->hdr);
|
ndm = NLMSG_DATA((*ret)->hdr);
|
||||||
|
|
||||||
|
|||||||
@ -106,7 +106,7 @@ static int dhcp_server_find_uplink(Link *link, Link **ret) {
|
|||||||
if (link->network->dhcp_server_uplink_index > 0)
|
if (link->network->dhcp_server_uplink_index > 0)
|
||||||
return link_get_by_index(link->manager, link->network->dhcp_server_uplink_index, ret);
|
return link_get_by_index(link->manager, link->network->dhcp_server_uplink_index, ret);
|
||||||
|
|
||||||
if (link->network->dhcp_server_uplink_index == 0) {
|
if (link->network->dhcp_server_uplink_index == UPLINK_INDEX_AUTO) {
|
||||||
/* It is not necessary to propagate error in automatic selection. */
|
/* It is not necessary to propagate error in automatic selection. */
|
||||||
if (manager_find_uplink(link->manager, AF_INET, link, ret) < 0)
|
if (manager_find_uplink(link->manager, AF_INET, link, ret) < 0)
|
||||||
*ret = NULL;
|
*ret = NULL;
|
||||||
@ -663,55 +663,3 @@ int config_parse_dhcp_server_address(
|
|||||||
network->dhcp_server_address_prefixlen = prefixlen;
|
network->dhcp_server_address_prefixlen = prefixlen;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_parse_dhcp_server_uplink(
|
|
||||||
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 = userdata;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(filename);
|
|
||||||
assert(lvalue);
|
|
||||||
assert(rvalue);
|
|
||||||
|
|
||||||
if (isempty(rvalue) || streq(rvalue, ":auto")) {
|
|
||||||
network->dhcp_server_uplink_index = 0; /* uplink will be selected automatically */
|
|
||||||
network->dhcp_server_uplink_name = mfree(network->dhcp_server_uplink_name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (streq(rvalue, ":none")) {
|
|
||||||
network->dhcp_server_uplink_index = -1; /* uplink will not be selected automatically */
|
|
||||||
network->dhcp_server_uplink_name = mfree(network->dhcp_server_uplink_name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = parse_ifindex(rvalue);
|
|
||||||
if (r > 0) {
|
|
||||||
network->dhcp_server_uplink_index = r;
|
|
||||||
network->dhcp_server_uplink_name = mfree(network->dhcp_server_uplink_name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ifname_valid_full(rvalue, IFNAME_VALID_ALTERNATIVE)) {
|
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
|
||||||
"Invalid interface name in %s=, ignoring assignment: %s", lvalue, rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = free_and_strdup_warn(&network->dhcp_server_uplink_name, rvalue);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
network->dhcp_server_uplink_index = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -15,4 +15,3 @@ int request_process_dhcp_server(Request *req);
|
|||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_agent_suboption);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_agent_suboption);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_emit);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_emit);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_address);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_address);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_uplink);
|
|
||||||
|
|||||||
@ -618,12 +618,8 @@ static int link_acquire_dynamic_ipv6_conf(Link *link) {
|
|||||||
|
|
||||||
log_link_debug(link, "Starting IPv6 Router Advertisements");
|
log_link_debug(link, "Starting IPv6 Router Advertisements");
|
||||||
|
|
||||||
r = radv_emit_dns(link);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_warning_errno(link, r, "Failed to configure DNS or Domains in IPv6 Router Advertisement: %m");
|
|
||||||
|
|
||||||
r = sd_radv_start(link->radv);
|
r = sd_radv_start(link->radv);
|
||||||
if (r < 0 && r != -EBUSY)
|
if (r < 0)
|
||||||
return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
|
return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1147,7 +1143,7 @@ static int link_configure(Link *link) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = radv_configure(link);
|
r = link_request_radv(link);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -265,7 +265,7 @@ IPv6AcceptRA.PrefixDenyList, config_parse_ndisc_address_filter,
|
|||||||
IPv6AcceptRA.RouteAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_route_prefix)
|
IPv6AcceptRA.RouteAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_route_prefix)
|
||||||
IPv6AcceptRA.RouteDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_route_prefix)
|
IPv6AcceptRA.RouteDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_route_prefix)
|
||||||
DHCPServer.ServerAddress, config_parse_dhcp_server_address, 0, 0
|
DHCPServer.ServerAddress, config_parse_dhcp_server_address, 0, 0
|
||||||
DHCPServer.UplinkInterface, config_parse_dhcp_server_uplink, 0, 0
|
DHCPServer.UplinkInterface, config_parse_uplink, 0, 0
|
||||||
DHCPServer.RelayTarget, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_server_relay_target)
|
DHCPServer.RelayTarget, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_server_relay_target)
|
||||||
DHCPServer.RelayAgentCircuitId, config_parse_dhcp_server_relay_agent_suboption, 0, offsetof(Network, dhcp_server_relay_agent_circuit_id)
|
DHCPServer.RelayAgentCircuitId, config_parse_dhcp_server_relay_agent_suboption, 0, offsetof(Network, dhcp_server_relay_agent_circuit_id)
|
||||||
DHCPServer.RelayAgentRemoteId, config_parse_dhcp_server_relay_agent_suboption, 0, offsetof(Network, dhcp_server_relay_agent_remote_id)
|
DHCPServer.RelayAgentRemoteId, config_parse_dhcp_server_relay_agent_suboption, 0, offsetof(Network, dhcp_server_relay_agent_remote_id)
|
||||||
@ -333,6 +333,7 @@ IPv6SendRA.DNS, config_parse_radv_dns,
|
|||||||
IPv6SendRA.EmitDomains, config_parse_bool, 0, offsetof(Network, router_emit_domains)
|
IPv6SendRA.EmitDomains, config_parse_bool, 0, offsetof(Network, router_emit_domains)
|
||||||
IPv6SendRA.Domains, config_parse_radv_search_domains, 0, 0
|
IPv6SendRA.Domains, config_parse_radv_search_domains, 0, 0
|
||||||
IPv6SendRA.DNSLifetimeSec, config_parse_sec, 0, offsetof(Network, router_dns_lifetime_usec)
|
IPv6SendRA.DNSLifetimeSec, config_parse_sec, 0, offsetof(Network, router_dns_lifetime_usec)
|
||||||
|
IPv6SendRA.UplinkInterface, config_parse_uplink, 0, 0
|
||||||
IPv6Prefix.Prefix, config_parse_prefix, 0, 0
|
IPv6Prefix.Prefix, config_parse_prefix, 0, 0
|
||||||
IPv6Prefix.OnLink, config_parse_prefix_flags, 0, 0
|
IPv6Prefix.OnLink, config_parse_prefix_flags, 0, 0
|
||||||
IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_flags, 0, 0
|
IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_flags, 0, 0
|
||||||
|
|||||||
@ -640,6 +640,7 @@ static Network *network_free(Network *network) {
|
|||||||
|
|
||||||
free(network->dhcp_server_timezone);
|
free(network->dhcp_server_timezone);
|
||||||
free(network->dhcp_server_uplink_name);
|
free(network->dhcp_server_uplink_name);
|
||||||
|
free(network->router_uplink_name);
|
||||||
|
|
||||||
for (sd_dhcp_lease_server_type_t t = 0; t < _SD_DHCP_LEASE_SERVER_TYPE_MAX; t++)
|
for (sd_dhcp_lease_server_type_t t = 0; t < _SD_DHCP_LEASE_SERVER_TYPE_MAX; t++)
|
||||||
free(network->dhcp_server_emit[t].addresses);
|
free(network->dhcp_server_emit[t].addresses);
|
||||||
@ -1185,6 +1186,73 @@ int config_parse_link_group(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int config_parse_uplink(
|
||||||
|
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 = userdata;
|
||||||
|
int *index, r;
|
||||||
|
char **name;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(section);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
|
||||||
|
if (streq(section, "DHCPServer")) {
|
||||||
|
index = &network->dhcp_server_uplink_index;
|
||||||
|
name = &network->dhcp_server_uplink_name;
|
||||||
|
} else if (streq(section, "IPv6SendRA")) {
|
||||||
|
index = &network->router_uplink_index;
|
||||||
|
name = &network->router_uplink_name;
|
||||||
|
} else
|
||||||
|
assert_not_reached();
|
||||||
|
|
||||||
|
if (isempty(rvalue) || streq(rvalue, ":auto")) {
|
||||||
|
*index = UPLINK_INDEX_AUTO;
|
||||||
|
*name = mfree(*name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq(rvalue, ":none")) {
|
||||||
|
*index = UPLINK_INDEX_NONE;
|
||||||
|
*name = mfree(*name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = parse_ifindex(rvalue);
|
||||||
|
if (r > 0) {
|
||||||
|
*index = r;
|
||||||
|
*name = mfree(*name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ifname_valid_full(rvalue, IFNAME_VALID_ALTERNATIVE)) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Invalid interface name in %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The interface name will be resolved later. */
|
||||||
|
r = free_and_strdup_warn(name, rvalue);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* Note, if uplink_name is set, then uplink_index will be ignored. So, the below does not mean
|
||||||
|
* an uplink interface will be selected automatically. */
|
||||||
|
*index = UPLINK_INDEX_AUTO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online, link_required_address_family, AddressFamily,
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online, link_required_address_family, AddressFamily,
|
||||||
"Failed to parse RequiredFamilyForOnline= setting");
|
"Failed to parse RequiredFamilyForOnline= setting");
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,10 @@
|
|||||||
#include "resolve-util.h"
|
#include "resolve-util.h"
|
||||||
#include "socket-netlink.h"
|
#include "socket-netlink.h"
|
||||||
|
|
||||||
|
/* Special values for *_uplink_index. */
|
||||||
|
#define UPLINK_INDEX_AUTO 0 /* uplink will be selected automatically */
|
||||||
|
#define UPLINK_INDEX_NONE -1 /* uplink will not be selected automatically */
|
||||||
|
|
||||||
typedef enum KeepConfiguration {
|
typedef enum KeepConfiguration {
|
||||||
KEEP_CONFIGURATION_NO = 0,
|
KEEP_CONFIGURATION_NO = 0,
|
||||||
KEEP_CONFIGURATION_DHCP_ON_START = 1 << 0,
|
KEEP_CONFIGURATION_DHCP_ON_START = 1 << 0,
|
||||||
@ -224,6 +228,8 @@ struct Network {
|
|||||||
struct in6_addr *router_dns;
|
struct in6_addr *router_dns;
|
||||||
unsigned n_router_dns;
|
unsigned n_router_dns;
|
||||||
OrderedSet *router_search_domains;
|
OrderedSet *router_search_domains;
|
||||||
|
int router_uplink_index;
|
||||||
|
char *router_uplink_name;
|
||||||
|
|
||||||
/* DHCPv6 Prefix Delegation support */
|
/* DHCPv6 Prefix Delegation support */
|
||||||
int dhcp6_pd;
|
int dhcp6_pd;
|
||||||
@ -364,6 +370,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration);
|
|||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy);
|
CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_link_group);
|
CONFIG_PARSER_PROTOTYPE(config_parse_link_group);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_uplink);
|
||||||
|
|
||||||
const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
|
const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
|
||||||
|
|
||||||
|
|||||||
@ -43,6 +43,8 @@ static void request_free_object(RequestType type, void *object) {
|
|||||||
case REQUEST_TYPE_NEXTHOP:
|
case REQUEST_TYPE_NEXTHOP:
|
||||||
nexthop_free(object);
|
nexthop_free(object);
|
||||||
break;
|
break;
|
||||||
|
case REQUEST_TYPE_RADV:
|
||||||
|
break;
|
||||||
case REQUEST_TYPE_ROUTE:
|
case REQUEST_TYPE_ROUTE:
|
||||||
route_free(object);
|
route_free(object);
|
||||||
break;
|
break;
|
||||||
@ -110,7 +112,7 @@ static void request_hash_func(const Request *req, struct siphash *state) {
|
|||||||
trivial_hash_func(req->object, state);
|
trivial_hash_func(req->object, state);
|
||||||
break;
|
break;
|
||||||
case REQUEST_TYPE_DHCP_SERVER:
|
case REQUEST_TYPE_DHCP_SERVER:
|
||||||
/* This type does not have object. */
|
/* This type does not have an object. */
|
||||||
break;
|
break;
|
||||||
case REQUEST_TYPE_IPV6_PROXY_NDP:
|
case REQUEST_TYPE_IPV6_PROXY_NDP:
|
||||||
in6_addr_hash_func(req->ipv6_proxy_ndp, state);
|
in6_addr_hash_func(req->ipv6_proxy_ndp, state);
|
||||||
@ -121,6 +123,9 @@ static void request_hash_func(const Request *req, struct siphash *state) {
|
|||||||
case REQUEST_TYPE_NEXTHOP:
|
case REQUEST_TYPE_NEXTHOP:
|
||||||
nexthop_hash_func(req->nexthop, state);
|
nexthop_hash_func(req->nexthop, state);
|
||||||
break;
|
break;
|
||||||
|
case REQUEST_TYPE_RADV:
|
||||||
|
/* This type does not have an object. */
|
||||||
|
break;
|
||||||
case REQUEST_TYPE_ROUTE:
|
case REQUEST_TYPE_ROUTE:
|
||||||
route_hash_func(req->route, state);
|
route_hash_func(req->route, state);
|
||||||
break;
|
break;
|
||||||
@ -174,6 +179,8 @@ static int request_compare_func(const struct Request *a, const struct Request *b
|
|||||||
return nexthop_compare_func(a->nexthop, b->nexthop);
|
return nexthop_compare_func(a->nexthop, b->nexthop);
|
||||||
case REQUEST_TYPE_ROUTE:
|
case REQUEST_TYPE_ROUTE:
|
||||||
return route_compare_func(a->route, b->route);
|
return route_compare_func(a->route, b->route);
|
||||||
|
case REQUEST_TYPE_RADV:
|
||||||
|
return 0;
|
||||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||||
return routing_policy_rule_compare_func(a->rule, b->rule);
|
return routing_policy_rule_compare_func(a->rule, b->rule);
|
||||||
case REQUEST_TYPE_SET_LINK:
|
case REQUEST_TYPE_SET_LINK:
|
||||||
@ -211,10 +218,14 @@ int link_queue_request(
|
|||||||
assert(IN_SET(type,
|
assert(IN_SET(type,
|
||||||
REQUEST_TYPE_ACTIVATE_LINK,
|
REQUEST_TYPE_ACTIVATE_LINK,
|
||||||
REQUEST_TYPE_DHCP_SERVER,
|
REQUEST_TYPE_DHCP_SERVER,
|
||||||
|
REQUEST_TYPE_RADV,
|
||||||
REQUEST_TYPE_SET_LINK,
|
REQUEST_TYPE_SET_LINK,
|
||||||
REQUEST_TYPE_UP_DOWN) ||
|
REQUEST_TYPE_UP_DOWN) ||
|
||||||
object);
|
object);
|
||||||
assert(type == REQUEST_TYPE_DHCP_SERVER || netlink_handler);
|
assert(IN_SET(type,
|
||||||
|
REQUEST_TYPE_DHCP_SERVER,
|
||||||
|
REQUEST_TYPE_RADV) ||
|
||||||
|
netlink_handler);
|
||||||
|
|
||||||
req = new(Request, 1);
|
req = new(Request, 1);
|
||||||
if (!req) {
|
if (!req) {
|
||||||
@ -298,6 +309,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
|
|||||||
case REQUEST_TYPE_NEXTHOP:
|
case REQUEST_TYPE_NEXTHOP:
|
||||||
r = request_process_nexthop(req);
|
r = request_process_nexthop(req);
|
||||||
break;
|
break;
|
||||||
|
case REQUEST_TYPE_RADV:
|
||||||
|
r = request_process_radv(req);
|
||||||
|
break;
|
||||||
case REQUEST_TYPE_ROUTE:
|
case REQUEST_TYPE_ROUTE:
|
||||||
r = request_process_route(req);
|
r = request_process_route(req);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -31,6 +31,7 @@ typedef enum RequestType {
|
|||||||
REQUEST_TYPE_IPV6_PROXY_NDP,
|
REQUEST_TYPE_IPV6_PROXY_NDP,
|
||||||
REQUEST_TYPE_NEIGHBOR,
|
REQUEST_TYPE_NEIGHBOR,
|
||||||
REQUEST_TYPE_NEXTHOP,
|
REQUEST_TYPE_NEXTHOP,
|
||||||
|
REQUEST_TYPE_RADV,
|
||||||
REQUEST_TYPE_ROUTE,
|
REQUEST_TYPE_ROUTE,
|
||||||
REQUEST_TYPE_ROUTING_POLICY_RULE,
|
REQUEST_TYPE_ROUTING_POLICY_RULE,
|
||||||
REQUEST_TYPE_SET_LINK,
|
REQUEST_TYPE_SET_LINK,
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include "networkd-link.h"
|
#include "networkd-link.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
#include "networkd-network.h"
|
#include "networkd-network.h"
|
||||||
|
#include "networkd-queue.h"
|
||||||
#include "networkd-radv.h"
|
#include "networkd-radv.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
@ -583,10 +584,7 @@ static int radv_set_dns(Link *link, Link *uplink) {
|
|||||||
goto set_dns;
|
goto set_dns;
|
||||||
|
|
||||||
if (uplink) {
|
if (uplink) {
|
||||||
if (!uplink->network) {
|
assert(uplink->network);
|
||||||
log_link_debug(uplink, "Cannot fetch DNS servers as uplink interface is not managed by us");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = network_get_ipv6_dns(uplink->network, &dns, &n_dns);
|
r = network_get_ipv6_dns(uplink->network, &dns, &n_dns);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
@ -595,7 +593,7 @@ static int radv_set_dns(Link *link, Link *uplink) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
set_dns:
|
set_dns:
|
||||||
return sd_radv_set_rdnss(link->radv,
|
return sd_radv_set_rdnss(link->radv,
|
||||||
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
|
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
|
||||||
dns, n_dns);
|
dns, n_dns);
|
||||||
@ -622,10 +620,7 @@ static int radv_set_domains(Link *link, Link *uplink) {
|
|||||||
goto set_domains;
|
goto set_domains;
|
||||||
|
|
||||||
if (uplink) {
|
if (uplink) {
|
||||||
if (!uplink->network) {
|
assert(uplink->network);
|
||||||
log_link_debug(uplink, "Cannot fetch DNS search domains as uplink interface is not managed by us");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
search_domains = uplink->network->search_domains;
|
search_domains = uplink->network->search_domains;
|
||||||
if (search_domains)
|
if (search_domains)
|
||||||
@ -634,7 +629,7 @@ static int radv_set_domains(Link *link, Link *uplink) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
set_domains:
|
set_domains:
|
||||||
s = ordered_set_get_strv(search_domains);
|
s = ordered_set_get_strv(search_domains);
|
||||||
if (!s)
|
if (!s)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
@ -645,20 +640,23 @@ static int radv_set_domains(Link *link, Link *uplink) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int radv_emit_dns(Link *link) {
|
static int radv_find_uplink(Link *link, Link **ret) {
|
||||||
Link *uplink = NULL;
|
assert(link);
|
||||||
int r;
|
|
||||||
|
|
||||||
(void) manager_find_uplink(link->manager, AF_INET6, link, &uplink);
|
if (link->network->router_uplink_name)
|
||||||
|
return link_get_by_name(link->manager, link->network->router_uplink_name, ret);
|
||||||
|
|
||||||
r = radv_set_dns(link, uplink);
|
if (link->network->router_uplink_index > 0)
|
||||||
if (r < 0)
|
return link_get_by_index(link->manager, link->network->router_uplink_index, ret);
|
||||||
log_link_warning_errno(link, r, "Could not set RA DNS: %m");
|
|
||||||
|
|
||||||
r = radv_set_domains(link, uplink);
|
if (link->network->router_uplink_index == UPLINK_INDEX_AUTO) {
|
||||||
if (r < 0)
|
/* It is not necessary to propagate error in automatic selection. */
|
||||||
log_link_warning_errno(link, r, "Could not set RA Domains: %m");
|
if (manager_find_uplink(link->manager, AF_INET6, link, ret) < 0)
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,8 +669,9 @@ static bool link_radv_enabled(Link *link) {
|
|||||||
return link->network->router_prefix_delegation;
|
return link->network->router_prefix_delegation;
|
||||||
}
|
}
|
||||||
|
|
||||||
int radv_configure(Link *link) {
|
static int radv_configure(Link *link) {
|
||||||
uint16_t router_lifetime;
|
uint16_t router_lifetime;
|
||||||
|
Link *uplink = NULL;
|
||||||
RoutePrefix *q;
|
RoutePrefix *q;
|
||||||
Prefix *p;
|
Prefix *p;
|
||||||
int r;
|
int r;
|
||||||
@ -680,9 +679,6 @@ int radv_configure(Link *link) {
|
|||||||
assert(link);
|
assert(link);
|
||||||
assert(link->network);
|
assert(link->network);
|
||||||
|
|
||||||
if (!link_radv_enabled(link))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (link->radv)
|
if (link->radv)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
@ -748,6 +744,16 @@ int radv_configure(Link *link) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(void) radv_find_uplink(link, &uplink);
|
||||||
|
|
||||||
|
r = radv_set_dns(link, uplink);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_debug_errno(link, r, "Could not set RA DNS: %m");
|
||||||
|
|
||||||
|
r = radv_set_domains(link, uplink);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_debug_errno(link, r, "Could not set RA Domains: %m");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -779,6 +785,96 @@ int radv_update_mac(Link *link) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int radv_is_ready_to_configure(Link *link) {
|
||||||
|
bool needs_uplink = false;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(link->network);
|
||||||
|
|
||||||
|
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (in6_addr_is_null(&link->ipv6ll_address))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (link->network->router_emit_dns && !link->network->router_dns) {
|
||||||
|
_cleanup_free_ struct in6_addr *dns = NULL;
|
||||||
|
size_t n_dns;
|
||||||
|
|
||||||
|
r = network_get_ipv6_dns(link->network, &dns, &n_dns);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
needs_uplink = r == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->network->router_emit_domains &&
|
||||||
|
!link->network->router_search_domains &&
|
||||||
|
!link->network->search_domains)
|
||||||
|
needs_uplink = true;
|
||||||
|
|
||||||
|
if (needs_uplink) {
|
||||||
|
Link *uplink = NULL;
|
||||||
|
|
||||||
|
if (radv_find_uplink(link, &uplink) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (uplink && !uplink->network)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int request_process_radv(Request *req) {
|
||||||
|
Link *link;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(req);
|
||||||
|
assert(req->link);
|
||||||
|
assert(req->type == REQUEST_TYPE_RADV);
|
||||||
|
|
||||||
|
link = req->link;
|
||||||
|
|
||||||
|
r = radv_is_ready_to_configure(link);
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = radv_configure(link);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_warning_errno(link, r, "Failed to configure IPv6 Router Advertisement engine: %m");
|
||||||
|
|
||||||
|
if (link_has_carrier(link)) {
|
||||||
|
r = sd_radv_start(link->radv);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_warning_errno(link, r, "Failed to start IPv6 Router Advertisement engine: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
log_link_debug(link, "IPv6 Router Advertisement engine is configured%s.",
|
||||||
|
link_has_carrier(link) ? " and started." : "");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int link_request_radv(Link *link) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
|
||||||
|
if (!link_radv_enabled(link))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (link->radv)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = link_queue_request(link, REQUEST_TYPE_RADV, NULL, false, NULL, NULL, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_warning_errno(link, r, "Failed to request IPv6 Router Advertisement engine: %m");
|
||||||
|
|
||||||
|
log_link_debug(link, "IPv6 Router Advertisement engine is requested.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int radv_add_prefix(
|
int radv_add_prefix(
|
||||||
Link *link,
|
Link *link,
|
||||||
const struct in6_addr *prefix,
|
const struct in6_addr *prefix,
|
||||||
|
|||||||
@ -14,8 +14,9 @@
|
|||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
#include "networkd-util.h"
|
#include "networkd-util.h"
|
||||||
|
|
||||||
typedef struct Network Network;
|
|
||||||
typedef struct Link Link;
|
typedef struct Link Link;
|
||||||
|
typedef struct Network Network;
|
||||||
|
typedef struct Request Request;
|
||||||
|
|
||||||
typedef enum RADVPrefixDelegation {
|
typedef enum RADVPrefixDelegation {
|
||||||
RADV_PREFIX_DELEGATION_NONE = 0,
|
RADV_PREFIX_DELEGATION_NONE = 0,
|
||||||
@ -50,12 +51,13 @@ void network_drop_invalid_prefixes(Network *network);
|
|||||||
void network_drop_invalid_route_prefixes(Network *network);
|
void network_drop_invalid_route_prefixes(Network *network);
|
||||||
void network_adjust_radv(Network *network);
|
void network_adjust_radv(Network *network);
|
||||||
|
|
||||||
int radv_emit_dns(Link *link);
|
|
||||||
int radv_configure(Link *link);
|
|
||||||
int radv_update_mac(Link *link);
|
int radv_update_mac(Link *link);
|
||||||
int radv_add_prefix(Link *link, const struct in6_addr *prefix, uint8_t prefix_len,
|
int radv_add_prefix(Link *link, const struct in6_addr *prefix, uint8_t prefix_len,
|
||||||
uint32_t lifetime_preferred, uint32_t lifetime_valid);
|
uint32_t lifetime_preferred, uint32_t lifetime_valid);
|
||||||
|
|
||||||
|
int request_process_radv(Request *req);
|
||||||
|
int link_request_radv(Link *link);
|
||||||
|
|
||||||
const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;
|
const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;
|
||||||
RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
|
RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
|
|||||||
@ -307,6 +307,7 @@ EmitDNS=
|
|||||||
EmitDomains=
|
EmitDomains=
|
||||||
Managed=
|
Managed=
|
||||||
OtherInformation=
|
OtherInformation=
|
||||||
|
UplinkInterface=
|
||||||
[IPv6PrefixDelegation]
|
[IPv6PrefixDelegation]
|
||||||
RouterPreference=
|
RouterPreference=
|
||||||
DNSLifetimeSec=
|
DNSLifetimeSec=
|
||||||
|
|||||||
7
test/test-network/conf/25-vxlan-ipv6.netdev
Normal file
7
test/test-network/conf/25-vxlan-ipv6.netdev
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[NetDev]
|
||||||
|
Name=vxlan97
|
||||||
|
Kind=vxlan
|
||||||
|
|
||||||
|
[VXLAN]
|
||||||
|
VNI=4831583
|
||||||
|
Local=fe80::281:8eff:fef0:73aa
|
||||||
@ -13,3 +13,7 @@ Prefix=2002:da8:1:0::/64
|
|||||||
[DHCPServer]
|
[DHCPServer]
|
||||||
DNS=192.168.5.1
|
DNS=192.168.5.1
|
||||||
NTP=192.168.5.1
|
NTP=192.168.5.1
|
||||||
|
|
||||||
|
[IPv6SendRA]
|
||||||
|
EmitDNS=no
|
||||||
|
EmitDomains=no
|
||||||
|
|||||||
@ -9,3 +9,4 @@ IPv6AcceptRA=yes
|
|||||||
RouterDenyList=2001::1
|
RouterDenyList=2001::1
|
||||||
PrefixDenyList=2001:db8:0:2::
|
PrefixDenyList=2001:db8:0:2::
|
||||||
RouteDenyList=2001:db1:fff::
|
RouteDenyList=2001:db1:fff::
|
||||||
|
UseDomains=yes
|
||||||
|
|||||||
@ -11,3 +11,4 @@ PrefixAllowList=2001:db8:0:1:: 2001:db8:0:1::
|
|||||||
PrefixDenyList=2001:db8:0:1:: 2001:db8:0:1::
|
PrefixDenyList=2001:db8:0:1:: 2001:db8:0:1::
|
||||||
RouteAllowList=2001:db0:fff:: 2001:db0:fff::
|
RouteAllowList=2001:db0:fff:: 2001:db0:fff::
|
||||||
RouteDenyList=2001:db0:fff:: 2001:db0:fff::
|
RouteDenyList=2001:db0:fff:: 2001:db0:fff::
|
||||||
|
UseDomains=yes
|
||||||
|
|||||||
@ -5,6 +5,9 @@ Name=veth99
|
|||||||
DHCP=no
|
DHCP=no
|
||||||
IPv6SendRA=yes
|
IPv6SendRA=yes
|
||||||
|
|
||||||
|
[IPv6SendRA]
|
||||||
|
UplinkInterface=dummy98
|
||||||
|
|
||||||
[IPv6Prefix]
|
[IPv6Prefix]
|
||||||
Prefix=2001:db8:0:1::/64
|
Prefix=2001:db8:0:1::/64
|
||||||
|
|
||||||
|
|||||||
8
test/test-network/conf/ipv6ra-uplink.network
Normal file
8
test/test-network/conf/ipv6ra-uplink.network
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[Match]
|
||||||
|
Name=dummy98
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
Address=2001:db8:1:1::1/64
|
||||||
|
DNS=2001:db8:1:1::2
|
||||||
|
Domains=example.com
|
||||||
24
test/test-network/conf/vxlan-ipv6.network
Normal file
24
test/test-network/conf/vxlan-ipv6.network
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[Match]
|
||||||
|
Name=vxlan97
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
LinkLocalAddressing=yes
|
||||||
|
|
||||||
|
[BridgeFDB]
|
||||||
|
MACAddress=00:00:00:00:00:00
|
||||||
|
Destination=fe80::27c:16ff:fec0:6c74
|
||||||
|
OutgoingInterface=test1
|
||||||
|
VNI=4831583
|
||||||
|
|
||||||
|
[BridgeFDB]
|
||||||
|
MACAddress=00:00:00:00:00:00
|
||||||
|
Destination=fe80::2a2:e4ff:fef9:2269
|
||||||
|
OutgoingInterface=test1
|
||||||
|
VNI=4831583
|
||||||
|
|
||||||
|
[BridgeFDB]
|
||||||
|
MACAddress=00:00:00:00:00:00
|
||||||
|
Destination=fe80::23b:d2ff:fe95:967f
|
||||||
|
OutgoingInterface=test1
|
||||||
|
VNI=4831583
|
||||||
@ -5,3 +5,4 @@ Name=test1
|
|||||||
IPv6AcceptRA=false
|
IPv6AcceptRA=false
|
||||||
LinkLocalAddressing=yes
|
LinkLocalAddressing=yes
|
||||||
VXLAN=vxlan99
|
VXLAN=vxlan99
|
||||||
|
VXLAN=vxlan97
|
||||||
|
|||||||
@ -854,6 +854,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
|||||||
'vtitun98',
|
'vtitun98',
|
||||||
'vtitun99',
|
'vtitun99',
|
||||||
'vxcan99',
|
'vxcan99',
|
||||||
|
'vxlan97',
|
||||||
'vxlan98',
|
'vxlan98',
|
||||||
'vxlan99',
|
'vxlan99',
|
||||||
'wg97',
|
'wg97',
|
||||||
@ -944,6 +945,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
|||||||
'25-vti-tunnel.netdev',
|
'25-vti-tunnel.netdev',
|
||||||
'25-vxcan.netdev',
|
'25-vxcan.netdev',
|
||||||
'25-vxlan-independent.netdev',
|
'25-vxlan-independent.netdev',
|
||||||
|
'25-vxlan-ipv6.netdev',
|
||||||
'25-vxlan.netdev',
|
'25-vxlan.netdev',
|
||||||
'25-wireguard-23-peers.netdev',
|
'25-wireguard-23-peers.netdev',
|
||||||
'25-wireguard-23-peers.network',
|
'25-wireguard-23-peers.network',
|
||||||
@ -974,6 +976,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
|||||||
'sit.network',
|
'sit.network',
|
||||||
'vti6.network',
|
'vti6.network',
|
||||||
'vti.network',
|
'vti.network',
|
||||||
|
'vxlan-ipv6.network',
|
||||||
'vxlan-test1.network',
|
'vxlan-test1.network',
|
||||||
'vxlan.network',
|
'vxlan.network',
|
||||||
'xfrm.network',
|
'xfrm.network',
|
||||||
@ -1635,36 +1638,43 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
|||||||
|
|
||||||
def test_vxlan(self):
|
def test_vxlan(self):
|
||||||
copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network',
|
copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network',
|
||||||
|
'25-vxlan-ipv6.netdev', 'vxlan-ipv6.network',
|
||||||
'25-vxlan-independent.netdev', 'netdev-link-local-addressing-yes.network',
|
'25-vxlan-independent.netdev', 'netdev-link-local-addressing-yes.network',
|
||||||
'11-dummy.netdev', 'vxlan-test1.network')
|
'11-dummy.netdev', 'vxlan-test1.network')
|
||||||
start_networkd()
|
start_networkd()
|
||||||
|
|
||||||
self.wait_online(['test1:degraded', 'vxlan99:degraded', 'vxlan98:degraded'])
|
self.wait_online(['test1:degraded', 'vxlan99:degraded', 'vxlan98:degraded', 'vxlan97:degraded'])
|
||||||
|
|
||||||
output = check_output('ip -d link show vxlan99')
|
output = check_output('ip -d link show vxlan99')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, '999')
|
self.assertIn('999', output)
|
||||||
self.assertRegex(output, '5555')
|
self.assertIn('5555', output)
|
||||||
self.assertRegex(output, 'l2miss')
|
self.assertIn('l2miss', output)
|
||||||
self.assertRegex(output, 'l3miss')
|
self.assertIn('l3miss', output)
|
||||||
self.assertRegex(output, 'udpcsum')
|
self.assertIn('udpcsum', output)
|
||||||
self.assertRegex(output, 'udp6zerocsumtx')
|
self.assertIn('udp6zerocsumtx', output)
|
||||||
self.assertRegex(output, 'udp6zerocsumrx')
|
self.assertIn('udp6zerocsumrx', output)
|
||||||
self.assertRegex(output, 'remcsumtx')
|
self.assertIn('remcsumtx', output)
|
||||||
self.assertRegex(output, 'remcsumrx')
|
self.assertIn('remcsumrx', output)
|
||||||
self.assertRegex(output, 'gbp')
|
self.assertIn('gbp', output)
|
||||||
|
|
||||||
output = check_output('bridge fdb show dev vxlan99')
|
output = check_output('bridge fdb show dev vxlan99')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, '00:11:22:33:44:55 dst 10.0.0.5 self permanent')
|
self.assertIn('00:11:22:33:44:55 dst 10.0.0.5 self permanent', output)
|
||||||
self.assertRegex(output, '00:11:22:33:44:66 dst 10.0.0.6 self permanent')
|
self.assertIn('00:11:22:33:44:66 dst 10.0.0.6 self permanent', output)
|
||||||
self.assertRegex(output, '00:11:22:33:44:77 dst 10.0.0.7 via test1 self permanent')
|
self.assertIn('00:11:22:33:44:77 dst 10.0.0.7 via test1 self permanent', output)
|
||||||
|
|
||||||
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'vxlan99', env=env)
|
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'vxlan99', env=env)
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'VNI: 999')
|
self.assertIn('VNI: 999', output)
|
||||||
self.assertRegex(output, 'Destination Port: 5555')
|
self.assertIn('Destination Port: 5555', output)
|
||||||
self.assertRegex(output, 'Underlying Device: test1')
|
self.assertIn('Underlying Device: test1', output)
|
||||||
|
|
||||||
|
output = check_output('bridge fdb show dev vxlan97')
|
||||||
|
print(output)
|
||||||
|
self.assertIn('00:00:00:00:00:00 dst fe80::23b:d2ff:fe95:967f via test1 self permanent', output)
|
||||||
|
self.assertIn('00:00:00:00:00:00 dst fe80::27c:16ff:fec0:6c74 via test1 self permanent', output)
|
||||||
|
self.assertIn('00:00:00:00:00:00 dst fe80::2a2:e4ff:fef9:2269 via test1 self permanent', output)
|
||||||
|
|
||||||
def test_macsec(self):
|
def test_macsec(self):
|
||||||
copy_unit_to_networkd_unit_path('25-macsec.netdev', '25-macsec.network', '25-macsec.key',
|
copy_unit_to_networkd_unit_path('25-macsec.netdev', '25-macsec.network', '25-macsec.key',
|
||||||
@ -4685,14 +4695,19 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
|
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
|
||||||
|
|
||||||
class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
|
class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
|
||||||
links = ['veth99']
|
links = [
|
||||||
|
'dummy98',
|
||||||
|
'veth99',
|
||||||
|
]
|
||||||
|
|
||||||
units = [
|
units = [
|
||||||
|
'12-dummy.netdev',
|
||||||
'25-veth.netdev',
|
'25-veth.netdev',
|
||||||
'ipv6ra-prefix-client-deny-list.network',
|
'ipv6ra-prefix-client-deny-list.network',
|
||||||
'ipv6ra-prefix-client.network',
|
'ipv6ra-prefix-client.network',
|
||||||
'ipv6ra-prefix.network'
|
'ipv6ra-prefix.network',
|
||||||
]
|
'ipv6ra-uplink.network',
|
||||||
|
]
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
remove_links(self.links)
|
remove_links(self.links)
|
||||||
@ -4705,10 +4720,11 @@ class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
|
|||||||
stop_networkd(show_logs=True)
|
stop_networkd(show_logs=True)
|
||||||
|
|
||||||
def test_ipv6_route_prefix(self):
|
def test_ipv6_route_prefix(self):
|
||||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6ra-prefix-client.network', 'ipv6ra-prefix.network')
|
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6ra-prefix-client.network', 'ipv6ra-prefix.network',
|
||||||
|
'12-dummy.netdev', 'ipv6ra-uplink.network')
|
||||||
|
|
||||||
start_networkd()
|
start_networkd()
|
||||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
self.wait_online(['veth99:routable', 'veth-peer:routable', 'dummy98:routable'])
|
||||||
|
|
||||||
output = check_output('ip address show dev veth-peer')
|
output = check_output('ip address show dev veth-peer')
|
||||||
print(output)
|
print(output)
|
||||||
@ -4727,11 +4743,20 @@ class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
|
|||||||
self.assertNotIn('inet6 2001:db8:0:1:', output)
|
self.assertNotIn('inet6 2001:db8:0:1:', output)
|
||||||
self.assertIn('inet6 2001:db8:0:2:', output)
|
self.assertIn('inet6 2001:db8:0:2:', output)
|
||||||
|
|
||||||
|
output = check_output(*resolvectl_cmd, 'dns', 'veth-peer', env=env)
|
||||||
|
print(output)
|
||||||
|
self.assertRegex(output, '2001:db8:1:1::2')
|
||||||
|
|
||||||
|
output = check_output(*resolvectl_cmd, 'domain', 'veth-peer', env=env)
|
||||||
|
print(output)
|
||||||
|
self.assertIn('example.com', output)
|
||||||
|
|
||||||
def test_ipv6_route_prefix_deny_list(self):
|
def test_ipv6_route_prefix_deny_list(self):
|
||||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6ra-prefix-client-deny-list.network', 'ipv6ra-prefix.network')
|
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6ra-prefix-client-deny-list.network', 'ipv6ra-prefix.network',
|
||||||
|
'12-dummy.netdev', 'ipv6ra-uplink.network')
|
||||||
|
|
||||||
start_networkd()
|
start_networkd()
|
||||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
self.wait_online(['veth99:routable', 'veth-peer:routable', 'dummy98:routable'])
|
||||||
|
|
||||||
output = check_output('ip address show dev veth-peer')
|
output = check_output('ip address show dev veth-peer')
|
||||||
print(output)
|
print(output)
|
||||||
@ -4750,6 +4775,14 @@ class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
|
|||||||
self.assertNotIn('inet6 2001:db8:0:1:', output)
|
self.assertNotIn('inet6 2001:db8:0:1:', output)
|
||||||
self.assertIn('inet6 2001:db8:0:2:', output)
|
self.assertIn('inet6 2001:db8:0:2:', output)
|
||||||
|
|
||||||
|
output = check_output(*resolvectl_cmd, 'dns', 'veth-peer', env=env)
|
||||||
|
print(output)
|
||||||
|
self.assertRegex(output, '2001:db8:1:1::2')
|
||||||
|
|
||||||
|
output = check_output(*resolvectl_cmd, 'domain', 'veth-peer', env=env)
|
||||||
|
print(output)
|
||||||
|
self.assertIn('example.com', output)
|
||||||
|
|
||||||
class NetworkdMTUTests(unittest.TestCase, Utilities):
|
class NetworkdMTUTests(unittest.TestCase, Utilities):
|
||||||
links = ['dummy98']
|
links = ['dummy98']
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user