mkptop 3.84 KB
Newer Older
1 2
#!/usr/bin/perl -w

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#
# Copyright (c) 2009 University of Utah and the Flux Group.
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
22
# 
23
# }}}
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#

#
# Makes a simple physical topology, based on a number of parameters (which
# are mostly hardcoded for now.) The topology simply fills up switches
# according to some simple rules about the number of interfaces per node and
# the number of ports per switch. Switches are connected in a "star" with
# a "hub" switch in middle to which all node switches have trunks
#

$| = 1;

use strict;
use POSIX qw(ceil floor);

my $nodes;

#
# Parameters
#

# Interfaces per node
my $IFACES = 4;
# Ports per switch (1000 looks like a 
my $PPS = 1000;

# Types that are assigned to every switch
my @SWITCHTYPES = ("switch:*","*lan:*");
# Features to be assigned to every switch
my @SWITCHFEATURES = ();
# Types that are assigned to every node
my @NODETYPES = ("pc:1", "pcvm:10");
# Features that are assigned to every node
my @NODEFEATURES = ();
# Type of links in use
my @LINKTYPES = ("ethernet");
# Speed of node interfaces (gigabit)
my $NODESPEED = "1000";
# Speed of trunk links - relative to speed of node interfaces (here, a single
# 100 gbit interface or 10 trunked 10gbit interfaces)
my $TRUNKSPEED = $NODESPEED * 100;

66 67 68 69 70 71 72 73 74 75 76 77
#
# Generate a list of (0-weight) features
#
sub featurelist($) {
    my ($howmany) = @_;
    my @features;
    foreach my $i (0 .. $howmany -1) {
        push @features, "FD$i:0";
    }
    return @features;
}

78 79
if (@ARGV == 1) {
    ($nodes) = @ARGV;
80 81 82 83
} elsif (@ARGV == 2) {
    my $featurecount;
    ($nodes,$featurecount) = @ARGV;
    @NODEFEATURES = featurelist($featurecount);
84 85 86 87 88
} elsif (@ARGV == 3) {
    my $trunkmult;
    ($nodes, $PPS, $trunkmult) = @ARGV;
    $TRUNKSPEED = $NODESPEED * $trunkmult;
} else {
89
    die "Usage: $0 <nodes> [pps trunkmult] | [ featurecount ]\n";
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
}

#
# How many nodes will fit on each swich
#
my $nodesperswitch = ($PPS*1.0/$IFACES);

#
# How many 'edge' switches are needed
#
my $switchcount = ceil($nodes*1.0 / $nodesperswitch);

#
# Print out a node with the given types and features
#
sub node($$$) {
    my ($name,$typeref,$fref) = @_;
    my @types = @$typeref;
    my @features = @$fref;
    print "node $name ". join(" ",@types) . " - " . join(" ",@features) . "\n";
}

#
# Print out n links with the given source, destination, and speed
#
sub links($$$$) {
    my ($count, $src, $dst, $speed) = @_;
    for (my $i = 0; $i < $count; $i++) {
        print "link $src-$dst-$i $src:(null)/$i $dst:(null)/$i $speed 0 0 " .
            join(" ",@LINKTYPES) . "\n";
    }
}

if ($switchcount > 1) {
    # Print out node line for the interconnect switch
    node("hub",\@SWITCHTYPES,\@SWITCHFEATURES);
}

for (my $i = 0; $i < $nodes; $i++) {
    my $switchname = "switch" . floor(($i / $nodesperswitch));
    #
    # Start a new switch
    #
    if ($i % $nodesperswitch == 0) {
        # Print out the switch for this set of nodes
        node($switchname, \@SWITCHTYPES, \@SWITCHFEATURES);
        # Link to the hub switch
        if ($switchcount > 1) {
            links(1,$switchname,"hub",$TRUNKSPEED);
        }
    }
    my $pcname = "pc" . $i;
    node($pcname,\@NODETYPES,\@NODEFEATURES);
    links($IFACES,$pcname,$switchname,$NODESPEED);
}