Back to Chromium

Open Network Configuration

chromeos/ash/components/network/onc/README.md

149.0.7827.215.8 KB
Original Source

Open Network Configuration

The Open Network Configuration (ONC) is a simple, open, but complete format that is used throughout ChromeOS to describe network configurations. While typically associated with enterprise policy, this format is used by all ChromeOS devices regardless of enrollment status. Nonetheless, it is important to remember that ONC is what enables enterprise policy to be capable of network configuration on ChromeOS.

Background

There are many layers involved when thinking about networking on ChromeOS (see more here), multiple of which involve ONC. Of these layers there are two areas in particular that are the most helpful to be familiar with and can be thought of as the "implementation" of ONC within ChromeOS: ONC constants and the translation to/from ONC.

ONC Constants

The ONC specification is defined in code in the chromium codebase. This specification documents every property that can be used in ONC, and where it can be used. For example,

## Ethernet networks

For Ethernet connections, **Type** must be set to
*Ethernet* and the field **Ethernet** must be set to an object of
type [Ethernet](#Ethernet-type).

### Ethernet type

* **Authentication**
    * (optional) - **string**
    * Allowed values are:
        * *None*
        * *8021X*

This section of ONC indicates that an ONC network configuration, when its Type property has the value of Ethernet, can have a property called Authentication with a value of None or 8021X. All of these fields, and every field needed to support the complete ONC specification, are defined as constants and organized such that they can easily be used by ChromeOS. These constants can be found in //components/onc.

Translation to/from ONC

As mentioned earlier, there are many layers when it comes to networking on ChromeOS and they do not all use ONC. In particular, the connection manager on ChromeOS, Shill, does not use ONC and requires that ONC be translated to the Shill format before being provided. This is by design; if Shill was tightly coupled with ONC it would be difficult or impossible for Shill to ever change its internal implementation. For example, there could be reasons why Shill would want to change which properties it exposes. By keeping ONC decoupled and making Chrome responsible for translation Shill is able to freely make changes without needing mirrored changes within ONC itself.

The core difference between the ONC and Shill formats is in the structure; ONC is nested, similar to JSON, and the Shill format is flat. This can be more clearly seen when inspecting the properties of a network using chrome://network.

ONC

  "WiFi": {
    "BSSID": "13:37:13:37:13:37",
    "BSSIDAllowlist": [],
    "BSSIDRequested": ""
  },

Shill

  "WiFi.BSSID": "13:37:13:37:13:37",
  "WiFi.BSSIDAllowlist": [],
  "WiFi.BSSIDRequested": "",

The ONC format uses two separate keys, WiFi and BSSID, for the BSSID property of a WiFi network whereas the Shill format uses a single key, WiFi.BSSID. While the example above would be straightforward to translate there are many unintuitive cases that need to be supported:

  • Verification that required properties exist and have valid values
  • Default values
  • Merging multiple ONC configurations, especially in regards to policy, to create a single configuration with no conflicting properties or values

This complexity is managed with the help of different classes and utility functionality:

Signatures

The default values for all ONC properties are defined in the onc_signature.h/onc_signature.cc files. These values are defined using "signatures", allowing for information beyond just the default value to be provided, e.g., the type of the value itself. There are two distinct signature types that are organized in a hierarchical structure that matches the ONC specification: a "field" signature that is used for all ONC properties and a "value" signature that is used to define the values of ONC properties. The "field" signatures support nesting, and the "value" signatures do not. For example, the EID property of a cellular network would be a "field" signature and the value, e.g., what the EID actually is, would be a "value" signature.

While the commonly used value signatures have already been defined, it is possible to create custom signatures when necessary. For an example please see the IP address config type value.

Note: The Shill constants that ONC properties are mapped to can be found in dbus-constants.h.

Validator

ONC configurations are validated before being applied to ensure that they align with the specification. The validation is performed by the Validator class; examples of issues this class checks for are:

  • Field has a value with the incorrect type
  • Field has an unknown enum value
  • Field has an integer value that is out of range
  • Field name is unknown
  • Duplicate values for fields intended to be globally unique, e.g. GUID
  • Required field is missing
  • Recommended field contains the name of a field that was not provided in the configuration
  • Recommended field exists but the configuration is not from enterprise policy

Please reference the ONC spec for more information and examples of recommended values.

There are different modes that can be used when performing validation of an ONC configuration:

  • Log warnings
  • Error when an unknown field name is found
  • Error when a field is unexpectedly recommended
  • Enterprise policy

For more information on the impact these modes have when performing validation see the Validator class documentation.

Merging functionality

Multiple ONC configurations can be applied to a device; for example, a device may have a "global" ONC configuration that is applied to all users of a device and a "user" ONC configuration that is applied to a specific user. Similar to how functionality is provided to check if a configuration is valid, functionality is also provided to merge configurations:

  • MergeSettingsAndPoliciesToEffective() returns the result of merging the provided configurations. If conflicting values are found when merging the provided configurations the "effective", or highest priority value, will be chosen. For example, if a network is configured locally on the DUT by the user to have auto-connect enabled but a global policy restricts auto-connect the effective value of auto-connect will be disabled/off.
    • Please note that this function expects that the provided configurations refer to the same section/level of ONC.
  • MergeSettingsAndPoliciesToAugmented() returns the result of merging the provided configurations, similar to MergeSettingsAndPoliciesToEffective(), but instead of providing the effective value for each field this function will provide the augmented values. The "augmented" value of a field is a dictionary that includes the effective value and can include additional values that provide additional context about the field such as the source of the different values and their enforcement. For more information about the dictionary format of augmented values see the managed ONC dictionary format section of the specification.

Translation tables

The ONC translation tables define the mapping of ONC properties to Shill properties and provide helper functions for translating properties. The tables allow properties with a direct mapping to automatically be translated. However, while all properties should be included in these tables, some properties require additional logic to be translated correctly. When additional logic is required the property is expected to be commented out, and to have documentation on the extra translation logic required.

Translation functionality

Building upon the concepts and functionality discussed earlier in this document, there are two functions that are used to translate ONC to/from Shill properties. Both functions accept an ONC signature that indicates to the translation logic at which level this translation is occurring; this feature allows clients to translate to and from any level of properties rather than needing to translate only from top-level ONC to top-level Shill properties.

These functions, TranslateONCObjectToShill and TranslateShillServiceToONCPart, internally perform translation using the [translation tables](#translation tables) and signatures by default but are implemented such that custom translation logic can easily be added.

Configuring Networks With ONC

While users typically will not be configuring networks using ONC, there are three primary places that ONC is used within ChromeOS:

  • The ManagedNetworkConfigurationHandler class provides multiple APIs that are used for creating and configuring networks on ChromeOS. Unlike other networking classes, the ManagedNetworkConfigurationHandler class specifically only accepts ONC with a stated goal of decoupling users from direct interaction with Shill.
  • The chrome://network page is useful for debugging network issues and inspecting the properties of networks. However, this page also provides a mechanism to provide ONC to ChromeOS; try using this approach to configure your next network!
  • The UI that is used by administrators to managed enterprise enrolled devices provides the functionality to configure networks. These network configurations are translated to ONC before being sent via policy to ChromeOS devices.

Extending ONC

Extending ONC is straightforward but requires care to ensure that all of the necessary changes are made. Additionally, it is important to consider when making these changes is what the expected behavior is when an older client without these changes receives a policy with these changes; this case is far from uncommon and it is worth checking that no issues would be introduced.

Depending on how ONC is being extended not all of the changes mentioned are required, but the comprehensive list is as follows:

Examples

  • This change introduces a new property to the ONC specification. The added property is intended to be mutually exclusive with another property, and to enforce this behavior the validators were updated to check that only one is provided.
  • This change changes the default of an existing property to be a value other than the default value for the variable type; in this case the change makes a boolean property default to true.