summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-07-25 01:13:47 +0200
committerTom Gundersen <teg@jklm.no>2014-07-30 17:45:47 +0200
commitba17915457271cc13d46cbafc876277d037acd67 (patch)
treea76a38fc688195537fa226ebd9950da099226f09
parent3f77a1b19f5a8ce33566f7f6e28e94c08ea30841 (diff)
networkd: ipv4ll - configure link-local address independently of DHCPv4
This changes the behavior when both DHCPv4 and IPv4LL are enabled. Before, we would disable IPv4LL when we got a DHCPv4 lease and enable it if the lease was lost. Now we just always set up both, if both are enabled, but the DHCPv4 addresses and routes will always take precedence due to their metric and scope.
-rw-r--r--man/systemd.network.xml3
-rw-r--r--src/network/networkd-link.c179
2 files changed, 46 insertions, 136 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index dc34154b26..34eca012b6 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -212,9 +212,6 @@
<term><varname>IPv4LL=</varname></term>
<listitem>
<para>A boolean. When true, enables IPv4 link-local support.
- If <literal>DHCP=</literal> is also true, acquiring DHCP address
- will deprecate previously acquired IPv4 link-local address or
- stop acquiring process if one has not been acquired before.
</para>
</listitem>
</varlistentry>
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 87bdd85644..d633399890 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -36,9 +36,6 @@
#include "network-util.h"
#include "dhcp-lease-internal.h"
-static int ipv4ll_address_update(Link *link, bool deprecate);
-static bool ipv4ll_is_bound(sd_ipv4ll *ll);
-
static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
_cleanup_link_unref_ Link *link = NULL;
uint16_t type;
@@ -205,9 +202,7 @@ static int link_stop_clients(Link *link) {
if (!link->network)
return 0;
- if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
- assert(link->dhcp_client);
-
+ if (link->dhcp_client) {
k = sd_dhcp_client_stop(link->dhcp_client);
if (k < 0) {
log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
@@ -215,9 +210,7 @@ static int link_stop_clients(Link *link) {
}
}
- if (link->network->ipv4ll) {
- assert(link->ipv4ll);
-
+ if (link->ipv4ll) {
k = sd_ipv4ll_stop(link->ipv4ll);
if (k < 0) {
log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
@@ -225,9 +218,7 @@ static int link_stop_clients(Link *link) {
}
}
- if (link->network->dhcp_server) {
- assert(link->dhcp_server);
-
+ if (link->dhcp_server) {
k = sd_dhcp_server_stop(link->dhcp_server);
if (k < 0) {
log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
@@ -235,8 +226,7 @@ static int link_stop_clients(Link *link) {
}
}
- if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
- assert(link->icmp6_router_discovery);
+ if(link->icmp6_router_discovery) {
if (link->dhcp6_client) {
k = sd_dhcp6_client_stop(link->dhcp6_client);
@@ -439,6 +429,20 @@ static int link_set_dhcp_routes(Link *link) {
return 0;
}
+static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
+ int r;
+ struct in_addr addr;
+
+ if (!ll)
+ return false;
+
+ r = sd_ipv4ll_get_address(ll, &addr);
+ if (r < 0)
+ return false;
+
+ return true;
+}
+
static int link_enter_set_routes(Link *link) {
Route *rt;
int r;
@@ -449,8 +453,9 @@ static int link_enter_set_routes(Link *link) {
link->state = LINK_STATE_SETTING_ROUTES;
- if (!link->network->static_routes && !link->dhcp_lease &&
- (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
+ if (!link->network->static_routes &&
+ !link->dhcp_lease &&
+ !ipv4ll_is_bound(link->ipv4ll))
return link_enter_configured(link);
log_debug_link(link, "setting routes");
@@ -467,31 +472,29 @@ static int link_enter_set_routes(Link *link) {
link->route_messages ++;
}
- if (link->ipv4ll && !link->dhcp_lease) {
+ if (ipv4ll_is_bound(link->ipv4ll)) {
_cleanup_route_free_ Route *route = NULL;
- if (r != -ENOENT) {
- r = route_new_dynamic(&route, RTPROT_STATIC);
- if (r < 0) {
- log_error_link(link, "Could not allocate route: %s",
- strerror(-r));
- return r;
- }
-
- route->family = AF_INET;
- route->scope = RT_SCOPE_LINK;
- route->metrics = IPV4LL_ROUTE_METRIC;
+ r = route_new_dynamic(&route, RTPROT_STATIC);
+ if (r < 0) {
+ log_error_link(link, "Could not allocate route: %s",
+ strerror(-r));
+ return r;
+ }
- r = route_configure(route, link, &route_handler);
- if (r < 0) {
- log_warning_link(link,
- "could not set routes: %s", strerror(-r));
- link_enter_failed(link);
- return r;
- }
+ route->family = AF_INET;
+ route->scope = RT_SCOPE_LINK;
+ route->metrics = IPV4LL_ROUTE_METRIC;
- link->route_messages ++;
+ r = route_configure(route, link, &route_handler);
+ if (r < 0) {
+ log_warning_link(link,
+ "could not set routes: %s", strerror(-r));
+ link_enter_failed(link);
+ return r;
}
+
+ link->route_messages ++;
}
if (link->dhcp_lease) {
@@ -662,8 +665,9 @@ static int link_enter_set_addresses(Link *link) {
link->state = LINK_STATE_SETTING_ADDRESSES;
- if (!link->network->static_addresses && !link->dhcp_lease &&
- (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
+ if (!link->network->static_addresses &&
+ !link->dhcp_lease &&
+ !ipv4ll_is_bound(link->ipv4ll))
return link_enter_set_routes(link);
log_debug_link(link, "setting addresses");
@@ -680,7 +684,7 @@ static int link_enter_set_addresses(Link *link) {
link->addr_messages ++;
}
- if (link->ipv4ll && !link->dhcp_lease) {
+ if (link->ipv4ll) {
_cleanup_address_free_ Address *ll_addr = NULL;
struct in_addr addr;
@@ -778,29 +782,6 @@ static int link_enter_set_addresses(Link *link) {
return 0;
}
-static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
- _cleanup_link_unref_ Link *link = userdata;
- int r;
-
- assert(m);
- assert(link);
- assert(link->ifname);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_rtnl_message_get_errno(m);
- if (r < 0 && r != -ENOENT)
- log_struct_link(LOG_WARNING, link,
- "MESSAGE=%-*s: could not update address: %s",
- IFNAMSIZ,
- link->ifname, strerror(-r),
- "ERRNO=%d", -r,
- NULL);
-
- return 1;
-}
-
static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
int r;
@@ -1197,17 +1178,6 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
}
}
- if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
- if (!sd_ipv4ll_is_running(link->ipv4ll))
- r = sd_ipv4ll_start(link->ipv4ll);
- else if (ipv4ll_is_bound(link->ipv4ll))
- r = ipv4ll_address_update(link, false);
- if (r < 0) {
- link_enter_failed(link);
- return;
- }
- }
-
break;
case DHCP_EVENT_RENEW:
r = dhcp_lease_renew(client, link);
@@ -1222,16 +1192,6 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
link_enter_failed(link);
return;
}
- if (link->ipv4ll) {
- if (ipv4ll_is_bound(link->ipv4ll))
- r = ipv4ll_address_update(link, true);
- else
- r = sd_ipv4ll_stop(link->ipv4ll);
- if (r < 0) {
- link_enter_failed(link);
- return;
- }
- }
break;
default:
if (event < 0)
@@ -1244,40 +1204,6 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
return;
}
-static int ipv4ll_address_update(Link *link, bool deprecate) {
- int r;
- struct in_addr addr;
-
- assert(link);
-
- r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
- if (r >= 0) {
- _cleanup_address_free_ Address *address = NULL;
-
- log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
- deprecate ? "deprecate" : "approve",
- ADDRESS_FMT_VAL(addr));
-
- r = address_new_dynamic(&address);
- if (r < 0) {
- log_error_link(link, "Could not allocate address: %s", strerror(-r));
- return r;
- }
-
- address->family = AF_INET;
- address->in_addr.in = addr;
- address->prefixlen = 16;
- address->scope = RT_SCOPE_LINK;
- address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
- address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
-
- address_update(address, link, &address_update_handler);
- }
-
- return 0;
-
-}
-
static int ipv4ll_address_lost(Link *link) {
int r;
struct in_addr addr;
@@ -1322,18 +1248,6 @@ static int ipv4ll_address_lost(Link *link) {
return 0;
}
-static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
- int r;
- struct in_addr addr;
-
- assert(ll);
-
- r = sd_ipv4ll_get_address(ll, &addr);
- if (r < 0)
- return false;
- return true;
-}
-
static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
struct in_addr address;
int r;
@@ -1726,8 +1640,6 @@ static int link_joined(Link *link) {
assert(link->state == LINK_STATE_ENSLAVING);
assert(link->network);
- log_debug_link(link, "joined netdev");
-
if (!(link->flags & IFF_UP)) {
r = link_up(link);
if (r < 0) {
@@ -1763,7 +1675,8 @@ static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata
NULL);
link_enter_failed(link);
return 1;
- }
+ } else
+ log_debug_link(link, "joined netdev");
if (link->enslaving <= 0)
link_joined(link);
@@ -1923,7 +1836,7 @@ static int link_configure(Link *link) {
return r;
if (link->network->dhcp_mtu) {
- r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
+ r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_INTERFACE_MTU);
if (r < 0)
return r;
}