Compare commits
3 Commits
65ca546f06
...
43a20059a5
Author | SHA1 | Date |
---|---|---|
Yu Watanabe | 43a20059a5 | |
Yu Watanabe | dc7d3c5fd4 | |
Susant Sahani | 051e77cac1 |
|
@ -986,9 +986,13 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>DuplicateAddressDetection=</varname></term>
|
<term><varname>DuplicateAddressDetection=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Takes a boolean. Do not perform Duplicate Address Detection
|
<para>Takes one of <literal>ipv4</literal>, <literal>ipv6</literal>,
|
||||||
<ulink url="https://tools.ietf.org/html/rfc4862">RFC 4862</ulink> when adding this address.
|
<literal>both</literal>, <literal>none</literal>. When <literal>ipv4</literal>,
|
||||||
Supported only on IPv6. Defaults to false.</para>
|
performs IPv4 Duplicate Address Detection. See
|
||||||
|
<ulink url="https://tools.ietf.org/html/rfc5227">RFC 5224</ulink>.
|
||||||
|
When <literal>ipv6</literal>, performs IPv6 Duplicate Address Detection. See
|
||||||
|
<ulink url="https://tools.ietf.org/html/rfc4862">RFC 4862</ulink>.
|
||||||
|
Defaults to <literal>ipv6</literal>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|
|
@ -32,6 +32,7 @@ int address_new(Address **ret) {
|
||||||
.scope = RT_SCOPE_UNIVERSE,
|
.scope = RT_SCOPE_UNIVERSE,
|
||||||
.cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME,
|
.cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME,
|
||||||
.cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME,
|
.cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME,
|
||||||
|
.duplicate_address_detection = ADDRESS_FAMILY_IPV6,
|
||||||
};
|
};
|
||||||
|
|
||||||
*ret = TAKE_PTR(address);
|
*ret = TAKE_PTR(address);
|
||||||
|
@ -102,7 +103,7 @@ void address_free(Address *address) {
|
||||||
hashmap_remove(address->network->addresses_by_section, address->section);
|
hashmap_remove(address->network->addresses_by_section, address->section);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address->link) {
|
if (address->link && !address->acd) {
|
||||||
set_remove(address->link->addresses, address);
|
set_remove(address->link->addresses, address);
|
||||||
set_remove(address->link->addresses_foreign, address);
|
set_remove(address->link->addresses_foreign, address);
|
||||||
|
|
||||||
|
@ -110,6 +111,8 @@ void address_free(Address *address) {
|
||||||
memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr));
|
memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sd_ipv4acd_unref(address->acd);
|
||||||
|
|
||||||
network_config_section_free(address->section);
|
network_config_section_free(address->section);
|
||||||
free(address->label);
|
free(address->label);
|
||||||
free(address);
|
free(address);
|
||||||
|
@ -587,7 +590,7 @@ int address_configure(
|
||||||
if (address->home_address)
|
if (address->home_address)
|
||||||
address->flags |= IFA_F_HOMEADDRESS;
|
address->flags |= IFA_F_HOMEADDRESS;
|
||||||
|
|
||||||
if (address->duplicate_address_detection)
|
if (!FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV6))
|
||||||
address->flags |= IFA_F_NODAD;
|
address->flags |= IFA_F_NODAD;
|
||||||
|
|
||||||
if (address->manage_temporary_address)
|
if (address->manage_temporary_address)
|
||||||
|
@ -658,9 +661,101 @@ int address_configure(
|
||||||
return log_link_error_errno(link, r, "Could not add address: %m");
|
return log_link_error_errno(link, r, "Could not add address: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (address->acd) {
|
||||||
|
assert(address->family == AF_INET);
|
||||||
|
if (DEBUG_LOGGING) {
|
||||||
|
_cleanup_free_ char *pretty = NULL;
|
||||||
|
|
||||||
|
(void) in_addr_to_string(address->family, &address->in_addr, &pretty);
|
||||||
|
log_debug("Starting IPv4ACD client. Probing address %s", strna(pretty));
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_ipv4acd_start(address->acd);
|
||||||
|
if (r < 0)
|
||||||
|
log_link_warning_errno(link, r, "Failed to start IPv4ACD client, ignoring: %m");
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
|
||||||
|
_cleanup_free_ char *pretty = NULL;
|
||||||
|
Address *address;
|
||||||
|
Link *link;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(acd);
|
||||||
|
assert(userdata);
|
||||||
|
|
||||||
|
address = (Address *) userdata;
|
||||||
|
link = address->link;
|
||||||
|
|
||||||
|
(void) in_addr_to_string(address->family, &address->in_addr, &pretty);
|
||||||
|
switch (event) {
|
||||||
|
case SD_IPV4ACD_EVENT_STOP:
|
||||||
|
log_link_debug(link, "Stopping ACD client...");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SD_IPV4ACD_EVENT_BIND:
|
||||||
|
log_link_debug(link, "Successfully claimed address %s", strna(pretty));
|
||||||
|
link_check_ready(link);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SD_IPV4ACD_EVENT_CONFLICT:
|
||||||
|
log_link_warning(link, "DAD conflict. Dropping address %s", strna(pretty));
|
||||||
|
r = address_remove(address, link, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
log_link_error_errno(link, r, "Failed to drop DAD conflicted address %s", strna(pretty));;
|
||||||
|
|
||||||
|
link_check_ready(link);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert_not_reached("Invalid IPv4ACD event.");
|
||||||
|
}
|
||||||
|
|
||||||
|
sd_ipv4acd_stop(acd);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int configure_ipv4_duplicate_address_detection(Link *link, Address *address) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(address);
|
||||||
|
assert(address->family == AF_INET);
|
||||||
|
assert(!address->link && address->network);
|
||||||
|
|
||||||
|
address->link = link;
|
||||||
|
|
||||||
|
r = sd_ipv4acd_new(&address->acd);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_ipv4acd_attach_event(address->acd, NULL, 0);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_ipv4acd_set_ifindex(address->acd, link->ifindex);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_ipv4acd_set_mac(address->acd, &link->mac);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_ipv4acd_set_address(address->acd, &address->in_addr.in);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_ipv4acd_set_callback(address->acd, static_address_on_acd, address);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int config_parse_broadcast(
|
int config_parse_broadcast(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
|
@ -897,14 +992,12 @@ int config_parse_address_flags(const char *unit,
|
||||||
r = parse_boolean(rvalue);
|
r = parse_boolean(rvalue);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
"Failed to parse address flag, ignoring: %s", rvalue);
|
"Failed to parse %s=, ignoring: %s", lvalue, rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq(lvalue, "HomeAddress"))
|
if (streq(lvalue, "HomeAddress"))
|
||||||
n->home_address = r;
|
n->home_address = r;
|
||||||
else if (streq(lvalue, "DuplicateAddressDetection"))
|
|
||||||
n->duplicate_address_detection = r;
|
|
||||||
else if (streq(lvalue, "ManageTemporaryAddress"))
|
else if (streq(lvalue, "ManageTemporaryAddress"))
|
||||||
n->manage_temporary_address = r;
|
n->manage_temporary_address = r;
|
||||||
else if (streq(lvalue, "PrefixRoute"))
|
else if (streq(lvalue, "PrefixRoute"))
|
||||||
|
@ -961,6 +1054,55 @@ int config_parse_address_scope(const char *unit,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_duplicate_address_detection(
|
||||||
|
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;
|
||||||
|
_cleanup_(address_free_or_set_invalidp) Address *n = NULL;
|
||||||
|
AddressFamily a;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(section);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
r = address_new_static(network, filename, section_line, &n);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = parse_boolean(rvalue);
|
||||||
|
if (r >= 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"For historical reasons, %s=%s means %s=%s. "
|
||||||
|
"Please use 'both', 'ipv4', 'ipv6' or 'none' instead.",
|
||||||
|
lvalue, rvalue, lvalue, r ? "none" : "both");
|
||||||
|
n->duplicate_address_detection = r ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_YES;
|
||||||
|
n = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = duplicate_address_detection_address_family_from_string(rvalue);
|
||||||
|
if (a < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Failed to parse %s=, ignoring: %s", lvalue, rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
n->duplicate_address_detection = a;
|
||||||
|
n = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool address_is_ready(const Address *a) {
|
bool address_is_ready(const Address *a) {
|
||||||
assert(a);
|
assert(a);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ typedef struct Address Address;
|
||||||
#include "networkd-network.h"
|
#include "networkd-network.h"
|
||||||
#include "networkd-util.h"
|
#include "networkd-util.h"
|
||||||
|
|
||||||
|
#include "sd-ipv4acd.h"
|
||||||
|
|
||||||
#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
|
#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
|
||||||
|
|
||||||
typedef struct Network Network;
|
typedef struct Network Network;
|
||||||
|
@ -38,11 +40,13 @@ struct Address {
|
||||||
union in_addr_union in_addr_peer;
|
union in_addr_union in_addr_peer;
|
||||||
|
|
||||||
bool ip_masquerade_done:1;
|
bool ip_masquerade_done:1;
|
||||||
bool duplicate_address_detection;
|
bool manage_temporary_address:1;
|
||||||
bool manage_temporary_address;
|
bool home_address:1;
|
||||||
bool home_address;
|
bool prefix_route:1;
|
||||||
bool prefix_route;
|
bool autojoin:1;
|
||||||
bool autojoin;
|
AddressFamily duplicate_address_detection;
|
||||||
|
|
||||||
|
sd_ipv4acd *acd;
|
||||||
|
|
||||||
LIST_FIELDS(Address, addresses);
|
LIST_FIELDS(Address, addresses);
|
||||||
};
|
};
|
||||||
|
@ -59,6 +63,7 @@ int address_remove(Address *address, Link *link, link_netlink_message_handler_t
|
||||||
bool address_equal(Address *a1, Address *a2);
|
bool address_equal(Address *a1, Address *a2);
|
||||||
bool address_is_ready(const Address *a);
|
bool address_is_ready(const Address *a);
|
||||||
int address_section_verify(Address *a);
|
int address_section_verify(Address *a);
|
||||||
|
int configure_ipv4_duplicate_address_detection(Link *link, Address *address);
|
||||||
|
|
||||||
DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free);
|
DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free);
|
||||||
|
|
||||||
|
@ -68,3 +73,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_label);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_lifetime);
|
CONFIG_PARSER_PROTOTYPE(config_parse_lifetime);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_address_flags);
|
CONFIG_PARSER_PROTOTYPE(config_parse_address_flags);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_address_scope);
|
CONFIG_PARSER_PROTOTYPE(config_parse_address_scope);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_duplicate_address_detection);
|
||||||
|
|
|
@ -774,6 +774,7 @@ static void link_enter_unmanaged(Link *link) {
|
||||||
|
|
||||||
int link_stop_clients(Link *link, bool may_keep_dhcp) {
|
int link_stop_clients(Link *link, bool may_keep_dhcp) {
|
||||||
int r = 0, k;
|
int r = 0, k;
|
||||||
|
Address *ad;
|
||||||
|
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->manager);
|
assert(link->manager);
|
||||||
|
@ -798,6 +799,14 @@ int link_stop_clients(Link *link, bool may_keep_dhcp) {
|
||||||
r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m");
|
r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link->network)
|
||||||
|
LIST_FOREACH(addresses, ad, link->network->static_addresses)
|
||||||
|
if (ad->acd && sd_ipv4acd_is_running(ad->acd) == 0) {
|
||||||
|
k = sd_ipv4acd_stop(ad->acd);
|
||||||
|
if (k < 0)
|
||||||
|
r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client: %m");
|
||||||
|
}
|
||||||
|
|
||||||
if (link->dhcp6_client) {
|
if (link->dhcp6_client) {
|
||||||
k = sd_dhcp6_client_stop(link->dhcp6_client);
|
k = sd_dhcp6_client_stop(link->dhcp6_client);
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
|
@ -2584,6 +2593,24 @@ static int link_drop_config(Link *link) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int link_configure_ipv4_dad(Link *link) {
|
||||||
|
Address *address;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(link->network);
|
||||||
|
|
||||||
|
LIST_FOREACH(addresses, address, link->network->static_addresses)
|
||||||
|
if (address->family == AF_INET &&
|
||||||
|
FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV4)) {
|
||||||
|
r = configure_ipv4_duplicate_address_detection(link, address);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_error_errno(link, r, "Failed to configure IPv4ACD: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int link_configure_qdiscs(Link *link) {
|
static int link_configure_qdiscs(Link *link) {
|
||||||
QDisc *qdisc;
|
QDisc *qdisc;
|
||||||
Iterator i;
|
Iterator i;
|
||||||
|
@ -2732,6 +2759,10 @@ static int link_configure(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = link_configure_ipv4_dad(link);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
return link_configure_after_setting_mtu(link);
|
return link_configure_after_setting_mtu(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,10 +105,10 @@ Address.Broadcast, config_parse_broadcast,
|
||||||
Address.Label, config_parse_label, 0, 0
|
Address.Label, config_parse_label, 0, 0
|
||||||
Address.PreferredLifetime, config_parse_lifetime, 0, 0
|
Address.PreferredLifetime, config_parse_lifetime, 0, 0
|
||||||
Address.HomeAddress, config_parse_address_flags, 0, 0
|
Address.HomeAddress, config_parse_address_flags, 0, 0
|
||||||
Address.DuplicateAddressDetection, config_parse_address_flags, 0, 0
|
|
||||||
Address.ManageTemporaryAddress, config_parse_address_flags, 0, 0
|
Address.ManageTemporaryAddress, config_parse_address_flags, 0, 0
|
||||||
Address.PrefixRoute, config_parse_address_flags, 0, 0
|
Address.PrefixRoute, config_parse_address_flags, 0, 0
|
||||||
Address.AutoJoin, config_parse_address_flags, 0, 0
|
Address.AutoJoin, config_parse_address_flags, 0, 0
|
||||||
|
Address.DuplicateAddressDetection, config_parse_duplicate_address_detection, 0, 0
|
||||||
Address.Scope, config_parse_address_scope, 0, 0
|
Address.Scope, config_parse_address_scope, 0, 0
|
||||||
IPv6AddressLabel.Prefix, config_parse_address_label_prefix, 0, 0
|
IPv6AddressLabel.Prefix, config_parse_address_label_prefix, 0, 0
|
||||||
IPv6AddressLabel.Label, config_parse_address_label, 0, 0
|
IPv6AddressLabel.Label, config_parse_address_label, 0, 0
|
||||||
|
|
|
@ -30,9 +30,17 @@ static const char * const routing_policy_rule_address_family_table[_ADDRESS_FAMI
|
||||||
[ADDRESS_FAMILY_IPV6] = "ipv6",
|
[ADDRESS_FAMILY_IPV6] = "ipv6",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * const duplicate_address_detection_address_family_table[_ADDRESS_FAMILY_MAX] = {
|
||||||
|
[ADDRESS_FAMILY_NO] = "none",
|
||||||
|
[ADDRESS_FAMILY_YES] = "both",
|
||||||
|
[ADDRESS_FAMILY_IPV4] = "ipv4",
|
||||||
|
[ADDRESS_FAMILY_IPV6] = "ipv6",
|
||||||
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
|
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
|
||||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family, AddressFamily, ADDRESS_FAMILY_YES);
|
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family, AddressFamily, ADDRESS_FAMILY_YES);
|
||||||
DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
|
DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFamily);
|
||||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
|
||||||
AddressFamily, "Failed to parse option");
|
AddressFamily, "Failed to parse option");
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@ AddressFamily link_local_address_family_from_string(const char *s) _pure_;
|
||||||
const char *routing_policy_rule_address_family_to_string(AddressFamily b) _const_;
|
const char *routing_policy_rule_address_family_to_string(AddressFamily b) _const_;
|
||||||
AddressFamily routing_policy_rule_address_family_from_string(const char *s) _pure_;
|
AddressFamily routing_policy_rule_address_family_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
|
const char *duplicate_address_detection_address_family_to_string(AddressFamily b) _const_;
|
||||||
|
AddressFamily duplicate_address_detection_address_family_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
int kernel_route_expiration_supported(void);
|
int kernel_route_expiration_supported(void);
|
||||||
|
|
||||||
int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s);
|
int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
[Match]
|
||||||
|
Name=veth-peer
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
|
||||||
|
[Address]
|
||||||
|
Address=192.168.100.10/24
|
||||||
|
DuplicateAddressDetection=ipv4
|
|
@ -0,0 +1,8 @@
|
||||||
|
[Match]
|
||||||
|
Name=veth99
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
|
||||||
|
[Address]
|
||||||
|
Address=192.168.100.10/24
|
|
@ -1479,6 +1479,8 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
'23-active-slave.network',
|
'23-active-slave.network',
|
||||||
'24-keep-configuration-static.network',
|
'24-keep-configuration-static.network',
|
||||||
'24-search-domain.network',
|
'24-search-domain.network',
|
||||||
|
'25-address-dad-veth-peer.network',
|
||||||
|
'25-address-dad-veth99.network',
|
||||||
'25-address-link-section.network',
|
'25-address-link-section.network',
|
||||||
'25-address-preferred-lifetime-zero.network',
|
'25-address-preferred-lifetime-zero.network',
|
||||||
'25-address-static.network',
|
'25-address-static.network',
|
||||||
|
@ -1581,6 +1583,20 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'default via 20.20.20.1 proto static')
|
self.assertRegex(output, 'default via 20.20.20.1 proto static')
|
||||||
|
|
||||||
|
def test_address_dad(self):
|
||||||
|
copy_unit_to_networkd_unit_path('25-address-dad-veth99.network', '25-address-dad-veth-peer.network',
|
||||||
|
'25-veth.netdev')
|
||||||
|
start_networkd()
|
||||||
|
self.wait_online(['veth99:routable', 'veth-peer:degraded'])
|
||||||
|
|
||||||
|
output = check_output('ip -4 address show dev veth99')
|
||||||
|
print(output)
|
||||||
|
self.assertRegex(output, '192.168.100.10/24')
|
||||||
|
|
||||||
|
output = check_output('ip -4 address show dev veth-peer')
|
||||||
|
print(output)
|
||||||
|
self.assertNotRegex(output, '192.168.100.10/24')
|
||||||
|
|
||||||
def test_configure_without_carrier(self):
|
def test_configure_without_carrier(self):
|
||||||
copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
|
copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
|
||||||
start_networkd()
|
start_networkd()
|
||||||
|
|
Loading…
Reference in New Issue