コード例 #1
0
ファイル: ppp.c プロジェクト: mtomaschewski/wicked
/*
 * PPP.changeDevice method
 */
static dbus_bool_t
ni_objectmodel_ppp_device_change(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 *ifp, *cfg;
	dbus_bool_t rv = FALSE;

	/* we've already checked that argv matches our signature */
	ni_assert(argc == 1);

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

	if (!(cfg = ni_objectmodel_ppp_device_arg(&argv[0]))) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		goto out;
	}

	if (ni_system_ppp_setup(nc, ifp, cfg) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "failed to set up ppp device");
		goto out;
	}

	rv = TRUE;
out:
	if (cfg)
		ni_netdev_put(cfg);
	return rv;
}
コード例 #2
0
ファイル: dummy.c プロジェクト: mtomaschewski/wicked
static ni_netdev_t *
__ni_objectmodel_dummy_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev_ifp = NULL;
	int rv;

	if (ni_string_empty(ifname)) {
		if (ni_string_empty(cfg_ifp->name) &&
		    (ifname = ni_netdev_make_name(nc, "dummy", 0))) {
			ni_string_dup(&cfg_ifp->name, ifname);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Unable to create dummy interface: "
				"name argument missed");
			goto out;
		}
		ifname = NULL;
	} else if(!ni_string_eq(cfg_ifp->name, ifname)) {
		ni_string_dup(&cfg_ifp->name, ifname);
	}

	if (cfg_ifp->link.hwaddr.len) {
		if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID)
			cfg_ifp->link.hwaddr.type = ARPHRD_ETHER;
		if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER ||
		    cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot create dummy interface: "
				"invalid ethernet address '%s'",
				ni_link_address_print(&cfg_ifp->link.hwaddr));
			return NULL;
		}
	}

	if ((rv = ni_system_dummy_create(nc, cfg_ifp, &dev_ifp)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || dev_ifp == NULL
		|| (ifname && dev_ifp && !ni_string_eq(dev_ifp->name, ifname))) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
					"Unable to create dummy interface: %s",
					ni_strerror(rv));
			dev_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("dummy interface exists (and name matches)");
	}

	if (dev_ifp->link.type != NI_IFTYPE_DUMMY) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create dummy interface: "
				"new interface is of type %s",
				ni_linktype_type_to_name(dev_ifp->link.type));
		dev_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return dev_ifp;
}
コード例 #3
0
ファイル: ifevent.c プロジェクト: nirmoy/wicked
/*
 * Embed rtnetlink socket into ni_socket_t and set ifevent handler
 */
int
ni_server_listen_interface_events(void (*ifevent_handler)(ni_netdev_t *, ni_event_t))
{
	ni_rtevent_handle_t *handle;
	unsigned int family;

	if (__ni_rtevent_sock || ni_global.interface_event) {
		ni_error("Interface event handler is already set");
		return -1;
	}

	if (!(__ni_rtevent_sock = __ni_rtevent_sock_open()))
		return -1;

	family = ni_netconfig_get_family_filter(ni_global_state_handle(0));
	handle = __ni_rtevent_sock->user_data;
	/* TODO: Move IPv6 info to separate function, dhcp4 does not need it */
	if (!__ni_rtevent_join_group(handle, RTNLGRP_LINK) ||
	    (family != AF_INET &&
	     !__ni_rtevent_join_group(handle, RTNLGRP_IPV6_IFINFO))) {
		ni_socket_release(__ni_rtevent_sock);
		__ni_rtevent_sock = NULL;
		return -1;
	}
	ni_global.interface_event = ifevent_handler;
	ni_socket_activate(__ni_rtevent_sock);
	return 0;
}
コード例 #4
0
ファイル: ifevent.c プロジェクト: nirmoy/wicked
/*
 * Receive events from netlink socket and generate events.
 */
static int
__ni_rtevent_process_cb(struct nl_msg *msg, void *ptr)
{
	const struct sockaddr_nl *sender = nlmsg_get_src(msg);
	struct nlmsghdr *nlh;
	ni_netconfig_t *nc;

	if ((nc = ni_global_state_handle(0)) == NULL)
		return NL_SKIP;

	if (sender->nl_pid != 0) {
		ni_error("ignoring rtnetlink event message from PID %u",
			sender->nl_pid);
		return NL_SKIP;
	}

	nlh = nlmsg_hdr(msg);
	if (__ni_rtevent_process(nc, sender, nlh) < 0) {
		ni_debug_events("ignoring %s rtnetlink event",
			ni_rtnl_msg_type_to_name(nlh->nlmsg_type, "unknown"));
		return NL_SKIP;
	}

	return NL_OK;
}
コード例 #5
0
ファイル: wireless.c プロジェクト: gsanso/wicked
/*
 * Callback from wpa_supplicant client whenever the association state changes
 * in a significant way.
 */
