// 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.
@available(added=HEAD)
library fuchsia.net.stack;

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
closed 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.
    strict 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.
    strict DelForwardingEntry(struct {
        entry ForwardingEntry;
    }) -> () error Error;

    /// Enables or disables the DHCP client on an interface.
    /// TODO(https://fxbug.dev/42162065): Remove this once the DHCP client is moved
    /// out of the netstack.
    strict 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.
    strict BridgeInterfaces(resource struct {
        interfaces vector<fuchsia.net.InterfaceId>:MAX;
        bridge server_end:fuchsia.net.interfaces.admin.Control;
    });
};

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