| # Fuchsia Networking API Evolution |
| |
| Fuchsia Networking offers a broad range of APIs with sometimes overlapping |
| functionality. This document is the basis of ongoing API evolution. |
| |
| ## Background |
| |
| At the time of writing, Fuchsia Networking APIs are the result of rapid |
| evolution and often-unintentional stabilization, resulting in a large surface |
| with out-of-tree consumers. Many of these APIs evolved before newer FIDL |
| features were available, making in-place migration even more difficult. |
| |
| More than other system areas, Networking must be mindful of its APIs becoming |
| prematurely load bearing. |
| |
| ## Design Principles |
| |
| ### Deliberate Stabilization |
| |
| Consider this excerpt from the [FIDL API Rubric][library_structure]: |
| |
| > How you decompose these definitions into libraries has a large effect on the |
| > consumers of these definitions because a FIDL library is the unit of |
| > dependency and distribution for your protocols. |
| |
| Be mindful of this when creating new protocols. Undue grouping of protocols, |
| even when semantically logical, can produce unwanted distribution coupling. In |
| other words, consider minting new libraries for new protocols to avoid premature |
| inclusion in the SDK. |
| |
| Consider `fuchsia.net.Connectivity` as a motivating example: by having been |
| placed in `fuchsia.net`, its inclusion in the SDK was entangled with that |
| library; it was de-facto stabilized without a formal decision. |
| |
| Note that `fuchsia.net.Connectivity` was removed in 5500eec6aa48c65516eae4d5ef4. |
| |
| ### Role Separation |
| |
| The [FIDL API Rubric][library_structure] advises: |
| |
| > To decide whether to decompose a library into smaller libraries, consider the |
| > following questions: |
| > |
| > - Do the customers for the library break down into separate roles that would |
| > want to use a subset of the functionality or declarations in the library? If |
| > so, consider breaking the library into separate libraries that target each |
| > role. |
| |
| We prefer a different framing in Networking: separate your API into different |
| roles by breaking it into multiple *protocols*; separate your API into different |
| stabilization units by breaking into multiple *libraries*. |
| |
| ### Cardinality |
| |
| Avoid introducing APIs that are non-orthogonal to existing APIs. Providing |
| multiple entry points for the same purpose can lead to confusion for consumers |
| and subtle behaviour differences. |
| |
| ### Prior Art and Compatibility |
| |
| Consider compatibility with existing software when designing APIs. As Fuchsia's |
| product requirements grow in scope, so will the burden of porting software to |
| platform-specific APIs; consider how your API might be translated to an existing |
| API that is widely used in the industry. Furthermore, existing APIs have evolved |
| to provide solutions to problems we may not have considered, it behooves us to |
| learn from their efforts. |
| |
| The obvious motivating example here is POSIX sockets; `fuchsia.posix.socket` |
| evolved directly to address this need, complete with the over-fitting described |
| above. At the time of writing, the API transports C structures on the wire |
| directly, creating portability problems and resulting in an ABI that is not |
| fully defined in FIDL. |
| |
| A less-obvious motivating example is [`netlink`]; networking management APIs are |
| not standardized in POSIX, yet `netlink` is widely used in existing software to |
| interact with Linux's networking subsystems. |
| |
| ### Time Pressure |
| |
| It will sometimes be necessary to provide partners with SDK-exposed APIs on a |
| time scale that does not permit a reasoned general-purpose solution to be |
| designed. Prefer the narrowest possible design that provides for the partner's |
| needs to avoid acquiring unintended consumers. Provide your API in a new |
| protocol to ease future deprecation. |
| |
| This approach allows us to respond quickly without compromising our design |
| principles in the long term. |
| |
| ## Site Survey and Ongoing Work |
| |
| At present, these are the libraries considered in this document: |
| |
| - `fuchsia.hardware.ethernet` |
| + being replaced with `fuchsia.hardware.network` |
| + neither is planned for SDK inclusion |
| - `fuchsia.net` |
| + included in SDK |
| + contains only common types, no protocols |
| - fuchsia.net.dhcp |
| + not planned for SDK inclusion |
| - fuchsia.net.dhcpv6 |
| + not planned for SDK inclusion |
| - `fuchsia.net.filter.deprecated` |
| + not planned for SDK inclusion |
| + contains only protocol `Filter` |
| + needs rework in consideration of `NETLINK_NETFILTER` (undocumented?) |
| - `fuchsia.net.http` |
| + out of scope of this document, not maintained by networking |
| - `fuchsia.net.mdns` |
| + out of scope of this document. do we need to bring it in scope? |
| - `fuchsia.net.name` |
| + not included in SDK |
| + protocol `LookupAdmin` is the role-separated pair of `Lookup` |
| - `fuchsia.net.neighbor` |
| + not planned for SDK inclusion |
| - `fuchsia.net.routes` |
| + included in SDK |
| + narrow route+MAC resolution API in service of partner needs |
| - `fuchsia.net.stack` |
| + not included in SDK |
| + broad general-purpose protocol `Stack` does not employ role separation, |
| should be decomposed into several protocols after consulting industry |
| standards |
| + protocol `Log` to be replaced by inspect in https://fxbug.dev/42118625 |
| - `fuchsia.net.tun` |
| + not included in SDK |
| + ownership-based |
| - `fuchsia.posix.socket` |
| + not included in SDK |
| + used via fdio which is included in SDK |
| |
| [library_structure]: /docs/development/api/fidl.md#library_structure |
| [`netlink`]: https://man7.org/linux/man-pages/man7/netlink.7.html |