Version 26 (modified by 11 years ago) (diff) | ,
---|
GENI Network Stitching Example
This page uses gcf 2.4 preview 7 to show an example experiment that creates a network stitching path between the GPO InstaGENI and the Utah InstaGENI racks.
The experiment uses GENI Clearinghouse credentials with the new omni tool named stitcher.py. GENI network stitching does not require any special configuration. If you haven't already configured Omni, please follow these configuration instructions. If you need further assistance, please contact help@geni.net.
1. Design the Stitching Experiment
At this time GENI network stitching is supported by several aggregate, this example shows a simple stitching scenario with one server VM in the GPO InstaGENI rack and one VM client in the Utah InstaGENI rack that are connected with a link. The server-gpo host is configured to be a Web, Iperf and PingPlus server, it also has a routable IP address that is used to access the web server and display results for all traffic types.
We define an RSpec with 2 nodes and one link between them. The link must specify the 2 aggregates that are the endpoints of the link. The tools will do the rest of the work required to stitch the topology. This is the request RSpec used for this experiment:
<?xml version="1.0" encoding="UTF-8"?> <rspec type="request" xmlns="http://www.geni.net/resources/rspec/3" xmlns:planetlab="http://www.planet-lab.org/resources/sfa/ext/planetlab/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:stitch="http://hpn.east.isi.edu/rspec/ext/stitch/0.1/" xsi:schemaLocation="http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/request.xsd"> <node client_id="server-gpo" component_manager_id="urn:publicid:IDN+instageni.gpolab.bbn.com+authority+cm" exclusive="false"> <sliver_type name="emulab-openvz"/> <services> <execute command="sudo /local/install-script.sh" shell="sh"/> <install install_path="/local" url="http://www.gpolab.bbn.com/~lnevers/StitchDemo.tar.gz"/> </services> <emulab:routable_control_ip xmlns:emulab="http://www.protogeni.net/resources/rspec/ext/emulab/1"/> <interface client_id="server-gpo:if0"> <ip address="192.168.4.1" netmask="255.255.255.0" type="ipv4"/> </interface> </node> <node client_id="client-utah" component_manager_id="urn:publicid:IDN+utah.geniracks.net+authority+cm" exclusive="false"> <sliver_type name="emulab-openvz"/> <services> <execute command="sudo /local/install-script.sh" shell="sh"/> <install install_path="/local" url="http://www.gpolab.bbn.com/~lnevers/StitchDemo.tar.gz"/> </services> <interface client_id="client-utah:if0"> <ip address="192.168.4.2" netmask="255.255.255.0" type="ipv4"/> </interface> </node> <link client_id="link"> <component_manager name="urn:publicid:IDN+instageni.gpolab.bbn.com+authority+cm"/> <component_manager name="urn:publicid:IDN+utah.geniracks.net+authority+cm"/> <interface_ref client_id="server-gpo:if0"/> <interface_ref client_id="client-utah:if0"/> <property source_id="server-gpo:if0" dest_id="client-utah:if0" capacity="100000"/> <property source_id="client-utah:if0" dest_id="server-gpo:if0" capacity="100000"/> </link> </rspec>
In the above RSpec, the link information in the component_manager name is used by the stitcher.py to contact the GENI Stitching Computation Service and determine a path between the end-point hosts.
2. Execute the Stitching experiment
We now use the stitcher.py to set up a stitched topology between the two nodes. The stitcher.py tool deliver:
- Simpler experiment set-up, it creates slivers at all aggregates including network stitching path.
- Stitcher.py parses RSpec to determine all compute resource aggregates from your RSpec. No longer need to specify “-a aggregateName”.
- Stitcher.py uses the MAX Stitching Computation Service (SCS) to determine VLAN path needed for your experiment.
- VLANs are a scarce commodity, and failures can happen. Stitcher.py will re-try to create sliver when failures occur.
First create a slice for this experiment:
$ omni.py createslice gpo2utah 13:23:22 INFO omni: Loading config file /home/lnevers/.gcf/omni_config 13:23:22 INFO omni: Using control framework portal 13:23:23 INFO omni: Created slice with Name gpo2utah, URN urn:publicid:IDN+ch.geni.net:ln-prj+slice+gpo2utah, Expiration 2013-07-25 14:41:19 13:23:23 INFO omni: ------------------------------------------------------------ 13:23:23 INFO omni: Completed createslice: Options as run: framework: portal project: ln-prj Args: createslice gpo2utah Result Summary: Created slice with Name gpo2utah, URN urn:publicid:IDN+ch.geni.net:ln-prj+slice+gpo2utah, Expiration 2013-07-25 14:41:19 13:23:23 INFO omni: ============================================================
Now, we create all slivers using the stitcher.py. Remember there is no need to specify the -a aggregate option, aggregates are determined from the RSpec and need not be specified. Note that a file is created in the directory where the slivers are created that capture the aggregates associated with the slice. Following is the stitcher command used:
$ stitcher.py createsliver gpo2utah stitch-ig-gpo-ig-utah.rspec -o 13:25:59 INFO stitcher: Loading config file /home/lnevers/.gcf/omni_config 13:25:59 INFO stitcher: Using control framework portal 13:25:59 INFO stitcher: Checking that slice gpo2utah is valid... <==(1) 13:26:00 INFO stitcher: Slice urn:publicid:IDN+ch.geni.net:ln-prj+slice+gpo2utah expires on 2013-07-25 14:41:19 UTC 13:26:00 INFO stitcher: <Aggregate urn:publicid:IDN+utah.geniracks.net+authority+cm> speaks AM API v3, but sticking with v2 <==(2) 13:26:00 INFO stitcher: <Aggregate urn:publicid:IDN+instageni.gpolab.bbn.com+authority+cm> speaks AM API v3, but sticking with v2 <==(2) 13:26:00 INFO stitcher: <Aggregate urn:publicid:IDN+emulab.net+authority+cm> speaks AM API v3, but sticking with v2 <==(2) 13:26:00 INFO stitch.Aggregate: Writing to '/tmp/gpo2utah-createsliver-request-11-instageni-gpolab-bbn-com.xml' <==(3) 13:26:00 INFO stitch.Aggregate: Stitcher doing createsliver at https://boss.instageni.gpolab.bbn.com:12369/protogeni/xmlrpc/am <==(4) 13:26:16 INFO stitch.Aggregate: Allocation at <Aggregate urn:publicid:IDN+instageni.gpolab.bbn.com+authority+cm> complete. 13:26:16 WARNING stitch.Aggregate: Slivers at PG Utah may not be requested initially for > 5 days. PG Utah slivers will expire earlier than at other aggregates - requested expiration being reset from 2013-07-25T14:41:19Z to 2013-07-23T17:06:16Z 13:26:16 INFO stitch.Aggregate: Writing to '/tmp/gpo2utah-createsliver-request-11-emulab-net.xml' <==(3) 13:26:16 INFO stitch.Aggregate: Stitcher doing createsliver at https://www.emulab.net:12369/protogeni/xmlrpc/am <==(4) 13:26:58 INFO stitch.Aggregate: Allocation at <Aggregate urn:publicid:IDN+emulab.net+authority+cm> complete. 13:26:58 INFO stitch.Aggregate: Writing to '/tmp/gpo2utah-createsliver-request-11-utah-geniracks-net.xml' <==(3) 13:26:58 INFO stitch.Aggregate: Stitcher doing createsliver at https://boss.utah.geniracks.net:12369/protogeni/xmlrpc/am <==(4) 13:27:17 INFO stitch.Aggregate: Allocation at <Aggregate urn:publicid:IDN+utah.geniracks.net+authority+cm> complete. 13:27:17 INFO stitch.Aggregate: Writing to '/tmp/gpo2utah-createsliver-request-11-ion-internet2-edu.xml' <==(3) 13:27:17 INFO stitch.Aggregate: Stitcher doing createsliver at http://geni-am.net.internet2.edu:12346 <==(4) 13:28:02 INFO stitch.Aggregate: DCN AM <Aggregate urn:publicid:IDN+ion.internet2.edu+authority+am>: must wait for status ready.... 13:28:02 INFO stitch.Aggregate: Pause to let circuit become ready... <==(5) 13:28:39 INFO stitch.Aggregate: DCN circuit 23221 is ready 13:28:45 INFO stitch.Aggregate: Allocation at <Aggregate urn:publicid:IDN+ion.internet2.edu+authority+am> complete. 13:28:45 INFO stitch.launcher: All aggregates are complete. 13:28:45 INFO stitcher: Writing to 'gpo2utah-manifest-rspec-stitching-combined.xml' 13:28:45 INFO stitcher: Saved combined reservation RSpec at 4 AMs to file gpo2utah-manifest-rspec-stitching-combined.xml <==(6) Stitching success: Reserved resources in slice gpo2utah at 4 Aggregates (including 2 intermediate aggregate(s) not in the original request), creating 1 link(s).
(1) Sticher.py gets your slice credentials to make sure you have named a valid slice in which to create your circuit and then it runs rspeclint on the stitch-ig-gpo-ig-utah.rspec file, if rspeclint is found in your search path.
(2) Sticher.py contacts the Stitching Computation Service (SCS) and returns the list of AMs that are needed to establish the stitching path in addition to the Internet2/ION aggregate.
(3) Stitcher.py generates a request RSpec for each of the aggregates in the path to request both network and compute resources.
(4) Creates sliver at each aggregate (path & end-points) (5) Request at Internet2/ION waits for DCN circuits. If this request fails, stitcher.py will try again after 600 seconds.
(6) A combined manifest rspec is assembled by the stitcher.py to show all aggregates and VLANs used in the sliver.
The above stitched scenario sliver creation brings together various areas that are normally involved in the manual setup of an equivalent circuit:
- Switch configuration at rack endpoints
- Static circuit to get to ION
- ION/OSCARS creation of a dynamic circuit with VLAN translation
- A static connection over UEN
- A routed connection across PG Utah
- A dynamic circuit and then a fixed circuit to Utah InstaGENI.
The combined manifest gpo2utah-manifest-rspec-stitching-combined.xml is attached. Also, the overall information about allocated resources that can be found in the file are shown here:
Below is part of the ig-gpo-ig-utah-manifest-rspec-stitching-combined.xml file showing the stitching manifest that includes all hops hops along the stitched VLAN path:
<stitching lastUpdateTime="2013-07-16T11:34:49.472Z" xmlns="http://hpn.east.isi.edu/rspec/ext/stitch/0.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hpn.east.isi.edu/rspec/ext/stitch/0.1/ http://hpn.east.isi.edu/rspec/ext/stitch/0.1/stitch-schema.xsd"> <path id="link"> <globalId> ion.internet2.edu-22931 </globalId> <lifetime id="ion.internet2.edu-22931"> <start type="xgc"> 2013-07-25T00:00:00.000Z </start> <end type="xgc"> 2013-07-16T11:34:49.472Z </end> </lifetime> <hop id="1"> <link id="urn:publicid:IDN+instageni.gpolab.bbn.com+interface+procurve2:5.24"> <trafficEngineeringMetric> 10 </trafficEngineeringMetric> <capacity> 100000 </capacity> <switchingCapabilityDescriptor> <switchingcapType> l2sc </switchingcapType> <encodingType> ethernet </encodingType> <switchingCapabilitySpecificInfo> <switchingCapabilitySpecificInfo_L2sc> <interfaceMTU> 9000 </interfaceMTU> <vlanRangeAvailability> 3748 </vlanRangeAvailability> <suggestedVLANRange> 3748 </suggestedVLANRange> <vlanTranslation> false </vlanTranslation> </switchingCapabilitySpecificInfo_L2sc> </switchingCapabilitySpecificInfo> </switchingCapabilityDescriptor> </link> <nextHop> 2 </nextHop> </hop> <hop id="4"> <link id="urn:publicid:IDN+emulab.net+interface+procurve-pgeni-atla:3.21"> <trafficEngineeringMetric> 10 </trafficEngineeringMetric> <capacity> 100000 </capacity> <switchingCapabilityDescriptor> <switchingcapType> l2sc </switchingcapType> <encodingType> ethernet </encodingType> <switchingCapabilitySpecificInfo> <switchingCapabilitySpecificInfo_L2sc> <interfaceMTU> 9000 </interfaceMTU> <vlanRangeAvailability> 874 </vlanRangeAvailability> <suggestedVLANRange> 874 </suggestedVLANRange> <vlanTranslation> false </vlanTranslation> </switchingCapabilitySpecificInfo_L2sc> </switchingCapabilitySpecificInfo> </switchingCapabilityDescriptor> </link> <nextHop> 5 </nextHop> </hop> <hop id="5"> <link id="urn:publicid:IDN+emulab.net+interface+procurveA:3.19"> <trafficEngineeringMetric> 10 </trafficEngineeringMetric> <capacity> 100000 </capacity> <switchingCapabilityDescriptor> <switchingcapType> l2sc </switchingcapType> <encodingType> ethernet </encodingType> <switchingCapabilitySpecificInfo> <switchingCapabilitySpecificInfo_L2sc> <interfaceMTU> 9000 </interfaceMTU> <vlanRangeAvailability> 874 </vlanRangeAvailability> <suggestedVLANRange> 874 </suggestedVLANRange> <vlanTranslation> false </vlanTranslation> </switchingCapabilitySpecificInfo_L2sc> </switchingCapabilitySpecificInfo> </switchingCapabilityDescriptor> </link> <nextHop> 6 </nextHop> </hop> <hop id="6"> <link id="urn:publicid:IDN+utah.geniracks.net+interface+procurve2:1.19"> <trafficEngineeringMetric> 10 </trafficEngineeringMetric> <capacity> 100000 </capacity> <switchingCapabilityDescriptor> <switchingcapType> l2sc </switchingcapType> <encodingType> ethernet </encodingType> <switchingCapabilitySpecificInfo> <switchingCapabilitySpecificInfo_L2sc> <interfaceMTU> 9000 </interfaceMTU> <vlanRangeAvailability> 874 </vlanRangeAvailability> <suggestedVLANRange> 874 </suggestedVLANRange> <vlanTranslation> false </vlanTranslation> </switchingCapabilitySpecificInfo_L2sc> </switchingCapabilitySpecificInfo> </switchingCapabilityDescriptor> </link> <nextHop> null </nextHop> </hop> </path> </stitching>
In the stitching definition:
- <hop id="1"> is for the GPO InstaGENI switch (procurve2:5.24) and uses VLAN 3748.
- <hop id="4"> is for PG Utah switch that connects PG Utah to ION (procurve-pgeni-atla:3.21) and uses VLAN 874
- <hop id="5"> is for the Utah PG switch that connects to Utah IG (procurveA:3.19) and uses VLAN 874
- <hop id="6"> is for the Utah InstaGENI switch (procurve2:1.19) and uses VLAN 874
At this point the experiment has been set up and you may determine the login information at each compute aggregate:
$ readyToLogin.py ig-gpo-ig-utah -a ig-gpo ... server-gpo's geni_status is: ready (am_status:ready) User lnevers logs in to server-gpo using: ssh -i /home/lnevers/.ssh/geni_cert_portal_key lnevers@pcvm2-14.instageni.gpolab.bbn.com $ readyToLogin.py ig-gpo-ig-utah -a ig-utah client-utah's geni_status is: ready (am_status:ready) User lnevers logs in to client-utah using: ssh -p 30522 -i /home/lnevers/.ssh/geni_cert_portal_key lnevers@pc1.utah.geniracks.net
We will use the server-gpo login to determine the routable IP address that was requested for the Web Server:
$ ssh -i /home/lnevers/.ssh/geni_cert_portal_key lnevers@pcvm2-14.instageni.gpolab.bbn.com [lnevers@server-gpo ~]$ /sbin/ifconfig eth999 Link encap:Ethernet HWaddr 02:1A:B9:6C:51:18 inet addr:192.1.242.151 Bcast:192.1.242.255 Mask:255.255.255.128 <==(a) UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:17379 errors:0 dropped:0 overruns:0 frame:0 TX packets:9372 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:25441630 (24.2 MiB) TX bytes:509859 (497.9 KiB) eth3748 Link encap:Ethernet HWaddr 02:73:1F:92:9B:C6 inet addr:192.168.4.1 Bcast:192.168.4.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:68 errors:0 dropped:0 overruns:0 frame:0 TX packets:52 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:3901 (3.8 KiB) TX bytes:27928 (27.2 KiB)
(a) publically routable IP address
You may also use the client-utah login to verify connectivity between to the server-gpo:
$ ssh -p 30522 -i /home/lnevers/.ssh/geni_cert_portal_key lnevers@pc1.utah.geniracks.net [lnevers@client-utah ~]$ /sbin/ifconfig eth874 Link encap:Ethernet HWaddr 02:16:D6:8B:87:01 inet addr:192.168.4.2 Bcast:192.168.4.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:55 errors:0 dropped:0 overruns:0 frame:0 TX packets:260 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:3434 (3.3 KiB) TX bytes:323831 (316.2 KiB) eth999 Link encap:Ethernet HWaddr 02:DF:E2:D1:9E:24 inet addr:172.17.1.4 Bcast:172.31.255.255 Mask:255.240.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:15802 errors:0 dropped:0 overruns:0 frame:0 TX packets:7917 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:22849021 (21.7 MiB) TX bytes:421874 (411.9 KiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:2 errors:0 dropped:0 overruns:0 frame:0 TX packets:2 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:196 (196.0 b) TX bytes:196 (196.0 b) [lnevers@client-utah ~]$ ping -c 5 192.168.4.1 PING 192.168.4.1 (192.168.4.1) 56(84) bytes of data. 64 bytes from 192.168.4.1: icmp_req=1 ttl=64 time=80.4 ms 64 bytes from 192.168.4.1: icmp_req=2 ttl=64 time=80.4 ms 64 bytes from 192.168.4.1: icmp_req=3 ttl=64 time=80.3 ms 64 bytes from 192.168.4.1: icmp_req=4 ttl=64 time=80.3 ms 64 bytes from 192.168.4.1: icmp_req=5 ttl=64 time=80.3 ms --- 192.168.4.1 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4001ms rtt min/avg/max/mdev = 80.376/80.395/80.436/0.180 ms [lnevers@client-utah ~]$
We can now connected to the web server to verify that iperf tests were run and that client completed wget operations:
Select the Web Server Statistics link and verify that wget was sucessfull for images:
Next, select the Iperf Server Logs link to verify that the iperf test completed:
3. Finish the Stitching Experiment
Now that the experiment is completed, we can release all resources:
$ stitcher.py deletesliver ig-gpo-ig-utah 08:33:23 INFO stitcher: Loading config file /home/lnevers/.gcf/omni_config 08:33:23 INFO stitcher: Using control framework portal 08:33:23 INFO stitcher: Reading stitching slice ig-gpo-ig-utah aggregates from file ch\.geni\.net.ln-prj.ig-gpo-ig-utah-amlist.txt <==(1) 08:33:23 INFO stitcher: Adding aggregate option https://boss.utah.geniracks.net:12369/protogeni/xmlrpc/am (urn:publicid:IDN+utah.geniracks.net+authority+cm) <==(2) 08:33:23 INFO stitcher: Adding aggregate option https://boss.instageni.gpolab.bbn.com:12369/protogeni/xmlrpc/am (urn:publicid:IDN+instageni.gpolab.bbn.com+authority+cm)<==(2) 08:33:23 INFO stitcher: Adding aggregate option https://www.emulab.net:12369/protogeni/xmlrpc/am (urn:publicid:IDN+emulab.net+authority+cm) <==(2) 08:33:23 INFO stitcher: Adding aggregate option http://geni-am.net.internet2.edu:12346 (urn:publicid:IDN+ion.internet2.edu+authority+am) <==(2) 08:33:23 INFO omni: Loading config file /home/lnevers/.gcf/omni_config 08:33:23 INFO omni: Using control framework portal 08:33:24 INFO omni: Slice urn:publicid:IDN+ch.geni.net:ln-prj+slice+ig-gpo-ig-utah expires on 2013-07-25 00:00:00 UTC 08:34:20 INFO omni: (PG log url - look here for details on any failures: https://boss.utah.geniracks.net/spewlogfile.php3?logfile=639d88975aaa36cc97fe2a95a9e359f1) 08:34:20 INFO omni: Deleted sliver urn:publicid:IDN+ch.geni.net:ln-prj+slice+ig-gpo-ig-utah on unspecified_AM_URN at https://boss.utah.geniracks.net:12369/protogeni/xmlrpc/am 08:35:04 INFO omni: (PG log url - look here for details on any failures: https://www.emulab.net/spewlogfile.php3?logfile=d87f3ca663ce1c55aae1537de2563458) 08:35:04 INFO omni: Deleted sliver urn:publicid:IDN+ch.geni.net:ln-prj+slice+ig-gpo-ig-utah on unspecified_AM_URN++ at https://www.emulab.net:12369/protogeni/xmlrpc/am 08:35:09 INFO omni: Deleted sliver urn:publicid:IDN+ch.geni.net:ln-prj+slice+ig-gpo-ig-utah on unspecified_AM_URN+++ at http://geni-am.net.internet2.edu:12346 08:36:00 INFO omni: (PG log url - look here for details on any failures: https://boss.instageni.gpolab.bbn.com/spewlogfile.php3?logfile=aa5267b3bd8b1bff2a67f4354efdce38) 08:36:00 INFO omni: Deleted sliver urn:publicid:IDN+ch.geni.net:ln-prj+slice+ig-gpo-ig-utah on unspecified_AM_URN+ at https://boss.instageni.gpolab.bbn.com:12369/protogeni/xmlrpc/am Deleted slivers on 4 out of a possible 4 aggregates <==(3)
(1) Stitcher.py uses the files ch\.geni\.net.ln-prj.ig-gpo-ig-utah-amlist.txt which has the AM list associated with the slice. Note, that is this file does not exist in the current working directory, stitcher.py will try to delete the sliver at all know aggregates, but you will still have to delete the sliver manually at the Internet2/ION aggregate (http://geni-am.net.internet2.edu:12346)
(2) List of aggregates where the sliver will be deleted.
(3) Sliver has been deletes and compute and network resources are released at all aggregates.
Additional Stitching Scenarios
Additional stitching scenarios have been tested and some example request RSpec can be used as a reference at this location:
- stitch-pg-utah-ig-utah.rspec - Utah PG to Utah InstaGENI
- stitch-ig-gpo-pg-uky.rspec - GPO InstaGENI to UKY PG
- stitch-eg-gpo-ig-utah.rspec - GPO ExoGENI to Utah InstaGENI
- stitch-ig-gpo-pg-utah.rspec - GPO IG to Utah PG
- stitch-pg-uky-ig-utah.rspec - UKY PG to Utah InstaGENI
- stitch-pg-utah-pg-uky.rspec - Utah PG to UKY PG
- stitch-max-ig-utah.rspec - MAX MyPLC to Utah InstaGENI
- stitch-pg-utah-ig-gpo.rspec - Utah PG to Utah InstaGENI
- stitch-3linear.rspec - 3 node linear topology (Utah IG <=> Utah PG <=> GPO IG)
- stitch-4linear.rspec - 4 node linear topology (Utah IG <=> Utah PG <=> GPO IG <=> MAX MyPLC)
- stitch-triangle.rspec - triangle topology (Utah PG<=>Utah KY<=> GPO IG <==> Utah PG)
If additional help is needed please contact help@geni.net
Attachments (6)
- IG-GPO-IG-Utah.jpg (55.5 KB) - added by 11 years ago.
- IG-GPO-IG-Utah-tags.jpg (68.0 KB) - added by 11 years ago.
- web-server-iperf.jpg (1.3 MB) - added by 11 years ago.
- web-server-stats.jpg (2.1 MB) - added by 11 years ago.
- web-server.jpg (1.7 MB) - added by 11 years ago.
- web-server-pingplus.jpg (819.4 KB) - added by 11 years ago.