// 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.
    /// + request `ip_version` the IP version 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, fuchsia.net.IpVersion ip_version)
        -> (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.
    /// + request `ip_version` the IP version to clear entries from.
    /// * 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, fuchsia.net.IpVersion ip_version)
        -> () error zx.status;

    /// Change the configuration of the neighbor discovery algorithm for an
    /// interface.
    ///
    /// + request `interface` the interface to be configured.
    /// + request `ip_version` the IP version 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, fuchsia.net.IpVersion ip_version,
                               UnreachabilityConfig config) -> () error zx.status;
};
