}
-proc findFreeIPnet { mask } {
+proc findFreeIPv4net { mask } {
global nodes
set ipnets {}
foreach node $nodes {
foreach ifc [ifcList $node] {
- set ipnet [lrange [split [getIfcIPaddr $node $ifc] .] 0 2]
+ set ipnet [lrange [split [getIfcIPv4addr $node $ifc] .] 0 2]
if {[lsearch $ipnets $ipnet] == -1} {
lappend ipnets $ipnet
}
}
+proc findFreeIPv6net { mask } {
+ global nodes
+
+ set ipnets {}
+ foreach node $nodes {
+ foreach ifc [ifcList $node] {
+ 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 "fefe $i"] == -1} {
+ set ipnet "fefe:$i"
+ return $ipnet
+ }
+ }
+}
+
+
proc listLANnodes { l2node l2peers } {
lappend l2peers $l2node
foreach ifc [ifcList $l2node] {
}
-proc newLANIP { l3node bridge } {
+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 [getIfcIPaddr $peer $peer_if]
+ set peer_ipaddr [getIfcIPv4addr $peer $peer_if]
if { $peer_ipaddr != "" } {
lappend peer_ipaddrs [lindex [split $peer_ipaddr /] 0]
}
}
return "$ipaddr/24"
} else {
- return "[findFreeIPnet 24].$targetbyte/24"
+ return "[findFreeIPv4net 24].$targetbyte/24"
+ }
+}
+
+
+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]
+ }
+ }
+ }
+ switch -exact -- [nodeType $l3node] {
+ router {
+ set targetbyte 1
+ }
+ host {
+ set targetbyte 10
+ }
+ pc {
+ set targetbyte 20
+ }
+ }
+ if { $peer_ipaddrs != "" } {
+ set ipnums [split [lindex $peer_ipaddrs 0] :]
+ set net "[lindex $ipnums 0]:[lindex $ipnums 1]"
+ set ipaddr $net\::$targetbyte
+ while { [lsearch $peer_ipaddrs $ipaddr] >= 0 } {
+ incr targetbyte
+ set ipaddr $net\::$targetbyte
+ }
+ return "$ipaddr/64"
+ } else {
+ return "[findFreeIPv6net 64]::$targetbyte/64"
}
}
foreach ifc [ifcList $bridge] {
set peer [peerByIfc $bridge $ifc]
set peer_if [ifcByPeer $peer $bridge]
- set peer_ipaddr [getIfcIPaddr $peer $peer_if]
+ set peer_ipaddr [getIfcIPv4addr $peer $peer_if]
if { [nodeType $peer] == "router" } {
return [lindex [split $peer_ipaddr /] 0]
}
foreach ifc [ifcList $bridge] {
set peer [peerByIfc $bridge $ifc]
if { [nodeType $peer] == "pc" || [nodeType $peer] == "host" } {
- setStatIProutes $peer [list "0.0.0.0/0 $gw"]
+ setStatIPv4routes $peer [list "0.0.0.0/0 $gw"]
}
}
return
set link [lindex [.c gettags "link && $lnode1 && $lnode2"] 1]
set ifc [ifcByPeer $lnode1 $lnode2]
- set ifipaddr [getIfcIPaddr $lnode1 $ifc]
+ set ifipv4addr [getIfcIPv4addr $lnode1 $ifc]
+ set ifipv6addr [getIfcIPv6addr $lnode1 $ifc]
if { $ifc == 0 } {
set ifc ""
}
if { $showIfNames } {
set labelstr "$labelstr$ifc\r"
}
- if { $showIfIPaddrs && $ifipaddr != "" } {
- set labelstr "$labelstr$ifipaddr\r"
+ if { $showIfIPaddrs && $ifipv4addr != "" } {
+ set labelstr "$labelstr$ifipv4addr\r"
+ }
+ if { $showIfIPaddrs && $ifipv6addr != "" } {
+ set labelstr "$labelstr$ifipv6addr\r"
}
set labelstr \
[string range $labelstr 0 [expr [string length $labelstr] - 2]]
! \
"router rip" \
" redistribute static" \
+ " redistribute connected" \
" network 0.0.0.0/0" \
+ ! \
+ "router ripng" \
+ " redistribute static" \
+ " redistribute connected" \
+ " network ::/0" \
! ]
} elseif {$activetool == "rj45"} {
set nconfig [list \
set link [newId link]
global $link
- set ipnet [findFreeIPnet 24]
+ set ipv4net [findFreeIPv4net 24]
+ set ipv6net [findFreeIPv6net 64]
set lannode ""
set ifname1 [newIfc [chooseIfName $lnode1 $lnode2] $lnode1]
lappend $lnode1 "interface-peer {$ifname1 $lnode2}"
if { [lsearch {lanswitch hub rj45} [nodeType $lnode1]] < 0 && \
[lsearch {lanswitch hub} [nodeType $lnode2]] >= 0 } {
- setIfcIPaddr $lnode1 $ifname1 [newLANIP $lnode1 $lnode2]
+ setIfcIPv4addr $lnode1 $ifname1 [newLANIPv4 $lnode1 $lnode2]
+ setIfcIPv6addr $lnode1 $ifname1 [newLANIPv6 $lnode1 $lnode2]
set lannode $lnode2
} elseif { [lsearch {hub frswitch lanswitch rj45} \
[nodeType $lnode1]] < 0 } {
- setIfcIPaddr $lnode1 $ifname1 $ipnet.1/24
+ setIfcIPv4addr $lnode1 $ifname1 $ipv4net.1/24
+ setIfcIPv6addr $lnode1 $ifname1 $ipv6net\::1/64
if { [nodeType $lnode1] == "pc" || \
[nodeType $lnode1] == "host" } {
- setStatIProutes $lnode1 [list "0.0.0.0/0 $ipnet.2"]
+ setStatIPv4routes $lnode1 [list "0.0.0.0/0 $ipv4net.2"]
}
}
lappend $lnode2 "interface-peer {$ifname2 $lnode1}"
if { [lsearch {lanswitch hub rj45} [nodeType $lnode2]] < 0 && \
[lsearch {lanswitch hub} [nodeType $lnode1]] >= 0 } {
- setIfcIPaddr $lnode2 $ifname2 [newLANIP $lnode2 $lnode1]
+ setIfcIPv4addr $lnode2 $ifname2 [newLANIPv4 $lnode2 $lnode1]
+ setIfcIPv6addr $lnode2 $ifname2 [newLANIPv6 $lnode2 $lnode1]
set lannode $lnode1
} elseif { [lsearch {hub frswitch lanswitch rj45} \
[nodeType $lnode2]] < 0 } {
- setIfcIPaddr $lnode2 $ifname2 $ipnet.2/24
+ setIfcIPv4addr $lnode2 $ifname2 $ipv4net.2/24
+ setIfcIPv6addr $lnode2 $ifname2 $ipv6net\::2/64
if { [nodeType $lnode2] == "pc" || \
[nodeType $lnode2] == "host" } {
- setStatIProutes $lnode2 [list "0.0.0.0/0 $ipnet.1"]
+ setStatIPv4routes $lnode2 [list "0.0.0.0/0 $ipv4net.1"]
}
}
}
if { $type != "rj45" } {
foreach ifc [ifcList $node] {
- set line "$line $ifc:[getIfcIPaddr $node $ifc]"
+ set line "$line $ifc:[getIfcIPv4addr $node $ifc]"
}
}
.bottom.textbox config -text "$line"
}
-proc checkIPAddr { str } {
+proc checkIPv4Addr { str } {
set n 0
while { $n < 4 } {
if { $n < 3 } {
}
-proc checkIPNet { str } {
- if { ![checkIPAddr [lindex [split $str /] 0]]} {
+proc checkIPv4Net { str } {
+ if { ![checkIPv4Addr [lindex [split $str /] 0]]} {
return 0
}
set net [lindex [split $str /] 1]
frame $wi.if$ifc.tab -width 10
frame $wi.if$ifc.cfg
- if { [nodeType [peerByIfc $target $ifc]] != "rj45" && \
- [nodeType $target] != "rj45" } {
+ if { 1 } {
#
# Queue config
#
if {[lsearch {router pc host} $type] >= 0} {
#
- # IP address & MTU
+ # IPv4 address & MTU
#
- frame $wi.if$ifc.cfg.ip
- label $wi.if$ifc.cfg.ip.addrl -text "IP address" \
+ frame $wi.if$ifc.cfg.ipv4
+ label $wi.if$ifc.cfg.ipv4.addrl -text "IPv4 address" \
-anchor w
- entry $wi.if$ifc.cfg.ip.addrv -bg white -width 16 \
+ entry $wi.if$ifc.cfg.ipv4.addrv -bg white -width 16 \
-validate focus -invcmd "focusAndFlash %W"
- $wi.if$ifc.cfg.ip.addrv insert 0 \
- [getIfcIPaddr $target $ifc]
- $wi.if$ifc.cfg.ip.addrv configure \
- -vcmd {checkIPNet %P}
- if { $model == "xorp" && $oper_mode != "edit" } {
- $wi.if$ifc.cfg.ip.addrv configure \
- -state readonly
- }
- label $wi.if$ifc.cfg.ip.mtul -text "MTU" \
+ $wi.if$ifc.cfg.ipv4.addrv insert 0 \
+ [getIfcIPv4addr $target $ifc]
+ $wi.if$ifc.cfg.ipv4.addrv configure \
+ -vcmd {checkIPv4Net %P}
+ label $wi.if$ifc.cfg.ipv4.mtul -text "MTU" \
-anchor e -width 5
- spinbox $wi.if$ifc.cfg.ip.mtuv -bg white -width 4 \
+ spinbox $wi.if$ifc.cfg.ipv4.mtuv -bg white -width 4 \
-validate focus -invcmd "focusAndFlash %W"
- $wi.if$ifc.cfg.ip.mtuv insert 0 \
+ $wi.if$ifc.cfg.ipv4.mtuv insert 0 \
[getIfcMTU $target $ifc]
if {![string first eth $ifc]} {
- $wi.if$ifc.cfg.ip.mtuv configure \
+ $wi.if$ifc.cfg.ipv4.mtuv configure \
-from 256 -to 1500 -increment 2 \
-vcmd {checkIntRange %P 256 1500}
} else {
- $wi.if$ifc.cfg.ip.mtuv configure \
+ $wi.if$ifc.cfg.ipv4.mtuv configure \
-from 256 -to 2044 -increment 2 \
-vcmd {checkIntRange %P 256 2044}
}
- if { $model == "xorp" && $oper_mode != "edit" } {
- $wi.if$ifc.cfg.ip.mtuv configure \
- -state readonly
- }
- pack $wi.if$ifc.cfg.ip.addrl \
- $wi.if$ifc.cfg.ip.addrv $wi.if$ifc.cfg.ip.mtul \
- $wi.if$ifc.cfg.ip.mtuv -side left
- pack $wi.if$ifc.cfg.ip -side top -anchor w
+ pack $wi.if$ifc.cfg.ipv4.addrl \
+ $wi.if$ifc.cfg.ipv4.addrv \
+ $wi.if$ifc.cfg.ipv4.mtul \
+ $wi.if$ifc.cfg.ipv4.mtuv -side left
+ pack $wi.if$ifc.cfg.ipv4 -side top -anchor w
+
+ #
+ # IPv6 address
+ #
+ frame $wi.if$ifc.cfg.ipv6
+ label $wi.if$ifc.cfg.ipv6.addrl -text "IPv6 address" \
+ -anchor w
+ entry $wi.if$ifc.cfg.ipv6.addrv -bg white -width 30 \
+ -validate focus -invcmd "focusAndFlash %W"
+ $wi.if$ifc.cfg.ipv6.addrv insert 0 \
+ [getIfcIPv6addr $target $ifc]
+if { 0 } {
+ $wi.if$ifc.cfg.ipv6.addrv configure \
+ -vcmd {checkIPv4Net %P}
+}
+ pack $wi.if$ifc.cfg.ipv6.addrl \
+ $wi.if$ifc.cfg.ipv6.addrv -side left
+ pack $wi.if$ifc.cfg.ipv6 -side top -anchor w
}
pack $wi.if$ifc.tab $wi.if$ifc.cfg -side left
pack $wi.if$ifc -side top -anchor w -fill both
#
# Static IP routes
#
- set routes [getStatIProutes $target]
+ set routes [getStatIPv4routes $target]
labelframe $wi.statrt -padx 4 -pady 4
label $wi.statrt.label -text "Static IP routes:"
pack $wi.statrt.label -side top -anchor w
}
#
- # IP address & MTU
+ # IPv4 / IPv6 address & MTU
#
- set ipaddr [$wi.if$ifc.cfg.ip.addrv get]
- set oldipaddr [getIfcIPaddr $target $ifc]
+ set ipaddr [$wi.if$ifc.cfg.ipv4.addrv get]
+ set oldipaddr [getIfcIPv4addr $target $ifc]
if { $ipaddr != $oldipaddr } {
- setIfcIPaddr $target $ifc $ipaddr
+ setIfcIPv4addr $target $ifc $ipaddr
updateIfcLabel $target [peerByIfc $target $ifc]
set changed 1
set ifconfchanged 1
}
- set mtu [$wi.if$ifc.cfg.ip.mtuv get]
+ set ipaddr [$wi.if$ifc.cfg.ipv6.addrv get]
+ set oldipaddr [getIfcIPv6addr $target $ifc]
+ if { $ipaddr != $oldipaddr } {
+ setIfcIPv6addr $target $ifc $ipaddr
+ updateIfcLabel $target [peerByIfc $target $ifc]
+ set changed 1
+ set ifconfchanged 1
+ }
+
+ set mtu [$wi.if$ifc.cfg.ipv4.mtuv get]
set oldmtu [getIfcMTU $target $ifc]
if { $mtu != $oldmtu } {
setIfcMTU $target $ifc $mtu
}
- set oldstatrtes [getStatIProutes $target]
+ set oldstatrtes [getStatIPv4routes $target]
set newstatrtes {}
set i 1
while { 1 } {
}
if { [lsort $oldstatrtes] != [lsort $newstatrtes] || \
$ifconfchanged == 1} {
- setStatIProutes $target $newstatrtes
+ setStatIPv4routes $target $newstatrtes
set changed 1
}
# router
# host
# pc
-# lan-switch
+# lanswitch
+# hub
# rj45
#
# The following node types are to be implemented in the future:
#
-# fr-switch
+# frswitch
# pseudo
# text
# image
# setIfcMTU { node_id ifc mtu }
# Sets the new MTU. Zero MTU value denotes the default MTU.
#
-# getIfcIPaddr { node_id ifc }
-# Returns a list of all IP addresses assigned to an interface.
+# getIfcIPv4addr { node_id ifc }
+# Returns a list of all IPv4 addresses assigned to an interface.
#
-# setIfcIPaddr { node_id ifc addr }
-# Sets a new IP address(es) on an interface. The correctness of the
+# setIfcIPv4addr { node_id ifc addr }
+# Sets a new IPv4 address(es) on an interface. The correctness of the
# IP address format is not checked / enforced.
#
-# getStatIProutes { node_id }
-# Returns a list of all static IP routes as a list of
-# {destination gateway} pairs.
+# getIfcIPv6addr { node_id ifc }
+# Returns a list of all IPv6 addresses assigned to an interface.
#
-# setStatIProutes { node_id route_list }
+# setIfcIPv6addr { node_id ifc addr }
+# Sets a new IPv6 address(es) on an interface. The correctness of the
+# IP address format is not checked / enforced.
+#
+# getStatIPv4routes { node_id }
+# Returns a list of all static IPv4 routes as a list of
+# {destination gateway {metric}} pairs.
+#
+# setStatIPv4routes { node_id route_list }
+# Replace all current static route entries with a new one, in form of
+# a list, as described above.
+#
+# getStatIPv6routes { node_id }
+# Returns a list of all static IPv6 routes as a list of
+# {destination gateway {metric}} pairs.
+#
+# setStatIPv6routes { node_id route_list }
# Replace all current static route entries with a new one, in form of
# a list, as described above.
#
}
-proc getIfcIPaddr { node ifc } {
+proc getIfcIPv4addr { node ifc } {
set addrlist {}
foreach line [netconfFetchSection $node "interface $ifc"] {
if { [lrange $line 0 1] == "ip address" } {
}
-proc setIfcIPaddr { node ifc addr } {
+proc setIfcIPv4addr { node ifc addr } {
set ifcfg [list "interface $ifc"]
foreach line [netconfFetchSection $node "interface $ifc"] {
if { [lrange $line 0 1] != "ip address" } {
}
-proc getStatIProutes { node } {
+proc getIfcIPv6addr { node ifc } {
+ set addrlist {}
+ foreach line [netconfFetchSection $node "interface $ifc"] {
+ if { [lrange $line 0 1] == "ipv6 address" } {
+ lappend addrlist [lindex $line 2]
+ }
+ }
+ return $addrlist
+}
+
+
+proc setIfcIPv6addr { node ifc addr } {
+ set ifcfg [list "interface $ifc"]
+ foreach line [netconfFetchSection $node "interface $ifc"] {
+ if { [lrange $line 0 1] != "ipv6 address" } {
+ lappend ifcfg $line
+ }
+ }
+ lappend ifcfg " ipv6 address $addr"
+ netconfInsertSection $node $ifcfg
+ return
+}
+
+
+proc getStatIPv4routes { node } {
global $node
set routes {}
set netconf [lindex [lsearch -inline [set $node] "network-config *"] 1]
foreach entry [lsearch -all -inline $netconf "ip route *"] {
- lappend routes [lrange $entry 2 3]
+ lappend routes [lrange $entry 2 end]
}
return $routes
}
-proc setStatIProutes { node routes } {
- netconfClearSection $node "ip route [lindex [getStatIProutes $node] 0]"
+proc setStatIPv4routes { node routes } {
+ netconfClearSection $node "ip route [lindex [getStatIPv4routes $node] 0]"
set section {}
foreach route $routes {
lappend section "ip route $route"
}
+proc getStatIPv6routes { node } {
+ global $node
+
+ set routes {}
+ set netconf [lindex [lsearch -inline [set $node] "network-config *"] 1]
+ foreach entry [lsearch -all -inline $netconf "ipv6 route *"] {
+ lappend routes [lrange $entry 2 end]
+ }
+ return $routes
+}
+
+
+proc setStatIPv6routes { node routes } {
+ netconfClearSection $node "ipv6 route [lindex [getStatIPv6routes $node] 0]"
+ set section {}
+ foreach route $routes {
+ lappend section "ipv6 route $route"
+ }
+ netconfInsertSection $node $section
+ return
+}
+
+
proc getNodeName { node } {
global $node