From 8831af89e91ffbb6a8ce1479815aea2a853b51bd Mon Sep 17 00:00:00 2001 From: marko Date: Mon, 31 Oct 2005 14:57:07 +0000 Subject: [PATCH] Reimplement IPv4 / IPv6 automatic address assignment process so that it works properly on cross-canvas links. Add the "blank.gif" to the install.sh script. Bug found by: Submitted by: Requested by: Reviewed by: Approved by: Obtained from: --- editor.tcl | 64 ++++++++++++++++++++++------------------------------- initgui.tcl | 4 ++-- install.sh | 2 +- ipv4.tcl | 58 +++++++++++++++++++++++++++++++----------------- ipv6.tcl | 54 ++++++++++++++++++++++++++------------------ nodecfg.tcl | 38 +++++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 82 deletions(-) diff --git a/editor.tcl b/editor.tcl index 5f3c0ec..15d5351 100755 --- a/editor.tcl +++ b/editor.tcl @@ -265,7 +265,7 @@ proc chooseIfName { lnode1 lnode2 } { proc listLANnodes { l2node l2peers } { lappend l2peers $l2node foreach ifc [ifcList $l2node] { - set peer [peerByIfc $l2node $ifc] + set peer [logicalPeerByIfc $l2node $ifc] set type [nodeType $peer] if { [ lsearch {lanswitch hub} $type] != -1 } { if { [lsearch $l2peers $peer] == -1 } { @@ -543,7 +543,8 @@ proc button3node { c x y } { -menu .button3menu.connect.$canvas } foreach peer_node $node_list { - if { $node != $peer_node && [nodeType $peer_node] != "pseudo" } { + if { $node != $peer_node && + [lsearch {pseudo rj45} [nodeType $peer_node]] < 0 } { set canvas [getNodeCanvas $peer_node] .button3menu.connect.$canvas add command \ -label [getNodeName $peer_node] \ @@ -758,7 +759,7 @@ proc button1-motion { c x y } { } -proc pseudo.layer { node } { +proc pseudo.layer {} { } @@ -805,6 +806,15 @@ proc newLink { c lnode1 lnode2 } { setLinkMirror $link1 $link2 setLinkMirror $link2 $link1 + if {[[typemodel $lnode1].layer] == "NETWORK" } { + autoIPv4addr $lnode1 [ifcByPeer $lnode1 $pnode1] + autoIPv6addr $lnode1 [ifcByPeer $lnode1 $pnode1] + } + if {[[typemodel $lnode2].layer] == "NETWORK" } { + autoIPv4addr $lnode2 [ifcByPeer $lnode2 $pnode2] + autoIPv6addr $lnode2 [ifcByPeer $lnode2 $pnode2] + } + # # Redraw our node so interface labels gets properly populated # @@ -812,10 +822,12 @@ proc newLink { c lnode1 lnode2 } { $c delete -withtags "node && $pnode1" $c delete -withtags "nodelabel && $pnode1" drawNode $pnode1 + updateIfcLabel $lnode1 $pnode1 } else { $c delete -withtags "node && $pnode2" $c delete -withtags "nodelabel && $pnode2" drawNode $pnode2 + updateIfcLabel $lnode2 $pnode2 } return yes @@ -864,43 +876,10 @@ proc newLink { c lnode1 lnode2 } { set link [newObjectId link] global $link - set ipv4net [findFreeIPv4net 24] - set ipv6net [findFreeIPv6net 64] - set lannode "" - set ifname1 [newIfc [chooseIfName $lnode1 $lnode2] $lnode1] lappend $lnode1 "interface-peer {$ifname1 $lnode2}" - if { [[typemodel $lnode1].layer] == "NETWORK" && \ - [lsearch {lanswitch hub} [nodeType $lnode2]] >= 0 } { - setIfcIPv4addr $lnode1 $ifname1 [newLANIPv4 $lnode1 $lnode2] - setIfcIPv6addr $lnode1 $ifname1 [newLANIPv6 $lnode1 $lnode2] - set lannode $lnode2 - } elseif { [[typemodel $lnode1].layer] == "NETWORK" } { - setIfcIPv4addr $lnode1 $ifname1 $ipv4net.1/24 - setIfcIPv6addr $lnode1 $ifname1 $ipv6net\::1/64 - if { [nodeType $lnode1] == "pc" || \ - [nodeType $lnode1] == "host" } { - setStatIPv4routes $lnode1 [list "0.0.0.0/0 $ipv4net.2"] - } - } - set ifname2 [newIfc [chooseIfName $lnode2 $lnode1] $lnode2] lappend $lnode2 "interface-peer {$ifname2 $lnode1}" - if { [nodeType $lnode2] != "pseudo" } { - if { [[typemodel $lnode2].layer] == "NETWORK" && \ - [lsearch {lanswitch hub} [nodeType $lnode1]] >= 0 } { - setIfcIPv4addr $lnode2 $ifname2 [newLANIPv4 $lnode2 $lnode1] - setIfcIPv6addr $lnode2 $ifname2 [newLANIPv6 $lnode2 $lnode1] - set lannode $lnode1 - } elseif { [[typemodel $lnode2].layer] == "NETWORK" } { - setIfcIPv4addr $lnode2 $ifname2 $ipv4net.2/24 - setIfcIPv6addr $lnode2 $ifname2 $ipv6net\::2/64 - if { [nodeType $lnode2] == "pc" || \ - [nodeType $lnode2] == "host" } { - setStatIPv4routes $lnode2 [list "0.0.0.0/0 $ipv4net.1"] - } - } - } lappend $link "nodes {$lnode1 $lnode2}" if { ([nodeType $lnode1] == "lanswitch" || \ @@ -915,8 +894,16 @@ proc newLink { c lnode1 lnode2 } { } lappend link_list $link - if { $lannode != "" } { - updateLANdg $lannode + + if { [nodeType $lnode2] != "pseudo" && + [[typemodel $lnode1].layer] == "NETWORK" } { + autoIPv4addr $lnode1 $ifname1 + autoIPv6addr $lnode1 $ifname1 + } + if { [nodeType $lnode1] != "pseudo" && + [[typemodel $lnode2].layer] == "NETWORK" } { + autoIPv4addr $lnode2 $ifname2 + autoIPv6addr $lnode2 $ifname2 } if { [getNodeCanvas $lnode1] == $curcanvas } { @@ -925,6 +912,7 @@ proc newLink { c lnode1 lnode2 } { nodeEnter $c redrawLink $link } + } return $regular diff --git a/initgui.tcl b/initgui.tcl index 16f9d52..7b81405 100755 --- a/initgui.tcl +++ b/initgui.tcl @@ -52,8 +52,8 @@ set cursorState 0 set clock_seconds 0 set oper_mode edit set grid 24 -set sizex 1024 -set sizey 768 +set sizex 900 +set sizey 620 set curcanvas [lindex $canvas_list 0] set autorearrange_enabled 0 diff --git a/install.sh b/install.sh index a883daf..a2a52b7 100755 --- a/install.sh +++ b/install.sh @@ -33,7 +33,7 @@ tiny_icons="delete.gif hub.gif frswitch.gif host.gif \ lanswitch.gif link.gif pc.gif rj45.gif router.gif select.gif" normal_icons="hub.gif frswitch.gif host.gif lanswitch.gif pc.gif \ - rj45.gif router.gif" + rj45.gif router.gif blank.gif" for file in ${lib_files}; do diff --git a/ipv4.tcl b/ipv4.tcl index b4b63fd..cfaf376 100755 --- a/ipv4.tcl +++ b/ipv4.tcl @@ -34,7 +34,7 @@ # -proc findFreeIPv4net { mask } { +proc findFreeIPv4Net { mask } { global node_list set ipnets {} @@ -57,20 +57,37 @@ proc findFreeIPv4net { mask } { } -proc newLANIPv4 { l3node bridge } { - set peer_ipaddrs {} - set l2nodes [listLANnodes $bridge {}] - foreach l2node $l2nodes { - foreach ifc [ifcList $l2node] { - set peer [peerByIfc $l2node $ifc] - set peer_if [ifcByPeer $peer $l2node] - set peer_ipaddr [getIfcIPv4addr $peer $peer_if] - if { $peer_ipaddr != "" } { - lappend peer_ipaddrs [lindex [split $peer_ipaddr /] 0] +proc autoIPv4addr { node iface } { + set peer_ip4addrs {} + + if { [[typemodel $node].layer] != "NETWORK" } { + # + # Shouldn't get called at all in this case + # +puts "autoIPv4 shouldn't get called for non-network layer nodes" + return "" + } + setIfcIPv4addr $node $iface "" + + set peer_node [logicalPeerByIfc $node $iface] + + if { [[typemodel $peer_node].layer] == "LINK" } { + foreach l2node [listLANnodes $peer_node {}] { + foreach ifc [ifcList $l2node] { + set peer [logicalPeerByIfc $l2node $ifc] + set peer_if [ifcByLogicalPeer $peer $l2node] + set peer_ip4addr [getIfcIPv4addr $peer $peer_if] + if { $peer_ip4addr != "" } { + lappend peer_ip4addrs [lindex [split $peer_ip4addr /] 0] + } } - } + } + } else { + set peer_if [ifcByLogicalPeer $peer_node $node] + set peer_ip4addr [getIfcIPv4addr $peer_node $peer_if] + set peer_ip4addrs [lindex [split $peer_ip4addr /] 0] } - switch -exact -- [nodeType $l3node] { + switch -exact -- [nodeType $node] { router { set targetbyte 1 } @@ -81,22 +98,23 @@ proc newLANIPv4 { l3node bridge } { set targetbyte 20 } } - if { $peer_ipaddrs != "" } { - set ipnums [split [lindex $peer_ipaddrs 0] .] + if { $peer_ip4addrs != "" } { + set ipnums [split [lindex $peer_ip4addrs 0] .] set net "[lindex $ipnums 0].[lindex $ipnums 1].[lindex $ipnums 2]" set ipaddr $net.$targetbyte - while { [lsearch $peer_ipaddrs $ipaddr] >= 0 } { + while { [lsearch $peer_ip4addrs $ipaddr] >= 0 } { incr targetbyte set ipaddr $net.$targetbyte } - return "$ipaddr/24" + setIfcIPv4addr $node $iface "$ipaddr/24" } else { - return "[findFreeIPv4net 24].$targetbyte/24" + setIfcIPv4addr $node $iface "[findFreeIPv4Net 24].$targetbyte/24" } + return } -proc findLANdgIP { bridge } { +proc findLANdgIPv4 { bridge } { foreach ifc [ifcList $bridge] { set peer [peerByIfc $bridge $ifc] set peer_if [ifcByPeer $peer $bridge] @@ -109,7 +127,7 @@ proc findLANdgIP { bridge } { proc updateLANdg { bridge } { - set gw [findLANdgIP $bridge] + set gw [findLANdgIPv4 $bridge] if { $gw == "" } { return } diff --git a/ipv6.tcl b/ipv6.tcl index cf102c3..a352dfd 100755 --- a/ipv6.tcl +++ b/ipv6.tcl @@ -34,41 +34,49 @@ # -proc findFreeIPv6net { mask } { +proc findFreeIPv6Net { mask } { global node_list set ipnets {} foreach node $node_list { foreach ifc [ifcList $node] { - set ipnet [lrange [split [getIfcIPv6addr $node $ifc] :] 0 3] + set ipnet [lrange [split [getIfcIPv6addr $node $ifc] :] 0 1] if {[lsearch $ipnets $ipnet] == -1} { lappend ipnets $ipnet } } } for { set i 0 } { $i <= 9999 } { incr i } { - if {[lsearch $ipnets "fec0 0 0 $i"] == -1} { - set ipnet "fec0:0:0:$i" + if {[lsearch $ipnets "a $i"] == -1} { + set ipnet "a:$i" return $ipnet } } } -proc newLANIPv6 { l3node bridge } { - set peer_ipaddrs {} - set l2nodes [listLANnodes $bridge {}] - foreach l2node $l2nodes { - foreach ifc [ifcList $l2node] { - set peer [peerByIfc $l2node $ifc] - set peer_if [ifcByPeer $peer $l2node] - set peer_ipaddr [getIfcIPv6addr $peer $peer_if] - if { $peer_ipaddr != "" } { - lappend peer_ipaddrs [lindex [split $peer_ipaddr /] 0] +proc autoIPv6addr { node iface } { + set peer_ip6addrs {} + setIfcIPv6addr $node $iface "" + set peer_node [logicalPeerByIfc $node $iface] + + if { [[typemodel $peer_node].layer] == "LINK" } { + foreach l2node [listLANnodes $peer_node {}] { + foreach ifc [ifcList $l2node] { + set peer [logicalPeerByIfc $l2node $ifc] + set peer_if [ifcByLogicalPeer $peer $l2node] + set peer_ip6addr [getIfcIPv6addr $peer $peer_if] + if { $peer_ip6addr != "" } { + lappend peer_ip6addrs [lindex [split $peer_ip6addr /] 0] + } } - } + } + } else { + set peer_if [ifcByLogicalPeer $peer_node $node] + set peer_ip6addr [getIfcIPv6addr $peer_node $peer_if] + set peer_ip6addrs [lindex [split $peer_ip6addr /] 0] } - switch -exact -- [nodeType $l3node] { + switch -exact -- [nodeType $node] { router { set targetbyte 1 } @@ -79,18 +87,22 @@ proc newLANIPv6 { l3node bridge } { set targetbyte 20 } } - if { $peer_ipaddrs != "" } { - set ipnums [split [lindex $peer_ipaddrs 0] :] + if { $peer_ip6addrs != "" } { + set ipnums [split [lindex $peer_ip6addrs 0] :] set net "[lindex $ipnums 0]:[lindex $ipnums 1]" set ipaddr $net\::$targetbyte - while { [lsearch $peer_ipaddrs $ipaddr] >= 0 } { + while { [lsearch $peer_ip6addrs $ipaddr] >= 0 } { incr targetbyte set ipaddr $net\::$targetbyte } - return "$ipaddr/64" + setIfcIPv6addr $node $iface "$ipaddr/64" } else { - return "[findFreeIPv6net 64]::$targetbyte/64" + setIfcIPv6addr $node $iface "[findFreeIPv6Net 64]::$targetbyte/64" } + return +} + +proc newLANIPv6 { l3node bridge } { } diff --git a/nodecfg.tcl b/nodecfg.tcl index f0d8d58..5e8e511 100755 --- a/nodecfg.tcl +++ b/nodecfg.tcl @@ -731,6 +731,20 @@ proc peerByIfc { node ifc } { } +proc logicalPeerByIfc { node ifc } { + global $node + + set peer [peerByIfc $node $ifc] + if { [nodeType $peer] != "pseudo" } { + return $peer + } else { + set mirror_node [getNodeMirror $peer] + set mirror_ifc [ifcList $mirror_node] + return [peerByIfc $mirror_node $mirror_ifc] + } +} + + proc ifcByPeer { node peer } { global $node @@ -739,6 +753,30 @@ proc ifcByPeer { node peer } { } +proc ifcByLogicalPeer { node peer } { + global $node + + set ifc [ifcByPeer $node $peer] + if { $ifc == "" } { + # + # Must search through pseudo peers + # + foreach ifc [ifcList $node] { + set t_peer [peerByIfc $node $ifc] + if { [nodeType $t_peer] == "pseudo" } { + set mirror [getNodeMirror $t_peer] + if { [peerByIfc $mirror [ifcList $mirror]] == $peer } { + return $ifc + } + } + } + return "" + } else { + return $ifc + } +} + + proc hasIPv4Addr { node } { foreach ifc [ifcList $node] { if { [getIfcIPv4addr $node $ifc] != "" } { -- 2.39.5