summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2019-05-21 21:52:44 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2019-07-05 11:04:32 +0200
commit401fee7c2040e87d7f9c83fd350733b0f538d578 (patch)
treea32b72b4f3d3398ea1437790aaf32b10cfb8bfa3
parentbe8f7b5a5de6ed18d9e329e0151fd3065747c7b0 (diff)
downloadNetworkManager-401fee7c2040e87d7f9c83fd350733b0f538d578.tar.gz
dhcp: support notifying the client of the result of DAD
The DHCP client is not meant to use the assigned address before DAD has completed successfully, if enabled. And if DAD fails, the server should be notified with a DECLINE, in order to potentially blacklist the address. Currently, none of the clients support this, but add the required callbacks, and allow clients to opt in if they want.
-rw-r--r--src/devices/nm-device.c8
-rw-r--r--src/dhcp/nm-dhcp-client.c30
-rw-r--r--src/dhcp/nm-dhcp-client.h14
3 files changed, 50 insertions, 2 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index abcff229bf..e649d267fe 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -7694,9 +7694,13 @@ clear_config:
static void
dhcp4_dad_cb (NMDevice *self, NMIP4Config **configs, gboolean success)
{
- if (success)
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+ if (success) {
+ nm_dhcp_client_accept (priv->dhcp4.client, NULL);
nm_device_activate_schedule_ip_config_result (self, AF_INET, NM_IP_CONFIG_CAST (configs[1]));
- else {
+ } else {
+ nm_dhcp_client_decline (priv->dhcp4.client, "Address conflict detected", NULL);
nm_device_ip_method_failed (self, AF_INET,
NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE);
}
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c
index 6c95d5790c..4dca4750e7 100644
--- a/src/dhcp/nm-dhcp-client.c
+++ b/src/dhcp/nm-dhcp-client.c
@@ -530,6 +530,36 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self,
error);
}
+gboolean
+nm_dhcp_client_accept (NMDhcpClient *self,
+ GError **error)
+{
+ g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE);
+
+ if (NM_DHCP_CLIENT_GET_CLASS (self)->accept) {
+ return NM_DHCP_CLIENT_GET_CLASS (self)->accept (self,
+ error);
+ }
+
+ return TRUE;
+}
+
+gboolean
+nm_dhcp_client_decline (NMDhcpClient *self,
+ const char *error_message,
+ GError **error)
+{
+ g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE);
+
+ if (NM_DHCP_CLIENT_GET_CLASS (self)->decline) {
+ return NM_DHCP_CLIENT_GET_CLASS (self)->decline (self,
+ error_message,
+ error);
+ }
+
+ return TRUE;
+}
+
static GBytes *
get_duid (NMDhcpClient *self)
{
diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h
index 1a8ccaba2b..33030a4f23 100644
--- a/src/dhcp/nm-dhcp-client.h
+++ b/src/dhcp/nm-dhcp-client.h
@@ -82,6 +82,13 @@ typedef struct {
const char *last_ip4_address,
GError **error);
+ gboolean (*accept) (NMDhcpClient *self,
+ GError **error);
+
+ gboolean (*decline) (NMDhcpClient *self,
+ const char *error_message,
+ GError **error);
+
gboolean (*ip6_start) (NMDhcpClient *self,
const char *anycast_addr,
const struct in6_addr *ll_addr,
@@ -155,6 +162,13 @@ gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self,
guint needed_prefixes,
GError **error);
+gboolean nm_dhcp_client_accept (NMDhcpClient *self,
+ GError **error);
+
+gboolean nm_dhcp_client_decline (NMDhcpClient *self,
+ const char *error_message,
+ GError **error);
+
void nm_dhcp_client_stop (NMDhcpClient *self, gboolean release);
/* Backend helpers for subclasses */