Three Gorges Dam from space
Three Gorges Dam from space (source: NASA via Wikimedia Commons)

When managing Junos devices, it is helpful to understand the way configuration data is validated and activated. When you commit a configuration change, a lot of work happens behind the scenes to ensure that you end up with a working configuration that is applied to all the appropriate components of the system.

The commit process

When you execute the commit command, the Junos software follows a carefully orchestrated process to ensure that the device ends up with a usable configuration.

Note

In this process, we describe a system with redundant routing engines (REs). In fact, we describe a system with more than two REs, as that system follows the most complicated commit process. To simplify this process for a system with fewer REs (even a single-RE system), simply omit the steps that apply to the other REs.

The steps are as follows:

  1. The master RE runs its commit checks. This may include:

    • Checking for consistency in the data. (For example, if a BGP group refers to a policy, that policy should be defined.)

    • Running commit scripts. (Commit scripts can return warnings or errors that are caught at this stage.)

    • Running daemons in a special mode that conducts more in-depth analysis of the candidate configuration.

  2. The master RE pushes the configuration to the other REs and asks those REs to conduct their commit checks.

  3. The other REs activate the new configuration.

  4. The master RE activates the new configuration.

If an error is detected at any step in the process, the commit process is aborted and the software returns to using the previous active configuration.

This process enforces a contract with the user: Junos will take the time it needs to thoroughly validate that the configuration is acceptable, and in return it will ensure that the Junos software components will be able to parse the configuration at the end of the process. In essence, you are sacrificing time in return for reliability.

Validating the configuration

The management daemon validates that each statement is syntactically correct. (Here, "syntactic correctness" refers to each command being properly formed and constructing a valid configuration block.) If it notices a problem, it typically rejects the configuration statement.

Additionally, MGD conducts some semantic checks as you modify the configuration. (Here, "semantic correctness" refers to the state where the entire configuration is coherent and understandable.) If it notices a problem, it typically adds a comment to the configuration to warn you of the problem. In this example, the BGP configuration references an export policy, but the policy it references is not in the configuration:

[edit]
user@r0# show protocols bgp export
export does_not_exist; ## 'does_not_exist' is not defined

Once you commit the configuration, MGD will again conduct its semantic checks; however, these checks will either result in an error or warning, as appropriate. For example, if you attempt to commit the configuration with the BGP export policy still undefined, you will see this output:

[edit]
user@r0# commit
error: Policy error: Policy does_not_exist referenced but not defined
[edit protocols bgp]
  'export'
    BGP: export list not applied
error: configuration check-out failed

If the MGD semantic checks pass, MGD applies any commit scripts that are listed in the candidate configuration. The commit scripts can return warnings or errors. Warnings are displayed to the user but do not impact the commit process. Errors are displayed to the user and abort the commit process. (There is more information about commit scripts in not available.)

If the commit scripts return no errors, MGD calls the various daemons interested in the changes and asks them to verify that the configuration is semantically correct. These daemons can return warnings or errors. Again, both are displayed to the user, but only errors abort the commit process.

Tip

Use the command commit check to view the results of these commit checks without actually committing the configuration.

Activating the configuration

When the RE activates the new configuration, the configuration is merged with other data (such as the platform defaults and transient changes from commit scripts). The new configuration then atomically becomes the new "active" configuration.

Tip

You can see the platform defaults for a particular platform by running the following command:

show configuration groups junos-defaults

These configuration statements are applied like any other configuration group. That means that they can be overridden by user configuration. (Put differently, configuration groups are applied "behind" the user-supplied configuration, which means that user-supplied configuration can obscure conflicting portions of the default configuration.) This is a fancy and long-winded way of saying that the default configuration statements behave exactly the way you would expect default configuration statements to behave.

Signaling daemons

Once the configuration is committed, MGD makes any changes it needs to make (such as adding or deleting user accounts, or other changes that MGD is responsible for making) and signals other daemons to read the new configuration and activate the configuration changes each is responsible for. Because the Junos software tracks the changes a user has made, it only needs to signal the daemons that are interested in the parts of the configuration that have changed. Therefore, depending on the exact change, MGD may signal more or fewer daemons to reread the configuration. This means the device may do more or less work for each configuration change, depending on the content of the change.

Note

This behavior becomes more relevant as the size of the configuration grows. For example, it takes much less time for the routing protocol daemon (RPD) to read a configuration with only a single routing instance and 10 static routes than it does for RPD to read a configuration with 1,000 routing instances and 400,000 static routes. Knowing the nature of your commit performance can help you develop smart strategies for handling configuration commits.

You can see this behavior by adding the | display detail directive to the end of the commit command. This causes the CLI to display the details about the activities MGD undertakes in order to activate the configuration. Among other details, you should see which daemons MGD signals to reread the configuration.

In rare circumstances you may encounter a bug in the logic that may cause MGD to miss signaling a daemon. (Juniper doesn't like to see those bugs, but they can occur occasionally.) In those cases, you can use the command commit full to cause MGD to take all the actions to commit the entire configuration without regard to what has changed. If you do this, MGD acts as if the entire configuration has changed and all daemons are signaled to reread their configuration.

Creating the merged configuration view

Figure 1-1 gives a fuller expansion of the way configuration data, including transient commit script changes and platform defaults, is combined into a "merged view" that the daemons can use to activate the new configuration.

This figure shows how configuration data is merged
              together. Transient commit script changes take precedence over
              the static configuration. The static configuration takes
              precedence over configuration groups (including the platform
              defaults). This configuration data is merged together into a
              "merged view", which is what the daemons read when they activate
              the configuration.
Figure 1-1. The combination of configuration information from multiple sources

In general, configuration data is applied with this precedence:

  1. Transient changes from commit scripts

  2. The committed configuration (note that this includes any permanent changes made by a commit script)

  3. Configuration applied from configuration groups (which includes platform defaults)

Note

not available contains more information on commit scripts, including the difference between transient and permanent configuration changes. For now, it is sufficient to understand that commit scripts can produce different kinds of changes, which will be applied with different precedence.

Actually, to be a little more precise, transient changes from commit scripts, the committed configuration, and configuration groups in the static configuration are merged together. After the data from these various sources is merged together, this "merged" view of the configuration (you can call it the "post-inheritance" configuration) is what the various daemons read when they activate a new configuration.

Note

Configuration groups are only applied to configuration in the static configuration database. They are not applied to transient changes from commit scripts.

Configuration data flow

When you commit configuration changes, the new configuration data is placed into a shared database that all the daemons can access. When this configuration database changes, MGD uses Unix signals to signal the appropriate daemons to reread the new configuration. After reading the configuration, the daemons activate its contents. If the new configuration requires changes in the forwarding plane, this data will be propagated to the PFEs. This process is illustrated in Figure 1-2.

Figure 1-2. Configuration data flow
Article image: Three Gorges Dam from space (source: NASA via Wikimedia Commons).