Example: Automatically Configure Logical Interfaces and IP Addresses
Every interface you configure requires at least one logical unit and one IP address. Asynchronous Transfer Mode (ATM) interfaces also require a virtual circuit identifier (VCI) for each logical interface. If you need to configure multiple logical units on an interface, you can use a commit script and macro to complete the task quickly and with no errors.
Requirements
This example uses a device running Junos OS with physical ATM interfaces.
Overview and Commit Script
The following commit script expands an apply-macro
statement that provides the name of a physical ATM interface and
a set of parameters that specify how to configure a number of logical
units on the interface. The units and VCI numbers are numbered sequentially
from the unit
variable to the max
variable and are given IP addresses starting at
the address
variable. To loop through the
logical units, Extensible Stylesheet Language Transformations (XSLT)
uses recursion, which is implemented in the <emit-interface>
template. Calculation of the next address is performed in the <next-address>
template.
The example script is shown in both XSLT and SLAX syntax:
XSLT Syntax
<?xml version="1.0" standalone="yes"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:junos="http://xml.juniper.net/junos/*/junos" xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0"> <xsl:import href="../import/junos.xsl"/> <xsl:template match="configuration"> <xsl:for-each select="interfaces/apply-macro"> <xsl:variable name="device" select="name"/> <xsl:variable name="address" select="data[name='address']/value"/> <xsl:variable name="max" select="data[name='max']/value"/> <xsl:variable name="unit" select="data[name='unit']/value"/> <xsl:variable name="real-max"> <xsl:choose> <xsl:when test="string-length($max) > 0"> <xsl:value-of select="$max"/> </xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="real-unit"> <xsl:choose> <xsl:when test="string-length($unit) > 0"> <xsl:value-of select="$unit"/> </xsl:when> <xsl:when test="contains($device, '.')"> <xsl:value-of select="substring-after($device, '.')"/> </xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="real-device"> <xsl:choose> <xsl:when test="contains($device, '.')"> <xsl:value-of select="substring-before($device, '.')"/> </xsl:when> <xsl:otherwise><xsl:value-of select="$device"/></xsl:otherwise> </xsl:choose> </xsl:variable> <transient-change> <interfaces> <interface> <name><xsl:value-of select="$real-device"/></name> <xsl:call-template name="emit-interface"> <xsl:with-param name="address" select="$address"/> <xsl:with-param name="unit" select="$real-unit"/> <xsl:with-param name="max" select="$real-max"/> </xsl:call-template> </interface> </interfaces> </transient-change> </xsl:for-each> </xsl:template> <xsl:template name="emit-interface"> <xsl:param name="$max"/> <xsl:param name="$unit"/> <xsl:param name="$address"/> <unit> <name><xsl:value-of select="$unit"/></name> <vci><xsl:value-of select="$unit"/></vci> <family> <inet> <address><xsl:value-of select="$address"/></address> </inet> </family> </unit> <xsl:if test="$max > $unit"> <xsl:call-template name="emit-interface"> <xsl:with-param name="address"> <xsl:call-template name="next-address"> <xsl:with-param name="address" select="$address"/> </xsl:call-template> </xsl:with-param> <xsl:with-param name="unit" select="$unit + 1"/> <xsl:with-param name="max" select="$max"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="next-address"> <xsl:param name="address"/> <xsl:variable name="arg-prefix" select="substring-after($address, '/')"/> <xsl:variable name="arg-addr" select="substring-before($address, '/')"/> <xsl:variable name="addr"> <xsl:choose> <xsl:when test="string-length($arg-addr) > 0"> <xsl:value-of select="$arg-addr"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$address"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="prefix"> <xsl:choose> <xsl:when test="string-length($arg-prefix) > 0"> <xsl:value-of select="$arg-prefix"/> </xsl:when> <xsl:otherwise>32</xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="a1" select="substring-before($addr, '.')"/> <xsl:variable name="a234" select="substring-after($addr, '.')"/> <xsl:variable name="a2" select="substring-before($a234, '.')"/> <xsl:variable name="a34" select="substring-after($a234, '.')"/> <xsl:variable name="a3" select="substring-before($a34, '.')"/> <xsl:variable name="a4" select="substring-after($a34, '.')"/> <xsl:variable name="r3"> <xsl:choose> <xsl:when test="$a4 < 255"> <xsl:value-of select="$a3"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$a3 + 1"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="r4"> <xsl:choose> <xsl:when test="$a4 < 255"> <xsl:value-of select="$a4 + 1"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="0"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:value-of select="$a1"/> <xsl:text>.</xsl:text> <xsl:value-of select="$a2"/> <xsl:text>.</xsl:text> <xsl:value-of select="$r3"/> <xsl:text>.</xsl:text> <xsl:value-of select="$r4"/> <xsl:text>/</xsl:text> <xsl:value-of select="$prefix"/> </xsl:template> </xsl:stylesheet>
SLAX Syntax
version 1.0; ns junos = "http://xml.juniper.net/junos/*/junos"; ns xnm = "http://xml.juniper.net/xnm/1.1/xnm"; ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0"; import "../import/junos.xsl"; match configuration { for-each (interfaces/apply-macro) { var $device = name; var $address = data[name='address']/value; var $max = data[name='max']/value; var $unit = data[name='unit']/value; var $real-max = { if (string-length($max) > 0) { expr $max; } else { expr "0"; } } var $real-unit = { if (string-length($unit) > 0) { expr $unit; } else if (contains($device, '.')) { expr substring-after($device, '.'); } else { expr "0"; } } var $real-device = { if (contains($device, '.')) { expr substring-before($device, '.'); } else { expr $device; } } <transient-change> { <interfaces> { <interface> { <name> $real-device; call emit-interface($address, $unit = $real-unit, $max = $real-max); } } } } } emit-interface ($max, $unit, $address) { <unit> { <name> $unit; <vci> $unit; <family> { <inet> { <address> $address; } } } if ($max > $unit) { call emit-interface($unit = $unit + 1, $max) { with $address = { call next-address($address); } } } } next-address ($address) { var $arg-prefix = substring-after($address, '/'); var $arg-addr = substring-before($address, '/'); var $addr = { if (string-length($arg-addr) > 0) { expr $arg-addr; } else { expr $address; } } var $prefix = { if (string-length($arg-prefix) > 0) { expr $arg-prefix; } else { expr "32"; } } var $a1 = substring-before($addr, '.'); var $a234 = substring-after($addr, '.'); var $a2 = substring-before($a234, '.'); var $a34 = substring-after($a234, '.'); var $a3 = substring-before($a34, '.'); var $a4 = substring-after($a34, '.'); var $r3 = { if ($a4 < 255) { expr $a3; } else { expr $a3 + 1; } } var $r4 = { if ($a4 < 255) { expr $a4 + 1; } else { expr 0; } } expr $a1; expr "."; expr $a2; expr "."; expr $r3; expr "."; expr $r4; expr "/"; expr $prefix; }
Configuration
Procedure
Step-by-Step Procedure
To download, enable, and run the script:
Copy the script into a text file, name the file atm-logical.xsl or atm-logical.slax as appropriate, and download it to the /var/db/scripts/commit/ directory on the device.
Select the following test configuration stanzas, and press Ctrl+c to copy them to the clipboard.
If you are using the SLAX version of the script, change the filename at the
[edit system scripts commit file]
hierarchy level to atm-logical.slax.system { scripts { commit { allow-transients; file atm-logical.xsl; } } } interfaces { apply-macro at-1/2/3 { address 10.12.13.14/20; max 200; unit 32; } at-1/2/3 { atm-options { pic-type atm2; vpi 0; } } }
In configuration mode, issue the
load merge terminal
command to merge the stanzas into your device configuration.[edit] user@host# load merge terminal [Type ^D at a new line to end input] ... Paste the contents of the clipboard here ...
At the prompt, paste the contents of the clipboard by using the mouse and the paste icon.
Press Enter.
Press Ctrl+d.
Issue the
commit
command to commit the configuration.user@host# commit
Verification
Verifying the Configuration
Purpose
Verify that the correct changes are integrated into the configuration.
Action
Before you commit the configuration, you can verify that
the commit script will produce the correct results by issuing the show interfaces at-1/2/3 | display commit-scripts
configuration
mode command. After you commit the configuration, you can review the
active configuration by issuing the show configuration interfaces
at-1/2/3
operational mode command. The following output appears:
atm-options { pic-type atm2; vpi 0; } unit 32 { vci 32; family inet { address 10.12.13.14/20; } } unit 33 { vci 33; family inet { address 10.12.13.15/20; } } unit 34 { vci 34; family inet { address 10.12.13.16/20; } } unit 35 { vci 35; family inet { address 10.12.13.17/20; } } ... Logical units 36 through 199 are omitted for brevity ... unit 200 { vci 200 ; family inet { address 10.12.13.182/20; } }
Meaning
The | display commit-scripts
option displays
the configuration data after all commit scripts have been applied.
The output includes both persistent and transient changes. If the
appropriate unit
and vci
are configured on each ATM interface, the commit script executes
successfully during a commit operation. After you commit the configuration,
you can review the active configuration by issuing the show configuration
interfaces at-1/2/3
operational mode command.