Example #1
0
void
ni_autoip_device_drop_lease(ni_autoip_device_t *dev)
{
	ni_addrconf_lease_t *lease;

	if ((lease = dev->lease) != NULL) {
		/* if we've configured the network using this
		 * lease, we need to isse a link down request */
		dev->notify = 1;

		/* delete the lease file. */
		ni_addrconf_lease_file_remove(dev->ifname, lease->type, lease->family);
		ni_autoip_device_set_lease(dev, NULL);

		/* Go back to square one */
		dev->fsm.state = NI_AUTOIP_STATE_INIT;
	}
}
Example #2
0
/*
 * Write a lease to a file
 */
int
ni_addrconf_lease_file_write(const char *ifname, ni_addrconf_lease_t *lease)
{
	char tempname[PATH_MAX] = {'\0'};
	ni_bool_t fallback = FALSE;
	char *filename = NULL;
	xml_node_t *xml = NULL;
	FILE *fp = NULL;
	int ret = -1;
	int fd;

	if (lease->state == NI_ADDRCONF_STATE_RELEASED) {
		ni_addrconf_lease_file_remove(ifname, lease->type, lease->family);
		return 0;
	}

	if (!__ni_addrconf_lease_file_path(&filename, ni_config_storedir(),
					ifname, lease->type, lease->family)) {
		ni_error("Cannot construct lease file name: %m");
		return -1;
	}

	ni_debug_dhcp("Preparing xml lease data for '%s'", filename);
	if ((ret = ni_addrconf_lease_to_xml(lease, &xml)) != 0) {
		if (ret > 0) {
			ni_debug_dhcp("Skipped, %s:%s leases are disabled",
		                        ni_addrfamily_type_to_name(lease->family),
					ni_addrconf_type_to_name(lease->type));
		} else {
			ni_error("Unable to represent %s:%s lease as XML",
					ni_addrfamily_type_to_name(lease->family),
					ni_addrconf_type_to_name(lease->type));
		}
		goto failed;
	}

	snprintf(tempname, sizeof(tempname), "%s.XXXXXX", filename);
	if ((fd = mkstemp(tempname)) < 0) {
		if (errno == EROFS && __ni_addrconf_lease_file_path(&filename,
						ni_config_statedir(), ifname,
						lease->type, lease->family)) {
			ni_debug_dhcp("Read-only filesystem, try fallback to %s",
					filename);
			snprintf(tempname, sizeof(tempname), "%s.XXXXXX", filename);
			fd = mkstemp(tempname);
			fallback = TRUE;
		}
		if (fd < 0) {
			ni_error("Cannot create temporary lease file '%s': %m",
					tempname);
			tempname[0] = '\0';
			ret = -1;
			goto failed;
		}
	}
	if ((fp = fdopen(fd, "we")) == NULL) {
		ret = -1;
		close(fd);
		ni_error("Cannot reopen temporary lease file '%s': %m", tempname);
		goto failed;
	}

	ni_debug_dhcp("Writing lease to temporary file for '%s'", filename);
	xml_node_print(xml, fp);
	fclose(fp);
	xml_node_free(xml);

	if ((ret = rename(tempname, filename)) != 0) {
		ni_error("Unable to rename temporary lease file '%s' to '%s': %m",
				tempname, filename);
		goto failed;
	} else if (!fallback) {
		__ni_addrconf_lease_file_remove(ni_config_statedir(),
				ifname, lease->type, lease->family);
	}

	ni_debug_dhcp("Lease written to file '%s'", filename);
	ni_string_free(&filename);
	return 0;

failed:
	if (fp)
		fclose(fp);
	if (xml)
		xml_node_free(xml);
	if (tempname[0])
		unlink(tempname);
	ni_string_free(&filename);
	return -1;
}
Example #3
0
int
ni_dhcp4_fsm_commit_lease(ni_dhcp4_device_t *dev, ni_addrconf_lease_t *lease)
{
	ni_capture_free(dev->capture);
	dev->capture = NULL;

	if (lease) {
		ni_debug_dhcp("%s: committing lease", dev->ifname);
		if (dev->config->dry_run == NI_DHCP4_RUN_NORMAL) {
			ni_debug_dhcp("%s: schedule renewal of lease in %u seconds",
					dev->ifname, lease->dhcp4.renewal_time);
			ni_dhcp4_fsm_set_timeout(dev, lease->dhcp4.renewal_time);
		}

		/* If the user requested a specific route metric, apply it now */
		if (dev->config) {
			ni_route_table_t *tab;
			ni_route_t *rp;
			unsigned int i;

			for (tab = lease->routes; tab; tab = tab->next) {
				for (i = 0; i < tab->routes.count; ++i) {
					if ((rp = tab->routes.data[i]) == NULL)
						continue;
					rp->protocol = RTPROT_DHCP;
					rp->priority = dev->config->route_priority;
				}
			}
		}

		ni_dhcp4_device_set_lease(dev, lease);
		dev->fsm.state = NI_DHCP4_STATE_BOUND;

		ni_note("%s: Committed DHCPv4 lease with address %s "
			"(lease time %u sec, renew in %u sec, rebind in %u sec)",
			dev->ifname, inet_ntoa(lease->dhcp4.address),
			lease->dhcp4.lease_time, lease->dhcp4.renewal_time,
			lease->dhcp4.rebind_time);

		/* Write the lease to lease cache */
		if (dev->config->dry_run != NI_DHCP4_RUN_OFFER) {
			ni_addrconf_lease_file_write(dev->ifname, lease);
		}

		/* Notify anyone who cares that we've (re-)acquired the lease */
		ni_dhcp4_send_event(NI_DHCP4_EVENT_ACQUIRED, dev, lease);

		if (dev->config->dry_run != NI_DHCP4_RUN_NORMAL) {
			ni_dhcp4_fsm_restart(dev);
			ni_dhcp4_device_stop(dev);
		}
	} else {

		/* Delete old lease file */
		if ((lease = dev->lease) != NULL) {
			ni_note("%s: Dropped DHCPv4 lease with UUID %s",
				dev->ifname, ni_uuid_print(&lease->uuid));

			lease->state = NI_ADDRCONF_STATE_RELEASED;
			ni_dhcp4_send_event(NI_DHCP4_EVENT_RELEASED, dev, lease);

			if (!dev->config || dev->config->dry_run != NI_DHCP4_RUN_OFFER) {
				ni_addrconf_lease_file_remove(dev->ifname, lease->type, lease->family);
			}
			ni_dhcp4_device_drop_lease(dev);
		}

		ni_dhcp4_fsm_restart(dev);
	}

	return 0;
}