void
ni_wireless_association_changed(unsigned int ifindex, ni_wireless_assoc_state_t new_state)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev;
	ni_wireless_t *wlan;

	if (!(dev = ni_netdev_by_index(nc, ifindex)))
		return;

	if (!(wlan = dev->wireless))
		return;

	if (new_state == wlan->assoc.state)
		return;

	wlan->assoc.state = new_state;
	if (new_state == NI_WIRELESS_ESTABLISHED)
		__ni_netdev_event(nc, dev, NI_EVENT_LINK_ASSOCIATED);

	/* We keep track of when we were last changing to or
	 * from fully authenticated state.
	 * We use this to decide when to give up and announce
	 * that we've lost the network - see the timer handling
	 * code above.
	 */
	ni_wireless_update_association_timer(dev);
}
コード例 #6
0
ファイル: addrconf.c プロジェクト: pwieczorkiewicz/wicked
/*
 * Extract interface index from object path.
 * Path names must be NI_OBJECTMODEL_OBJECT_PATH "/" <something> "/Interface/" <index>
 */
static ni_netdev_t *
ni_objectmodel_addrconf_path_to_device(const char *path)
{
	unsigned int ifindex;
	ni_netconfig_t *nc;
	char cc;

	if (strncmp(path, NI_OBJECTMODEL_OBJECT_PATH, strlen(NI_OBJECTMODEL_OBJECT_PATH)))
		return NULL;
	path += strlen(NI_OBJECTMODEL_OBJECT_PATH);

	if (*path++ != '/')
		return NULL;
	while ((cc = *path++) != '/') {
		if (cc == '\0')
			return NULL;
	}

	if (strncmp(path, "Interface/", 10))
		return NULL;
	path += 10;

	if (ni_parse_uint(path, &ifindex, 10) < 0)
		return NULL;

	nc = ni_global_state_handle(1);
	if (nc == NULL) {
		ni_error("%s: unable to refresh interfaces", __func__);
		return NULL;
	}

	return ni_netdev_by_index(nc, ifindex);
}
コード例 #7
0
ファイル: ppp.c プロジェクト: mtomaschewski/wicked
static ni_netdev_t *
ni_objectmodel_ppp_device_create(ni_netdev_t *cfg, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev = NULL;
	int rv;

	ni_netdev_get_ppp(cfg);
	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "ppp", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create ppp interface - too many interfaces");
		return NULL;
	}
	ni_string_dup(&cfg->name, ifname);

	if ((rv = ni_system_ppp_create(nc, cfg, &dev)) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create ppp interface '%s'",
				cfg->name);
		return NULL;
	}

	if (dev && dev->link.type != NI_IFTYPE_PPP) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			"Unable to create ppp interface: new interface is of type %s",
			ni_linktype_type_to_name(dev->link.type));
		return NULL;
	}
	return dev;
}
コード例 #8
0
ファイル: infiniband.c プロジェクト: pwieczorkiewicz/wicked
/*
 * InfinibandChild.Factory.newDevice:
 * Create a new infiniband child interface
 */
static ni_netdev_t *
__ni_objectmodel_ib_newchild(ni_netdev_t *cfg, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev = NULL;
	const ni_infiniband_t *ib;
	const char *err;
	int rv;

	ib = ni_netdev_get_infiniband(cfg);
	if ((err = ni_infiniband_validate(NI_IFTYPE_INFINIBAND_CHILD,
					ib, &cfg->link.lowerdev)) != NULL) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		return NULL;
	}

	if (ni_string_empty(ifname)) {
		if (ni_string_empty(cfg->name) &&
		    !ni_string_printf(&cfg->name, "%s.%04x",
					cfg->link.lowerdev.name, ib->pkey)) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create infiniband child: "
				"name argument missed, failed to construct");
			return NULL;
		}
		ifname = NULL;
	} else if (!ni_string_eq(cfg->name, ifname)) {
		ni_string_dup(&cfg->name, ifname);
	}

	if (ni_string_eq(cfg->name, cfg->link.lowerdev.name)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
			"Cannot to create infiniband child: "
			"child name %s equal with parent device name",
			cfg->name);
		return NULL;
	}

	if ((rv = ni_system_infiniband_child_create(nc, cfg, &dev)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || !dev
		|| (ifname && dev && !ni_string_eq(ifname, dev->name))) {
			dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create infiniband child interface: %s",
				ni_strerror(rv));
			return NULL;
		}
	}

	if (dev && dev->link.type != NI_IFTYPE_INFINIBAND_CHILD) {
		dbus_set_error(error,
			DBUS_ERROR_FAILED,
			"Unable to create infiniband child interface %s: it exists with type %s",
			cfg->name, ni_linktype_type_to_name(dev->link.type));
		return NULL;
        }

	return dev;
}
コード例 #9
0
ファイル: team.c プロジェクト: mtomaschewski/wicked
static ni_netdev_t *
__ni_objectmodel_team_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	int rv;

	ni_netdev_get_team(cfg_ifp);
	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "team", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface - too many interfaces");
		goto out;
	}
	ni_string_dup(&cfg_ifp->name, ifname);

	if (cfg_ifp->link.hwaddr.len) {
		if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID)
			cfg_ifp->link.hwaddr.type = ARPHRD_ETHER;

		if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER ||
		    cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
					"Cannot create team interface: invalid ethernet address '%s'",
					ni_link_address_print(&cfg_ifp->link.hwaddr));
			goto out;
		}
	}

	if ((rv = ni_system_team_create(nc, cfg_ifp, &new_ifp)) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create team interface '%s'", cfg_ifp->name);
		new_ifp = NULL;
		goto out;
#if 0
		if (rv != -NI_ERROR_DEVICE_EXISTS
		 && (ifname != NULL && strcmp(ifname, new_ifp->name))) {
			dbus_set_error(error,
					DBUS_ERROR_FAILED,
					"Unable to create team interface: %s",
					ni_strerror(rv));
			goto out;
		}
		ni_debug_dbus("Bonding interface exists (and name matches)");
#endif
	}

	if (new_ifp->link.type != NI_IFTYPE_TEAM) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create team interface: new interface is of type %s",
				ni_linktype_type_to_name(new_ifp->link.type));
		new_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
コード例 #10
0
ファイル: fsm.c プロジェクト: pwieczorkiewicz/wicked
void
ni_dhcp4_fsm_process_arp_packet(ni_arp_socket_t *arph, const ni_arp_packet_t *pkt, void *user_data)
{
	ni_dhcp4_device_t *dev = user_data;
	ni_netconfig_t *nc = ni_global_state_handle(0);
	const ni_netdev_t *ifp;
	ni_bool_t false_alarm = FALSE;
	ni_bool_t found_addr = FALSE;

	if (!pkt || pkt->op != ARPOP_REPLY || !dev || !dev->lease)
		return;

	/* Is it about the address we're validating at all? */
	if (pkt->sip.s_addr != dev->lease->dhcp4.address.s_addr)
		return;

	/* Ignore any ARP replies that seem to come from our own
	 * MAC address. Some helpful switches seem to generate
	 * these. */
	if (ni_link_address_equal(&dev->system.hwaddr, &pkt->sha))
		return;

	/* As well as ARP replies that seem to come from our own
	 * host: dup if same address, not a dup if there are two
	 * interfaces connected to the same broadcast domain.
	 */
	for (ifp = ni_netconfig_devlist(nc); ifp; ifp = ifp->next) {
		if (ifp->link.ifindex == dev->link.ifindex)
			continue;

		if (!ni_netdev_link_is_up(ifp))
			continue;

		if (!ni_link_address_equal(&ifp->link.hwaddr, &pkt->sha))
			continue;

		/* OK, we have an interface matching the hwaddr,
		 * which will answer arp requests when it is on
		 * the same broadcast domain and causes a false
		 * alarm, except it really has the IP assigned.
		 */
		false_alarm = TRUE;
		if (__ni_dhcp4_address_on_device(ifp, pkt->sip))
			found_addr = TRUE;
	}
	if (false_alarm && !found_addr)
		return;

	ni_debug_dhcp("%s: address %s already in use by %s",
			dev->ifname, inet_ntoa(pkt->sip),
			ni_link_address_print(&pkt->sha));
	ni_dhcp4_device_arp_close(dev);
	ni_dhcp4_fsm_decline(dev);
}
コード例 #11
0
ファイル: fsm.c プロジェクト: pwieczorkiewicz/wicked
static ni_bool_t
__ni_dhcp4_address_on_link(ni_dhcp4_device_t *dev, struct in_addr ipv4)
{
	ni_netconfig_t *nc;
	ni_netdev_t *ifp;

	nc = ni_global_state_handle(0);
	if (!nc || !(ifp = ni_netdev_by_index(nc, dev->link.ifindex)))
		return FALSE;

	return __ni_dhcp4_address_on_device(ifp, ipv4);
}
コード例 #12
0
ファイル: gre.c プロジェクト: mtomaschewski/wicked
static dbus_bool_t
ni_objectmodel_gre_change(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, *cfg;
	ni_gre_t *gre;
	const char *err;

	/* we've already checked that argv matches our signature */
	ni_assert(argc == 1);

	if (!(dev = ni_objectmodel_unwrap_netif(object, error)) ||
		!(cfg = __ni_objectmodel_gre_device_arg(&argv[0])) ||
		!(ni_netdev_get_gre(dev))) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		return FALSE;
	}

	gre = ni_netdev_get_gre(cfg);
	if ((err = ni_gre_validate(gre))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		return FALSE;
	}

	cfg->link.ifindex = dev->link.ifindex;
	if (ni_string_empty(cfg->name))
		ni_string_dup(&cfg->name, dev->name);

	if (ni_netdev_device_is_up(dev)) {
		ni_debug_objectmodel("Skipping gre changeDevice call on %s: "
				"device is up", dev->name);
		return TRUE;
	}

	if (!ni_string_empty(cfg->link.lowerdev.name) &&
	    !ni_objectmodel_bind_netdev_ref_index(cfg->name, "gre tunnel",
					&cfg->link.lowerdev, nc, error))
		return FALSE;

	if (ni_system_tunnel_change(nc, dev, cfg) < 0) {
		dbus_set_error(error,
			DBUS_ERROR_FAILED,
			"Unable to change gre properties on interface %s",
			dev->name);
		return FALSE;
	}

	return TRUE;
}
コード例 #13
0
ファイル: device.c プロジェクト: mijos/wicked
/*
 * Refresh the device mtu and MAC address info prior to taking any actions
 */
int
ni_dhcp4_device_refresh(ni_dhcp4_device_t *dev)
{
	ni_netconfig_t *nih = ni_global_state_handle(0);
	int rv;

	if ((rv = __ni_device_refresh_link_info(nih, &dev->link)) < 0) {
		ni_error("%s: cannot refresh interface: %s",
				__func__, ni_strerror(rv));
		return rv;
	}

	return ni_capture_devinfo_refresh(&dev->system, dev->ifname, &dev->link);
}
コード例 #14
0
ファイル: infiniband.c プロジェクト: pwieczorkiewicz/wicked
/*
 * Infiniband(Child).changeDevice method
 */
static dbus_bool_t
ni_objectmodel_ib_setup(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 *ifp, *cfg;
	dbus_bool_t rv = FALSE;

	/* we've already checked that argv matches our signature */
	if (argc != 1 || !(ifp = ni_objectmodel_unwrap_netif(object, error)))
		return FALSE;

	if (ifp->link.type == NI_IFTYPE_INFINIBAND) {
		cfg = __ni_objectmodel_ibparent_device_arg(&argv[0]);
	} else
	if (ifp->link.type == NI_IFTYPE_INFINIBAND_CHILD) {
		cfg = __ni_objectmodel_ibchild_device_arg(&argv[0]);
	} else {
		cfg = NULL;
	}
	if (!cfg) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		goto out;
	}

	/* when <infiniband/> node is empty (defaults only), skip setup */
	if (cfg->infiniband) {
		const char *err;

		if ((err = ni_infiniband_validate(ifp->link.type, cfg->infiniband,
							&cfg->link.lowerdev))) {
			dbus_set_error(error, DBUS_ERROR_FAILED, "%s", err);
			goto out;
		}

		if (ni_system_infiniband_setup(nc, ifp, cfg) < 0) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
					"failed to configure infiniband device %s",
					ifp->name);
			goto out;
		}
	}

	rv = TRUE;
out:
	if (cfg)
		ni_netdev_put(cfg);
	return rv;
}
コード例 #15
0
ファイル: tun.c プロジェクト: pwieczorkiewicz/wicked
static ni_netdev_t *
__ni_objectmodel_tun_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	const ni_tun_t *tun;
	const char *err;
	int rv;

	/* There's nothing in the device argument that we could use. */

	ni_debug_dbus("TUN.newDevice(name=%s)", ifname);

	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "tun", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create tun - too many interfaces");
		goto out;
	}

	tun = ni_netdev_get_tun(cfg_ifp);
	if ((err = ni_tun_validate(tun))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		goto out;
	}

	if ((rv = ni_system_tun_create(nc, ifname, tun, &new_ifp)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || new_ifp == NULL
		|| (ifname && new_ifp && !ni_string_eq(new_ifp->name, ifname))) {
			ni_dbus_set_error_from_code(error, rv,
					"unable to create TUN interface %s",
					ifname);
			new_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("TUN interface exists (and name matches)");
	}

	if (new_ifp->link.type != NI_IFTYPE_TUN) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create TUN interface: new interface is of type %s",
				ni_linktype_type_to_name(new_ifp->link.type));
		new_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
コード例 #16
0
ni_netdev_t *
ni_netdev_ref_bind_ifindex(ni_netdev_ref_t *ref, ni_netconfig_t *nc)
{
	ni_netdev_t *dev;

	if (!ref || (!nc && !(nc = ni_global_state_handle(0))))
		return NULL;

	dev = ni_netdev_by_name(nc, ref->name);
	if (dev == NULL)
		return NULL;

	ref->index = dev->link.ifindex;
	return dev;
}
コード例 #17
0
ni_netdev_t *
ni_netdev_ref_bind_ifname(ni_netdev_ref_t *ref, ni_netconfig_t *nc)
{
	ni_netdev_t *dev;

	if (!ref || (!nc && !(nc = ni_global_state_handle(0))))
		return NULL;

	dev = ni_netdev_by_index(nc, ref->index);
	if (dev == NULL)
		return NULL;

	if (!ni_string_eq(ref->name, dev->name))
		ni_string_dup(&ref->name, dev->name);
	return dev;
}
コード例 #18
0
ファイル: device.c プロジェクト: kmroz/wicked
/*
 * Process a request to reconfigure the device (ie rebind a lease, or discover
 * a new lease).
 */
int
ni_autoip_device_refresh(ni_autoip_device_t *dev)
{
	ni_netconfig_t *nih = ni_global_state_handle(0);
	int rv;

	/* Go back to INIT state to force a reclaim */
	dev->fsm.state = NI_AUTOIP_STATE_INIT;

	if ((rv = __ni_device_refresh_link_info(nih, &dev->link)) < 0) {
		ni_error("%s: cannot refresh interface: %s", __func__, ni_strerror(rv));
		return rv;
	}

	return ni_capture_devinfo_refresh(&dev->devinfo, dev->ifname, &dev->link);
}
コード例 #19
0
ni_netdev_t *
ni_netdev_ref_resolve(ni_netdev_ref_t *ref, ni_netconfig_t *nc)
{
	ni_netdev_t *dev = NULL;

	if (!ref || (!nc && !(nc = ni_global_state_handle(0))))
		return NULL;

	if (ref->index && (dev = ni_netdev_by_index(nc, ref->index)))
		return dev;

	if (ref->name && (dev = ni_netdev_by_name(nc, ref->name)))
		return dev;

	return NULL;
}
コード例 #20
0
ファイル: bonding.c プロジェクト: pwieczorkiewicz/wicked
static ni_netdev_t *
__ni_objectmodel_bond_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	const ni_bonding_t *bond;
	int rv;

	bond = ni_netdev_get_bonding(cfg_ifp);

	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "bond", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bonding interface - too many interfaces");
		goto out;
	}
	ni_string_dup(&cfg_ifp->name, ifname);

	if ((rv = ni_system_bond_create(nc, cfg_ifp->name, bond, &new_ifp)) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create bonding interface '%s'", cfg_ifp->name);
		new_ifp = NULL;
		goto out;
#if 0
		if (rv != -NI_ERROR_DEVICE_EXISTS
		 && (ifname != NULL && strcmp(ifname, new_ifp->name))) {
			dbus_set_error(error,
					DBUS_ERROR_FAILED,
					"Unable to create bonding interface: %s",
					ni_strerror(rv));
			goto out;
		}
		ni_debug_dbus("Bonding interface exists (and name matches)");
#endif
	}

	if (new_ifp->link.type != NI_IFTYPE_BOND) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create bonding interface: new interface is of type %s",
				ni_linktype_type_to_name(new_ifp->link.type));
		new_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
コード例 #21
0
ファイル: dummy.c プロジェクト: mtomaschewski/wicked
static dbus_bool_t
ni_objectmodel_dummy_change(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, *cfg;

	/* we've already checked that argv matches our signature */
	ni_assert(argc == 1);

	if (!(dev = ni_objectmodel_unwrap_netif(object, error)) ||
	    !(cfg = __ni_objectmodel_dummy_device_arg(&argv[0]))) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		return FALSE;
	}

	cfg->link.ifindex = dev->link.ifindex;
	if (ni_string_empty(cfg->name))
		ni_string_dup(&cfg->name, dev->name);

	if (ni_netdev_device_is_up(dev)) {
		ni_debug_objectmodel("Skipping dummy changeDevice call on %s: "
				"device is up", dev->name);
		return TRUE;
	}

	if (ni_system_dummy_change(nc, dev, cfg) < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to change dummy properties on interface %s",
				dev->name);
		return FALSE;
	}

	if (cfg->link.hwaddr.type == ARPHRD_VOID)
		cfg->link.hwaddr.type = ARPHRD_ETHER;
	if (!ni_link_address_is_invalid(&cfg->link.hwaddr) &&
	    ni_system_hwaddr_change(nc, dev, &cfg->link.hwaddr) < 0) {
		ni_error("Unable to change hwaddr on dummy interface %s",
				dev->name);
		/* fail? */
	}

	return TRUE;
}
コード例 #22
0
ファイル: wireless.c プロジェクト: gsanso/wicked
static void
__ni_wireless_association_timeout(void *ptr, const ni_timer_t *timer)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev = ptr;
	ni_wireless_t *wlan = dev->wireless;

	if (wlan->assoc.timer != timer)
		return;

	ni_debug_wireless("%s: association timed out", dev->name);
	wlan->assoc.timer = NULL;

	__ni_netdev_event(nc, dev, NI_EVENT_LINK_DOWN);
	__ni_netdev_event(nc, dev, NI_EVENT_LINK_ASSOCIATION_LOST);

	ni_wireless_disconnect(dev);
}
コード例 #23
0
ファイル: ppp.c プロジェクト: mchf/wicked
static ni_netdev_t *
__ni_objectmodel_ppp_newlink(ni_netdev_t *cfg, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_dev = NULL;
	int rv;

	ni_debug_dbus("PPP.newDevice(name=%s)", ifname);

	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "ppp"))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create ppp - too many interfaces");
		return NULL;
	}

	if ((rv = ni_system_ppp_create(nc, ifname, cfg->ppp, &new_dev)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS
		 && (ifname != NULL && strcmp(ifname, new_dev->name))) {
			ni_dbus_set_error_from_code(error, rv,
					"unable to create PPP interface %s",
					ifname);
			return NULL;
		}
		ni_debug_dbus("PPP interface exists (and name matches)");
	}

	if (new_dev->link.type != NI_IFTYPE_PPP) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create PPP interface: new interface is of type %s",
				ni_linktype_type_to_name(new_dev->link.type));
		/* FIXME: delete device? */
		return NULL;
	}

	if (ni_ppp_write_config(new_dev->ppp) < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create PPP interface: failed to write coniguration files");
		/* FIXME: delete device */
		return NULL;
	}

	return new_dev;
}
コード例 #24
0
ファイル: ppp.c プロジェクト: mtomaschewski/wicked
/*
 * 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;
}
コード例 #25
0
ファイル: arputil.c プロジェクト: gsanso/wicked
static int
__do_arp_validate_init(struct arp_handle *handle, ni_capture_devinfo_t *dev_info)
{
	ni_netconfig_t *nc;
	ni_netdev_t *dev;

	if (ni_server_listen_interface_events(NULL) < 0) {
		ni_error("unable to initialize netlink link listener");
		return NI_LSB_RC_ERROR;
	}
	if (ni_server_enable_interface_addr_events(NULL) < 0) {
		ni_error("unable to initialize netlink addr listener");
		return NI_LSB_RC_ERROR;
	}

	if (!(nc = ni_global_state_handle(1))) {
		ni_error("Cannot refresh interface list!");
		return NI_LSB_RC_ERROR;
	}

	if (!(dev = ni_netdev_by_name(nc, handle->ifname))) {
		ni_error("Cannot find interface with name '%s'",
				handle->ifname);
		return NI_LSB_RC_ERROR;
	}
	if (!ni_netdev_supports_arp(dev)) {
		ni_error("%s: arp is not supported/enabled", dev->name);
		return NI_LSB_RC_ERROR;
	}
	if (!ni_netdev_link_is_up(dev)) {
		ni_error("%s: link is not up", dev->name);
		return NI_LSB_RC_ERROR;
	}

	if (ni_capture_devinfo_init(dev_info, dev->name, &dev->link) < 0) {
		ni_error("%s: cannot initialize capture", dev->name);
		return NI_LSB_RC_ERROR;
	}

	return 0;
}
コード例 #26
0
ファイル: ovs.c プロジェクト: mtomaschewski/wicked
static ni_netdev_t *
__ni_objectmodel_ovs_bridge_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	int rv;

	ni_netdev_get_ovs_bridge(cfg_ifp);
	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "ovsbr", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create ovs bridge interface - too many interfaces");
		goto out;
	}
	ni_string_dup(&cfg_ifp->name, ifname);

	if ((rv = ni_system_ovs_bridge_create(nc, cfg_ifp, &new_ifp)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || new_ifp == NULL
		|| (ifname && new_ifp && !ni_string_eq(ifname, new_ifp->name))) {
			dbus_set_error(error,
					DBUS_ERROR_FAILED,
					"Unable to create OVS bridge device: %s",
					ni_strerror(rv));
			new_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("OVS bridge device %s exists (and with correct type)", ifname);
	}

	if (new_ifp->link.type != NI_IFTYPE_OVS_BRIDGE) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create ovs bridge interface: new interface is of type %s",
				ni_linktype_type_to_name(new_ifp->link.type));
		new_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
コード例 #27
0
ファイル: bridge.c プロジェクト: gsanso/wicked
static ni_netdev_t *
__ni_objectmodel_bridge_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	const ni_bridge_t *bridge;
	int rv;

	bridge = ni_netdev_get_bridge(cfg_ifp);

	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "br", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bridging interface - too many interfaces");
		goto out;
	}
	ni_string_dup(&cfg_ifp->name, ifname);

	if ((rv = ni_system_bridge_create(nc, cfg_ifp->name, bridge, &new_ifp)) < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create bridging interface: %s",
				ni_strerror(rv));
		new_ifp = NULL;
		goto out;
	}

	if (new_ifp->link.type != NI_IFTYPE_BRIDGE) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create bridging interface: new interface is of type %s",
				ni_linktype_type_to_name(new_ifp->link.type));
		new_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
コード例 #28
0
ファイル: ifevent.c プロジェクト: nirmoy/wicked
int
ni_server_enable_interface_addr_events(void (*ifaddr_handler)(ni_netdev_t *, ni_event_t, const ni_address_t *))
{
	ni_rtevent_handle_t *handle;
	unsigned int family;

	if (!__ni_rtevent_sock || ni_global.interface_addr_event) {
		ni_error("Interface address event handler already set");
		return -1;
	}

	family = ni_netconfig_get_family_filter(ni_global_state_handle(0));
	handle = __ni_rtevent_sock->user_data;
	if ((family != AF_INET6 &&
	     !__ni_rtevent_join_group(handle, RTNLGRP_IPV4_IFADDR)) ||
	    (family != AF_INET  &&
	     !__ni_rtevent_join_group(handle, RTNLGRP_IPV6_IFADDR))) {
		ni_error("Cannot add rtnetlink address event membership: %m");
		return -1;
	}

	ni_global.interface_addr_event = ifaddr_handler;
	return 0;
}
コード例 #29
0
ファイル: arputil.c プロジェクト: gsanso/wicked
static void
__do_arp_validate_process(ni_arp_socket_t *sock, const ni_arp_packet_t *pkt,
		void *user_data)
{
	struct arp_handle *handle = user_data;
	ni_netconfig_t *nc = ni_global_state_handle(0);
	const ni_netdev_t *ifp;
	ni_bool_t false_alarm = FALSE;
	ni_bool_t found_addr = FALSE;
	const ni_address_t *ap;
	ni_sockaddr_t addr;

	if (!pkt || pkt->op != ARPOP_REPLY || !handle->replies)
		return;

	/* Is it about the address we're validating at all? */
	if (pkt->sip.s_addr != handle->ipaddr.sin.sin_addr.s_addr) {
		ni_debug_application("%s: report about different address",
				handle->ifname);
		return;
	}

	/* Ignore any ARP replies that seem to come from our own
	 * MAC address. Some helpful switches seem to generate
	 * these. */
	if (ni_link_address_equal(&sock->dev_info.hwaddr, &pkt->sha)) {
		ni_debug_application("%s: adress in use by ourself",
				handle->ifname);
		return;
	}

	/* As well as ARP replies that seem to come from our own
	 * host: dup if same address, not a dup if there are two
	 * interfaces connected to the same broadcast domain.
	 */
	ni_sockaddr_set_ipv4(&addr, pkt->sip, 0);
	for (ifp = ni_netconfig_devlist(nc); ifp; ifp = ifp->next) {
		if (ifp->link.ifindex == sock->dev_info.ifindex)
			continue;

		if (!ni_netdev_link_is_up(ifp))
			continue;

		if (!ni_link_address_equal(&ifp->link.hwaddr, &pkt->sha))
			continue;

		/* OK, we have an interface matching the hwaddr,
		 * which will answer arp requests when it is on
		 * the same broadcast domain and causes a false
		 * alarm, except it really has the IP assigned.
		 */
		false_alarm = TRUE;
		for (ap = ifp->addrs; !found_addr && ap; ap = ap->next) {
			if (ap->family != AF_INET)
				continue;
			if (ni_sockaddr_equal(&ap->local_addr, &addr))
				found_addr = TRUE;
		}
	}
	if (false_alarm && !found_addr) {
		ni_debug_application("%s: reply from one of our interfaces",
				handle->ifname);
		return;
	}

	ni_info("%s: adress %s in use by %s reported",
			handle->ifname,
			inet_ntoa(pkt->sip),
			ni_link_address_print(&pkt->sha));
	handle->hwaddr = pkt->sha;
}
コード例 #30
0
ファイル: macvlan.c プロジェクト: gsanso/wicked
/*
 * Change a macvlan/macvtap interface
 */
static dbus_bool_t
__ni_objectmodel_macvlan_change(ni_netdev_t *cfg, ni_netdev_t *dev, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	const char *err;
	ni_macvlan_t *macvlan;
	const char *dev_iftype = NULL;

	macvlan = ni_netdev_get_macvlan(cfg);
	if ((err = ni_macvlan_validate(macvlan))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		return FALSE;
	}

	if ((cfg->link.lowerdev.index &&
	     (cfg->link.lowerdev.index != dev->link.lowerdev.index)) ||
	    (cfg->link.lowerdev.name &&
	     !ni_string_eq(cfg->link.lowerdev.name, dev->link.lowerdev.name))) {
		const char *cfg_iftype = ni_linktype_type_to_name(cfg->link.type);

		if (cfg->link.lowerdev.name) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot change %s lower device to %s",
				cfg_iftype, cfg->link.lowerdev.name);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot change %s lower device to %u",
				cfg_iftype, cfg->link.lowerdev.index);
		}
		return FALSE;
	}
	cfg->link.lowerdev.index = dev->link.lowerdev.index;
	ni_string_dup(&cfg->link.lowerdev.name, dev->link.lowerdev.name);

	cfg->link.ifindex = dev->link.ifindex;
	if (ni_string_empty(cfg->name))
		ni_string_dup(&cfg->name, dev->name);

	dev_iftype = ni_linktype_type_to_name(dev->link.type);

	if (!macvlan->mode) {
		macvlan->mode = dev->macvlan->mode;
	} else
	if ((macvlan->mode == NI_MACVLAN_MODE_PASSTHRU) !=
	    (dev->macvlan->mode == NI_MACVLAN_MODE_PASSTHRU)) {
		/* Passthrough mode can't be set or cleared dynamically */
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot change %s mode to %s",
			dev_iftype,
			ni_macvlan_mode_to_name(macvlan->mode));
		return FALSE;
	}

	if (ni_netdev_device_is_up(dev)) {
		ni_debug_objectmodel("Skipping %s changeDevice call on %s: "
				"device is up", dev_iftype, dev->name);
		return TRUE;
	}

	if (ni_system_macvlan_change(nc, dev, cfg) < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to change %s properties on interface %s",
			dev_iftype, dev->name);
		return FALSE;
	}

	if (cfg->link.hwaddr.type == ARPHRD_VOID)
		cfg->link.hwaddr.type = ARPHRD_ETHER;
	if (!ni_link_address_is_invalid(&cfg->link.hwaddr) &&
	    ni_system_hwaddr_change(nc, dev, &cfg->link.hwaddr) < 0) {
		ni_error("Unable to change hwaddr on %s interface %s",
			dev_iftype, dev->name);
		/* fail? */
	}

	return TRUE;
}