1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-12 13:18:14 +03:00

Merge pull request #19344 from yuwata/network-route-metric-19028

network: add RouteMetric= setting in [Address] and more
This commit is contained in:
Yu Watanabe 2021-04-21 20:51:31 +09:00 committed by GitHub
commit b67bbfef14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 187 additions and 53 deletions

View File

@ -1099,6 +1099,15 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
Defaults to <literal>global</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>The metric of the prefix route, which is pointing to the subnet of the configured IP
address, taking the configured prefix length into account. Takes an unsigned integer in the
range 0…4294967295. When unset or set to 0, the kernel's default value is used. This
setting will be ignored when <varname>AddPrefixRoute=</varname> is false.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>HomeAddress=</varname></term>
<listitem>
@ -1421,7 +1430,8 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<varlistentry>
<term><varname>Metric=</varname></term>
<listitem>
<para>The metric of the route (an unsigned integer).</para>
<para>The metric of the route. Takes an unsigned integer in the range 0…4294967295.
Defaluts to unset, and the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -1837,7 +1847,8 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>Set the routing metric for routes specified by the DHCP server. Defaults to 1024.</para>
<para>Set the routing metric for routes specified by the DHCP server. Takes an unsigned
integer in the range 0…4294967295. Defaults to 1024.</para>
</listitem>
</varlistentry>
@ -1977,13 +1988,6 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>Set the routing metric for routes specified by the DHCP server. Defaults to 1024.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RapidCommit=</varname></term>
<listitem>
@ -2158,6 +2162,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<para>As in the [Address] section, but defaults to true.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>The metric of the route to the delegated prefix subnet. Takes an unsigned integer in
the range 0…4294967295. When unset or set to 0, the kernel's default value is used.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -2207,6 +2219,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>Set the routing metric for the routes received in the Router Advertisement. Takes an
unsigned integer in the range 0…4294967295. Defaults to 1024.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseAutonomousPrefix=</varname></term>
<listitem>
@ -2564,6 +2584,15 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<listitem><para>Takes a boolean. When true, adds an address from the prefix. Default to false.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>The metric of the prefix route. Takes an unsigned integer in the range 0…4294967295.
When unset or set to 0, the kernel's default value is used. This setting is ignored when
<varname>Assign=</varname> is false.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -683,13 +683,13 @@ static const NLType rtnl_address_types[] = {
[IFA_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_LABEL] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 },
[IFA_BROADCAST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
[IFA_BROADCAST] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_ANYCAST] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
/*
[IFA_ANYCAST],
[IFA_MULTICAST],
*/
[IFA_MULTICAST] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_FLAGS] = { .type = NETLINK_TYPE_U32 },
[IFA_RT_PRIORITY] = { .type = NETLINK_TYPE_U32 },
[IFA_TARGET_NETNSID] = { .type = NETLINK_TYPE_S32 },
};
static const NLTypeSystem rtnl_address_type_system = {

View File

@ -918,6 +918,10 @@ int address_configure(
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFA_CACHEINFO attribute: %m");
r = sd_netlink_message_append_u32(req, IFA_RT_PRIORITY, address->route_metric);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFA_RT_PRIORITY attribute: %m");
k = address_add(link, address, &a);
if (k < 0)
return log_link_error_errno(link, k, "Could not add address: %m");
@ -1091,6 +1095,7 @@ int link_set_addresses(Link *link) {
return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m");
address->family = AF_INET6;
address->route_metric = p->route_metric;
r = static_address_configure(address, link);
if (r < 0)
return r;
@ -1801,6 +1806,48 @@ int config_parse_address_scope(
return 0;
}
int config_parse_address_route_metric(
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;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = address_new_static(network, filename, section_line, &n);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to allocate new address, ignoring assignment: %m");
return 0;
}
r = safe_atou32(rvalue, &n->route_metric);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Could not parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
TAKE_PTR(n);
return 0;
}
int config_parse_duplicate_address_detection(
const char *unit,
const char *filename,

View File

@ -28,6 +28,7 @@ typedef struct Address {
unsigned char prefixlen;
unsigned char scope;
uint32_t flags;
uint32_t route_metric; /* route metric for prefix route */
char *label;
int set_broadcast;
@ -83,6 +84,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_label);
CONFIG_PARSER_PROTOTYPE(config_parse_lifetime);
CONFIG_PARSER_PROTOTYPE(config_parse_address_flags);
CONFIG_PARSER_PROTOTYPE(config_parse_address_scope);
CONFIG_PARSER_PROTOTYPE(config_parse_address_route_metric);
CONFIG_PARSER_PROTOTYPE(config_parse_duplicate_address_detection);
#define IPV4_ADDRESS_FMT_STR "%u.%u.%u.%u"

View File

@ -332,14 +332,14 @@ int config_parse_dhcp_route_metric(
if (streq_ptr(section, "DHCPv4")) {
network->dhcp_route_metric = metric;
network->dhcp_route_metric_set = true;
} else if (streq_ptr(section, "DHCPv6")) {
network->dhcp6_route_metric = metric;
network->dhcp6_route_metric_set = true;
} else if (STRPTR_IN_SET(section, "DHCPv6", "IPv6AcceptRA")) {
network->ipv6_accept_ra_route_metric = metric;
network->ipv6_accept_ra_route_metric_set = true;
} else { /* [DHCP] section */
if (!network->dhcp_route_metric_set)
network->dhcp_route_metric = metric;
if (!network->dhcp6_route_metric_set)
network->dhcp6_route_metric = metric;
if (!network->ipv6_accept_ra_route_metric_set)
network->ipv6_accept_ra_route_metric = metric;
}
return 0;

View File

@ -893,6 +893,7 @@ static int dhcp4_update_address(Link *link, bool announce) {
if (prefixlen <= 30)
addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
SET_FLAG(addr->flags, IFA_F_NOPREFIXROUTE, !link_prefixroute(link));
addr->route_metric = link->network->dhcp_route_metric;
/* allow reusing an existing address and simply update its lifetime
* in case it already exists */

View File

@ -284,6 +284,7 @@ static int dhcp6_set_pd_route(Link *link, const union in_addr_union *prefix, con
route->dst = *prefix;
route->dst_prefixlen = 64;
route->protocol = RTPROT_DHCP;
route->priority = link->network->dhcp6_pd_route_metric;
r = route_configure(route, link, dhcp6_pd_route_handler, &ret);
if (r < 0)
@ -399,6 +400,7 @@ static int dhcp6_set_pd_address(
address->cinfo.ifa_prefered = lifetime_preferred;
address->cinfo.ifa_valid = lifetime_valid;
SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp6_pd_manage_temporary_address);
address->route_metric = link->network->dhcp6_pd_route_metric;
r = address_configure(address, link, dhcp6_pd_address_handler, &ret);
if (r < 0)

View File

@ -91,6 +91,7 @@ static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
ll_addr->prefixlen = 16;
ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htobe32(0xfffffffflu >> ll_addr->prefixlen);
ll_addr->scope = RT_SCOPE_LINK;
ll_addr->route_metric = IPV4LL_ROUTE_METRIC;
r = address_configure(ll_addr, link, ipv4ll_address_handler, NULL);
if (r < 0)

View File

@ -530,7 +530,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
route->family = AF_INET6;
route->table = table;
route->priority = link->network->dhcp6_route_metric;
route->priority = link->network->ipv6_accept_ra_route_metric;
route->protocol = RTPROT_RA;
route->pref = preference;
route->gw_family = AF_INET6;
@ -554,7 +554,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
if (!route_gw->table_set)
route_gw->table = table;
if (!route_gw->priority_set)
route_gw->priority = link->network->dhcp6_route_metric;
route_gw->priority = link->network->ipv6_accept_ra_route_metric;
if (!route_gw->protocol_set)
route_gw->protocol = RTPROT_RA;
if (!route_gw->pref_set)
@ -814,7 +814,7 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
route->family = AF_INET6;
route->table = link_get_ipv6_accept_ra_route_table(link);
route->priority = link->network->dhcp6_route_metric;
route->priority = link->network->ipv6_accept_ra_route_metric;
route->protocol = RTPROT_RA;
route->flags = RTM_F_PREFIX;
route->dst_prefixlen = prefixlen;
@ -899,7 +899,7 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
route->family = AF_INET6;
route->table = link_get_ipv6_accept_ra_route_table(link);
route->priority = link->network->dhcp6_route_metric;
route->priority = link->network->ipv6_accept_ra_route_metric;
route->protocol = RTPROT_RA;
route->pref = preference;
route->gw = gateway;

View File

@ -146,6 +146,7 @@ Address.AddPrefixRoute, config_parse_address_flags,
Address.AutoJoin, config_parse_address_flags, IFA_F_MCAUTOJOIN, 0
Address.DuplicateAddressDetection, config_parse_duplicate_address_detection, 0, 0
Address.Scope, config_parse_address_scope, 0, 0
Address.RouteMetric, config_parse_address_route_metric, 0, 0
IPv6AddressLabel.Prefix, config_parse_address_label_prefix, 0, 0
IPv6AddressLabel.Label, config_parse_address_label, 0, 0
Neighbor.Address, config_parse_neighbor_address, 0, 0
@ -243,13 +244,13 @@ DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool,
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0
DHCPv6.WithoutRA, config_parse_dhcp6_client_start_mode, 0, offsetof(Network, dhcp6_without_ra)
DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
DHCPv6.RouteMetric, config_parse_dhcp_route_metric, 0, 0
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_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.RouteMetric, config_parse_dhcp_route_metric, 0, 0
IPv6AcceptRA.RouterAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_router)
IPv6AcceptRA.RouterDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_router)
IPv6AcceptRA.PrefixAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_prefix)
@ -308,6 +309,7 @@ DHCPv6PrefixDelegation.Announce, config_parse_bool,
DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign)
DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_manage_temporary_address)
DHCPv6PrefixDelegation.Token, config_parse_dhcp6_pd_token, 0, offsetof(Network, dhcp6_pd_token)
DHCPv6PrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp6_pd_route_metric)
IPv6SendRA.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
IPv6SendRA.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information)
@ -323,6 +325,7 @@ IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_flags,
IPv6Prefix.ValidLifetimeSec, config_parse_prefix_lifetime, 0, 0
IPv6Prefix.PreferredLifetimeSec, config_parse_prefix_lifetime, 0, 0
IPv6Prefix.Assign, config_parse_prefix_assign, 0, 0
IPv6Prefix.RouteMetric, config_parse_prefix_metric, 0, 0
IPv6RoutePrefix.Route, config_parse_route_prefix, 0, 0
IPv6RoutePrefix.LifetimeSec, config_parse_route_prefix_lifetime, 0, 0
LLDP.MUDURL, config_parse_lldp_mud, 0, 0
@ -491,6 +494,7 @@ DHCP.RapidCommit, config_parse_bool,
DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
DHCPv4.UseDomainName, config_parse_dhcp_use_domains, 0, 0
DHCPv4.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)
DHCPv6.RouteMetric, config_parse_dhcp_route_metric, 0, 0
IPv6AcceptRA.DenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_prefix)
IPv6AcceptRA.BlackList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_prefix)
TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0

