The Junos load command loads configuration from a file or the terminal. It is an incredibly useful and powerful tool.
Remember that none of the changes you make with the load command will become active until you commit the configuration. So as long as you don’t commit, you can always use ‘rollback 0’ to abandon your changes.
I like to think that the general form of the command is ‘load <type> <source> <options>’. The type can be one of the following:
The source can either be a filename or ‘terminal’ if you want to paste configuration into your cli session. One option you can specify is ‘relative’, this means the supplied configuration is relative to where you are in the configuration hierarchy. I’ll have examples of this as we go through the various load types below.
Text Formatting Of Source File or Terminal Input
When loading configuration from a file, or the terminal, the configuration needs to be correctly formatted and have the full path specified. That is, it should look the same as when you ‘show’ the configuration. All of the curly braces need to be in the right place, and you need to have the right number of opening and closing braces.
The exception to this is when you use the ‘relative’ option. This makes the configuration relative to where you are in the configuration hierarchy.
When using the terminal as the source, the input needs to end with a new line, and then <Ctrl-D>. That is hold the control key and press the ‘D’ key.
This is an example of some “good” interface configuration:
interfaces {
ge-0/0/1 {
unit 0 {
family inet {
address 192.168.20.1/24;
}
}
}
ge-0/0/2 {
unit 0 {
family inet {
address 10.100.1.2/24;
}
}
}
ge-0/0/3 {
description Good-Description;
}
fxp0 {
unit 0 {
family inet {
address 10.0.0.21/24;
}
}
}
}
Here is an example of some “bad” interface configuration:
interfaces {
ge-0/0/1 {
unit 0 {
family inet {
address 192.168.20.1/24;
}
}
ge-0/0/2 {
unit 0 {
family inet {
address 10.100.1.2/24
}
}
}
ge-0/0/3 {
{
description Good-Description;
}
fxp0 {
family inet {
address 10.0.0.21/24;
}
}
}
}
- Missing closing brace on ge-0/0/1 unit 0
- Missing semi-colon on address statement for ge-0/0/2
- Extra opening brace under ge-0/0/3
- Missing unit 0 line under fxp0.
If you were at the ‘interfaces ge-0/0/2’ level of the configuration, then the following could be added using the ‘relative’ option.
unit 0 {
family inet {
address 10.100.1.2/24;
}
}
Load Factory-Default
The load factory-default command will set the configuration back to the default configuration for that version of Junos. The exact configuration may differ between devices and software versions. A default configuration for an SRX firewall will differ from that of an MX series router or EX series switch. Once you’ve loaded this configuration, you must set the root password before you’ll be able to commit the configuration or you will get a missing mandatory statement error.
This will retain local data on the device. If you want to wipe the logs, rollbacks, and other local user data, then you should consider running ‘request system zeroize’.
The below example is from a vMX. I won’t show the current configuration but will show how many lines it is for comparison to the factory default.
[edit]
lab@vMX-1# show | count
Count: 118 lines
[edit]
lab@vMX-1# load factory-default
warning: activating factory configuration
[edit]
lab@vMX-1# show | count
Count: 16 lines
[edit]
lab@vMX-1# show
## Last changed: 2024-01-01 09:41:20 UTC
system {
commit {
factory-settings;
}
syslog {
file messages {
any notice;
authorization info;
}
file interactive-commands {
interactive-commands any;
}
}
## Warning: missing mandatory statement(s): 'root-authentication'
}
[edit]
lab@vMX-1#
Load Override
Load override will replace the entire current configuration with whatever is in the file you specify or that you load via the terminal. When you commit an override configuration, all of the subsystems will re-parse the configuration.
Load override comes in useful in three common situations.
Firstly, when restoring a configuration to a device. This might occur when a router has failed. Once the device is replaced and you have management access to the new router, you can copy the backup file to the device and use load override to apply it.
Secondly, in production networks when making major or complicated changes that might involve many steps. You can save the configuration to a file before starting the change. If you need to back out the change for any reason you can simply load the saved configuration file. You could also use the rollback function, but if you have made a lot of commits during the change, the original configuration may not be one of the available rollbacks.
Thirdly, in lab or teaching environments. Load override allows you to quickly reconfigure the device to a known configuration. You might save different configurations to use the device for different purposes. Perhaps one for a routing lab, another for an MPLS lab, and yet another for a multicast lab. Load override allows you to quickly switch between these configurations.
Here are a couple of examples:
Load Override With A Partial Configuration File
In this example, I’ve saved the interface configuration to a file called Config-Backup-Interfaces.conf, and am now loading it via the load override command. Note how the entire config was replaced, and only the interface configuration is set.
lab@vMX-1# show | count
Count: 118 lines
[edit]
lab@vMX-1# load override /var/home/lab/Config-Backup-Interfaces.conf
load complete
[edit]
lab@vMX-1# show | count
Count: 29 lines
[edit]
lab@vMX-1# show
## Last changed: 2024-01-01 11:07:15 UTC
interfaces {
ge-0/0/1 {
mac aa:bb:cc:dd:00:10;
unit 0 {
family inet {
address 192.168.20.1/24;
}
}
}
ge-0/0/2 {
mac aa:bb:cc:dd:00:11;
unit 0 {
family inet {
address 10.100.1.2/24;
}
}
}
ge-0/0/3 {
description Good-Description;
}
fxp0 {
unit 0 {
family inet {
address 10.0.0.21/24;
}
}
}
}
[edit]
lab@vMX-1#
Load Override With A Partial Configuration Via Terminal
In this example, the configuration is loaded via the terminal. Load override does not have a ‘relative’ option, as it replaces the entire configuration with whatever is supplied.
Again, I’m just using a partial configuration to illustrate how this command works. You should always use a complete configuration when running this command.
[edit]
lab@vMX-1# load override terminal
[Type ^D at a new line to end input]
interfaces {
ge-0/0/2 {
unit 0 {
family inet {
address 10.100.1.2/24;
}
}
}
}
load complete
[edit]
lab@vMX-1# show
## Last changed: 2024-01-01 11:15:24 UTC
interfaces {
ge-0/0/2 {
unit 0 {
family inet {
address 10.100.1.2/24;
}
}
}
}
[edit]
lab@vMX-1#
Load Merge
The load merge command merges the configuration into your candidate configuration. It is useful for adding new config where it does not exist in the current configuration. For example, adding a new interface or policy statement.
When merging with the existing configuration, the new config will take precedence where only one value can be specified. Think of an interface MTU setting or description. Where more than one value can be specified, such as next-hops for routes or IP addresses for interfaces, a second entry will be added.
In this example, we will merge some interface and policy updates. The existing config is shown below.
interfaces {
ge-0/0/1 {
mac aa:bb:cc:dd:00:10;
unit 0 {
family inet {
address 192.168.20.1/24;
}
}
}
ge-0/0/2 {
mac aa:bb:cc:dd:00:11;
unit 0 {
family inet {
address 10.100.1.2/24;
}
}
}
ge-0/0/3 {
description Good-Description;
mtu 2000;
unit 0 {
family inet {
address 192.168.0.1/24;
}
}
}
fxp0 {
unit 0 {
family inet {
address 10.0.0.21/24;
}
}
}
}
policy-options {
policy-statement test-policy {
term export-static {
from protocol static;
then accept;
}
term reject-bgp {
from protocol bgp;
then reject;
}
term final {
then reject;
}
}
}
The following merges are done with terminal input, but you can also use a file. The terminal method makes the example a little clearer.
[edit]
lab@vMX-1# load merge terminal
[Type ^D at a new line to end input]
interfaces {
ge-0/0/3 {
description "Updated Description";
mtu 4096;
unit 0 {
family inet {
address 172.16.0.1/24;
}
}
}
ge-0/0/4 {
description "New Interface Here";
unit 0 {
family inet {
address 192.168.1.1/24;
}
}
}
}
policy-options {
policy-statement test-policy {
term export-ospf {
from protocol ospf;
then accept;
}
}
}
load complete
[edit]
lab@vMX-1# show | compare
[edit interfaces ge-0/0/3]
- description Good-Description;
+ description "Updated Description";
- mtu 2000;
+ mtu 4096;
[edit interfaces ge-0/0/3 unit 0 family inet]
address 192.168.0.1/24 { ... }
+ address 172.16.0.1/24;
[edit interfaces]
+ ge-0/0/4 {
+ description "New Interface Here";
+ unit 0 {
+ family inet {
+ address 192.168.1.1/24;
+ }
+ }
+ }
[edit policy-options policy-statement test-policy]
term final { ... }
+ term export-ospf {
+ from protocol ospf;
+ then accept;
+ }
[edit]
lab@vMX-1#
From the above output you can see that:
- ge-0/0/4 is added in its entirety, as it did not previously exist
- ge-0/0/3 had its MTU and description replaced with the new values
- ge-0/0/3 had an additional IP Address entered, rather than replacing the existing one. This is because an interface can have more than one IP Address.
- The additional policy term we added was placed at the end of the policy-statement
Let’s look at interface ge-0/0/3 and the policy-statement to make those last two points a bit clearer.
[edit]
lab@vMX-1# show interfaces ge-0/0/3
description "Updated Description";
mtu 4096;
unit 0 {
family inet {
address 192.168.0.1/24;
address 172.16.0.1/24;
}
}
[edit]
lab@vMX-1# show policy-options
policy-statement test-policy {
term export-static {
from protocol static;
then accept;
}
term reject-bgp {
from protocol bgp;
then reject;
}
term final {
then reject;
}
term export-ospf {
from protocol ospf;
then accept;
}
}
[edit]
lab@vMX-1#
To move the new term to where it should be in the policy-statement, we use the insert command.
[edit]
lab@vMX-1# insert policy-options policy-statement test-policy term export-ospf before term final
[edit]
lab@vMX-1# show policy-options
policy-statement test-policy {
term export-static {
from protocol static;
then accept;
}
term reject-bgp {
from protocol bgp;
then reject;
}
term export-ospf {
from protocol ospf;
then accept;
}
term final {
then reject;
}
}
[edit]
lab@vMX-1#
After doing a rollback 0, let’s now look at using the relative option. Here, we’ll just do the ge-0/0/3 portion of what was done above.
[edit]
lab@vMX-1# edit interfaces ge-0/0/3
[edit interfaces ge-0/0/3]
lab@vMX-1# load merge terminal relative
[Type ^D at a new line to end input]
description "Updated Description";
mtu 4096;
unit 0 {
family inet {
address 172.16.0.1/24;
}
}
load complete
[edit interfaces ge-0/0/3]
lab@vMX-1# top
[edit]
lab@vMX-1# show | compare
[edit interfaces ge-0/0/3]
- description Good-Description;
+ description "Updated Description";
- mtu 2000;
+ mtu 4096;
[edit interfaces ge-0/0/3 unit 0 family inet]
address 192.168.0.1/24 { ... }
+ address 172.16.0.1/24;
[edit]
lab@vMX-1#
Load Patch
When you perform a show | compare, Junos is comparing the current candidate configuration against the current active configuration. This produces a “patch” output similar to the Unix ‘diff’ command.
This “patch” can be applied with a load patch command.
This makes it very easy to apply a change to one device, do a show | compare, and apply the output to other devices.
A few things worth noting are:
- load patch doesn’t have a relative option. The patch itself includes information about the “path” of where the configuration should be applied
- Because the patch includes the “path” information, terms added to a policy will be in the correct location
- The patch file can both add and remove configuration.
Here is an example. It is the same as the merge example above, except we are also removing a term from the test-policy as well.
[edit]
lab@vMX-1# load patch terminal
[Type ^D at a new line to end input]
[edit interfaces ge-0/0/3]
- description Good-Description;
+ description "Updated Description";
- mtu 2000;
+ mtu 4096;
[edit interfaces ge-0/0/3 unit 0 family inet]
address 192.168.0.1/24 { ... }
+ address 172.16.0.1/24;
[edit interfaces]
+ ge-0/0/4 {
+ description "New Interface Here";
+ unit 0 {
+ family inet {
+ address 192.168.1.1/24;
+ }
+ }
+ }
[edit policy-options policy-statement test-policy]
term reject-bgp { ... }
+ term export-ospf {
+ from protocol ospf;
+ then accept;
+ }
term final { ... }
[edit policy-options policy-statement test-policy]
- term export-static {
- from protocol static;
- then accept;
- }
load complete
[edit]
lab@vMX-1# show | compare
[edit interfaces ge-0/0/3]
- description Good-Description;
+ description "Updated Description";
- mtu 2000;
+ mtu 4096;
[edit interfaces ge-0/0/3 unit 0 family inet]
address 192.168.0.1/24 { ... }
+ address 172.16.0.1/24;
[edit interfaces]
+ ge-0/0/4 {
+ description "New Interface Here";
+ unit 0 {
+ family inet {
+ address 192.168.1.1/24;
+ }
+ }
+ }
[edit policy-options policy-statement test-policy]
term reject-bgp { ... }
+ term export-ospf {
+ from protocol ospf;
+ then accept;
+ }
term final { ... }
[edit policy-options policy-statement test-policy]
- term export-static {
- from protocol static;
- then accept;
- }
[edit]
lab@vMX-1#
Notice how the patch we applied and the show | compare output match?
Let’s look at the policy-statement.
[edit]
lab@vMX-1# show policy-options
policy-statement test-policy {
term reject-bgp {
from protocol bgp;
then reject;
}
term export-ospf {
from protocol ospf;
then accept;
}
term final {
then reject;
}
}
[edit]
lab@vMX-1#
The export-ospf term has been added where we wanted it, before the final term. The export-static term has been removed.
Load Replace
The load replace command is used to replace certain parts of the configuration. The behavior can be a little confusing at first.
In the configuration file you are loading, the portions or stanzas of config you want to replace need to have the “replace:” tag in front of them.
- Where the new configuration has a replace tag, and that config is already defined, it is replaced with the new configuration.
- Where the new configuration has a replace tag, and the config is not already defined, the new config is merged in.
- Where the new configuration does not have a replace tag, it is merged in.
That sounds a bit complicated, so time for an example. Replace tags are set on the interfaces, but not the policy.
[edit]
lab@vMX-1# load replace terminal
[Type ^D at a new line to end input]
interfaces {
replace: ge-0/0/3 {
description "Updated Description";
mtu 4096;
unit 0 {
family inet {
address 172.16.0.1/24;
}
}
}
replace: ge-0/0/4 {
description "New Interface Here";
unit 0 {
family inet {
address 192.168.1.1/24;
}
}
}
}
policy-options {
policy-statement test-policy {
term export-ospf {
from protocol ospf;
then accept;
}
}
}
load complete
[edit]
lab@vMX-1# show | compare
[edit interfaces ge-0/0/3]
- description Good-Description;
+ description "Updated Description";
- mtu 2000;
+ mtu 4096;
[edit interfaces ge-0/0/3 unit 0 family inet]
+ address 172.16.0.1/24;
- address 192.168.0.1/24;
[edit interfaces]
+ ge-0/0/4 {
+ description "New Interface Here";
+ unit 0 {
+ family inet {
+ address 192.168.1.1/24;
+ }
+ }
+ }
[edit policy-options policy-statement test-policy]
term final { ... }
+ term export-ospf {
+ from protocol ospf;
+ then accept;
+ }
[edit]
lab@vMX-1#
Since the ge-0/0/3 interface had the replace tag, and it existed in the configuration already, it was replaced by the config that was loaded.
The ge-0/0/4 interface also had the replace tag, but since it didn’t already exist, this config was merged in.
The policy-statement did not have the replace tag. It was treated as a merge and added the new export-ospf term.
Here is another example. This time we are just replacing the policy-statement.
[edit]
lab@vMX-1# load replace terminal
[Type ^D at a new line to end input]
policy-options {
replace: policy-statement test-policy {
term export-ospf {
from protocol ospf;
then accept;
}
}
}
load complete
[edit]
lab@vMX-1# show | compare
[edit policy-options policy-statement test-policy]
+ term export-ospf {
+ from protocol ospf;
+ then accept;
+ }
- term export-static {
- from protocol static;
- then accept;
- }
- term reject-bgp {
- from protocol bgp;
- then reject;
- }
- term final {
- then reject;
- }
[edit]
lab@vMX-1#
Load Update
The load update command is another that can be slightly confusing, and the behavior can be a bit unexpected.
It compares the candidate configuration and the newly applied configuration and makes updates where needed. Although this sounds like you can simply replace a small section of the configuration, you need to provide a complete configuration file.
Firstly, let’s look at an example gone wrong. We’ll use the same configuration we used for the load merge example. Then we’ll do a simple show, and not a show | compare.
[edit]
lab@vMX-1# load update terminal
[Type ^D at a new line to end input]
interfaces {
ge-0/0/3 {
description "Updated Description";
mtu 4096;
unit 0 {
family inet {
address 172.16.0.1/24;
}
}
}
ge-0/0/4 {
description "New Interface Here";
unit 0 {
family inet {
address 192.168.1.1/24;
}
}
}
}
policy-options {
policy-statement test-policy {
term export-ospf {
from protocol ospf;
then accept;
}
}
}
load complete
[edit]
lab@vMX-1# show
## Last changed: 2024-01-01 23:27:58 UTC
interfaces {
ge-0/0/3 {
description "Updated Description";
mtu 4096;
unit 0 {
family inet {
address 172.16.0.1/24;
}
}
}
ge-0/0/4 {
description "New Interface Here";
unit 0 {
family inet {
address 192.168.1.1/24;
}
}
}
}
policy-options {
policy-statement test-policy {
term export-ospf {
from protocol ospf;
then accept;
}
}
}
[edit]
lab@vMX-1#
As you can see, the entire configuration has been replaced with only what we pasted in.
It appears this command instead wants a complete configuration file that you have updated already. To simulate this I repeated the load patch example and saved that configuration as Test-Config-1.conf before rolling back to our base config. We’ll use this file in the next example.
[edit]
lab@vMX-1# load update /var/home/lab/Test-Config-1.conf
load complete
[edit]
lab@vMX-1# show | compare
[edit interfaces ge-0/0/3]
- description Good-Description;
+ description "Updated Description";
- mtu 2000;
+ mtu 4096;
[edit interfaces ge-0/0/3 unit 0 family inet]
+ address 172.16.0.1/24;
- address 192.168.0.1/24;
[edit interfaces]
+ ge-0/0/4 {
+ description "New Interface Here";
+ unit 0 {
+ family inet {
+ address 192.168.1.1/24;
+ }
+ }
+ }
[edit policy-options policy-statement test-policy]
term reject-bgp { ... }
+ term export-ospf {
+ from protocol ospf;
+ then accept;
+ }
term final { ... }
[edit]
lab@vMX-1#
Take particular note of interface ge-0/0/3. The IP address has been replaced. The policy also has the new term in the right location.
Load Set
The load set command takes set commands and applies them.
This one almost sounds a bit redundant, why have a load set option when you could just paste in all of the set commands and achieve the same outcome?
The answer is that pasting in a lot of set commands, especially over the console, can be error-prone. If you want to test this out, try pasting in hundreds of set commands over a console connection and see whether you get any errors.
Let’s try the full path first.
[edit]
lab@vMX-1# load set terminal
[Type ^D at a new line to end input]
set interfaces ge-0/0/3 description "Updated Description"
set interfaces ge-0/0/3 mtu 4096
set interfaces ge-0/0/3 unit 0 family inet address 172.16.0.1/24
set interfaces ge-0/0/4 description "New Interface Here"
set interfaces ge-0/0/4 unit 0 family inet address 192.168.1.1/24
set policy-options policy-statement test-policy term export-ospf from protocol ospf
set policy-options policy-statement test-policy term export-ospf then accept
insert policy-options policy-statement test-policy term export-ospf before term final
load complete
[edit]
lab@vMX-1# show | compare
[edit interfaces ge-0/0/3]
- description Good-Description;
+ description "Updated Description";
- mtu 2000;
+ mtu 4096;
[edit interfaces ge-0/0/3 unit 0 family inet]
address 192.168.0.1/24 { ... }
+ address 172.16.0.1/24;
[edit interfaces]
+ ge-0/0/4 {
+ description "New Interface Here";
+ unit 0 {
+ family inet {
+ address 192.168.1.1/24;
+ }
+ }
+ }
[edit policy-options policy-statement test-policy]
term reject-bgp { ... }
+ term export-ospf {
+ from protocol ospf;
+ then accept;
+ }
term final { ... }
[edit]
lab@vMX-1#
Now we’ll use the relative option from under the interfaces stanza.
[edit]
lab@vMX-1# edit interfaces
[edit interfaces]
lab@vMX-1# load set terminal relative
[Type ^D at a new line to end input]
set ge-0/0/3 description "Updated Description"
set ge-0/0/3 mtu 4096
set ge-0/0/3 unit 0 family inet address 172.16.0.1/24
set ge-0/0/4 description "New Interface Here"
set ge-0/0/4 unit 0 family inet address 192.168.1.1/24
load complete
[edit interfaces]
lab@vMX-1# top
[edit]
lab@vMX-1# show | compare
[edit interfaces ge-0/0/3]
- description Good-Description;
+ description "Updated Description";
- mtu 2000;
+ mtu 4096;
[edit interfaces ge-0/0/3 unit 0 family inet]
address 192.168.0.1/24 { ... }
+ address 172.16.0.1/24;
[edit interfaces]
+ ge-0/0/4 {
+ description "New Interface Here";
+ unit 0 {
+ family inet {
+ address 192.168.1.1/24;
+ }
+ }
+ }
[edit]
lab@vMX-1#
Summary
So what do we take away from all of this?
Load merge and load patch are great for adding additional configuration to devices.
Load replace can be tricky. It allows you to replace parts of the config in their entirety but also acts similar to a load merge in some situations.
Load update is perhaps most useful when you save a copy of the configuration and update it with a text editor. You can then copy the file back onto the router and perform a load update to reflect all of the changes into your current candidate configuration.
Load override will replace the entire configuration and is useful for restoring backups or reverting to saved configurations.
As mentioned at the start, the load command is very useful. When used wisely it can save a lot of time and effort when configuring Junos devices.