| // Copyright 2020 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=7) |
| library fuchsia.net.interfaces; |
| |
| using fuchsia.hardware.network; |
| using fuchsia.net; |
| using zx; |
| |
| /// The maximum length of an interface name. |
| // `sizeof((struct ifreq).ifr_name) == 16`; the last byte is reserved for the |
| // null terminator. |
| const INTERFACE_NAME_LENGTH uint8 = 15; |
| |
| /// An interface name as a sequence of bytes. |
| alias Name = string:INTERFACE_NAME_LENGTH; |
| |
| // TODO(https://fxbug.dev/7913): Use built-in empty struct when available. |
| type Empty = struct {}; |
| |
| /// Information about the preferred lifetime of an IP address or delegated |
| /// prefix. |
| @available(added=9) |
| type PreferredLifetimeInfo = strict union { |
| /// The end of the preferred lifetime. |
| /// |
| /// The address/prefix should *not* be considered deprecated if `zx.time` |
| /// is in the past. `preferred_until` is exchanged as a means to inform |
| /// the deadline where deprecation is expected to happen. |
| /// |
| /// The preferred lifetime of addresses is defined in |
| /// [RFC 4862, section 2](https://tools.ietf.org/html/rfc4862#section-2). |
| /// |
| /// Addresses configured using a delegated prefix must have a preferred |
| /// lifetime no longer than that of the prefix according to |
| /// [RFC 8415, section 6.3](https://datatracker.ietf.org/doc/html/rfc8415#section-6.3). |
| /// |
| /// Must be greater than 0. If `zx.time.INFINITE`, the preferred lifetime |
| /// does not expire. |
| 1: preferred_until zx.time; |
| |
| /// The address/prefix is deprecated. |
| /// |
| /// Deprecated addresses should no longer be used for initiating |
| /// new connections unless explicitly requested, or if no other |
| /// non-deprecated addresses are assigned (as described in |
| /// [RFC 4862, section 1](https://tools.ietf.org/html/rfc4862#section-1)). |
| /// |
| /// Addresses configured using a deprecated delegated prefix must also be |
| /// deprecated according to |
| /// [RFC 8415, section 6.3](https://datatracker.ietf.org/doc/html/rfc8415#section-6.3). |
| /// |
| /// An address/prefix can become undeprecated if its preferred lifetime is |
| /// extended. |
| 2: deprecated Empty; |
| }; |
| |
| /// Properties of a network interface. |
| type Properties = table { |
| /// An opaque identifier for the interface. Its value will not be reused |
| /// even if the device is removed and subsequently re-added. Immutable. |
| 1: id fuchsia.net.InterfaceId; |
| /// The addresses currently assigned to the interface. |
| /// |
| /// Addresses are sorted on [`Address.addr`], and no two addresses can |
| /// have the same `Address.addr` value. |
| 2: addresses vector<@generated_name("Address") table { |
| /// The address and prefix length. |
| /// |
| /// Required. |
| 1: addr fuchsia.net.Subnet; |
| /// The time after which the address will no longer be valid. |
| /// |
| /// Its value must be greater than 0. A value of `ZX_TIME_INFINITE` |
| /// indicates that the address will always be valid. The value is |
| /// derived from the monotonic clock. |
| /// |
| /// As a `zx.time`, the value has |
| /// [monotonic clock semantics](https://fuchsia.dev/fuchsia-src/concepts/time/monotonic), |
| /// which implies that it has no meaning outside of the host on which it |
| /// was generated and no meaning across host restarts. |
| /// |
| /// Optional; may be omitted due to disinterest. |
| 2: valid_until zx.time; |
| // TODO(https://fxbug.dev/107618): Send this field to clients. |
| /// Preferred lifetime information. |
| /// |
| /// Optional; may be omitted due to disinterest. |
| @available(added=9) |
| 3: preferred_lifetime_info PreferredLifetimeInfo; |
| }>:MAX; |
| /// The device is enabled and its physical state is online. |
| 3: online bool; |
| /// The device class of the interface. Immutable. |
| 4: device_class strict union { |
| /// The interface is loopback. |
| 1: loopback Empty; |
| /// The interface's network device class. |
| 2: device fuchsia.hardware.network.DeviceClass; |
| }; |
| |
| /// Whether there is a default IPv4 route through this interface. |
| 5: has_default_ipv4_route bool; |
| /// Whether there is a default IPv6 route through this interface. |
| 6: has_default_ipv6_route bool; |
| /// The name of the interface. Immutable. |
| 7: name Name; |
| }; |
| |
| /// Network interface state inspection and observation. |
| @discoverable |
| protocol State { |
| /// Initialize a watcher for interface state. |
| /// |
| /// The server enqueues interface addition, deletion and property changes as |
| /// they occur, which can then be retrieved via the pipelined protocol. |
| /// |
| /// + request `options` specifies the behavior of the [`Watcher`]. |
| /// + request `watcher` grants access to a [`Watcher`]. Closed if the queue |
| /// cannot be allocated or if the queue is full when the server attempts |
| /// to enqueue an event. |
| GetWatcher(resource struct { |
| /// Options for configuring the interface state watcher. |
| options @generated_name("WatcherOptions") table { |
| // TODO(https://fxbug.dev/110587): Implement disinterest in address |
| // properties in NS3. |
| // TODO(https://fxbug.dev/110587): Add netemul integration tests |
| // once fuchsia.net.interfaces.admin/Control.AddAddress supports |
| // address lifetimes. |
| /// Bitfield for registering interest in address properties. |
| /// |
| /// Optional; interpreted as all bits set to 0 if not present. |
| @available(added=HEAD) |
| 1: address_properties_interest flexible bits : uint64 { |
| VALID_UNTIL = 0x01; |
| PREFERRED_LIFETIME_INFO = 0x02; |
| }; |
| // TODO(https://fxbug.dev/110084): Add bitfield for registering |
| // interest in the other interface property fields. |
| }; |
| watcher server_end:Watcher; |
| }); |
| }; |
| |
| /// Observer protocol for changes to network interfaces (addition, deletion, and |
| /// interface property changes). |
| protocol Watcher { |
| /// Hanging get for an interface addition/deletion change. |
| /// |
| /// Clients should only have one call of this method at a time; a second |
| /// call to this method while a call is already pending will cause the |
| /// server end of the protocol to be closed. |
| /// |
| /// If there are N interfaces present at the time the server end of the |
| /// protocol is initialized, then the first N invocations of this method |
| /// will return [`Event.existing`] followed by a single [`Event.idle`] |
| /// indicating that all existing interfaces have been sent. Subsequent calls |
| /// will immediately return if there is a change to be reported, or block |
| /// until a change occurs. |
| /// |
| /// The server may choose to coalesce property change events, e.g. when |
| /// multiple independent property changes occur. As a result, clients cannot |
| /// assume that the order in which they observe the interface changes is the |
| /// order in which the changes occurred. |
| /// |
| /// - response `event` the interface change event. |
| Watch() -> (struct { |
| event strict union { |
| /// Properties of an interface that existed when watching started. |
| /// |
| /// All interested fields and [`Properties.id`] are set. |
| 1: existing Properties; |
| /// Properties of an interface that was added while watching. |
| /// |
| /// All interested fields and [`Properties.id`] are set. |
| 2: added Properties; |
| /// ID of an interface that was removed while watching. |
| 3: removed fuchsia.net.InterfaceId; |
| /// Properties of an interface that changed while watching. |
| /// |
| /// Only [`Properties.id`] and interested fields which have changed |
| /// are set with the new values. |
| 4: changed Properties; |
| /// Sentinel value indicating no more [`existing`] events will be |
| /// sent. |
| 5: idle Empty; |
| }; |
| }); |
| }; |