Remove controller_1_3 and replace it with controller_1_3_1

This commit is contained in:
2022-05-29 20:59:16 +02:00
parent 26b35cc2e5
commit 2965053154
3 changed files with 61 additions and 557 deletions

View File

@@ -1,3 +1,6 @@
# Abgabe von:
# Jutta Seth, Janek Schoffit, Eva Hoegner
# Problem 1.3 (IP Router for IPv4)
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
@@ -11,10 +14,14 @@ from ryu.lib.packet import icmp
from ryu.lib.packet.arp import arp
from ryu.lib.packet.packet import Packet
# For IP address subnet matching
import ipaddress
class L3Switch(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
IP_ADDR = ["10.0.1.14", "10.0.2.254", "10.0.2.252", "10.0.3.62", "10.0.4.2"]
IP_ADDR = ["10.0.2.254", "10.0.2.252", "10.0.1.14", "10.0.3.62", "10.0.4.2"]
MAC_ADDR = ["52:00:00:00:00:01", "52:00:00:00:00:02"]
def __init__(self, *args, **kwargs):
@@ -40,30 +47,6 @@ class L3Switch(app_manager.RyuApp):
ofproto.OFPCML_NO_BUFFER)]
self.add_flow(datapath, 0, match, actions)
self.logger.info("Add new action for: ")
self.logger.info(datapath.id)
# Routing Switch 2 to 1
if datapath.id == 2:
actions = [parser.OFPActionDecNwTtl(), #decrease TTL count
parser.OFPActionSetField(eth_src=self.MAC_ADDR[1]), # set own mac as source
parser.OFPActionSetField(eth_dst=self.MAC_ADDR[0]), # set dst switch
parser.OFPActionOutput(1)]
match = parser.OFPMatch(ipv4_src=("10.0.4.1", "255.255.255.252"), ipv4_dst=("10.0.1.1", "255.255.255.240"), eth_type=0x0800)
#match = parser.OFPMatch(ipv4_src="10.0.4.1", ipv4_dst="10.0.1.1", eth_type=0x0800)
self.add_flow(datapath, 0, match, actions)
# Routing Switch 1 to 2
if datapath.id == 1:
actions = [parser.OFPActionDecNwTtl(), #decrease TTL count
parser.OFPActionSetField(eth_src=self.MAC_ADDR[0]), # set own mac as source
parser.OFPActionSetField(eth_dst=self.MAC_ADDR[1]), # set dst switch
parser.OFPActionOutput(4)]
match = parser.OFPMatch(ipv4_dst=("10.0.4.1", "255.255.255.252"), eth_type=0x0800)
self.add_flow(datapath, 0, match, actions)
def add_flow(self, datapath, priority, match, actions, buffer_id=None):
ofproto = datapath.ofproto
@@ -109,16 +92,17 @@ class L3Switch(app_manager.RyuApp):
dpid = datapath.id
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
macaddr = self.MAC_ADDR[dpid-1]
arpPacket = packet.get_protocol(arp)
if arpPacket.opcode == 1 :
# arp request
arp_dstIp = arpPacket.dst_ip
self.logger.info('received ARP Request %s => %s (port%d)'%(frame.src, frame.dst, inPort))
self.logger.info('received ARP Request %s => %s (port%d, ip: %s)'%(frame.src, frame.dst, inPort, arp_dstIp))
if arp_dstIp in self.IP_ADDR:
# this switch was requested
opcode = 2
srcMAC = self.MAC_ADDR[dpid-1]
srcMAC = macaddr
srcIP = arp_dstIp
dstMAC = frame.src
dstIP = arpPacket.src_ip
@@ -191,13 +175,14 @@ class L3Switch(app_manager.RyuApp):
self.send_packet(datapath, outPort, p)
def do_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp):
dpid = datapath.id
self.logger.info(pkt_icmp.type)
self.logger.info(icmp.ICMP_ECHO_REQUEST)
if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST:
return
pkt = packet.Packet()
pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
dst=pkt_ethernet.src,
src=self.MAC_ADDR[dpid]))
src=self.MAC_ADDR[datapath.id-1]))
pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,
src=pkt_ipv4.dst,
proto=pkt_ipv4.proto))
@@ -205,7 +190,8 @@ class L3Switch(app_manager.RyuApp):
code=icmp.ICMP_ECHO_REPLY_CODE,
csum=0,
data=pkt_icmp.data))
self.logger.info("do icmp: %s" %(pkt))
self.logger.info("do icmp: %s" %(pkt,))
self.logger.info("port: %s" %(port))
self.send_packet(datapath, port, pkt)
def do_l2_switch(self, datapath, dpid, packet, frame, in_port, buffer_id=None):
@@ -242,21 +228,59 @@ class L3Switch(app_manager.RyuApp):
parser = datapath.ofproto_parser
if ipv4_pkt.dst in self.ip_to_mac[dpid]:
# GEt mac and port of the given destination
# Get mac and port of the given destination
dstMac = self.ip_to_mac[dpid][ipv4_pkt.dst]
out_port = self.mac_to_port[dpid][dstMac]
else:
# This flow is for the second switch if the address is in range 10.0.0.0-10.0.3.255
# The ipaddress module assumes an IP adress as a unicode string (python 2.7 default for a string is ascii encoding)
if datapath.id == 2 and ipaddress.ip_address(unicode(ipv4_pkt.dst)) in ipaddress.ip_network(unicode("10.0.0.0/22")):
actions = [parser.OFPActionDecNwTtl(), #decrease TTL count
parser.OFPActionSetField(eth_src=self.MAC_ADDR[1]), # set own mac as source
parser.OFPActionSetField(eth_dst=self.MAC_ADDR[0]), # set dst switch
parser.OFPActionOutput(2)]
match = parser.OFPMatch(ipv4_dst=("10.0.0.0", "255.255.252.0"), eth_dst=self.MAC_ADDR[1], eth_type=0x0800)
self.add_flow(datapath, 1, match, actions)
data = None
if buffer_id == ofproto.OFP_NO_BUFFER:
data = packet.data
out = parser.OFPPacketOut(datapath=datapath, buffer_id=buffer_id,
in_port=in_port, actions=actions, data=data)
datapath.send_msg(out)
return
# Add a flow for the first switch if the ipadress matches network 4.
if datapath.id == 1 and ipaddress.ip_address(unicode(ipv4_pkt.dst)) in ipaddress.ip_network(unicode("10.0.4.0/30")):
actions = [parser.OFPActionDecNwTtl(), #decrease TTL count
parser.OFPActionSetField(eth_src=self.MAC_ADDR[0]), # set own mac as source
parser.OFPActionSetField(eth_dst=self.MAC_ADDR[1]), # set dst switch
parser.OFPActionOutput(1)]
match = parser.OFPMatch(ipv4_dst=("10.0.4.0", "255.255.255.252"), eth_dst=self.MAC_ADDR[0], eth_type=0x0800)
self.add_flow(datapath, 1, match, actions)
data = None
if buffer_id == ofproto.OFP_NO_BUFFER:
data = packet.data
out = parser.OFPPacketOut(datapath=datapath, buffer_id=buffer_id,
in_port=in_port, actions=actions, data=data)
datapath.send_msg(out)
return
# Send an arp request and define mac and port
# so we're able to apply the following actions
# on the packet.
out_port = ofproto.OFPP_FLOOD
dstMac = "FF:FF:FF:FF:FF:FF"
self.send_arp(datapath, 1, self.MAC_ADDR[dpid-1], ipv4_pkt.src, dstMac, ipv4_pkt.dst, out_port)
self.send_arp(datapath, 1, self.MAC_ADDR[datapath.id-1], ipv4_pkt.src, dstMac, ipv4_pkt.dst, out_port)
# Actions are applied in the same order as defined in the list.
# OFPActionOutput terminates the chain. So this call should be the last action.
actions = [parser.OFPActionDecNwTtl(), #decrease TTL count
parser.OFPActionSetField(eth_src=self.MAC_ADDR[1]), # set own mac as source
parser.OFPActionSetField(eth_src=self.MAC_ADDR[datapath.id-1]), # set own mac as source
parser.OFPActionSetField(eth_dst=dstMac), # set dst from arp request
parser.OFPActionOutput(out_port)] # forward packet through out_port
@@ -313,17 +337,18 @@ class L3Switch(app_manager.RyuApp):
self.logger.info("packet in dpid: %s, src: %s, dest: %s, in_port: %s", dpid, src, dst, in_port)
self.logger.info(pkt)
#self.logger.info(pkt)
#learn mac to port mapping
if src not in self.mac_to_port[dpid]:
self.mac_to_port[dpid][src] = in_port
if eth.ethertype == ether_types.ETH_TYPE_ARP:
if eth.ethertype == ether_types.ETH_TYPE_ARP and src not in self.MAC_ADDR:
self.do_arp(datapath, pkt, eth, in_port)
return
if eth.ethertype == ether_types.ETH_TYPE_IP:
ipv4_pkt = pkt.get_protocol(ipv4.ipv4)
self.logger.info("IP src: %s, dst: %s", ipv4_pkt.src, ipv4_pkt.dst)
#check if packet is for this switch
if ipv4_pkt.dst in self.IP_ADDR:
@@ -333,11 +358,10 @@ class L3Switch(app_manager.RyuApp):
else:
# forward the package into a different subnet
self.do_l3_switch(datapath, dpid, pkt, eth, ipv4_pkt, in_port, msg.buffer_id)
return
# packet is not for this switch, so do l2 switching
if dst != self.MAC_ADDR[dpid - 1]:
if dst != self.MAC_ADDR[dpid-1]:
self.do_l2_switch(datapath, dpid, pkt, eth, in_port, msg.buffer_id)
return
return