def _handle_PacketIn(event): global server_index packet = event.parsed # First make sure the packet is addressed using IPv4 if (not event.parsed.find("ipv4")): return EventContinue msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) # If the ip matches controller virtual ip then continue if (msg.match.nw_dst != controllerip): return EventContinue # Employing round robin algorithm here index = server_index % total_servers print index selected_server_ip = server[index]['ip'] selected_server_mac = server[index]['mac'] selected_server_outport = server[index]['outport'] server_index += 1 # Setup route to server msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip)) msg.actions.append(of.ofp_action_output(port=selected_server_outport)) event.connection.send(msg) # Once the last server is reached, reverse the route reverse_msg = of.ofp_flow_mod() reverse_msg.buffer_id = None reverse_msg.in_port = selected_server_outport reverse_msg.match = of.ofp_match() reverse_msg.match.dl_src = selected_server_mac reverse_msg.match.nw_src = selected_server_ip reverse_msg.match.tp_src = msg.match.tp_dst reverse_msg.match.dl_dst = msg.match.dl_src reverse_msg.match.nw_dst = msg.match.nw_src reverse_msg.match.tp_dst = msg.match.tp_src reverse_msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, controllermac)) reverse_msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, controllerip)) reverse_msg.actions.append(of.ofp_action_output(port=msg.in_port)) event.connection.send(reverse_msg) return EventHalt
def _handle_PacketIn(event): global server_index packet = event.parsed # Only handle IPv4 flows if (not event.parsed.find("ipv4")): return EventContinue msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) # Only handle traffic destined to virtual IP if (msg.match.nw_dst != virtual_ip): return EventContinue # Round robin selection of servers index = server_index % total_servers print index selected_server_ip = server[index]['ip'] selected_server_mac = server[index]['mac'] selected_server_outport = server[index]['outport'] server_index += 1 # Setup route to server msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip)) msg.actions.append(of.ofp_action_output(port=selected_server_outport)) event.connection.send(msg) # Setup reverse route from server reverse_msg = of.ofp_flow_mod() reverse_msg.buffer_id = None reverse_msg.in_port = selected_server_outport reverse_msg.match = of.ofp_match() reverse_msg.match.dl_src = selected_server_mac reverse_msg.match.nw_src = selected_server_ip reverse_msg.match.tp_src = msg.match.tp_dst reverse_msg.match.dl_dst = msg.match.dl_src reverse_msg.match.nw_dst = msg.match.nw_src reverse_msg.match.tp_dst = msg.match.tp_src reverse_msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac)) reverse_msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, virtual_ip)) reverse_msg.actions.append(of.ofp_action_output(port=msg.in_port)) event.connection.send(reverse_msg) return EventHalt
def packet_handler(event): global server_no packet = event.parsed # Only handle traffic destined to virtual IP if (not event.parsed.find("ipv4")): return event_cont message = of.ofp_flow_mod() message.match = of.ofp_match.from_packet(packet) # Handing requests routed to the Load Balancer Ip if (message.match.nw_dst != load_balancer_hardcoded_ip): return event_cont # Random selection of servers iterator = random.randint(0, server_no - 1) print iterator serverip = topology_server[iterator]['ip'] selected_server_mac = topology_server[iterator]['mac'] server_output = topology_server[iterator]['outport'] # Route followed to server message.buffer_id = event.ofp.buffer_id message.in_port = event.port message.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, serverip)) message.actions.append(of.ofp_action_output(port=server_output)) event.connection.send(message) # Route from server to load balancer reply = of.ofp_flow_mod() reply.buffer_id = None reply.in_port = server_output reply.match = of.ofp_match() reply.match.dl_src = selected_server_mac reply.match.nw_src = serverip reply.match.tp_src = message.match.tp_dst reply.match.dl_dst = message.match.dl_src reply.match.nw_dst = message.match.nw_src reply.match.tp_dst = message.match.tp_src reply.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac)) reply.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, load_balancer_hardcoded_ip)) reply.actions.append(of.ofp_action_output(port=message.in_port)) event.connection.send(reply) return EventHalt
def _handle_PacketIn (event): global server_index packet = event.parsed # Only handle IPv4 flows if (not event.parsed.find("ipv4")): return EventContinue msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) # Only handle traffic destined to virtual IP if (msg.match.nw_dst != virtual_ip): return EventContinue # Round robin selection of servers index = server_index % total_servers print index selected_server_ip = server[index]['ip'] selected_server_mac = server[index]['mac'] selected_server_outport = server[index]['outport'] server_index += 1 # Setup route to server msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, selected_server_ip)) msg.actions.append(of.ofp_action_output(port = selected_server_outport)) event.connection.send(msg) # Setup reverse route from server reverse_msg = of.ofp_flow_mod() reverse_msg.buffer_id = None reverse_msg.in_port = selected_server_outport reverse_msg.match = of.ofp_match() reverse_msg.match.dl_src = selected_server_mac reverse_msg.match.nw_src = selected_server_ip reverse_msg.match.tp_src = msg.match.tp_dst reverse_msg.match.dl_dst = msg.match.dl_src reverse_msg.match.nw_dst = msg.match.nw_src reverse_msg.match.tp_dst = msg.match.tp_src reverse_msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac)) reverse_msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, virtual_ip)) reverse_msg.actions.append(of.ofp_action_output(port = msg.in_port)) event.connection.send(reverse_msg) return EventHalt
def CreateActions(self, actions, entry, outbound): if outbound: actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external)) actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, NAT_IP_EXTERNAL)) actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC, entry["natport"])) actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, GetMACFromIP(entry["extip"]))) actions.append(of.ofp_action_output(port=self.port_external)) else: actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external)) actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, entry["int"])) actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, entry["intip"])) actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_DST, entry["intport"])) actions.append(of.ofp_action_output(port=GetPortFromIP(entry["intip"])))
def _match_action(self,msg): if len(self.actions) == 1 and self.actions[0] == "" : return for action in self.actions: action_name = action.split('=')[0] if action_name != "STRIP_VLAN": action_argu = action.split('=')[1] if(action_name == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(action_argu))) elif(action_name == "ENQUEUE"): port = action_argu.split(':')[0] queue_id = action_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(action_name == "STRIP_VLAN"): msg.actions.append(of.ofp_action_strip_vlan()) elif(action_name == "SET_VLAN_VID"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(action_argu))) elif(action_name == "SET_VLAN_PCP"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(action_argu))) elif(action_name == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(action_argu))) elif(action_name == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(action_argu))) elif(action_name == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(action_argu))) elif(action_name == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(action_argu))) elif(action_name == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(action_argu))) elif(action_name == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(action_argu))) elif(action_name == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(action_argu)))
def Round_Robin(event): global ServerUsed global server_virtual_ip global server_virtual_mac packet = event.parsed msg_to_server = of.ofp_flow_mod() msg_to_server.match = of.ofp_match.from_packet(packet) if (event.parsed.find("ipv4")) and (msg_to_server.match.nw_dst == server_virtual_ip): print ('Server in Service => Server :', ServerUsed) server_ip = serverList[ServerUsed] ['ip'] print ('With IP => ServerIP = :', server_ip) server_mac= serverList[ServerUsed]['mac'] server_outport= serverList[ServerUsed]['port'] # Setup route to server # setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport) msg_to_server.buffer_id = event.ofp.buffer_id msg_to_server.in_port = event.port msg_to_server.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, server_mac)) msg_to_server.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, server_ip)) msg_to_server.actions.append(of.ofp_action_output(port = server_outport)) event.connection.send(msg_to_server) # Setup reverse route from server # setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport) msg_from_server = of.ofp_flow_mod()
def send_arp_request(self, connection, ip): log.debug("FUNCTION: send_arp_request") arp_req = arp() arp_req.hwtype = arp_req.HW_TYPE_ETHERNET arp_req.prototype = arp_req.PROTO_TYPE_IP arp_req.hwlen = 6 arp_req.protolen = arp_req.protolen arp_req.opcode = arp.REQUEST arp_req.protodst = ip arp_req.hwsrc = LOADBALANCER_MAC arp_req.hwdst = ETHERNET_BROADCAST_ADDRESS arp_req.protosrc = self.LOADBALANCER_IP eth = ethernet() #Creating ethernet frame eth.type = eth.ARP_TYPE eth.dst = ETHERNET_BROADCAST_ADDRESS eth.set_payload(arp_req) msg = of.ofp_packet_out() msg.data = eth.pack() msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, ip)) msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) #Appending the action to the message telling the switch to flood the package connection.send(msg)
def _arp(event): packet = event.parsed arp_packet = packet.find('arp') ip_src = str(arp_packet.protosrc) ip_dst = str(arp_packet.protodst) mac_src = ipToMac[ip_src] mac_dst = ipToMac[ip_dst] if arp_packet is not None: print "From host : ip = ", ip_src, ", mac = ", mac_src print "To host : ip = ", ip_dst, ", mac = ", mac_dst if arp_packet.opcode == arp.REQUEST: #print "arp.REQUEST" #create arp packet a = arp() a.opcode = arp.REPLY #if request from src, fake reply from dst if arp_packet.hwsrc == EthAddr(mac_src): a.hwsrc = EthAddr(mac_dst) a.hwdst = EthAddr(mac_src) elif arp_packet.hwsrc == EthAddr(mac_dst): a.hwsrc = EthAddr(mac_src) a.hwdst = EthAddr(mac_dst) #fake reply IP a.protosrc = IPAddr(ip_dst) a.protodst = arp_packet.protosrc a.hwlen = 6 a.protolen = 4 a.hwtype = arp.HW_TYPE_ETHERNET a.prototype = arp.PROTO_TYPE_IP #create ethernet packet e = ethernet() e.set_payload(a) e.type = ethernet.ARP_TYPE if arp_packet.hwsrc == EthAddr(mac_src): e.src = EthAddr(mac_dst) e.dst = EthAddr(mac_src) elif arp_packet.hwsrc == EthAddr(mac_dst): e.src = EthAddr(mac_src) e.dst = EthAddr(mac_dst) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, IPAddr(ip_dst))) msg.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(msg) getRandomPath(mac_src, mac_dst) # choice random path from h_src to h_dst getRandomPath( mac_dst, mac_src ) # choice random path from h_dst to h_src (back transfer) print "-------------------------------------------------------\n" print "Random path : \t"
def send_proxied_arp_request(self, connection, ip): #construct the arp packet ar = arp() #type of packet ar.hwtype = ar.HW_TYPE_ETHERNET #type of hardware tyr ar.prototype = ar.PROTO_TYPE_IP #protocol type ar.hwlen = 6 #hardware addrese length 6 bytes and mac=ipv6 ar.protolen = ar.protolen #the ipv4 length ar.opcode = ar.REQUEST ar.hwdst = self.ethernet_broad # broadcast to all possible interfaces ar.protodst = ip #ip dest to send ar.hwsrc = self.lb_mac #fake mac address ar.protosrc = self.lb_real_ip # the real ip of the address # packet has inside it the r packet e = ethernet(type=ethernet.ARP_TYPE, src=self.lb_mac, dst=self.ethernet_broad) e.set_payload( ar) # take the previous packet and put it into th message data msg = of.ofp_packet_out( ) # send packet out cause we dont need an entry in the flow table msg.data = e.pack() msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, ip)) # send to this ip msg.actions.append( of.ofp_action_output(port=of.OFPP_FLOOD)) # flood to all ports connection.send(msg)
def send_arp_request(self, connection, ip): # Difficulties? https://en.wikipedia.org/wiki/Address_Resolution_Protocol#Example log.debug("FUNCTION: send_arp_request") arp_req = arp() arp_req.hwtype = arp_req.HW_TYPE_ETHERNET arp_req.prototype = arp_req.PROTO_TYPE_IP arp_req.hwlen = 6 arp_req.protolen = arp_req.protolen arp_req.opcode = arp_req.REQUEST # ADD OPCODE arp_req.protodst = ip # IP the load balancer is looking for arp_req.hwsrc = LOADBALANCER_MAC # Set the MAC source of the ARP REQUEST arp_req.hwdst = ETHERNET_BROADCAST_ADDRESS # Set the MAC address in such a way that the packet is marked as a Broadcast arp_req.protosrc = self.LOADBALANCER_IP # Set the IP source of the ARP REQUEST eth = ethernet( ) # Create an ethernet frame and set the arp_req as it's payload. eth.type = ethernet.ARP_TYPE # Set packet Typee eth.dst = ETHERNET_BROADCAST_ADDRESS # Set the MAC address in such a way that the packet is marked as a Broadcast eth.set_payload(arp_req) msg = of.ofp_packet_out( ) # create the necessary Openflow Message to make the switch send the ARP Request msg.data = eth.pack() msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, ip)) msg.actions.append( of.ofp_action_output(port=of.OFPP_FLOOD) ) # append an action to the message which makes the switch flood the packet out connection.send(msg)
def send_ofmod_modify_forward(self, _called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst, fport, duration): msg = of.ofp_flow_mod() msg.priority = 0x7000 msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4) msg.match.nw_src = IPAddr(nw_src) msg.match.nw_dst = IPAddr(nw_dst) msg.match.nw_proto = 17 #UDP if tp_dst != None: msg.match.tp_dst = int(tp_dst) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] if _called_from == 'packet_in': msg.buffer_id = event.ofp.buffer_id msg.actions.append( of.ofp_action_nw_addr(nw_addr=IPAddr(new_dst), type=7)) msg.actions.append( of.ofp_action_dl_addr(dl_addr=EthAddr(new_dl_dst), type=5)) msg.actions.append(of.ofp_action_output(port=fport)) conn.send(msg) print '\nsend_ofmod_modify_forward to sw_dpid=%s' % conn.dpid print 'wcs: src_ip=%s, dst_ip=%s, tp_dst=%s' % (nw_src, nw_dst, tp_dst) print 'acts: new_dst=%s, new_dl_dst=%s, fport=%s\n' % ( new_dst, new_dl_dst, fport)
def _match_action(self,msg): if(self.actions == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(self.actions_argu))) elif(self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif(self.actions == "set-vlan-id"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu))) elif(self.actions == "set-vlan-priority"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu))) elif(self.actions == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu))) elif(self.actions == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu))) elif(self.actions == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu)))
def CreateActions(self, actions, entry, outbound): if outbound: actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external)) actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, NAT_IP_EXTERNAL)) actions.append( of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC, entry["natport"])) actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, GetMACFromIP(entry["extip"]))) actions.append(of.ofp_action_output(port=self.port_external)) else: actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, self.if_external)) actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, entry["int"])) actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, entry["intip"])) actions.append( of.ofp_action_tp_port(of.OFPAT_SET_TP_DST, entry["intport"])) actions.append( of.ofp_action_output(port=GetPortFromIP(entry["intip"])))
def send_ofmod_modify_forward (_called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst,o_port, duration): msg = of.ofp_flow_mod() msg.priority = 0x7000 msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4) msg.match.nw_src = IPAddr(nw_src) msg.match.nw_dst = IPAddr(nw_dst) msg.match.nw_proto = 17 #UDP if tp_dst != None: msg.match.tp_dst = int(tp_dst) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] if _called_from == 'packet_in': msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7)) msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5)) msg.actions.append(of.ofp_action_output(port = o_port)) conn.send(msg) print "\nFrom dpid: ", conn.dpid, "send_ofmod_modify_forward", "src_ip: ",nw_src, print " dst_ip: ",nw_dst," tp_dst: ",tp_dst," new_dst_ip: ",new_dst, " new_dst_mac: ", new_dl_dst, " fport: ", o_port, " is sent\n"
def send_ofmod_modify_forward(self, _called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst,fport, duration): msg = of.ofp_flow_mod() msg.priority = 0x7000 msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4) msg.match.nw_src = IPAddr(nw_src) msg.match.nw_dst = IPAddr(nw_dst) msg.match.nw_proto = 17 #UDP if tp_dst != None: msg.match.tp_dst = int(tp_dst) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] if _called_from == 'packet_in': msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7)) msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5)) msg.actions.append(of.ofp_action_output(port = fport)) conn.send(msg) print '\nsend_ofmod_modify_forward to sw_dpid=%s' % conn.dpid print 'wcs: src_ip=%s, dst_ip=%s, tp_dst=%s' % (nw_src,nw_dst,tp_dst) print 'acts: new_dst=%s, new_dl_dst=%s, fport=%s\n' % (new_dst, new_dl_dst, fport)
def send_ofmod_modify_forward (self, _called_from, conn, nw_src, nw_dst, tp_dst, new_dst, new_dl_dst, o_port, duration): msg = of.ofp_flow_mod() msg.priority = 0x7000 msg.match.dl_type = 0x800 # Ethertype / length (e.g. 0x0800 = IPv4) msg.match.nw_src = IPAddr(nw_src) msg.match.nw_dst = IPAddr(nw_dst) if tp_dst != None: msg.match.nw_proto = 17 #UDP msg.match.tp_dst = int(tp_dst) msg.idle_timeout = duration[0] msg.hard_timeout = duration[1] if _called_from == 'packet_in': msg.buffer_id = event.ofp.buffer_id msg.actions.append(of.ofp_action_nw_addr(nw_addr = IPAddr(new_dst), type=7)) msg.actions.append(of.ofp_action_dl_addr(dl_addr = EthAddr(new_dl_dst), type=5)) msg.actions.append(of.ofp_action_output(port = o_port)) conn.send(msg) print "\nFrom dpid: ", conn.dpid, "send_ofmod_modify_forward", "src_ip: ", \ nw_src," dst_ip: ",nw_dst," tp_dst: ",tp_dst," new_dst_ip: ",new_dst, \ " new_dst_mac: ", new_dl_dst, " fport: ", o_port, " is sent\n"
def _handle_PacketIn (self, event): """ Handle packet in messages from the switch to implement above algorithm. """#52:54:00:79:95:26 26:6a:fb:3c:f8:fd cptv = server_infos(conf.captive_portal.ip,conf.captive_portal.mac,conf.captive_portal.switch_port,conf.captive_portal.tcp_port)#"130.192.225.168","52:54:00:79:95:26",5,8085) #cptv = server_infos("130.192.225.156","88:51:fb:42:2b:f8",5,8080) if self.connection.dpid not in switchs_info: lock.acquire() try: dpi = DPI() dpi.setDPI(self.connection.dpid) # add a new switch to our infos switchs_info[self.connection.dpid] = switch_infos(self.connection) finally: lock.release() # release lock, no matter what switch = switchs_info[self.connection.dpid] if event.port not in switch.ports_info: lock.acquire() try: #print (dpid_to_str(self.connection.dpid)) #print self.connection.sock.getpeername()[0] switch.ports_info[event.port] = port_infos(event.port) finally: lock.release() # release lock, no matter what #if event.port == conf.my_infos.my_default_GRE_tunnel: is_user_port = True log.info("Comparing the ports speaking " + str(event.port)) for not_user_port in conf.my_infos.not_user_ports: if str(event.port) == str(not_user_port): is_user_port = False break if not is_user_port: log.info("Event port is " + str(event.port)) log.info("First for the ethernet interface") # First rule: allow all traffic self.connection.send( of.ofp_flow_mod( action=of.ofp_action_output(port=of.OFPP_NORMAL), priority=1, match=of.ofp_match( in_port = event.port))) else: """ Packet from user """ log.info("First packet from user") # First rule: drop all traffic msg = of.ofp_flow_mod() msg.priority = 1 msg.match.in_port = event.port msg.actions.append(of.ofp_action_output(port=of.OFPP_NONE)) self.connection.send(msg) # Second rule: normal process for DNS traffic msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 17 msg.match.tp_dst = 53 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Third rule: normal process for ARP traffic msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x806 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Fourth rule: normal process for DHCPDISCOVER msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 17 msg.match.nw_src = "0.0.0.0" msg.match.nw_dst = "255.255.255.255" msg.match.tp_src = 68 msg.match.tp_dst = 67 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Fifth rule: send the HTTP traffic to the controller msg = of.ofp_flow_mod() msg.priority = 1000 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 6 msg.match.tp_dst = 80 msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) msg.data = event.ofp self.connection.send(msg) packet = event.parsed if not packet.parsed: log.info("ignoring unparsed packet") return client_list = switch.ports_info[event.port].clients_info log.info("LOOP Thread id: "+str(thread.get_ident() )) log.debug("packet.type: "+ str(packet.type) +" || pkt.ethernet.IP_TYPE: "+ str(pkt.ethernet.IP_TYPE)) if packet.type == pkt.ethernet.IP_TYPE: ipv4_hdr = packet.payload log.debug("ipv4_hdr.protocol: "+ str(ipv4_hdr.protocol) +" || pkt.ipv4.TCP_PROTOCOL: "+ str(pkt.ipv4.TCP_PROTOCOL)) if ipv4_hdr.protocol == pkt.ipv4.TCP_PROTOCOL: tcp_hdr = ipv4_hdr.payload log.info("tcp_hdr.dstport: "+ str(tcp_hdr.dstport) +" || DestPort: || 80") if tcp_hdr.dstport == 80: log.debug("packet.src: "+ str(packet.src)) if str(packet.src) not in client_list: log.info("packet.src is not in client_list") lock.acquire() try: log.info("save host info: IP=" + str(ipv4_hdr.srcip) + ", MAC=" + str(packet.src) + ", INGRESS_SWITCH_PORT=" + str(switch.infos.ports[event.port].name)) client_list[str(packet.src)] = host_infos(ipv4_hdr.srcip,packet.src,event.port,0) finally: lock.release() # release lock, no matter what else: log.debug("PACKET_IN INFOs: user MAC: "+ str(packet.src)+", user IP: "+ str(ipv4_hdr.srcip)) user_infos = client_list[str(packet.src)] user_ip = user_infos.IP log.debug("Local informations: user MAC: "+ str(packet.src)+", user IP: "+ str(user_ip)) if user_ip != ipv4_hdr.srcip: log.debug("Updating client IP informations") user_infos.IP = ipv4_hdr.srcip client = client_list[str(packet.src)] if (client.flag_auth == 0): log.info("installing new flow to set destination IP to captive portal IP") msg = of.ofp_flow_mod() msg.priority = 10000 msg.idle_timeout=30 msg.match.dl_type = 0x800 msg.match.dl_src = client.MAC msg.match.nw_proto = 6 #Adding the match on the TCP source port of the user, in order to genererate a PACKET_IN for every #new TCP connection msg.match.tp_src = tcp_hdr.srcport msg.match.tp_dst = 80 msg.match.nw_dst = ipv4_hdr.dstip msg.match.in_port = event.port msg.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST,cptv.MAC)) msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST,cptv.IP)) msg.actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_DST,cptv.port)) msg.actions.append(of.ofp_action_output(port=cptv.switch_port)) #msg.data = event.ofp self.connection.send(msg) log.info("installing new flow to set return path") msg = of.ofp_flow_mod() msg.priority = 10000 msg.idle_timeout=30 msg.match.dl_type = 0x800 msg.match.nw_proto = 6 msg.match.tp_dst = tcp_hdr.srcport msg.match.nw_dst = ipv4_hdr.srcip msg.match.nw_src = cptv.IP msg.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC,ipv4_hdr.dstip)) msg.actions.append(of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC,tcp_hdr.dstport)) msg.actions.append(of.ofp_action_output(port=event.port)) msg.data = event.ofp self.connection.send(msg) '''
def handle_IPPacket( self, event ): is_src_router = (event.ofp.in_port == of.OFPP_LOCAL) # @UndefinedVariable if event.parsed.next.srcip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "source ip is not routable" return if event.parsed.src != self.bridge_mac and not self.check_access(event.parsed.src): print "%s is not permmited" % (str(event.parsed.src)) return if event.parsed.next.dstip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "destination is not routable" return is_src_local = event.parsed.next.srcip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.srcip.inNetwork(INIT_SUBNET, INIT_NETMASK) if is_src_local and (event.parsed.next.srcip.toUnsigned(networkOrder=False) & 0x3) == 1: if not self.get_DHCP_mapping().is_valid_mapping(event.parsed.next.srcip, event.parsed.src) and event.parsed.src != self.bridge_mac: print "received packet from unrecorded mac address" return if event.parsed.next.dstip.inNetwork(MULTICAST_SUBNET, MULTICAST_NETMASK): print "multicast" if event.parsed.next.dstip in self.multicast_ip: action = of.ofp_action_output(port=of.OFPP_FLOOD) # @UndefinedVariable command = of.OFPFC_ADD # @UndefinedVariable self.send_flow_modification(event, command, [action], timeout=30) # check if broadcast. Change nw_dst to 10.2.255.255 if event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ((event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x3) == 0x3): print "broadcast IP" nw_new = of.ofp_action_nw_addr() nw_new.type = of.OFPAT_SET_NW_DST # @UndefinedVariable nw_new.nw_addr = IPAddr("10.2.255.255") out = of.ofp_action_output(port=of.OFPP_IN_PORT if event.ofp.in_port == 0 else 0) # @UndefinedVariable actions = [out, nw_new] command = of.OFPFC_ADD # @UndefinedVariable self.send_flow_modification(event, command, actions, timeout=30) dst_port = 0 if event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ((event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x01) == 0x01): dst_port = 1 else: dst_port = 0 actions = [] is_dst_local = event.parsed.next.dstip.inNetwork(ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.dstip.inNetwork(INIT_SUBNET, INIT_NETMASK) if is_dst_local and is_src_local and (dst_port != 0) and (not is_src_router): dst_mac = self.get_DHCP_mapping().get_mac(event.parsed.next.dstip) new_dl_src = of.ofp_action_dl_addr() new_dl_src.type = of.OFPAT_SET_DL_SRC # @UndefinedVariable new_dl_src.set_src(self.bridge_mac) actions.append(new_dl_src) new_dl_dst = of.ofp_action_dl_addr() new_dl_dst.type = of.OFPAT_SET_DL_DST # @UndefinedVariable new_dl_dst.set_dst(dst_mac) actions.append(new_dl_dst) out = of.ofp_action_output(port=of.OFPP_FLOOD) # @UndefinedVariable actions.append(out) if 0 < event.ofp.in_port and event.ofp.in_port < of.OFPP_MAX: # @UndefinedVariable out_of_in = of.ofp_action_output(port=of.OFPP_IN_PORT) # @UndefinedVariable actions.append(out_of_in) command = of.OFPFC_ADD # @UndefinedVariable self.send_flow_modification(event, command, actions, timeout=30)
def packet_handler(event): global count_server packet = event.parsed # Only handle IPv4 flows if (not event.parsed.find("ipv4")): return event_cont message = of.ofp_flow_mod() message.match = of.ofp_match.from_packet(packet) # Handing requests routed to the Load Balancer Ip if (message.match.nw_dst != virtual_ip): return event_cont # Implemented Weighted Random Server Selection iterator = server_no % 6 print iterator if (IPAddr(message.match.nw_src) in clients): iterator = clients[IPAddr(message.match.nw_src)] serverip = topology_server[iterator]['ip'] selected_server_mac = topology_server[iterator]['mac'] server_output = topology_server[iterator]['outport'] elif (iterator < topology_server[0]['weight']): serverip = topology_server[0]['ip'] selected_server_mac = topology_server[0]['mac'] server_output = topology_server[0]['outport'] clients[IPAddr(message.match.nw_src)] = 0 server_no += 1 elif (iterator < (topology_server[0]['weight'] + topology_server[1]['weight'])): serverip = topology_server[1]['ip'] selected_server_mac = topology_server[1]['mac'] server_output = topology_server[1]['outport'] clients[IPAddr(message.match.nw_src)] = 1 server_no += 1 elif (iterator < (topology_server[0]['weight'] + topology_server[1]['weight'] + topology_server[2]['weight'])): serverip = topology_server[2]['ip'] selected_server_mac = topology_server[2]['mac'] server_output = topology_server[2]['outport'] clients[IPAddr(message.match.nw_src)] = 2 server_no += 1 # Route followed to server message.buffer_id = event.ofp.buffer_id message.in_port = event.port message.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, serverip)) message.actions.append(of.ofp_action_output(port=server_output)) event.connection.send(message) # Route from server to load balancer reply = of.ofp_flow_mod() reply.buffer_id = None reply.in_port = server_output reply.match = of.ofp_match() reply.match.dl_src = selected_server_mac reply.match.nw_src = serverip reply.match.tp_src = message.match.tp_dst reply.match.dl_dst = message.match.dl_src reply.match.nw_dst = message.match.nw_src reply.match.tp_dst = message.match.tp_src reply.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, virtual_mac)) reply.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, virtual_ip)) reply.actions.append(of.ofp_action_output(port=message.in_port)) event.connection.send(reply) return EventHalt
def _match_action(self, msg): if len(self.actions) == 1 and self.actions[0] == "": return for action in self.actions: action_name = action.split('=')[0] if action_name != "STRIP_VLAN": action_argu = action.split('=')[1] if (action_name == "OUTPUT"): msg.actions.append(of.ofp_action_output(port=int(action_argu))) elif (action_name == "ENQUEUE"): port = action_argu.split(':')[0] queue_id = action_argu.split(':')[1] msg.actions.append( of.ofp_action_enqueue(port=int(port), queue_id=int(queue_id))) elif (action_name == "STRIP_VLAN"): msg.actions.append(of.ofp_action_strip_vlan()) elif (action_name == "SET_VLAN_VID"): msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(action_argu))) elif (action_name == "SET_VLAN_PCP"): msg.actions.append( of.ofp_action_vlan_pcp(vlan_pcp=int(action_argu))) elif (action_name == "SET_DL_SRC"): msg.actions.append( of.ofp_action_dl_addr(type=4, dl_addr=EthAddr(action_argu))) elif (action_name == "SET_DL_DST"): msg.actions.append( of.ofp_action_dl_addr(type=5, dl_addr=EthAddr(action_argu))) elif (action_name == "SET_NW_TOS"): msg.actions.append( of.ofp_action_nw_tos(nw_tos=int(action_argu))) elif (action_name == "SET_NW_SRC"): msg.actions.append( of.ofp_action_nw_addr(type=6, nw_addr=IPAddr(action_argu))) elif (action_name == "SET_NW_DST"): msg.actions.append( of.ofp_action_nw_addr(type=7, nw_addr=IPAddr(action_argu))) elif (action_name == "SET_TP_SRC"): msg.actions.append( of.ofp_action_tp_port(type=9, tp_port=int(action_argu))) elif (action_name == "SET_TP_DST"): msg.actions.append( of.ofp_action_tp_port(type=10, tp_port=int(action_argu)))
def _handle_PacketIn(self, event): balancer_ip = IPAddr("10.0.0.99") balancer_eth = EthAddr("00:00:00:00:00:99") packet = event.parsed packet_in = event.ofp flow = of.ofp_flow_mod() flow.match = of.ofp_match.from_packet(packet) flow.match.in_port = packet_in.in_port if flow.match.nw_src not in self.dicts: self.dicts[flow.match.nw_src] = packet_in.in_port if flow.match.nw_dst == balancer_ip: # if the request is to balancer print("[Request]: From " + str(flow.match.nw_src) + " to " + str(flow.match.nw_dst)) if flow.match.in_port == self.ind + 1: # if the chosen server is the same as the client self.ind = (self.ind + 1) % self.N # shift the server id ethnum = str(hex(self.ind + 1)) if self.ind < 15: ethnum = "0" + ethnum[2:len(ethnum)] else: ethnum = ethnum[2:len(ethnum)] ipnum = str(self.ind + 1) server_port = self.ind + 1 server_ip = IPAddr("10.0.0." + ipnum) server_eth = EthAddr("00:00:00:00:00:" + ethnum) print("The chosen server is " + str(server_ip)) print(server_eth) flow.buffer_id = packet_in.buffer_id new_ip_dst = of.ofp_action_nw_addr(7, server_ip) new_eth_dst = of.ofp_action_dl_addr(5, server_eth) action = of.ofp_action_output(port=server_port) flow.actions.append(new_ip_dst) flow.actions.append(new_eth_dst) self.ind = (self.ind + 1) % self.N flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(action) event.connection.send(flow) flow.command = of.OFPFC_DELETE event.connection.send(flow) # indicate the current server and client info self.cur_client = packet_in.in_port self.cur_ser = server_port self.request = 1 else: if flow.match.nw_dst in self.dicts: outport = self.dicts[flow.match.nw_dst] else: outport = of.OFPP_ALL if outport == self.cur_client and self.request == 1: #response message new_ip_src = of.ofp_action_nw_addr(6, balancer_ip) new_eth_src = of.ofp_action_dl_addr(4, balancer_eth) action = of.ofp_action_output(port=outport) flow.buffer_id = packet_in.buffer_id flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(new_ip_src) flow.actions.append(new_eth_src) flow.actions.append(action) event.connection.send(flow) flow.command = of.OFPFC_DELETE event.connection.send(flow) print("[Response]: Server " + str(self.cur_ser) + " response") self.cur_ser = -1 self.cur_client = -1 self.request = 0 else: action = of.ofp_action_output(port=outport) flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(action) if event.ofp.buffer_id != -1: flow.buffer_id = event.ofp.buffer_id event.connection.send(flow) print("Normal Message from " + str(flow.match.nw_src) + " to " + str(flow.match.nw_dst)) flow.command = of.OFPFC_DELETE event.connection.send(flow) return
def packet_handler (event): global count_server packet = event.parsed # Only handle IPv4 flows if (not event.parsed.find("ipv4")): return event_cont message = of.ofp_flow_mod() message.match = of.ofp_match.from_packet(packet) # Only handle traffic destined to virtual IP if (message.match.nw_dst != load_balancer_hardcoded_ip): return event_cont # Implementing Weighted Round robin Server Selection iterator = count_server % 6 print iterator if(iterator < topology_server[0]['weight']): serverip = topology_server[0]['ip'] selected_server_mac = topology_server[0]['mac'] server_output = topology_server[0]['outport'] elif(iterator < (topology_server[0]['weight']+topology_server[1]['weight'])): serverip = topology_server[1]['ip'] selected_server_mac = topology_server[1]['mac'] server_output = topology_server[1]['outport'] elif(iterator < (server[0]['weight']+server[1]['weight']+server[2]['weight'])): serverip = server[2]['ip'] selected_server_mac = server[2]['mac'] server_output = server[2]['outport'] count_server += 1 # Route followed to server message.buffer_id = event.ofp.buffer_id message.in_port = event.port message.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, selected_server_mac)) message.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, serverip)) message.actions.append(of.ofp_action_output(port = server_output)) event.connection.send(message) # Route from server to load balancer reply = of.ofp_flow_mod() reply.buffer_id = None reply.in_port = server_output reply.match = of.ofp_match() reply.match.dl_src = selected_server_mac reply.match.nw_src = serverip reply.match.tp_src = message.match.tp_dst reply.match.dl_dst = message.match.dl_src reply.match.nw_dst = message.match.nw_src reply.match.tp_dst = message.match.tp_src reply.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, load_balancer_hardcoded_mac)) reply.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, load_balancer_hardcoded_ip)) reply.actions.append(of.ofp_action_output(port = message.in_port)) event.connection.send(reply) return EventHalt
def handle_IPPacket(self, event): is_src_router = (event.ofp.in_port == of.OFPP_LOCAL) if event.parsed.next.srcip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "source ip is not routable" return if event.parsed.src != self.bridge_mac and not self.check_access( event.parsed.src): print "%s is not permmited" % (str(event.parsed.src)) return if event.parsed.next.dstip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "destination is not routable" return is_src_local = event.parsed.next.srcip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.srcip.inNetwork( INIT_SUBNET, INIT_NETMASK) if is_src_local and (event.parsed.next.srcip.toUnsigned( networkOrder=False) & 0x3) == 1: if not self.get_DHCP_mapping().is_valid_mapping( event.parsed.next.srcip, event.parsed.src) and event.parsed.src != self.bridge_mac: print "received packet from unrecorded mac address" return if event.parsed.next.dstip.inNetwork(MULTICAST_SUBNET, MULTICAST_NETMASK): print "multicast" if event.parsed.next.dstip in self.multicast_ip: action = of.ofp_action_output(port=of.OFPP_FLOOD) command = of.OFPFC_ADD self.send_flow_modification(event, command, [action], timeout=30) # check if broadcast. Change nw_dst to 10.2.255.255 if event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ( (event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x3) == 0x3): print "broadcast IP" nw_new = of.ofp_action_nw_addr() nw_new.type = of.OFPAT_SET_NW_DST nw_new.nw_addr = IPAddr("10.2.255.255") out = of.ofp_action_output( port=of.OFPP_IN_PORT if event.ofp.in_port == 0 else 0) actions = [out, nw_new] command = of.OFPFC_ADD self.send_flow_modification(event, command, actions, timeout=30) dst_port = 0 if event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ( (event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x01) == 0x01): dst_port = 1 else: dst_port = 0 actions = [] is_dst_local = event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.dstip.inNetwork( INIT_SUBNET, INIT_NETMASK) if is_dst_local and is_src_local and (dst_port != 0) and (not is_src_router): dst_mac = self.get_DHCP_mapping().get_mac(event.parsed.next.dstip) new_dl_src = of.ofp_action_dl_addr() new_dl_src.type = of.OFPAT_SET_DL_SRC new_dl_src.set_src(self.bridge_mac) actions.append(new_dl_src) new_dl_dst = of.ofp_action_dl_addr() new_dl_dst.type = of.OFPAT_SET_DL_DST new_dl_dst.set_dst(dst_mac) actions.append(new_dl_dst) out = of.ofp_action_output(port=of.OFPP_FLOOD) actions.append(out) if 0 < event.ofp.in_port and event.ofp.in_port < of.OFPP_MAX: out_of_in = of.ofp_action_output(port=of.OFPP_IN_PORT) actions.append(out_of_in) command = of.OFPFC_ADD self.send_flow_modification(event, command, actions, timeout=30)
# Setup route to server setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport) # Setup reverse route from server setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport) return EventHalt else: return EventContinue def setup_route_to_server(event,msg_to_server,server_mac,server_ip,server_outport): msg_to_server.buffer_id = event.ofp.buffer_id msg_to_server.in_port = event.port msg_to_server.actions.append(of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, server_mac)) msg_to_server.actions.append(of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, server_ip)) msg_to_server.actions.append(of.ofp_action_output(port = server_outport)) event.connection.send(msg_to_server) def setup_route_from_server(event,msg_to_server,server_mac,server_ip,server_outport): global ServerUsed msg_from_server = of.ofp_flow_mod() msg_from_server.buffer_id = None msg_from_server.in_port = server_outport msg_from_server.match = of.ofp_match() msg_from_server.match.dl_src = server_mac msg_from_server.match.nw_src = server_ip msg_from_server.match.tp_src = msg_to_server.match.tp_dst
def _modify_flow(self, command_type): msg = of.ofp_flow_mod() print self.payload if command_type == "MOD_ST": msg.command = of.OFPFC_MODIFY_STRICT elif command_type == "MOD": msg.command = of.OFPFC_MODIFY if self.payload.has_key("wildcards"): msg.match.wildcards = int(self.payload['wildcards']) if self.payload.has_key("dstIP"): msg.match.nw_dst = IPAddr(self.payload['dstIP']) if self.payload.has_key("srcMac"): msg.match.dl_src = EthAddr(self.payload['srcMac']) if self.payload.has_key("srcIP"): msg.match.nw_src = IPAddr(self.payload['srcIP']) if self.payload.has_key("dstMac"): msg.match.dl_dst = EthAddr(self.payload['dstMac']) if self.payload.has_key("hardTimeout"): msg.hard_timeout = int(self.payload['hardTimeout']) if self.payload.has_key("srcPort"): msg.match.tp_src = int(self.payload['srcPort']) if self.payload.has_key("priority"): msg.priority = int(self.payload['priority']) if self.payload.has_key("ingressPort"): msg.match.in_port = int(self.payload['ingressPort']) if self.payload.has_key("vlan"): msg.match.dl_vlan = int(self.payload['vlan']) if self.payload.has_key("ether-type"): msg.match.dl_type = int(self.payload['ether-type']) if self.payload.has_key("duration"): msg.duration_sec = int(self.payload['duration']) if self.payload.has_key("idleTimeout"): msg.idle_timeout = int(self.payload['idleTimeout']) if self.payload.has_key("netProtocol"): msg.match.nw_proto = int(self.payload['netProtocol']) self.dpid = self.payload['switch'].replace(':', '-')[6:] self._parse_actions(self.payload['actions']) for connection in core.openflow._connections.values(): # print dpidToStr(connection.dpid) conn_dpid = str(dpidToStr(connection.dpid)) print conn_dpid if conn_dpid == self.dpid: """match actions""" if (self.actions == "OUTPUT"): msg.actions.append( of.ofp_action_output(port=int(self.actions_argu))) elif (self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append( of.ofp_action_enqueue(port=int(port), queue_id=int(queue_id))) elif (self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif (self.actions == "set-vlan-id"): msg.actions.append( of.ofp_action_vlan_vid( vlan_vid=int(self.actions_argu))) elif (self.actions == "set-vlan-priority"): msg.actions.append( of.ofp_action_vlan_pcp( vlan_pcp=int(self.actions_argu))) elif (self.actions == "SET_DL_SRC"): msg.actions.append( of.ofp_action_dl_addr(type=4, dl_addr=EthAddr( self.actions_argu))) elif (self.actions == "SET_DL_DST"): msg.actions.append( of.ofp_action_dl_addr(type=5, dl_addr=EthAddr( self.actions_argu))) elif (self.actions == "SET_NW_TOS"): msg.actions.append( of.ofp_action_nw_tos(nw_tos=int(self.actions_argu))) elif (self.actions == "SET_NW_SRC"): msg.actions.append( of.ofp_action_nw_addr(type=6, nw_addr=IPAddr( self.actions_argu))) elif (self.actions == "SET_NW_DST"): msg.actions.append( of.ofp_action_nw_addr(type=7, nw_addr=IPAddr( self.actions_argu))) elif (self.actions == "SET_TP_SRC"): msg.actions.append( of.ofp_action_tp_port(type=9, tp_port=int(self.actions_argu))) elif (self.actions == "SET_TP_DST"): msg.actions.append( of.ofp_action_tp_port(type=10, tp_port=int(self.actions_argu))) connection.send(msg)
def _modify_flow(self,command_type): msg = of.ofp_flow_mod() print self.payload if command_type == "MOD_ST": msg.command = of.OFPFC_MODIFY_STRICT elif command_type == "MOD": msg.command = of.OFPFC_MODIFY if self.payload.has_key("wildcards"): msg.match.wildcards = int(self.payload['wildcards']) if self.payload.has_key("dstIP"): msg.match.nw_dst = IPAddr(self.payload['dstIP']) if self.payload.has_key("srcMac"): msg.match.dl_src = EthAddr(self.payload['srcMac']) if self.payload.has_key("srcIP"): msg.match.nw_src = IPAddr(self.payload['srcIP']) if self.payload.has_key("dstMac"): msg.match.dl_dst = EthAddr(self.payload['dstMac']) if self.payload.has_key("hardTimeout"): msg.hard_timeout = int(self.payload['hardTimeout']) if self.payload.has_key("srcPort"): msg.match.tp_src = int(self.payload['srcPort']) if self.payload.has_key("priority"): msg.priority = int(self.payload['priority']) if self.payload.has_key("ingressPort"): msg.match.in_port = int(self.payload['ingressPort']) if self.payload.has_key("vlan"): msg.match.dl_vlan = int(self.payload['vlan']) if self.payload.has_key("ether-type"): msg.match.dl_type = int(self.payload['ether-type']) if self.payload.has_key("duration"): msg.duration_sec = int(self.payload['duration']) if self.payload.has_key("idleTimeout"): msg.idle_timeout = int(self.payload['idleTimeout']) if self.payload.has_key("netProtocol"): msg.match.nw_proto = int(self.payload['netProtocol']) self.dpid = self.payload['switch'].replace(':','-')[6:] self._parse_actions(self.payload['actions']) for connection in core.openflow._connections.values() : # print dpidToStr(connection.dpid) conn_dpid = str(dpidToStr(connection.dpid)) print conn_dpid if conn_dpid == self.dpid: """match actions""" if(self.actions == "OUTPUT"): msg.actions.append(of.ofp_action_output(port = int(self.actions_argu))) elif(self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id))) elif(self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif(self.actions == "set-vlan-id"): msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu))) elif(self.actions == "set-vlan-priority"): msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu))) elif(self.actions == "SET_DL_SRC"): msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_DL_DST"): msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu))) elif(self.actions == "SET_NW_TOS"): msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu))) elif(self.actions == "SET_NW_SRC"): msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_NW_DST"): msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu))) elif(self.actions == "SET_TP_SRC"): msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu))) elif(self.actions == "SET_TP_DST"): msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu))) connection.send(msg)
def _handle_PacketIn(self, event): """ Handle packet in messages from the switch to implement above algorithm. """#52:54:00:79:95:26 26:6a:fb:3c:f8:fd cptv = server_infos(conf.captive_portal.ip, conf.captive_portal.mac, conf.captive_portal.switch_port, conf.captive_portal.tcp_port ) #"130.192.225.168","52:54:00:79:95:26",5,8085) #cptv = server_infos("130.192.225.156","88:51:fb:42:2b:f8",5,8080) if self.connection.dpid not in switchs_info: lock.acquire() try: dpi = DPI() dpi.setDPI(self.connection.dpid) # add a new switch to our infos switchs_info[self.connection.dpid] = switch_infos( self.connection) finally: lock.release() # release lock, no matter what switch = switchs_info[self.connection.dpid] if event.port not in switch.ports_info: lock.acquire() try: #print (dpid_to_str(self.connection.dpid)) #print self.connection.sock.getpeername()[0] switch.ports_info[event.port] = port_infos(event.port) finally: lock.release() # release lock, no matter what #if event.port == conf.my_infos.my_default_GRE_tunnel: is_user_port = True log.info("Comparing the ports speaking " + str(event.port)) for not_user_port in conf.my_infos.not_user_ports: if str(event.port) == str(not_user_port): is_user_port = False break if not is_user_port: log.info("Event port is " + str(event.port)) log.info("First for the ethernet interface") # First rule: allow all traffic self.connection.send( of.ofp_flow_mod( action=of.ofp_action_output(port=of.OFPP_NORMAL), priority=1, match=of.ofp_match(in_port=event.port))) else: """ Packet from user """ log.info("First packet from user") # First rule: drop all traffic msg = of.ofp_flow_mod() msg.priority = 1 msg.match.in_port = event.port msg.actions.append(of.ofp_action_output(port=of.OFPP_NONE)) self.connection.send(msg) # Second rule: normal process for DNS traffic msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 17 msg.match.tp_dst = 53 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Third rule: normal process for ARP traffic msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x806 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Fourth rule: normal process for DHCPDISCOVER msg = of.ofp_flow_mod() msg.priority = 100 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 17 msg.match.nw_src = "0.0.0.0" msg.match.nw_dst = "255.255.255.255" msg.match.tp_src = 68 msg.match.tp_dst = 67 msg.actions.append(of.ofp_action_output(port=of.OFPP_NORMAL)) #msg.data = event.ofp self.connection.send(msg) # Fifth rule: send the HTTP traffic to the controller msg = of.ofp_flow_mod() msg.priority = 1000 msg.match.in_port = event.port msg.match.dl_type = 0x800 msg.match.nw_proto = 6 msg.match.tp_dst = 80 msg.actions.append( of.ofp_action_output(port=of.OFPP_CONTROLLER)) msg.data = event.ofp self.connection.send(msg) packet = event.parsed if not packet.parsed: log.info("ignoring unparsed packet") return client_list = switch.ports_info[event.port].clients_info log.info("LOOP Thread id: " + str(thread.get_ident())) log.debug("packet.type: " + str(packet.type) + " || pkt.ethernet.IP_TYPE: " + str(pkt.ethernet.IP_TYPE)) if packet.type == pkt.ethernet.IP_TYPE: ipv4_hdr = packet.payload log.debug("ipv4_hdr.protocol: " + str(ipv4_hdr.protocol) + " || pkt.ipv4.TCP_PROTOCOL: " + str(pkt.ipv4.TCP_PROTOCOL)) if ipv4_hdr.protocol == pkt.ipv4.TCP_PROTOCOL: tcp_hdr = ipv4_hdr.payload log.info("tcp_hdr.dstport: " + str(tcp_hdr.dstport) + " || DestPort: || 80") if tcp_hdr.dstport == 80: log.debug("packet.src: " + str(packet.src)) if packet.src not in client_list: log.info("packet.src is not in client_list") lock.acquire() try: log.info("save host info: IP=" + str(ipv4_hdr.srcip) + ", MAC=" + str(packet.src) + ", INGRESS_SWITCH_PORT=" + str(switch.infos.ports[event.port].name)) client_list[packet.src] = host_infos( ipv4_hdr.srcip, packet.src, event.port, 0) finally: lock.release() # release lock, no matter what else: log.debug("PACKET_IN INFOs: user MAC: " + str(packet.src) + ", user IP: " + str(ipv4_hdr.srcip)) user_infos = client_list[packet.src] user_ip = user_infos.IP log.debug("Local informations: user MAC: " + str(packet.src) + ", user IP: " + str(user_ip)) if user_ip != ipv4_hdr.srcip: log.debug("Updating client IP informations") user_infos.IP = ipv4_hdr.srcip client = client_list[packet.src] if (client.flag_auth == 0): log.info( "installing new flow to set destination IP to captive portal IP" ) msg = of.ofp_flow_mod() msg.priority = 10000 msg.idle_timeout = 30 msg.match.dl_type = 0x800 msg.match.dl_src = client.MAC msg.match.nw_proto = 6 #Adding the match on the TCP source port of the user, in order to genererate a PACKET_IN for every #new TCP connection msg.match.tp_src = tcp_hdr.srcport msg.match.tp_dst = 80 msg.match.nw_dst = ipv4_hdr.dstip msg.match.in_port = event.port msg.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, cptv.MAC)) msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_DST, cptv.IP)) msg.actions.append( of.ofp_action_tp_port(of.OFPAT_SET_TP_DST, cptv.port)) msg.actions.append( of.ofp_action_output(port=cptv.switch_port)) #msg.data = event.ofp self.connection.send(msg) log.info("installing new flow to set return path") msg = of.ofp_flow_mod() msg.priority = 10000 msg.idle_timeout = 30 msg.match.dl_type = 0x800 msg.match.nw_proto = 6 msg.match.tp_dst = tcp_hdr.srcport msg.match.nw_dst = ipv4_hdr.srcip msg.match.nw_src = cptv.IP msg.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, ipv4_hdr.dstip)) msg.actions.append( of.ofp_action_tp_port(of.OFPAT_SET_TP_SRC, tcp_hdr.dstport)) msg.actions.append( of.ofp_action_output(port=event.port)) msg.data = event.ofp self.connection.send(msg) '''
def _handle_PacketIn(self, event): # parsing the input packet packet = event.parse() # If no switch has ever seen this host before, then it must be directly # connected to us! Record that in our global list. if packet.src not in self.hostlocations or self.hostlocations[ packet.src]["lastseen"] < (datetime.now() - timedelta(0, IDLE_TIMEOUT)): #log.debug("s%s takes ownership of host %s" % (self.connection.ID, packet.src)) self.hostlocations[packet.src] = { "ID": self.connection.ID, "lastseen": datetime.now() } # Record which hosts exists on which of our ports ip = GetIPFromMAC(packet.src) if ip is not None: #log.debug(" on IP '%s'" % ip) self.hostports[event.port] = packet.src elif self.hostlocations[packet.src]["ID"] == self.connection.ID: #log.debug("s%s continues to own host %s" % (datetime.now(), self.connection.ID, packet.src)) self.hostlocations[packet.src]["lastseen"] = datetime.now() # Keep a list of which MAC addresses live on which port, so we can forward # packets as needed if packet.src not in self.mactable or self.mactable[ packet.src] != event.ofp.in_port: self.mactable[packet.src] = event.ofp.in_port #log.debug("Learned port %s connects to %s" % (event.ofp.in_port, packet.src)) if packet.type == packet.LLDP_TYPE or packet.type == 0x86DD: # Drop LLDP packets # Drop IPv6 packets # send of command without actions msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) return # Watch for ARP packets trying to discover a load-balance target. packet_arp = packet.find('arp') if packet_arp is not None and str( packet_arp.protodst).startswith(LOADBALANCE_TARGET): # Found one! Respond with a special MAC address, which our switches will # be able to identify easily for load-balancing. #log.debug('ARP Packet!!!! Looking for %s' % packet_arp.protodst) mac = GetMACForLoadBalancing() reply_arp = arp() reply_arp.hwtype = packet_arp.hwtype reply_arp.prototype = packet_arp.prototype reply_arp.hwlen = packet_arp.hwlen reply_arp.protolen = packet_arp.protolen reply_arp.opcode = arp.REPLY reply_arp.hwdst = packet_arp.hwsrc reply_arp.hwsrc = mac reply_arp.protodst = packet_arp.protosrc reply_arp.protosrc = packet_arp.protodst reply_eth = ethernet(type=packet.type, src=mac, dst=packet_arp.hwsrc) reply_eth.payload = reply_arp reply = of.ofp_packet_out(in_port=of.OFPP_NONE) reply.actions.append(of.ofp_action_output(port=event.port)) reply.data = reply_eth.pack() event.connection.send(reply) return # If this packet is being delivered to a special MAC, set up some flows to # get the data to the right place. packet_ipv4 = packet.find('ipv4') if IsMACForLoadBalancing(packet.dst) and packet_ipv4 is not None: eligibleports = [] for port in self.connection.features.ports: if port.port_no != event.port and not port.config & OFPPC_PORT_DOWN: eligibleports.append(port.port_no) port_out = random.choice(eligibleports) # Establish bi-directional flows! log.debug("Establishing load-balancing flows for %s <--> %s" % (packet.src, packet.dst)) flow_in = of.ofp_flow_mod() flow_out = of.ofp_flow_mod() flow_in.idle_timeout = flow_out.idle_timeout = IDLE_TIMEOUT flow_in.hard_timeout = flow_out.hard_timeout = HARD_TIMEOUT flow_in.match = of.ofp_match(dl_dst=packet.src, dl_src=packet.dst) flow_out.match = of.ofp_match(dl_dst=packet.dst, dl_src=packet.src) if port_out in self.hostports: # If we're delivering to a host (instead of another switch), we need # to rewrite some of the packet data, so that things line up properly # on each end. The sender sends to the special IP, and the receiver # should see the packet addressed to itself (and vice versa). log.debug("...which will be handled by %s" % (self.hostports[port_out])) flow_in.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_SRC, packet.dst)) flow_in.actions.append( of.ofp_action_nw_addr(of.OFPAT_SET_NW_SRC, packet_ipv4.dstip)) flow_out.actions.append( of.ofp_action_dl_addr(of.OFPAT_SET_DL_DST, self.hostports[port_out])) flow_out.actions.append( of.ofp_action_nw_addr( of.OFPAT_SET_NW_DST, GetIPFromMAC(self.hostports[port_out]))) # We also need to update one of our match rules, since the packet will # be sent with a non-special MAC address. flow_in.match.dl_src = self.hostports[port_out] flow_in.actions.append(of.ofp_action_output(port=event.port)) flow_out.actions.append(of.ofp_action_output(port=port_out)) flow_in.in_port = port_out flow_out.in_port = event.port flow_out.data = event.ofp self.connection.send(flow_in) self.connection.send(flow_out) return elif packet.dst in self.mactable: # If we know the destination, but are being told about it, recreate the # flow, since this is either the initial discovery, or the flow expired. log.debug( "Establishing flow to deliver packets for %s to port %s" % (packet.dst, self.mactable[packet.dst])) fm = of.ofp_flow_mod() fm.idle_timeout = IDLE_TIMEOUT fm.hard_timeout = HARD_TIMEOUT fm.actions.append( of.ofp_action_output(port=self.mactable[packet.dst])) # Defining the match via from_packet will cause us to establish a flow # for each unique packet type per destination, instead of just per dest. fm.match = of.ofp_match(dl_dst=packet.dst, dl_src=packet.src) #fm.match = of.ofp_match.from_packet(packet) fm.data = event.ofp # Deliver the packet along this flow self.connection.send(fm) return log.debug("Port for %s unknown -- flooding" % (packet.dst, )) msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg)