示例#1
0
Interface::~Interface()
{
	TRACE("Interface %p: destructor\n", this);

	put_device_interface(fDeviceInterface);

	// Uninitialize the domain datalink protocols

	DatalinkTable::Iterator iterator = fDatalinkTable.GetIterator();
	while (domain_datalink* datalink = iterator.Next()) {
		put_domain_datalink_protocols(this, datalink->domain);
	}

	// Free domain datalink objects

	domain_datalink* next = fDatalinkTable.Clear(true);
	while (next != NULL) {
		domain_datalink* datalink = next;
		next = next->hash_link;

		delete datalink;
	}

	recursive_lock_destroy(&fLock);

	// Release reference of the stack - at this point, our stack may be unloaded
	// if no other interfaces or sockets are left
	put_module(gNetStackInterfaceModule.info.name);
}
示例#2
0
status_t
domain_interface_control(net_domain_private* domain, int32 option,
	ifreq* request)
{
	const char* name = request->ifr_name;
	status_t status = B_OK;

	net_device_interface* device = get_device_interface(name, false);
	if (device == NULL)
		return ENODEV;

	RecursiveLocker _(domain->lock);

	net_interface* interface = find_interface(domain, name);
	if (interface != NULL) {
		switch (option) {
			case SIOCDIFADDR:
				remove_interface_from_domain(interface);
				break;

			case SIOCSIFFLAGS:
			{
				uint32 requestFlags = request->ifr_flags;
				request->ifr_flags &= ~(IFF_UP | IFF_LINK | IFF_BROADCAST);

				if ((requestFlags & IFF_UP) != (interface->flags & IFF_UP)) {
					if (requestFlags & IFF_UP) {
						status = interface->first_info->interface_up(
							interface->first_protocol);
						if (status == B_OK)
							interface->flags |= IFF_UP;
					} else {
						interface_set_down(interface);
					}
				}

				if (status == B_OK) {
					// TODO: why shouldn't we able to delete IFF_BROADCAST?
					interface->flags &= IFF_UP | IFF_LINK | IFF_BROADCAST;
					interface->flags |= request->ifr_flags;
				}
				break;
			}
		}
	}

	// If the SIOCDIFADDR call above removed the last interface associated with
	// the device interface, this will effectively remove the interface
	put_device_interface(device);

	return status;
}
示例#3
0
status_t
add_interface_to_domain(net_domain* _domain,
	struct ifreq& request)
{
	net_domain_private* domain = (net_domain_private*)_domain;

	const char* deviceName = request.ifr_parameter.device[0]
		? request.ifr_parameter.device : request.ifr_name;
	const char* baseName = request.ifr_parameter.base_name[0]
		? request.ifr_parameter.base_name : request.ifr_name;

	net_device_interface* deviceInterface = get_device_interface(deviceName);
	if (deviceInterface == NULL)
		return ENODEV;

	RecursiveLocker locker(domain->lock);

	net_interface_private* interface = NULL;
	status_t status;

	if (find_interface(domain, request.ifr_name) == NULL) {
		// We must not hold the domain's link when creating the interface:
		// this will call get_module() which might want to access a network
		// device when booting from network.
		locker.Unlock();
		status = create_interface(domain, request.ifr_name,
			baseName, deviceInterface, &interface);
		locker.Lock();

		if (find_interface(domain, request.ifr_name) != NULL) {
			delete_interface(interface);
			status = B_NAME_IN_USE;
		}
	} else
		status = B_NAME_IN_USE;

	put_device_interface(deviceInterface);

	if (status == B_OK) {
		list_add_item(&domain->interfaces, interface);
		notify_interface_added(interface);
	}

	return status;
}