Example #1
0
status_t
init_stack()
{
	status_t status = init_domains();
	if (status != B_OK)
		return status;

	status = init_interfaces();
	if (status != B_OK)
		goto err1;

	status = init_device_interfaces();
	if (status != B_OK)
		goto err2;

	status = init_timers();
	if (status != B_OK)
		goto err3;

	status = init_notifications();
	if (status < B_OK) {
		// If this fails, it just means there won't be any notifications,
		// it's not a fatal error.
		dprintf("networking stack notifications could not be initialized: %s\n",
			strerror(status));
	}

	module_info* dummy;
	status = get_module(NET_SOCKET_MODULE_NAME, &dummy);
	if (status != B_OK)
		goto err4;

	mutex_init(&sChainLock, "net chains");
	mutex_init(&sInitializeChainLock, "net intialize chains");

	sFamilies = new(std::nothrow) FamilyTable();
	if (sFamilies == NULL || sFamilies->Init(10) != B_OK) {
		status = B_NO_MEMORY;
		goto err5;
	}

	sProtocolChains = new(std::nothrow) ChainTable();
	if (sProtocolChains == NULL || sProtocolChains->Init(10) != B_OK) {
		status = B_NO_MEMORY;
		goto err6;
	}

	sDatalinkProtocolChains = new(std::nothrow) ChainTable();
	if (sDatalinkProtocolChains == NULL
			|| sDatalinkProtocolChains->Init(10) != B_OK) {
		status = B_NO_MEMORY;
		goto err7;
	}

	sReceivingProtocolChains = new(std::nothrow) ChainTable();
	if (sReceivingProtocolChains == NULL
			|| sReceivingProtocolChains->Init(10) != B_OK) {
		status = B_NO_MEMORY;
		goto err8;
	}

	sInitialized = true;

	link_init();
	scan_modules("network/protocols");
	scan_modules("network/datalink_protocols");

	// TODO: for now!
	register_domain_datalink_protocols(AF_INET, IFT_LOOP,
		"network/datalink_protocols/loopback_frame/v1", NULL);
#if 0 // PPP is not (currently) included in the build
	register_domain_datalink_protocols(AF_INET, IFT_PPP,
		"network/datalink_protocols/ppp_frame/v1", NULL);
#endif
	register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
		"network/datalink_protocols/loopback_frame/v1", NULL);
	register_domain_datalink_protocols(AF_INET, IFT_ETHER,
		"network/datalink_protocols/arp/v1",
		"network/datalink_protocols/ethernet_frame/v1",
		NULL);
	register_domain_datalink_protocols(AF_INET6, IFT_ETHER,
		"network/datalink_protocols/ipv6_datagram/v1",
		"network/datalink_protocols/ethernet_frame/v1",
		NULL);

	return B_OK;

err8:
	delete sDatalinkProtocolChains;
err7:
	delete sProtocolChains;
err6:
	delete sFamilies;
err5:
	mutex_destroy(&sInitializeChainLock);
	mutex_destroy(&sChainLock);
err4:
	uninit_timers();
err3:
	uninit_device_interfaces();
err2:
	uninit_interfaces();
err1:
	uninit_domains();
	return status;
}
status_t
init_stack()
{
    status_t status = init_domains();
    if (status != B_OK)
        return status;

    status = init_interfaces();
    if (status != B_OK)
        goto err1;

    status = init_device_interfaces();
    if (status != B_OK)
        goto err2;

    status = init_timers();
    if (status != B_OK)
        goto err3;

    status = init_notifications();
    if (status < B_OK) {
        // If this fails, it just means there won't be any notifications,
        // it's not a fatal error.
        dprintf("networking stack notifications could not be initialized: %s\n",
                strerror(status));
    }

    module_info* dummy;
    status = get_module(NET_SOCKET_MODULE_NAME, &dummy);
    if (status != B_OK)
        goto err4;

    mutex_init(&sChainLock, "net chains");
    mutex_init(&sInitializeChainLock, "net intialize chains");

    sFamilies = hash_init(10, offsetof(struct family, next),
                          &family::Compare, &family::Hash);
    if (sFamilies == NULL) {
        status = B_NO_MEMORY;
        goto err5;
    }

    sProtocolChains = hash_init(10, offsetof(struct chain, next),
                                &chain::Compare, &chain::Hash);
    if (sProtocolChains == NULL) {
        status = B_NO_MEMORY;
        goto err6;
    }

    sDatalinkProtocolChains = hash_init(10, offsetof(struct chain, next),
                                        &chain::Compare, &chain::Hash);
    if (sDatalinkProtocolChains == NULL) {
        status = B_NO_MEMORY;
        goto err7;
    }

    sReceivingProtocolChains = hash_init(10, offsetof(struct chain, next),
                                         &chain::Compare, &chain::Hash);
    if (sReceivingProtocolChains == NULL) {
        status = B_NO_MEMORY;
        goto err8;
    }

    sInitialized = true;

    link_init();
    scan_modules("network/protocols");
    scan_modules("network/datalink_protocols");

    // TODO: for now!
    register_domain_datalink_protocols(AF_INET, IFT_LOOP,
                                       "network/datalink_protocols/loopback_frame/v1", NULL);
    register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
                                       "network/datalink_protocols/loopback_frame/v1", NULL);
    register_domain_datalink_protocols(AF_INET, IFT_ETHER,
                                       "network/datalink_protocols/arp/v1",
                                       "network/datalink_protocols/ethernet_frame/v1",
                                       NULL);
    register_domain_datalink_protocols(AF_INET6, IFT_ETHER,
                                       "network/datalink_protocols/ipv6_datagram/v1",
                                       "network/datalink_protocols/ethernet_frame/v1",
                                       NULL);

    return B_OK;

err8:
    hash_uninit(sDatalinkProtocolChains);
err7:
    hash_uninit(sProtocolChains);
err6:
    hash_uninit(sFamilies);
err5:
    mutex_destroy(&sInitializeChainLock);
    mutex_destroy(&sChainLock);
err4:
    uninit_timers();
err3:
    uninit_device_interfaces();
err2:
    uninit_interfaces();
err1:
    uninit_domains();
    return status;
}