// Copyright 2019 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.

/// The neighbor table helps decide where to send IP packets. It allows for the
/// translation between IP addresses and MAC addresses.
///
/// With current implementations, the neighbor table uses the ARP or NDP
/// protocol to dynamically discover new neighbor entries for IPv4 or IPv6
/// addresses, respectively.
///
/// This library enables inspection and manipulation of the neighbor table.
///  * See [`fuchsia.net.neighbor/View`] for viewing neighbor table entries and
///    interface configuration.
///  * See [`fuchsia.net.neighbor/Controller`] for adding static neighbor table
///    entries, removing entries, and updating interface configuration.
///
/// # Important Concepts
///
///
/// [`Entry`] represents a neighboring device and is stored in the neighbor
/// table, which is also managed by the networking stack.
///
/// [`UnreachabilityConfig`] holds the various parameters used for tweaking the
/// behavior of Neighbor Unreachability Detection (NUD). This allows
/// implementations to operate over links with widely varying performance
/// characteristics.
///
/// # Privacy Considerations
///
/// The Neighbor API deals with MAC addresses, which are device identifiers and
/// should not be exposed to most applications. There are separate protocols for
/// inspecting and modifying the neighbor table; this is done to protect
/// sensitive data.
///
/// # Security Considerations
///
/// The Neighbor API enables clients to view and manipulate the neighbor table,
/// which should both be privileged actions and granted only to trusted
/// applications. Additionally, not all clients will need both read and write
/// access. This has been addressed by splitting methods into two protocols:
/// Viewer for read methods and Controller for write methods.
///
/// This API is not concerned with throttling consumption of ARP or NDP
/// messages. If a DoS of ARP/NDP packets reaches this API, the damage had
/// already been done. Once the packets reach the control plane, they are
/// processed by the networking stack where the DoS would first manifest.
library fuchsia.net.neighbor;

using fuchsia.net;
using zx;

/// Inspect the neighbor table and related interface configuration.
[Discoverable]
protocol View {
    /// Open a connection to an [`EntryIterator`] for listing existing entries
    /// and optionally watching for state changes.
    ///
    /// + request `it` request the server to bind an implementation of
    ///     `EntryIterator` to this channel.
    /// + request `options` modifies the behavior of the [`EntryIterator`].
    OpenEntryIterator(request<EntryIterator> it, EntryIteratorOptions options);

    /// View the current configurations of an interface.
    ///
    /// + request `interface` interface to read configurations from.
    /// - response `config` a snapshot of the interface's configuration.
    /// * error `ZX_ERR_NOT_FOUND` if `interface` does not exist.
    // TODO(fxbug.dev/59058): Reading configuration should be moved to
    // interface-scoped protocols in fuchsia.net.interfaces.
    GetUnreachabilityConfig(fuchsia.net.interface_id interface)
        -> (UnreachabilityConfig config) error zx.status;
};

/// Modify the neighbor table and related interface configuration.
[Discoverable]
protocol Controller {
    /// Create a static entry. If a conflict is found, overwrite the existing
    /// entry. Conflicts occur when two entries have the same interface
    /// identifier and IP address.
    ///
    /// + request `interface` identifier for the interface used for
    ///     communicating with the neighbor.
    /// + request `neighbor` IP address of the neighbor.
    /// + request `mac` MAC address of the neighbor.
    /// * error `ZX_ERR_NOT_FOUND` if `interface` does not exist.
    /// * error `ZX_ERR_NOT_SUPPORTED` if `interface` does not keep a neighbor
    ///     table (e.g. point-to-point links).
    AddEntry(fuchsia.net.interface_id interface, fuchsia.net.IpAddress neighbor, fuchsia.net.MacAddress mac)
        -> () error zx.status;

    /// Delete a dynamic or static entry.
    ///
    /// + request `interface` identifier for the interface associated with the
    ///     entry to be deleted.
    /// + request `neighbor` IP address of the entry to be deleted.
    /// * error `ZX_ERR_NOT_FOUND` if no entries match `interface` and
    ///   `neighbor`.
    /// * error `ZX_ERR_NOT_SUPPORTED` if `interface` does not keep a neighbor
    ///     table (e.g. point-to-point links).
    RemoveEntry(fuchsia.net.interface_id interface, fuchsia.net.IpAddress neighbor)
        -> () error zx.status;

    /// Delete all dynamic and static entries belonging to an interface.
    ///
    /// + request `interface` identifier for the interface associated with the
    ///     entries to be deleted.
    /// * error `ZX_ERR_NOT_FOUND` if `interface` does not exist.
    /// * error `ZX_ERR_NOT_SUPPORTED` if `interface` does not keep a neighbor
    ///     table (e.g. point-to-point links).
    ClearEntries(fuchsia.net.interface_id interface) -> () error zx.status;

    /// Change the configuration of the neighbor discovery algorithm for an
    /// interface.
    ///
    /// + request `interface` the interface to be configured.
    /// + request `config` used for updating the configuration for an interface.
    ///     Only the specified fields will be changed. All other fields will
    ///     remain the same as the original configuration.
    /// * error `ZX_ERR_NOT_FOUND` if `interface` references an interface that
    ///     does not exist.
    /// * error `ZX_ERR_NOT_SUPPORTED` if `interface` references an interface
    ///     that does not keep a neighbor table (e.g. point-to-point links).
    /// * error `ZX_ERR_INVALID_ARGS` if `config` contains an invalid value,
    ///     see [`fuchsia.net.neighbor/UnreachabilityConfig`] for the list of
    ///     constraints.
    // TODO(fxbug.dev/59058): Updating configuration should be moved to
    // interface-scoped protocols in fuchsia.net.interfaces.
    UpdateUnreachabilityConfig(fuchsia.net.interface_id interface, UnreachabilityConfig config)
        -> () error zx.status;
};
