Statistics
| Branch: | Revision:

lorenzoghiroms / network_builder.py @ master

History | View | Annotate | Download (8.44 KB)

1 539671f0 Luca Baldesi
import re
2 c09f8d98 Leonardo Maccari
import sys
3
import networkx as nx
4
5
from mininet.net import Mininet
6
from mininet.log import setLogLevel
7
from mininet.node import OVSController
8
from mininet.cli import CLI
9
from mininet.log import info, error, debug, output
10
from mininet.node import CPULimitedHost
11
from mininet.link import TCLink
12
13
sys.path.append('community_networks_analysis')
14
15
from gengraphs import loadGraph
16
from misclibs import showGraph
17
18
class PowerNet(Mininet):
19
    def __init__(self,**params):
20
        if 'controller' not in params.keys():
21
            params['controller'] = OVSController
22
        if 'host' not in params.keys():
23
            params['host'] = CPULimitedHost
24
        if 'link' not in params.keys():
25
            params['link'] = TCLink
26
        super(PowerNet,self).__init__(**params)
27
28
    def enableForwarding(self):
29
        for node in self.values():
30
            node.cmd("echo 1 > /proc/sys/net/ipv4/ip_forward")
31
32
    def setNeighboursRoutes(self):
33
        for node in self.values():
34
            for intf in node.intfList():
35
                if intf.link:
36
                    rintf = self.remoteIntf(intf)
37
                    raddrs = self.getNodeAddrs(rintf.node)
38
                    for addr in raddrs:
39
                        node.setHostRoute(addr,intf.name)
40
41
    def getNodeAddrs(self,node):
42
        r = []
43
        for intf in node.intfList():
44 0e1720b2 Luca Baldesi
            if intf.link and intf.ip:
45 c09f8d98 Leonardo Maccari
                r.append(intf.ip)
46
        return r
47
48
    def remoteIntf(self,intf):
49
        if intf.link:
50
            intfs = [ intf.link.intf1, intf.link.intf2 ]
51
            intfs.remove(intf)
52
            return intfs[0]
53
        return None
54
55 46af05a6 Luca Baldesi
    def getLinks(self):
56
        # returns the hosts couples representing the links
57
        links = []
58 428f3ed3 Luca Baldesi
        hosts = self.values()
59 46af05a6 Luca Baldesi
        for h in hosts:
60 428f3ed3 Luca Baldesi
            intfs = h.intfList()
61 46af05a6 Luca Baldesi
            for intf in intfs:
62
                if intf.link != None and intf.link not in links:
63
                    links.append(intf.link)
64 428f3ed3 Luca Baldesi
        return links
65 46af05a6 Luca Baldesi
66
    def linkSentPackets(self,link):
67 44d6a454 luca baldesi
        pstr1 = link.intf1.node.cmd("ifconfig ",link.intf1.name ,"| grep -Eo 'TX packets:[0-9]+' | cut -d':' -f 2")
68
        pstr2 = link.intf2.node.cmd("ifconfig ",link.intf2.name ,"| grep -Eo 'TX packets:[0-9]+' | cut -d':' -f 2")
69
        packets1 = int(pstr1.split("\n")[0])
70
        packets2 = int(pstr2.split("\n")[0])
71 46af05a6 Luca Baldesi
        return packets1+packets2
72
73 976ba3fc Luca Baldesi
    def linkSentBytes(self,link):
74
        pstr1 = link.intf1.node.cmd("ifconfig ",link.intf1.name ,"| grep -Eo 'TX bytes:[0-9]+' | cut -d':' -f 2")
75
        pstr2 = link.intf2.node.cmd("ifconfig ",link.intf2.name ,"| grep -Eo 'TX bytes:[0-9]+' | cut -d':' -f 2")
76
        bytes1 = int(pstr1.split("\n")[0].split(" ")[0])
77
        bytes2 = int(pstr2.split("\n")[0].split(" ")[0])
78
        return bytes2+bytes1
