}
static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
- _cleanup_link_unref_ Link *link = NULL;
+ _cleanup_(link_unrefp) Link *link = NULL;
uint16_t type;
const char *ifname, *kind = NULL;
int r, ifindex;
}
static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(link->route_messages > 0);
}
int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(m);
}
static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(rtnl);
}
static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(rtnl);
log_link_warning_errno(link, r, "Failed to set DNS server for DHCP server, ignoring: %m");
}
-
if (link->network->dhcp_server_emit_ntp) {
if (link->network->n_dhcp_server_ntp > 0)
}
int link_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(m);
}
static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
log_link_debug(link, "Set link");
}
static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(m);
}
static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(m);
if (!link->network)
return 0;
- if (link->network->arp < 0)
+ if (link->network->arp < 0 && link->network->multicast < 0 && link->network->allmulticast < 0)
return 0;
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
if (link->network->arp >= 0) {
ifi_change |= IFF_NOARP;
- ifi_flags |= link->network->arp ? 0 : IFF_NOARP;
+ SET_FLAG(ifi_flags, IFF_NOARP, link->network->arp == 0);
+ }
+
+ if (link->network->multicast >= 0) {
+ ifi_change |= IFF_MULTICAST;
+ SET_FLAG(ifi_flags, IFF_MULTICAST, link->network->multicast);
+ }
+
+ if (link->network->allmulticast >= 0) {
+ ifi_change |= IFF_ALLMULTI;
+ SET_FLAG(ifi_flags, IFF_ALLMULTI, link->network->allmulticast);
}
r = sd_rtnl_message_link_set_flags(req, ifi_flags, ifi_change);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, !link->network->use_bpdu);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m");
+ if (link->network->use_bpdu >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, link->network->use_bpdu);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m");
+ }
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m");
+ if (link->network->hairpin >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m");
+ }
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
+ if (link->network->fast_leave >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
+ }
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, !link->network->allow_port_to_be_root);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
+ if (link->network->allow_port_to_be_root >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, link->network->allow_port_to_be_root);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
- r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
+ }
+
+ if (link->network->unicast_flood >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
+
+ }
if (link->network->cost != 0) {
r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
}
static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(link);
for this interface, or if it is a bridge slave, then disable IPv6 else enable it. */
(void) link_enable_ipv6(link);
- if (link->network->mtu) {
+ if (link->network->mtu != 0) {
/* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes
on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */
if (link_ipv6_enabled(link) && link->network->mtu < IPV6_MIN_MTU) {
}
static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(link);
}
static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
int r;
assert(link);
log_struct(LOG_DEBUG,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(link->network->bond),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname),
- NULL);
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname));
r = netdev_join(link->network->bond, link, netdev_join_handler);
if (r < 0) {
log_struct_errno(LOG_WARNING, r,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(link->network->bond),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname),
- NULL);
-
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname));
link_enter_failed(link);
return r;
}
log_struct(LOG_DEBUG,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(link->network->bridge),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname),
- NULL);
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname));
r = netdev_join(link->network->bridge, link, netdev_join_handler);
if (r < 0) {
log_struct_errno(LOG_WARNING, r,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(link->network->bridge),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname),
- NULL),
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname));
link_enter_failed(link);
return r;
}
log_struct(LOG_DEBUG,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(link->network->vrf),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname),
- NULL);
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname));
+
r = netdev_join(link->network->vrf, link, netdev_join_handler);
if (r < 0) {
log_struct_errno(LOG_WARNING, r,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(link->network->vrf),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->vrf->ifname),
- NULL);
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->vrf->ifname));
link_enter_failed(link);
return r;
}
log_struct(LOG_DEBUG,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(netdev),
- LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname),
- NULL);
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
r = netdev_join(netdev, link, netdev_join_handler);
if (r < 0) {
log_struct_errno(LOG_WARNING, r,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(netdev),
- LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname),
- NULL);
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname));
link_enter_failed(link);
return r;
}
return 0;
}
+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 (!socket_ipv6_is_supported())
+ return 0;
+
+ if (link->flags & IFF_LOOPBACK)
+ return 0;
+
+ 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, 0);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Cannot set IPv6 MTU for interface: %m");
+
+ return 0;
+}
+
static int link_drop_foreign_config(Link *link) {
Address *address;
Route *route;
if (r < 0)
return r;
+ r = link_set_ipv6_mtu(link);
+ if (r < 0)
+ return r;
+
if (link_ipv4ll_enabled(link)) {
r = ipv4ll_configure(link);
if (r < 0)
static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
+ _cleanup_(link_unrefp) Link *link = userdata;
Network *network;
int r;
assert(link);
- r = parse_env_file(link->state_file, NEWLINE,
+ r = parse_env_file(NULL, link->state_file, NEWLINE,
"NETWORK_FILE", &network_file,
"ADDRESSES", &addresses,
"ROUTES", &routes,
int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
Link *link;
- _cleanup_udev_device_unref_ struct udev_device *device = NULL;
+ _cleanup_(udev_device_unrefp) struct udev_device *device = NULL;
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
int r;
if (r >= 0 && !streq(ifname, link->ifname)) {
log_link_info(link, "Interface name change detected, %s has been renamed to %s.", link->ifname, ifname);
- link_free_carrier_maps(link);
-
- r = free_and_strdup(&link->ifname, ifname);
- if (r < 0)
- return r;
+ if (link->state == LINK_STATE_PENDING) {
+ r = free_and_strdup(&link->ifname, ifname);
+ if (r < 0)
+ return r;
+ } else {
+ Manager *manager = link->manager;
- r = link_new_carrier_maps(link);
- if (r < 0)
- return r;
+ link_drop(link);
+ r = link_add(manager, m, &link);
+ if (r < 0)
+ return r;
+ }
}
r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
if (r >= 0 && mtu > 0) {
link->mtu = mtu;
- if (!link->original_mtu) {
+ if (link->original_mtu == 0) {
link->original_mtu = mtu;
log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
}
/* Make sure to flush out old entries before we use the NDISC data */
ndisc_vacuum(link);
- if (link->network->dhcp_use_dns && link->ndisc_rdnss) {
+ if (link->network->ipv6_accept_ra_use_dns && link->ndisc_rdnss) {
NDiscRDNSS *dd;
SET_FOREACH(dd, link->ndisc_rdnss, i) {