View File

@ -321,7 +321,6 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp6_use_hostname = true,
.dhcp6_use_ntp = true,
.dhcp6_rapid_commit = true,
.dhcp6_route_metric = DHCP_ROUTE_METRIC,
.dhcp6_pd = -1,
.dhcp6_pd_announce = true,
@ -379,6 +378,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipv6_accept_ra_use_autonomous_prefix = true,
.ipv6_accept_ra_use_onlink_prefix = true,
.ipv6_accept_ra_route_table = RT_TABLE_MAIN,
.ipv6_accept_ra_route_metric = DHCP_ROUTE_METRIC,
.ipv6_accept_ra_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES,
.can_triple_sampling = -1,

View File

@ -170,8 +170,6 @@ struct Network {
DHCPUseDomains dhcp6_use_domains;
bool dhcp6_use_domains_set;
uint8_t dhcp6_pd_length;
uint32_t dhcp6_route_metric;
bool dhcp6_route_metric_set;
char *dhcp6_mudurl;
char **dhcp6_user_class;
char **dhcp6_vendor_class;
@ -221,6 +219,7 @@ struct Network {
bool dhcp6_pd_assign;
bool dhcp6_pd_manage_temporary_address;
int64_t dhcp6_pd_subnet_id;
uint32_t dhcp6_pd_route_metric;
union in_addr_union dhcp6_pd_token;
/* Bridge Support */
@ -277,10 +276,12 @@ struct Network {
bool ipv6_accept_ra_use_onlink_prefix;
bool active_slave;
bool primary_slave;
bool ipv6_accept_ra_route_table_set;
DHCPUseDomains ipv6_accept_ra_use_domains;
IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client;
uint32_t ipv6_accept_ra_route_table;
bool ipv6_accept_ra_route_table_set;
uint32_t ipv6_accept_ra_route_metric;
bool ipv6_accept_ra_route_metric_set;
Set *ndisc_deny_listed_router;
Set *ndisc_allow_listed_router;
Set *ndisc_deny_listed_prefix;

View File

@ -382,6 +382,45 @@ int config_parse_prefix_assign(
return 0;
}
int config_parse_prefix_metric(
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_(prefix_free_or_set_invalidp) Prefix *p = NULL;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = prefix_new_static(network, filename, section_line, &p);
if (r < 0)
return log_oom();
r = safe_atou32(rvalue, &p->route_metric);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
TAKE_PTR(p);
return 0;
}
int config_parse_route_prefix(
const char *unit,
const char *filename,

View File

@ -33,6 +33,7 @@ typedef struct Prefix {
sd_radv_prefix *radv_prefix;
bool assign;
uint32_t route_metric;
} Prefix;
typedef struct RoutePrefix {
@ -64,6 +65,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_flags);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_lifetime);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_assign);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_metric);
CONFIG_PARSER_PROTOTYPE(config_parse_radv_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_radv_search_domains);
CONFIG_PARSER_PROTOTYPE(config_parse_route_prefix);

View File

@ -628,11 +628,11 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
(void) route_protocol_full_to_string_alloc(route->protocol, &proto);
log_link_debug(link,
"%s route: dst: %s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s, nexthop: %"PRIu32,
"%s route: dst: %s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s, nexthop: %"PRIu32", priority: %"PRIu32,
str, strna(dst), strna(src), strna(gw), strna(prefsrc),
strna(scope), strna(table), strna(proto),
strna(route_type_to_string(route->type)),
route->nexthop_id);
route->nexthop_id, route->priority);
}
}

