mirror of
https://github.com/edoardoColi/Communication_Sandbox.git
synced 2026-10-16 19:02:12 +00:00
Mininet Project
This commit is contained in:
+81
-62
@@ -6,6 +6,7 @@ from mininet.node import Node
|
|||||||
from mininet.cli import CLI
|
from mininet.cli import CLI
|
||||||
from mininet.link import TCLink
|
from mininet.link import TCLink
|
||||||
from mininet.log import setLogLevel
|
from mininet.log import setLogLevel
|
||||||
|
from copy import copy #TODO verify/temporaneo
|
||||||
|
|
||||||
class MyRouter (Node):
|
class MyRouter (Node):
|
||||||
def config(self, **params):
|
def config(self, **params):
|
||||||
@@ -17,65 +18,79 @@ class MyRouter (Node):
|
|||||||
|
|
||||||
def build_topology(config_file):
|
def build_topology(config_file):
|
||||||
topo = Topo()
|
topo = Topo()
|
||||||
|
elementsH = {} # Dictionary to store nodes
|
||||||
|
elementsR = {} # Dictionary to store nodes
|
||||||
|
elementsS = {} # Dictionary to store nodes
|
||||||
|
|
||||||
with open(config_file, 'r') as file:
|
h1 = topo.addHost('h1', ip='161.46.247.131/26', defaultRoute='via 161.46.247.129')
|
||||||
for line in file:
|
h2 = topo.addHost('h2', ip='161.46.247.196/27', defaultRoute='via 161.46.247.195')
|
||||||
line = line.strip()
|
|
||||||
if line.startswith('#'): #Skip comment
|
|
||||||
continue
|
|
||||||
|
|
||||||
parts = line.split(" ") #Parse the topology file using spaces
|
r1 = topo.addNode('r1', cls=MyRouter, ip='161.46.247.129/26')
|
||||||
if parts[0] == 'host': #Parse hosts
|
|
||||||
host_name = parts[1]
|
|
||||||
host_ip = parts[2]
|
|
||||||
host_nexthop = 'via ' + parts[3]
|
|
||||||
topo.addHost(host_name, ip=host_ip, defaultRoute=host_nexthop)
|
|
||||||
|
|
||||||
elif parts[0] == 'router': #Parse routers
|
topo.addLink(h1, r1, intfName2='R23', params2={'ip' : '161.46.247.129/26'})
|
||||||
router_name = parts[1]
|
topo.addLink(h2, r1, intfName2='R22', params2={'ip' : '161.46.247.195/27'})
|
||||||
router_ip = parts[2]
|
|
||||||
topo.addNode(router_name, cls=MyRouter, ip=router_ip)
|
# with open(config_file, 'r') as file:
|
||||||
|
# for line in file:
|
||||||
|
# line = line.strip()
|
||||||
|
# if line.startswith('#'): #Skip comment
|
||||||
|
# continue
|
||||||
|
|
||||||
elif parts[0] == 'switch': #Parse switches
|
# parts = line.split(" ") #Parse the topology file using spaces
|
||||||
switch_name = parts[1]
|
# if parts[0] == 'host': #Parse hosts
|
||||||
topo.addSwitch(switch_name)
|
# host_name = parts[1]
|
||||||
|
# host_ip = parts[2]
|
||||||
|
# host_nexthop = 'via ' + parts[3]
|
||||||
|
# host = topo.addHost(host_name, ip=host_ip, defaultRoute=host_nexthop)
|
||||||
|
# host_c = copy(host)
|
||||||
|
# elementsH[host_name] = (host_c)
|
||||||
|
|
||||||
elif parts[0] == 'linkSH': #Parse links switches to hosts
|
# elif parts[0] == 'router': #Parse routers
|
||||||
node1 = parts[1]
|
# router_name = parts[1]
|
||||||
node2 = parts[2]
|
# router_ip = parts[2]
|
||||||
topo.addLink(node1, node2)
|
# router = topo.addNode(router_name, cls=MyRouter, ip=router_ip)
|
||||||
|
# router_c = copy(router)
|
||||||
|
# elementsR[router_name] = (router_c)
|
||||||
|
|
||||||
elif parts[0] == 'linkSS': #Parse links switches to switches
|
# elif parts[0] == 'switch': #Parse switches
|
||||||
node1 = parts[1]
|
# switch_name = parts[1]
|
||||||
node2 = parts[2]
|
# switch = topo.addSwitch(switch_name)
|
||||||
topo.addLink(node1, node2)
|
# switch_c = copy(switch)
|
||||||
|
# elementsS[switch_name] = (switch_c)
|
||||||
|
|
||||||
elif parts[0] == 'linkHR': #Parse links hosts to routers
|
# elif parts[0] == 'linkSH': #Parse links switches to hosts
|
||||||
node1 = parts[1]
|
# node1 = parts[1]
|
||||||
node2 = parts[2]
|
# node2 = parts[2]
|
||||||
intf_name2 = parts[3]
|
# # topo.addLink(node1, node2)
|
||||||
n2_ip = parts[4]
|
|
||||||
topo.addLink(node1, node2, intfName2=intf_name2, params2={'ip' : n2_ip})
|
|
||||||
|
|
||||||
elif parts[0] == 'linkRR': #Parse links routers to routers
|
# elif parts[0] == 'linkSS': #Parse links switches to switches
|
||||||
node1 = parts[1]
|
# node1 = parts[1]
|
||||||
node2 = parts[2]
|
# node2 = parts[2]
|
||||||
intf_name1 = parts[3]
|
# # topo.addLink(node1, node2)
|
||||||
intf_name2 = parts[4]
|
|
||||||
ip1 = parts[5]
|
# elif parts[0] == 'linkHR': #Parse links hosts to routers
|
||||||
ip2 = parts[6]
|
# node1 = parts[1]
|
||||||
topo.addLink(node1, node2, intfName1=intf_name1, intfName2=intf_name2, params1={'ip' : ip1}, params2={'ip' : ip2})
|
# node2 = parts[2]
|
||||||
|
# intf_name2 = parts[3]
|
||||||
|
# n2_ip = parts[4]
|
||||||
|
# topo.addLink(elementsH.get(node1), elementsR.get(node2), intfName2=intf_name2, params2={'ip' : n2_ip})
|
||||||
|
|
||||||
|
# elif parts[0] == 'linkRR': #Parse links routers to routers
|
||||||
|
# node1 = parts[1]
|
||||||
|
# node2 = parts[2]
|
||||||
|
# intf_name1 = parts[3]
|
||||||
|
# intf_name2 = parts[4]
|
||||||
|
# ip1 = parts[5]
|
||||||
|
# ip2 = parts[6]
|
||||||
|
# # topo.addLink(node1, node2, intfName1=intf_name1, intfName2=intf_name2, params1={'ip' : ip1}, params2={'ip' : ip2})
|
||||||
|
|
||||||
# elif parts[0] == 'route': #Parse routing tables
|
# # elif parts[0] == 'route': #Parse routing tables
|
||||||
# name = parts[1]
|
# # name = parts[1]
|
||||||
# for node in topo.nodes():
|
# # for node in topo.nodes():
|
||||||
# if node == name:
|
# # if node == name:
|
||||||
# (node).cmd('ip route add 0.0.0.0/0 via 10.0.0.1 dev r1-eth2')
|
# # (node).cmd('ip route add 0.0.0.0/0 via 10.0.0.1 dev r1-eth2')
|
||||||
# break
|
# # break
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# (topo.getNodeByName('r1')).cmd('ip route add 0.0.0.0/0 via 10.0.0.1 dev r1-eth2')
|
|
||||||
return topo
|
return topo
|
||||||
|
|
||||||
def run_topology(config_file):
|
def run_topology(config_file):
|
||||||
@@ -84,19 +99,23 @@ def run_topology(config_file):
|
|||||||
net = Mininet(topo=topo, link=TCLink)
|
net = Mininet(topo=topo, link=TCLink)
|
||||||
net.start() #Starting the network
|
net.start() #Starting the network
|
||||||
|
|
||||||
with open(config_file, 'r') as file: #Search in the configuration file for routing table
|
# net.addLink(h1, r1, intfName2='R23', params2={'ip' : '161.46.247.129/26'})
|
||||||
for line in file:
|
# net.addLink(h2, r1, intfName2='R22', params2={'ip' : '161.46.247.195/27'})
|
||||||
line = line.strip()
|
|
||||||
if line.startswith('#'): #Skip comment
|
# with open(config_file, 'r') as file: #Search in the configuration file for routing table
|
||||||
continue
|
# for line in file:
|
||||||
parts = line.split(" ")
|
# line = line.strip()
|
||||||
if parts[0] == 'route': #Parse routing tables
|
# if line.startswith('#'): #Skip comment
|
||||||
name = parts[1]
|
# continue
|
||||||
pck_src = parts[2]
|
# parts = line.split(" ")
|
||||||
pck_nexthop = parts[3]
|
# if parts[0] == 'route': #Parse routing tables
|
||||||
interf = parts[4]
|
# name = parts[1]
|
||||||
cmd = 'ip route add ' + pck_src + ' via ' + pck_nexthop + ' dev ' + interf
|
# pck_src = parts[2]
|
||||||
(net.getNodeByName(name)).cmd(cmd)
|
# pck_nexthop = parts[3]
|
||||||
|
# interf = parts[4]
|
||||||
|
# cmd = 'ip route add ' + pck_src + ' via ' + pck_nexthop + ' dev ' + interf
|
||||||
|
# (net.getNodeByName(name)).cmd(cmd)
|
||||||
|
|
||||||
if net.pingAll():
|
if net.pingAll():
|
||||||
print(Fore.RED + "Network has issues" + Style.RESET_ALL)
|
print(Fore.RED + "Network has issues" + Style.RESET_ALL)
|
||||||
else:
|
else:
|
||||||
|
|||||||
+9
-9
@@ -1,14 +1,14 @@
|
|||||||
######## Set hosts ########
|
######## Set hosts ########
|
||||||
## host name ip defRoute ##
|
## host name ip defRoute ##
|
||||||
###########################
|
###########################
|
||||||
host h1 10.1.0.2/24 10.1.0.1
|
host h1 161.46.247.131/26 161.46.247.129
|
||||||
host h2 10.2.0.2/24 10.2.0.1
|
host h2 161.46.247.196/27 161.46.247.195
|
||||||
|
|
||||||
#### Set routers ###
|
#### Set routers ###
|
||||||
## router name ip ##
|
## router name ip ##
|
||||||
####################
|
####################
|
||||||
router r1 10.1.0.1/24
|
router r1 161.46.247.129/26
|
||||||
router r2 10.2.0.1/24
|
#router r2 10.2.0.1/24
|
||||||
|
|
||||||
## Set switches ##
|
## Set switches ##
|
||||||
## switch name ##
|
## switch name ##
|
||||||
@@ -33,16 +33,16 @@ router r2 10.2.0.1/24
|
|||||||
##################### Set links #####################
|
##################### Set links #####################
|
||||||
## linkHR host, router, router_intfName, router_ip ##
|
## linkHR host, router, router_intfName, router_ip ##
|
||||||
#####################################################
|
#####################################################
|
||||||
linkHR h1 r1 r1-eth1 10.1.0.1/24
|
linkHR h1 r1 R23 161.46.247.129/26
|
||||||
linkHR h2 r2 r2-eth1 10.2.0.1/24
|
linkHR h2 r1 R22 161.46.247.195/27
|
||||||
|
|
||||||
######################### Set links #########################
|
######################### Set links #########################
|
||||||
## linkRR router1, router2, intfName1, intfName2, ip1, ip2 ##
|
## linkRR router1, router2, intfName1, intfName2, ip1, ip2 ##
|
||||||
#############################################################
|
#############################################################
|
||||||
linkRR r1 r2 r1-eth2 r2-eth2 10.0.0.0/31 10.0.0.1/31
|
# linkRR r1 r2 r1-eth2 r2-eth2 10.0.0.0/31 10.0.0.1/31
|
||||||
|
|
||||||
############# route table #############
|
############# route table #############
|
||||||
## route name source destRoute interf ##
|
## route name source destRoute interf ##
|
||||||
########################################
|
########################################
|
||||||
route r1 0.0.0.0/0 10.0.0.1 r1-eth2
|
# route r1 0.0.0.0/0 10.0.0.1 r1-eth2
|
||||||
route r2 0.0.0.0/0 10.0.0.0 r2-eth2
|
# route r2 0.0.0.0/0 10.0.0.0 r2-eth2
|
||||||
|
|||||||
-187
@@ -1,187 +0,0 @@
|
|||||||
import mininet
|
|
||||||
import time, socket, random
|
|
||||||
import numpy as np
|
|
||||||
from mininet.cli import CLI
|
|
||||||
from mininet.log import setLogLevel
|
|
||||||
from mininet.net import Mininet
|
|
||||||
from mininet.topo import Topo
|
|
||||||
from mininet.link import TCLink
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
# Define custom topology
|
|
||||||
class MyTopology(Topo):
|
|
||||||
def build(self):
|
|
||||||
# Create switches
|
|
||||||
s1 = self.addSwitch('s1')
|
|
||||||
s2 = self.addSwitch('s2')
|
|
||||||
|
|
||||||
# Create hosts
|
|
||||||
h1 = self.addHost('h1')
|
|
||||||
h2 = self.addHost('h2')
|
|
||||||
|
|
||||||
# Add links
|
|
||||||
self.addLink(h1, s1, cls=TCLink, delay='10ms', bw=1)
|
|
||||||
self.addLink(s1, s2, cls=TCLink, delay='50ms', bw=0.5)
|
|
||||||
self.addLink(s2, h2, cls=TCLink, delay='10ms', bw=1)
|
|
||||||
|
|
||||||
# Define TCP agent
|
|
||||||
class MyTCPAgent:
|
|
||||||
def __init__(self):
|
|
||||||
# Initialize TCP agent
|
|
||||||
self.transmission_rounds = []
|
|
||||||
self.congestion_window_sizes = []
|
|
||||||
|
|
||||||
|
|
||||||
def handle_connection(self):
|
|
||||||
print("TCP connection establishment")
|
|
||||||
# Implement TCP connection establishment
|
|
||||||
|
|
||||||
# Example TCP connection establishment using a socket
|
|
||||||
# self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
# self.sock.connect(('localhost', 19191))
|
|
||||||
|
|
||||||
# Example TCP connection establishment simulation
|
|
||||||
time.sleep(1) # Simulating connection establishment delay
|
|
||||||
|
|
||||||
def handle_data_transfer(self, tunnel, window_size):
|
|
||||||
print("Performing data transfer with tunnel:", tunnel, "and window size:", window_size)
|
|
||||||
# Implement TCP data transfer with the given tunnel and window size using socket programming
|
|
||||||
|
|
||||||
# Implement TCP data transfer simulation
|
|
||||||
|
|
||||||
# Placeholder logic: Simulating data transfer
|
|
||||||
time.sleep(0.1) # Simulating data transfer delay
|
|
||||||
|
|
||||||
# Simulate congestion control by waiting for a fixed amount of time
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
# Record transmission round and final congestion window size
|
|
||||||
self.transmission_rounds.append(len(self.transmission_rounds) + 1)
|
|
||||||
self.congestion_window_sizes.append(window_size)
|
|
||||||
|
|
||||||
# Define RL agent for tunnel selection
|
|
||||||
class TunnelSelectionAgent:
|
|
||||||
def __init__(self, tunnels):
|
|
||||||
# Initialize your RL agent for tunnel selection
|
|
||||||
self.rewards = []
|
|
||||||
self.selected_tunnels = []
|
|
||||||
self.tunnels = tunnels
|
|
||||||
self.current_tunnel = 0
|
|
||||||
|
|
||||||
def select_tunnel(self):
|
|
||||||
# Implement tunnel selection based on RL policy
|
|
||||||
# Placeholder logic: Select a tunnel randomly or based on some criteria
|
|
||||||
selected_tunnel = self.tunnels[self.current_tunnel]
|
|
||||||
self.current_tunnel = (self.current_tunnel + 1) % len(self.tunnels)
|
|
||||||
return selected_tunnel
|
|
||||||
|
|
||||||
def update_policy(self, reward):
|
|
||||||
# Implement RL policy update based on rewards
|
|
||||||
self.rewards.append(reward)
|
|
||||||
self.selected_tunnels.append(self.select_tunnel())
|
|
||||||
|
|
||||||
# Define RL agent for window prediction
|
|
||||||
class WindowPredictionAgent:
|
|
||||||
def __init__(self):
|
|
||||||
# Initialize the RL agent for window prediction
|
|
||||||
self.window_sizes = [1, 2, 4, 8, 16, 32, 64] # Possible window sizes
|
|
||||||
self.alpha = 0.1 # Learning rate
|
|
||||||
self.gamma = 0.9 # Discount factor
|
|
||||||
self.q_table = {} # Q-table to store state-action values
|
|
||||||
|
|
||||||
def predict_window_size(self):
|
|
||||||
# Get the current state (e.g., network conditions)
|
|
||||||
state = self.get_state()
|
|
||||||
|
|
||||||
# Check if the state is in the Q-table
|
|
||||||
if state not in self.q_table:
|
|
||||||
# Initialize Q-values for all possible actions in the current state
|
|
||||||
self.q_table[state] = {window_size: 0 for window_size in self.window_sizes}
|
|
||||||
|
|
||||||
# Choose the action (window size) based on epsilon-greedy policy
|
|
||||||
if random.random() < 0.2: # Exploration (20% of the time)
|
|
||||||
action = random.choice(self.window_sizes)
|
|
||||||
else: # Exploitation (80% of the time)
|
|
||||||
action = self.get_best_action(state)
|
|
||||||
|
|
||||||
return action
|
|
||||||
|
|
||||||
def get_state(self):
|
|
||||||
# Implement the logic to determine the current state based on network conditions
|
|
||||||
# For example, you can consider factors such as round-trip time, packet loss rate, or congestion signals
|
|
||||||
|
|
||||||
# Placeholder logic: Return a random state
|
|
||||||
return random.randint(1, 10)
|
|
||||||
|
|
||||||
def get_best_action(self, state):
|
|
||||||
# Find the action (window size) with the highest Q-value for the given state
|
|
||||||
best_action = max(self.q_table[state], key=self.q_table[state].get)
|
|
||||||
return best_action
|
|
||||||
|
|
||||||
def update_policy(self, reward):
|
|
||||||
# Update the Q-value based on the reward received after taking an action
|
|
||||||
# Get the previous state and action
|
|
||||||
prev_state = self.get_state() # Replace with the actual previous state
|
|
||||||
prev_action = self.predict_window_size() # Replace with the actual previous action
|
|
||||||
|
|
||||||
# Get the current state
|
|
||||||
curr_state = self.get_state()
|
|
||||||
|
|
||||||
# Check if the current state is in the Q-table
|
|
||||||
if curr_state not in self.q_table:
|
|
||||||
# Initialize Q-values for all possible actions in the current state
|
|
||||||
self.q_table[curr_state] = {window_size: 0 for window_size in self.window_sizes}
|
|
||||||
|
|
||||||
# Update the Q-value using the Q-learning update rule
|
|
||||||
max_q_value = max(self.q_table[curr_state].values()) # Get the maximum Q-value for the current state
|
|
||||||
self.q_table[prev_state][prev_action] += self.alpha * (reward + self.gamma * max_q_value - self.q_table[prev_state][prev_action])
|
|
||||||
|
|
||||||
# Create the Mininet network with custom topology
|
|
||||||
def create_network():
|
|
||||||
topo = MyTopology()
|
|
||||||
net = Mininet(topo=topo)
|
|
||||||
net.start()
|
|
||||||
return net
|
|
||||||
|
|
||||||
# Main function
|
|
||||||
if __name__ == '__main__':
|
|
||||||
setLogLevel('info')
|
|
||||||
|
|
||||||
# Create the Mininet network
|
|
||||||
net = create_network()
|
|
||||||
|
|
||||||
# Instantiate TCP and RL agents
|
|
||||||
tcp_agent = MyTCPAgent()
|
|
||||||
tunnels = ['myPrivate1']
|
|
||||||
tunnel_agent = TunnelSelectionAgent(tunnels)
|
|
||||||
window_agent = WindowPredictionAgent()
|
|
||||||
|
|
||||||
# Perform TCP connection establishment
|
|
||||||
tcp_agent.handle_connection()
|
|
||||||
|
|
||||||
# Perform data transfer with RL-based tunnel selection and window prediction
|
|
||||||
start_time = time.time()
|
|
||||||
|
|
||||||
while True:
|
|
||||||
if time.time() - start_time > 10: # End packet exchange after <X> seconds
|
|
||||||
break
|
|
||||||
tunnel = tunnel_agent.select_tunnel()
|
|
||||||
window_size = window_agent.predict_window_size()
|
|
||||||
|
|
||||||
# Perform data transfer
|
|
||||||
tcp_agent.handle_data_transfer(tunnel, window_size)
|
|
||||||
|
|
||||||
# Update RL agents based on rewards
|
|
||||||
reward = 0.5 # Actual reward value
|
|
||||||
tunnel_agent.update_policy(reward)
|
|
||||||
# window_agent.update_policy(reward)
|
|
||||||
|
|
||||||
# Stop the Mininet network
|
|
||||||
net.stop()
|
|
||||||
|
|
||||||
# Plot Transmission Round versus Congestion Window Size
|
|
||||||
plt.plot(tcp_agent.transmission_rounds, tcp_agent.congestion_window_sizes)
|
|
||||||
plt.xlabel('Transmission Round')
|
|
||||||
plt.ylabel('Congestion Window Size')
|
|
||||||
plt.title('TCP+RL Window Prediction')
|
|
||||||
plt.show()
|
|
||||||
@@ -15,7 +15,7 @@ pip3 install colorama
|
|||||||
pip3 install mininet
|
pip3 install mininet
|
||||||
pip3 install ryu
|
pip3 install ryu
|
||||||
pip3 install --upgrade pip
|
pip3 install --upgrade pip
|
||||||
pip install pillow
|
pip3 install pillow
|
||||||
pip3 install matplotlib
|
pip3 install matplotlib
|
||||||
sudo apt-get install mininet
|
sudo apt-get install mininet
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user