1# 2# 3# Package d'analyse de fichiers de configuration JunOS 4# 5# Historique 6# 2004/03/22 : pda/jean : d�but de la conception 7# 2004/03/26 : pda/jean : fin de la r�daction 8# 2004/06/08 : pda/jean : changement de format du fichier de sortie 9# 2004/09/24 : pda/jean : nb d'arg variable pour les routes statiques 10# 2005/04/04 : pda : ajout family address arp 11# 2005/06/01 : pda : ajout family inet policer 12# 2006/05/26 : pda/jean : ajout des points de collecte de m�trologie 13# 2006/06/01 : pda/jean : ajout snmp 14# 2007/01/06 : pda : ajout desc interface 15# 2009/12/21 : pda/jean : debut analyse junos switch 16# 2010/09/01 : pda/jean : analyse des directives voip 17# 18 19############################################################################### 20# Fonctions utilitaires 21############################################################################### 22 23proc juniper-init {} { 24 global juniper_masques 25 global juniper_where 26 27 # masques(24) {0xff 0xff 0xff 0x00 0x00 ... 0x00 } 28 # masques(25) {0xff 0xff 0xff 0x80 0x00 ... 0x00 } 29 # masques(64) {0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x00 ... 0x00 } 30 31 for {set i 1} {$i <= 128} {incr i} { 32 set juniper_masques($i) {} 33 set v 0 34 for {set j 0} {$j < 128} {incr j} { 35 if {$j < $i} then { 36 set v [expr (($v << 1) | 1)] 37 } else { 38 set v [expr (($v << 1) | 0)] 39 } 40 if {$j % 8 == 7} then { 41 set juniper_masques($i) [concat $juniper_masques($i) $v] 42 set v 0 43 } 44 } 45 } 46 47 set juniper_where {} 48} 49 50proc juniper-warning {msg} { 51 global juniper_where 52 53 if {[llength $juniper_where] > 0} then { 54 puts -nonewline stderr "$juniper_where: " 55 } 56 puts stderr "$msg" 57} 58 59proc juniper-debug {msg} { 60 juniper-warning $msg 61} 62 63 64proc juniper-read-conf {fd} { 65 set conf "" 66 while {[gets $fd ligne] > -1} { 67 regsub { ## SECRET-DATA$} $ligne {} ligne 68 # remove comment lines 69 regsub {^#.*} $ligne {} ligne 70 71 # join bracketed statement running on consecutive lines 72 if { [regexp {^\s*\S+\s\[[^\]]*$} $ligne]} then { 73 while { ![eof $fd] && ![regexp {\]} $ligne]} { 74 append ligne [gets $fd] 75 } 76 } 77 78 if {! [regexp {/\*.*\*/} $ligne]} then { 79 regsub -all { \[ (.*) \];$} $ligne { { \1 } ;} ligne 80 regsub -all {;$} $ligne { { } } ligne 81 append conf "\n $ligne" 82 } 83 } 84 return $conf 85} 86 87# 88# Convertit une adresse au format Juniper (adr d'i/f + "/" + longueur pr�fixe) 89# en un CIDR de r�seau. 90# 91# Entr�e : 92# - ifadr : adresse au format Juniper 93# Sortie : 94# - valeur de retour : cidr de r�seau ou cha�ne vide en cas d'erreur 95# 96# Historique 97# 2004/03/25 : pda/jean : conception 98# 2004/03/26 : pda/jean : documentation 99# 100 101proc juniper-convert-ifadr-to-cidr {ifadr} { 102 global juniper_masques 103 104 if {! [regexp {^(.*)/(.*)$} $ifadr bidon adr preflen]} then { 105 juniper-warning "invalid interface address ($ifadr)" 106 return "" 107 } 108 109 set v6 [regexp ":" $adr] 110 111 if {$v6} then { 112 # Elimination des cas particuliers des adresses contenant 113 # un "::" situ� au d�but ou � la fin de l'adresse 114 regsub {^::} $adr {0::} adr 115 regsub {::$} $adr {::0} adr 116 117 # Traitement du cas particulier des adresses compatibles 118 # IPv4 : on les transforme en adresses en format IPv6 119 # (i.e. uniquement avec de l'hexa s�par� par des ":") 120 set l [split $adr ":"] 121 122 # cas particulier des adresses compatibles v4 (dernier = a.b.c.d) 123 set ip4 [split [lindex $l end] "."] 124 if {[llength $ip4] == 4} then { 125 set l [lreplace $l end end] 126 set p1 [format "%x" [expr [lindex $ip4 0] * 256 + [lindex $ip4 1]]] 127 128 lappend l $p1 129 set p2 [format "%x" [expr [lindex $ip4 2] * 256 + [lindex $ip4 3]]] 130 lappend l $p2 131 } 132 133 # Traitement du cas des "::" dans l'adresse 134 set n [llength $l] 135 set lg0 [expr 8 - $n] 136 set posvide [lsearch $l {}] 137 if {$posvide >= 0} then { 138 set l [concat [lrange $l 0 [expr $posvide - 1]] \ 139 [lrange {0 0 0 0 0 0 0 0} 0 $lg0] \ 140 [lrange $l [expr $posvide + 1] end] \ 141 ] 142 } 143 # A ce stade, l est une liste de 8 valeurs sur 16 bits en hexa (sans 0x) 144 145 # Transformer chaque �l�ment en octet (en d�cimal) 146 set nl {} 147 foreach e $l { 148 lappend nl [expr ((0x$e >> 8) & 0xff)] 149 lappend nl [expr (0x$e & 0xff)] 150 } 151 152 # A ce stade, nl est une liste de 16 octets en d�cimal 153 set m $juniper_masques($preflen) 154 set na {} 155 for {set i 0} {$i < 16} {incr i} { 156 lappend na [expr [lindex $nl $i] & [lindex $m $i]] 157 } 158 159 # Reconstituer l'adresse IPv6 160 set l {} 161 for {set i 0} {$i < 8} {incr i} { 162 set o1 [lindex $na [expr $i * 2]] 163 set o2 [lindex $na [expr ($i * 2) + 1]] 164 lappend l [format "%x" [expr ($o1 << 8) + $o2]] 165 } 166 set a [join $l ":"] 167 168 # supprimer les 0 finaux 169 regsub -expanded {(:0)+$} $a {::} a 170 171 set na $a 172 } else { 173 # 174 # IPv4 175 # 176 set a [split $adr "."] 177 set m $juniper_masques($preflen) 178 set na {} 179 for {set i 0} {$i < 4} {incr i} { 180 lappend na [expr [lindex $a $i] & [lindex $m $i]] 181 } 182 set na [join $na "."] 183 } 184 185 return "$na/$preflen" 186} 187 188# 189# Teste l'appartenance d'une adresse IP (v4 ou v6) � un r�seau 190# 191# Entr�e : 192# - adr : adresse � tester 193# - cidr : cidr du r�seau 194# Sortie : 195# - valeur de retour : -1 (erreur), 1 (appartenance) ou 0 (pas d'appartenance) 196# 197# Historique 198# 2004/03/25 : pda/jean : conception 199# 2004/03/26 : pda/jean : documentation 200# 201 202proc juniper-match-network {adr cidr} { 203 if {! [regexp {^(.*)/(.*)$} $cidr bidon bidon2 preflen]} then { 204 juniper-warning "invalid network address ($cidr)" 205 set r -1 206 } else { 207 set na [juniper-convert-ifadr-to-cidr "$adr/$preflen"] 208 set r [string equal $na $cidr] 209 } 210 return $r 211} 212 213############################################################################### 214# Analyse du fichier de configuration 215############################################################################### 216 217# 218# Entr�e : 219# - libdir : r�pertoire contenant les greffons d'analyse 220# - model : mod�le de l'�quipement (ex: M20) 221# - fdin : descripteur de fichier en entr�e 222# - fdout : descripteur de fichier pour la g�n�ration 223# - conf : { interfaces ... system ... etc } 224# - eq : <eqname> 225# Remplit : 226# - tab(eq) {<eqname> ... <eqname>} 227# 228# Historique 229# 2004/03/23 : pda/jean : conception 230# 2004/06/08 : pda/jean : ajout de model 231# 2008/07/07 : pda/jean : ajout param�tre libdir 232# 2009/12/21 : pda/jean : debut analyse junos switch 233# 234 235proc juniper-parse {libdir model fdin fdout tab eq} { 236 upvar $tab t 237 238 array set kwtab { 239 version {2 NOP} 240 groups {1 NOP} 241 apply-groups {2 NOP} 242 apply-groups-except {2 NOP} 243 interfaces {1 juniper-parse-interfaces} 244 snmp {1 juniper-parse-snmp} 245 routing-options {1 juniper-parse-routing-options} 246 ethernet-switching-options {1 juniper-parse-ethernet-swopt} 247 vlans {1 juniper-parse-vlans} 248 bridge-domains {1 juniper-parse-bridge-domains} 249 protocols {1 juniper-parse-protocols} 250 * {1 NOP} 251 252 } 253 254 set conf [juniper-read-conf $fdin] 255 256 # le nom de l'�quipement en cours d'analyse 257 lappend t(eq) $eq 258 259 set t(eq!$eq!if!disabled) {} 260 set t(eq!$eq!brcandidate) {} 261 set t(eq!$eq!brdomlist) {} 262 set t(eq!$eq!ranges) {} 263 set t(eq!$eq!voip!if!list) {} 264 265 set error [juniper-parse-list kwtab $conf t "eq!$eq"] 266 267 if {! $error} then { 268 set error [juniper-post-process $model $fdout $eq t] 269 } 270 271 return $error 272} 273 274# 275# Analyse un extrait de conf JunOS 276# 277# Entr�e : 278# - kwtab : tableau des mots-clefs autoris�s dans la fonction, sous la 279# forme kwtab(<kw>) { <nb args> <fct d'analyse> } 280# si <nb-args> n'est pas un entier, il s'agit d'une fonction 281# que l'on appelle, et qui doit retourner le nb d'arguments 282# - tab : tableau contenant les informations r�sultant de l'analyse 283# - conf : extrait de conf 284# - idx : index dans le tableau tab 285# - variable globale debug : affiche tous les mots-clefs en cours d'analyse 286# Sortie : 287# - valeur de retour : 1 si erreur, 0 sinon 288# 289# Historique 290# 2004/03/25 : pda/jean : conception (ouh la la !) 291# 292 293proc juniper-parse-list {kwtab conf tab idx} { 294 global juniper_where 295 global debug 296 upvar $kwtab k 297 upvar $tab t 298 299 set inactive 0 300 set error 0 301 while {[llength $conf] > 0} { 302 set kw [lindex $conf 0] 303 304 if {$debug & 0x01} then { 305 juniper-debug "kw = <$kw>" 306 } 307 308 if {[string equal $kw "inactive:"]} then { 309 set inactive 1 310 set last 0 311 } else { 312 if {[info exists k($kw)]} then { 313 set l $k($kw) 314 } else { 315 set l $k(*) 316 } 317 set last [lindex $l 0] 318 if {! [regexp {^[0-9]+$} $last]} then { 319 set fct $last 320 if {[catch [list $fct $conf t $idx] last]} then { 321 juniper-warning "$idx: error while fetching arg count ($kw)" 322 set last end 323 set inactive 1 324 } 325 } 326 if {! $inactive} then { 327 set fct [lindex $l 1] 328 if {$debug & 0x04} then { 329 juniper-debug "kw = <$kw>, fct = <$fct>" 330 } 331 if {$debug & 0x08} then { 332 juniper-debug "kw = <$kw>, fct = <$fct>, conf 0/1 = <[lindex $conf 0]><[lindex $conf 1]>" 333 } 334 switch $fct { 335 NOP { 336 set error 0 337 } 338 ERROR { 339 juniper-warning "$idx: unrecognized keyword ($kw)" 340 set error 1 341 } 342 default { 343 lappend juniper_where $kw 344 set error [$fct $conf t $idx] 345 set juniper_where [lreplace $juniper_where end end] 346 } 347 } 348 349 if {$error} then { 350 break 351 } 352 } 353 set inactive 0 354 } 355 set conf [lreplace $conf 0 $last] 356 } 357 return $error 358} 359 360 361# 362# Entr�e : 363# - conf = <ifname> { <parm> } <ifname> { <parm> } ... 364# - idx = eq!<eqname> 365# Remplit 366# - tab(eq!<nom eq>!if) {<ifname> ... <ifname>} 367# 368# Historique 369# 2004/03/23 : pda/jean : conception 370# 2005/05/26 : pda : ignorer l'i/f tap 371# 372 373proc juniper-parse-interfaces {conf tab idx} { 374 upvar $tab t 375 376 array set kwtab { 377 fxp0 {1 NOP} 378 fxp1 {1 NOP} 379 lo0 {1 NOP} 380 tap {1 NOP} 381 traceoptions {1 NOP} 382 apply-groups {2 NOP} 383 apply-groups-except {2 NOP} 384 interface-range {2 juniper-parse-if-range} 385 * {1 juniper-parse-if} 386 } 387 388 return [juniper-parse-list kwtab [lindex $conf 1] t "$idx"] 389} 390 391 392# 393# Entr�e : 394# - idx = eq!<eqname> ou eq!<eqname>!ifrange!<nom> 395# - conf = {ge-0/0/0 { description <desc> unit <nb> { ... }} ... } 396# ou {<range> { description <desc> unit <nb> { ... }} ... } si range 397# Remplit : 398# - t(eq!<eqname>!ranges) {<range> ... <range>} 399# - t(eq!<eqname>!if) {<ifname> ... <ifname>} 400# 401# Historique : 402# 2009/12/21 : pda/jean : debut analyse junos switch 403# 2010/03/24 : pda : interfaces d�sactiv�es 404# 405 406proc juniper-parse-if {conf tab idx} { 407 upvar $tab t 408 409 array set kwtab { 410 mtu {2 NOP} 411 description {2 juniper-parse-if-descr} 412 disable {1 juniper-parse-if-disable} 413 native-vlan-id {2 juniper-parse-if-nativevlan} 414 unit {2 juniper-parse-if-unit} 415 gigether-options {1 juniper-parse-if-gigopt} 416 ether-options {1 juniper-parse-if-gigopt} 417 aggregated-ether-options {1 NOP} 418 flexible-vlan-tagging {1 NOP} 419 encapsulation {2 NOP} 420 vlan-tagging {1 juniper-parse-if-vlan-tagging} 421 member-range {4 juniper-parse-member-range} 422 member {2 juniper-parse-member} 423 traceoptions {1 NOP} 424 apply-groups {2 NOP} 425 apply-groups-except {2 NOP} 426 * {2 ERROR} 427 } 428 429 # ifname peut �tre un nom d'interface ou d'intervalle (range) 430 set ifname [lindex $conf 0] 431 set ifparm [lindex $conf 1] 432 433 set t(current!iface) $ifname 434 435 if {[info exists t(in-range)]} then { 436 lappend t($idx!ranges) $ifname 437 set idxin "$idx!range!$ifname" 438 } else { 439 # on diff�re l'ajout de l'interface dans la liste 440 # des interfaces apr�s l'analyse, pour le cas o� 441 # l'interface serait d�sactiv�e. 442 set idxin "$idx!if!$ifname" 443 } 444 445 set error [juniper-parse-list kwtab $ifparm t $idxin] 446 447 # ajout de l'interface dans la liste des interfaces 448 # activ�es ou d�sactiv�es 449 if {! [info exists t(in-range)]} then { 450 if {! [info exists t($idx!if!$ifname!disable)]} then { 451 lappend t($idx!if) $ifname 452 } else { 453 lappend t($idx!if!disabled) $ifname 454 } 455 } 456 457 unset t(current!iface) 458 459 return $error 460} 461 462# 463# Entr�e : 464# - idx = eq!<eqname> 465# Remplit : 466# - <plein de choses> 467# 468# Historique : 469# 2009/12/21 : pda/jean : conception 470# 471 472proc juniper-parse-if-range {conf tab idx} { 473 upvar $tab t 474 475 set t(in-range) "n'importe quoi" 476 set r [juniper-parse-if [lreplace $conf 0 0] t $idx] 477 unset t(in-range) 478 479 return $r 480} 481 482# 483# Entr�e : 484# - idx = eq!<eqname>!range!<range> 485# - conf = { member-range <if1> to <if2> ... } 486# Remplit : 487# - t(eq!<eqname>!range!<range>!members) {{<ifstart> <ifend>} ...} 488# 489# Historique : 490# 2009/12/21 : pda/jean : conception 491# 492 493proc juniper-parse-member-range {conf tab idx} { 494 upvar $tab t 495 496 set if1 [lindex $conf 1] 497 set if2 [lindex $conf 3] 498 lappend t($idx!members) [list $if1 $if2] 499 return 0 500} 501 502# 503# Entr�e : 504# - idx = eq!<eqname>!range!<range> 505# - conf = { member <if> ... } 506# Remplit : 507# - t(eq!<eqname>!range!<range>!members) {{<if> <if>} ...} 508# 509# Historique : 510# 2009/12/21 : pda/jean : conception 511# 512 513proc juniper-parse-member {conf tab idx} { 514 upvar $tab t 515 516 set if [lindex $conf 1] 517 lappend t($idx!members) [list $if $if] 518 return 0 519} 520 521# 522# Entr�e : 523# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 524# Remplit : 525# tab(eq!<eqname>!if!<ifname>!link!name) <linkname> 526# tab(eq!<nom eq>!if!<ifname>!link!stat) <statname> ou vide 527# tab(eq!<nom eq>!if!<ifname>!link!desc) <desc> 528# 529# Historique : 530# 2004/03/23 : pda/jean : conception 531# 2006/05/23 : pda/jean : ajout de stat 532# 2007/01/06 : pda : ajout de desc 533# 534 535proc juniper-parse-if-descr {conf tab idx} { 536 upvar $tab t 537 538 set line [lindex $conf 1] 539 540 if {[parse-desc $line linkname statname descname msg]} then { 541 if {[string equal $linkname ""]} then { 542 juniper-warning "$idx: no link name found ($line)" 543 set error 1 544 } else { 545 set t($idx!link!name) $linkname 546 set t($idx!link!stat) $statname 547 set t($idx!link!desc) $descname 548 set error 0 549 } 550 } else { 551 juniper-warning "$idx: $msg ($line)" 552 set error 1 553 } 554 555 return $error 556} 557 558# 559# Entr�e : 560# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 561# Remplit : 562# tab(eq!<eqname>!if!<ifname>!disable) 1 563# 564# Historique : 565# 2010/03/24 : pda : conception 566# 567 568proc juniper-parse-if-disable {conf tab idx} { 569 upvar $tab t 570 571 set t($idx!disable) yes 572 return 0 573} 574 575# 576# Entr�e : 577# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 578# Remplit : 579# 580 581proc juniper-parse-if-unit {conf tab idx} { 582 upvar $tab t 583 584 array set kwtab { 585 description {2 juniper-parse-unit-descr} 586 vlan-id {2 juniper-parse-vlan-id} 587 family {2 juniper-parse-family} 588 disable {1 juniper-parse-unit-disable} 589 encapsulation {2 juniper-parse-unit-encap} 590 tunnel {1 NOP} 591 apply-groups {2 NOP} 592 apply-groups-except {2 NOP} 593 traceoptions {1 NOP} 594 * {2 ERROR} 595 } 596 597 set unitnb [lindex $conf 1] 598 set unitparm [lindex $conf 2] 599 600 set t(current!unitnb) $unitnb 601 set t($idx!vlan!$unitnb!stat) "" 602 set error [juniper-parse-list kwtab $unitparm t "$idx"] 603 unset t(current!unitnb) 604 605# XXX 606# This code has been deactivated since some interface networks 607# may be emtpy on JunOS routers (eg interface connected to a 608# bridge domain) without being a switch. 609# 610# # 611# # Cas particulier : s'il n'y a aucun network, l'interface 612# # est consid�r�e comme participant � un JunOS switch. 613# # Ce cas est n�cessaire pour g�rer la d�sactivation de 614# # port via l'interface Web. 615# # 616# 617# if {! [info exists t($idx!vlan!$unitnb!networks)]} then { 618# set t($idx!l2switch) on 619# } 620 621 return $error 622} 623 624# 625# Entr�e : 626# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 627# Remplit : 628# tab(eq!<eqname>!if!<ifname>!disable) 1 629# 630# Historique : 631# 2010/03/24 : pda : conception 632# 633 634proc juniper-parse-unit-disable {conf tab idx} { 635 upvar $tab t 636 637 set unit $t(current!unitnb) 638 set t($idx!vlan!$unit!disable) yes 639 640 return 0 641} 642 643 644# 645# Entr�e : 646# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 647# Remplit : 648# nothing 649# 650# Historique : 651# 2010/03/24 : pda : conception 652# 653 654proc juniper-parse-unit-encap {conf tab idx} { 655 upvar $tab t 656 657 # placeholder for future 658 return 0 659} 660 661 662# 663# Entr�e : 664# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 665# - tab(current!unitnb) = <unit number> 666# Remplit : 667# tab(eq!<nom eq>!if!<ifname>!vlan!<vlan-id>!stat) <statname> ou vide 668# 669# Historique : 670# 2006/05/26 : pda/jean : conception 671# 672 673proc juniper-parse-unit-descr {conf tab idx} { 674 upvar $tab t 675 676 set unitnb $t(current!unitnb) 677 set line [lindex $conf 1] 678 679 if {[parse-desc $line linkname statname descname msg]} then { 680 # 681 # 1) linkname peut contenir n'importe quoi (compatibilit� avec 682 # l'ancienne syntaxe), donc on l'ignore 683 # 2) on fait toujours l'approximation : num�ro d'unit� = no de vlan 684 # 3) m�me s'il n'y a pas de d�finition d'un point de collecte 685 # de m�trologie (statname = cha�ne vide), on remplit 686 # le tableau 687 # 688 set t($idx!vlan!$unitnb!stat) $statname 689 set error 0 690 } else { 691 juniper-warning "$idx: $msg ($line)" 692 set error 1 693 } 694 695 return $error 696} 697 698 699# 700# Entr�e : 701# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 702# - tab(current!unitnb) = <unit number> 703# Remplit : 704# tab(eq!<eqname>!if!<ifname>!vlans) {<vlan-id> ...} 705# 706# Historique : 707# 2004/03/23 : pda/jean : conception 708# 709 710proc juniper-parse-vlan-id {conf tab idx} { 711 upvar $tab t 712 713 set unitnb $t(current!unitnb) 714 set parm [lindex $conf 1] 715 716 # approximation : num�ro d'unit� = no de vlan 717 if {$unitnb != $parm} then { 718 juniper-warning "$idx: vlan-id $parm does not match unit $unitnb" 719 return 1 720 } 721 722 lappend t($idx!vlans) $unitnb 723 return 0 724} 725 726# 727# Entr�e : 728# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 729# - tab(current!unitnb) = <unit number> 730# Remplit : 731# tab(eq!<eqname>!if!<ifname>!vlan!<unitnb>!adr) {<adr46> ...} 732# 733# tab(eq!<eqname>!if!<ifname>!vlan!<unitnb>!networks) {<cidr46> ...} 734# tab(eq!<eqname>!if!<ifname>!vlan!<unitnb>!net!<cidr46>) { <adr46> [<poidsvrrp> <virtadr>]} 735# 736 737proc juniper-parse-family {conf tab idx} { 738 upvar $tab t 739 740 set fam [lindex $conf 1] 741 switch $fam { 742 inet - 743 inet6 { 744 array set kwtab { 745 targeted-broadcast {1 NOP} 746 filter {1 NOP} 747 sampling {1 NOP} 748 policer {1 NOP} 749 address {2 juniper-parse-if-address} 750 apply-groups {2 NOP} 751 apply-groups-except {2 NOP} 752 traceoptions {1 NOP} 753 * {2 NOP} 754 } 755 set unitnb $t(current!unitnb) 756 set parm [lindex $conf 2] 757 set error [juniper-parse-list kwtab $parm t "$idx!vlan!$unitnb"] 758 } 759 mpls - 760 iso { 761 set error 0 762 } 763 ethernet-switching { 764 array set kwtab { 765 interface-mode {2 juniper-parse-l2switch-portmode} 766 port-mode {2 juniper-parse-l2switch-portmode} 767 vlan {1 juniper-parse-l2switch-vlan} 768 native-vlan-id {2 juniper-parse-l2switch-nativevlan} 769 traceoptions {1 NOP} 770 * {2 NOP} 771 } 772 set t($idx!l2switch) on 773 set parm [lindex $conf 2] 774 set error [juniper-parse-list kwtab $parm t $idx] 775 } 776 bridge { 777 array set kwtab { 778 filter {1 NOP} 779 interface-mode {2 juniper-parse-fbridge-ifmode} 780 vlan-id {2 juniper-parse-fbridge-vlanid} 781 vlan-id-list {2 juniper-parse-fbridge-vlanidlist} 782 * {2 NOP} 783 } 784 set t($idx!link!allowedvlans) {} 785 set parm [lindex $conf 2] 786 set error [juniper-parse-list kwtab $parm t $idx] 787 # append this interface to the list of candidates to a bridge domain 788 set eq $t(eq) 789 lappend t(eq!$eq!brcandidate) $t(current!iface) 790 } 791 default { 792 juniper-warning "$idx: family '$fam' not supported" 793 set error 1 794 } 795 } 796 return $error 797} 798 799# 800# Entr�e : 801# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 802# 803# Historique 804# 2009/12/22 : pda/jean : conception 805# 806 807proc juniper-parse-l2switch-portmode {conf tab idx} { 808 upvar $tab t 809 810 set error 0 811 set mode [lindex $conf 1] 812 switch $mode { 813 trunk { 814 set t($idx!link!type) "trunk" 815 } 816 access { 817 set t($idx!link!type) "ether" 818 } 819 default { 820 juniper-warning "$idx: port-mode '$mode' not supported" 821 set error 1 822 } 823 } 824 return $error 825} 826 827# 828# Entr�e : 829# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 830# 831# Historique 832# 2009/12/22 : pda/jean : conception 833# 834 835proc juniper-parse-l2switch-vlan {conf tab idx} { 836 upvar $tab t 837 838 array set kwtab { 839 members {3 juniper-parse-l2switch-vlan-members} 840 apply-groups {2 NOP} 841 apply-groups-except {2 NOP} 842 traceoptions {1 NOP} 843 * {1 ERROR} 844 } 845 set error [juniper-parse-list kwtab [lindex $conf 1] t "$idx"] 846 return $error 847} 848 849# 850# Entr�e : 851# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 852# 853# Historique 854# 2009/12/22 : pda/jean : conception 855# 856 857proc juniper-parse-l2switch-vlan-members {conf tab idx} { 858 upvar $tab t 859 860 set vlans [lindex $conf 1] 861 foreach v $vlans { 862 if {[regexp {^(\d+)-(\d+)$} $v bidon min max]} then { 863 set l [list $min $max] 864 } else { 865 set l [list $v $v] 866 } 867 lappend t($idx!link!allowedvlans) $l 868 } 869 return 0 870} 871 872# 873# Entrée : 874# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 875# - tab(current!unitnb) = <unit number> 876# Remplit : 877# tab(eq!<eqname>!if!<ifname>!link!allowedvlans) {<vlan-id|vlan-name> ...} 878# tab(eq!<eqname>!if!<ifname>!native-vlan) <vlan-id|vlan-name> 879# 880# Historique 881# 2009/12/22 : pda/jean : conception 882# 2010/08/31 : pda/jean : gestion effective du vlan natif 883# 884 885proc juniper-parse-l2switch-nativevlan {conf tab idx} { 886 upvar $tab t 887 888 set vlan [lindex $conf 1] 889 lappend t($idx!link!allowedvlans) [list $vlan $vlan] 890 set t($idx!native-vlan) $vlan 891 return 0 892} 893 894# 895# Entr�e : 896# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 897# Remplit : 898# tab(eq!<eqname>!if!<ifname>!native-vlan) <vlan-id|vlan-name> 899# 900# Apparently used only for bridge family 901# 902# Historique 903# 2012/07/03 : pda/jean : conception 904# 905 906proc juniper-parse-if-nativevlan {conf tab idx} { 907 upvar $tab t 908 909 set vlan [lindex $conf 1] 910 set t($idx!native-vlan) $vlan 911 return 0 912} 913 914# 915# Entr�e : 916# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 917# - tab(current!unitnb) = <unit number> 918# Remplit : 919# tab(eq!<eqname>!if!<ifname>!link!type) trunk|ether 920# 921# Historique 922# 2012/07/03 : pda/jean : conception 923# 924 925proc juniper-parse-fbridge-ifmode {conf tab idx} { 926 upvar $tab t 927 928 set error 0 929 set mode [lindex $conf 1] 930 switch $mode { 931 trunk { 932 set t($idx!link!type) "trunk" 933 } 934 access { 935 set t($idx!link!type) "ether" 936 } 937 default { 938 juniper-warning "$idx: interface-mode '$mode' not supported" 939 set error 1 940 } 941 } 942 return $error 943} 944 945# 946# Entr�e : 947# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 948# Remplit : 949# tab(eq!<eqname>!if!<ifname>!link!allowedvlans) {id id} 950# 951# Historique 952# 2012/07/03 : pda/jean : conception 953# 954 955proc juniper-parse-fbridge-vlanid {conf tab idx} { 956 upvar $tab t 957 958 set vlan [lindex $conf 1] 959 lappend t($idx!link!allowedvlans) [list $vlan $vlan] 960 return 0 961} 962 963# 964# Entr�e : 965# - idx = eq!<eqname>!if!<ifname> ou eq!<eqname>!range!<range> 966# Remplit : 967# tab(eq!<eqname>!if!<ifname>!bridge!<vlanid>!mode) trunk (for all $vlanid) 968# tab(eq!<eqname>!if!<ifname>!link!allowed-vlans) {{ min max } ...} 969# (except native-vlan) 970# 971# Historique 972# 2012/07/03 : pda/jean : conception 973# 974 975proc juniper-parse-fbridge-vlanidlist {conf tab idx} { 976 upvar $tab t 977 978 # native vlan (if any) will be checked during post processing 979 # t(eq!<eq>!if!<ifname>!nativevlan) <vland-id> 980 981 set vlans [lindex $conf 1] 982 foreach v $vlans { 983 if {[regexp {^(\d+)-(\d+)$} $v bidon min max]} then { 984 set l [list $min $max] 985 } else { 986 set l [list $v $v] 987 } 988 lappend t($idx!link!allowedvlans) $l 989 } 990 return 0 991} 992 993# 994# Entr�e : 995# - idx = eq!<eqname>!if!<ifname>!unit!<unitnb> 996# Remplit : 997# tab(eq!<eqname>!if!<ifname>!vlan!<unitnb>!networks) {<cidr46> ...} 998# tab(eq!<eqname>!if!<ifname>!vlan!<unitnb>!net!<cidr46>) <adr46> 999# tab(eq!<eqname>!if!<ifname>!vlan!<unitnb>!net!<cidr46>!preflen) <preflen> 1000# 1001 1002proc juniper-parse-if-address {conf tab idx} { 1003 upvar $tab t 1004 1005 array set kwtab { 1006 vrrp-group {2 juniper-parse-vrrp} 1007 vrrp-inet6-group {2 juniper-parse-vrrp} 1008 arp {4 NOP} 1009 destination {2 NOP} 1010 apply-groups {2 NOP} 1011 apply-groups-except {2 NOP} 1012 traceoptions {1 NOP} 1013 * {2 ERROR} 1014 } 1015 1016 set parm [lindex $conf 1] 1017 if {! [regexp {^(.*)/(.*)$} $parm bidon ifadr preflen]} then { 1018 juniper-warning "$idx: invalid address ($parm)" 1019 } 1020 set cidr [juniper-convert-ifadr-to-cidr $parm] 1021 if {[string equal $cidr ""]} then { 1022 set error 1 1023 } else { 1024 lappend t($idx!networks) $cidr 1025 set idx "$idx!net!$cidr" 1026 set t($idx) $ifadr 1027 set t($idx!preflen) $preflen 1028 set error [juniper-parse-list kwtab [lindex $conf 2] t "$idx"] 1029 } 1030 1031 return $error 1032} 1033 1034# 1035# Entr�e : 1036# - idx = eq!<eqname>!if!<ifname>!net!<cidr> 1037# Remplit : 1038# - rien 1039# 1040# Historique : 1041# 2004/03/23 : pda/jean : conception 1042# 1043 1044proc juniper-parse-vrrp {conf tab idx} { 1045 upvar $tab t 1046 1047 array set kwtab { 1048 virtual-address {2 juniper-parse-vrrp-vadr} 1049 priority {2 juniper-parse-vrrp-prio} 1050 virtual-inet6-address {2 juniper-parse-vrrp-vadr} 1051 accept-data {1 NOP} 1052 apply-groups {2 NOP} 1053 apply-groups-except {2 NOP} 1054 traceoptions {1 NOP} 1055 * {2 NOP} 1056 } 1057 1058 return [juniper-parse-list kwtab [lindex $conf 2] t $idx] 1059} 1060 1061# 1062# Entr�e : 1063# - idx = eq!<eqname>!if!<ifname>!net!<cidr> 1064# Remplit : 1065# - tab(eq!<eqname>!if!<ifname>!net!<cidr>!vrrp!virtual) <adrvirt> 1066# 1067# Historique : 1068# 2004/03/25 : pda/jean : conception 1069# 1070 1071proc juniper-parse-vrrp-vadr {conf tab idx} { 1072 upvar $tab t 1073 1074 set t($idx!vrrp!virtual) [lindex $conf 1] 1075 return 0 1076} 1077 1078# 1079# Entr�e : 1080# - idx = eq!<eqname>!if!<ifname>!net!<cidr> 1081# Remplit : 1082# - tab(eq!<eqname>!if!<ifname>!net!<cidr>!vrrp!priority) <prio> 1083# 1084# Historique : 1085# 2004/03/25 : pda/jean : conception 1086# 1087 1088proc juniper-parse-vrrp-prio {conf tab idx} { 1089 upvar $tab t 1090 1091 set t($idx!vrrp!priority) [lindex $conf 1] 1092 return 0 1093} 1094 1095# 1096# Entr�e : 1097# - idx = eq!<eqname>!if!<ifname> 1098# Remplit : 1099# - rien 1100# 1101# Historique : 1102# 2004/03/23 : pda/jean : conception 1103# 2010/06/17 : pda : ajout link-mode 1104# 2010/09/?? : saillard : ajout no-auto-nego + no-flow-control 1105# 1106 1107proc juniper-parse-if-gigopt {conf tab idx} { 1108 upvar $tab t 1109 1110 array set kwtab { 1111 802.3ad {2 juniper-parse-802-3ad} 1112 link-mode {2 NOP} 1113 speed {1 NOP} 1114 auto-negotiation {1 NOP} 1115 no-auto-negotiation {1 NOP} 1116 no-flow-control {1 NOP} 1117 apply-groups {2 NOP} 1118 apply-groups-except {2 NOP} 1119 traceoptions {1 NOP} 1120 * {2 ERROR} 1121 } 1122 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1123} 1124 1125# 1126# Entr�e : 1127# - idx = eq!<eqname>!if!<ifname> 1128# Remplit : 1129# - tab(eq!<eqname>!if!<ifname>!link!type) aggregate 1130# - tab(eq!<eqname>!if!<ifname>!link!ifname) <ifname2> 1131# 1132# Historique : 1133# 2004/03/23 : pda/jean : conception 1134# 1135 1136proc juniper-parse-802-3ad {conf tab idx} { 1137 upvar $tab t 1138 1139 set ifname [lindex $conf 1] 1140 set t($idx!link!type) "aggregate" 1141 set t($idx!link!ifname) $ifname 1142 1143 return 0 1144} 1145 1146# 1147# Entr�e : 1148# - idx = eq!<eqname>!if!<ifname> 1149# Remplit : 1150# - tab(eq!<eqname>!if!<ifname>!link!type) trunk 1151# 1152# Historique : 1153# 2004/03/23 : pda/jean : conception 1154# 1155 1156proc juniper-parse-if-vlan-tagging {conf tab idx} { 1157 upvar $tab t 1158 1159 set t($idx!link!type) "trunk" 1160 return 0 1161} 1162 1163# 1164# Entr�e : 1165# - idx = eq!<eqname> 1166# Remplit : 1167# - rien 1168# 1169# Historique : 1170# 2004/03/25 : pda/jean : conception 1171# 1172 1173proc juniper-parse-routing-options {conf tab idx} { 1174 upvar $tab t 1175 1176 array set kwtab { 1177 rib {2 NOP} 1178 static {1 juniper-parse-static-routes} 1179 autonomous-system {2 NOP} 1180 apply-groups {2 NOP} 1181 apply-groups-except {2 NOP} 1182 traceoptions {1 NOP} 1183 * {1 NOP} 1184 } 1185 1186 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1187} 1188 1189# 1190# Entr�e : 1191# - idx = eq!<eqname> 1192# Remplit : 1193# - rien 1194# 1195# Historique : 1196# 2004/03/25 : pda/jean : conception 1197# 2010/06/21 : pda : ignorer rib-group 1198# 1199 1200proc juniper-parse-static-routes {conf tab idx} { 1201 upvar $tab t 1202 1203 array set kwtab { 1204 route {juniper-parse-count-route juniper-parse-route-entry} 1205 rib-group {2 NOP} 1206 apply-groups {2 NOP} 1207 apply-groups-except {2 NOP} 1208 traceoptions {1 NOP} 1209 * {1 ERROR} 1210 } 1211 1212 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1213} 1214 1215# 1216# Entr�e : 1217# - idx = eq!<eqname> 1218# Remplit : 1219# - tab(eq!<eqname>!static!gw) {<gwadr46> ... } 1220# - tab(eq!<eqname>!static!<gwadr46>) {<cidr46> ... } 1221# 1222# Historique : 1223# 2004/03/25 : pda/jean : conception 1224# 2004/03/26 : pda/jean : inversion des donn�es dans le tableau 1225# 2004/09/21 : pda/jean : nb d'arguments variable pour les entr�es statiques 1226# 1227 1228# cette fonction ne fait que retourner le nombre d'arguments 1229proc juniper-parse-count-route {conf tab idx} { 1230 upvar $tab t 1231 1232 set n 2 1233 if {[string equal [lindex $conf 2] "next-hop"]} then { 1234 set n 4 1235 } 1236 return $n 1237} 1238 1239 1240proc juniper-parse-route-entry {conf tab idx} { 1241 upvar $tab t 1242 1243 set cidr [lindex $conf 1] 1244 1245 if {[string equal [lindex $conf 2] "next-hop"]} then { 1246 set gwadr [lindex $conf 3] 1247 if {[llength $gwadr] > 1} then { 1248 # XXX : il y a plusieurs passerelles pour cette route 1249 # on ne conserve que la premi�re 1250 set gwadr [lindex $gwadr 0] 1251 } 1252 1253 if {! [info exists t($idx!static!$gwadr)]} then { 1254 lappend t($idx!static!gw) $gwadr 1255 } 1256 lappend t($idx!static!$gwadr) $cidr 1257 } 1258 1259 return 0 1260} 1261 1262 1263 1264# 1265# Entr�e : 1266# - idx = eq!<eqname> 1267# Remplit : 1268# - rien 1269# 1270# Historique : 1271# 2006/06/01 : pda/jean : conception 1272# 2008/05/06 : pda : ajout location 1273# 1274 1275proc juniper-parse-snmp {conf tab idx} { 1276 upvar $tab t 1277 1278 array set kwtab { 1279 trap-options {1 NOP} 1280 trap-group {2 NOP} 1281 community {2 juniper-parse-snmp-community} 1282 location {2 juniper-parse-snmp-location} 1283 apply-groups {2 NOP} 1284 apply-groups-except {2 NOP} 1285 traceoptions {1 NOP} 1286 routing-instance-access {1 NOP} 1287 * {1 ERROR} 1288 } 1289 1290 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1291} 1292 1293# 1294# Entr�e : 1295# - idx = eq!<eqname> 1296# Remplit : 1297# - tab(eq!<eqname>!snmp) {<community string> ... } 1298# 1299# Historique : 1300# 2006/06/01 : pda/jean : conception 1301# 1302 1303proc juniper-parse-snmp-community {conf tab idx} { 1304 upvar $tab t 1305 1306 set comm [lindex $conf 1] 1307 lappend t($idx!snmp) $comm 1308 return 0 1309} 1310 1311# 1312# Entr�e : 1313# - idx = eq!<eqname> 1314# Remplit : 1315# - tab(eq!<eqname>!location) {<location> <blablah> } 1316# 1317# Historique : 1318# 2008/05/06 : pda : conception 1319# 1320 1321proc juniper-parse-snmp-location {conf tab idx} { 1322 upvar $tab t 1323 1324 set error 0 1325 set ipmac 0 1326 set portmac 0 1327 set line [lindex $conf 1] 1328 if {[parse-location $line location ipmac portmac blablah msg]} then { 1329 if {! [string equal $location ""]} then { 1330 set t($idx!location) [list $location $blablah] 1331 } 1332 } else { 1333 juniper-warning "$idx: $msg ($line)" 1334 set error 1 1335 } 1336 1337 set t($idx!ipmac) $ipmac 1338 set t($idx!portmac) $portmac 1339 1340 return $error 1341} 1342 1343# 1344# Entr�e : 1345# - idx = eq!<eqname> 1346# Remplit : 1347# - rien 1348# 1349# Historique : 1350# 2010/09/01 : pda/jean : conception 1351# 1352 1353proc juniper-parse-ethernet-swopt {conf tab idx} { 1354 upvar $tab t 1355 1356 array set kwtab { 1357 voip {1 juniper-parse-voip} 1358 analyzer {2 NOP} 1359 apply-groups {2 NOP} 1360 apply-groups-except {2 NOP} 1361 traceoptions {1 NOP} 1362 * {1 NOP} 1363 } 1364 1365 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1366} 1367 1368# 1369# Entr�e : 1370# - idx = eq!<eqname> 1371# Remplit : 1372# - rien 1373# 1374# Historique : 1375# 2010/09/01 : pda/jean : conception 1376# 1377 1378proc juniper-parse-voip {conf tab idx} { 1379 upvar $tab t 1380 1381 array set kwtab { 1382 interface {2 juniper-parse-voip-iface} 1383 apply-groups {2 NOP} 1384 apply-groups-except {2 NOP} 1385 traceoptions {1 NOP} 1386 * {1 NOP} 1387 } 1388 1389 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1390} 1391 1392# 1393# Entr�e : 1394# - idx = eq!<eqname> 1395# Remplit : 1396# - tab(eq!<eqname>!voip!if!list) {ge-0/0/0 ...} 1397# - tab(eq!<eqname>!voip!if!all) <existe ou non> 1398# - tab(eq!<eqname>!voip!if!access-ports) <existe ou non> 1399# 1400# Historique : 1401# 2010/09/01 : pda/jean : conception 1402# 1403 1404proc juniper-parse-voip-iface {conf tab idx} { 1405 upvar $tab t 1406 1407 array set kwtab { 1408 vlan {2 juniper-parse-voip-iface-vlan} 1409 apply-groups {2 NOP} 1410 apply-groups-except {2 NOP} 1411 traceoptions {1 NOP} 1412 * {2 NOP} 1413 } 1414 1415 # 1416 # l'interface peut �tre 1417 # - all 1418 # - access-ports : tous les ports access d�clar�s sur le switch 1419 # - ge-n/n/n.0 : supprimer la "unit" 1420 # 1421 1422 set iface [lindex $conf 1] 1423 1424 switch $iface { 1425 all { set t($idx!voip!if!all) "yes" } 1426 access-ports { set t($idx!voip!if!access-ports) "yes" } 1427 default { 1428 if {[regexp {(.*)\.(\d)$} $iface bidon iface unit]} then { 1429 if {$unit != 0} then { 1430 juniper-warning "$idx: invalid unit '$iface.$unit'" 1431 } 1432 } 1433 lappend t($idx!voip!if!list) $iface 1434 } 1435 } 1436 1437 set idx "$idx!voip!iface!$iface" 1438 1439 return [juniper-parse-list kwtab [lindex $conf 2] t $idx] 1440} 1441 1442# 1443# Entr�e : 1444# - idx = eq!<eqname>!voip!iface!<iface> 1445# Remplit : 1446# - tab(eq!<eqname>!voip!iface!<iface>!vlan) <id|nom|"untagged"> 1447# 1448# Historique : 1449# 2010/09/01 : pda/jean : conception 1450# 1451 1452proc juniper-parse-voip-iface-vlan {conf tab idx} { 1453 upvar $tab t 1454 1455 set vlan [lindex $conf 1] 1456 set t($idx!vlan) $vlan 1457 return 0 1458} 1459 1460# 1461# Entr�e : 1462# - idx = eq!<eqname> 1463# Remplit : 1464# - rien 1465# 1466# Historique : 1467# 2009/12/21 : pda/jean : conception 1468# 1469 1470proc juniper-parse-vlans {conf tab idx} { 1471 upvar $tab t 1472 1473 array set kwtab { 1474 apply-groups {2 NOP} 1475 apply-groups-except {2 NOP} 1476 traceoptions {1 NOP} 1477 * {1 juniper-parse-vlans-entry} 1478 } 1479 1480 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1481} 1482 1483# 1484# Entr�e : 1485# - idx = eq!<eqname> 1486# Remplit : 1487# - tab(eq!<eqname>!vlans!names) {<nom> <nom> ...} 1488# 1489# Historique : 1490# 2010/01/04 : pda/jean : conception 1491# 1492 1493proc juniper-parse-vlans-entry {conf tab idx} { 1494 upvar $tab t 1495 1496 array set kwtab { 1497 description {2 juniper-parse-vlans-entry-desc} 1498 vlan-id {2 juniper-parse-vlans-entry-vlan-id} 1499 l3-interface {2 juniper-parse-vlans-entry-l3-interface} 1500 interface {1 juniper-parse-vlans-entry-interface} 1501 } 1502 1503 set nom [lindex $conf 0] 1504 set t(current!vlan-name) $nom 1505 1506 lappend t($idx!vlans!names) $nom 1507 1508 set r [juniper-parse-list kwtab [lindex $conf 1] t "$idx!vlans!name!$nom"] 1509 unset t(current!vlan-name) 1510 1511 return $r 1512} 1513 1514# 1515# Entr�e : 1516# - idx = eq!<eqname> 1517# Remplit : 1518# - tab(eq!<eqname>!vlans!names) {<nom> <nom> ...} 1519# 1520# Historique : 1521# 2010/03/24 : pda : conception 1522# 1523 1524proc juniper-parse-vlans-entry-desc {conf tab idx} { 1525 upvar $tab t 1526 1527 # NOP pour l'instant 1528 1529 return 0 1530} 1531 1532# 1533# Entr�e : 1534# - idx = eq!<eqname>!vlans!name!<nom> 1535# Remplit : 1536# - tab(eq!<eqname>!vlans!name!<nom>!id) <vlanid> 1537# 1538# Historique : 1539# 2010/01/04 : pda/jean : conception 1540# 1541 1542proc juniper-parse-vlans-entry-vlan-id {conf tab idx} { 1543 upvar $tab t 1544 1545 set vlanid [lindex $conf 1] 1546 set t($idx!id) $vlanid 1547 return 0 1548} 1549 1550# 1551# Entr�e : 1552# - idx = eq!<eqname>!vlans!name!<nom> 1553# Remplit : 1554# - tab(eq!<eqname>!if!....!link!allowedvlans) {... {vlanid vlanid} ...} 1555# 1556# Historique : 1557# 2016/03/04 : boggia/jean : conception 1558# 1559 1560proc juniper-parse-vlans-entry-interface {conf tab idx} { 1561 upvar $tab t 1562 1563 # 1564 # get equipment name, current vlanid and interface bloc 1565 # 1566 1567 set eq [lindex [split $idx !] 1] 1568 set vlanid $t($idx!id) 1569 set ifaces [lindex $conf 1] 1570 1571 # 1572 # interface bloc is a list { ge-0/0/1.0 {} xe-0/2/1.0 {} ... } 1573 # 1574 1575 foreach {iface dummy} $ifaces { 1576 # 1577 # remove unit number 1578 # 1579 regexp {(.+)\.0$} $iface dummy iface 1580 set ifidx "eq!$eq!if!$iface!link!allowedvlans" 1581 lappend t($ifidx) [list $vlanid $vlanid] 1582 } 1583 1584 return 0 1585} 1586 1587 1588# 1589# Entr�e : 1590# - idx = eq!<eqname>!vlans!name!<nom> 1591# Remplit : 1592# - tab(eq!<eqname>!vlans!name!<nom>!l3) {<iface> <unit>} 1593# 1594# Historique : 1595# 2010/01/04 : pda/jean : conception 1596# 1597 1598proc juniper-parse-vlans-entry-l3-interface {conf tab idx} { 1599 upvar $tab t 1600 1601 set ifaceunit [lindex $conf 1] 1602 if {! [regexp {^(vlan|irb)\.([0-9]+)} $ifaceunit bidon iface unit]} then { 1603 juniper-warning "$idx: invalid l3-interface '$ifaceunit'" 1604 } else { 1605 set t($idx!l3) [list $iface $unit] 1606 } 1607 return 0 1608} 1609 1610# 1611# Entr�e : 1612# - idx = eq!<eqname> 1613# Remplit : 1614# - rien 1615# 1616# Historique : 1617# 2012/07/03 : pda/jean : conception 1618# 1619 1620proc juniper-parse-bridge-domains {conf tab idx} { 1621 upvar $tab t 1622 1623 array set kwtab { 1624 * {1 juniper-parse-bridge-domains-entry} 1625 } 1626 1627 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1628} 1629 1630 1631# 1632# Entr�e : 1633# - idx = eq!<eqname> 1634# Remplit : 1635# - t(eq!<eq>!brdomlist) { <bdname> ...} 1636# 1637# Historique : 1638# 2012/07/03 : pda/jean : conception 1639# 1640 1641proc juniper-parse-bridge-domains-entry {conf tab idx} { 1642 upvar $tab t 1643 1644 array set kwtab { 1645 description {2 NOP} 1646 domain-type {2 NOP} 1647 bridge-options {1 NOP} 1648 vlan-id {2 juniper-parse-bridged-vlanid} 1649 vlan-id-list {2 juniper-parse-bridged-vlanidlist} 1650 interface {2 juniper-parse-bridged-if} 1651 routing-interface {2 juniper-parse-bridged-routif} 1652 * {2 ERROR} 1653 } 1654 1655 set bdname [lindex $conf 0] 1656 set bdparm [lindex $conf 1] 1657 set t(current!brdom) $bdname 1658 set t($idx!brdom!$bdname!iflist) {} 1659 set error [juniper-parse-list kwtab $bdparm t "$idx!brdom!$bdname"] 1660 if {! $error} then { 1661 lappend t($idx!brdomlist) $bdname 1662 } 1663 unset t(current!brdom) 1664 1665 return $error 1666} 1667 1668# 1669# Entr�e : 1670# - idx = eq!<eqname>!brdom!<bdname> 1671# Remplit : 1672# - t(eq!<eqname>!brdom!<bdname>!vlans) {{<vlanid> <vlanid>}} 1673# 1674# Historique : 1675# 2012/07/10 : pda/jean : conception 1676# 1677 1678proc juniper-parse-bridged-vlanid {conf tab idx} { 1679 upvar $tab t 1680 1681 set vlanid [lindex $conf 1] 1682 set t($idx!vlans) [list [list $vlanid $vlanid]] 1683 return 0 1684} 1685 1686# 1687# Entr�e : 1688# - idx = eq!<eqname>!brdom!<bdname> 1689# Remplit : 1690# - t(eq!<eqname>!brdom!<bdname>!vlans) {{<vlanid> <vlanid>} ... } 1691# 1692# Historique : 1693# 2012/07/10 : pda/jean : conception 1694# 1695 1696proc juniper-parse-bridged-vlanidlist {conf tab idx} { 1697 upvar $tab t 1698 1699 set t($idx!vlans) {} 1700 set vlans [lindex $conf 1] 1701 foreach v $vlans { 1702 if {[regexp {^(\d+)-(\d+)$} $v bidon min max]} then { 1703 set l [list $min $max] 1704 } else { 1705 set l [list $v $v] 1706 } 1707 lappend t($idx!vlans) $l 1708 } 1709 return 0 1710} 1711 1712# 1713# Entr�e : 1714# - idx = eq!<eqname>!brdom!<bdname> 1715# Remplit : 1716# - t(eq!<eqname>!brdom!<bdname>!vlans) {{<vlanid> <vlanid>} ... } 1717# 1718# Historique : 1719# 2012/07/10 : pda/jean : conception 1720# 1721 1722proc juniper-parse-bridged-if {conf tab idx} { 1723 upvar $tab t 1724 1725 set eq $t(eq) 1726 set brdom $t(current!brdom) 1727 1728 set ifname_unit [lindex $conf 1] 1729 if {[regexp {^(.*)\.(\d+)$} $ifname_unit bidon iface unit]} then { 1730 set error 0 1731 if {[info exists t(eq!$eq!if!$iface!vlans)] 1732 && [lsearch -exact $t(eq!$eq!if!$iface!vlans) $unit] != -1} then { 1733 # 1734 # Mark this interface as participating to this bridge-domain 1735 # 1736 lappend t($idx!iflist) [list $iface $unit] 1737 lappend t(eq!$eq!if!$iface!brdom) $brdom 1738 1739 } else { 1740 juniper-warning "$eq: interface '$ifname_unit' not found in bridge domain" 1741 set error 1 1742 } 1743 } else { 1744 juniper-warning "$eq: invalid interface '$ifname_unit' in bridge domain" 1745 set error 1 1746 } 1747 1748 return $error 1749} 1750 1751# 1752# Entr�e : 1753# - idx = eq!<eqname>!brdom!<bdname> 1754# Remplit : 1755# ??????????????????????????????????????? 1756# - t(eq!<eqname>!brdom!<bdname>!vlans) {{<vlanid> <vlanid>} ... } 1757# 1758# Historique : 1759# 2012/07/10 : pda/jean : conception 1760# 1761 1762proc juniper-parse-bridged-routif {conf tab idx} { 1763 upvar $tab t 1764 1765 return 0 1766} 1767 1768# 1769# Entr�e : 1770# - idx = eq!<eqname> 1771# Remplit : 1772# - rien 1773# 1774# Historique : 1775# 2015/09/28 : jean : conception 1776# 1777 1778proc juniper-parse-protocols {conf tab idx} { 1779 upvar $tab t 1780 1781 array set kwtab { 1782 mvrp {1 juniper-parse-protocols-mvrp} 1783 * {1 NOP} 1784 } 1785 1786 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1787} 1788 1789# 1790# Entr�e : 1791# - idx = eq!<eqname> 1792# Remplit : 1793# - rien 1794# 1795# Historique : 1796# 2015/09/28 : jean : conception 1797# 1798 1799proc juniper-parse-protocols-mvrp {conf tab idx} { 1800 upvar $tab t 1801 1802 array set kwtab { 1803 interface {2 juniper-parse-mvrp-iface} 1804 apply-groups {2 NOP} 1805 apply-groups-except {2 NOP} 1806 traceoptions {1 NOP} 1807 * {1 NOP} 1808 } 1809 1810 return [juniper-parse-list kwtab [lindex $conf 1] t $idx] 1811} 1812 1813 1814# 1815# Entr�e : 1816# - idx = eq!<eqname> 1817# Remplit : 1818# - tab(eq!<eqname>!if!<ifname>!link!allowvlans) ... {1 4094} 1819# 1820# Historique : 1821# 2015/09/28 : jean : adapted from parse-voip-iface 1822# 1823 1824proc juniper-parse-mvrp-iface {conf tab idx} { 1825 upvar $tab t 1826 1827 # 1828 # interface : 1829 # - ge-n/n/n.0 : remove unit number 1830 # - all : unsupported yet 1831 # 1832 1833 set iface [lindex $conf 1] 1834 1835 set error 0 1836 switch $iface { 1837 all { 1838 juniper-warning "$eq: mvrp interface all not supported" 1839 set error 1 1840 } 1841 default { 1842 if {[regexp {(.*)\.(\d)$} $iface bidon iface unit]} then { 1843 if {$unit != 0} then { 1844 juniper-warning "$idx: invalid unit '$iface.$unit'" 1845 } 1846 } 1847 set idx "$idx!if!$iface" 1848 lappend t($idx!link!allowedvlans) [list 1 4094] 1849 } 1850 } 1851 1852 return $error 1853} 1854 1855############################################################################### 1856# Traitement apr�s analyse 1857############################################################################### 1858 1859# 1860# Traite le tableau r�sultant de l'analyse pour permettre d'acc�der 1861# plus facilement aux r�seaux (de niveau 3) et aux liens (de niveau 2) 1862# g�r�s par cet �quipement 1863# 1864# Entr�e : 1865# - model : mod�le de l'�quipement 1866# - fdout : descripteur de fichier pour la g�n�ration 1867# - eq : nom de l'�quipement 1868# - tab : tableau rempli au cours de l'analyse 1869# Sortie : 1870# - valeur de retour : 0 si pas d'erreur, 1 si erreur 1871# - tab : tableau modifi� 1872# 1873# Historique 1874# 2004/03/26 : pda/jean : conception 1875# 2004/06/08 : pda/jean : ajout du mod�le 1876# 2004/06/08 : pda/jean : changement de format du fichier de sortie 1877# 2006/06/01 : pda/jean : ajout snmp 1878# 2006/08/21 : pda/pegon : liens X+X+X+...+X deviennent X 1879# 2007/01/06 : pda : ajout desc interface 1880# 2007/07/13 : pda : ajout sortie tableau si debug 1881# 2010/03/25 : pda : ajout "members all" 1882# 2010/09/01 : pda/jean : ajout voip 1883# 1884 1885proc juniper-post-process {model fdout eq tab} { 1886 global debug 1887 upvar $tab t 1888 1889 if {$debug & 0x02} then { 1890 debug-array t 1891 } 1892 1893 if {[info exists t(eq!$eq!snmp)]} then { 1894 # XXX : on ne prend que la premi�re communaut� trouv�e 1895 set c [lindex $t(eq!$eq!snmp) 0] 1896 } else { 1897 set c "-" 1898 } 1899 if {[info exists t(eq!$eq!location)]} then { 1900 # XXX : on ne prend que la partie reconnue <...> 1901 set l [lindex $t(eq!$eq!location) 0] 1902 } else { 1903 set l "-" 1904 } 1905 if {[info exists t(eq!$eq!ipmac)]} then { 1906 set ipmac $t(eq!$eq!ipmac) 1907 } else { 1908 set ipmac 0 1909 } 1910 if {[info exists t(eq!$eq!portmac)]} then { 1911 set portmac $t(eq!$eq!portmac) 1912 } else { 1913 set portmac 0 1914 } 1915 puts $fdout "eq $eq type juniper model $model snmp $c location $l ipmac $ipmac portmac $portmac manual 0" 1916 1917 # 1918 # Parcourir la liste des interfaces, dont on compl�tera les 1919 # caract�ristiques selon les d�finitions des intervalles d�finis. 1920 # (JunOS switch) 1921 # 1922 1923 foreach if $t(eq!$eq!if) { 1924 set ranges [juniper-find-ranges t $eq $if] 1925 foreach r $ranges { 1926 juniper-completer-iface t $eq $if $r 1927 } 1928 1929 # 1930 # Les interfaces non typ�es sont "ether" par d�faut 1931 # 1932 1933 set idx "eq!$eq!if!$if" 1934 if {! [info exists t($idx!link!type)]} then { 1935 set t($idx!link!type) "ether" 1936 } 1937 1938 # 1939 # V�rifier que chaque interface a une description 1940 # 1941 1942 if {! [info exists t($idx!link!name)]} then { 1943 juniper-warning "$eq/$if: link name in 'description' not found" 1944 set error 1 1945 } 1946 } 1947 1948 # 1949 # Convertir les noms de vlans en id num�riques, phase 0 1950 # D�terminer les intervalles dans la liste des vlan-id trouv�s 1951 # sur cet �quipement 1952 # 1953 1954 if {[info exists t(eq!$eq!vlans!names)]} then { 1955 # d�terminer les vlan-id 1956 set lid {} 1957 foreach id [array names t -glob "*!vlans!name!*!id"] { 1958 lappend lid $t($id) 1959 } 1960 set lid [lsort -integer $lid] 1961 1962 # d�terminer les intervalles 1963 set ranges {} 1964 set min [lindex $lid 0] 1965 set max [lindex $lid 0] 1966 foreach id [lreplace $lid 0 0] { 1967 if {$max != $id - 1} then { 1968 lappend ranges [list $min $max] 1969 set min $id 1970 } 1971 set max $id 1972 } 1973 lappend ranges [list $min $max] 1974 set t(eq!$eq!vlans!ranges) $ranges 1975 } 1976 1977 # 1978 # Convertir les noms de vlans en id num�riques, phase 1 1979 # Remplacer "all" (members all) par la liste des vlans 1980 # connus dans la section "vlans" 1981 # (JunOS switch) 1982 # 1983 1984 if {[info exists t(eq!$eq!vlans!names)] && [info exists t(eq!$eq!vlans!ranges)]} then { 1985 # Parcourir toutes les "!allowedvlans" positionn�s 1986 # � "all all" 1987 foreach i [array names t -glob "*!link!allowedvlans"] { 1988 set l {} 1989 foreach c $t($i) { 1990 set v1 [lindex $c 0] 1991 set v2 [lindex $c 1] 1992 if {[string equal $v1 "all"] && [string equal $v2 "all"]} then { 1993 set l [concat $l $t(eq!$eq!vlans!ranges)] 1994 } else { 1995 lappend l [list $v1 $v2] 1996 } 1997 } 1998 set t($i) $l 1999 } 2000 } 2001 2002 # 2003 # Convertir les noms de vlans en id num�riques, phase 2 2004 # Mettre les interfaces vlan.<unit> dans le bon vlan-id 2005 # (JunOS switch) 2006 # 2007 2008 if {[info exists t(eq!$eq!vlans!names)]} then { 2009 foreach name $t(eq!$eq!vlans!names) { 2010 # 2011 # Conversion des noms de vlans : parcourir toutes les 2012 # "!allowedvlans" pour convertir les noms 2013 # 2014 foreach i [array names t -glob "*!link!allowedvlans"] { 2015 set l {} 2016 foreach c $t($i) { 2017 set v1 [lindex $c 0] 2018 if {[info exists t(eq!$eq!vlans!name!$v1!id)]} then { 2019 set v1 $t(eq!$eq!vlans!name!$v1!id) 2020 } 2021 set v2 [lindex $c 1] 2022 if {[info exists t(eq!$eq!vlans!name!$v2!id)]} then { 2023 set v2 $t(eq!$eq!vlans!name!$v2!id) 2024 } 2025 lappend l [list $v1 $v2] 2026 } 2027 set t($i) $l 2028 } 2029 2030 # 2031 # Inscription des interfaces vlan.<unit> et irb.<unit> dans le bon 2032 # vlan-id 2033 # 2034 foreach iftype {vlan irb} { 2035 array unset nt 2036 if {[info exists t(eq!$eq!vlans!name!$name!l3)]} then { 2037 set ifaceunit $t(eq!$eq!vlans!name!$name!l3) 2038 set iface [lindex $ifaceunit 0] 2039 set unit [lindex $ifaceunit 1] 2040 if [string eq $iface $iftype] { 2041 set vlanid $t(eq!$eq!vlans!name!$name!id) 2042 lappend nt(eq!$eq!if!$iftype!vlans) $vlanid 2043 foreach i [array names t -glob "eq!$eq!if!$iface!vlan!$unit!*"] { 2044 regexp "!$iface!vlan!$unit!(.*)" $i bidon reste 2045 set nt(eq!$eq!if!$iface!vlan!$vlanid!$reste) $t($i) 2046 unset t($i) 2047 } 2048 foreach i [array names nt] { 2049 if {![info exists t($i)]} then { 2050 set t($i) {} 2051 } 2052 foreach e $nt($i) { 2053 lappend t($i) $e 2054 } 2055 } 2056 } 2057 } 2058 } 2059 } 2060 } 2061 2062 # 2063 # Convertir les noms de vlans en id num�riques, phase 3 2064 # Convertir les native-vlan 2065 # (JunOS switch) 2066 # 2067 2068 if {[info exists t(eq!$eq!vlans!names)]} then { 2069 foreach name $t(eq!$eq!vlans!names) { 2070 # 2071 # Conversion des noms de vlans : parcourir toutes les 2072 # "!allowedvlans" pour convertir les noms 2073 # 2074 set vlanid $t(eq!$eq!vlans!name!$name!id) 2075 foreach i [array names t -glob "*!native-vlan"] { 2076 if {[string equal $name $t($i)]} then { 2077 set t($i) $vlanid 2078 } 2079 } 2080 } 2081 } 2082 2083 # 2084 # Convertir les noms de vlans en id num�riques, phase 4 2085 # Convertir les vlans sp�cifi�s dans les blocs "voip" 2086 # (JunOS switch) 2087 # 2088 2089 foreach iface [concat $t(eq!$eq!voip!if!list) {access-ports all}]] { 2090 if {[info exists t(eq!$eq!voip!iface!$iface!vlan)]} then { 2091 set vlan $t(eq!$eq!voip!iface!$iface!vlan) 2092 if {[info exists t(eq!$eq!vlans!name!$vlan!id)]} then { 2093 set vlanid $t(eq!$eq!vlans!name!$vlan!id) 2094 set t(eq!$eq!voip!iface!$iface!vlan) $vlanid 2095 } 2096 } 2097 } 2098 2099 # 2100 # Traiter les sp�cifications "voip" sur les interfaces, phase 1 2101 # G�n�raliser les directives "access-ports" et "all" aux 2102 # interfaces concern�es. 2103 # 2104 2105 # pr�-traitement des access-ports 2106 if {[info exists t(eq!$eq!voip!if!access-ports)]} then { 2107 set vlanid $t(eq!$eq!voip!iface!access-ports!vlan) 2108 foreach iface $t(eq!$eq!if) { 2109 if {! [string equal $iface "vlan"]} then { 2110 set linktype $t(eq!$eq!if!$iface!link!type) 2111 if {[string equal $linktype "ether"]} then { 2112 if {! [info exists t(eq!$eq!voip!iface!$iface!vlan)]} then { 2113 set t(eq!$eq!voip!iface!$iface!vlan) $vlanid 2114 lappend t(eq!$eq!voip!if!list) $iface 2115 } 2116 2117 } 2118 } 2119 } 2120 } 2121 2122 # pr�-traitement des all 2123 if {[info exists t(eq!$eq!voip!if!all)]} then { 2124 set vlanid $t(eq!$eq!voip!iface!all!vlan) 2125 foreach iface $t(eq!$eq!if) { 2126 if {! [string equal $iface "vlan"]} then { 2127 set linktype $t(eq!$eq!if!$iface!link!type) 2128 if {! [info exists t(eq!$eq!voip!iface!$iface!vlan)]} then { 2129 set t(eq!$eq!voip!iface!$iface!vlan) $vlanid 2130 lappend t(eq!$eq!voip!if!list) $iface 2131 } 2132 } 2133 } 2134 } 2135 2136 # Propagate native-vlan information into allowed vlans 2137 foreach iface $t(eq!$eq!if) { 2138 if {[info exists t(eq!$eq!if!$iface!native-vlan)] && 2139 [info exists t(eq!$eq!if!$iface!link!allowedvlans)]} then { 2140 set nvlan $t(eq!$eq!if!$iface!native-vlan) 2141 set allow {} 2142 foreach cv $t(eq!$eq!if!$iface!link!allowedvlans) { 2143 lassign $cv min max 2144 if {$nvlan == $min} then { 2145 incr min 2146 if {$min < $max} then { 2147 lappend allow [list $min $max] 2148 } 2149 } elseif {$nvlan == $max} then { 2150 incr max -1 2151 if {$min < $max} then { 2152 lappend allow [list $min $max] 2153 } 2154 } elseif {$nvlan > $min && $nvlan < $max} then { 2155 set nmax [expr $nvlan-1] 2156 if {$min < $nmax} then { 2157 lappend allow [list $min $nmax] 2158 } 2159 set nmin [expr $nvlan+1] 2160 if {$nmin < $max} then { 2161 lappend allow [list $nmin $max] 2162 } 2163 } else { 2164 lappend allow [list $min $max] 2165 } 2166 } 2167 set t(eq!$eq!if!$iface!link!allowedvlans) $allow 2168 } 2169 } 2170 2171 # Traiter les sp�cifications "voip" sur les interfaces, phase 2 2172 # 2173 # Ce qui est � faire d�pend du statut actuel de l'interface 2174 # type directive action 2175 # actuel voip->vlan 2176 # ------- ------------ ---------------------------------- 2177 # ether <id> passer en trunk pour <id> + native pour 2178 # le vlan d�clar� en ether 2179 # ether untagged aucun changement 2180 # trunk <id> aucun changement de type + v�rifier que 2181 # <id> figure dans les "allowedvlans" 2182 # trunk untagged erreur 2183 # 2184 2185 foreach iface $t(eq!$eq!voip!if!list) { 2186 set disabled [info exists t(eq!$eq!if!$iface!disable)] 2187 if {! $disabled} then { 2188 set id $t(eq!$eq!voip!iface!$iface!vlan) 2189 set new "id" 2190 if {[string equal $id "untagged"]} then { 2191 set new "untagged" 2192 } 2193 2194 set linktype $t(eq!$eq!if!$iface!link!type) 2195 2196 switch "$linktype-$new" { 2197 ether-id { 2198 set t(eq!$eq!if!$iface!link!type) trunk 2199 2200 if {[info exist t(eq!$eq!if!$iface!link!allowedvlans)]} then { 2201 set a [lindex $t(eq!$eq!if!$iface!link!allowedvlans) 0] 2202 set oldvlan [lindex $a 0] 2203 set t(eq!$eq!if!$iface!native-vlan) $oldvlan 2204 } 2205 lappend t(eq!$eq!if!$iface!link!allowedvlans) [list $id $id] 2206 } 2207 ether-untagged { 2208 # aucun changement 2209 } 2210 trunk-id { 2211 set found 0 2212 foreach c $t(eq!$eq!if!$iface!link!allowedvlans) { 2213 set v1 [lindex $c 0] 2214 set v2 [lindex $c 1] 2215 if {$id >= $v1 && $id <= $v2} then { 2216 set found 1 2217 break 2218 } 2219 } 2220 if {! $found} then { 2221 lappend t(eq!$eq!if!$iface!link!allowedvlans) [list $id $id] 2222 } 2223 } 2224 trunk-untagged { 2225 juniper-warning "Inconsistent voip specification on '$eq/$iface'" 2226 } 2227 default { 2228 juniper-warning "Internal error for voip on '$eq/$iface'" 2229 } 2230 } 2231 } 2232 } 2233 2234 # 2235 # Chercher tous les liens. Pour cela, parcourir la liste 2236 # des interfaces 2237 # 2238 catch {unset agtab} 2239 2240 # premi�re boucle pour constituer les noms des liens agr�g�s 2241 foreach iface $t(eq!$eq!if) { 2242 set linkname $t(eq!$eq!if!$iface!link!name) 2243 set linktype $t(eq!$eq!if!$iface!link!type) 2244 if {[string equal $linktype "aggregate"]} then { 2245 set parentif $t(eq!$eq!if!$iface!link!ifname) 2246 lappend agtab($parentif) $linkname 2247 } 2248 } 2249 2250 # 2251 # On JunOS router, interface may candidate to some declared 2252 # bridge domains or may be explicitely named by a bridge domain 2253 # declaration. 2254 # Explore all bridge domains to generate bridge (or bridge pattern) 2255 # nodes, and mark selected interfaces. 2256 # 2257 2258 foreach brdom $t(eq!$eq!brdomlist) { 2259 # 2260 # If this is a bridge domain with only one specified 2261 # vlan, instantiate a bridge node specific for this vlan 2262 # and not a bridge pattern (brpat) to instanciate. 2263 # 2264 2265 set brnode 0 2266 set vlans $t(eq!$eq!brdom!$brdom!vlans) 2267 if {[llength $vlans] <= 1} then { 2268 lassign [lindex $vlans 0] min max 2269 if {$min eq $max} then { 2270 set brnode [newnode] 2271 puts $fdout "node $brnode type bridge eq $eq" 2272 set t(eq!$eq!brdom!$brdom!brnode) $brnode 2273 2274 # 2275 # Mark (with the bridge node) all interfaces explicitely 2276 # named in this bridge domain 2277 # 2278 2279 foreach iface_unit $t(eq!$eq!brdom!$brdom!iflist) { 2280 lassign $iface_unit iface unit 2281 lappend t(eq!$eq!if!$iface!bridges) [list $brnode $unit $unit] 2282 } 2283 } 2284 } 2285 2286 # 2287 # Gathers all interfaces which candidate to this bridge 2288 # 2289 2290 foreach cv $vlans { 2291 # vlans allowed on the bridge 2292 lassign $cv brmin brmax 2293 2294 foreach iface $t(eq!$eq!brcandidate) { 2295 set allow {} 2296 foreach ca $t(eq!$eq!if!$iface!link!allowedvlans) { 2297 lassign $ca amin amax 2298 2299 # 2300 # Check intersection of intervals by computing 2301 # the resulting interval. 2302 # 2303 # nmin = max (amin, brmin) 2304 # nmax = min (amax, brmax) 2305 # 2306 set nmin [expr $amin < $brmin ? $brmin : $amin] 2307 set nmax [expr $amax > $brmax ? $brmax : $amax] 2308 if {$nmin <= $nmax} then { 2309 lappend t(eq!$eq!if!$iface!bridges) [list $brnode $nmin $nmax] 2310 } 2311 } 2312 } 2313 } 2314 } 2315 2316 # XXX : pour l'instant, il n'y a qu'une seule instance de routage 2317 # dans *nos* Juniper... 2318 # En fait, il y en a deux : la "default" pour v4 et la "default" pour v6 2319 2320 set nodeR4 "" 2321 set nodeR6 "" 2322 2323 # 2324 # Boucle principale : retrouver les liens de niveau 2 2325 # (sans le d�tail des constituants d'un lien agr�g�) 2326 # Parcourir la liste des interfaces. 2327 # 2328 2329 # par d�faut, pas de brpat 2330 set nodebrpat 0 2331 2332 if {$debug & 0x02} then { 2333 debug-array t 2334 } 2335 2336 foreach iface $t(eq!$eq!if) { 2337 if {[info exists agtab($iface)]} then { 2338 # 2339 # Si tous les liens sont "X", constituer un lien "X" 2340 # au lieu d'un lien "X+X+X+..+X" 2341 # 2342 set tousX 1 2343 foreach l $agtab($iface) { 2344 if {! [string equal $l "X"]} then { 2345 set tousX 0 2346 break 2347 } 2348 } 2349 if {$tousX} then { 2350 set linkname "X" 2351 } else { 2352 set linkname [join [lsort $agtab($iface)] "+"] 2353 } 2354 } else { 2355 set linkname $t(eq!$eq!if!$iface!link!name) 2356 } 2357 set statname $t(eq!$eq!if!$iface!link!stat) 2358 if {[string equal $statname ""]} then { 2359 set statname "-" 2360 } 2361 set desc $t(eq!$eq!if!$iface!link!desc) 2362 if {[string equal $desc ""]} then { 2363 set desc "-" 2364 } 2365 set linktype $t(eq!$eq!if!$iface!link!type) 2366 2367 if {[string equal $iface "vlan"] || [string equal $iface "irb"]} then { 2368 # 2369 # Traitement sp�cial pour les interface "vlan" et "irb" qu'on 2370 # trouve sur les JunOS switch 2371 # Cas r�duit d'une interface physique sur JunOS routeur 2372 # 2373 2374 if {[info exists t(eq!$eq!if!$iface!vlans)]} then { 2375 foreach v $t(eq!$eq!if!$iface!vlans) { 2376 set nodeL2 [newnode] 2377 set t(eq!$eq!if!$iface!vlan!$v!node) $nodeL2 2378 if {![info exists t(eq!$eq!if!$iface!vlan!$v!stat)]} { 2379 juniper-warning "Warning: '$iface.$v' l3-interface not defined" 2380 continue 2381 } 2382 set statname $t(eq!$eq!if!$iface!vlan!$v!stat) 2383 if {[string equal $statname ""]} then { 2384 set statname "-" 2385 } 2386 puts $fdout "node $nodeL2 type L2 eq $eq vlan $v stat $statname native 0 ifname -" 2387 puts $fdout "link $nodeL2 $nodebrpat" 2388 2389 # 2390 # Parcourir la liste des r�seaux support�s par cette 2391 # sous-interface. 2392 # 2393 foreach cidr $t(eq!$eq!if!$iface!vlan!$v!networks) { 2394 set ifname "$iface.$v" 2395 set idx "eq!$eq!if!$iface!vlan!$v!net!$cidr" 2396 2397 # r�cup�rer l'adresse du routeur dans ce r�seau 2398 # (i.e. l'adresse IP de l'interface) 2399 set gwadr $t($idx) 2400 set preflen $t($idx!preflen) 2401 set nodeL3 [newnode] 2402 2403 puts $fdout "node $nodeL3 type L3 eq $eq addr $gwadr/$preflen" 2404 puts $fdout "link $nodeL3 $nodeL2" 2405 } 2406 } 2407 } 2408 2409 } elseif {! [string equal $linktype "aggregate"]} then { 2410 # 2411 # Cas standard pour toutes les interfaces physiques 2412 # (non constituant un lien aggr�g�) 2413 # 2414 2415 set nodeL1 [newnode] 2416 puts $fdout "node $nodeL1 type L1 eq $eq name $iface link $linkname encap $linktype stat $statname desc $desc" 2417 2418 if {[info exists t(eq!$eq!if!$iface!l2switch)]} then { 2419 # 2420 # Interface de JunOS switch : "family ethernet-switching" 2421 # 2422 2423 set nodeL2 [newnode] 2424 2425 switch -- $t(eq!$eq!if!$iface!link!type) { 2426 ether { 2427 if {[info exists t(eq!$eq!if!$iface!link!allowedvlans)]} then { 2428 set a [lindex $t(eq!$eq!if!$iface!link!allowedvlans) 0] 2429 set v [lindex $a 0] 2430 puts $fdout "node $nodeL2 type L2 eq $eq vlan $v stat - native 1 ifname -" 2431 } else { 2432 set nodeL2 "" 2433 } 2434 } 2435 trunk { 2436 puts -nonewline $fdout "node $nodeL2 type L2pat eq $eq" 2437 foreach allowedvlans $t(eq!$eq!if!$iface!link!allowedvlans) { 2438 set v1 [lindex $allowedvlans 0] 2439 set v2 [lindex $allowedvlans 1] 2440 puts -nonewline $fdout " allow $v1 $v2" 2441 } 2442 if {[info exists t(eq!$eq!if!$iface!native-vlan)]} then { 2443 set nv $t(eq!$eq!if!$iface!native-vlan) 2444 puts -nonewline $fdout " native $nv" 2445 } 2446 puts $fdout "" 2447 } 2448 default { 2449 juniper-warning "Unknown link type for '$eq/$iface'" 2450 } 2451 } 2452 2453 if {! [string equal $nodeL2 ""]} then { 2454 puts $fdout "link $nodeL1 $nodeL2" 2455 if {$nodebrpat == 0} then { 2456 set nodebrpat [newnode] 2457 puts $fdout "node $nodebrpat type brpat eq $eq" 2458 } 2459 puts $fdout "link $nodeL2 $nodebrpat" 2460 } 2461 2462 } else { 2463 # 2464 # Interface de JunOS routeur : "family inet[6]" 2465 # 2466 2467 switch $linktype { 2468 ether { 2469 # VLAN = 0 pour un lien Ether 2470 set arg 0 2471 } 2472 trunk { 2473 set arg {} 2474 if {[info exists t(eq!$eq!if!$iface!vlans)]} then { 2475 # Liste des vlans pour ce lien 2476 set arg $t(eq!$eq!if!$iface!vlans) 2477 } 2478 } 2479 default { 2480 juniper-warning "Unknown link type for '$eq/$iface" 2481 } 2482 } 2483 2484 foreach v $arg { 2485 if {! [info exists t(eq!$eq!if!$iface!vlan!$v!disable)]} then { 2486 if {[info exists t(eq!$eq!if!$iface!vlan!$v!networks)]} then { 2487 # 2488 # Interconnexion des VLAN aux interfaces physiques 2489 # 2490 set nodeL2 [newnode] 2491 set t(eq!$eq!if!$iface!vlan!$v!node) $nodeL2 2492 set statname $t(eq!$eq!if!$iface!vlan!$v!stat) 2493 if {[string equal $statname ""]} then { 2494 set statname "-" 2495 } 2496 if {$v == 0} then { 2497 set native 1 2498 } else { 2499 set native 0 2500 } 2501 puts $fdout "node $nodeL2 type L2 eq $eq vlan $v stat $statname native $native ifname -" 2502 puts $fdout "link $nodeL1 $nodeL2" 2503 2504 # 2505 # Parcourir la liste des r�seaux support�s par cette 2506 # sous-interface. 2507 # 2508 foreach cidr $t(eq!$eq!if!$iface!vlan!$v!networks) { 2509 set ifname "$iface.$v" 2510 set idx "eq!$eq!if!$iface!vlan!$v!net!$cidr" 2511 2512 # r�cup�rer l'adresse du routeur dans ce r�seau 2513 # (i.e. l'adresse IP de l'interface) 2514 set gwadr $t($idx) 2515 set preflen $t($idx!preflen) 2516 set nodeL3 [newnode] 2517 2518 puts $fdout "node $nodeL3 type L3 eq $eq addr $gwadr/$preflen" 2519 puts $fdout "link $nodeL3 $nodeL2" 2520 2521 if {[string first ":" $gwadr] != -1} then { 2522 if {[string equal $nodeR6 ""]} then { 2523 set nodeR6 [newnode] 2524 puts $fdout "node $nodeR6 type router eq $eq instance _v6" 2525 } 2526 set nodeR $nodeR6 2527 } else { 2528 if {[string equal $nodeR4 ""]} then { 2529 set nodeR4 [newnode] 2530 puts $fdout "node $nodeR4 type router eq $eq instance _v4" 2531 } 2532 set nodeR $nodeR4 2533 } 2534 2535 puts $fdout "link $nodeL3 $nodeR" 2536 2537 set static {} 2538 2539 # parcourir les passerelles cit�es dans les routes statiques, 2540 # pour d�terminer celles qui sont dans *ce* r�seau 2541 if {[info exists t(eq!$eq!static!gw)]} then { 2542 foreach gw $t(eq!$eq!static!gw) { 2543 set r [juniper-match-network $gw $cidr] 2544 if {$r == -1} then { 2545 return 1 2546 } elseif {$r} then { 2547 foreach n $t(eq!$eq!static!$gw) { 2548 append static "$n $gw " 2549 } 2550 } 2551 } 2552 } 2553 2554 # est-ce qu'il y a du VRRP sur cette interface pour ce r�seau ? 2555 if {[info exists t($idx!vrrp!virtual)]} then { 2556 set vrrp "$t($idx!vrrp!virtual) $t($idx!vrrp!priority)" 2557 } else { 2558 set vrrp "- -" 2559 } 2560 2561 puts $fdout "rnet $cidr $nodeR $nodeL3 $nodeL2 $nodeL1 $vrrp $static" 2562 } 2563 } 2564 } 2565 } 2566 2567 # 2568 # Output interfaces (on JunOS router) marked as 2569 # participating to a bridge domain 2570 # 2571 2572 if {[info exists t(eq!$eq!if!$iface!bridges)]} then { 2573 # 2574 # This interface has at least one unit which 2575 # participates to a bridge-domain 2576 # 2577 foreach b $t(eq!$eq!if!$iface!bridges) { 2578 lassign $b brnode min max 2579 2580 if {$brnode == 0} then { 2581 if {$nodebrpat == 0} then { 2582 set nodebrpat [newnode] 2583 puts $fdout "node $nodebrpat type brpat eq $eq" 2584 } 2585 set brnode $nodebrpat 2586 } 2587 2588 # Is there a sensor? 2589 set statname "" 2590 if {$min == $max} then { 2591 # if this unit has a specific description 2592 # it may have a declared sensor 2593 if {[info exists t(eq!$eq!if!$iface!vlan!$min!stat)]} then { 2594 set statname $t(eq!$eq!if!$iface!vlan!$min!stat) 2595 } 2596 } 2597 if {$statname eq ""} then { 2598 set statname "-" 2599 } 2600 2601 # native vlan ? 2602 set native 0 2603 if {$t(eq!$eq!if!$iface!link!type) eq "ether"} then { 2604 set native 1 2605 } 2606 if {[info exists t(eq!$eq!if!$iface!native-vlan)]} then { 2607 set nv $t(eq!$eq!if!$iface!native-vlan) 2608 if {$min == $max && $min == $nv} then { 2609 set native 1 2610 } 2611 } 2612 2613 set nodeL2 [newnode] 2614 if {$min == $max} then { 2615 set ntype "L2" 2616 set allow "vlan $min" 2617 } else { 2618 set ntype "L2pat" 2619 set allow "allow $min $max" 2620 } 2621 puts $fdout "node $nodeL2 type $ntype eq $eq $allow stat $statname native $native ifname -" 2622 puts $fdout "link $nodeL1 $nodeL2" 2623 puts $fdout "link $nodeL2 $brnode" 2624 } 2625 } 2626 } 2627 } 2628 } 2629 2630 # 2631 # Parcourir la liste des interfaces marqu�es "disable" 2632 # 2633 2634 foreach iface $t(eq!$eq!if!disabled) { 2635 if {! [string equal $iface "vlan"]} then { 2636 set nodeL1 [newnode] 2637 puts $fdout "node $nodeL1 type L1 eq $eq name $iface link X encap disabled stat - desc -" 2638 } 2639 } 2640 2641 return 0 2642} 2643 2644proc juniper-find-ranges {tab eq if} { 2645 upvar $tab t 2646 2647 set lr {} 2648 if {[regexp {^[A-Za-z]+-.*} $if]} then { 2649 foreach r $t(eq!$eq!ranges) { 2650 set lc $t(eq!$eq!range!$r!members) 2651 foreach c $lc { 2652 set min [lindex $c 0] 2653 set max [lindex $c 1] 2654 if {[juniper-iface-cmp $if $min]>=0 && [juniper-iface-cmp $if $max]<=0} then { 2655 lappend lr $r 2656 break 2657 } 2658 } 2659 } 2660 } 2661 return $lr 2662} 2663 2664proc juniper-iface-cmp {i1 i2} { 2665 if {! [regexp {^([A-Za-z]+)-(.*)} $i1 bidon n1 r1]} then { 2666 puts stderr "Invalid interface name '$i1' (range $i1 $i2)" 2667 return -1 2668 } 2669 if {! [regexp {^([A-Za-z]+)-(.*)} $i2 bidon n2 r2]} then { 2670 puts stderr "Invalid interface name '$i2'" 2671 return -1 2672 } 2673 2674 set l1 [split $r1 "/"] 2675 set l2 [split $r2 "/"] 2676 2677 set r [string compare $n1 $n2] 2678 if {$r == 0} then { 2679 foreach e1 $l1 e2 $l2 { 2680 if {$e1 < $e2} then { 2681 set r -1 2682 break 2683 } elseif {$e1 > $e2} then { 2684 set r 1 2685 break 2686 } 2687 } 2688 } 2689 2690 return $r 2691} 2692 2693proc juniper-completer-iface {tab eq if range} { 2694 upvar $tab t 2695 2696 foreach e {link!name link!desc link!stat link!type link!ifname} { 2697 if {[info exists t(eq!$eq!if!$if!$e)] && ! [string equal $t(eq!$eq!if!$if!$e) ""]} then { 2698 # rien � faire 2699 } else { 2700 if {[info exists t(eq!$eq!range!$range!$e)]} then { 2701 set t(eq!$eq!if!$if!$e) $t(eq!$eq!range!$range!$e) 2702 } 2703 } 2704 } 2705} 2706 2707############################################################################### 2708# Initialisation du module 2709############################################################################### 2710 2711juniper-init 2712