View File

@ -147,6 +147,7 @@ Announce=
Assign=
ManageTemporaryAddress=
Token=
RouteMetric=
[Route]
Destination=
Protocol=
@ -236,6 +237,7 @@ PreferredLifetimeSec=
AddressAutoconfiguration=
ValidLifetimeSec=
Assign=
RouteMetric=
[IPv6RoutePrefix]
Route=
LifetimeSec=
@ -270,6 +272,7 @@ ManageTemporaryAddress=
Broadcast=
Peer=
Label=
RouteMetric=
[RoutingPolicyRule]
Table=
IncomingInterface=
@ -317,6 +320,7 @@ Prefix=
[IPv6AcceptRA]
UseDomains=
RouteTable=
RouteMetric=
UseDNS=
DHCPv6Client=
UseAutonomousPrefix=

View File

@ -3911,7 +3911,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
@ -4014,7 +4014,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip address show dev veth99 scope global')
print(output)
self.assertRegex(output, r'inet 192.168.5.250/24 brd 192.168.5.255 scope global veth99')
self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global secondary dynamic veth99')
self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global secondary dynamic veth99')
output = check_output('ip route show dev veth99')
print(output)
@ -4044,7 +4044,9 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip route show dev veth99')
print(output)
self.assertRegex(output, 'metric 24')
self.assertIn('default via 192.168.5.1 proto dhcp src 192.168.5.181 metric 24', output)
self.assertIn('192.168.5.0/24 proto kernel scope link src 192.168.5.181 metric 24', output)
self.assertIn('192.168.5.1 proto dhcp scope link src 192.168.5.181 metric 24', output)
def test_dhcp_client_reassign_static_routes_ipv4(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
@ -4056,7 +4058,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip address show dev veth99 scope global')
print(output)
self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
output = check_output('ip route show dev veth99')
print(output)
@ -4201,7 +4203,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
output = check_output('ip address show dev veth99 scope global')
@ -4244,7 +4246,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable', 'vrf99:carrier'])
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
print('## ip -d link show dev vrf99')
@ -4255,14 +4257,14 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print('## ip address show vrf vrf99')
output = check_output('ip address show vrf vrf99')
print(output)
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 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')
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
self.assertRegex(output, 'inet6 .* scope link')
print('## ip address show dev veth99')
output = check_output('ip address show dev veth99')
print(output)
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 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')
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
self.assertRegex(output, 'inet6 .* scope link')
@ -4338,9 +4340,9 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -6 address show dev veth99 scope link')
self.assertRegex(output, r'inet6 .* scope link')
output = check_output('ip -4 address show dev veth99 scope global dynamic')
self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 brd 192\.168\.5\.255 scope global dynamic veth99')
self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic veth99')
output = check_output('ip -4 address show dev veth99 scope link')
self.assertNotRegex(output, r'inet 169\.254\.\d+\.\d+/16 brd 169\.254\.255\.255 scope link')
self.assertNotRegex(output, r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link')
print('Wait for the dynamic address to be expired')
time.sleep(130)
@ -4353,9 +4355,9 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -6 address show dev veth99 scope link')
self.assertRegex(output, r'inet6 .* scope link')
output = check_output('ip -4 address show dev veth99 scope global dynamic')
self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 brd 192\.168\.5\.255 scope global dynamic veth99')
self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic veth99')
output = check_output('ip -4 address show dev veth99 scope link')
self.assertNotRegex(output, r'inet 169\.254\.\d+\.\d+/16 brd 169\.254\.255\.255 scope link')
self.assertNotRegex(output, r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link')
search_words_in_dnsmasq_log('DHCPOFFER', show_all=True)
@ -4375,13 +4377,13 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -6 address show dev veth99 scope link')
self.assertRegex(output, r'inet6 .* scope link')
output = check_output('ip -4 address show dev veth99 scope global dynamic')
self.assertNotRegex(output, r'inet 192\.168\.5\.\d+/24 brd 192\.168\.5\.255 scope global dynamic veth99')
self.assertNotRegex(output, r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic veth99')
output = check_output('ip -4 address show dev veth99 scope link')
self.assertRegex(output, r'inet 169\.254\.\d+\.\d+/16 brd 169\.254\.255\.255 scope link')
self.assertRegex(output, r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link')
start_dnsmasq(lease_time='2m')
self.wait_address('veth99', r'inet 192\.168\.5\.\d+/24 brd 192\.168\.5\.255 scope global dynamic', ipv='-4')
self.wait_address_dropped('veth99', r'inet 169\.254\.\d+\.\d+/16 brd 169\.255\.255\.255 scope link', scope='link', ipv='-4')
self.wait_address('veth99', r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic', ipv='-4')
self.wait_address_dropped('veth99', r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.255\.255\.255 scope link', scope='link', ipv='-4')
def test_dhcp_client_route_remove_on_renew(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
@ -4395,7 +4397,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -4 address show dev veth99 scope global dynamic')
print(output)
self.assertRegex(output, 'inet 192.168.5.1[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
self.assertRegex(output, 'inet 192.168.5.1[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
address1=None
for line in output.splitlines():
if 'brd 192.168.5.255 scope global dynamic veth99' in line:
@ -4415,10 +4417,10 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -4 address show dev veth99 scope global dynamic')
print(output)
self.assertRegex(output, 'inet 192.168.5.2[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
self.assertRegex(output, 'inet 192.168.5.2[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
address2=None
for line in output.splitlines():
if 'brd 192.168.5.255 scope global dynamic veth99' in line:
if 'metric 1024 brd 192.168.5.255 scope global dynamic veth99' in line:
address2 = line.split()[1].split('/')[0]
break
@ -4440,7 +4442,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3)
@ -4458,7 +4460,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3)
@ -4476,7 +4478,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3)
@ -4494,7 +4496,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3)