79
80 46af05a6 Luca Baldesi
    def hostSentPackets(self,host):
81
        sent_packets = 0
82
        sent_bytes = 0
83
        intfs = host.intfNames()
84
        for intf in intfs:
85
            host.cmd("ifconfig",intf ,"| grep -Eo 'TX bytes:[0-9]+' | cut -d':' -f 2")
86 539671f0 Luca Baldesi
            sent_bytes += int(re.findall(r'\d+',host.cmd("ifconfig",intf ,"| grep -Eo 'TX bytes:[0-9]+' | cut -d':' -f 2"))[0])
87
            sent_packets += int(re.findall(r'\d+',host.cmd("ifconfig ",intf ,"| grep -Eo 'TX packets:[0-9]+' | cut -d':' -f 2"))[0])
88 46af05a6 Luca Baldesi
        return (sent_packets,sent_bytes)
89
90
    def hostReceivedPackets(self,host):
91
        received_packets = 0
92
        received_bytes = 0
93
        intfs = host.intfNames()
94
        for intf in intfs:
95 539671f0 Luca Baldesi
            received_bytes += int(re.findall(r'\d+',host.cmd("ifconfig "+intf +" | grep -Eo 'RX bytes:[0-9]+' | cut -d':' -f 2"))[0])
96
            received_packets += int(re.findall(r'\d+',host.cmd("ifconfig "+intf +" | grep -Eo 'RX packets:[0-9]+' | cut -d':' -f 2"))[0])
97 46af05a6 Luca Baldesi
        return (received_packets,received_bytes)
98
        
99
    def sentPackets(self):
100
        # if you experience assertion errors, you should
101
        # try to make sleep the mininet thread for a second
102
        sent_packets = 0
103
        sent_bytes = 0
104
        hosts = self.values()
105
        for h in hosts:
106
            p,b = self.hostSentPackets(h)
107
            sent_packets += p
108
            sent_bytes += b
109
        return (sent_packets,sent_bytes)
110 c09f8d98 Leonardo Maccari
111
class GraphNet(PowerNet):
112 e32aaa99 leonardo
    def __init__(self, edges_file, draw=True, **params):
113 976ba3fc Luca Baldesi
        if "link_opts" in params.keys():
114
            self.link_opts = params["link_opts"]
115
            del params["link_opts"]
116
117 e32aaa99 leonardo
        super(GraphNet, self).__init__(**params)
118 c09f8d98 Leonardo Maccari
        info("\nReading "+edges_file+"\n")
119
120
        g = loadGraph(edges_file, connected=True)
121
122
        nodeCounter = 0
123
        nodeMap = {}
124 e32aaa99 leonardo
        # mininet bails if host names are longer than 10 chars
125
        max_name_len = 10 - len(str(len(g))) - 2
126 c09f8d98 Leonardo Maccari
        for name in g.nodes():
127 e32aaa99 leonardo
            # remove unprintable chars from name
128
            nodeMap[name] = "h" + filter(str.isalnum, str(name))[-max_name_len:]\
129
                            + "_" + str(nodeCounter)
130 c09f8d98 Leonardo Maccari
            nodeCounter += 1
131
132 e32aaa99 leonardo
        self.gg = nx.relabel_nodes(g, nodeMap)
133 c09f8d98 Leonardo Maccari
134
        self.hosts_port = {}
135
136
        # add nodes
137
        for n in self.gg.nodes():
138
            self.addHost(n)
139 0e1720b2 Luca Baldesi
            self.hosts_port[n] = 1
140 c09f8d98 Leonardo Maccari
141
        # add edges
142
        for e in self.gg.edges(data=True):
143
            # 10 Mbps, 5ms delay, 10% loss, 1000 packet queue
144
            # htp: Hierarchical Token Bucket rate limiter
145
#            quality_params = {"bw":10,"delay":'5ms', "loss":100-100.0/e[2]['weight'], "use_htb":True}
146
            quality_params = {}
147 976ba3fc Luca Baldesi
            quality_params.update(self.link_opts)
