| // Copyright 2021 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.interfaces.admin; |
| |
| using fuchsia.net; |
| using fuchsia.hardware.network; |
| using fuchsia.net.interfaces; |
| using zx; |
| |
| /// NudConfiguration for an interface. |
| /// |
| /// This is scoped to IPv4 or IPv6 configuration by the [`Configuration`] type. |
| type NudConfiguration = table { |
| /// The number of multicast solicitations before considering a neighbor |
| /// unreachable. |
| /// |
| /// Must be nonzero. `ILLEGAL_ZERO_VALUE` is returned on |
| /// [`Control.SetConfiguration`] otherwise. |
| 1: max_multicast_solicitations uint16; |
| /// The number of unicast solicitations before considering a neighbor |
| /// unreachable. |
| /// |
| /// Must be nonzero. |
| 2: max_unicast_solicitations uint16; |
| /// A base duration for computing the random reachable time. |
| /// |
| /// Reachable time is the duration for which a neighbor is considered |
| /// reachable after a positive reachability confirmation is received. |
| /// After this time, an entry will transition from REACHABLE to STALE state. |
| /// |
| /// Referred to as "BaseReachableTime" by RFC 4861. |
| /// |
| /// Must be greater than 0. |
| 3: base_reachable_time zx.Duration; |
| }; |
| |
| /// DAD (Duplicate Address Detection) configuration for an interface. |
| type DadConfiguration = table { |
| /// Number of transmissions before an address is considered available for |
| /// use. |
| /// |
| /// A value of zero effectively disables DAD for the interface. |
| 1: transmits uint16; |
| }; |
| |
| /// The configuration for an interface. |
| type Configuration = table { |
| /// The IPv4 configuration for an interface. |
| 1: ipv4 @generated_name("Ipv4Configuration") table { |
| /// Controls whether or not IPv4 unicast packets may be forwarded if not |
| /// destined to the host. |
| /// TODO(https://fxbug.dev/42052564): Rename this field to |
| /// unicast_forwarding. |
| 1: forwarding bool; |
| |
| /// Controls whether or not IPv4 multicast packets may be forwarded. |
| 2: multicast_forwarding bool; |
| |
| /// Controls IGMP configuration. |
| 3: igmp @generated_name("IgmpConfiguration") table { |
| /// Indicates the version of IGMP to be performed. |
| /// |
| /// Note that the stack may perform lower versioned IGMP as required |
| /// for backwards compatibility with other nodes on the network per |
| /// IGMP requirements. |
| 1: version @generated_name("IgmpVersion") flexible enum : uint8 { |
| /// IGMPv1. |
| V1 = 1; |
| /// IGMPv2. |
| V2 = 2; |
| /// IGMPv3. |
| V3 = 3; |
| }; |
| }; |
| |
| /// Controls ARP configuration. |
| 4: arp @generated_name("ArpConfiguration") table { |
| /// Neighbor Unreachabilty Detection over ARP configuration. |
| 1: nud NudConfiguration; |
| // TODO(https://fxbug.dev/42077260): Add DAD configuration when DAD |
| // over IPv4 is supported. |
| }; |
| }; |
| |
| /// The IPv6 configuration for an interface. |
| 2: ipv6 @generated_name("Ipv6Configuration") table { |
| /// Controls whether or not IPv6 unicast packets may be forwarded if not |
| /// destined to the host. |
| /// TODO(https://fxbug.dev/42052564): Rename this field to |
| /// unicast_forwarding. |
| 1: forwarding bool; |
| |
| /// Controls whether or not IPv6 multicast packets may be forwarded. |
| 2: multicast_forwarding bool; |
| |
| /// Controls MLD configuration. |
| 3: mld @generated_name("MldConfiguration") table { |
| /// Indicates the version of MLD to be performed. |
| /// |
| /// Note that the stack may perform lower versioned MLD as required |
| /// for backwards compatibility with other nodes on the network per |
| /// MLD requirements. |
| 1: version @generated_name("MldVersion") flexible enum : uint8 { |
| /// MLDv1. |
| V1 = 1; |
| /// MLDv2. |
| V2 = 2; |
| }; |
| }; |
| |
| /// Controls NDP configuration. |
| 4: ndp @generated_name("NdpConfiguration") table { |
| /// Neighbor Unreachabilty Detection over NDP configuration. |
| 1: nud NudConfiguration; |
| /// Duplicate Address Detection over NDP configuration. |
| 2: dad DadConfiguration; |
| }; |
| }; |
| }; |
| |
| /// A credential passed into the `fuchsia.net.*` family of APIs to authenticate |
| /// access to a particular interface. The Netstack only needs the ability to |
| /// inspect the token's basic info when proving that the client is authorized |
| /// to access a resource. |
| type ProofOfInterfaceAuthorization = resource struct { |
| /// The ID of the interface this credential is authenticating. |
| interface_id fuchsia.net.InterfaceId; |
| /// The EVENT providing authentication over this interface. The token |
| /// only requires the `TRANSFER` right so that it can be sent to the |
| /// Netstack. |
| token zx.Handle:<EVENT, zx.Rights.TRANSFER>; |
| }; |
| |
| /// Provides control over an interface. |
| /// |
| /// This protocol encodes the underlying interface's lifetime in both |
| /// directions; the interface exists iff both ends of the protocol are open. |
| /// That is: |
| /// |
| /// - Closing the client end causes the interface to be removed. |
| /// - Observing a closure of the server end indicates the interface no longer |
| /// exists. |
| closed protocol Control { |
| // TODO(https://fxbug.dev/42160986): Currently Netstack2's implementation |
| // does not support any values being present in `parameters`, and will |
| // cause an event containing `AddressRemovalReason.INVALID` to be sent |
| // and the server end of the protocol to be closed. |
| // TODO(https://fxbug.dev/42051260): Clarify address semantics in regards to |
| // adding and removing same address on different subnets and/or interfaces. |
| /// Assigns an address to the interface. |
| /// |
| /// Errors are communicated via |
| /// [`fuchsia.net.interfaces.admin/AddressStateProvider.OnAddressRemoved`]. |
| /// |
| /// + request `address` the address to assign to the interface. |
| /// + request `parameters` additional address-specific options. |
| /// + request `address_state_provider` provides address assignment state |
| /// and enables updating address properties. |
| strict AddAddress(resource struct { |
| address fuchsia.net.Subnet; |
| parameters AddressParameters; |
| address_state_provider server_end:AddressStateProvider; |
| }); |
| |
| /// Removes an address from the interface. |
| /// |
| /// + request `address` the address to remove. |
| /// - response `did_remove` `true` iff `address` was removed from the |
| /// interface as a consequence of this call. |
| strict RemoveAddress(struct { |
| address fuchsia.net.Subnet; |
| }) -> (struct { |
| did_remove bool; |
| }) error flexible enum {}; |
| |
| /// Gets the interface identifier. |
| /// |
| /// - response `id` the interface identifier. |
| strict GetId() -> (struct { |
| id fuchsia.net.InterfaceId; |
| }); |
| |
| /// Sets the configuration for the interface. |
| /// |
| /// Only set fields that are supported in the provided [`Configuration`] |
| /// will be set; unset fields will be left unmodified. The server will |
| /// return a [`Configuration`] which holds the previous configuration for |
| /// fields that the interface supports and set, even if the call did not |
| /// update the configuration's value. |
| /// |
| /// + request `config` the configuration fields to update on the interface. |
| /// - response `previous_config` a snapshot of the interface's previous |
| /// configuration. Only supported fields present in `config` will be set. |
| strict SetConfiguration(struct { |
| config Configuration; |
| }) -> (struct { |
| previous_config Configuration; |
| }) error flexible enum { |
| /// Indicates that the provided value for `config.ipv4.forwarding` is |
| /// unsupported. |
| IPV4_FORWARDING_UNSUPPORTED = 1; |
| /// Indicates that the provided value for `config.ipv4.multicast_forwarding` |
| /// is unsupported. |
| IPV4_MULTICAST_FORWARDING_UNSUPPORTED = 2; |
| /// Indicates that the provided value for `config.ipv4.igmp.version` is |
| /// unsupported. |
| IPV4_IGMP_VERSION_UNSUPPORTED = 3; |
| /// Indicates that the provided value for `config.ipv6.forwarding` is |
| /// unsupported. |
| IPV6_FORWARDING_UNSUPPORTED = 4; |
| /// Indicates that the provided value for `config.ipv6.multicast_forwarding` |
| /// is unsupported. |
| IPV6_MULTICAST_FORWARDING_UNSUPPORTED = 5; |
| /// Indicates that the provided value for `config.ipv6.mld.version` is |
| /// unsupported. |
| IPV6_MLD_VERSION_UNSUPPORTED = 6; |
| /// Indicates that a zero value was provided for a field that must be |
| /// nonzero. |
| ILLEGAL_ZERO_VALUE = 7; |
| /// Indicates that ARP configurations are not supported for this device. |
| /// |
| /// Devices without a link (notably loopback) do not support ARP. |
| ARP_NOT_SUPPORTED = 8; |
| /// Indicates that NDP configurations are not supported for this device. |
| /// |
| /// Devices without a link (notably loopback) do not support NDP. |
| NDP_NOT_SUPPORTED = 9; |
| /// Indicates that a negative value was provided for a field that must be |
| /// non-negative. |
| ILLEGAL_NEGATIVE_VALUE = 10; |
| }; |
| |
| /// Gets a snapshot of the interface's configuration. |
| /// |
| /// The server will populate the returned [`Configuration`] with the |
| /// configuration for features/protocols that the interface supports. That |
| /// is, fields for unsupported configurations will be unset in the returned |
| /// [`Configuration`]. |
| /// |
| /// - response `config` a snapshot of the interface's configuration. |
| strict GetConfiguration() -> (struct { |
| config Configuration; |
| }) error flexible enum {}; |
| |
| /// Enables the interface. |
| /// |
| /// - response `did_enable` `true` iff the interface moved from disabled to |
| /// enabled as a consequence of this call. |
| strict Enable() -> (struct { |
| did_enable bool; |
| }) error flexible enum {}; |
| |
| /// Disables the interface. |
| /// |
| /// - response `did_disable` `true` iff the interface moved from enabled to |
| /// disabled as a consequence of this call. |
| strict Disable() -> (struct { |
| did_disable bool; |
| }) error flexible enum {}; |
| |
| /// Detaches the client end from the interface's lifetime. |
| /// |
| /// After calling `Detach`, closing this client end no longer causes the |
| /// interface to be removed. |
| strict Detach(); |
| |
| /// Get an authentication credential for this interface. |
| /// |
| /// The credential contains a [`zx::handle::EVENT`], whose entangled |
| /// partner is held by the server. This credential can be converted into a |
| /// [`ProofOfInterfaceAuthorization`] and then passed into `fuchsia.net.*` |
| /// API calls to prove ownership of this interface. The `EVENT` is |
| /// stable throughout the lifetime of the interface. Clients may duplicate |
| /// this `EVENT` to make multiple API calls, or transfer the `EVENT` |
| /// to other clients. |
| /// |
| /// - response `credential` the authorization credential for this interface. |
| strict GetAuthorizationForInterface() -> (resource struct { |
| credential @generated_name("GrantForInterfaceAuthorization") resource struct { |
| /// The ID of the interface this credential is authenticating. |
| interface_id fuchsia.net.InterfaceId; |
| /// The EVENT providing authentication over this interface. |
| token zx.Handle:<EVENT, zx.Rights.TRANSFER | zx.Rights.DUPLICATE>; |
| }; |
| }); |
| |
| /// Initiates interface removal. |
| /// |
| /// This method returns success once interface removal has started. When the |
| /// interface is removed, a `USER` removed reason is issued in |
| /// [`OnInterfaceRemoved`] and the server end is closed. |
| strict Remove() -> () error flexible enum { |
| /// This interface can't be removed. |
| NOT_ALLOWED = 1; |
| }; |
| |
| /// Terminal event. Immediately precedes the closure of the server end of |
| /// the protocol. |
| /// |
| /// - response `reason` the removal reason. |
| strict -> OnInterfaceRemoved(struct { |
| reason @generated_name("InterfaceRemovedReason") flexible enum { |
| /// Interface failed to be instantiated because the requested name |
| /// is in use. |
| DUPLICATE_NAME = 1; |
| /// The requested port is already bound to an interface. |
| PORT_ALREADY_BOUND = 2; |
| /// The provided device port can't be made into an interface because |
| /// of incompatible configuration. |
| BAD_PORT = 3; |
| /// The device port backing this interface has been closed. |
| PORT_CLOSED = 4; |
| /// Administrative user action removed the interface. |
| USER = 5; |
| }; |
| }); |
| }; |
| |
| /// Installs devices on the network stack. |
| @discoverable |
| closed protocol Installer { |
| /// Installs a device on the network stack. |
| /// |
| /// + request `device` the device to install on the network stack. |
| /// + request `device_control` grants access to the installed device. |
| strict InstallDevice(resource struct { |
| device client_end:fuchsia.hardware.network.Device; |
| device_control server_end:DeviceControl; |
| }); |
| }; |
| |
| /// Administrative control over an installed device on the network stack. |
| /// |
| /// An instance of `DeviceControl` maps to an instance of |
| /// [`fuchsia.hardware.network/Session`]. All interfaces generated from a single |
| /// `DeviceControl` instance share the same `Session` and set of device buffers; |
| /// and are therefore subject to backpressure over the same pool of resources. |
| /// |
| /// By the same measure, creating multiple `DeviceControl` instances attached to |
| /// the same underlying device causes data copies, because each `DeviceControl` |
| /// starts a new `Session`. For that reason, users should avoid creating |
| /// multiple `DeviceControl` instances for the same device and prefer |
| /// instantiating ports into interfaces from a single `DeviceControl` instance |
| /// per device. |
| /// |
| /// This protocol encodes the underlying device's lifetime in both |
| /// directions; the device exists iff both ends of the protocol are open. |
| /// That is: |
| /// |
| /// - Closing the client end causes the device to be removed, including all |
| /// interfaces created from it. |
| /// - Observing a closure of the server end indicates the device (and all |
| /// interfaces created from it) no longer exists. |
| closed protocol DeviceControl { |
| /// Creates an interface on the network stack. |
| /// |
| /// + request `port` the device's port to instantiate as an interface. |
| /// + request `control` grants access to the created interface. |
| strict CreateInterface(resource struct { |
| port fuchsia.hardware.network.PortId; |
| control server_end:Control; |
| options table { |
| /// New interface name. |
| /// |
| /// If not set, an implementation-defined name will be selected. |
| 1: name fuchsia.net.interfaces.Name; |
| /// The default metric value used for routes through this interface. |
| /// |
| /// If not set, the server will use a sensible default. |
| 2: metric fuchsia.net.RouteMetric; |
| }; |
| }); |
| |
| /// Detaches the client end from the device's lifetime. |
| /// |
| /// After calling `Detach`, closing this client end no longer causes the |
| /// device or any of the interfaces created from it to be removed. Note that |
| /// the lifetime of any created interface will continue to be coupled with |
| /// the associated [`Control`] client end. |
| strict Detach(); |
| }; |