示例:自动配置逻辑接口和 IP 地址
您配置的每个接口至少需要一个逻辑单元和一个 IP 地址。 异步传输模式 (ATM) 接口还需要每个逻辑接口的虚拟电路标识符 (VCI)。如果您需要在一个接口上配置多个逻辑单元,则可以使用提交脚本和宏快速完成任务,而不会出错。
要求
此示例使用使用物理 ATM 接口运行 Junos OS 的设备。
概述和提交脚本
以下提交脚本将扩展一个apply-macro语句,该语句提供物理 ATM 接口的名称和一组参数,用于指定如何在接口上配置多个逻辑单元。单元和 VCI 编号按顺序从变量编号到max变量,并提供从unit变量开始address的 IP 地址。要在逻辑单元中循环,可扩展样式表语言转换 (XSLT) 使用在模板中<emit-interface>实施的复发。在模板中执行下一个地址的<next-address>计算。
该示例脚本同时显示在 XSLT 和 SLAX 语法中:
XSLT 语法
<?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 语法
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;
}
配置
程序
逐步过程
要下载、启用和运行脚本:
将脚本复制到文本文件中,根据需要命名文件 atm-logical.xsl 或 atm-logical.slax ,然后将其下载到设备上的 /var/db/scripts/commit/ directory。
选择以下测试配置部分,然后按 Ctrl+c 将其复制到剪贴板。
如果您使用脚本的 SLAX 版本,请将层次结构级别的文件
[edit system scripts commit file]名更改为 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; } } }在配置模式下
load merge terminal,发出 命令将部分合并到设备配置中。[edit] user@host# load merge terminal [Type ^D at a new line to end input] ... Paste the contents of the clipboard here ...
出现提示时,使用鼠标和粘贴图标粘贴剪贴板的内容。
按 Enter。
按下 Ctrl+d。
commit发出 命令提交配置。user@host# commit
验证
验证配置
目的
验证是否已将正确的更改集成到配置中。
行动
提交配置之前,您可以验证提交脚本是否将发出 show interfaces at-1/2/3 | display commit-scripts 配置模式命令,从而生成正确的结果。提交配置后,可通过发出 show configuration interfaces at-1/2/3 操作模式命令来查看活动配置。显示以下输出:
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;
}
}
意义
在应用了所有提交脚本之后,选项 | display commit-scripts 将显示配置数据。输出包括持续和瞬时更改。如果适用 unit 且 vci 已在每个 ATM 接口上配置,则提交脚本在提交操作期间成功执行。提交配置后,可通过发出 show configuration interfaces at-1/2/3 操作模式命令来查看活动配置。