#include "dhcp-lease-internal.h"
+static bool link_dhcp6_enabled(Link *link) {
+ if (link->flags & IFF_LOOPBACK)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ return IN_SET(link->network->dhcp, DHCP_SUPPORT_V6, DHCP_SUPPORT_BOTH);
+}
+
+static bool link_dhcp4_enabled(Link *link) {
+ if (link->flags & IFF_LOOPBACK)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ return IN_SET(link->network->dhcp, DHCP_SUPPORT_V4, DHCP_SUPPORT_BOTH);
+}
+
+static bool link_dhcp4_server_enabled(Link *link) {
+ if (link->flags & IFF_LOOPBACK)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ return link->network->dhcp_server;
+}
+
+static bool link_ipv4ll_enabled(Link *link) {
+ if (link->flags & IFF_LOOPBACK)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ return link->network->ipv4ll;
+}
+
+#define FLAG_STRING(string, flag, old, new) \
+ (((old ^ new) & flag) \
+ ? ((old & flag) ? (" -" string) : (" +" string)) \
+ : "")
+
+static int link_update_flags(Link *link, sd_rtnl_message *m) {
+ unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
+ uint8_t operstate;
+ int r;
+
+ assert(link);
+
+ r = sd_rtnl_message_link_get_flags(m, &flags);
+ if (r < 0) {
+ log_warning_link(link, "Could not get link flags");
+ return r;
+ }
+
+ r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
+ if (r < 0)
+ /* if we got a message without operstate, take it to mean
+ the state was unchanged */
+ operstate = link->kernel_operstate;
+
+ if ((link->flags == flags) && (link->kernel_operstate == operstate))
+ return 0;
+
+ if (link->flags != flags) {
+ log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
+ FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
+ FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
+ FLAG_STRING("UP", IFF_UP, link->flags, flags),
+ FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
+ FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
+ FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
+ FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
+ FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
+ FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
+ FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
+ FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
+ FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
+ FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
+ FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
+ FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
+ FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
+ FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
+ FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
+
+ unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
+ IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
+ IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
+ IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
+ IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
+ IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
+ unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
+ unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
+
+ /* link flags are currently at most 18 bits, let's align to
+ * printing 20 */
+ if (unknown_flags_added)
+ log_debug_link(link,
+ "unknown link flags gained: %#.5x (ignoring)",
+ unknown_flags_added);
+
+ if (unknown_flags_removed)
+ log_debug_link(link,
+ "unknown link flags lost: %#.5x (ignoring)",
+ unknown_flags_removed);
+ }
+
+ link->flags = flags;
+ link->kernel_operstate = operstate;
+
+ link_save(link);
+
+ return 0;
+}
+
static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
_cleanup_link_unref_ Link *link = NULL;
uint16_t type;
if (r < 0)
return -ENOMEM;
- r = hashmap_ensure_allocated(&manager->links, NULL, NULL);
+ r = hashmap_ensure_allocated(&manager->links, NULL);
if (r < 0)
return r;
if (r < 0)
return r;
+ r = link_update_flags(link, message);
+ if (r < 0)
+ return r;
+
*ret = link;
link = NULL;
assert(link->network);
assert(link->state == LINK_STATE_SETTING_ROUTES);
- if (link->network->dhcp_server &&
+ if (link_dhcp4_server_enabled(link) &&
!sd_dhcp_server_is_running(link->dhcp_server)) {
struct in_addr pool_start;
Address *address;
if (!link->static_configured)
return;
- if (link->network->ipv4ll)
+ if (link_ipv4ll_enabled(link))
if (!link->ipv4ll_address ||
!link->ipv4ll_route)
return;
- if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4))
- if (!link->dhcp4_configured)
+ if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
return;
if (link->state != LINK_STATE_CONFIGURED)
return 1;
r = sd_bus_message_get_errno(m);
- if (r < 0)
- r = -r;
if (r > 0)
log_warning_link(link, "Could not set hostname: %s",
strerror(r));
assert(link->manager);
assert(link->manager->event);
- if (link->network->ipv4ll) {
+ if (link_ipv4ll_enabled(link)) {
assert(link->ipv4ll);
log_debug_link(link, "acquiring IPv4 link-local address");
}
}
- if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
+ if (link_dhcp4_enabled(link)) {
assert(link->dhcp_client);
log_debug_link(link, "acquiring DHCPv4 lease");
}
}
- if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
+ if (link_dhcp6_enabled(link)) {
assert(link->icmp6_router_discovery);
log_debug_link(link, "discovering IPv6 routers");
return false;
}
-#define FLAG_STRING(string, flag, old, new) \
- (((old ^ new) & flag) \
- ? ((old & flag) ? (" -" string) : (" +" string)) \
- : "")
-
-static int link_update_flags(Link *link, sd_rtnl_message *m) {
- unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
- uint8_t operstate;
- int r;
-
- assert(link);
-
- r = sd_rtnl_message_link_get_flags(m, &flags);
- if (r < 0) {
- log_warning_link(link, "Could not get link flags");
- return r;
- }
-
- r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
- if (r < 0)
- /* if we got a message without operstate, take it to mean
- the state was unchanged */
- operstate = link->kernel_operstate;
-
- if ((link->flags == flags) && (link->kernel_operstate == operstate))
- return 0;
-
- if (link->flags != flags) {
- log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
- FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
- FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
- FLAG_STRING("UP", IFF_UP, link->flags, flags),
- FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
- FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
- FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
- FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
- FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
- FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
- FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
- FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
- FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
- FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
- FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
- FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
- FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
- FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
- FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
-
- unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
- IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
- IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
- IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
- IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
- IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
- unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
- unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
-
- /* link flags are currently at most 18 bits, let's align to
- * printing 20 */
- if (unknown_flags_added)
- log_debug_link(link,
- "unknown link flags gained: %#.5x (ignoring)",
- unknown_flags_added);
-
- if (unknown_flags_removed)
- log_debug_link(link,
- "unknown link flags lost: %#.5x (ignoring)",
- unknown_flags_removed);
- }
-
- link->flags = flags;
- link->kernel_operstate = operstate;
-
- link_save(link);
-
- return 0;
-}
-
static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
int r;
assert(link->network);
assert(link->state == LINK_STATE_PENDING);
- if (link->network->ipv4ll) {
+ if (link_ipv4ll_enabled(link)) {
r = ipv4ll_configure(link);
if (r < 0)
return r;
}
- if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
+ if (link_dhcp4_enabled(link)) {
r = dhcp4_configure(link);
if (r < 0)
return r;
}
- if (link->network->dhcp_server) {
+ if (link_dhcp4_server_enabled(link)) {
r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
if (r < 0)
return r;
return r;
}
- if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
+ if (link_dhcp6_enabled(link)) {
r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
if (r < 0)
return r;
} else if (r < 0)
return r;
+ if (link->flags & IFF_LOOPBACK) {
+ if (network->ipv4ll)
+ log_debug_link(link, "ignoring IPv4LL for loopback link");
+
+ if (network->dhcp != DHCP_SUPPORT_NONE)
+ log_debug_link(link, "ignoring DHCP clients for loopback link");
+
+ if (network->dhcp_server)
+ log_debug_link(link, "ignoring DHCP server for loopback link");
+ }
+
r = network_apply(link->manager, network, link);
if (r < 0)
return r;
} else {
r = link_get(m, ifindex, &link);
if (r < 0 || !link) {
- log_warning("rtnl: received address for a nonexistent link, ignoring");
+ log_warning("rtnl: received address for a nonexistent link (%d), ignoring", ifindex);
return 0;
}
}
case RTM_NEWADDR:
if (!address_dropped)
log_debug_link(link, "added address: %s/%u (valid for %s)",
- buf, address->prefixlen,
- strna(valid_str));
+ buf, address->prefixlen, valid_str);
else
log_debug_link(link, "updated address: %s/%u (valid for %s)",
- buf, address->prefixlen,
- strna(valid_str));
+ buf, address->prefixlen, valid_str);
LIST_PREPEND(addresses, link->addresses, address);
address = NULL;
case RTM_DELADDR:
if (address_dropped) {
log_debug_link(link, "removed address: %s/%u (valid for %s)",
- buf, address->prefixlen,
- strna(valid_str));
+ buf, address->prefixlen, valid_str);
link_save(link);
} else
log_warning_link(link,
"removing non-existent address: %s/%u (valid for %s)",
- buf, address->prefixlen,
- strna(valid_str));
+ buf, address->prefixlen, valid_str);
break;
default:
char **address, **domain;
bool space;
+ fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
+
fputs("DNS=", f);
space = false;
STRV_FOREACH(address, link->network->dns) {