#include "fd-util.h"
#include "fileio.h"
#include "missing_network.h"
+#include "netdev/vrf.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "networkd-ipv6-proxy-ndp.h"
#include "stdio-util.h"
#include "string-table.h"
#include "strv.h"
+#include "sysctl-util.h"
#include "tmpfile-util.h"
#include "util.h"
#include "virt.h"
+uint32_t link_get_vrf_table(Link *link) {
+ return link->network->vrf ? VRF(link->network->vrf)->table : RT_TABLE_MAIN;
+}
+
+uint32_t link_get_dhcp_route_table(Link *link) {
+ /* When the interface is part of an VRF use the VRFs routing table, unless
+ * another table is explicitly specified. */
+ if (link->network->dhcp_route_table_set)
+ return link->network->dhcp_route_table;
+ return link_get_vrf_table(link);
+}
+
+uint32_t link_get_ipv6_accept_ra_route_table(Link *link) {
+ if (link->network->ipv6_accept_ra_route_table_set)
+ return link->network->ipv6_accept_ra_route_table;
+ return link_get_vrf_table(link);
+}
+
DUID* link_get_duid(Link *link) {
if (link->network->duid.type != _DUID_TYPE_INVALID)
return &link->network->duid;
if (!link->network)
return false;
+ if (link->network->bond)
+ return false;
+
+ if (manager_sysctl_ipv6_enabled(link->manager) == 0)
+ return false;
+
return link->network->dhcp & ADDRESS_FAMILY_IPV6;
}
if (!link->network)
return false;
+ if (link->network->bond)
+ return false;
+
return link->network->dhcp & ADDRESS_FAMILY_IPV4;
}
if (!link->network)
return false;
+ if (link->network->bond)
+ return false;
+
return link->network->dhcp_server;
}
if (!link->network)
return false;
- if (streq_ptr(link->kind, "wireguard"))
+ if (STRPTR_IN_SET(link->kind, "vrf", "wireguard"))
+ return false;
+
+ if (link->network->bond)
return false;
return link->network->link_local & ADDRESS_FAMILY_IPV4;
if (!link->network)
return false;
- if (streq_ptr(link->kind, "wireguard"))
+ if (STRPTR_IN_SET(link->kind, "vrf", "wireguard"))
+ return false;
+
+ if (link->network->bond)
+ return false;
+
+ if (manager_sysctl_ipv6_enabled(link->manager) == 0)
return false;
return link->network->link_local & ADDRESS_FAMILY_IPV6;
if (!socket_ipv6_is_supported())
return false;
- if (link->network->bridge)
+ if (link->network->bond)
+ return false;
+
+ if (manager_sysctl_ipv6_enabled(link->manager) == 0)
return false;
/* DHCPv6 client will not be started if no IPv6 link-local address is configured. */
if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
return false;
+ if (manager_sysctl_ipv6_enabled(link->manager) == 0)
+ return false;
+
return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
}
}
static int link_enable_ipv6(Link *link) {
- const char *p = NULL;
bool disabled;
int r;
disabled = !link_ipv6_enabled(link);
- p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/disable_ipv6");
-
- r = write_string_file(p, one_zero(disabled), WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property_boolean(AF_INET6, link->ifname, "disable_ipv6", disabled);
if (r < 0)
log_link_warning_errno(link, r, "Cannot %s IPv6 for interface %s: %m",
enable_disable(!disabled), link->ifname);
return 0;
}
-void link_update_operstate(Link *link) {
+static bool link_is_enslaved(Link *link) {
+ if (link->flags & IFF_SLAVE)
+ /* Even if the link is not managed by networkd, honor IFF_SLAVE flag. */
+ return true;
+
+ if (!link->enslaved_raw)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ if (link->network->bridge)
+ /* TODO: support the case when link is not managed by networkd. */
+ return true;
+
+ return false;
+}
+
+static void link_update_master_operstate(Link *link, NetDev *netdev) {
+ Link *master;
+
+ if (!netdev)
+ return;
+
+ if (link_get(link->manager, netdev->ifindex, &master) < 0)
+ return;
+
+ link_update_operstate(master, true);
+}
+
+void link_update_operstate(Link *link, bool also_update_master) {
LinkOperationalState operstate;
+ Iterator i;
+
assert(link);
if (link->kernel_operstate == IF_OPER_DORMANT)
else if (link_has_carrier(link)) {
Address *address;
uint8_t scope = RT_SCOPE_NOWHERE;
- Iterator i;
/* if we have carrier, check what addresses we have */
SET_FOREACH(address, link->addresses, i) {
else
operstate = LINK_OPERSTATE_OFF;
+ if (IN_SET(operstate, LINK_OPERSTATE_DEGRADED, LINK_OPERSTATE_CARRIER) &&
+ link_is_enslaved(link))
+ operstate = LINK_OPERSTATE_ENSLAVED;
+
+ if (IN_SET(operstate, LINK_OPERSTATE_CARRIER, LINK_OPERSTATE_ENSLAVED, LINK_OPERSTATE_ROUTABLE)) {
+ Link *slave;
+
+ HASHMAP_FOREACH(slave, link->slaves, i) {
+ link_update_operstate(slave, false);
+
+ if (IN_SET(slave->operstate,
+ LINK_OPERSTATE_OFF, LINK_OPERSTATE_NO_CARRIER, LINK_OPERSTATE_DORMANT))
+ operstate = LINK_OPERSTATE_DEGRADED;
+ }
+ }
+
if (link->operstate != operstate) {
link->operstate = operstate;
link_send_changed(link, "OperationalState", NULL);
link_dirty(link);
}
+
+ if (also_update_master && link->network) {
+ link_update_master_operstate(link, link->network->bond);
+ link_update_master_operstate(link, link->network->bridge);
+ }
}
#define FLAG_STRING(string, flag, old, new) \
link->flags = flags;
link->kernel_operstate = operstate;
- link_update_operstate(link);
+ link_update_operstate(link, true);
return 0;
}
}
static Link *link_free(Link *link) {
+ Link *carrier, *master;
Address *address;
- Link *carrier;
Route *route;
Iterator i;
hashmap_remove(link->bound_by_links, INT_TO_PTR(carrier->ifindex));
hashmap_free(link->bound_by_links);
+ hashmap_free(link->slaves);
+
+ if (link->network) {
+ if (link->network->bond &&
+ link_get(link->manager, link->network->bond->ifindex, &master) >= 0)
+ (void) hashmap_remove(master->slaves, INT_TO_PTR(link->ifindex));
+
+ if (link->network->bridge &&
+ link_get(link->manager, link->network->bridge->ifindex, &master) >= 0)
+ (void) hashmap_remove(master->slaves, INT_TO_PTR(link->ifindex));
+ }
+
return mfree(link);
}
!link->ipv4ll_route)
return;
- if (!link->network->bridge) {
-
- if (link_ipv6ll_enabled(link))
- if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0)
- return;
+ if (link_ipv6ll_enabled(link) &&
+ in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address))
+ return;
- if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
- !link->dhcp4_configured) ||
- (link_dhcp6_enabled(link) && !link_dhcp4_enabled(link) &&
- !link->dhcp6_configured) ||
- (link_dhcp4_enabled(link) && link_dhcp6_enabled(link) &&
- !link->dhcp4_configured && !link->dhcp6_configured))
- return;
+ if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
+ !link->dhcp4_configured) ||
+ (link_dhcp6_enabled(link) && !link_dhcp4_enabled(link) &&
+ !link->dhcp6_configured) ||
+ (link_dhcp4_enabled(link) && link_dhcp6_enabled(link) &&
+ !link->dhcp4_configured && !link->dhcp6_configured))
+ return;
- if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured)
- return;
- }
+ if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured)
+ return;
if (link->state != LINK_STATE_CONFIGURED)
link_enter_configured(link);
if (link->network->dhcp_use_dns && link->dhcp_lease) {
const struct in_addr *da = NULL;
- int n;
+ int j, n;
n = sd_dhcp_lease_get_dns(link->dhcp_lease, &da);
if (n > 0) {
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
return log_oom();
- memcpy(addresses + n_addresses, da, n * sizeof(struct in_addr));
- n_addresses += n;
+ for (j = 0; j < n; j++)
+ if (in4_addr_is_non_local(&da[j]))
+ addresses[n_addresses++] = da[j];
}
}
if (link->network->dhcp_use_ntp && link->dhcp_lease) {
const struct in_addr *da = NULL;
- int n;
+ int j, n;
n = sd_dhcp_lease_get_ntp(link->dhcp_lease, &da);
if (n > 0) {
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
return log_oom();
- memcpy(addresses + n_addresses, da, n * sizeof(struct in_addr));
- n_addresses += n;
+ for (j = 0; j < n; j++)
+ if (in4_addr_is_non_local(&da[j]))
+ addresses[n_addresses++] = da[j];
}
}
}
static int link_set_proxy_arp(Link *link) {
- const char *p = NULL;
int r;
if (!link_proxy_arp_enabled(link))
return 0;
- p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/proxy_arp");
-
- r = write_string_file(p, one_zero(link->network->proxy_arp), WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property_boolean(AF_INET, link->ifname, "proxy_arp", link->network->proxy_arp > 0);
if (r < 0)
log_link_warning_errno(link, r, "Cannot configure proxy ARP for interface: %m");
return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
/* If IPv6 not configured (no static IPv6 address and IPv6LL autoconfiguration is disabled)
- * for this interface, or if it is a bridge slave, then disable IPv6 else enable it. */
+ * for this interface, then disable IPv6 else enable it. */
(void) link_enable_ipv6(link);
/* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes
return r;
}
-static int link_bond_set(Link *link) {
+static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+ int r;
+
+ assert(m);
+ assert(link);
+ assert(link->ifname);
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 1;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Could not set bonding interface: %m");
+ return 1;
+ }
+
+ return 1;
+}
+
+static int link_set_bond(Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
- r = netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
+ r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
return r;
}
+static int link_append_to_master(Link *link, NetDev *netdev) {
+ Link *master;
+ int r;
+
+ assert(link);
+ assert(netdev);
+
+ r = link_get(link->manager, netdev->ifindex, &master);
+ if (r < 0)
+ return r;
+
+ r = hashmap_ensure_allocated(&master->slaves, NULL);
+ if (r < 0)
+ return r;
+
+ r = hashmap_put(master->slaves, INT_TO_PTR(link->ifindex), link);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
static int link_lldp_save(Link *link) {
_cleanup_free_ char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
if (r < 0)
return r;
- if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) == 0) {
+ if (!in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address)) {
r = link_acquire_ipv6_conf(link);
if (r < 0)
return r;
if (!link_ipv6ll_enabled(link))
ipv6ll_mode = IN6_ADDR_GEN_MODE_NONE;
- else {
- const char *p = NULL;
- _cleanup_free_ char *stable_secret = NULL;
-
- p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/stable_secret");
-
+ else if (sysctl_read_ip_property(AF_INET6, link->ifname, "stable_secret", NULL) < 0)
/* The file may not exist. And event if it exists, when stable_secret is unset,
- * then reading the file fails and EIO is returned. */
- r = read_one_line_file(p, &stable_secret);
- if (r < 0)
- ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
- else
- ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
- }
+ * reading the file fails with EIO. */
+ ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
+ else
+ ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
if (r < 0)
r = link_set_bridge(link);
if (r < 0)
log_link_error_errno(link, r, "Could not set bridge message: %m");
+
+ r = link_append_to_master(link, link->network->bridge);
+ if (r < 0)
+ log_link_error_errno(link, r, "Failed to add to bridge master's slave list: %m");
}
if (link->network->bond) {
- r = link_bond_set(link);
+ r = link_set_bond(link);
if (r < 0)
log_link_error_errno(link, r, "Could not set bond message: %m");
+
+ r = link_append_to_master(link, link->network->bond);
+ if (r < 0)
+ log_link_error_errno(link, r, "Failed to add to bond master's slave list: %m");
}
if (link->network->use_br_vlan &&
assert(link);
assert(link->network);
+ assert(link->enslaving > 0);
+ assert(!link->enslaved_raw);
link->enslaving--;
} else
log_link_debug(link, "Joined netdev");
- if (link->enslaving <= 0)
+ if (link->enslaving == 0) {
+ link->enslaved_raw = true;
link_joined(link);
+ }
return 1;
}
link_set_state(link, LINK_STATE_CONFIGURING);
link_dirty(link);
-
- if (!link->network->bridge &&
- !link->network->bond &&
- !link->network->vrf &&
- hashmap_isempty(link->network->stacked_netdevs))
- return link_joined(link);
+ link->enslaving = 0;
+ link->enslaved_raw = false;
if (link->network->bond) {
if (link->network->bond->state == NETDEV_STATE_READY &&
LOG_NETDEV_INTERFACE(link->network->bond),
LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname));
+ link->enslaving++;
+
r = netdev_join(link->network->bond, link, netdev_join_handler);
if (r < 0) {
log_struct_errno(LOG_WARNING, r,
link_enter_failed(link);
return r;
}
-
- link->enslaving++;
}
if (link->network->bridge) {
LOG_NETDEV_INTERFACE(link->network->bridge),
LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname));
+ link->enslaving++;
+
r = netdev_join(link->network->bridge, link, netdev_join_handler);
if (r < 0) {
log_struct_errno(LOG_WARNING, r,
link_enter_failed(link);
return r;
}
-
- link->enslaving++;
}
if (link->network->vrf) {
LOG_NETDEV_INTERFACE(link->network->vrf),
LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname));
+ link->enslaving++;
+
r = netdev_join(link->network->vrf, link, netdev_join_handler);
if (r < 0) {
log_struct_errno(LOG_WARNING, r,
link_enter_failed(link);
return r;
}
-
- link->enslaving++;
}
HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
LOG_NETDEV_INTERFACE(netdev),
LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
+ link->enslaving++;
+
r = netdev_join(netdev, link, netdev_join_handler);
if (r < 0) {
log_struct_errno(LOG_WARNING, r,
link_enter_failed(link);
return r;
}
-
- link->enslaving++;
}
+ if (link->enslaving == 0)
+ return link_joined(link);
+
return 0;
}
* primarily to keep IPv4 and IPv6 packet forwarding behaviour
* somewhat in sync (see below). */
- r = write_string_file("/proc/sys/net/ipv4/ip_forward", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property(AF_INET, NULL, "ip_forward", "1");
if (r < 0)
log_link_warning_errno(link, r, "Cannot turn on IPv4 packet forwarding, ignoring: %m");
* same behaviour there and also propagate the setting from
* one to all, to keep things simple (see above). */
- r = write_string_file("/proc/sys/net/ipv6/conf/all/forwarding", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property(AF_INET6, "all", "forwarding", "1");
if (r < 0)
log_link_warning_errno(link, r, "Cannot configure IPv6 packet forwarding, ignoring: %m");
}
static int link_set_ipv6_privacy_extensions(Link *link) {
- char buf[DECIMAL_STR_MAX(unsigned) + 1];
IPv6PrivacyExtensions s;
- const char *p = NULL;
int r;
s = link_ipv6_privacy_extensions(link);
if (s < 0)
return 0;
- p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr");
- xsprintf(buf, "%u", (unsigned) link->network->ipv6_privacy_extensions);
-
- r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "use_tempaddr", (int) link->network->ipv6_privacy_extensions);
if (r < 0)
log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
}
static int link_set_ipv6_accept_ra(Link *link) {
- const char *p = NULL;
int r;
/* Make this a NOP if IPv6 is not available */
if (!link->network)
return 0;
- p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/accept_ra");
-
- /* We handle router advertisements ourselves, tell the kernel to GTFO */
- r = write_string_file(p, "0", WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property(AF_INET6, link->ifname, "accept_ra", "0");
if (r < 0)
log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m");
}
static int link_set_ipv6_dad_transmits(Link *link) {
- char buf[DECIMAL_STR_MAX(int) + 1];
- const char *p = NULL;
int r;
/* Make this a NOP if IPv6 is not available */
if (link->network->ipv6_dad_transmits < 0)
return 0;
- p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/dad_transmits");
- xsprintf(buf, "%i", link->network->ipv6_dad_transmits);
-
- r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "dad_transmits", link->network->ipv6_dad_transmits);
if (r < 0)
log_link_warning_errno(link, r, "Cannot set IPv6 dad transmits for interface: %m");
}
static int link_set_ipv6_hop_limit(Link *link) {
- char buf[DECIMAL_STR_MAX(int) + 1];
- const char *p = NULL;
int r;
/* Make this a NOP if IPv6 is not available */
if (link->network->ipv6_hop_limit < 0)
return 0;
- p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/hop_limit");
- xsprintf(buf, "%i", link->network->ipv6_hop_limit);
-
- r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "hop_limit", link->network->ipv6_hop_limit);
if (r < 0)
log_link_warning_errno(link, r, "Cannot set IPv6 hop limit for interface: %m");
}
static int link_set_ipv6_mtu(Link *link) {
- char buf[DECIMAL_STR_MAX(unsigned) + 1];
- const char *p = NULL;
int r;
/* Make this a NOP if IPv6 is not available */
if (link->network->ipv6_mtu == 0)
return 0;
- p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/mtu");
-
- xsprintf(buf, "%" PRIu32, link->network->ipv6_mtu);
-
- r = write_string_file(p, buf, WRITE_STRING_FILE_DISABLE_BUFFER);
+ r = sysctl_write_ip_property_uint32(AF_INET6, link->ifname, "mtu", link->network->ipv6_mtu);
if (r < 0)
log_link_warning_errno(link, r, "Cannot set IPv6 MTU for interface: %m");
assert(link);
- if (link->network->ignore_carrier_loss)
+ if (link->network && link->network->ignore_carrier_loss)
return 0;
/* Some devices reset itself while setting the MTU. This causes the DHCP client fall into a loop.
const struct in_addr *addresses;
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
- if (r > 0) {
- if (space)
- fputc(' ', f);
- serialize_in_addrs(f, addresses, r);
- space = true;
- }
+ if (r > 0)
+ if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
+ space = true;
}
if (link->network->dhcp_use_dns && dhcp6_lease) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
- if (r > 0) {
- if (space)
- fputc(' ', f);
- serialize_in_addrs(f, addresses, r);
- space = true;
- }
+ if (r > 0)
+ if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
+ space = true;
}
if (link->network->dhcp_use_ntp && dhcp6_lease) {
(void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
}
- fputs("DOMAINS=", f);
- space = false;
- fputstrv(f, link->network->search_domains, NULL, &space);
+ ordered_set_print(f, "DOMAINS=", link->network->search_domains);
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
NDiscDNSSL *dd;
fputc('\n', f);
- fputs("ROUTE_DOMAINS=", f);
- space = false;
- fputstrv(f, link->network->route_domains, NULL, &space);
+ ordered_set_print(f, "ROUTE_DOMAINS=", link->network->route_domains);
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
NDiscDNSSL *dd;
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
if (r >= 0) {
fputs("DHCP4_ADDRESS=", f);
- serialize_in_addrs(f, &address, 1);
+ serialize_in_addrs(f, &address, 1, false, NULL);
fputc('\n', f);
}
r = sd_ipv4ll_get_address(link->ipv4ll, &address);
if (r >= 0) {
fputs("IPV4LL_ADDRESS=", f);
- serialize_in_addrs(f, &address, 1);
+ serialize_in_addrs(f, &address, 1, false, NULL);
fputc('\n', f);
}
}
[LINK_OPERSTATE_DORMANT] = "dormant",
[LINK_OPERSTATE_CARRIER] = "carrier",
[LINK_OPERSTATE_DEGRADED] = "degraded",
+ [LINK_OPERSTATE_ENSLAVED] = "enslaved",
[LINK_OPERSTATE_ROUTABLE] = "routable",
};