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 macro to complete the task quickly and with no errors.
This example 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.
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;
}