// Copyright 2013 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.netstack;

using fuchsia.hardware.ethernet;
using fuchsia.net.dhcp;
using fuchsia.net.interfaces;
using fuchsia.net;
using zx;

type NetErr = struct {
    status strict enum {
        OK = 0;
        UNKNOWN_ERROR = 1;
        DNS_ERROR = 2;
        PARSE_ERROR = 3;
        IPV4_ONLY = 4;
        UNKNOWN_INTERFACE = 5;
    };
    message string:MAX;
};

type RouteTableEntry = struct {
    destination fuchsia.net.Subnet;
    gateway fuchsia.net.IpAddress:optional;
    nicid uint32;
    metric uint32;
};

@discoverable
protocol Netstack {
    /// Returns current route table.
    GetRouteTable() -> (struct {
        rt vector<RouteTableEntry>:MAX;
    });

    /// Sets the status (up or down) for the interface with the given nicid.
    SetInterfaceStatus(struct {
        nicid uint32;
        enabled bool;
    });

    /// Sets the address for the interface with the given nicid.
    /// Masks off addr.PrefixLen bits from addr.Addr to set the subnet.
    @deprecated("Use fuchsia.net.interfaces.admin/Control.AddAddress")
    SetInterfaceAddress(struct {
        nicid uint32;
        addr fuchsia.net.IpAddress;
        prefix_len uint8;
    }) -> (struct {
        result NetErr;
    });

    /// Removes the address for the interface with the given nicid.
    /// Masks off addr.PrefixLen bits from addr.Addr to set the subnet.
    @deprecated("Use fuchsia.net.interfaces.admin/Control.RemoveAddress")
    RemoveInterfaceAddress(struct {
        nicid uint32;
        addr fuchsia.net.IpAddress;
        prefix_len uint8;
    }) -> (struct {
        result NetErr;
    });

    /// Sets the route metric for the interface with the given nicid.
    SetInterfaceMetric(struct {
        nicid uint32;
        metric uint32;
    }) -> (struct {
        result NetErr;
    });

    /// Creates a bridge and returns the newly created nicid or an
    /// error if the creation fails.
    BridgeInterfaces(struct {
        nicids vector<uint32>:MAX;
    }) -> (struct {
        result NetErr;
        nicid uint32;
    });

    /// Adds a new interface backed by the given ethernet device.
    AddEthernetDevice(resource struct {
        topological_path string:MAX;
        interface_config struct {
            name fuchsia.net.interfaces.name;

            /// An unstable file path corresponding to the interface. Used in
            /// watching the creation and destruction of the interface, or in
            /// accessing the interface using netdump.
            filepath string:MAX;

            metric uint32;
        };
        device client_end:fuchsia.hardware.ethernet.Device;
    }) -> (struct {
        nicid uint32;
    }) error zx.status;

    /// Connects to a DHCP client.
    ///
    /// + request `nicid` the interface on which the target client is running.
    /// + request `request` grants control over the client.
    // TODO(stijlist): re-home this protocol. GetDhcpClient should be a member
    // of the protocol that eventually owns network interface management
    // in general.
    GetDhcpClient(resource struct {
        nicid uint32;
        client server_end:fuchsia.net.dhcp.Client;
    }) -> (struct {}) error zx.status;

    /// Begin a route transaction to synchronize updates to the route table.
    ///
    /// Returns `ZX_OK` if a transaction can be started; `ZX_ERR_SHOULD_WAIT` if
    /// a transaction is currently in progress.
    StartRouteTableTransaction(resource struct {
        route_table_transaction server_end:RouteTableTransaction;
    }) -> (struct {
        status zx.status;
    });
};

@discoverable
protocol RouteTableTransaction {
    AddRoute(struct {
        r RouteTableEntry;
    }) -> (struct {
        status zx.status;
    });
    DelRoute(struct {
        r RouteTableEntry;
    }) -> (struct {
        status zx.status;
    });
};
