1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! A networking stack.
#![deny(clippy::unused_async)]
#![deny(missing_docs, unreachable_patterns, unused)]
#![recursion_limit = "256"]

mod bindings;

use argh::FromArgs;
use fuchsia_component::server::{ServiceFs, ServiceFsDir};

use bindings::{NetstackSeed, Service};

/// Netstack3.
///
/// The networking stack for Fuchsia.
#[derive(FromArgs)]
struct Options {
    /// run with debug logging.
    #[argh(switch)]
    debug: bool,
}

/// Runs Netstack3.
pub fn main() {
    // TODO(https://fxbug.dev/316616750): Support running with multiple threads.
    // This is currently blocked on fixing race conditions when concurrent
    // operations are allowed.
    let mut executor = fuchsia_async::SendExecutor::new(1 /* num_threads */);

    let Options { debug } = argh::from_env();
    let mut log_options = diagnostics_log::PublishOptions::default();
    if debug {
        log_options = log_options.minimum_severity(diagnostics_log::Severity::Debug);
    }
    diagnostics_log::initialize(log_options).expect("failed to initialize log");

    fuchsia_trace_provider::trace_provider_create_with_fdio();

    let mut fs = ServiceFs::new();
    let _: &mut ServiceFsDir<'_, _> = fs
        .dir("svc")
        // TODO(https://fxbug.dev/42076541): This is transitional. Once the
        // out-of-stack DHCP client is being used by both netstacks, it
        // should be moved out of the netstack realm and into the network
        // realm. The trip through Netstack3 allows for availability of DHCP
        // client to be dependent on Netstack version when using
        // netstack-proxy.
        .add_proxy_service::<fidl_fuchsia_net_dhcp::ClientProviderMarker, _>()
        .add_service_connector(Service::DebugDiagnostics)
        .add_fidl_service(Service::DebugInterfaces)
        .add_fidl_service(Service::DnsServerWatcher)
        .add_fidl_service(Service::Stack)
        .add_fidl_service(Service::Socket)
        .add_fidl_service(Service::PacketSocket)
        .add_fidl_service(Service::RawSocket)
        .add_fidl_service(Service::RootInterfaces)
        .add_fidl_service(Service::RoutesState)
        .add_fidl_service(Service::RoutesStateV4)
        .add_fidl_service(Service::RoutesStateV6)
        .add_fidl_service(Service::RoutesAdminV4)
        .add_fidl_service(Service::RoutesAdminV6)
        .add_fidl_service(Service::RootRoutesV4)
        .add_fidl_service(Service::RootRoutesV6)
        .add_fidl_service(Service::Interfaces)
        .add_fidl_service(Service::InterfacesAdmin)
        .add_fidl_service(Service::FilterState)
        .add_fidl_service(Service::FilterControl)
        .add_fidl_service(Service::Neighbor)
        .add_fidl_service(Service::NeighborController)
        .add_fidl_service(Service::Verifier);

    let seed = NetstackSeed::default();

    let inspector = fuchsia_inspect::component::inspector();
    let _inspect_server_task =
        inspect_runtime::publish(inspector, inspect_runtime::PublishOptions::default())
            .expect("publish Inspect task");

    let _: &mut ServiceFs<_> = fs.take_and_serve_directory_handle().expect("directory handle");

    executor.run(seed.serve(fs, inspector))
}