// 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.
library fuchsia.net.stack;

using fuchsia.net.name;
using fuchsia.net;
using fuchsia.net.interfaces.admin;

/// A path to a device node.
alias DevicePath = string:255;

/// A value indicating that a [`ForwardingEntry`]'s metric is unspecified.
const UNSPECIFIED_METRIC uint32 = 0;

/// An entry in the forwarding table for the network stack.
///
/// Valid if at least one of [`device_id`] and [`next_hop`] is specified.
type ForwardingEntry = struct {
    /// The destination subnet this route can be used to send to.
    subnet fuchsia.net.Subnet;

    /// The opaque identifier of the device to which packets should be forwarded. The zero value is
    /// interpreted as unspecified. If unspecified, [`next_hop`] must be set, and will be used by
    /// the server to select an appropriate device.
    device_id fuchsia.net.InterfaceId;

    /// The IP address of the next hop. Used for link-layer address resolution, if present.
    next_hop fuchsia.net.IpAddress:optional;

    /// This entry's metric.
    ///
    /// [`UNSPECIFIED_METRIC`] is interpreted as unspecified.
    metric uint32;
};

type Error = strict enum {
    INTERNAL = 1;
    NOT_SUPPORTED = 2;
    INVALID_ARGS = 3;
    BAD_STATE = 4;
    TIME_OUT = 5;
    NOT_FOUND = 6;
    ALREADY_EXISTS = 7;
    IO = 8;
};

@discoverable
protocol Stack {
    /// Add a new entry to the forwarding table.
    ///
    /// If the table already contains an entry with the same subnet and
    /// destination, an already exists error is returned.
    AddForwardingEntry(struct {
        entry ForwardingEntry;
    }) -> () error Error;

    /// Removes the forwarding entry. The entry must exactly match an entry in
    /// the forwarding table, with the exception of the metric value, which is
    /// ignored.
    DelForwardingEntry(struct {
        entry ForwardingEntry;
    }) -> () error Error;

    /// Sets the IP forwarding state for an interface.
    // TODO(https://fxbug.dev/94475): Remove this.
    @deprecated("Use fuchsia.net.interfaces.admin/Control.SetConfiguration")
    SetInterfaceIpForwardingDeprecated(struct {
        id fuchsia.net.InterfaceId;
        ip_version fuchsia.net.IpVersion;
        enabled bool;
    }) -> () error Error;

    /// Get a [`fuchsia.net.name/DnsServerWatcher`].
    GetDnsServerWatcher(resource struct {
        watcher server_end:fuchsia.net.name.DnsServerWatcher;
    });

    /// Enables or disables the DHCP client on an interface.
    /// TODO(https://fxbug.dev/81593): Remove this once the DHCP client is moved
    /// out of the netstack.
    SetDhcpClientEnabled(resource struct {
        id fuchsia.net.InterfaceId;
        enable bool;
    }) -> () error Error;

    /// Creates a bridge over the provided `interfaces`.
    ///
    /// If the bridge can't be created, `bridge` is closed with a `BAD_PORT`
    /// termination reason.
    ///
    /// NOTE: We're shoehorning bridging into the `admin/Control` API and
    /// reassigning meaning to `BAD_PORT` because we don't want to leak
    /// bridging-specific errors there. The POR is that bridging is going to get
    /// its own API at some point.
    ///
    /// Bridge lifetime is controlled through the `bridge` handle.
    // TODO(https://fxbug.dev/86661): Redesign and re-home this.
    BridgeInterfaces(resource struct {
        interfaces vector<fuchsia.net.InterfaceId>:MAX;
        bridge server_end:fuchsia.net.interfaces.admin.Control;
    });
};

@discoverable
protocol Log {
    /// Dynamically set packet logging.
    // TODO(fxbug.dev/42432): replace with optional packet captures in Inspect
    // output.
    SetLogPackets(struct {
        enabled bool;
    }) -> ();
};
