Example #1
0
/*
 * PPP.delete method
 */
static dbus_bool_t
ni_objectmodel_ppp_device_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev;

	if (!(dev = ni_objectmodel_unwrap_netif(object, error)))
		return FALSE;

	NI_TRACE_ENTER_ARGS("dev=%s", dev->name);
	if (ni_system_ppp_delete(nc, dev) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Error deleting ppp interface %s", dev->name);
		return FALSE;
	}

	ni_client_state_drop(dev->link.ifindex);
	return TRUE;
}
Example #2
0
/*
 * InfinibandChild.delete method
 */
static dbus_bool_t
ni_objectmodel_ib_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error)
{
	ni_netdev_t *ifp;

	if (!(ifp = ni_objectmodel_unwrap_netif(object, error)))
		return FALSE;

	NI_TRACE_ENTER_ARGS("ifp=%s", ifp->name);
	if (ni_system_infiniband_child_delete(ifp) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			"Unable to delete infiniband child interface", ifp->name);
		return FALSE;
	}

	ni_client_state_drop(ifp->link.ifindex);
	ni_dbus_object_free(object);
	return TRUE;
}
Example #3
0
static dbus_bool_t
__ni_objectmodel_macvlan_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error)
{
	ni_netdev_t *dev;
	int rv;

	if (!(dev = ni_objectmodel_unwrap_netif(object, error)))
		return FALSE;

	NI_TRACE_ENTER_ARGS("dev=%s", dev->name);
	if ((rv = ni_system_macvlan_delete(dev)) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			"Error deleting macvlan interface %s: %s",
			dev->name, ni_strerror(rv));
		return FALSE;
	}

	ni_client_state_drop(dev->link.ifindex);
	return TRUE;
}
Example #4
0
/*
 * Delete a PPP interface
 */
dbus_bool_t
ni_objectmodel_ppp_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error)
{
	ni_netdev_t *dev;
	int rv;

	if (!(dev = ni_objectmodel_unwrap_netif(object, error)))
		return FALSE;

	NI_TRACE_ENTER_ARGS("dev=%s", dev->name);
	if ((rv = ni_system_ppp_delete(dev)) < 0) {
		ni_dbus_set_error_from_code(error, rv,
				"Unable to delete PPP interface %s: %s",
				dev->name, ni_strerror(rv));
		return FALSE;
	}

	ni_client_state_drop(dev->link.ifindex);
	ni_dbus_object_free(object);
	return TRUE;
}
Example #5
0
/*
 * Process DELLINK event
 */
int
__ni_rtevent_dellink(ni_netconfig_t *nc, const struct sockaddr_nl *nladdr, struct nlmsghdr *h)
{
	struct ifinfomsg *ifi;
	ni_netdev_t *dev;
	struct nlattr *nla;
	const char *ifname = NULL;

	if (!(ifi = ni_rtnl_ifinfomsg(h, RTM_DELLINK)))
		return -1;

	if ((nla = nlmsg_find_attr(h, sizeof(*ifi), IFLA_IFNAME)) != NULL) {
		ifname = (char *) nla_data(nla);
	}
	if (ifi->ifi_family == AF_BRIDGE) {
		ni_debug_events("%s: ignoring bridge DELLINK event", ifname);
		return 0;
	}

	/* Open code interface removal. */
	if ((dev = ni_netdev_by_index(nc, ifi->ifi_index)) == NULL) {
		ni_debug_events("RTM_DELLINK message for unknown interface %s index %d",
				ifname, ifi->ifi_index);
		return -1;
	} else {
		unsigned int old_flags = dev->link.ifflags;

		dev->link.ifflags = __ni_netdev_translate_ifflags(ifi->ifi_flags, old_flags);
		dev->deleted = 1;
		__ni_netdev_process_events(nc, dev, old_flags);
		ni_client_state_drop(dev->link.ifindex);
		ni_netconfig_device_remove(nc, dev);
	}

	return 0;
}
Example #6
0
/*
 * Process NEWLINK event
 */
int
__ni_rtevent_newlink(ni_netconfig_t *nc, const struct sockaddr_nl *nladdr, struct nlmsghdr *h)
{
	char namebuf[IF_NAMESIZE+1] = {'\0'};
	ni_netdev_t *dev, *old;
	struct ifinfomsg *ifi;
	struct nlattr *nla;
	char *ifname = NULL;
	int old_flags = 0;

	if (!(ifi = ni_rtnl_ifinfomsg(h, RTM_NEWLINK)))
		return -1;

	if (ifi->ifi_family == AF_BRIDGE)
		return 0;

	old = ni_netdev_by_index(nc, ifi->ifi_index);
	ifname = if_indextoname(ifi->ifi_index, namebuf);
	if (!ifname) {
		/*
		 * device (index) does not exists any more;
		 * process deletion/cleanup of the device.
		 */
		if (old) {
			old_flags = old->link.ifflags;
			old->link.ifflags = 0;
			old->deleted = 1;

			__ni_netdev_process_events(nc, old, old_flags);
			ni_client_state_drop(old->link.ifindex);
			ni_netconfig_device_remove(nc, old);
		}
		return 0;
	}

	if (old) {
		if (!ni_string_eq(old->name, ifname)) {
			ni_debug_events("%s[%u]: device renamed to %s",
					old->name, old->link.ifindex, ifname);
			ni_string_dup(&old->name, ifname);
			__ni_netdev_event(nc, old, NI_EVENT_DEVICE_RENAME);
		}
		dev = old;
		old_flags = old->link.ifflags;
	} else {
		if (!(dev = ni_netdev_new(ifname, ifi->ifi_index))) {
			ni_warn("%s[%u]: unable to allocate memory for device",
					ifname, ifi->ifi_index);
			return -1;
		}
		dev->created = 1;
		ni_netconfig_device_append(nc, dev);
	}

	if (__ni_netdev_process_newlink(dev, h, ifi, nc) < 0) {
		ni_error("Problem parsing RTM_NEWLINK message for %s", ifname);
		return -1;
	}

	if ((ifname = dev->name)) {
		ni_netdev_t *conflict;

		conflict = ni_netdev_by_name(nc, ifname);
		if (conflict && conflict->link.ifindex != (unsigned int)ifi->ifi_index) {
			/*
			 * As the events often provide an already obsolete name [2 events,
			 * we process 1st with next in read buffer], we are reading the
			 * current dev->name in advance (above).
			 *
			 * On a rename like eth0->rename1->eth1, eth1->rename2->eth0, the
			 * current dev->name is already eth1 at processing time of eth0
			 * to rename1 event. This sometimes causes that we find eth1 in
			 * our device list [eth1 -> rename2 event in the read buffer].
			 *
			 * Just update the name of the conflicting device in advance too
			 * and when the interface does not exist any more, emit events.
			 */
			char *current = if_indextoname(conflict->link.ifindex, namebuf);
			if (current) {
				ni_string_dup(&conflict->name, current);
				__ni_netdev_event(nc, conflict, NI_EVENT_DEVICE_RENAME);
			} else {
				unsigned int ifflags = conflict->link.ifflags;
				conflict->link.ifflags = 0;
				conflict->deleted = 1;

				__ni_netdev_process_events(nc, conflict, ifflags);
				ni_client_state_drop(conflict->link.ifindex);
				ni_netconfig_device_remove(nc, conflict);
			}
		}
	}

	__ni_netdev_process_events(nc, dev, old_flags);

	if ((nla = nlmsg_find_attr(h, sizeof(*ifi), IFLA_WIRELESS)) != NULL)
		__ni_wireless_link_event(nc, dev, nla_data(nla), nla_len(nla));

	return 0;
}