Mininet拓扑没有从由2个交换机分隔的2个主机完成iperf命令



我正试图在这个网站上完成mininet拓扑练习https://github.com/mininet/openflow-tutorial/wiki/Advanced-Topology.基本上,我必须创建这样一个拓扑:

h1-----s1--s2-h3

(还有另一个主机连接到s1,称为h2(

并对POX控制器进行编程以将流安装到交换机,使得CCD_ 1和CCD_。除了iperf命令在从h1到h3或从h2到h3运行时失败外,其他一切都很好。

这是我的代码,我认为问题与正确的交换机通信有关,该如何处理不同于arpicmp类型的数据包,但我在这个问题上纠缠太久了,决定在这里寻求帮助。

from pox.core import core
import pox.openflow.libopenflow_01 as of
import pox.lib.packet as pkt #ipv4, arp..
import pox.lib.addresses as adr #EthAddr , IPAddr ..
log = core.getLogger()

class Tutorial (object):
def __init__ (self, connection):
# Keep track of the connection to the switch so that we can
# send it messages!
self.connection = connection
# This binds our PacketIn event listener
connection.addListeners(self)
self.dpid_table = {'10.0.1.1': 1, '10.0.2.1': 2}
# Use this table to keep track of which ethernet address is on
# which switch port (keys are MACs, values are ports).
self.ip_to_port = {'10.0.1.2':1, '10.0.1.3':2, '10.0.2.2':3}
self.mac_to_port = {}
self.routing_table = {
'10.0.1.0/24': [['10.0.1.2', 's1-eth1', '10.0.1.1', 1, '00:00:00:00:00:01'],
['10.0.1.3', 's1-eth2', '10.0.1.1', 2, '00:00:00:00:00:02']],
'10.0.2.0/24': ['10.0.2.2', 's2-eth1', '10.0.2.1', 3, '00:00:00:00:00:03'],
}
def FlowMode(self, packet_in, out_port):
print("Creating Flow...")
msg = of.ofp_flow_mod()
msg.match.in_port = packet_in.in_port
#msg_match = of.ofp_match(dl_type = pkt.ethernet.IP_TYPE, nw_proto = pkt.ipv4.IPv4)
msg.idle_timeout = 15
msg.buffer_id = packet_in.buffer_id
action = of.ofp_action_output(port = out_port)
msg.actions.append(action)
self.connection.send(msg)
print("flow created")
def act_like_router (self, packet, packet_in):
#handle ARP Requests and replies
etherPayload = packet.payload #the stripped ethFrame, contains ipv4 or arp packet
if packet.type == pkt.ethernet.ARP_TYPE:
#etherPayload is an ARP packet
src_ip = etherPayload.protosrc
dst_ip = etherPayload.protodst
if etherPayload.opcode == pkt.arp.REQUEST:
print("ARP REQUEST received by controller....n Constructing reply...")
arp_reply = pkt.arp()
arp_reply.hwsrc = adr.EthAddr("11:12:13:14:15:16") #fake mac in response
arp_reply.hwdst = etherPayload.hwsrc
arp_reply.opcode = pkt.arp.REPLY
arp_reply.protosrc = etherPayload.protodst
arp_reply.protodst = etherPayload.protosrc
#encapsulate in ethernet frame now
ether = pkt.ethernet()
ether.type = pkt.ethernet.ARP_TYPE
ether.dst = packet.src
ether.src = packet.dst
ether.payload = arp_reply
msg = of.ofp_packet_out()
msg.data = ether.pack()
action = of.ofp_action_output(port = packet_in.in_port)
msg.actions.append(action)
self.connection.send(msg)
#send to switch, will have to implement flow instead
#self.resend_packet(ether, packet_in.in_port)
print("ARP Reply sent!")
elif etherPayload.opcode == pkt.arp.REPLY:
if src_ip not in self.arp_table:
self.arp_table[str(src_ip)] = etherPayload.hwsrc
self.mac_to_port[etherPayload.hwsrc] = packet_in.in_port
print("ARP REPLY received by controller updating tables")
print(self.mac_to_port)
print(self.arp_table)
#else:
#self.mac_to_port[etherPayload.hwsrc] = packet_in.in_port
else:
print("some other ARP OPCODE received")
elif packet.type == pkt.ethernet.IP_TYPE:
#etherPayload is an IP packet
if etherPayload.protocol == pkt.ipv4.ICMP_PROTOCOL:
icmp_packet = etherPayload.payload
if icmp_packet.type == pkt.TYPE_ECHO_REQUEST:
print("received ping request...n creating echo_reply message")
src_ip = etherPayload.srcip
dst_ip = etherPayload.dstip
k = 0
#check if destination exist in any of the subnets
for subnet in self.routing_table.keys():
if dst_ip.inNetwork(subnet): #possible mistake here maybe turn dst_ip into IPADDR obj
k = subnet
break
if k!=0:
#host exists create and send echo reply
print('Sending reply to network  ' + str(k))
#create echo fields
ech = pkt.echo() #echo contained in pkt.icmp
ech.id = icmp_packet.payload.id
ech.seq = icmp_packet.payload.seq + 1
#encapsulates in icmp
icmp_reply = pkt.icmp()
icmp_reply.type = pkt.TYPE_ECHO_REPLY #code 0
icmp_reply.payload = ech
#encapsulates in ipv4
ip_p = pkt.ipv4()
ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL
ip_p.srcip = dst_ip
ip_p.dstip = src_ip
ip_p.payload = icmp_reply
#encapsulates in ethernet
eth_p = pkt.ethernet()
eth_p.type = pkt.ethernet.IP_TYPE
eth_p.src = packet.dst
eth_p.dst = packet.src
eth_p.payload = ip_p
msg = of.ofp_packet_out()
msg.data = eth_p.pack()
action = of.ofp_action_output(port = packet_in.in_port)
print("sending reply from: " + str(dst_ip) + " to: " + str(src_ip) + " using packet_in.in_port: " + str(packet_in.in_port))
msg.actions.append(action)
self.connection.send(msg)
#send to switch, will have to implement flow instead
#self.resend_packet(eth_p, packet_in.in_port)
print("echo Reply sent!")

else:
#host doesn't exist send dst unreachable
print("ICMP destination unreachable")
unr = pkt.unreach()
unr.payload = etherPayload
icmp_reply = pkt.icmp()
icmp_reply.type = pkt.TYPE_DEST_UNREACH
icmp_reply.payload = unr
ip_p = pkt.ipv4()
ip_p.srcip = dst_ip
ip_p.dstip = src_ip
ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL
ip_p.payload = icmp_reply
eth_p = pkt.ethernet()
eth_p.type = pkt.ethernet.IP_TYPE
eth_p.dst = packet.src
eth_p.src = packet.dst
eth_p.payload = ip_p
msg = of.ofp_packet_out()
msg.data = eth_p.pack()
action = of.ofp_action_output(port = packet_in.in_port)
#print("sending reply from: " + str(dst_ip) + " to: " + str(src_ip) + " using packet_in.in_port: " + str(packet_in.in_port))
msg.actions.append(action)
self.connection.send(msg)
#send to switch, will have to implement flow instead
#self.resend_packet(eth_p, packet_in.in_port)
log.debug("echo Reply sent!")
#se non e` ICMP
else:
print("received some ip packet...n handling it... ")
src_ip = etherPayload.srcip
dst_ip = etherPayload.dstip
k = 0
#check if destination exist in any of the subnets
'''
self.routing_table = {
'10.0.1.0/24': ['10.0.1.2', 's1-eth1', '10.0.1.1', 1, '00:00:00:00:00:02'],
['10.0.1.3', 's1-eth2', '10.0.1.1', 2, '00:00:00:00:00:03']
'''
for subnet in self.routing_table.keys():
if dst_ip.inNetwork(subnet):
k = subnet
break
if k!=0:
port1 = self.ip_to_port[str(dst_ip)] #get port to communicate on that subnet
if str(dst_ip) == '10.0.1.2':
#ethDest = adr.EthAddr("4e:2d:32:b9:bc:52")
ethDest = adr.EthAddr(self.routing_table[subnet][0][4])
msg = of.ofp_packet_out()
action = of.ofp_action_output(port = port1)
packet.src = packet.dst
packet.dst = ethDest#adr.EthAddr('11:11:11:11:11:11')#ethDest
msg.data = packet.pack()
msg.actions.append(action)
self.connection.send(msg)
print("installing flow for packets for: " + str(dst_ip))
self.FlowMode(packet_in, packet_in.in_port)
elif str(dst_ip) == '10.0.1.3':
#ethDest = adr.EthAddr("22:02:eb:9c:27:2d")
ethDest = adr.EthAddr(self.routing_table[subnet][1][4])
msg = of.ofp_packet_out()
action = of.ofp_action_output(port = port1)
packet.src = packet.dst
packet.dst = ethDest#adr.EthAddr('11:11:11:11:11:11')#ethDest
msg.data = packet.pack()
msg.actions.append(action)
self.connection.send(msg)
print("installing flow for packets for: " + str(dst_ip))
self.FlowMode(packet_in, packet_in.in_port)
elif str(dst_ip) == '10.0.2.2':
ethDest = adr.EthAddr(self.routing_table[subnet][4])
if packet_in.in_port == 1 and self.connection.dpid == 1:
outport = 3
msg = of.ofp_packet_out()
action = of.ofp_action_output(port = outport)
packet.src = packet.dst
packet.dst = ethDest
msg.data = packet.pack()
msg.actions.append(action)
self.connection.send(msg)
print("installing flow for packets for: " + str(dst_ip) + " to switch number: " + str(connection.dpid)
+ str(etherPayload.id))
self.FlowMode(packet_in, packet_in.in_port)
elif (packet_in.in_port == 2 or packet_in.in_port == 3)  and self.connection.dpid == 1:
outport = 1
msg = of.ofp_packet_out()
action = of.ofp_action_output(port = outport)
packet.src = packet.dst
packet.dst = ethDest
msg.data = packet.pack()
msg.actions.append(action)
self.connection.send(msg)
print("installing flow for packets for: " + str(dst_ip) + " to switch number: " + str(self.connection.dpid)
+ str(etherPayload.id))
self.FlowMode(packet_in, packet_in.in_port)
elif packet_in.in_port == 1 and self.connection.dpid == 2:
outport = 3
msg = of.ofp_packet_out()
action = of.ofp_action_output(port = outport)
packet.src = packet.dst
packet.dst = ethDest
msg.data = packet.pack()
msg.actions.append(action)
self.connection.send(msg)
print("installing flow for packets for: " + str(dst_ip) + " to switch number: " + str(self.connection.dpid)
+ str(etherPayload.id))
self.FlowMode(packet_in, packet_in.in_port)
elif(packet_in.in_port == 2 or packet_in.in_port == 3)  and self.connection.dpid == 2:
outport = 1
msg = of.ofp_packet_out()
action = of.ofp_action_output(port = outport)
packet.src = packet.dst
packet.dst = ethDest
msg.data = packet.pack()
msg.actions.append(action)
self.connection.send(msg)
print("installing flow for packets for: " + str(dst_ip) + " to switch number: " + str(self.connection.dpid)
+ str(etherPayload.id))
self.FlowMode(packet_in, packet_in.in_port)

'''
router_msg = of.ofp_flow_mod()
router_msg.match = of.ofp_match.from_packet(packet)
router_msg.idle_timeout = 100
router_msg.buffer_id = packet_in.buffer_id
action = of.ofp_action_output(port = packet_in.in_port)
router_msg.actions.append(action)
self.connection.send(router_msg)
'''


#don't forget flow mode

def _handle_PacketIn (self, event):
"""
Handles packet in messages from the switch.
"""
packet = event.parsed # This is the ethernet packet.
if not packet.parsed:
log.warning("Ignoring incomplete packet")
return
packet_in = event.ofp # The actual ofp_packet_in message.


self.act_like_router(packet, packet_in)
def resend_packet(self, packet_in, out_port):
"""
Instructs the switch to resend a packet that it had sent to us.
"packet_in" is the ofp_packet_in object the switch had sent to the
controller due to a table-miss.
"""
msg = of.ofp_packet_out()
msg.data = packet_in.pack()
# Add an action to send to the specified port
action = of.ofp_action_output(port=out_port)
msg.actions.append(action)
# Send message to switch
self.connection.send(msg)

def launch ():
"""
Starts the component
"""
def start_switch (event):
log.debug("Controlling %s" % (event.connection,))
Tutorial(event.connection)
core.openflow.addListenerByName("ConnectionUp", start_switch)

编辑:

我通过将指向h3的IP_packets洪泛到除in_port 之外的所有端口来解决此问题

最新更新