http://qs321.pair.com?node_id=11132953

jamescmatt has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I only come here as I have been working on a script for a bit and keep running into the same problem. When iterating through the loop, when it hits a service-instance with a filter, it always puts the filter on the following interface. I know I suck at all of this and sorry for the bothering.

Example of configuration file I am using (I call it for instance, gi1_3, and the outgoing file, ge-1/1/1 ( from cli, ./parser.pl gi1_3 ge-1/1/1). What the script does is take an interface configuration, parse through it, and match based on a string. When it matches, it sets it to a variable so I can convert the configuration from Cisco to Juniper. The issue I have as stated above, is that when iterating through, for whatever reason the match on the service-policy is always put on the line after it. Now I know I am not great at perl and I do my best, but I just can't figure out how to fix this, and I have tried everything. EDIT: I found a workable solution(print filter earlier, in hindsight I can probably do this for all matches, and probably will soon), and a few edits. I think this is a great script for anyone in my line of work and can easily be modified for use-case. As such, going to toss in a few updates to the below. I know it isn't perfect and can be made tons better, but I do what I can with what I have.

service instance 20 ethernet description Internal site encapsulation dot1q 17 rewrite ingress tag pop 1 symmetric xconnect 192.168.51.20 838969735 encapsulation mpls mtu 9202 ! service instance 21 ethernet description Client 1 important encapsulation dot1q 18 rewrite ingress tag pop 1 symmetric xconnect 192.168.51.21 838969736 encapsulation mpls mtu 9202 ! service instance 22 ethernet description Client other 2 encapsulation dot1q 22 rewrite ingress tag pop 1 symmetric xconnect 192.168.56.22 838925386 encapsulation mpls mtu 9202 ! service instance 23 ethernet description Client name with fun stuff encapsulation dot1q 3200 second-dot1q 5 rewrite ingress tag pop 2 symmetric service-policy input CoS_222_333_23 xconnect 192.168.56.23 571125465 encapsulation mpls mtu 9202 ! service instance 24 ethernet description Client - not as important encapsulation dot1q 3200 second-dot1q 6 rewrite ingress tag pop 2 symmetric service-policy input 222_444_24 xconnect 192.168.56.24 571637077 encapsulation mpls mtu 9202
Below is the output I get when running my script (only a partial of the output)
set interfaces ge-1/1/1 unit 23 description "Client name with fun stuf +f" set interfaces ge-1/1/1 unit 23 encapsulation vlan-ccc set interfaces ge-1/1/1 unit 23 vlan-tags outer 3200 inner 5 set interfaces ge-1/1/1 unit 23 input-vlan-map pop-pop set interfaces ge-1/1/1 unit 23 output-vlan-map push-push COS: set class-of-service interfaces ge-1/1/1 unit 23 rewrite-rules ieee-80 +2.1 vlan-tag outer-and-inner set protocols l2circuit neighbor 192.168.56.23 interface ge-1/1/1.23 d +escription "Client name with fun stuff" set protocols l2circuit neighbor 192.168.56.23 interface ge-1/1/1.23 c +ontrol-word set protocols l2circuit neighbor 192.168.56.23 interface ge-1/1/1.23 i +gnore-mtu-mismatch set protocols l2circuit neighbor 192.168.56.23 interface ge-1/1/1.23 m +tu 9202 set protocols l2circuit neighbor 192.168.56.23 interface ge-1/1/1.23 p +seudowire-status-tlv set protocols l2circuit neighbor 192.168.56.23 interface ge-1/1/1.23 e +ncapsulation-type ethernet set protocols l2circuit neighbor 192.168.56.23 interface ge-1/1/1.23 v +irtual-circuit-id 571125465 set interfaces ge-1/1/1 unit 24 description "Client - not as important +" set interfaces ge-1/1/1 unit 24 encapsulation vlan-ccc set interfaces ge-1/1/1 unit 24 vlan-tags outer 3200 inner 6 set interfaces ge-1/1/1 unit 24 input-vlan-map pop-pop set interfaces ge-1/1/1 unit 24 output-vlan-map push-push <b>COS: BIZDSLIP_HSIHYP_NOBP_96KBMG</b> This should be on the unit 23. + Instead, the filter for unit 23 is pushed to unit 24, and the filter + for 24 is pushed to 25 etc. set interfaces ge-1/1/1 unit 24 family ccc filter input BIZDSLIP_HSIHY +P_NOBP_96KBMG set class-of-service interfaces ge-1/1/1 unit 24 rewrite-rules ieee-80 +2.1 vlan-tag outer-and-inner
Below is the actual script, please go easy on me. Below is a part of the output I get, notice how unit 23 does not have the COS, and unit 24 has the COS for unit 23.
#!/usr/bin/perl use warnings; use strict; my $interface = $ARGV[1]; my $intcisco = $ARGV[0]; my $intfc = $interface; $interface =~ s/\//\_/g; my $filename = "$intcisco.txt"; my $newfile = "$interface-tmp.txt"; my $line; my $desc = ""; my @splitunit = ""; my $unit = ""; my @splitxc = ""; my $neighbor = ""; my @splitvlan = ""; my $vlanida = ""; my $vlanidb = ""; my $pop; my $daf = 0; open(FH, '<', $filename) or die $!; open(NF, '>', $newfile) or die "$ARGV[1] does not exist.\n"; while (<FH>) { $line = <FH>; print "$line\n"; foreach my $line(<FH>){ my $vcid; my $tag; my @splittag; my $pop; my $xcon; my $cos; my @splitcos; ### Match Service instance, variable for unit ### if ($line =~ /service instance/s){ @splitunit = split(' ',$line); $unit = $splitunit[2]; #print "UNIT: $unit\n"; #debug } ### Match description, format it ### if ($line =~ /description/s){ $desc = $line; $desc =~ s/^\s+//; $desc =~ s/description/description "/g; $desc =~ s/description " /description "/g; $desc =~ s/\r/"/; #print "DESCRIPTION: $desc\n" #debug; } ### Match encapsulation for vlan/s ### if ($line =~ m/encapsulation dot1q/s){ @splitvlan = split(' ', $line); $vlanida = $splitvlan[2]; $vlanidb = $splitvlan[4]; } ### Match service-policy for Filter/CoS if ($line =~ /service-policy input/g){ @splitcos = split(' ', $line); $cos = $splitcos[2]; push(@cosarray,($cos)); #print "COS: $cos\n"; #debug # not perfect, I know, but it works now print NF "set interfaces $intfc unit $unit family ccc filt +er input @cosarray\n"; } ### Match on xconnect to split off neighbor/vcid ### if ($line =~ m/xconnect/s){ $xcon = $line; @splitxc = split(' ', $xcon); $neighbor = $splitxc[1]; $vcid = $splitxc[2]; } ### match on rewrite for tags ### if ($line =~ m/rewrite/s){ my $tag = $line; @splittag = split(' ', $tag); $pop = $splittag[4]; } ### match for bridge ### if ($line =~ /bridge/g) { @splitbridge = split(' ', $line); $bridge = @splitbridge[1]; push(@bridgevlans,($bridge)); print "@bridgevlans\n"; } ### Print to file after converting to Juniper ### if ($unit eq $bridge){ print NF "set interfaces $intfc unit $unit $desc\n"; print NF "set interfaces $intfc unit $unit vlan-id $vlanida\n"; + print NF "set interfaces $intfc unit $unit encapsulation vlan-brid +ge\n"; #print NF "set interfaces $intfc unit $unit input-vlan-map pop\n"; #print NF "set interfaces $intfc unit $unit input-vlan-map push\n\ +n"; #print NF "set interfaces $intfc unit $unit mtu 9202\n"; print NF "set bridge-domains $unit interface $intfc.$unit\n"; print NF " \n"; } elsif ($pop eq "1") { print NF "set interfaces $intfc unit $unit $desc\n"; print NF "set interfaces $intfc unit $unit vlan-id $vlanida\n"; print NF "set interfaces $intfc unit $unit encapsulation vlan-ccc\ +n"; print NF "set interfaces $intfc unit $unit input-vlan-map pop\n"; print NF "set interfaces $intfc unit $unit output-vlan-map push\n\ +n"; #if (!length(@cosarray)) { #print NF "COS: @cosarray\n"; #debug #print NF "set interfaces $intfc unit $unit family ccc filter inpu +t @cosarray\n"; #} } elsif ($pop eq "2"){ print NF "set interfaces $intfc unit $unit $desc\n"; print NF "set interfaces $intfc unit $unit encapsulation vlan-ccc\ +n"; print NF "set interfaces $intfc unit $unit vlan-tags outer $vlanid +a inner $vlanidb\n"; print NF "set interfaces $intfc unit $unit input-vlan-map pop-pop\ +n"; print NF "set interfaces $intfc unit $unit output-vlan-map push-pu +sh\n\n"; #print NF "set class-of-service interfaces $intfc unit $unit class +ifiers ieee-802.1 BMG-COS-Classifer\n"; #print NF "set class-of-service interfaces $intfc unit $unit rewri +te-rules ieee-802.1 BMG-COS-Rewrite\n"; #if (!length(@cosarray)) { #print NF "COS: @cosarray[0]\n"; #debug #print NF "set interfaces $intfc unit $unit family ccc filter inpu +t @cosarray\n"; # } } #print NF "set interfaces $intfc unit $unit family ccc mtu 9202\n" +; if ($neighbor eq ''){} #todo elsif ($vcid eq '') {} #todo else { print NF "set protocols l2circuit neighbor $neighbor interface $in +tfc.$unit $desc\n"; print NF "set protocols l2circuit neighbor $neighbor interface $in +tfc.$unit control-word\n"; print NF "set protocols l2circuit neighbor $neighbor interface $in +tfc.$unit ignore-mtu-mismatch\n"; print NF "set protocols l2circuit neighbor $neighbor interface $in +tfc.$unit mtu 9202\n"; print NF "set protocols l2circuit neighbor $neighbor interface $in +tfc.$unit pseudowire-status-tlv\n"; print NF "set protocols l2circuit neighbor $neighbor interface $in +tfc.$unit encapsulation-type ethernet\n"; print NF "set protocols l2circuit neighbor $neighbor interface $in +tfc.$unit virtual-circuit-id $vcid\n\n"; } if (($pop eq "1") && ($unit !~ /^(51|86|3201|3551|3552|3900|3901|3 +902|3903|3905|3910|3911|3917|3918|3928|3929|3950|3951)$/)){ print NF "set class-of-service interfaces $intfc unit $unit classi +fiers ieee-802.1 CL-OPM-COS\n"; print NF "set class-of-service interfaces $intfc unit $unit rewrit +e-rules ieee-802.1 RR-OPM-COS\n"; print NF "\n"; } if (($pop eq "2") && ($unit !~ /^(51|86|3201|3551|3552|3900|3901|3 +902|3903|3905|3910|3911|3917|3918|3928|3929|3950|3951)$/)){ print NF "set class-of-service interfaces $intfc unit $unit re +write-rules ieee-802.1 vlan-tag outer-and-inner\n"; print NF "\n"; } if ($daf <= 0) { print NF "set protocols oam ethernet link-fault-management interfa +ce $intfc pdu-interval 1000\n"; print NF "set protocols oam ethernet link-fault-management interfa +ce $intfc loopback-tracking\n"; print NF "set protocols oam ethernet link-fault-management interfa +ce $intfc link-discovery active\n"; print NF "set protocols oam ethernet link-fault-management interfa +ce $intfc pdu-threshold 3\n"; print NF "set class-of-service interfaces $intfc scheduler-map POR +TBASED-EGRESS-SCHEDULERMAP-1GE\n"; print NF "set class-of-service interfaces $intfc unit * classifier +s ieee-802.1 COS-Classifier\n"; print NF "set class-of-service interfaces $intfc unit * rewrite-ru +les ieee-802.1 COS-Rewrite\n"; print NF "\n"; $daf++; } } } while(<FH>); close(FH); close(NF);