148
            #quality_params["bw"] = 10
149
            #quality_params["delay"] = '0.515ms'
150
            #quality_params["jitter"] = '0.284ms'
151
            #quality_params["delay_distribution"] = 'wifi_m0.515_s0.284'
152
            if "loss" in quality_params.keys():
153
                if quality_params["loss"] == "wifi_loss":
154 e32aaa99 leonardo
                    quality_params["loss"] = \
155
                        100*((1-(1.0/(e[2]['weight'])))**7)
156 976ba3fc Luca Baldesi
                else:
157 e32aaa99 leonardo
                    quality_params["loss"] = float(quality_params["loss"])
158
            # the number of retransmisison (4) derives from a parameter of the
159
            # 802.11 standard: dot11LongRetryLink (for Long Packets, are longer
160
            # than dot11RTSthreshold)
161 c09f8d98 Leonardo Maccari
            quality_params["use_htb"] = True
162 e32aaa99 leonardo
            self.insertLink(self.get(e[0]), self.get(e[1]), quality_params)
163 c09f8d98 Leonardo Maccari
164
        if draw:
165
            showGraph(self.gg)
166
167
    def pickHostAddrPort(self, node):
168
        port = self.hosts_port[node.name]
169
        addr = "10.0."+node.name.split('_')[-1]+"."+str(port)+"/8"
170
        self.hosts_port[node.name] += 1
171 e32aaa99 leonardo
        return addr, port
172 c09f8d98 Leonardo Maccari
173
    def insertLink(self, n1, n2, quality_params={}):
174
        addr1, port1 = self.pickHostAddrPort(n1)
175
        addr2, port2 = self.pickHostAddrPort(n2)
176 e32aaa99 leonardo
        self.addLink(n1, n2,
177
                     port1=port1,
178
                     port2=port2,
179
                     params1=dict([('ip', addr1)] + quality_params.items()),
180
                     params2=dict([('ip', addr2)] + quality_params.items()))
181 c09f8d98 Leonardo Maccari
182
    def setShortestRoutes(self):
183 976ba3fc Luca Baldesi
        paths = nx.all_pairs_dijkstra_path(self.gg, weight='weight')
184 c09f8d98 Leonardo Maccari
        for node1 in paths.keys():
185
            host1 = self.get(node1)
186
            debug("Starting node: "+node1+'\n')
187
            debug("\tpaths: "+str(paths[node1])+'\n')
188
            for node2 in paths[node1].keys():
189 e32aaa99 leonardo
                if node2 != node1:
190
                    if len(paths[node1][node2]) > 2:
191 c09f8d98 Leonardo Maccari
                        debug("\tDestination node: "+node2+'\n')
192
                        nextHop = self.get(paths[node1][node2][1])
193
                        debug("\tNextHop node: "+nextHop.name+'\n')
194
                        dsts = self.getNodeAddrs(self.get(node2))
195
                        intfs = host1.connectionsTo(nextHop)
196 0e1720b2 Luca Baldesi
                        nextAddrs = [ couple[1].ip for couple in intfs if couple[1].ip ]
197 c09f8d98 Leonardo Maccari
                        rintf = intfs[0][0] # WARNING we just consider one link
198
                        for dst in dsts:
199
                            for addr in nextAddrs:
200 0e1720b2 Luca Baldesi
                                debug("\tip route add "+str(dst)+" via "+str(addr)+'\n')
201 c09f8d98 Leonardo Maccari
                                host1.cmd("ip route add "+dst+" via "+addr+" dev "+rintf.name)
202
                                debug("\tip route add "+dst+" via "+addr+'\n')
203
                    else :
204
                        host2 = self.get(node2)
205
                        intfs = [ couple[0] for couple in host1.connectionsTo(host2) ]
206
                        rintf = intfs[0] # WARNING we just consider one link
207
                        raddrs = self.getNodeAddrs(host2)
208
                        for addr in raddrs:
209
                            host1.setHostRoute(addr,rintf.name)
210