def act_like_l2switch(self, event, packet): dst_port = None self.hwadr2Port[packet.src] = event.port if packet.dst not in (ETHER_ANY, ETHER_BROADCAST) and not packet.dst.is_multicast: dst_port = self.hwadr2Port.get(packet.dst, None) if dst_port is None: packet_in = event.ofp match = of.ofp_match.from_packet(packet) msg = of.ofp_flow_mod() msg = of.ofp_packet_out() msg.data = packet_in #log.debug("match info at %s: %s"%(self.name, match)) # Add an action to send to the specified port action = of.ofp_action_output(port = of.OFPP_ALL) msg.actions.append(action) # Send message to switch self.connection.send(msg) else: msg = of.ofp_flow_mod() msg.match.dl_dst = packet.src msg.match.dl_src = packet.dst msg.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(msg) # This is the packet that just came in -- we want to # install the rule and also resend the packet. msg = of.ofp_flow_mod() msg.data = event.ofp # Forward the incoming packet msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.actions.append(of.ofp_action_output(port = dst_port)) event.connection.send(msg)
def _handle_PortStatus(event): #print event.dpid, event.port #print event.added, event.deleted, event.modified #print event.dpid, event.port, type(event.ofp.desc.state),type(of.OFPPC_PORT_DOWN) if event.ofp.desc.state == 1 and of.OFPPC_PORT_DOWN == 1: #a link goes down downSwitch = 's' + str(event.dpid) downPort = event.port brokenLink = DpidPortLink[(downSwitch, downPort)] #print linkTopo[brokenLink] if brokenLink not in linkTopo: return print "Warning: port failure happening on port" + str(event.port) + " on switch " + str(event.dpid) + " -- Updating flow rules." msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) for connection in core.openflow.connections: connection.send(msg) for connection in core.openflow.connections: currSwitch = Dpid_To_Ip[connection.dpid] for host in linkTopo[brokenLink].hosts: portNum = linkTopo[brokenLink].GetPortNumAndMacAddr(currSwitch,host)#get the destination IP address of the host, get its MAC address from the arpTable. MacAddr = arpTable[getValue(host)[0]] msg = of.ofp_flow_mod() msg.match.dl_type = 0x800 msg.match.nw_dst = IPAddr(getValue(host)[0]) msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(MacAddr))) msg.actions.append(of.ofp_action_output(port = portNum)) connection.send(msg)
def listarFluxosIp(event): global fluxosIp global listaIDS fluxosIp = [] if ipBro != None: for fluxo in event.stats: #print 'Um dos Fluxos Atuais' #print fluxo.match if fluxo.match.nw_src == IPAddr(ipBro): fluxosIp.append(fluxo.match) msg = of.ofp_flow_mod() msg.match = fluxo.match msg.idle_timeout = 60 msg.hard_timeout = 60 msg.priority = 65535 event.connection.send(msg) removerFluxo(listaIDS, fluxo.match) print 'Fluxo barrado' print listaIDS #print fluxo.match msg = of.ofp_flow_mod() msg.match.dl_type = 0x800 msg.match.nw_src = IPAddr(ipBro) msg.idle_timeout = 60 msg.hard_timeout = 60 msg.priority = 65535 event.connection.send(msg)
def flow_add(): my_match = of.ofp_match() my_match.nw_src = IPAddr("10.0.0.2") my_match.nw_dst = IPAddr("10.0.0.3") my_match.dl_type=0x800 msg = of.ofp_flow_mod() msg.match = my_match msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.4"))) log.info("msg builded") for conn in core.openflow.connections: log.info("in connections loop") conn.send(msg) match_2 = of.ofp_match() match_2.nw_src = IPAddr("10.0.0.1") match_2.nw_dst = IPAddr("10.0.0.4") match_2.dl_type = 0x800 msg2 = of.ofp_flow_mod() msg2.match = match_2 msg2.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr("10.0.0.4"))) for conn in core.openflow.connections: conn.send(msg2) match3 = of.ofp_match() match3.nw_src = IPAddr("10.0.0.4") match3.nw_dst = IPAddr("10.0.0.1") match3.dl_type = 0x800 msg3 = of.ofp_flow_mod() msg3.match = match3 msg3.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr("10.0.0.2"))) for conn in core.openflow.connections: conn.send(msg3)
def _handle_ConnectionUp(self, event): # Use dpid to differentiate between switches (datapath-id) # Each switch has its own flow table. As we'll see in this # example we need to write different rules in different tables. # dpid = dpidToStr(event.dpid) log.debug("Slice for Switch %s ...", event.dpid) """ Add your logic here """ # h1 h4 if event.dpid == 1 or event.dpid == 4: msg = of.ofp_flow_mod() msg.priority = 65500 msg.match.in_port = 3 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg.match.in_port = 1 msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg.match.in_port = 4 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg.match.in_port = 2 msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) # h2 h3 if event.dpid == 2 or event.dpid == 3: msg = of.ofp_flow_mod() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_pytap (event): # packet is an instance of class 'pox.lib.packet.ethernet.ethernet' packet = event.parsed print packet.dst, packet.src # # Learn the source srcPort = event.port if srcPort == 1 or srcPort == 2: # build the flow from port 1 to port 2 forwardFlow = of.ofp_flow_mod() forwardFlow.idle_timeout = 120 forwardFlow.hard_timeout = 120 forwardFlow.match.in_port = 1 forwardFlow.actions.append(of.ofp_action_output(port=2)) event.connection.send(forwardFlow) # build the flow from port 2 to port 1 returnFlow = of.ofp_flow_mod() returnFlow.idle_timeout = 120 returnFlow.hard_timeout = 120 returnFlow.match.in_port = 2 returnFlow.actions.append(of.ofp_action_output(port=1)) event.connection.send(returnFlow) log.debug("Installing flow from Port 1 to Port 2")
def _handle_ConnectionUp (self, event): ''' Add your logic here ... ''' policyFileContent = open(policyFile) policyFileContent.readline() while True: line = policyFileContent.readline() if not line: break print line info = line.split(',') info[2].strip('\n') msg = of.ofp_flow_mod() msg_mirror = of.ofp_flow_mod() msg.priority = msg_mirror.priority = 42 #msg.idle_timeout = 100 #msg.hard_timeout = 200 msg.match.dl_type = msg_mirror.match.dl_type = 0x0800 msg.match.dl_src = EthAddr(info[1]) msg_mirror.match.dl_dst = EthAddr(info[1]) msg.match.dl_dst = EthAddr(info[2]) msg_mirror.match.dl_src = EthAddr(info[2]) #msg.actions.append(of.ofp_action_output(port=OFPP_NONE)) event.connection.send(msg) event.connection.send(msg_mirror) print log.debug("Firewall rules installed on %s", dpidToStr(event.dpid))
def fwd(target, duration=(RULE_DURATION_SEC, RULE_DURATION_SEC)): if not isinstance(duration, tuple): duration = (duration, duration) # srcip -> dstip msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.actions.append(of.ofp_action_nw_addr.set_dst(target)) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg) # target -> srcip msg = of.ofp_flow_mod() msg.match = of.ofp_match(dl_type=0x800, nw_src=target, nw_dst=ip.srcip) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.actions.append(of.ofp_action_nw_addr.set_src(ip.dstip)) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg) # send this pkt msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_nw_addr.set_dst(target)) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.data = event.ofp msg.in_port = event.port event.connection.send(msg)
def _install (self, switch, in_port, out_port, match, buf = None, tree = False, mod_eth = False): if tree: msg = of.ofp_flow_mod() msg.match = match if in_port != None: msg.match.in_port = in_port msg.idle_timeout = FLOW_IDLE_TIMEOUT msg.hard_timeout = FLOW_HARD_TIMEOUT #log.debug('Out ports: %s:%s', str(switch), str(out_port)) if mod_eth: msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr('ff:ff:ff:ff:ff:ff'))) msg.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr('255.255.255.255'))) for op in out_port: msg.actions.append(of.ofp_action_output(port = op)) msg.buffer_id = buf switch.connection.send(msg) else: msg = of.ofp_flow_mod() msg.match = match msg.match.in_port = in_port msg.idle_timeout = FLOW_IDLE_TIMEOUT msg.hard_timeout = FLOW_HARD_TIMEOUT msg.actions.append(of.ofp_action_output(port = out_port)) msg.buffer_id = buf switch.connection.send(msg)
def installL2Pair(self,event,port): '''If packet reaches installL2Pair, there's no match''' packet = event.parsed eth = packet.find('ethernet') # First, install the 'packet response' entry msg = of.ofp_flow_mod() msg.idle_timeout = FLOW_TIMEOUT msg.hard_timeout = 5*FLOW_TIMEOUT msg.match.dl_type = eth.type msg.match.dl_src = eth.dst msg.match.dl_dst = eth.src msg.match.in_port = port msg.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(msg) # Then install forwarding rule and send packet msg = of.ofp_flow_mod() msg.idle_timeout = FLOW_TIMEOUT msg.hard_timeout = 5*FLOW_TIMEOUT msg.data = event.ofp msg.match.dl_type = eth.type msg.match.dl_src = eth.src msg.match.dl_dst = eth.dst msg.match.in_port = event.port msg.actions.append(of.ofp_action_output(port = port)) event.connection.send(msg)
def _handle_PacketIn (event): packet = event.parsed # Learn the source table[(event.connection,packet.src)] = event.port dst_port = table.get((event.connection,packet.dst)) if dst_port is None: # We don't know where the destination is yet. So, we'll just # send the packet out all ports (except the one it came in on!) # and hope the destination is out there somewhere. :) msg = of.ofp_packet_out(data = event.ofp) msg.actions.append(of.ofp_action_output(port = all_ports)) event.connection.send(msg) else: # Since we know the switch ports for both the source and dest # MACs, we can install rules for both directions. msg = of.ofp_flow_mod() msg.match.dl_dst = packet.src msg.match.dl_src = packet.dst msg.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(msg) # This is the packet that just came in -- we want to # install the rule and also resend the packet. msg = of.ofp_flow_mod() msg.data = event.ofp # Forward the incoming packet msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.actions.append(of.ofp_action_output(port = dst_port)) event.connection.send(msg) log.debug("Installing %s <-> %s" % (packet.src, packet.dst))
def _handle_PacketIn_portmod(self, event): data, eth_packet, vlan_packet, ip_packet, tcp_packet = self.parsePacket(event) # print "*** " + str(eth_packet) + " " + str(vlan_packet) + " " + str(ip_packet) # Switch the request over to 5001 if tcp_packet and tcp_packet.dstport == 5000: match_clause = of.ofp_match.from_packet(eth_packet, event.port) dst_mac = eth_packet.dst out_port = self.lookup_port_for_mac(dst_mac) if out_port: set_dst_action_clause = of.ofp_action_tp_port.set_dst(5001); output_action_clause = of.ofp_action_output(port=out_port) action_clauses = [set_dst_action_clause, output_action_clause] msg = of.ofp_flow_mod(match=match_clause, actions=action_clauses) self._connection.send(msg) # Switch to response back to 5000 elif tcp_packet and tcp_packet.srcport == 5001: match_clause = of.ofp_match.from_packet(eth_packet, event.port) dst_mac = eth_packet.dst out_port = self.lookup_port_for_mac(dst_mac) if out_port: set_dst_action_clause = of.ofp_action_tp_port.set_src(5000); output_action_clause = of.ofp_action_output(port=out_port) action_clauses = [set_dst_action_clause, output_action_clause] msg = of.ofp_flow_mod(match=match_clause, actions=action_clauses) self._connection.send(msg) # Oherwise (not part of this test), handle the packet as is else: SimpleLearningSwitch._handle_PacketIn(self, event)
def verifyIdentity(self, mac_addr): """ retry authentication to check if is the same user who send packets """ mac_addr = checkMac(mac_addr) self.authenticatedToProgress(mac_addr) port = self.host_progress[mac_addr]['port'] #Ajout de 2 flux pour la gestion de 802.1x msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type= 0x888e msg.match.in_port = port msg.match.dl_src = mac_addr msg.priority = 200 action = of.ofp_action_output( port = of.OFPP_CONTROLLER ) msg.actions.append(action) self.connection.send(msg) self.host_progress[mac_addr]['match'].append(msg.match) msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = 0x888e msg.match.in_port= of.OFPP_CONTROLLER msg.match.dl_dst = mac_addr action = of.ofp_action_output( port = port) msg.actions.append(action) msg.priority = 200 self.connection.send(msg) self.host_progress[mac_addr]['match'].append(msg.match) self.sendRequestIdentity(mac_addr, self.host_progress[mac_addr]['port'])
def _handle_ConnectionUp (self, event): policies = self.read_policies(policyFile) for policy in policies.itervalues(): # TODO: implement the code to add a rule to block the flow # between the source and destination specified in each policy # Note: The policy data structure has two fields which you can # access to turn the policy into a rule. policy.dl_src will # give you the source mac address and policy.dl_dst will give # you the destination mac address # Note: Set the priority for your rule to 20 so that it # doesn't conflict with the learning bridge setup fm1 = of.ofp_flow_mod() fm1.priority = 20 fm1.match.dl_src = policy.dl_src fm1.match.dl_dst = policy.dl_dst event.connection.send(fm1) fm2 = of.ofp_flow_mod() fm2.priority = 20 fm2.match.dl_src = policy.dl_dst fm2.match.dl_dst = policy.dl_src event.connection.send(fm2) log.debug("Firewall rules installed on %s", dpidToStr(event.dpid))
def _install_monitoring_path(prev_path, adj): match = ofp_match_withHash() match.dl_src = struct.pack("!Q", prev_path.src)[2:] #convert dpid to EthAddr match.dl_dst = struct.pack("!Q", prev_path.dst)[2:] match.dl_type = pkt.ethernet.IP_TYPE match.nw_proto = 253 # Use for experiment and testing match.nw_dst = IPAddr("224.0.0.255") #IANA Unassigned multicast addres match.nw_src = IPAddr(prev_path.__hash__()) #path hash dst_sw = prev_path.dst cur_sw = prev_path.dst msg = of.ofp_flow_mod() msg.match = match msg.idle_timeout = 30 #msg.flags = of.OFPFF_SEND_FLOW_REM msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) log.debug("Installing monitoring forward from switch %s to controller port", util.dpid_to_str(cur_sw)) switches[dst_sw].connection.send(msg) next_sw = cur_sw cur_sw = prev_path.prev[next_sw] while cur_sw is not None: #for switch in path.keys(): msg = of.ofp_flow_mod() msg.match = match msg.idle_timeout = 10 #msg.flags = of.OFPFF_SEND_FLOW_REM log.debug("Installing monitoring forward from switch %s to switch %s output port %s", util.dpid_to_str(cur_sw), util.dpid_to_str(next_sw), adj[cur_sw][next_sw]) msg.actions.append(of.ofp_action_output(port = adj[cur_sw][next_sw])) switches[cur_sw].connection.send(msg) next_sw = cur_sw cur_sw = prev_path.prev[next_sw]
def _handle_ConnectionUp (self, event): policies = self.read_policies(policyFile) for policy in policies.itervalues(): # TODO: implement the code to add a rule to block the flow # between the source and destination specified in each policy # Note: The policy data structure has two fields which you can # access to turn the policy into a rule. policy.dl_src will # give you the source mac address and policy.dl_dst will give # you the destination mac address # Note: Set the priority for your rule to 20 so that it # doesn't conflict with the learning bridge setup #### Solution starts here: # Idea: If you don't specify any action in a openflow msg, # then matching packets will be dropped. # http://courses.engr.illinois.edu/cs538/assignments/a1.pdf match1 = of.ofp_match() match1.dl_src = policy.dl_src match1.dl_dst = policy.dl_dst msg1 = of.ofp_flow_mod() msg1.match = match1 event.connection.send(msg1) match2 = of.ofp_match() match2.dl_src = policy.dl_dst match2.dl_dst = policy.dl_src msg2 = of.ofp_flow_mod() msg2.match = match2 event.connection.send(msg2) log.debug("Firewall rules installed on %s", dpidToStr(event.dpid))
def flow_redirect (self, packet, packet_in): if packet.src not in self.mac_to_port: log.debug("==========> adding mac_to_port_entry: src = " + str(packet.src) + "; in_port = " + str(packet_in.in_port)) self.mac_to_port[packet.src] = packet_in.in_port if packet.dst == EthAddr("00:15:17:5d:13:6c"): log.debug("packet destination is node2, redirecting to node3...") msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 1200 msg.hard_timeout = 3600 msg.buffer_id = packet_in.buffer_id msg.priority = 65535 msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr("00:15:17:5d:33:64"))) msg.actions.append(of.ofp_action_output(port = 3)) # msg.data = event.ofp log.debug("==========> Installing flow... src = " + str(packet.src) + "; dest = " + str(packet.dst) + "; port = 3") #packet.dst = EthAddr("00:15:17:57:c6:f1") self.connection.send(msg) # self.resend_packet(packet_in, 3) elif packet.dst in self.mac_to_port: log.debug("==========> Installing flow... src = " + str(packet.src) + "; dest = " + str(packet.dst) + "; port = " + str(self.mac_to_port[packet.dst])) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 1200 msg.hard_timeout = 3600 msg.buffer_id = packet_in.buffer_id msg.actions.append(of.ofp_action_output(port = self.mac_to_port[packet.dst])) self.connection.send(msg) else: self.resend_packet(packet_in, of.OFPP_ALL)
def __init__(self, connection): self.connections = {} self.replicas = deque() self.connection = connection connection.addListeners(self) # Send UDP updates to the controller. fm = of.ofp_flow_mod() fm.priority = of.OFP_DEFAULT_PRIORITY fm.match.dl_type = pkt.ethernet.IP_TYPE fm.match.nw_dst = external_nw_addr fm.match.nw_proto = pkt.ipv4.UDP_PROTOCOL fm.match.tp_dst = update_tp_addr fm.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) self.connection.send(fm) # Send new connections to the controller. fm.match.nw_proto = pkt.ipv4.TCP_PROTOCOL fm.match.nw_dst = external_nw_addr fm.match.tp_dst = external_tp_addr fm.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) self.connection.send(fm) # Let the non-OpenFlow stack handle everything else. fm = of.ofp_flow_mod() fm.priority = of.OFP_DEFAULT_PRIORITY - 1 fm.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) self.connection.send(fm)
def _handle_ConnectionUp(self, event): fm1 = of.ofp_flow_mod() fm1.priority -= 0x1000 fm1.match.dl_type = ethernet.ARP_TYPE fm1.match.nw_src = self.ip fm1.match.dl_src = self.mac fm1.match.nw_proto = arp.REQUEST fm1.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(fm1) fm2 = of.ofp_flow_mod() fm2.priority -= 0x1000 fm2.match.dl_type = ethernet.ARP_TYPE fm2.match.nw_dst = self.ip fm2.match.dl_dst = self.mac fm2.match.nw_proto = arp.REPLY fm2.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) event.connection.send(fm2) fm3 = of.ofp_flow_mod() fm3.priority -= 0x1000 fm3.match.dl_type = ethernet.ARP_TYPE fm3.match.nw_proto = arp.REQUEST fm3.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) event.connection.send(fm3) fm4 = of.ofp_flow_mod() fm4.priority -= 0x1000 fm4.match.dl_type = ethernet.ARP_TYPE fm4.match.nw_proto = arp.REPLY fm4.actions.append(of.ofp_action_output(port=of.OFPP_NONE)) event.connection.send(fm4)
def _handle_ConnectionUp (self, event): if self._install_flow: msg = of.ofp_flow_mod() #msg.match = of.ofp_match() #msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.dn_dst = "www.uol.com.br" msg.match.dn_dst="formiga.lecom.dcc.ufmg.br" #msg.match.dn_src = "www.uol.com" #msg.match.in_port=1 #msg.match.dl_type=0x0800 msg.idle_timeout = 65535 msg.priority = 65535 msg.actions.append(of.ofp_action_output(port = 3 )) #msg.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr("150.164.0.135"))) event.connection.send(msg) print "regra inserida", msg msg = of.ofp_flow_mod() msg.match.dn_src="formiga.lecom.dcc.ufmg.br" #msg.match.dl_type=0x0800 #msg.match.in_port=3 #msg.idle_timeout = 65535 #msg.priority = 65535 #msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr("150.164.0.135"))) msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg)
def _install_path(prev_path, match): dst_sw = prev_path.dst cur_sw = prev_path.dst dst_pck = match.dl_dst msg = of.ofp_flow_mod() msg.match = match msg.idle_timeout = 10 msg.flags = of.OFPFF_SEND_FLOW_REM msg.actions.append(of.ofp_action_output(port = mac_learning[dst_pck].port)) log.debug("Installing forward from switch %s to output port %s", util.dpid_to_str(cur_sw), mac_learning[dst_pck].port) switches[dst_sw].connection.send(msg) next_sw = cur_sw cur_sw = prev_path.prev[next_sw] while cur_sw is not None: #for switch in path.keys(): msg = of.ofp_flow_mod() msg.match = match msg.idle_timeout = 10 msg.flags = of.OFPFF_SEND_FLOW_REM log.debug("Installing forward from switch %s to switch %s output port %s", util.dpid_to_str(cur_sw), util.dpid_to_str(next_sw), adj[cur_sw][next_sw]) msg.actions.append(of.ofp_action_output(port = adj[cur_sw][next_sw])) switches[cur_sw].connection.send(msg) next_sw = cur_sw cur_sw = prev_path.prev[next_sw]
def _setup_data_fwd_flows(self, switch_id, dst_mac): """ Given a switch and dst_mac address, setup two flows for data forwarding on the switch and its peer switch if the two are not the same. If the same, setup only one flow. """ (peer_switch_id, peer_fwd_port) = (self.inception. mac_to_dpid_port[dst_mac]) peer_ip = self.inception.dpid_to_ip[peer_switch_id] # two switches are different, setup a first flow at switch if switch_id != peer_switch_id: fwd_port = self.inception.dpid_ip_to_port[(switch_id, peer_ip)] core.openflow.sendToDPID(switch_id, of.ofp_flow_mod( match=of.ofp_match(dl_dst=dst_mac), action=of.ofp_action_output(port=fwd_port), priority=priority.DATA_FWD)) LOGGER.info("Setup forward flow on switch=%s for dst_mac=%s", dpid_to_str(switch_id), dst_mac) # Setup flow at the peer switch core.openflow.sendToDPID(peer_switch_id, of.ofp_flow_mod( match=of.ofp_match(dl_dst=dst_mac), action=of.ofp_action_output(port=peer_fwd_port), priority=priority.DATA_FWD)) LOGGER.info("Setup forward flow on switch=%s for dst_mac=%s", dpid_to_str(peer_switch_id), dst_mac)
def connection_up(event): msg = of.ofp_flow_mod() msg.match.priority = 50 msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.match.priority = 100 msg.match.dl_type = 0x800 msg.match.nw_proto = 1 msg.match.nw_src = IPAddr("192.168.1.2") msg.match.nw_dst = IPAddr("192.168.1.3") msg.match.tp_src = 8 msg.actions.append(of.ofp_action_dl_addr.set_dst( EthAddr("fe:fd:02:00:00:03"))) msg.actions.append(of.ofp_action_nw_addr.set_dst( IPAddr("192.168.1.4"))) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.match.priority = 100 msg.match.dl_type = 0x800 msg.match.nw_proto = 1 msg.match.nw_src = IPAddr("192.168.1.4") msg.match.nw_dst = IPAddr("192.168.1.2") msg.match.tp_src = 0 msg.actions.append(of.ofp_action_dl_addr.set_src( EthAddr("fe:fd:02:00:00:02"))) msg.actions.append(of.ofp_action_nw_addr.set_src( IPAddr("192.168.1.3"))) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg)
def handle_flows_redirection(cls, dpid, connections, switch_addresss, message): """ Sends flow mod messages to redirect flows to created queues """ #print 'message from ' + str(switch_addresss) #print 'Connections ' + str(dir(connections)) dpid = dpid[:len(dpid)-1] dpid = dpid[len(dpid)-12:] #print 'Received dpid: ' + str(dpid) #print "message to be used for redirection" + str(message) msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.priority = 65535 #print "dpid parameter: " + str(dpid) for connection in connections: connection_dpid = connection.dpid dpid_str = dpidToStr(connection_dpid) dpid_str = dpid_str.replace("-", "") #print 'Real dpid_str: ' + dpid_str if dpid == dpid_str: connection.send(msg) #print 'Sent to: ' + str(connection) #print 'Well...done' for i in range(len(message['bw_list'])): # We only want to redirect outgoing flows if message['bw_list'][i]['action'] != 'OFPP_LOCAL': my_match = of.ofp_match(dl_type = 0x800,nw_src=message['bw_list'][i]['nw_src'],nw_dst=message['bw_list'][i]['nw_dst']) #print "Flow Match: " + str(my_match) msg = of.ofp_flow_mod() msg.match = my_match msg.priority = 65535 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.actions.append(of.ofp_action_enqueue(port=int(message['bw_list'][i]['action']), queue_id=int(message['queue_list'][i]['queueId']))) #print "Flow mod message: " + str(msg) #toDo: Check a better way to do this #print "dpid parameter: " + str(dpid) for connection in connections: connection_dpid=connection.dpid #print "Connection dpid: " + str(connection_dpid) dpid_str=dpidToStr(connection_dpid) dpid_str=dpid_str.replace("-", "") #print 'Real dpid_str: ' + dpid_str if dpid == dpid_str: connection.send(msg) global flow_mod_time flow_mod_time = time.time() print "Notification time: " + str(notification_time) print "Flow stats reply: " + str(flow_stats_reply_time) print "Queues done time: " + str(queues_done_time) print "Flow mode time :" + str(flow_mod_time)
def AddFlowFromModel(self, flow): # add outgoing flow msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_src = str(flow.internalip) msg.match.nw_dst = str(flow.externalip) msg.match.in_port = flow.internalport msg.idle_timeout = flow.idletime msg.hard_timeout = flow.hardtime msg.actions.append(of.ofp_action_output(port = flow.externalport)) log.debug("installing Manos Flow 1") self.connection.send(msg) # add incoming flow msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_src = str(flow.externalip) msg.match.nw_dst = str(flow.internalip) msg.match.in_port = flow.externalport msg.idle_timeout = flow.idletime msg.hard_timeout = flow.hardtime msg.actions.append(of.ofp_action_output(port = flow.internalport)) log.debug("installing Manos Flow 2") self.connection.send(msg)
def _handle_ConnectionUp(self, event): # XXX while debugging del all flows from switches msg = of.ofp_flow_mod(command = of.OFPFC_DELETE) conn = core.openflow.getConnection(event.dpid) conn.send(msg) log.debug('DISCOVERY: Clearing all flows from %s' % event.dpid) # install flow for all LLDP packets to be forward to controller msg = of.ofp_flow_mod() # LLDP Ether type msg.match.dl_type = 0x88cc # LLDP dest addr '01:80:c2:00:00:0e' msg.match.dl_dst = '\x01\x80\xc2\x00\x00\x0e' # LLDPs to controller msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) event.connection.send(msg) log.debug('LLDP flow-mod configuration sent. Switch: %s' % event.dpid) # if dpid no scheduled, then do it! if not event.dpid in self.scheduled_switches: Timer(self.lldp_ttl, self.send_LLDP, args = [event], recurring = True) self.scheduled_switches.append(event.dpid) # install flow for al ARP packets to be forwarded to controller msg = of.ofp_flow_mod() # ARP Ether type msg.match.dl_type = 0x0806 msg.match.dl_dst = '\xff\xff\xff\xff\xff\xff' # ARPs to controller msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER)) event.connection.send(msg) log.debug('ARP flow-mod configuration sent. Switch: %s' % event.dpid)
def _handle_ConnectionUp (self, event): policies = self.read_policies(policyFile) for policy in policies.itervalues(): msg = of.ofp_flow_mod() msg.match.dl_src = policy.dl_src msg.match.dl_dst = policy.dl_dst msg.priority = 20 event.connection.send(msg) # Hey Prof: there still seems to be a bit of confusion on # the forums regarding the bidirectional issue. AFAICT, # the decision to implement bidirectional blockages is # defensible given the wording of the HW. Just in case, # though, you can make it directionally sensitive by # swapping the boolean below. I've tested it by manually # updating the ARP tables and sending UDP packets. do_block_both_directions = True if do_block_both_directions: msg = of.ofp_flow_mod() msg.match.dl_dst = policy.dl_src msg.match.dl_src = policy.dl_dst msg.priority = 20 event.connection.send(msg) log.debug("Firewall rules installed on %s", dpidToStr(event.dpid))
def configure_icmp_proxy(connection): log.info("icmp_proxy: loading...") msg = of.ofp_flow_mod() msg.match.priority = 50 msg.actions.append(of.ofp_action_output(port = of.OFPP_NORMAL)) connection.send(msg) msg = of.ofp_flow_mod() msg.match.priority = 100 msg.match.dl_type = 0x800 msg.match.nw_proto = 1 msg.match.nw_src = IPAddr("192.168.1.2") msg.match.nw_dst = IPAddr("192.168.2.3") msg.match.tp_src = 8 msg.actions.append(of.ofp_action_dl_addr.set_dst( EthAddr("fe:fd:02:00:00:03"))) msg.actions.append(of.ofp_action_nw_addr.set_dst( IPAddr("192.168.3.4"))) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) connection.send(msg) msg = of.ofp_flow_mod() msg.match.priority = 100 msg.match.dl_type = 0x800 msg.match.nw_proto = 1 msg.match.nw_src = IPAddr("192.168.3.4") msg.match.nw_dst = IPAddr("192.168.1.2") msg.match.tp_src = 0 msg.actions.append(of.ofp_action_dl_addr.set_dst( EthAddr("fe:fd:02:00:00:01"))) msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr("192.168.2.3"))) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) connection.send(msg)
def listarFluxosIp(event): print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" fluxosIp = [] IP_dst=IPAddr("192.168.0.14") for fluxo in event.stats: print 'Um dos Fluxos Atuais' print fluxo.match if fluxo.match.nw_src == IP_dst: fluxosIp.append(fluxo.match) msg = of.ofp_flow_mod() msg.match = fluxo.match msg.idle_timeout = 20 msg.hard_timeout = 20 msg.priority = 65535 print 'Fluxo barrado' print fluxo.match msg = of.ofp_flow_mod() msg.match.dl_type = 0x800 msg.match.nw_src = IPAddr(IP_dst) msg.idle_timeout = 20 msg.hard_timeout = 20 msg.priority = 65535 print 'Ip barrado', IP_dst print fluxosIp
def _install (self, switch, in_port, out_port, match, buf = None): print "inside _install" print "IN PORT ********** ",in_port msg = of.ofp_flow_mod() if in_port==TRANSCODER_TO_SWITCH_PORT and switch.dpid==TRANSCODER_SERVICE_SWITCH_DPID and match.nw_dst==HOSTB_ADDR: msg1 =of.ofp_flow_mod() #msg1.match.dl_src=EthAddr("8e:f0:0d:59:7b:18") #msg1.match.dl_dst=EthAddr("ca:0b:cb:59:d8:1c") #msg1.match.nw_src=IPAddr("10.0.0.3") #msg1.match.nw_dst=IPAddr("10.0.0.2") msg1.actions.append(of.ofp_action_dl_addr.set_src("8a:3d:5a:6c:e3:fe")) #set src mac address to ip address of host A msg1.actions.append(of.ofp_action_nw_addr.set_src(HOSTA_ADDR)) #set src ip address to ip address of host A msg1.match.in_port=in_port msg1.hard_timeout = FLOW_HARD_TIMEOUT msg1.idle_timeout = FLOW_IDLE_TIMEOUT msg1.actions.append(of.ofp_action_output(port = out_port)) switch.connection.send(msg1) return elif in_port==FIREWALL_TO_SWITCH_PORT and switch.dpid==FIREWALL_SERVICE_SWITCH_DPID and match.nw_dst==HOSTB_ADDR: msg1 =of.ofp_flow_mod() #msg1.match.dl_src=EthAddr("8e:f0:0d:59:7b:18") #msg1.match.dl_dst=EthAddr("ca:0b:cb:59:d8:1c") #msg1.match.nw_src=IPAddr("10.0.0.3") #msg1.match.nw_dst=IPAddr("10.0.0.2") msg1.actions.append(of.ofp_action_dl_addr.set_src("8a:3d:5a:6c:e3:fe")) #set src mac address to ip address of host A msg1.actions.append(of.ofp_action_nw_addr.set_src(HOSTA_ADDR)) #set src ip address to ip address of host A msg1.match.in_port=in_port msg1.hard_timeout = FLOW_HARD_TIMEOUT msg1.idle_timeout = FLOW_IDLE_TIMEOUT msg1.actions.append(of.ofp_action_output(port = out_port)) switch.connection.send(msg1) return else: msg.match = match msg.match.in_port = in_port msg.idle_timeout = FLOW_IDLE_TIMEOUT msg.hard_timeout = FLOW_HARD_TIMEOUT # msg.actions.append(of.ofp_action_output(port = out_port)) msg.buffer_id = buf # switch.connection.send(msg) #print match.nw_dst #print msg.match.nw_dst #print out_port #Below lines may be needed if we want to change dst_ip address of packets towards host B to ip address of TRANSCODER VM if out_port==SWITCH_TO_TRANSCODER_PORT and switch.dpid==TRANSCODER_SERVICE_SWITCH_DPID and match.nw_dst==HOSTB_ADDR: msg.actions.append(of.ofp_action_nw_addr.set_dst(TRANSCODER_VM_IP)) msg.actions.append(of.ofp_action_dl_addr.set_dst("8e:f0:0d:59:7b:18")) if out_port==SWITCH_TO_FIREWALL_PORT and switch.dpid==FIREWALL_SERVICE_SWITCH_DPID and match.nw_dst==HOSTB_ADDR: msg.actions.append(of.ofp_action_nw_addr.set_dst(FIREWALL_VM_IP)) msg.actions.append(of.ofp_action_dl_addr.set_dst("8e:f0:0d:59:7b:18")) #set mac address of flow to mac address of FIREWALL VM msg.actions.append(of.ofp_action_output(port = out_port)) switch.connection.send(msg) print "******message sent to switch:" print switch
def _handle_PacketIn (self, event): """ Manipular o pacote em mensagens do switch para implementar o algoritmo acima """ packet = event.parsed def flood (message = None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: if self.hold_down_expired is False: self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) else: pass msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) def drop (duration = None): """ Drops este pacote e, opcionalmente, instala um fluxo para continuar dropping similares por um tempo """ if duration is not None: if not isinstance(duration, tuple): duration = (duration,duration) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.buffer_id = event.ofp.buffer_id self.connection.send(msg) elif event.ofp.buffer_id is not None: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) self.macToPort[packet.src] = event.port # 1 # Obter o DPID da Switch Connection dpidstr = dpid_to_str(event.connection.dpid) # Regras Firewall if self.CheckRule(dpidstr, packet.src) == False: drop() return if not self.transparent: # 2 if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered(): drop() # 2a return if packet.dst.is_multicast: flood() # 3a else: if packet.dst not in self.macToPort: # 4 flood("Port for %s unknown -- flooding" % (packet.dst,)) # 4a else: port = self.macToPort[packet.dst] if port == event.port: # 5 # 5a log.warning("Same port for packet from %s -> %s on %s.%s. Drop." % (packet.src, packet.dst, dpid_to_str(event.dpid), port)) drop(10) return # 6 log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = port)) msg.data = event.ofp # 6a self.connection.send(msg)
def _handle_openflow_PacketIn (self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("S: %d P: %d - Ignorando pacote mal-formado", dpid, inport) return # Switch nao esta na tabela. Aloca Espaco. if dpid not in self.arpTable: self.arpTable[dpid] = {} #Ignora pacotes nivel 2 - LLDP if packet.type == ethernet.LLDP_TYPE: return # Pacotes IPv4 if isinstance(packet.next, ipv4): log.debug("S: %i P: %i - IP %s => %s", dpid,inport,packet.next.srcip,packet.next.dstip) #self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) dstaddr = packet.next.dstip if dstaddr == self.victim: if dpid in self.SwitchesToApply and (inport == 2 or inport == 3) : log.warning("Trafego sendo redirecionado para Limitacao") actions = [] actions.append(of.ofp_action_dl_addr.set_dst("00:00:00:00:00:1"+str(dpid))) actions.append(of.ofp_action_output(port = 4)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, #idle_timeout=FLOW_IDLE_TIMEOUT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) elif dstaddr in self.arpTable[dpid]: log.warning("Trafego sendo redirecionado para Destino") prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, #idle_timeout=FLOW_IDLE_TIMEOUT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) # Sei pra que porta vai mandar. elif dstaddr in self.arpTable[dpid]: prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if inport==4 and (dpid==1 or dpid ==2 or dpid ==5): log.warning("Descartei") else: if prt == inport: log.warning("S: %i P: %i - Porta de entrada e a mesma de saida - %s" % (dpid, inport,str(dstaddr))) else: log.debug("S: %i P: %i - Instalando Flow para %s => %s out porta %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, #idle_timeout=FLOW_IDLE_TIMEOUT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) # Pacotes ARP elif isinstance(packet.next, arp): a = packet.next log.debug("S: %i P: %i - ARP %s %s => %s", dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst) self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # Tem Resposta local r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Nao sabe ent'ao inunda log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst)) msg = of.ofp_packet_out(in_port = inport, data = event.ofp, action = of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg)
def delete_flow_rule(self, match): msg = of.ofp_flow_mod() msg.match = match msg.command = of.OFPFC_DELETE_STRICT self.connection.send(msg)
def set_output(self, out_port, in_port, event): fm = of.ofp_flow_mod() fm.match.in_port = in_port fm.actions.append(of.ofp_action_output(port=out_port)) event.connection.send(fm)
def _handle_ConnectionUp(event): ####################### REGRAS PRINCIPAIS ############################# #Instala a regra de ida (alterar os numeros das portas, se preciso) msg1 = of.ofp_flow_mod() msg1.match.in_port = 13 msg1.priority = 10 msg1.actions.append(of.ofp_action_output(port=21)) event.connection.send(msg1) #Instala a regra de volta (alterar os numeros das portas, se preciso) msg2 = of.ofp_flow_mod() msg2.match.in_port = 21 msg2.priority = 10 msg2.actions.append(of.ofp_action_output(port=13)) event.connection.send(msg2) #Regra de encaminhamento para o controlador msgc = of.ofp_flow_mod() msgc.match.in_port = 24 msgc.priority = 2 msgc.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) event.connection.send(msgc) #Regra de drop para miss msg0 = of.ofp_flow_mod() msg0.priority = 1 event.connection.send(msg0) #################### REGRAS COMPLEMENTARES ################################### ''' #Permite a passagem de regras ARP (ida e volta) msg3 = of.ofp_flow_mod() msg3.match.in_port = 13 msg3.match.dl_type = 0x0806 msg3.actions.append(of.ofp_action_output(port = 21)) event.connection.send(msg3) msg3 = of.ofp_flow_mod() msg3.match.in_port = 21 msg3.match.dl_type = 0x0806 msg3.actions.append(of.ofp_action_output(port = 13)) event.connection.send(msg3) #Permite a troca de pacotes SSH (se necessario) msg3 = of.ofp_flow_mod() msg3.match.in_port = 13 msg3.match.dl_type = 0x0800 msg3.match.nw_proto = 6 # tcp = 6 e udp = 17 msg3.match.tp_dst = 22 msg3.actions.append(of.ofp_action_output(port = 21)) event.connection.send(msg3) msg3 = of.ofp_flow_mod() msg3.match.in_port = 21 msg3.match.dl_type = 0x0800 msg3.match.nw_proto = 6 # tcp = 6 e udp = 17 msg3.match.tp_src = 22 msg3.actions.append(of.ofp_action_output(port = 13)) event.connection.send(msg3) ''' log.info("Regras instaladas no switch %s.", dpidToStr(event.dpid)) global tempoEnv tempoEnv = time.time() - t event.connection.send(of.ofp_barrier_request(xid=77777))
def _handle_PacketIn(self, event): if self._outside_eth is None: return #print #print "PACKET",event.connection.ports[event.port].name,event.port, #print self.outside_port, self.make_match(event.ofp) incoming = event.port == self._outside_portno if self._gateway_eth is None: # Need to find gateway MAC -- send an ARP self._arp_for_gateway() return packet = event.parsed dns_hack = False # We only handle TCP and UDP tcpp = packet.find('tcp') if not tcpp: tcpp = packet.find('udp') if not tcpp: return if tcpp.dstport == 53 and tcpp.prev.dstip == self.inside_ip: if self.dns_ip and not incoming: # Special hack for DNS since we've lied and claimed to be the server dns_hack = True ipp = tcpp.prev if not incoming: # Assume we only NAT public addresses if self._is_local(ipp.dstip) and not dns_hack: return else: # Assume we only care about ourselves if ipp.dstip != self.outside_ip: return match = self.make_match(event.ofp) if incoming: match2 = match.clone() match2.dl_dst = None # See note below record = self._record_by_incoming.get(match2) if record is None: # Ignore for a while fm = of.ofp_flow_mod() fm.idle_timeout = 1 fm.hard_timeout = 10 fm.match = of.ofp_match.from_packet(event.ofp) event.connection.send(fm) return log.debug("%s reinstalled", record) record.incoming_fm.data = event.ofp # Hacky! else: record = self._record_by_outgoing.get(match) if record is None: record = Record() record.real_srcport = tcpp.srcport record.fake_srcport = self._pick_port(match) # Outside heading in fm = of.ofp_flow_mod() fm.flags |= of.OFPFF_SEND_FLOW_REM fm.hard_timeout = FLOW_TIMEOUT fm.match = match.flip() fm.match.in_port = self._outside_portno fm.match.nw_dst = self.outside_ip fm.match.tp_dst = record.fake_srcport fm.match.dl_src = self._gateway_eth # We should set dl_dst, but it can get in the way. Why? Because # in some situations, the ARP may ARP for and get the local host's # MAC, but in others it may not. #fm.match.dl_dst = self._outside_eth fm.match.dl_dst = None fm.actions.append(of.ofp_action_dl_addr.set_src(packet.dst)) fm.actions.append(of.ofp_action_dl_addr.set_dst(packet.src)) fm.actions.append(of.ofp_action_nw_addr.set_dst(ipp.srcip)) if dns_hack: fm.match.nw_src = self.dns_ip fm.actions.append( of.ofp_action_nw_addr.set_src(self.inside_ip)) if record.fake_srcport != record.real_srcport: fm.actions.append( of.ofp_action_tp_port.set_dst(record.real_srcport)) fm.actions.append(of.ofp_action_output(port=event.port)) record.incoming_match = self.strip_match(fm.match) record.incoming_fm = fm # Inside heading out fm = of.ofp_flow_mod() fm.data = event.ofp fm.flags |= of.OFPFF_SEND_FLOW_REM fm.hard_timeout = FLOW_TIMEOUT fm.match = match.clone() fm.match.in_port = event.port fm.actions.append( of.ofp_action_dl_addr.set_src(self._outside_eth)) fm.actions.append( of.ofp_action_nw_addr.set_src(self.outside_ip)) if dns_hack: fm.actions.append( of.ofp_action_nw_addr.set_dst(self.dns_ip)) if record.fake_srcport != record.real_srcport: fm.actions.append( of.ofp_action_tp_port.set_src(record.fake_srcport)) fm.actions.append( of.ofp_action_dl_addr.set_dst(self._gateway_eth)) fm.actions.append( of.ofp_action_output(port=self._outside_portno)) record.outgoing_match = self.strip_match(fm.match) record.outgoing_fm = fm self._record_by_incoming[record.incoming_match] = record self._record_by_outgoing[record.outgoing_match] = record log.debug("%s installed", record) else: log.debug("%s reinstalled", record) record.outgoing_fm.data = event.ofp # Hacky! record.touch() # Send/resend the flow mods if incoming: data = record.outgoing_fm.pack() + record.incoming_fm.pack() else: data = record.incoming_fm.pack() + record.outgoing_fm.pack() self._connection.send(data) # We may have set one of the data fields, but they should be reset since # they won't be valid in the future. Kind of hacky. record.outgoing_fm.data = None record.incoming_fm.data = None
def test_OUTPUT(event): out_port = 2 num = len(event.connection.phyports) msg = of.ofp_port_mod() portmessage = event.connection.phyports[3] msg.setByPortState(portmessage) msg.desc.openflowEnable = 1 event.connection.send(msg) ofmatch20_1 = of.ofp_match20() ofmatch20_1.fieldId = 1 ofmatch20_1.offset = 0 ofmatch20_1.length = 48 msg = of.ofp_table_mod() msg.flowTable.matchFieldList.append(ofmatch20_1) msg.flowTable.command = 0 #OFPTC_ADD msg.flowTable.tableType = 0 #OF_MM_TABLE msg.flowTable.matchFieldNum = 1 #msg.flowTable.matchFieldNum=len(msg.flowTable.matchFieldList) msg.flowTable.tableSize = 128 msg.flowTable.tableId = 0 msg.flowTable.tableName = "FirstEntryTable" msg.flowTable.keyLength = 48 event.connection.send(msg) ############################################################################## #flow_mod 1 ############################################################################### msg = of.ofp_flow_mod() msg.counterId = 1 msg.cookie = 0 msg.cookieMask = 0 msg.tableId = 0 msg.tableType = 0 #OF_MM_TABLE msg.priority = 0 msg.index = 1 tempmatchx = of.ofp_matchx() tempmatchx.fieldId = 1 tempmatchx.offset = 0 tempmatchx.length = 48 tempmatchx.set_value("00") # null tempmatchx.set_mask("00") msg.matchx.append(tempmatchx) #instruction tempins = of.ofp_instruction_applyaction() action = of.ofp_action_addfield() action.fieldId = 2 action.fieldPosition = 96 action.fieldLength = 16 tempins.actionList.append(action) action = of.ofp_action_output() action.portId = out_port action.metadataOffset = 0 action.metadataLength = 0 action.packetOffset = 0 tempins.actionList.append(action) msg.instruction.append(tempins) event.connection.send(msg) ############################################################################## #flow_mod 1 ############################################################################### msg = of.ofp_flow_mod() msg.command = 3 msg.counterId = 1 msg.cookie = 0 msg.cookieMask = 0 msg.tableId = 0 msg.tableType = 0 #OF_MM_TABLE msg.priority = 0 msg.index = 1 event.connection.send(msg)
def do_final(self, packet, packet_in, port_on_switch, switch_id): # This is where you'll put your code. The following modifications have # been made from Lab 4: # - port_on_switch represents the port that the packet was received on. # - switch_id represents the id of the switch that received the packet # (for example, s1 would have switch_id == 1, s2 would have switch_id == 2, etc...) #end system IPs h1 = '10.0.1.10' h2 = '10.0.2.20' h3 = '10.0.3.30' h4 = '10.0.4.40' h5 = '10.0.5.50' h6 = '10.0.6.60' h7 = '10.0.7.70' h8 = '10.0.8.80' untrusted = '172.16.10.100' server = '10.0.9.10' # numbers corresponding to switches # f1s1 = 1, f1s2 = 2, f2s1 = 3, f2s2 = 4, datacenter = 5, core = 6 msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 20 msg.hard_timeout = 50 # Firewall Rules: untrusted host cant send TCP to server 1 # untrusted cant send ICMP at all to anyone # flags to see if packets are valid under firewall rules icmpFlag = ((packet.find('icmp') is not None) and (packet.find('ipv4').srcip != untrusted)) tcpFlag = ((packet.find('tcp') is not None) and (packet.find('ipv4').srcip == untrusted and packet.find('ipv4').dstip == server) is False) if (packet.find('ipv4') is None): #not IP packet print('non-IP packet') msg.data = packet_in flood = of.ofp_action_output(port=of.OFPP_FLOOD) msg.actions.append(flood) #flood traffic out all ports self.connection.send(msg) else: # IP packet, TCP or ICMP type packet if (icmpFlag == True or tcpFlag == True): # check if packet is valid under rules print('valid IP packet') print(' Source IP: {}'.format(packet.find('ipv4').srcip)) print(' Destination IP: {}'.format(packet.find('ipv4').dstip)) if (packet.find('icmp') is not None): print(' Type: ICMP packet') if (packet.find('tcp') is not None): print(' Type: TCP packet') msg.data = packet_in if (switch_id == 1): # floor1 switch1 if (packet.find('ipv4').dstip == h1): msg.actions.append(of.ofp_action_output(port=1)) elif (packet.find('ipv4').dstip == h2): msg.actions.append(of.ofp_action_output(port=2)) else: msg.actions.append(of.ofp_action_output(port=3)) elif (switch_id == 2): # floor1 switch2 if (packet.find('ipv4').dstip == h3): msg.actions.append(of.ofp_action_output(port=1)) elif (packet.find('ipv4').dstip == h4): msg.actions.append(of.ofp_action_output(port=2)) else: msg.actions.append(of.ofp_action_output(port=3)) elif (switch_id == 3): # floor2 switch1 if (packet.find('ipv4').dstip == h5): msg.actions.append(of.ofp_action_output(port=1)) elif (packet.find('ipv4').dstip == h6): msg.actions.append(of.ofp_action_output(port=2)) else: msg.actions.append(of.ofp_action_output(port=3)) elif (switch_id == 4): # floor2 switch2 if (packet.find('ipv4').dstip == h7): msg.actions.append(of.ofp_action_output(port=1)) elif (packet.find('ipv4').dstip == h8): msg.actions.append(of.ofp_action_output(port=2)) else: msg.actions.append(of.ofp_action_output(port=3)) elif (switch_id == 5): # data center if (packet.find('ipv4').dstip == server): msg.actions.append(of.ofp_action_output(port=1)) else: msg.actions.append(of.ofp_action_output(port=3)) else: #core if (packet.find('ipv4').dstip == h1 or packet.find('ipv4').dstip == h2): msg.actions.append(of.ofp_action_output(port=1)) elif (packet.find('ipv4').dstip == h3 or packet.find('ipv4').dstip == h4): msg.actions.append(of.ofp_action_output(port=2)) elif (packet.find('ipv4').dstip == h5 or packet.find('ipv4').dstip == h6): msg.actions.append(of.ofp_action_output(port=3)) elif (packet.find('ipv4').dstip == h7 or packet.find('ipv4').dstip == h8): msg.actions.append(of.ofp_action_output(port=4)) elif (packet.find('ipv4').dstip == untrusted): print('To untrusted') msg.actions.append(of.ofp_action_output(port=5)) elif (packet.find('ipv4').dstip == server): msg.actions.append(of.ofp_action_output(port=6)) else: print( 'Should not be able to get here as all cases are covered for' ) self.connection.send(msg) else: #dropped packet if invalid under firewall rules print('Dropped Packet') print(' Source IP: {}'.format(packet.find('ipv4').srcip)) print(' Destination IP: {}'.format(packet.find('ipv4').dstip)) if (packet.find('icmp') is not None): print(' Type: ICMP packet') if (packet.find('tcp') is not None): print(' Type: TCP packet') self.connection.send(msg)
def _handle_PacketIn(self, event): """ Handle packet in messages from the switch to implement above algorithm. """ packet = event.parsed def flood(message=None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) def drop(duration=None): """ Drops this packet and optionally installs a flow to continue dropping similar ones for a while """ if duration is not None: if not isinstance(duration, tuple): duration = (duration, duration) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.priority = 100 msg.buffer_id = event.ofp.buffer_id self.connection.send(msg) elif event.ofp.buffer_id is not None: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) if packet.type == packet.ARP_TYPE: # Increase the Port ARP count. self.mutex.acquire() try: self.portARPCount[event.port] += 1 except KeyError: self.portARPCount[event.port] = 0 print "\nARP count for Port " + str(event.port) + " " + str( self.portARPCount[event.port]) self.mutex.release() # Check ARP Spoofing if self.isEdgeSwitch and ARPSpoofDetection.IsSpoofedPacket(packet): # Spoofing detected time_d = time.time() print "*******************SPOOFING DETECTED at " + str( time_d) + " **********************\n" ARPSpoofDetection.handleSpoofing(event, packet) # Done with this ARP packet return print "Valid packet" # Valid packet, do processing. self.macToPort[packet.src] = event.port # 1 if not self.transparent: # 2 print "Dropped because the mode is transparent" drop() # 2a return if packet.dst.is_multicast: print "Flooding due to the multicast dest address present in the header" flood() # 3a else: if packet.dst not in self.macToPort: # 4 print "Flooding" flood("Port for %s unknown -- flooding" % (packet.dst, )) # 4a else: port = self.macToPort[packet.dst] print "Port for dest MAC " + str( packet.dst) + " is " + str(port) if port == event.port: # 5 # 5a log.warning( "Same port for packet from %s -> %s on %s.%s. Drop." % (packet.src, packet.dst, dpid_to_str( event.dpid), port)) drop(10) return # 6 log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port=port)) msg.data = event.ofp # 6a self.connection.send(msg)
def do_final (self, packet, packet_in, port_on_switch, switch_id): # This is where you'll put your code. The following modifications have # been made from Lab 3: # - port_on_switch: represents the port that the packet was received on. # - switch_id represents the id of the switch that received the packet. # (for example, s1 would have switch_id == 1, s2 would have switch_id == 2, etc...) # You should use these to determine where a packet came from. To figure out where a packet # is going, you can use the IP header information. #ICMP traffic is a type of IP traffic #everything goes through switch 4 #check if IP traffic #if true -> check if ICMP traffic #if ICMP traffic -> check if it is coming from host4 #if true -> do not allow #if false -> allow traffic communication #if NOT ICMP traffic -> check if host4 is trying to send it to the server (host5) #if true -> do not allow (dont allow host4 send IP traffic to host5) #if false -> allow traffic communication #if false (Not IP traffic) -> flood msg = of.ofp_flow_mod() #msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 40 msg.hard_timeout = 60 ip = packet.find('ipv4') ICMP = packet.find('icmp') port = 0 if ip is not None: #print "PASS: ip is not NONE! " #msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) if ICMP is not None: if switch_id == 4: if ip.srcip == "123.45.67.89" and ip.dstip == "10.1.1.10": msg.data = packet_in self.connection.send(msg) print "dropped. ICMP 1: h4->h1" elif ip.srcip == "123.45.67.89" and ip.dstip == "10.2.2.20": msg.data = packet_in self.connection.send(msg) print "dropped. ICMP 2: h4->h2" elif ip.srcip == "123.45.67.89" and ip.dstip == "10.3.3.30": msg.data = packet_in self.connection.send(msg) print "dropped. ICMP 3: h4->h3" elif ip.srcip == "123.45.67.89" and ip.dstip == "10.5.5.50": msg.data = packet_in self.connection.send(msg) print "dropped. ICMP 4: h4->h5" elif ip.dstip == "10.1.1.10": port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif ip.dstip == "10.2.2.20": port = 2 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif ip.dstip == "10.3.3.30": port = 3 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif ip.dstip == "123.45.67.89": print "ICMP: destination host 4, code was reached" port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif ip.dstip == "10.5.5.50": port = 5 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif switch_id == 1: if ip.dstip == "10.1.1.10": port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) #take out this line for dropping self.connection.send(msg) else: #any other destination send to switch 4 port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif switch_id == 2: if ip.dstip == "10.2.2.20": port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) #take out this line for dropping self.connection.send(msg) else: #any other destination send to switch 4 port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif switch_id == 3: if ip.dstip == "10.3.3.30": port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) #take out this line for dropping self.connection.send(msg) else: #any other destination send to switch 4 port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif switch_id == 5: if ip.dstip == "10.5.5.50": port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) #take out this line for dropping self.connection.send(msg) else: #any other destination send to switch 4 port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) else: # longest one is switch 4 if switch_id == 4: if ip.srcip == "123.45.67.89" and ip.dstip == "10.5.5.50": msg.data = packet_in self.connection.send(msg) print "dropped. IP: h4->h5" elif ip.dstip == "10.1.1.10": port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif ip.dstip == "10.2.2.20": port = 2 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif ip.dstip == "10.3.3.30": port = 3 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif ip.dstip == "123.45.67.89": print "IP: destination host 4, code was reached" port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif ip.dstip == "10.5.5.50": port = 5 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif switch_id == 1: if ip.dstip == "10.1.1.10": port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) #take out this line for dropping self.connection.send(msg) else: #any other destination send to switch 4 port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif switch_id == 2: if ip.dstip == "10.2.2.20": port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) #take out this line for dropping self.connection.send(msg) else: #any other destination send to switch 4 port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif switch_id == 3: if ip.dstip == "10.3.3.30": port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) #take out this line for dropping self.connection.send(msg) else: #any other destination send to switch 4 port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg) elif switch_id == 5: if ip.dstip == "10.5.5.50": port = 8 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) #take out this line for dropping self.connection.send(msg) else: #any other destination send to switch 4 port = 1 msg.data = packet_in msg.actions.append(of.ofp_action_output(port = port)) self.connection.send(msg)
def _handle_ConnectionUp(event): log.debug("Switch %s esta UP" % (dpid_to_str(event.dpid))) ##REGRA 01.01 - IDENTICAS msg1 = of.ofp_flow_mod() msg1.match.in_port= 3 msg1.table_id = 0x1 msg1.priority = 3000 msg1.match.dl_type = 0x800 msg1.match.nw_proto = 6 msg1.match.nw_src = "10.0.0.0/8" msg1.match.nw_dst = "10.0.0.2" msg1.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) event.connection.send(msg1) msg1 = of.ofp_flow_mod() msg1.table_id = 0x1 msg1.priority = 3000 msg1.match.dl_type = 0x800 msg1.match.nw_proto = 6 msg1.match.nw_src = "10.0.0.2" msg1.match.nw_dst = "10.0.0.1" msg1.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) event.connection.send(msg1) ##REGRA 01.02 msg2 = of.ofp_flow_mod() msg2.match.in_port = 3 msg2.priority = 3000 msg2.match.dl_type = 0x800 msg2.match.nw_proto = 6 msg2.match.nw_src = "10.0.0.100" msg2.match.nw_dst = "10.0.0.1" msg2.match.tp_src = 80 msg2.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg2) msg3 = of.ofp_flow_mod() msg3.priority = 42 msg3.match.dl_type = 0x800 msg3.match.nw_proto = 6 msg3.match.nw_src = "10.0.0.0" msg3.match.tp_dst = 22 event.connection.send(msg3) msg4 = of.ofp_flow_mod() msg4.priority = 42 msg4.match.dl_type = 0x800 msg4.match.nw_proto = 6 msg4.match.nw_dst = "192.168.101.150" msg4.match.tp_dst = 443 msg4.match.tp_src = 80 msg4.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg4) #Esta ultima regra nao pode conflitar msg5 = of.ofp_flow_mod() msg5.priority = 41 msg5.match.dl_type = 0x800 msg5.match.nw_proto = 6 msg5.match.nw_src = "191.10.10.150" msg5.match.nw_dst = "192.168.10.150" msg5.match.tp_dst = 445 msg5.match.tp_src = 81 event.connection.send(msg5) """actionlist = []
def add_ethernet_rule(self, conn, src, dst): msg = of.ofp_flow_mod() msg.match.dl_src = EthAddr(src) msg.match.dl_dst = EthAddr(dst) conn.send(msg)
msg.command = of.OFPFC_MODIFY else: msg.command = of.OFPFC_ADD msg.match.dl_type = 0x800 # IPV4 msg.match.nw_dst = self.dst_mcast_address msg.match.nw_src = self.src_ip output_port = receiver[1] msg.actions.append(of.ofp_action_output(port = output_port)) outgoing_rules[receiver[0]] = msg #log.debug('NR: Configured router ' + dpid_to_str(receiver[0]) + ' to forward group ' + \ # str(self.dst_mcast_address) + ' to network over port: ' + str(output_port)) """ # Setup empty rules for any router not involved in this path for router_dpid in self.node_list: if not router_dpid in outgoing_rules and router_dpid in self.installed_node_list: msg = of.ofp_flow_mod() msg.match.dl_type = 0x800 # IPV4 msg.match.nw_dst = self.dst_mcast_address msg.match.nw_src = self.src_ip msg.command = of.OFPFC_DELETE outgoing_rules[router_dpid] = msg #log.debug('Removed rule on router ' + dpid_to_str(router_dpid) + ' for group ' + str(self.dst_mcast_address)) for router_dpid in outgoing_rules: connection = core.openflow.getConnection(router_dpid) if connection is not None: connection.send(outgoing_rules[router_dpid]) if not outgoing_rules[router_dpid].command == of.OFPFC_DELETE: self.installed_node_list.append(router_dpid) else: self.installed_node_list.remove(router_dpid)
import time from pox.lib.revent import * from pox.lib.recoco import Timer from collections import defaultdict from pox.openflow.discovery import Discovery from pox.lib.util import dpid_to_str log = core.getLogger() #flow3: switch2 = 0000000000000003 flow2msg = of.ofp_flow_mod() flow2msg.cookie = 0 # flow2msg.match.in_port = 1 flow2msg.match.dl_type = 0x0800 flow2msg.match.nw_dst = IPAddr("10.0.0.7") # flow2msg.match.nw_src = IPAddr("10.0.0.1") # ACTIONS--------------------------------- flow2out = of.ofp_action_output(port=6) flow2dstIP = of.ofp_action_nw_addr.set_dst(IPAddr("10.0.0.6"))
def install_openflow_rules(self): self.calc_path_tree_dijkstras() """Selects routes for active receivers from the cached shortest path tree, and installs/removes OpenFlow rules accordingly.""" reception_state = self.get_reception_state(self.dst_mcast_address, self.src_ip) log.debug('Receivers for this multicast group are: ' + str(self.dst_mcast_address) + ': ' + str(reception_state)) outgoing_rules = defaultdict(lambda : None) # Calculate the paths for the specific receivers that are currently active from the previously # calculated mst edges_to_install = [] calculated_path_router_dpids = [] for receiver in reception_state: if receiver[0] == self.src_router_dpid: continue if receiver[0] in calculated_path_router_dpids: continue # log.debug('Building path for receiver on router: ' + dpid_to_str(receiver[0])) receiver_path = self.path_tree_map[receiver[0]] log.debug('Receiver path for receiver ' + str(receiver[0]) + ': ' + str(receiver_path)) if receiver_path is None: log.warn('Path could not be determined for receiver ' + dpid_to_str(receiver[0]) + ' (network is not fully connected)') continue while receiver_path[1]: edges_to_install.append((receiver_path[1][0], receiver_path[0])) #dla kazdej pary switchy na sciezce: dodaj ja do tych dla ktorych trzeba zainstalowac regule receiver_path = receiver_path[1] calculated_path_router_dpids.append(receiver[0]) # Get rid of duplicates in the edge list edges_to_install = list(Set(edges_to_install)) if not edges_to_install is None: # log.info('Installing edges:') for edge in edges_to_install: log.debug('Installing: ' + str(edge[0]) + ' -> ' + str(edge[1])) for edge in edges_to_install: if edge[0] in outgoing_rules: # Add the output action to an existing rule if it has already been generated output_port = self.adjacency[edge[0]][edge[1]] outgoing_rules[edge[0]].actions.append(of.ofp_action_output(port = output_port)) #regula jest dodawana tylko dla tych switchy z ktorych ruch jest wysylany, nie na odwrot #log.debug('ER: Configured router ' + dpid_to_str(edge[0]) + ' to forward group ' + \ # str(self.dst_mcast_address) + ' to next router ' + \ # dpid_to_str(edge[1]) + ' over port: ' + str(output_port)) else: # Otherwise, generate a new flow mod msg = of.ofp_flow_mod() msg.hard_timeout = 0 msg.idle_timeout = 0 if edge[0] in self.installed_node_list: msg.command = of.OFPFC_MODIFY else: msg.command = of.OFPFC_ADD msg.match.dl_type = 0x800 # IPV4 msg.match.nw_dst = self.dst_mcast_address msg.match.nw_src = self.src_ip output_port = self.adjacency[edge[0]][edge[1]] msg.actions.append(of.ofp_action_output(port = output_port)) outgoing_rules[edge[0]] = msg
def dcs31_setup(self): #put datacenter switch rules here fm=of.ofp_flow_mod() fm.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) self.connection.send(fm)
def _handle_PacketIn(self, event): log.info('Start main funciton') dpid = event.connection.dpid log.info('dpid is %s ' % dpid) packet = event.parsed # This is the parsed packet data. inport = event.port if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return packet_in = event.ofp # The actual ofp_packet_in message. log.info("Installing flow...") # Maybe the log statement should have source/destination/port? log.debug('the source MAC is %s' % packet.src) log.debug('the dist MAC is %s' % packet.dst) log.debug('the source port is %s' % packet_in.in_port) if dpid == 1: _route = _route1 elif dpid == 2: _route = _route2 else: _route = _route3 '***********************ARP**********************************' if packet.find("arp"): a = packet.find('arp') if not a: return _ip_to_port[a.protosrc] = inport log.debug("ARP %s %s => %s", { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) #Deal with ARP REQUEST then ARP REPLY to hosts if a.prototype == arp.PROTO_TYPE_IP and a.hwtype == arp.HW_TYPE_ETHERNET and a.opcode == arp.REQUEST: _arp_cache[IPAddr(a.protosrc)] = EthAddr(a.hwsrc) if dpid == 1: if inport == 1 or inport == 2: #broadcast arp request from r1 p = arp() p.hwtype = arp.HW_TYPE_ETHERNET p.prototype = arp.PROTO_TYPE_IP p.hwlen = 6 p.protolen = 4 p.opcode = arp.REQUEST p.hwdst = EthAddr('ff:ff:ff:ff:ff:ff') p.hwsrc = EthAddr('00:00:00:00:01:04') p.protodst = a.protodst p.protosrc = IPAddr('10.0.1.1') E = ethernet(type=ethernet.ARP_TYPE, src=p.hwsrc, dst=p.hwdst) E.payload = p self.resend_packet(E, 4) self.resend_packet(E, 5) self.resend_packet(E, 6) else: #reply to host the router's mac r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = EthAddr('00:00:00:00:01:04') e = ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc) e.payload = r log.info("Answering ARP for %s" % (str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) msg1 = of.ofp_flow_mod() msg1.match = of.ofp_match() msg1.match.dl_type = 0x800 msg1.match.nw_dst = a.protosrc msg1.actions.append( of.ofp_action_dl_addr.set_src(r.hwsrc)) msg1.actions.append( of.ofp_action_dl_addr.set_dst(r.hwdst)) msg1.actions.append(of.ofp_action_output(port=inport)) self.connection.send(msg1) elif dpid == 2: if inport == 1 or inport == 3: #broadcast arp request from r1 or r3 p2 = arp() p2.hwtype = arp.HW_TYPE_ETHERNET p2.prototype = arp.PROTO_TYPE_IP p2.hwlen = 6 p2.protolen = 4 p2.opcode = arp.REQUEST p2.hwdst = EthAddr('ff:ff:ff:ff:ff:ff') p2.hwsrc = EthAddr('00:00:00:00:02:07') p2.protodst = a.protodst p2.protosrc = IPAddr('10.0.2.1') E2 = ethernet(type=ethernet.ARP_TYPE, src=p2.hwsrc, dst=p2.hwdst) E2.payload = p2 self.resend_packet(E2, 7) self.resend_packet(E2, 8) self.resend_packet(E2, 9) else: #reply to host the router's mac r2 = arp() r2.hwtype = a.hwtype r2.prototype = a.prototype r2.hwlen = a.hwlen r2.protolen = a.protolen r2.opcode = arp.REPLY r2.hwdst = a.hwsrc r2.protodst = a.protosrc r2.protosrc = a.protodst r2.hwsrc = EthAddr('00:00:00:00:02:07') e2 = ethernet(type=packet.type, src=r2.hwsrc, dst=a.hwsrc) e2.payload = r2 msg2 = of.ofp_packet_out() msg2.data = e2.pack() msg2.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg2.in_port = inport event.connection.send(msg2) msg22 = of.ofp_flow_mod() msg22.match = of.ofp_match() msg22.match.dl_type = 0x800 msg22.match.nw_dst = a.protosrc msg22.actions.append( of.ofp_action_dl_addr.set_src(r2.hwsrc)) msg22.actions.append( of.ofp_action_dl_addr.set_dst(r2.hwdst)) msg22.actions.append(of.ofp_action_output(port=inport)) self.connection.send(msg22) else: if inport == 2 or inport == 3: #broadcast arp request from r1 p3 = arp() p3.hwtype = arp.HW_TYPE_ETHERNET p3.prototype = arp.PROTO_TYPE_IP p3.hwlen = 6 p3.protolen = 4 p3.opcode = arp.REQUEST p3.hwdst = EthAddr('ff:ff:ff:ff:ff:ff') p3.hwsrc = EthAddr('00:00:00:00:03:10') p3.protodst = a.protodst p3.protosrc = IPAddr('10.0.3.1') E3 = ethernet(type=ethernet.ARP_TYPE, src=p3.hwsrc, dst=p3.hwdst) E3.payload = p3 self.resend_packet(E3, 10) self.resend_packet(E3, 11) self.resend_packet(E3, 12) else: #reply to host the router's mac r3 = arp() r3.hwtype = a.hwtype r3.prototype = a.prototype r3.hwlen = a.hwlen r3.protolen = a.protolen r3.opcode = arp.REPLY r3.hwdst = a.hwsrc r3.protodst = a.protosrc r3.protosrc = a.protodst r3.hwsrc = EthAddr('00:00:00:00:03:10') e3 = ethernet(type=packet.type, src=r3.hwsrc, dst=a.hwsrc) e3.payload = r3 msg3 = of.ofp_packet_out() msg3.data = e3.pack() msg3.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg3.in_port = inport event.connection.send(msg3) msg33 = of.ofp_flow_mod() msg33.match = of.ofp_match() msg33.match.dl_type = 0x800 msg33.match.nw_dst = a.protosrc msg33.actions.append( of.ofp_action_dl_addr.set_src(r3.hwsrc)) msg33.actions.append( of.ofp_action_dl_addr.set_dst(r3.hwdst)) msg33.actions.append(of.ofp_action_output(port=inport)) self.connection.send(msg33) #Deal with ARP REPLY and store ARP cache #Prepare to send buffered ICMP REQUEST packets with new MAC address if a.prototype == arp.PROTO_TYPE_IP and a.hwtype == arp.HW_TYPE_ETHERNET and a.opcode == arp.REPLY: _arp_cache[IPAddr(a.protosrc)] = EthAddr(a.hwsrc) msg4 = of.ofp_flow_mod() msg4.match = of.ofp_match() msg4.match.dl_type = 0x800 msg4.match.nw_dst = a.protosrc msg4.actions.append(of.ofp_action_dl_addr.set_src(a.hwdst)) msg4.actions.append(of.ofp_action_dl_addr.set_dst(a.hwsrc)) msg4.actions.append(of.ofp_action_output(port=inport)) self.connection.send(msg4) self.msg_send(_buff[IPAddr(a.protosrc)], a.hwdst, a.hwsrc, inport) '****************************ICMP***********************' if packet.find("icmp"): _ip_to_port[packet.payload.srcip] = inport log.info('IP occurs') log.debug('the source IP is %s' % packet.payload.srcip) log.debug('the dist IP is %s' % packet.payload.dstip) #intall the packet and get information of the packet #rqt_src: router interface IP addr; rqt_port: router port; rqt_pfx: network prefix; rqt_hwsrc: router interface MAC addr. payload_bf = packet.payload.payload.payload icmp_bf = packet.payload.payload log.info('icmp type =%s' % packet.payload.payload.type) global rqtsrc, rqtdst, rqtport, rqtpfx, rqthwsrc global rplsrc, rpldst, rplport, rplpfx, rplhwsrc #log.info('icmp cache is %s' %_arp_cache) target = 0 for j in range(0, 5): for i in range(0, 9): if str(_route[i][j]) == str(packet.payload.dstip): if j == 0: rqtsrc = _route[i][1] rqtdst = _route[i][0] rqtport = _route[i][2] rqtpfx = _route[i][3] rqthwsrc = _route[i][4] #target = 1 means the icmp packet is to host target = 1 break elif j == 1: #router reply to host rplsrc = _route[i][1] rpldst = _route[i][0] rplport = _route[i][2] rplpfx = _route[i][3] rplhwsrc = _route[i][4] #target = 2 means the icmp packet is to router interface target = 2 flagd = i break for k in range(0, 9): log.info(_route[k][0]) if str(_route[k][0]) == str(packet.payload.srcip): interfaceip = _route[k][1] interfacedst = _route[k][0] flags = _route[k][2] log.info('flags is %s' % flags) break '*********ICMP REQUEST***' if target == 0: self.icmp_unknownhost(packet, interfaceip, inport) log.info('unknown from %s' % interfaceip) elif packet.payload.payload.type == 8 and target != 0: #If we do not have IP_MAC in routing table, create ARP Request if packet.payload.dstip not in _arp_cache: _buff[IPAddr(packet.payload.dstip)] = packet _ip_bf[IPAddr(packet.payload.dstip)] = packet.payload if dpid == 1: if rqtport == 1: #r1 broadcast arp request to r2 self.arp_request(packet, _arp_cache[_port_to_mac_1['1']], _port_to_mac_1['1'], 1) elif rqtport == 2: #r1 broadcast arp request to r3 self.arp_request(packet, _arp_cache[_port_to_mac_1['2']], _port_to_mac_1['2'], 2) else: self.arp_request(packet, rqtsrc, rqthwsrc, 4) self.arp_request(packet, rqtsrc, rqthwsrc, 5) self.arp_request(packet, rqtsrc, rqthwsrc, 6) elif dpid == 2: if rqtport == 1: #r2 broadcast arp request to r1 self.arp_request(packet, _arp_cache[_port_to_mac_2['1']], _port_to_mac_2['1'], 1) elif rqtport == 3: #r2 broadcast arp request to r3 self.arp_request(packet, _arp_cache[_port_to_mac_2['3']], _port_to_mac_2['3'], 3) else: self.arp_request(packet, rqtsrc, rqthwsrc, 7) self.arp_request(packet, rqtsrc, rqthwsrc, 8) self.arp_request(packet, rqtsrc, rqthwsrc, 9) else: if rqtport == 2: #r3 broadcast arp request to r1 self.arp_request(packet, _arp_cache[_port_to_mac_3['2']], _port_to_mac_3['2'], 2) elif rqtport == 3: #r1 broadcast arp request to r3 self.arp_request(packet, _arp_cache[_port_to_mac_3['3']], _port_to_mac_3['3'], 3) else: self.arp_request(packet, rqtsrc, rqthwsrc, 10) self.arp_request(packet, rqtsrc, rqthwsrc, 11) self.arp_request(packet, rqtsrc, rqthwsrc, 12) #If we have IP_MAC in routing table, forward packet directly elif packet.payload.dstip in _arp_cache: if target == 2: if dpid == 1: #r1 received the request from h4 if rplport == 1: #r1 send the request to r2 interface self.msg_send(packet, packet.src, packet.dst, 1) elif rplport == 2: #r1 send the request to r3 interface self.msg_send(packet, packet.src, packet.dst, 2) else: #r1 reply to h4's request self.icmp_forward( payload_bf, TYPE_ECHO_REPLY, packet.payload.dstip, packet.payload.srcip, rplhwsrc, _arp_cache[packet.payload.srcip], rplport) elif dpid == 2: if inport == 1: #r2 received icmp request from r1 and reply to r1 self.icmp_forward( payload_bf, TYPE_ECHO_REPLY, packet.payload.dstip, packet.payload.srcip, _port_to_mac_2[str(inport)], _arp_cache[packet.payload.srcip], inport) else: if inport == 2: #r3 received icmp request from r1 and reply to r1 self.icmp_forward( payload_bf, TYPE_ECHO_REPLY, packet.payload.dstip, packet.payload.srcip, _port_to_mac_3[str(inport)], _arp_cache[packet.payload.srcip], inport) elif target == 1: if dpid == 1: if rqtport == 1: #r1 send the request to r2 self.msg_send(packet, _port_to_mac_1['1'], _port_to_mac_2['1'], 1) elif rplport == 2: #r1 send the request to r3 self.msg_send(packet, _port_to_mac_1['2'], _port_to_mac_3['2'], 2) else: #r1 forward the request to h5 or h6(in cache) self.msg_send(packet, rqthwsrc, _arp_cache[rqtdst], rqtport) elif dpid == 2: if rqtport == 1: #r2 send the request to r1 self.msg_send(packet, _port_to_mac_2['1'], _port_to_mac_1['1'], 1) elif rplport == 3: #r2 send the request to r3 self.msg_send(packet, _port_to_mac_2['3'], _port_to_mac_3['3'], 3) else: #r2 forward the request to hosts(in cache) self.msg_send(packet, rqthwsrc, _arp_cache[rqtdst], rqtport) else: if rqtport == 2: #r3 send the request to r1 self.msg_send(packet, _port_to_mac_3['2'], _port_to_mac_1['2'], 2) elif rplport == 3: #r3 send the request to r2 self.msg_send(packet, _port_to_mac_3['3'], _port_to_mac_2['3'], 3) else: #r3 forward the request to hosts(in cache) self.msg_send(packet, rqthwsrc, _arp_cache[rqtdst], rqtport) ############ICMP REPLY############### #Receive ICPM Reply, we need forward the the reply elif packet.payload.payload.type == 0: if dpid == 1: if rqtport == 1: #r1 send the reply to r2 self.msg_send(packet, _port_to_mac_1['1'], _port_to_mac_2['1'], 1) msg3 = of.ofp_flow_mod() msg3.match = of.ofp_match() msg3.match.dl_type = 0x800 msg3.match.nw_dst = packet.payload.dstip msg3.actions.append( of.ofp_action_dl_addr.set_src(_port_to_mac_1['1'])) msg3.actions.append( of.ofp_action_dl_addr.set_dst(_port_to_mac_2['1'])) msg3.actions.append(of.ofp_action_output(port=1)) log.info('flow mod end 2') self.connection.send(msg3) elif rqtport == 2: #r1 send the reply to r3 self.msg_send(packet, _port_to_mac_1['2'], _port_to_mac_3['2'], 2) log.info('flow mod starts 2') msg4 = of.ofp_flow_mod() msg4.match = of.ofp_match() msg4.match.dl_type = 0x800 msg4.match.nw_dst = packet.payload.dstip msg4.actions.append( of.ofp_action_dl_addr.set_src(_port_to_mac_1['2'])) msg4.actions.append( of.ofp_action_dl_addr.set_dst(_port_to_mac_3['2'])) msg4.actions.append(of.ofp_action_output(port=2)) log.info('flow mod end 2') self.connection.send(msg4) else: #r1 send the reply to h4 self.msg_send(packet, rqthwsrc, _arp_cache[packet.payload.dstip], rqtport) elif dpid == 2: if rqtport == 1: #r2 send the reply to r1 self.msg_send(packet, _port_to_mac_2['1'], _port_to_mac_1['1'], 1) log.info('flow mod starts 1') msg0 = of.ofp_flow_mod() msg0.match = of.ofp_match() msg0.match.dl_type = 0x800 msg0.match.nw_dst = packet.payload.dstip msg0.actions.append( of.ofp_action_dl_addr.set_src(_port_to_mac_2['1'])) msg0.actions.append( of.ofp_action_dl_addr.set_dst(_port_to_mac_1['1'])) msg0.actions.append(of.ofp_action_output(port=1)) log.info('flow mod ends 1') self.connection.send(msg0) elif rqtport == 3: #r2 send the reply to r3 self.msg_send(packet, _port_to_mac_2['3'], _port_to_mac_3['3'], 3) log.info('flow mod starts 1') msg0 = of.ofp_flow_mod() msg0.match = of.ofp_match() msg0.match.dl_type = 0x800 msg0.match.nw_dst = packet.payload.dstip msg0.actions.append( of.ofp_action_dl_addr.set_src(_port_to_mac_2['3'])) msg0.actions.append( of.ofp_action_dl_addr.set_dst(_port_to_mac_3['3'])) msg0.actions.append(of.ofp_action_output(port=3)) log.info('flow mod ends 1') self.connection.send(msg0) else: #r2 send the reply to hosts self.msg_send(packet, rqthwsrc, _arp_cache[packet.payload.dstip], rqtport) else: if rqtport == 2: #r3 send the reply to r1 self.msg_send(packet, _port_to_mac_3['2'], _port_to_mac_1['2'], 2) log.info('flow mod starts 1') msg0 = of.ofp_flow_mod() msg0.match = of.ofp_match() msg0.match.dl_type = 0x800 msg0.match.nw_dst = packet.payload.dstip msg0.actions.append( of.ofp_action_dl_addr.set_src(_port_to_mac_3['2'])) msg0.actions.append( of.ofp_action_dl_addr.set_dst(_port_to_mac_1['2'])) msg0.actions.append(of.ofp_action_output(port=2)) log.info('flow mod ends 1') self.connection.send(msg0) elif rqtport == 3: #r3 send the reply to r2 self.msg_send(packet, _port_to_mac_3['3'], _port_to_mac_2['3'], 3) log.info('flow mod starts 1') msg0 = of.ofp_flow_mod() msg0.match = of.ofp_match() msg0.match.dl_type = 0x800 msg0.match.nw_dst = packet.payload.dstip msg0.actions.append( of.ofp_action_dl_addr.set_src(_port_to_mac_3['3'])) msg0.actions.append( of.ofp_action_dl_addr.set_dst(_port_to_mac_2['3'])) msg0.actions.append(of.ofp_action_output(port=3)) log.info('flow mod ends 1') self.connection.send(msg0) else: #r3 send the reply to hosts self.msg_send(packet, rqthwsrc, _arp_cache[packet.payload.dstip], rqtport) elif packet.find("ipv4"): for i in range(0, 9): if str(_route[i][0]) == str(packet.payload.dstip): tcpsrc = _route[i][1] tcpdst = _route[i][0] tcpport = _route[i][2] tcppfx = _route[i][3] tcphwsrc = _route[i][4] break if packet.payload.dstip in _arp_cache: if dpid == 1: if tcpport == 1: self.msg_send(packet, _port_to_mac_1['1'], _port_to_mac_2['1'], 1) elif tcpport == 2: self.msg_send(packet, _port_to_mac_1['2'], _port_to_mac_3['2'], 2) else: self.msg_send(packet, tcphwsrc, _arp_cache[tcpdst], tcpport) if dpid == 2: if inport == 1: self.msg_send(packet, tcphwsrc, _arp_cache[tcpdst], tcpport) else: self.msg_send(packet, _port_to_mac_2['1'], _port_to_mac_1['1'], 1) else: _buff[IPAddr(packet.payload.dstip)] = packet _ip_bf[IPAddr(packet.payload.dstip)] = packet.payload if dpid == 1: if tcpport == 1: #r1 broadcast arp request to r2 self.arp_request(packet, _arp_cache[_port_to_mac_1['1']], _port_to_mac_1['1'], 1) elif tcpport == 2: #r1 broadcast arp request to r3 self.arp_request(packet, _arp_cache[_port_to_mac_1['2']], _port_to_mac_1['2'], 2) else: self.arp_request(packet, tcpsrc, tcphwsrc, 4) self.arp_request(packet, tcpsrc, tcphwsrc, 5) self.arp_request(packet, tcpsrc, tcphwsrc, 6) elif dpid == 2: if tcpport == 1: #r2 broadcast arp request to r1 self.arp_request(packet, _arp_cache[_port_to_mac_2['1']], _port_to_mac_2['1'], 1) elif tcpport == 3: #r2 broadcast arp request to r3 self.arp_request(packet, _arp_cache[_port_to_mac_2['3']], _port_to_mac_2['3'], 3) else: self.arp_request(packet, tcpsrc, tcphwsrc, 7) self.arp_request(packet, tcpsrc, tcphwsrc, 8) self.arp_request(packet, tcpsrc, tcphwsrc, 9) else: if tcpport == 2: #r3 broadcast arp request to r1 self.arp_request(packet, _arp_cache[_port_to_mac_3['2']], _port_to_mac_3['2'], 2) elif tcpport == 3: #r3 broadcast arp request to r2 self.arp_request(packet, _arp_cache[_port_to_mac_3['3']], _port_to_mac_3['3'], 3) else: self.arp_request(packet, tcpsrc, tcphwsrc, 10) self.arp_request(packet, tcpsrc, tcphwsrc, 11) self.arp_request(packet, tcpsrc, tcphwsrc, 12)
def test_for_ipv6(event): ofmatch20_1 = of.ofp_match20() ofmatch20_1.fieldId = 1 ofmatch20_1.offset = 0 ofmatch20_1.length = 48 ofmatch20_2 = of.ofp_match20() ofmatch20_2.fieldId = 2 ofmatch20_2.offset = 48 ofmatch20_2.length = 48 ofmatch20_3 = of.ofp_match20() ofmatch20_3.fieldId = 3 ofmatch20_3.offset = 96 ofmatch20_3.length = 16 ofmatch20_4 = of.ofp_match20() ofmatch20_4.fieldId = 4 ofmatch20_4.offset = 112 ofmatch20_4.length = 64 ofmatch20_5 = of.ofp_match20() ofmatch20_5.fieldId = 5 ofmatch20_5.offset = 176 ofmatch20_5.length = 64 ofmatch20_6 = of.ofp_match20() ofmatch20_6.fieldId = 6 ofmatch20_6.offset = 240 ofmatch20_6.length = 16 ############################################################################## #table_mod 0 ############################################################################### msg = of.ofp_table_mod() msg.flowTable.matchFieldList.append(ofmatch20_1) msg.flowTable.command = 0 #OFPTC_ADD msg.flowTable.tableType = 0 #OF_MM_TABLE msg.flowTable.matchFieldNum = 1 msg.flowTable.tableSize = 128 msg.flowTable.tableId = 0 msg.flowTable.tableName = "FirstEntryTable" msg.flowTable.keyLength = 144 event.connection.send(msg) ############################################################################## #table_mod 1 ############################################################################### msg = of.ofp_table_mod() msg.flowTable.tableId = 0 msg.flowTable.command = 0 #OFPTC_ADD msg.flowTable.tableType = 3 msg.flowTable.tableSize = 128 msg.flowTable.keyLength = 144 msg.flowTable.tableName = "CC" event.connection.send(msg) ############################################################################## #flow_mod 1 ############################################################################### msg = of.ofp_flow_mod() msg.counterId = 0 msg.cookie = 0 msg.cookieMask = 0 msg.tableId = 0 msg.tableType = 0 #OF_MM_TABLE msg.priority = 0 msg.index = 0 #matchx 1 tempmatchx = of.ofp_matchx() tempmatchx.fieldId = 1 tempmatchx.offset = 0 tempmatchx.length = 48 tempmatchx.set_value("000000000001") tempmatchx.set_mask("ffffffffffff") msg.matchx.append(tempmatchx) #instruction writemetadatafrompacket 7 tempins = of.ofp_instruction_writemetadata() tempins.metaDataOffset = 32 tempins.value = [1, 1, 1, 1, 1, 1] tempins.writeLength = 48 #msg.instruction.append(tempins) tempins = of.ofp_instruction_gotodirecttable() tempins.nextTableId = 16 tempins.indexType = 0 tempins.packetOffset = 0 tempins.indexValue = 0 msg.instruction.append(tempins) event.connection.send(msg) ############################################################################## #flow_mod 2 ############################################################################### msg = of.ofp_flow_mod() msg.counterId = 4 msg.cookie = 0 msg.cookieMask = 0 msg.tableId = 0 msg.tableType = 3 msg.priority = 0 msg.index = 0 tempins = of.ofp_instruction_applyaction() action = of.ofp_action_deletefield() action.tagPosition = 0 action.tagLengthValueType = 0 action.tagLengthValue = 48 tempins.actionList.append(action) #msg.instruction.append(tempins) #instruction writemetadata 2 tempins = of.ofp_instruction_writemetadata() tempins.metaDataOffset = 0 tempins.writeLength = 0 tempins.value = [] #msg.instruction.append(tempins) tempins = of.ofp_instruction_applyaction() action = of.ofp_action_output() action.portId = 0x10045 action.metadataOffset = 0 action.metadataLength = 0 action.packetOffset = 0 tempins.actionList.append(action) msg.instruction.append(tempins) event.connection.send(msg)
def _handle_PacketIn(self, event): """ Handle packet in messages from the switch to implement above algorithm. """ packet = event.parsed def flood(message=None): """ Floods the packet """ msg = of.ofp_packet_out() if time.time() - self.connection.connect_time >= _flood_delay: # Only flood if we've been connected for a little while... if self.hold_down_expired is False: # Oh yes it is! self.hold_down_expired = True log.info("%s: Flood hold-down expired -- flooding", dpid_to_str(event.dpid)) if message is not None: log.debug(message) #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst) # OFPP_FLOOD is optional; on some switches you may need to change # this to OFPP_ALL. msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) else: pass #log.info("Holding down flood for %s", dpid_to_str(event.dpid)) msg.data = event.ofp msg.in_port = event.port self.connection.send(msg) def drop(duration=None): """ Drops this packet and optionally installs a flow to continue dropping similar ones for a while """ if duration is not None: if not isinstance(duration, tuple): duration = (duration, duration) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] msg.buffer_id = event.ofp.buffer_id self.connection.send(msg) elif event.ofp.buffer_id is not None: msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) self.macToPort[packet.src] = event.port # 1 if not self.transparent: # 2 if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered( ): drop() # 2a return if packet.dst.is_multicast: flood() # 3a else: if packet.dst not in self.macToPort: # 4 flood("Port for %s unknown -- flooding" % (packet.dst, )) # 4a else: port = self.macToPort[packet.dst] if port == event.port: # 5 # 5a log.warning( "Same port for packet from %s -> %s on %s.%s. Drop." % (packet.src, packet.dst, dpid_to_str( event.dpid), port)) drop(10) return # 6 log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port=port)) msg.data = event.ofp # 6a self.connection.send(msg)
def _clear_flowtable(self, dpid): msg = of.ofp_flow_mod(match=of.ofp_match(), command=of.OFPFC_DELETE) core.openflow.sendToDPID(dpid, msg.pack())
def Connect(self, host1, host2, path=None): """ Build a connection based on either @path or a new path found between host1's parent and host2's parent. @param host1 @param host2 @param path """ try: if path == None: path = self.graph.get_path(str(host1[u"_parent"]), str(host2[u"_parent"])) except KeyError: print("KeyError") return {} self.connections[path.get_id()] = Connection(path.get_id(), host1, host2) flows_to_install = {} for i in range(len(path)): n = path.at(i) dpid = n.get_dpid() if not dpid in flows_to_install: flows_to_install[dpid] = [] if n.get_ingress() == None and n.get_egress() == None: fmod = of.ofp_flow_mod(hard_timeout=0) fmod.match.dl_dst = EthAddr(host2["mac"]) fmod.match.dl_src = EthAddr(host1["mac"]) fmod.actions.append( of.ofp_action_output(port=int(host2["port_no"]))) flows_to_install[dpid].append(fmod) fmod = of.ofp_flow_mod(hard_timeout=0) fmod.match.dl_dst = EthAddr(host1["mac"]) fmod.match.dl_src = EthAddr(host2["mac"]) fmod.actions.append( of.ofp_action_output(port=int(host1["port_no"]))) flows_to_install[dpid].append(fmod) elif n.get_ingress() == None and n.get_egress() != None: fmod = of.ofp_flow_mod(hard_timeout=0) fmod.match.dl_dst = EthAddr(host2["mac"]) fmod.match.dl_src = EthAddr(host1["mac"]) fmod.actions.append( of.ofp_action_output(port=int(n.get_egress()))) flows_to_install[dpid].append(fmod) fmod = of.ofp_flow_mod(hard_timeout=0) fmod.match.dl_dst = EthAddr(host1["mac"]) fmod.match.dl_src = EthAddr(host2["mac"]) fmod.actions.append( of.ofp_action_output(port=int(host1["port_no"]))) flows_to_install[dpid].append(fmod) elif n.get_ingress() != None and n.get_egress() == None: fmod = of.ofp_flow_mod(hard_timeout=0) fmod.match.dl_dst = EthAddr(host2["mac"]) fmod.match.dl_src = EthAddr(host1["mac"]) fmod.actions.append( of.ofp_action_output(port=int(host2["port_no"]))) flows_to_install[dpid].append(fmod) fmod = of.ofp_flow_mod(hard_timeout=0) fmod.match.dl_dst = EthAddr(host1["mac"]) fmod.match.dl_src = EthAddr(host2["mac"]) fmod.actions.append( of.ofp_action_output(port=int(n.get_ingress()))) flows_to_install[dpid].append(fmod) elif n.get_ingress() != None and n.get_egress() != None: fmod = of.ofp_flow_mod(hard_timeout=0) fmod.match.dl_dst = EthAddr(host2["mac"]) fmod.match.dl_src = EthAddr(host1["mac"]) fmod.actions.append( of.ofp_action_output(port=int(n.get_egress()))) flows_to_install[dpid].append(fmod) fmod = of.ofp_flow_mod(hard_timeout=0) fmod.match.dl_dst = EthAddr(host1["mac"]) fmod.match.dl_src = EthAddr(host2["mac"]) fmod.actions.append( of.ofp_action_output(port=int(n.get_ingress()))) flows_to_install[dpid].append(fmod) else: print("ERROR::This should not have happened.") return flows_to_install
def _install_flow(self, p, c, n, port_src, port_dst=None, **kw): """Install a flow entry at c to forward packet coming form p to n""" node_p = core.Outband.t.name(p) node_c = core.Outband.t.name(c) node_n = core.Outband.t.name(n) inport = node_c.port(node_p) outport = node_c.port(node_n) if not inport: log.error('%s->%s: not found' % (node_c.name, node_p.name)) return if not outport: log.error('%s->%s: not found' % (node_c.name, node_n.name)) return nw_src = nw_dst = None info_src = info_dst = "" if port_src: nw_src = port_src.ip info_src = "%s(%s) => " % (port_src.parent.name, nw_src) if port_dst: nw_dst = port_dst.ip info_dst = " => %s(%s)" % (port_dst.parent.name, nw_dst) backport = node_n.port(node_c) if backport: mac = backport.mac else: log.error('%s->%s: link not found' % (node_n.name, node_c.name)) return str_from = "%s.%s" % (dpid_to_str(node_c.dpid), c) str_out = "%s.%s" % (dpid_to_str(node_n.dpid), n) eth_in, eth_out = '', '' if mac: eth_out = '!' if not outport or outport < 0 or not inport.num or inport.num < 0: log.error('unknown port: %s %s->%s %s' % (str_from, inport.num, outport.num, str_out)) return actions = [] if not mac and 'add_eth_label' in kw: mac = ETH_LABEL eth_out = '+' if not mac and 'del_eth_label' in kw: mac = ETHER_BROADCAST eth_out = '-' if mac: actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=outport.num)) match = of.ofp_match( in_port=inport.num, #nw_proto = ipv4.TCP_PROTOCOL, #dl_vlan = 1301, #dl_type = ethernet.VLAN_TYPE, dl_type=ethernet.IP_TYPE, nw_src=nw_src, #None, nw_dst=nw_dst) match.adjust_wildcards = False if 'with_eth_label' in kw or 'del_eth_label' in kw: match.dl_dst = ETH_LABEL eth_in = '*' if port_src and port_src.mac: match.dl_src = port_src.mac else: #log.error('unknown port_src.mac') return priority = of.OFP_DEFAULT_PRIORITY if 'add_eth_label' in kw: priority = FAILOVER_PRIORITY if mac: priority = of.OFP_DEFAULT_PRIORITY + 1 + outport.num if 'priority' in kw: priority = kw['priority'] if 'failover_entry' in kw: mark = '=>' else: mark = '->' if 'udp' in kw: match.nw_proto = ipv4.UDP_PROTOCOL log.info('%s%s %i%s%s%s%i %s%s', info_src, str_from, inport.num, eth_in, mark, eth_out, outport.num, str_out, info_dst) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, actions=actions, match=match, priority=priority) if 'failover_entry' in kw: self._add_failover_entry(c, msg) else: core.openflow.sendToDPID(node_c.dpid, msg.pack()) if (not ('udp' in kw)) and outport.mac: #sending to destination, separte udp traffic self._install_flow(p, c, n, port_src, port_dst, udp=True, priority=of.OFP_DEFAULT_PRIORITY + 99, **kw) return
def _handle_PacketIn(self, event): print('Load Balancer: ', balancer_plot) packet = event.parsed self.macToPort[packet.src] = event.port if packet.type == packet.ARP_TYPE: log.info("ARP Packet type") log.info('from ' + str(packet.next.protosrc) + ' to ' + str(packet.next.protodst)) self.ipToMac[str(packet.payload.protosrc)] = packet.src #client -> server : rewrite src as load balancer V if packet.next.protodst == LOAD_BALANCER['IP']: log.info('A Client arp req server') # Get the ARP request from packet arp_req = packet.next # Create ARP reply arp_rep = arp() arp_rep.opcode = arp.REPLY arp_rep.hwsrc = LOAD_BALANCER['MAC'] arp_rep.hwdst = arp_req.hwsrc arp_rep.protosrc = LOAD_BALANCER['IP'] arp_rep.protodst = arp_req.protosrc # Create the Ethernet packet ether = ethernet() ether.type = ethernet.ARP_TYPE ether.dst = packet.src ether.src = LOAD_BALANCER['MAC'] ether.set_payload(arp_rep) log.info('Faking ARP reply for client as loadbalancer') # Send the ARP reply to client msg = of.ofp_packet_out() msg.data = ether.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = event.port event.connection.send(msg) elif packet.next.protodst in clients_ip: # flooding between clients log.info(' ' + str(packet.src) + ' Flooding: wants to know who is: ' + str(packet.dst)) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.data = event.ofp event.connection.send(msg) elif packet.dst not in clients_ip: msg = of.ofp_packet_out() log.info(packet.payload.protosrc) msg.actions.append( of.ofp_action_output(port=self.macToPort[self.ipToMac[str( packet.next.protodst)]])) msg.data = event.ofp msg.in_port = event.port event.connection.send(msg) elif packet.type == packet.IP_TYPE: log.info("Sending non ARP packet") self.ipToMac[str(packet.next.srcip)] = packet.src if packet.dst == LOAD_BALANCER['MAC']: #client -> server , choose random server and create rule server_num = random.randint(0, 3) server_ip = servers_ip[server_num] self.results[server_num] = self.results[server_num] + 1 balancer_plot[server_ip] = self.results[server_num] server_mac = self.ipToMac[server_ip] server_port = self.macToPort[server_mac] server_ip = IPAddr(server_ip) server_mac = EthAddr(server_mac) msg = of.ofp_flow_mod() msg.idle_timeout = 1 msg.hard_timeout = 10 msg.buffer_id = None msg.match.in_port = server_port msg.match.dl_src = server_mac msg.match.dl_dst = packet.src msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_src = server_ip msg.match.nw_dst = packet.next.srcip msg.actions.append( of.ofp_action_nw_addr.set_src(LOAD_BALANCER['IP'])) msg.actions.append( of.ofp_action_dl_addr.set_src(LOAD_BALANCER['MAC'])) msg.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(msg) # install the forward rule from client to server + forward packet msg = of.ofp_flow_mod() msg.idle_timeout = 1 msg.hard_timeout = 10 msg.buffer_id = None msg.data = event.ofp msg.match.in_port = event.port msg.match.dl_src = packet.src msg.match.dl_dst = LOAD_BALANCER['MAC'] msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_src = packet.next.srcip msg.match.nw_dst = LOAD_BALANCER['IP'] msg.actions.append(of.ofp_action_nw_addr.set_dst(server_ip)) msg.actions.append(of.ofp_action_dl_addr.set_dst(server_mac)) msg.actions.append(of.ofp_action_output(port=server_port)) event.connection.send(msg) log.info("Installing %s with %s" % (packet.next.srcip, server_ip)) elif EthAddr(packet.dst) in clients_mac: #client -> client if EthAddr(packet.dst) not in self.macToPort: #flooding msg = of.ofp_packet_out() msg.actions.append( of.ofp_action_output(port=of.OFPP_FLOOD)) msg.data = event.ofp event.connection.send(msg) else: #client already discovered msg = of.ofp_flow_mod() msg.idle_timeout = 10 msg.hard_timeout = 30 msg.match = of.ofp_match.from_packet(packet, event.port) msg.actions.append( of.ofp_action_output( port=self.macToPort[EthAddr(packet.dst)])) msg.data = event.ofp msg.in_port = event.port event.connection.send(msg)
def _handle_openflow_discovery_LinkEvent(self, event): def flip(link): return Discovery.Link(link[2], link[3], link[0], link[1]) l = event.link sw1 = switches[l.dpid1] sw2 = switches[l.dpid2] # Invalidate all flows and path info. # For link adds, this makes sure that if a new link leads to an # improved path, we use it. # For link removals, this makes sure that we don't use a # path that may have been broken. #NOTE: This could be radically improved! (e.g., not *ALL* paths break) clear = of.ofp_flow_mod(command=of.OFPFC_DELETE) for sw in switches.itervalues(): if sw.connection is None: continue sw.connection.send(clear) path_map.clear() if event.removed: # This link no longer okay if sw2 in adjacency[sw1]: del adjacency[sw1][sw2] if sw1 in adjacency[sw2]: del adjacency[sw2][sw1] # But maybe there's another way to connect these... for ll in core.openflow_discovery.adjacency: if ll.dpid1 == l.dpid1 and ll.dpid2 == l.dpid2: if flip(ll) in core.openflow_discovery.adjacency: # Yup, link goes both ways adjacency[sw1][sw2] = ll.port1 adjacency[sw2][sw1] = ll.port2 # Fixed -- new link chosen to connect these break # Update "Ports" and remove entries for this port if swdebug: print "Link removed", l for switch in ports: for port in ports[switch]: if port is l.port1: if swdebug: print "Port removed = ", port del ports[switch][port] break if swdebug: print "****************** Printing ports after Link removed event ****************" print ports print "***************************************************************************" else: # If we already consider these nodes connected, we can # ignore this link up. # Otherwise, we might be interested... if event.added: ports[dpidToStr(l.dpid1)][l.port1] = [0.0, 100, 0, 0] ports[dpidToStr(l.dpid2)][l.port2] = [0.0, 100, 0, 0] if adjacency[sw1][sw2] is None: # These previously weren't connected. If the link # exists in both directions, we consider them connected now. if flip(l) in core.openflow_discovery.adjacency: # Yup, link goes both ways -- connected! adjacency[sw1][sw2] = l.port1 adjacency[sw2][sw1] = l.port2 # If we have learned a MAC on this port which we now know to # be connected to a switch, unlearn it. bad_macs = set() for mac, (sw, port) in mac_map.iteritems(): if sw is sw1 and port == l.port1: bad_macs.add(mac) if sw is sw2 and port == l.port2: bad_macs.add(mac) for mac in bad_macs: log.debug("Unlearned %s", mac) del mac_map[mac]
def s3_setup(self): #put switch 3 rules here fm=of.ofp_flow_mod() fm.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) self.connection.send(fm)
def send_table(self): if self.connection is None: self.log.debug("Can't send table: disconnected") return clear = of.ofp_flow_mod(command=of.OFPFC_DELETE) self.connection.send(clear) self.connection.send(of.ofp_barrier_request()) # From DHCPD msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_proto = pkt.ipv4.UDP_PROTOCOL #msg.match.nw_dst = IP_BROADCAST # add msg.match.tp_src = pkt.dhcp.CLIENT_PORT msg.match.tp_dst = pkt.dhcp.SERVER_PORT msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) #msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) self.connection.send(msg) core.openflow_discovery.install_flow(self.connection) src = self for dst in switches_by_dpid.itervalues(): if dst is src: continue p = _get_path(src, dst) log.info("their path: %s", str(p)) our_p = _our_get_path(src, dst) log.info("our path: %s", str(our_p)) # pdb.set_trace() p = our_p if (p is None) or \ (p[0] is None) or \ (len(p[0]) < 2) or (p[0][1] is None): continue msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = "%s/%s" % (dst.network, dst.subnet) msg.match.nw_dst = "%s/%s" % (dst.network, "255.255.0.0") msg.actions.append(of.ofp_action_output(port=p[0][1])) self.connection.send(msg) """ # Can just do this instead of MAC learning if you run arp_responder... for port in self.ports: p = port.port_no if p < 0 or p >= of.OFPP_MAX: continue msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_dst = "10.%s.%s.0/255.255.255.0" % (self._id,p) msg.actions.append(of.ofp_action_output(port=p)) self.connection.send(msg) """ for ip, mac in self.ip_to_mac.iteritems(): self._send_rewrite_rule(ip, mac) flood_ports = [] for port in self.ports: p = port.port_no if p < 0 or p >= of.OFPP_MAX: continue if core.openflow_discovery.is_edge_port(self.dpid, p): flood_ports.append(p) msg = of.ofp_flow_mod() msg.priority -= 1 msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_dst = "10.%s.%s.0/255.255.255.0" % (self._id, p) msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) self.connection.send(msg) msg = of.ofp_flow_mod() msg.priority -= 1 msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_dst = "255.255.255.255" for p in flood_ports: msg.actions.append(of.ofp_action_output(port=p)) self.connection.send(msg)
def _handle_PacketIn(self, event): dpid = event.connection.dpid #getting the switch in port of the packet inport = event.port #parsing the packet, used later to determine the outport and packet type packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} if isinstance(packet.next, ipv4): destinIP = packet.next.dstip log.info("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) #converting the destination ip address to string for future modifying stringIPaddress = str(destinIP) #splitting the des ip to get the last octet of the ip address last_Oct = stringIPaddress.split('.') intIP = int(last_Oct[-1]) #used for testing log.info("%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, destinIP, intIP)) log.info("ip address last digit is %s", intIP) #adding the output flow rule to forward the packet to the outport port got from the last octet of the des IP actions = of.ofp_action_output(port=intIP) #creating the match structure for the rule to match on match = of.ofp_match.from_packet(packet, inport) #creating the flow mod msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) #converting msg object to on-the-wire format and sending flow mod to the switch event.connection.send(msg.pack()) elif isinstance(packet.next, arp): a = packet.next log.info("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][a.protodst].mac e = ethernet( type=packet.type, src=EthAddr("%012x" % (dpid & 0xffFFffFFffFF, )), dst=a.hwsrc) e.set_payload(r) log.info("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def ipv4pkt_send2(self, packet, packet_in): log.debug("ipv4 function pkt send src ip %r dst ip %r" % (packet.payload.srcip, packet.payload.dstip)) dstip_pkt = packet.payload.dstip srcip_pkt = packet.payload.srcip if str(dstip_pkt) in self.network2: if str(srcip_pkt) in self.network2: msg = of.ofp_flow_mod() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.match.nw_src = packet.payload.srcip msg.match.nw_dst = packet.payload.dstip msg.match.in_port = packet_in.in_port msg.data = packet_in msg.actions.append( of.ofp_action_output( port=self.network2[str(dstip_pkt)][0])) self.connection.send(msg) elif str(srcip_pkt) in self.network1: log.debug("flow mode...") msg = of.ofp_flow_mod() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.match.nw_src = packet.payload.srcip msg.match.nw_dst = packet.payload.dstip msg.match.in_port = packet_in.in_port msg.data = packet_in msg.actions.append( of.ofp_action_dl_addr.set_dst( EthAddr(self.network2[str(dstip_pkt)][1]))) msg.actions.append(of.ofp_action_dl_addr.set_src(packet.dst)) msg.actions.append( of.ofp_action_output( port=self.network2[str(dstip_pkt)][0])) self.connection.send(msg) else: pass elif str(dstip_pkt) in self.network1: log.debug("forward the packet from %r to %r" % (packet.payload.srcip, packet.payload.dstip)) log.debug("flow mode...") msg = of.ofp_flow_mod() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.match.nw_src = packet.payload.srcip msg.match.nw_dst = packet.payload.dstip msg.match.in_port = packet_in.in_port msg.data = packet_in msg.actions.append( of.ofp_action_dl_addr.set_dst(EthAddr("10:10:10:10:10:10"))) msg.actions.append(of.ofp_action_dl_addr.set_src(packet.dst)) msg.actions.append(of.ofp_action_output(port=2)) self.connection.send(msg) else: pass
def do_firewall(self, packet, packet_in): # Variables idle_timeout = 30 # Time taken to timeout in seconds hard_timeout = 60 # Max time taken to timeout in seconds msg = of.ofp_flow_mod() # Match Packet msg.match = of.ofp_match.from_packet(packet) # Timeout timers msg.idle_timeout = idle_timeout msg.hard_timeout = hard_timeout protocol_ARP = packet.find('arp') protocol_TCP = packet.find('tcp') protocol_ICMP = packet.find('icmp') # ARP, TCP, or ICMP Check ### TCP Check ########################################################## if protocol_TCP is not None: # Check if IPv4 protocol_IPv4 = packet.find('ipv4') # Determine if traffic flow from 10.0.1.40 to 10.0.1.10 or vice versa if (protocol_IPv4.srcip == '10.0.1.40' and protocol_IPv4.dstip == '10.0.1.10') or (protocol_IPv4.srcip == '10.0.1.10' and protocol_IPv4.dstip == '10.0.1.40'): # Take in data packet msg.data = packet_in # Check if TCP type msg.nw_proto = 6 ###-*-### # Action to send to specified port ###-*-### action = of.ofp_action_output(port = of.OFPP_FLOOD) msg.actions.append(action) # Send message to switch self.connection.send(msg) # If source/destination IP don't match condition, then just direct to switch else: # Send message to switch self.connection.send(msg) ### ICMP Check ######################################################### elif protocol_ICMP is not None: # Take in data packet msg.data = packet_in # Check if TCP type msg.IP_PROTO = 1 ###-*-### # Action to send to specified port ###-*-### action = of.ofp_action_output(port = of.OFPP_FLOOD) msg.actions.append(action) # Send message to switch self.connection.send(msg) #### ARP Check ######################################################### elif protocol_ARP is not None: # Take in data packet msg.data = packet_in # Check if ARP type msg.match.dl_type = 0x8086 ###-*-### # Action to send to specified port ###-*-### action = of.ofp_action_output(port = of.OFPP_FLOOD) msg.actions.append(action) # Send message to switch self.connection.send(msg) ###################################################################### else: self.connection.send(msg)
def test_GOTO_TABLE(event): out_port =4 num = len(event.connection.phyports) msg = of.ofp_port_mod() portmessage = event.connection.phyports[1] msg.setByPortState(portmessage) msg.desc.openflowEnable = 1 event.connection.send(msg) ofmatch20_1 =of.ofp_match20() ofmatch20_1.fieldId=1; ofmatch20_1.offset=0; ofmatch20_1.length=48; ############################################################################### # table_mode 1 ############################################################################### print " config flowTable 1" msg =of.ofp_table_mod() msg.flowTable.matchFieldList.append(ofmatch20_1) msg.flowTable.command=0 #OFPTC_ADD msg.flowTable.tableType=0 #OF_MM_TABLE msg.flowTable.matchFieldNum = 1 #msg.flowTable.matchFieldNum=len(msg.flowTable.matchFieldList) msg.flowTable.tableSize=128 msg.flowTable.tableId=0 msg.flowTable.tableName="FirstEntryTable" msg.flowTable.keyLength=48 event.connection.send(msg) ############################################################################## #flow_mod 1 ############################################################################### msg=of.ofp_flow_mod() msg.counterId=1 msg.cookie=0 msg.cookieMask=0 msg.tableId=0 msg.tableType=0 #OF_MM_TABLE msg.priority=0 msg.index=0 tempmatchx=of.ofp_matchx() tempmatchx.fieldId=1 tempmatchx.offset=0 tempmatchx.length=48 tempmatchx.set_value("00") # null tempmatchx.set_mask("00") msg.matchx.append(tempmatchx) #instruction tempins=of.ofp_instruction_gototable() tempins.nextTableId=1 tempins.packetOffset=0 tempins.matchList.append(ofmatch20_1) msg.instruction.append(tempins) event.connection.send(msg) ############################################################################### # table_mode 2 ############################################################################### print " config flowTable 2" msg =of.ofp_table_mod() msg.flowTable.matchFieldList=[] msg.flowTable.matchFieldList.append(ofmatch20_1) msg.flowTable.command=0 #OFPTC_ADD msg.flowTable.tableType=0 #OF_MM_TABLE msg.flowTable.matchFieldNum = 1 #msg.flowTable.matchFieldNum=len(msg.flowTable.matchFieldList) msg.flowTable.tableSize=128 msg.flowTable.tableId=1 msg.flowTable.tableName="Table 2" msg.flowTable.keyLength=48 event.connection.send(msg) ############################################################################## #flow_mod 1 ############################################################################### msg=of.ofp_flow_mod() msg.counterId=2 msg.cookie=0 msg.cookieMask=0 msg.tableId=1 msg.tableType=0 #OF_MM_TABLE msg.priority=0 msg.index=0 tempmatchx=of.ofp_matchx() tempmatchx.fieldId=1 tempmatchx.offset=0 tempmatchx.length=48 tempmatchx.set_value("00") # null tempmatchx.set_mask("00") msg.matchx.append(tempmatchx) #instruction tempins=of.ofp_instruction_applyaction() action=of.ofp_action_output() action.portId=out_port action.metadataOffset=0 action.metadataLength=0 action.packetOffset=0 tempins.actionList.append(action) msg.instruction.append(tempins) event.connection.send(msg)