dhcp: track last IPv4 address on start for renewal

Really only used by systemd because it doesn't have as good lease
handling, but it's also necessary if we switch DHCP clients mid-stream
(which we'll be doing later) since the new DHCP client won't
have a lease file for the current IP address, and thus has nowhere
to pull the current IP address from to request the same address
from the DHCP server.
This commit is contained in:
Dan Williams 2014-11-03 22:35:22 -06:00
parent 034917e129
commit 49cac9f32f
8 changed files with 32 additions and 23 deletions

View file

@ -2975,7 +2975,8 @@ dhcp4_start (NMDevice *self,
nm_setting_ip_config_get_dhcp_hostname (s_ip4),
nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)),
priv->dhcp_timeout,
priv->dhcp_anycast_address);
priv->dhcp_anycast_address,
NULL);
if (tmp)
g_byte_array_free (tmp, TRUE);

View file

@ -393,7 +393,8 @@ gboolean
nm_dhcp_client_start_ip4 (NMDhcpClient *self,
const char *dhcp_client_id,
const char *dhcp_anycast_addr,
const char *hostname)
const char *hostname,
const char *last_ip4_address)
{
NMDhcpClientPrivate *priv;
@ -412,7 +413,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self,
g_clear_pointer (&priv->hostname, g_free);
priv->hostname = g_strdup (hostname);
return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr);
return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr, last_ip4_address);
}
/* uuid_parse does not work for machine-id, so we use our own converter */

View file

@ -64,7 +64,8 @@ typedef struct {
/* Methods */
gboolean (*ip4_start) (NMDhcpClient *self,
const char *anycast_addr);
const char *anycast_addr,
const char *last_ip4_address);
gboolean (*ip6_start) (NMDhcpClient *self,
const char *anycast_addr,
@ -130,7 +131,8 @@ const char *nm_dhcp_client_get_hostname (NMDhcpClient *self);
gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self,
const char *dhcp_client_id,
const char *dhcp_anycast_addr,
const char *hostname);
const char *hostname,
const char *last_ip4_address);
gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self,
const char *dhcp_anycast_addr,

View file

@ -477,7 +477,7 @@ dhclient_start (NMDhcpClient *client,
}
static gboolean
ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr)
ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address)
{
NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
GBytes *client_id;

View file

@ -73,7 +73,7 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED)
}
static gboolean
ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr)
ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address)
{
NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client);
GPtrArray *argv = NULL;

View file

@ -224,7 +224,8 @@ client_start (NMDhcpManager *self,
const char *dhcp_anycast_addr,
const char *hostname,
gboolean info_only,
NMSettingIP6ConfigPrivacy privacy)
NMSettingIP6ConfigPrivacy privacy,
const char *last_ip4_address)
{
NMDhcpManagerPrivate *priv;
NMDhcpClient *client;
@ -265,7 +266,7 @@ client_start (NMDhcpManager *self,
if (ipv6)
success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, hostname, info_only, privacy);
else
success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname);
success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, last_ip4_address);
if (!success) {
remove_client (self, client);
@ -296,7 +297,8 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self,
const char *dhcp_hostname,
const char *dhcp_client_id,
guint32 timeout,
const char *dhcp_anycast_addr)
const char *dhcp_anycast_addr,
const char *last_ip_address)
{
const char *hostname = NULL;
@ -306,7 +308,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self,
hostname = get_send_hostname (self, dhcp_hostname);
return client_start (self, iface, ifindex, hwaddr, uuid, priority, FALSE,
dhcp_client_id, timeout, dhcp_anycast_addr, hostname,
FALSE, 0);
FALSE, 0, last_ip_address);
}
/* Caller owns a reference to the NMDhcpClient on return */
@ -332,7 +334,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self,
hostname = get_send_hostname (self, dhcp_hostname);
return client_start (self, iface, ifindex, hwaddr, uuid, priority, TRUE,
NULL, timeout, dhcp_anycast_addr, hostname, info_only,
privacy);
privacy, NULL);
}
void

View file

@ -61,7 +61,8 @@ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager,
const char *dhcp_hostname,
const char *dhcp_client_id,
guint32 timeout,
const char *dhcp_anycast_addr);
const char *dhcp_anycast_addr,
const char *last_ip_address);
NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager,
const char *iface,

View file

@ -515,7 +515,7 @@ get_arp_type (const GByteArray *hwaddr)
}
static gboolean
ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr)
ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address)
{
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (client);
const char *iface = nm_dhcp_client_get_iface (client);
@ -524,7 +524,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr)
GBytes *override_client_id;
const uint8_t *client_id = NULL;
size_t client_id_len = 0;
struct in_addr last_addr;
struct in_addr last_addr = { 0 };
const char *hostname;
int r, i;
@ -578,14 +578,16 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr)
sd_dhcp_lease_load (priv->lease_file, &lease);
if (lease) {
r = sd_dhcp_lease_get_address (lease, &last_addr);
if (r == 0) {
r = sd_dhcp_client_set_request_address (priv->client4, &last_addr);
if (r < 0) {
nm_log_warn (LOGD_DHCP4, "(%s): failed to set last IPv4 address (%d)", iface, r);
goto error;
}
if (last_ip4_address)
inet_pton (AF_INET, last_ip4_address, &last_addr);
else if (lease)
sd_dhcp_lease_get_address (lease, &last_addr);
if (last_addr.s_addr) {
r = sd_dhcp_client_set_request_address (priv->client4, &last_addr);
if (r < 0) {
nm_log_warn (LOGD_DHCP4, "(%s): failed to set last IPv4 address (%d)", iface, r);
goto error;
}
}