def add_flow(self, priority, dl_type, nw_dst, nw_src, queue_id, action, interface): #TODO: Add low-level checking of_msg = of.ofp_flow_mod() of_msg.priority = int(priority) of_msg.match.dl_type = dl_type of_msg.match.nw_dst = nw_dst of_msg.match.nw_src = nw_src #: Ports: eth0 = 1, wifi = 2, eth3: 4g if action == 'forward': port = of.OFPP_NORMAL if queue_id is not None: of_msg.actions.append(of.ofp_action_enqueue(port=1, \ queue_id=int(queue_id))) of_msg.actions.append(of.ofp_action_enqueue(port=2, \ queue_id=int(queue_id))) of_msg.actions.append(of.ofp_action_enqueue(port=3, \ queue_id=int(queue_id))) else: of_msg.actions.append(of.ofp_action_output(port=port)) else: of_msg.actions = [] self.current_connection.send(of_msg)
def add_flows(ev, ipsrc, ipdst, n): inport = 0 if ipsrc == "10.0.0." and ipdst == "11.0.0.": inport = 6 elif ipsrc == "10.0.0." and ipdst == "12.0.0.": inport = 7 elif ipsrc == "11.0.0." and ipdst == "10.0.0.": inport = 6 elif ipsrc == "11.0.0." and ipdst == "12.0.0.": inport = 7 elif ipsrc == "12.0.0." and ipdst == "10.0.0.": inport = 6 elif ipsrc == "12.0.0." and ipdst == "11.0.0.": inport = 7 for j in range(1, 6): msg = of.ofp_flow_mod() msg.match.dl_type = 0x0800 myipdst = ipdst + str(j) msg.match.nw_dst = myipdst msg.actions.append( of.ofp_action_dl_addr.set_dst( EthAddr("00:00:00:00:00:" + str(n) + str(j)))) if str(myipdst).rsplit('.', 1)[1] == "1" or str(myipdst).rsplit( '.', 1)[1] == "2": msg.actions.append(of.ofp_action_enqueue(port=inport, queue_id=1)) elif str(myipdst).rsplit('.', 1)[1] == "3" or str(myipdst).rsplit( '.', 1)[1] == "4": msg.actions.append(of.ofp_action_enqueue(port=inport, queue_id=2)) elif str(myipdst).rsplit('.', 1)[1] == "5": msg.actions.append(of.ofp_action_enqueue(port=inport, queue_id=3)) ev.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid # print "PacketIn: ", dpidToStr(event.connection.dpid) if event.connection.dpid==s1_dpid: # Flujo entrante por el puerto 2 (h1 --- s1) msg = of.ofp_flow_mod() msg.priority = 100 # A numero mas alto mayor prioridad msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0800 msg.match.nw_proto = 6 msg.match.tp_src=5000 msg.actions.append(of.ofp_action_enqueue(port = 1, queue_id = 2)) event.connection.send(msg) # Flujo entrante por el puerto 1 (s1 --- s2) msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0800 msg.match.nw_proto = 6 msg.match.tp_dst=5000 # Aqui tengo mis dudas por ser dos switches? msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) if event.connection.dpid==s2_dpid: # Flujo entrante por el puerto 2 (s2 --- h2) msg = of.ofp_flow_mod() msg.priority = 100 # A numero mas alto mayor prioridad msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type = 0x0800 msg.match.nw_proto = 6 msg.match.tp_dst=5000 msg.actions.append(of.ofp_action_enqueue(port = 1, queue_id = 2)) event.connection.send(msg) # Flujo entrante por el puerto 1 (s1 --- s2) msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type = 0x0800 msg.match.nw_proto = 6 msg.match.tp_src=5000 # Aqui tengo mis dudas por ser dos switches? msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
def create(self, switch1, switch2): self.switches2 += [switch1, switch2] try: s = self.switches[switch1] s = self.switches[switch2] except KeyError: s = self.WPSwitch(switch1) self.switches[s.dpid] = s s = self.WPSwitch(switch2) self.switches[s.dpid] = s if self.qos: path = nx.shortest_path (graph, switch1, switch2, weight='cost') log.info(' -> path with minimum QoS cost between {} and {} is: {}'.format(switch1, switch2, path)) else: path = nx.shortest_path (graph, switch1, switch2) log.info(' -> shortest path between {} and {} is: {}'.format(switch1, switch2, path)) self.path = path msg = of.ofp_flow_mod() msg.command = of.OFPFC_MODIFY_STRICT # of.OFPFC_MODIFY || of.OFPFC_ADD #msg.match.dl_type = 0x0880 # Causes conflicts with user-space switches msg.match.dl_dst = self.title_hash[:6] msg.match.dl_src = self.title_hash[6:] if path.__len__() > 1: if self.bw and self.cos: log.info(" -> enqueuing in queue 1, corresponding to CoS silver") for i in path: if i == path[-1]: self.switches[i].used_ports.add(graph[i][path[path.index(i)-1]]['ports'][i]) elif i == path[0]: self.switches[i].used_ports.add(graph[i][path[path.index(i)+1]]['ports'][i]) else: try: s = self.switches[i] except KeyError: s = self.WPSwitch(i) self.switches[i] = s self.switches[i].used_ports.add(graph[i][path[path.index(i)+1]]['ports'][i]) self.switches[i].used_ports.add(graph[i][path[path.index(i)-1]]['ports'][i]) if self.bw and self.cos: if cos[self.cos]: cos[self.cos] += self.bw else: cos[self.cos] = self.bw log.info(' -> Class of Service {} equals {} after receiving {}'.format([self.cos], cos[self.cos], self.bw)) msg.actions = [of.ofp_action_enqueue(port=p, queue_id=0) for p in self.switches[i].used_ports] # ofp_action_enqueue(port=0, queue_id=0) else: msg.actions = [of.ofp_action_enqueue(port=p, queue_id=1) for p in self.switches[i].used_ports] core.openflow.sendToDPID(i, msg) else: msg.actions = [of.ofp_action_output(port=p) for p in s.used_ports] core.openflow.sendToDPID(s.dpid, msg)
def create(self, switch1, switch2): self.switches2 += [switch1, switch2] try: s = self.switches[switch1] s = self.switches[switch2] except KeyError: s = self.WPSwitch(switch1) self.switches[s.dpid] = s s = self.WPSwitch(switch2) self.switches[s.dpid] = s if self.qos: path = nx.shortest_path (graph, switch1, switch2, weight='cost') log.info(' -> path with minimum QoS cost between {} and {} is: {}'.format(switch1, switch2, path)) else: path = nx.shortest_path (graph, switch1, switch2) log.info(' -> shortest path between {} and {} is: {}'.format(switch1, switch2, path)) self.path = path msg = of.ofp_flow_mod() msg.command = of.OFPFC_MODIFY_STRICT # of.OFPFC_MODIFY || of.OFPFC_ADD #msg.match.dl_type = 0x0880 # Causes conflicts with user-space switches msg.match.dl_dst = self.title_hash[:6] msg.match.dl_src = self.title_hash[6:] if path.__len__() > 1: if self.bw and self.cos: log.info(" -> enqueuing in queue 1, corresponding to CoS silver") for i in path: if i == path[-1]: self.switches[i].used_ports.add(graph[i][path[path.index(i)-1]]['ports'][i]) elif i == path[0]: self.switches[i].used_ports.add(graph[i][path[path.index(i)+1]]['ports'][i]) else: try: s = self.switches[i] except KeyError: s = self.WPSwitch(i) self.switches[i] = s self.switches[i].used_ports.add(graph[i][path[path.index(i)+1]]['ports'][i]) self.switches[i].used_ports.add(graph[i][path[path.index(i)-1]]['ports'][i]) if self.bw and self.cos: msg.actions = [of.ofp_action_enqueue(port=p, queue_id=0) for p in self.switches[i].used_ports] # ofp_action_enqueue(port=0, queue_id=0) else: msg.actions = [of.ofp_action_enqueue(port=p, queue_id=1) for p in self.switches[i].used_ports] core.openflow.sendToDPID(i, msg) else: msg.actions = [of.ofp_action_output(port=p) for p in s.used_ports] core.openflow.sendToDPID(s.dpid, msg)
def add_flow(msg, msg2, queue): global s1_dpid, s2_dpid, s3_dpid for connection in core.openflow._connections.values(): if connection.dpid == s1_dpid: msg.actions.append(of.ofp_action_enqueue(port=4, queue_id=queue)) connection.send(msg) if msg.match.nw_src == "10.0.0.1": msg2.actions.append(of.ofp_action_output(port=1)) elif msg.match.nw_src == "10.0.0.2": msg2.actions.append(of.ofp_action_output(port=2)) elif msg.match.nw_src == "10.0.0.3": msg2.actions.append(of.ofp_action_output(port=3)) elif connection.dpid == s2_dpid: msg.actions.append(of.ofp_action_output(port=3)) connection.send(msg) if msg.match.nw_src == "10.0.0.1" or msg.match.nw_src == "10.0.0.2" or msg.match.nw_src == "10.0.0.3": msg2.actions.append(of.ofp_action_output(port=1)) elif connection.dpid == s3_dpid: msg.actions.append(of.ofp_action_output(port=2)) connection.send(msg) if msg.match.nw_src == "10.0.0.1" or msg.match.nw_src == "10.0.0.2" or msg.match.nw_src == "10.0.0.3": msg2.actions.append(of.ofp_action_output(port=3))
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 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 = of.ofp_packet_out() for port in self.switchPorts: if port != event.port: if packet.find('tcp') != None and (packet.payload.payload.srcport == 5002 or packet.payload.payload.dstport == 5002): msg.actions.append(of.ofp_action_enqueue(port = of.OFPP_FLOOD,queue_id=1)) else: 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 SendFlowMod(port, event, src, dst, placeInThrottleQueue): msg = of.ofp_flow_mod() # msg is a flow modification (openflow) msg.priority = 100 msg.idle_timeout = 0 # Timeout the flow rule, if no traffic is happening during x seconds msg.hard_timeout = 0 # Timeout the flow rule after X seconds msg.match.dl_type = 0x0800 # ipv4 traffic code - the rule will only affect ipv4 msg.match.nw_src = src # Source IP msg.match.nw_dst = dst # Destination IP if placeInThrottleQueue == True: # Place in the throttled queue msg.actions = [of.ofp_action_enqueue(port=port, queue_id=1)] elif placeInThrottleQueue == False: # Place in the non-throttled queue msg.actions.append(of.ofp_action_enqueue(port=port, queue_id=0)) # Send message to the switch, responsible for the flow event.connection.send(msg)
def enviar_a_fila(self, event, port): # Este metodo en particular, envia hacia una fila determinada por el ultimo octeto de la IP de origen, si la direccion es 10.0.0.1 enviara a la fila 1 # note que tomamos el parametro "port" que nos indica el puerto de destino packet = event.parsed ip_packet = packet.payload ip_origen = ip_packet.srcip hora1 = datetime.strftime("06:00:00", "%X").time() hora2 = datetime.strftime("18:00:00", "%X").time() hora_act = datetime.now().time() print hora_act if hora_act > hora1 and hora_act < hora2: print "Hora actual 1 " + hora_act id_fila = 1 else: print "Hora actual 2 " + hora_act id_fila = 2 #id_fila = str(ip_origen).split(".")[3] print "La fila seria: ", id_fila msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 # La unica diferencia respecto a un "output" normal, es que agregamos el id de la fila msg.actions.append( of.ofp_action_enqueue(port=port, queue_id=int(id_fila))) msg.data = event.ofp # 6a self.connection.send(msg)
def push_flow_label(self, source_ip, dest_ip, out_port): msg = of.ofp_flow_mod() print "Flow label for destination network : "+self.buffer[dest_ip]['DestinationNetwork'] msg.priority = 10 msg.match.dl_type = ethernet.IP_TYPE #msg.match.nw_proto = ipv4.ICMP_PROTOCOL if dest_ip == "10.0.4.100": print "The flow that's going to be added must match source ip ("+source_ip+") too along with destination ip "+dest_ip msg.match.nw_src = IPAddr(source_ip) else: print "source_ip match constraint not added" msg.match.set_nw_dst(self.buffer[dest_ip]['DestinationNetwork']) # msg.match.nw_dst = IPAddr(srcip) msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.arp_table[self.routing_table[self.buffer[dest_ip]['DestinationNetwork']]['RouterInterface']]))) msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.arp_table[dest_ip]))) if dest_ip == "10.0.4.100": if source_ip == "10.0.1.100": queueno=1 elif source_ip == "10.0.2.100": queueno=2 else: queueno=0 print "PUSHING QOS FLOW for source_ip "+source_ip+" @queue "+str(queueno) msg.actions.append(of.ofp_action_enqueue(port = 4, queue_id=queueno)) self.allocated_bandwidths[source_ip] = {'dest_ip': dest_ip,'bandwidth': queueno} #queueno denotes bandwidth else: print "PUSHING REGULAR FLOW!" msg.actions.append(of.ofp_action_output(port=out_port)) self.connection.send(msg) log.debug("Flow mod for destination network %s sent!", self.buffer[srcip]['DestinationNetwork']) log.debug("allocated bandwidths table : "+self.allocated_bandwidths)
def act_like_switch (self, packet, packet_in): """ Implement switch-like behavior. """ srcaddr = EthAddr(packet.src) if not self.mac_to_port.has_key(srcaddr): self.mac_to_port[srcaddr] = packet_in.in_port for key, value in dict.items(self.mac_to_port): print key, value dstaddr = EthAddr(packet.dst) #if my_match.dl_dst in mac_t _port: if dstaddr in self.mac_to_port: # Send packet out the associated port out_port = self.mac_to_port[dstaddr] match = of.ofp_match() msg = of.ofp_flow_mod() #creates a flow table entry in switc #msg.match.dl_src = srcaddr #msg.match.dl_dst = dstaddr msg.match.tp_dst = out_port for con in core.openflow.connections: msg2 = of.ofp_queue_stats_request() msg2.port_no = out_port msg2.queue_id = of.OFPQ_ALL con.send(of.ofp_stats_request(body=msg2)) # Add an action to send to the specified port action = of.ofp_action_output(port = of.OFPP_CONTROLLER) msg.actions.append(action) queue_action = of.ofp_action_enqueue() queue_action.port = out_port queue_action.queue_id = 1 msg.actions.append(queue_action) print "printing q stats in act like switch\n" #global stats1 #print ("%s",s.stats) for f in s.stats: print f print "\n" # Send message to switch self.connection.send(msg) self.resend_packet(packet_in,out_port) else: # Flood the packet out everything but the input port # This part looks familiar, right? self.resend_packet (packet_in,of.OFPP_FLOOD) print "------flood-------"
def forward(outport, message=None, is_premium=False): message.data = event.ofp if is_premium: message.actions.append( of.ofp_action_enqueue(port=outport, queue_id=1)) else: message.actions.append(of.ofp_action_output(port=outport)) event.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid #print("payload:"+str(dir(event.parsed.payload))) #print("event.con:"+str(event.connection)) #print("hwdst:"+str(event.parsed.payload.hwdst)) switch_id = event.connection.dpid print "switch_id:" print switch_id packet = event.parsed (pckt_srcip, hasARP) = getSrcIPandARP(packet.next) if pckt_srcip is None: pckt_srcip = "10.0.0.0" #print("Pckt_srcip:"+str(pckt_srcip)) #self.updateIPInfo(pckt_srcip,macEntry,hasARP) print("pckt_srcip is NONE and is set to 10.0.0.0!") inTable[(event.connection, packet.src)] = event.port dst_port = inTable.get((event.connection, packet.dst)) #print('came into handle_packetin') 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)) #ipv4_packet = event.parsed.find("ipv4") #if ipv4_packet is None: # print("ipv4 none") #ipv4_src_ip = ipv4_packet.srcip #print("ipv4 src ip :"+str(ipv4_src_ip)) msg.actions.append( of.ofp_action_enqueue(port=dst_port, queue_id=getQidFromMatrix( str(pckt_srcip), switch_id - 1)) ) #switch id -1 because it is the index in the matrix for that switch print("Msg sent to Switch " + str(event.connection.dpid) + ": Port" + str(dst_port) + ", Queue" + str(getQidFromMatrix(str(pckt_srcip), switch_id - 1))) #print("srcip:"+str(packet.src)) event.connection.send(msg) log.debug("Installing %s <-> %s" % (packet.src, packet.dst)) pass
def send_InstallFlow_msg_IPdst_match(event, _priority, nw_dst_str, _port, _queue_id=0): msg = of.ofp_flow_mod() msg.priority = _priority # Example 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = nw_dst_str # Eg : nw_dst_str can be "10.0.0.3" # msg.actions.append(of.ofp_action_output(port = 3)) msg.actions.append(of.ofp_action_enqueue(port = _port, queue_id = _queue_id)) event.connection.send(msg)
def install_enqueue(event, packet, outport, qid): log.debug("# S%i: Installing flow %s.%i -> %s.%i", dpid, src, inport, dst, outport) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, inport) msg.actions.append(of.ofp_action_enqueue(port = outport, queue_id = qid)) msg.data = event.ofp msg.priority = self.VPN_PRIORITY event.connection.send(msg) log.debug("# S%i: Rule sent: Outport %i, Queue %i\n", dpid, outport, qid) return
def flood(message=None, is_premium=False): message.data = event.ofp if is_premium: message.actions.append( of.ofp_action_enqueue(port=of.OFPP_FLOOD, queue_id=1)) else: message.actions.append( of.ofp_action_output(port=of.OFPP_FLOOD)) # TODO: use OFPP_ALL and checksum to avoid event.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid # print "PacketIn: ", dpidToStr(event.connection.dpid) if event.connection.dpid==s1_dpid: # Flujo entrante por el puerto 2 (h1 --- s1) msg = of.ofp_flow_mod() msg.priority = 100 # A numero mas alto mayor prioridad msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.actions.append(of.ofp_action_enqueue(port = 1, queue_id = 2)) event.connection.send(msg) # Flujo entrante por el puerto 1 (s1 --- s2) msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) if event.connection.dpid==s2_dpid: # Flujo entrante por el puerto 2 (s2 --- h2) msg = of.ofp_flow_mod() msg.priority = 100 # A numero mas alto mayor prioridad msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.actions.append(of.ofp_action_enqueue(port = 1, queue_id = 2)) event.connection.send(msg) # Flujo entrante por el puerto 1 (s1 --- s2) msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg)
def install_enqueue(event, packet, outport, q_id): log.info("Installing flow for %s:%i -> %s:%i", source, port, destination, outport) message = of.ofp_flow_mod() message.match = of.ofp_match.from_packet(packet, port) message.actions.append(of.ofp_action_enqueue(port = outport, queue_id = q_id)) message.data = event.ofp # Set to Premium Service Channel priority (Task 4) message.priority = 1000 event.connection.send(message) log.info("Packet with queue ID %i sent via port %i\n", q_id, outport) return
def push_flow_label(self, source_ip, dest_ip, out_port): msg = of.ofp_flow_mod() print "Flow label for destination network : " + self.buffer[dest_ip][ 'DestinationNetwork'] msg.priority = 150 msg.match.dl_type = ethernet.IP_TYPE #msg.match.nw_proto = ipv4.ICMP_PROTOCOL if dest_ip == "10.0.2.100": print "The flow that's going to be added must match source ip (" + source_ip + ") too along with destination ip " + dest_ip msg.match.nw_src = IPAddr(source_ip) else: print "source_ip match constraint not added" #I SUSPECT MATCHING THIS ENTIRE NETWORK RANGE AND APPENDING A SINGLE MAC ID FOR THE FLOW IS WRONG. DEBUG FROM HERE msg.match.set_nw_dst(self.buffer[dest_ip]['DestinationNetwork']) # msg.match.nw_dst = IPAddr(srcip) msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr(self.arp_table[self.routing_table[self.buffer[dest_ip][ 'DestinationNetwork']]['RouterInterface']]))) msg.actions.append( of.ofp_action_dl_addr.set_dst(EthAddr(self.arp_table[dest_ip]))) print 'the flow will set source MAC as interface oda MAC ID: ' print str((EthAddr(self.arp_table[self.routing_table[ self.buffer[dest_ip]['DestinationNetwork']]['RouterInterface']]))) print ' and dst MAC as destIP oda MAC ID ' + str( EthAddr(self.arp_table[dest_ip])) if dest_ip == "10.0.2.100": if source_ip == "10.0.1.100": queueno = 1 elif source_ip == "10.0.1.101": queueno = 2 else: queueno = 0 print "PUSHING QOS FLOW for source_ip " + source_ip + " @queue " + str( queueno) msg.actions.append( of.ofp_action_enqueue(port=2, queue_id=queueno) ) #BUG WAS HERE, CHANGE OUT_PORT NUMBER HERE IN FUTURE UPDATES! self.allocated_bandwidths[source_ip] = { 'dest_ip': dest_ip, 'bandwidth': queueno } #queueno denotes bandwidth else: print "(NOT. LOL.) PUSHING REGULAR FLOW!" return msg.actions.append(of.ofp_action_output(port=out_port)) self.connection.send(msg) log.debug("Flow mod for destination network %s sent!", self.buffer[dest_ip]['DestinationNetwork']) log.debug("allocated bandwidths table : " + str(self.allocated_bandwidths))
def sendFlowMod(): global globalEvent log.debug("sending throttle message") msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_enqueue(port=2, queue_id=1)) #port 2 = eth2 globalEvent.connection.send(msg)
def add_flow(ev, ipsrc, ipdst): inport = 0 if str(ipsrc).rsplit('.', 1)[0] == "10.0.0" and str(ipdst).rsplit( '.', 1)[0] == "10.0.1": inport = 6 elif str(ipsrc).rsplit('.', 1)[0] == "10.0.0" and str(ipdst).rsplit( '.', 1)[0] == "10.0.2": inport = 7 elif str(ipsrc).rsplit('.', 1)[0] == "10.0.1" and str(ipdst).rsplit( '.', 1)[0] == "10.0.0": inport = 6 elif str(ipsrc).rsplit('.', 1)[0] == "10.0.1" and str(ipdst).rsplit( '.', 1)[0] == "10.0.2": inport = 7 elif str(ipsrc).rsplit('.', 1)[0] == "10.0.2" and str(ipdst).rsplit( '.', 1)[0] == "10.0.0": inport = 6 elif str(ipsrc).rsplit('.', 1)[0] == "10.0.2" and str(ipdst).rsplit( '.', 1)[0] == "10.0.1": inport = 7 msg = of.ofp_flow_mod() msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = ipsrc msg.match.nw_dst = ipdst if str(ipdst).rsplit('.', 1)[1] == "1" or str(ipdst).rsplit('.', 1)[1] == "2": msg.actions.append(of.ofp_action_enqueue(port=inport, queue_id=1)) elif str(ipdst).rsplit('.', 1)[1] == "3" or str(ipdst).rsplit('.', 1)[1] == "4": msg.actions.append(of.ofp_action_enqueue(port=inport, queue_id=2)) elif str(ipdst).rsplit('.', 1)[1] == "5": msg.actions.append(of.ofp_action_enqueue(port=inport, queue_id=3)) ev.connection.send(msg)
def _handle_PacketIn (event): global s1_dpid, s2_dpid #print("payload:"+str(dir(event.parsed.payload))) #print("event.con:"+str(event.connection)) #print("hwdst:"+str(event.parsed.payload.hwdst)) switch_id = event.connection.dpid print "switch_id:" print switch_id packet = event.parsed (pckt_srcip, hasARP) = getSrcIPandARP(packet.next) if pckt_srcip is None: pckt_srcip = "10.0.0.0" #print("Pckt_srcip:"+str(pckt_srcip)) #self.updateIPInfo(pckt_srcip,macEntry,hasARP) print("pckt_srcip is NONE and is set to 10.0.0.0!") inTable[(event.connection,packet.src)] = event.port dst_port = inTable.get((event.connection,packet.dst)) #print('came into handle_packetin') 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)) #ipv4_packet = event.parsed.find("ipv4") #if ipv4_packet is None: # print("ipv4 none") #ipv4_src_ip = ipv4_packet.srcip #print("ipv4 src ip :"+str(ipv4_src_ip)) msg.actions.append(of.ofp_action_enqueue(port = dst_port, queue_id=getQidFromMatrix(str(pckt_srcip),switch_id-1))) #switch id -1 because it is the index in the matrix for that switch print("Msg sent to Switch "+str(event.connection.dpid)+": Port"+str(dst_port)+", Queue"+str(getQidFromMatrix(str(pckt_srcip),switch_id-1))) #print("srcip:"+str(packet.src)) event.connection.send(msg) log.debug("Installing %s <-> %s" % (packet.src, packet.dst)) pass
def handleFlowsRedirection(self, dpid, connections, switchAddress, message): print 'message from ' + str(switchAddress) 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) for i in range(len(message['Flowlist'])): # We only want to redirect outgoing flows if message['Flowlist'][i]['action'] != 'LOCAL': #my_match = of.ofp_match(nw_src=message['Flowlist'][i]['nw_src'],nw_dst=message['Flowlist'][i]['nw_dst']) my_match = of.ofp_match( dl_type=0x800, nw_src=message['Flowlist'][i]['nw_src'], nw_dst=message['Flowlist'][i]['nw_dst']) print "Flow Match: " + str(my_match) msg = of.ofp_flow_mod() msg.match = my_match msg.priority = 65535 # There is a bug here, the error it shows reads "can't convert argument to int" when try to send the message # If the actions are omitted (aka we order to drop the packets with match, we get no error) msg.actions.append( of.ofp_action_enqueue( port=int( message['Flowlist'][i]['action'].split(':')[1]), queue_id=int(message['QueueList'][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: connectionDpid = connection.dpid print "Connection dpid: " + str(connectionDpid) dpidStr = dpidToStr(connectionDpid) dpidStr = dpidStr.replace("-", "") print 'Real dpidStr: ' + dpidStr if dpid == dpidStr: connection.send(msg) print 'Sent to: ' + str(connection) print 'Well...done'
def install_enqueue(event, packet, outport, q_id): log.debug("** Switch %i: Installing flow %s.%i -> %s.%i", dpid, src_mac, inport, dst_mac, outport) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, inport) msg.priority = QOS_PRIORITY msg.actions.append( of.ofp_action_enqueue(port=outport, queue_id=q_id)) msg.data = event.ofp msg.idle_timeout = IDLE_TTL msg.hard_timeout = HARD_TTL event.connection.send(msg) log.debug("** Switch %i: Rule sent: Outport %i, Queue %i", dpid, outport, q_id) return
def take_action(self, packet, msg, event, port): if packet.find("ipv4") is not None \ and (packet.find("tcp") is not None or packet.find("udp") is not None): if packet.find("tcp") is not None: transport_type = "tcp" else: transport_type = "udp" transport = packet.find(transport_type) transport_srcport = transport.srcport transport_dstport = transport.dstport src_mac = packet.src dst_mac = packet.dst ip_packet = packet.find("ipv4") src_ip = ip_packet.srcip dst_ip = ip_packet.dstip msg.match = of.ofp_match.from_packet(packet, event.port) action = self.get_action(transport_type, transport_srcport, transport_dstport, src_mac, dst_mac, src_ip, dst_ip) print action if action == "DP": None elif action == "HP": msg.actions.append(of.ofp_action_enqueue(port=port, queue_id=0)) else: msg.actions.append(of.ofp_action_enqueue(port=port, queue_id=1)) else: msg.match = of.ofp_match.from_packet(packet, event.port) msg.actions.append(of.ofp_action_output(port=port)) msg.data = event.ofp self.connection.send(msg)
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 enqueue_mac(self, priority, idle, hard, classifier, dstMAC, port, queue, srcMAC=None, data=None): msg = of.ofp_flow_mod() msg.data = data msg.priority = priority msg.idle_timeout = idle msg.hard_timeout = hard msg.match = of.ofp_match(dl_dst=dstMAC) msg.actions.append(of.ofp_action_enqueue(port=port, queue_id=queue)) self.connection.send(msg)
def handle_flows_redirection(cls, dpid, connections, switch_addresss, message): """ Sends flow mod messages to redirect flows to created queues """ dpid = dpid[:len(dpid)-1] dpid = dpid[len(dpid)-12:] msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.priority = 65535 cls.send_command_to_switch(dpid, connections, msg) 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']) msg = of.ofp_flow_mod() msg.match = my_match msg.priority = 65535 msg.idle_timeout = 60 #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']))) for connection in connections: connection_dpid=connection.dpid dpid_str=dpidToStr(connection_dpid) dpid_str=dpid_str.replace("-", "") if dpid == dpid_str: connection.send(msg) global flow_mod_time flow_mod_time = time.time() - queues_done_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) #if len(message['bw_list']) > capacity/min_sla: if len(message['bw_list']) > capacity/min_sla: self.handle_queues_full(dpid, connections, switch_addresss, message)
def push_flow_label_bandwidth(self, source_ip, dest_ip, out_port, timeout, bandwidth_this, destination_network, rid): output_interface = self.port_to_interface[out_port] msg = of.ofp_flow_mod() msg.idle_timeout = 0 msg.hard_timeout = timeout msg.match.dl_type = ethernet.IP_TYPE #msg.match.nw_proto = ipv4.ICMP_PROTOCOL msg.match.nw_src = IPAddr(source_ip) #if dest_ip == "10.0.2.100": # print "The flow that's going to be added must match source ip ("+source_ip+") too along with destination ip "+dest_ip # msg.match.nw_src = IPAddr(source_ip) #else: # print "source_ip match constraint not added" #I SUSPECT MATCHING THIS ENTIRE NETWORK RANGE AND APPENDING A SINGLE MAC ID FOR THE FLOW IS WRONG. DEBUG FROM HERE msg.match.nw_dst = IPAddr(dest_ip) # msg.match.nw_dst = IPAddr(srcip) msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr(self.arp_table[self.routing_table[destination_network] ['RouterInterface']]))) msg.actions.append( of.ofp_action_dl_addr.set_dst(EthAddr(self.arp_table[dest_ip]))) msg.actions.append( of.ofp_action_enqueue( port=out_port, queue_id=self.bandwidth_to_queue[bandwidth_this])) self.connection.send(msg) print "\n#Starting thread to keep track of connection time#" t1 = threading.Thread(target=timer, args=(timeout, bandwidth_this, rid)) t1.start() self.allocated_bandwidths[output_interface][source_ip] = { 'dest_ip': dest_ip, 'bandwidth': self.bandwidth_to_queue[bandwidth_this] } #queueno denotes bandwidth
def packetForwarding(): queueId = 2 if packet.type == packet.ARP_TYPE: srcIp = str(packet.payload.protosrc) dstIp = str(packet.payload.protodst) elif packet.type == packet.IP_TYPE: srcIp = str(packet.payload.srcip) dstIp = str(packet.payload.dstip) if packet.next.protocol == packet.next.TCP_PROTOCOL: dstPort = str(packet.next.payload.dstport) if checkFirewallRules(srcIp, dstIp, dstPort): return if checkPremiumPolicies(dstIp) | checkPremiumPolicies(srcIp): log.info("premium") queueId = 1 if dpid not in self.forwardingTable: self.forwardingTable[dpid] = {} self.forwardingTable[dpid][src] = {} self.forwardingTable[dpid][src]["port"] = inport self.forwardingTable[dpid][src][ "timestamp"] = datetime.datetime.now() if dst in self.forwardingTable[dpid]: if (datetime.datetime.now() - self.forwardingTable[dpid][dst]["timestamp"] ).total_seconds() > 30: self.forwardingTable[dpid].pop(dst) if dst not in self.forwardingTable[dpid]: flood() return log.info("queueID: %s", queueId) outport = self.forwardingTable[dpid][dst]["port"] log.info("# S%i: Message sent: Outport %i src %s inport %s\n", dpid, outport, src, inport) msg = of.ofp_flow_mod() msg.data = event.ofp msg.match = of.ofp_match.from_packet(packet, inport) msg.priority = 1000 # msg.actions.append(of.ofp_action_output(port = outport)) msg.actions.append( of.ofp_action_enqueue(port=outport, queue_id=queueId)) event.connection.send(msg)
def handleFlowsRedirection(self, dpid, connections, switchAddress, message): print 'message from ' + str(switchAddress) 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) for i in range(len(message['Flowlist'])): # We only want to redirect outgoing flows if message['Flowlist'][i]['action'] != 'LOCAL': #my_match = of.ofp_match(nw_src=message['Flowlist'][i]['nw_src'],nw_dst=message['Flowlist'][i]['nw_dst']) my_match = of.ofp_match(dl_type = 0x800,nw_src=message['Flowlist'][i]['nw_src'],nw_dst=message['Flowlist'][i]['nw_dst']) print "Flow Match: " + str(my_match) msg = of.ofp_flow_mod() msg.match = my_match msg.priority=65535 # There is a bug here, the error it shows reads "can't convert argument to int" when try to send the message # If the actions are omitted (aka we order to drop the packets with match, we get no error) msg.actions.append(of.ofp_action_enqueue(port=int(message['Flowlist'][i]['action'].split(':')[1]), queue_id=int(message['QueueList'][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: connectionDpid=connection.dpid print "Connection dpid: " + str(connectionDpid) dpidStr=dpidToStr(connectionDpid) dpidStr=dpidStr.replace("-", "") print 'Real dpidStr: ' + dpidStr if dpid == dpidStr: connection.send(msg) print 'Sent to: ' + str(connection) print 'Well...done'
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 install_enqueue(): q_id = 2 #default free user if self.user_queue.get(src_ip) != None and self.user_queue.get( dst_ip) != None: q_id = max(self.user_queue[src_ip], self.user_queue[dst_ip]) elif self.user_queue.get(dst_ip) != None: q_id = self.user_queue[dst_ip] elif self.user_queue.get(src_ip) != None: q_id = self.user_queue[src_ip] log.debug( "\nPutting packet of source {} destination {} into queue {}". format(src_ip, dst_ip, q_id)) msg = of.ofp_flow_mod() msg.priority = 50 # lower than firewall msg.data = ofMsg msg.hard_timeout = 5 msg.match = of.ofp_match.from_packet(packet, in_port) msg.actions.append( of.ofp_action_enqueue(port=self.macMap[dpid][dst_mac], queue_id=q_id)) event.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid print "PacketIn: ", dpidToStr(event.connection.dpid) if event.connection.dpid == s1_dpid: msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL)) print "broadcast" event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_enqueue(port=4, queue_id=1)) print "Enqueue to port 4 qid 1" event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_enqueue(port=4, queue_id=2)) print "Enqueue to port 4 qid 2" event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port=1)) print "output to port 1" event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port=2)) print "output to port 2" event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port=3)) print "output to port 3" event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port=4)) print "output to port 4" event.connection.send(msg) elif event.connection.dpid == s2_dpid: msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.actions.append(of.ofp_action_output(port=2)) print "output to port 2" event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.actions.append(of.ofp_action_output(port=1)) print "output to port 1" 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 #if msg.match.tp_src == 5001 or msg.match.tp_dst == 5001: # msg.actions.append(of.ofp_action_enqueue(port = port,queue_id=1)) # 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 if msg.match.tp_src == int(x) or msg.match.tp_dst == int(x): msg.actions.append(of.ofp_action_enqueue(port = port,queue_id=1)) else: msg.actions.append(of.ofp_action_output(port = port)) msg.data = event.ofp # 6a self.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 reply_request(self, success, request_id, event, title_aggr=None, w = None): # Build the response resp_msg = dts_pb2.ControlResponse() resp_msg.status = resp_msg.SUCCESS if success else resp_msg.FAILURE if request_id != None: resp_msg.request_id = request_id if self.aggr and w: # reply for the second workspace attachment print 'title_aggr', title_aggr, 'flow', self.flow # Send FLOW_MOD to the swith that is ataching an entity title = w.title if title_aggr in workspaces_aggr: w2 = workspaces_aggr[title_aggr] else: log.info('Unknown aggregated workspace title') title_hash = hashlib.sha256(title).digest()[:12] title_hash_aggr = hashlib.sha256(title_aggr).digest()[:12] recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append(of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(event.dpid, recvRule) try: s = w.switches[event.dpid] except KeyError: s = w.WPSwitch(event.dpid) w.switches[s.dpid] = s if event.dpid == w2.path[-1]: s.used_ports.add(graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1])-1]]['ports'][w2.path[-1]]) else: s.used_ports.add(graph[w2.path[0]][w2.path[w2.path.index(w2.path[0])+1]]['ports'][w2.path[0]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append(of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(event.dpid, sendRule) # Send FLOW_MOD to the switch that created the workspace switch1 = wks[w.title] print 'OZUUUUUU1', switch1.dpid, switch1.port, try: s = w.switches[switch1.dpid] except KeyError: s = w.WPSwitch(switch1.dpid) w.switches[s.dpid] = s if switch1.dpid == w2.path[0]: s.used_ports.add(graph[w2.path[0]][w2.path[w2.path.index(w2.path[0])+1]]['ports'][w2.path[0]]) else: s.used_ports.add(graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1])-1]]['ports'][w2.path[-1]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append(of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, sendRule) recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append(of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, recvRule) resp_msg = resp_msg.SerializeToString() # Send response back to the entity resp = of.ofp_packet_out() if not self.wifi: # not wifi resp.data = ''.join((DTSA.HEADER, struct.pack("<H", len(resp_msg)), resp_msg)) else: resp.data = ''.join((self.addrResp, struct.pack("<H", len(resp_msg)), resp_msg)) resp.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(resp)
def _handle_PacketIn(self, event): dpid = event.connection.dpid inport = event.port 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] = {} # Cria uma tabela vazia para registro de disponibilidade de QoS self.hasQoS[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%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) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) else: log.debug("%i %i learned %s", dpid, inport, str(packet.next.srcip)) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning( "%i %i not sending packet for %s back out of the " + "input port" % (dpid, inport, str(dstaddr))) else: log.debug( "%i %i installing flow for %s => %s out port %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) match.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=of.ofp_match.from_packet( packet, inport)) event.connection.send(msg.pack()) ########################################################################################################## ########################################### Instrucoes QoS ############################################### ########################################################################################################## net = packet.next transp = packet.next.next # Realiza o mapeamento inicial entre IP, porta e QoS (-1) if net.protocol == 6 and transp.dstport == SERVER_PORT: if not self.portMap.has_key(net.srcip): self.portMap = {net.srcip: (transp.srcport, -1)} # Testa se o pacote eh UDP (troca de mensagens RSVP) if net.protocol == 17: # Testa se a mensagem eh RSVP originada pelo cliente if transp.srcport == RSVP_CLIENT_PORT: # Testa se a mensagem eh RSVP RESV if net.tos != 0: # Atualiza a fila do mapeamento IP, porta e QoS port, queue = self.portMap[net.srcip] queue = (net.tos / 10) - 1 self.portMap[net.srcip] = (port, queue) # Consulta a disponibilidade de QoS na porta de saida do roteador if not self.hasQoS[dpid].has_key(inport): self.hasQoS[dpid][inport] = be if self.hasQoS[dpid][inport] + classlist[ queue].pico <= TX_MAX: log.info( "QoS disponivel em R%d - porta %d: %d", dpid, inport, TX_MAX - self.hasQoS[dpid][inport]) else: log.info( "QoS nao disponivel - largura de banda insuficiente" ) # Testa de a mensagem eh RSVP FIN else: # Exclui o mapeamento IP, porta e QoS if self.portMap.has_key(net.srcip): del self.portMap[net.srcip] # Testa se a mensagem eh RSVP originada pelo servidor if transp.srcport == RSVP_SERVER_PORT: # Testa se a mensagem eh RSVP RESV_CONF if net.tos != 0: port, queue = self.portMap[net.dstip] # Aplica QoS na porta de saida do roteador qos = os.popen( "ovs-vsctl list qos | grep _uuid | awk '{print $3}'" ).read().strip('\n') os.system('ovs-vsctl set port r%d-eth%d qos=%s' % (dpid, prt, qos)) log.info("QoS %s aplicada em R%s - porta %d", qos, dpid, prt) # Acrescenta a banda alocada a tabela de disponibilidade de QoS self.hasQoS[dpid][prt] += classlist[self.portMap[ net.dstip][1]].pico # Copia os parametros de cabecalho do pacote UDP msg1 = of.ofp_flow_mod(command=of.OFPFC_MODIFY) msg1.match = of.ofp_match.from_packet( packet, inport) # Altera os parametros de cabecalho para o futuro fluxo TCP msg1.priority = 65535 msg1.idle_timeout = 30 msg1.hard_timeout = 120 msg1.match.nw_proto = 6 msg1.match.nw_tos = 0 msg1.match.tp_src = SERVER_PORT msg1.match.tp_dst = port msg1.actions.append( of.ofp_action_enqueue(port=prt, queue_id=queue)) # Instala a regra no roteador event.connection.send(msg1) log.info("Fila %d aplicada ao fluxo tp_dst %d", queue, port) ########################################################################################################## ########################################### Instrucoes QoS ############################################### ########################################################################################################## elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } # Check if we've already ARPed recently if (dpid, dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, str(r.protodst), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, str(a.protosrc)) else: log.debug("%i %i learned %s", dpid, inport, str(a.protosrc)) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) # 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... if not self.arpTable[dpid][ a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves 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, 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) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(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 attach(self, entity, packet=None): if entity.title in self.entities: return False self.entities[entity.title] = entity entity.workspaces[self.title] = self self.switches2 += [entity.switch_dpid] try: s = self.switches[entity.switch_dpid] except KeyError: s = self.WPSwitch(entity.switch_dpid) self.switches[s.dpid] = s s.used_ports.add(entity.port) #print 'self.switches.keys', self.switches.keys() #print g.nodes() if self.qos: path = nx.shortest_path (g, self.switches2[-1], self.switches2[0], weight='cost') strInfo = ' -> path with minimum QoS cost between %d and %d is: ' % (self.switches2[-1], self.switches2[0]) else: path = nx.shortest_path (g, self.switches2[-1], self.switches2[0]) strInfo = ' -> shortest path between %d and %d is: ' % (self.switches2[-1], self.switches2[0]) strInfo += str(path) log.info(strInfo) if not self.wifi: msg = of.ofp_flow_mod() #msg.match.dl_type = 0x0880 msg.command = of.OFPFC_MODIFY_STRICT # of.OFPFC_MODIFY || of.OFPFC_ADD msg.match.dl_dst = self.title_hash[:6] msg.match.dl_src = self.title_hash[6:] if path.__len__() > 1: if self.bw and self.cos: log.info(" -> enqueuing in queue , corresponding to CoS '%s'" % self.cos) for i in path: if i == path[-1]: self.switches[i].used_ports.add(g[i][path[path.index(i)-1]]['ports'][i]) elif i == path[0]: self.switches[i].used_ports.add(g[i][path[path.index(i)+1]]['ports'][i]) else: try: s = self.switches[i] except KeyError: s = self.WPSwitch(i) self.switches[i] = s self.switches[i].used_ports.add(g[i][path[path.index(i)+1]]['ports'][i]) self.switches[i].used_ports.add(g[i][path[path.index(i)-1]]['ports'][i]) if self.bw and self.cos: msg.actions = [of.ofp_action_enqueue(port=p) for p in self.switches[i].used_ports] # ofp_action_enqueue(port=0, queue_id=0) else: print 'action_ouput' msg.actions = [of.ofp_action_output(port=p) for p in self.switches[i].used_ports] core.openflow.sendToDPID(i, msg) else: msg.actions = [of.ofp_action_output(port=p) for p in s.used_ports] core.openflow.sendToDPID(s.dpid, msg) else: # ============================================================================================================================== wifi rule1 = of.ofp_flow_mod() rule1.match.dl_dst = self.title_hash[:6] #rule1.match.dl_type = 0x0880 rule1.command = of.OFPFC_MODIFY_STRICT rule1.actions.append(of.ofp_action_dl_addr.set_src(self.title_hash[:6])) rule1.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr("FF:FF:FF:FF:FF:FF"))) rule2 = of.ofp_flow_mod() rule2.match.dl_dst = EthAddr("FF:FF:FF:FF:FF:FF") rule2.match.dl_src = self.title_hash[6:] #rule2.match.dl_type = 0x0880 rule2.command = of.OFPFC_MODIFY_STRICT if path.__len__() > 1: for i in path: if i == path[-1]: self.switches[i].used_ports.add(g[i][path[path.index(i)-1]]['ports'][i]) elif i == path[0]: self.switches[i].used_ports.add(g[i][path[path.index(i)+1]]['ports'][i]) for p in self.switches[i].used_ports: rule1.actions.append(of.ofp_action_output(port=p)) core.openflow.sendToDPID(i, rule1) else: try: s = self.switches[i] except KeyError: s = self.WPSwitch(i) self.switches[i] = s self.switches[i].used_ports.add(g[i][path[path.index(i)+1]]['ports'][i]) self.switches[i].used_ports.add(g[i][path[path.index(i)-1]]['ports'][i]) if self.bw and self.cos: # print 'enqueue' rule2.actions = [of.ofp_action_enqueue(port=p) for p in self.switches[i].used_ports] # ofp_action_enqueue(port=0, queue_id=0) else: rule2.actions = [of.ofp.action_output(port=p) for p in self.switches[i].used_ports] core.openflow.sendToDPID(i, rule2) else: for p in s.used_ports: rule1.actions.append(of.ofp_action_output(port=p)) core.openflow.sendToDPID(s.dpid, rule1) rule2.actions = [of.ofp_action_output(port=p) for p in s.used_ports] core.openflow.sendToDPID(s.dpid, rule2) #print 'self.switches', self.switches # for debug return True
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_flows_redirection(cls, dpid, connections, switch_addresss, message): """ Sends flow mod messages to redirect flows to created queues """ #print "Received message for flow redirection: ", message dpid = dpid[:len(dpid)-1] dpid = dpid[len(dpid)-12:] #msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) #msg.priority = 65535 #cls.send_command_to_switch(dpid, connections, msg) #dpid_a = str(dpidToStr(event.dpid)) #dpid_str = dpid_a.replace("-", "") switch_index = 0 # Create a new entry in our flow state table for the new flow for i in range(len(switch_states)): if switch_states[i]['dpid'] == dpid: #print "found switch" switch_index = i for i in range(len(message['bw_list'])): # We only want to redirect outgoing flows if message['bw_list'][i]['action'] != 'OFPP_LOCAL': for j in range(len(switch_states[switch_index]['flow_stats'])): if (message['bw_list'][i]['nw_src'] == switch_states[switch_index]['flow_stats'][j]['nw_src']) and (message['bw_list'][i]['nw_dst'] == switch_states[switch_index]['flow_stats'][j]['nw_dst']): flow_index = j break if ((switch_states[switch_index]['flow_stats'][flow_index]['nw_src'] == '10.1.1.3') or (switch_states[switch_index]['flow_stats'][flow_index]['nw_src'] == '10.1.1.13')): my_match = of.ofp_match(dl_type = 0x800, \ dl_src = EthAddr(switch_states[switch_index]['flow_stats'][flow_index]['dl_src']), dl_dst = EthAddr(switch_states[switch_index]['flow_stats'][flow_index]['dl_dst']),\ nw_src = switch_states[switch_index]['flow_stats'][flow_index]['nw_src'], nw_dst = switch_states[switch_index]['flow_stats'][flow_index]['nw_dst'], \ dl_vlan = switch_states[switch_index]['flow_stats'][flow_index]['dl_vlan'], \ #in_port = switch_states[switch_index]['flow_stats'][flow_index]['in_port'], \ nw_tos = switch_states[switch_index]['flow_stats'][flow_index]['nw_tos'], nw_proto = switch_states[switch_index]['flow_stats'][flow_index]['nw_proto'], \ tp_dst = switch_states[switch_index]['flow_stats'][flow_index]['tp_dst']) else: my_match = of.ofp_match(dl_type = 0x800, \ dl_src = EthAddr(switch_states[switch_index]['flow_stats'][flow_index]['dl_src']), dl_dst = EthAddr(switch_states[switch_index]['flow_stats'][flow_index]['dl_dst']),\ nw_src = switch_states[switch_index]['flow_stats'][flow_index]['nw_src'], nw_dst = switch_states[switch_index]['flow_stats'][flow_index]['nw_dst'], \ dl_vlan = switch_states[switch_index]['flow_stats'][flow_index]['dl_vlan'], \ #in_port = switch_states[switch_index]['flow_stats'][flow_index]['in_port'], \ nw_tos = switch_states[switch_index]['flow_stats'][flow_index]['nw_tos'], nw_proto = switch_states[switch_index]['flow_stats'][flow_index]['nw_proto'], \ tp_src = switch_states[switch_index]['flow_stats'][flow_index]['tp_src'], tp_dst = switch_states[switch_index]['flow_stats'][flow_index]['tp_dst']) #if ((switch_states[switch_index]['flow_stats'][flow_index]['nw_src'] == '10.1.1.3') or (switch_states[switch_index]['flow_stats'][flow_index]['nw_src'] == '10.1.1.13')): #msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) #msg.priority = 65535 #cls.send_command_to_switch(dpid, connections, msg) msg = of.ofp_flow_mod() msg.match = my_match #print "Match for flow: ", msg.match msg.priority = 65535 msg.idle_timeout = 60 msg.actions.append(of.ofp_action_enqueue(port=int(message['bw_list'][i]['action']), queue_id=int(message['queue_list'][i]['queueId']))) #print "Sending redirect" cls.send_command_to_switch(dpid, connections, msg) #if len(message['bw_list']) > capacity/min_sla: #if len(message['bw_list']) > capacity/min_sla: #self.handle_queues_full(dpid, connections, switch_addresss, message) controlled = 1
def _handle_PacketIn (self, event): # parsing the input packet packet = event.parse() # updating out mac to port mapping self.macToPort[packet.src] = event.port if packet.type == packet.LLDP_TYPE or packet.type == 0x86DD: # Drop LLDP packets # Drop IPv6 packets # Send of command without actions #log.debug("Port type is LLDP or IPv6 -- dropping") msg = of.ofp_packet_out() msg.buffer_id = event.ofp.buffer_id msg.in_port = event.port self.connection.send(msg) return if packet.dst not in self.macToPort: # does not know out port # flood the packet # this is an ARP request/reply packet which is arriving to the switch for the first time #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) else: # The outport is known # Thus, we can create a open flow rule # installing Flow outport = self.macToPort[packet.dst] # creating openflow message msg = of.ofp_flow_mod() msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.idle_timeout = IDLE_TIMEOUT msg.hard_timeout = HARD_TIMEOUT msg.buffer_id = event.ofp.buffer_id if packet.type == packet.IP_TYPE: # extracting ipv4 payload from the ethernet part ip_part = packet.find('ipv4') #log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, outport)) # if packet is coming from 10.0.0.3, give it queue 1 (mentioned in the topo file) if ip_part.srcip == '10.0.0.3' or ip_part.srcip == '10.0.0.4': log.debug("-------QUEUE 3--------"); msg.actions.append(of.ofp_action_enqueue(port = outport, queue_id = 3)) self.connection.send(msg) return if outport == event.port: #log.warning("Same port for packet from %s -> %s on %s. Drop." % (packet.src, packet.dst, outport), dpidToStr(event.dpid)) return # For any other traffic, full bandwidth can be used (queue 0) log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, outport)) log.debug("-------QUEUE 0--------"); msg.actions.append(of.ofp_action_enqueue(port = outport, queue_id = 0)) self.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid # print "PacketIn: ", dpidToStr(event.connection.dpid) # switch s1 if event.connection.dpid==s1_dpid: # Flujos para la tabla de flujos del switch flow_s1_0 = of.ofp_flow_mod() flow_s1_0.priority = 32768 # A mayor valor mas prioridad flow_s1_0.match.in_port = 1 flow_s1_0vlan_id = of.ofp_action_vlan_vid(vlan_vid = 10) flow_s1_queue1 = of.ofp_action_enqueue(port = 3, queue_id = 1) flow_s1_0.actions = [flow_s1_0vlan_id,flow_s1_queue1] flow_s1_1 = of.ofp_flow_mod() flow_s1_1.priority = 32768 # A mayor valor mas prioridad flow_s1_1.match.in_port = 2 flow_s1_1vlan_id = of.ofp_action_vlan_vid(vlan_vid = 20) flow_s1_queue2 = of.ofp_action_enqueue(port = 3, queue_id = 2) flow_s1_1.actions = [flow_s1_1vlan_id,flow_s1_queue2] flow_s1_2 = of.ofp_flow_mod() flow_s1_2.priority = 32768 # A mayor valor mas prioridad flow_s1_2.match.dl_vlan = 10 flow_s1_2stripvlan = of.ofp_action_strip_vlan() flow_s1_2out = of.ofp_action_output(port = 1) flow_s1_2.actions = [flow_s1_2stripvlan,flow_s1_2out] flow_s1_3 = of.ofp_flow_mod() flow_s1_3.priority = 32768 # A mayor valor mas prioridad flow_s1_3.match.dl_vlan = 20 flow_s1_3stripvlan = of.ofp_action_strip_vlan() flow_s1_3out = of.ofp_action_output(port = 2) flow_s1_3.actions = [flow_s1_3stripvlan,flow_s1_3out] # Instalacion de los flujos previamente definidos core.openflow.sendToDPID(s1_dpid,flow_s1_0) core.openflow.sendToDPID(s1_dpid,flow_s1_1) core.openflow.sendToDPID(s1_dpid,flow_s1_2) core.openflow.sendToDPID(s1_dpid,flow_s1_3) # switch s2 if event.connection.dpid==s2_dpid: # Flujos para la tabla de flujos del switch flow_s2_0 = of.ofp_flow_mod() flow_s2_0.priority = 32768 # A mayor valor mas prioridad flow_s2_0.match.in_port = 2 flow_s2_0vlan_id = of.ofp_action_vlan_vid(vlan_vid = 20) flow_s2_queue2 = of.ofp_action_enqueue(port = 1, queue_id = 2) flow_s2_0.actions = [flow_s2_0vlan_id,flow_s2_queue2] flow_s2_1 = of.ofp_flow_mod() flow_s2_1.priority = 32768 # A mayor valor mas prioridad flow_s2_1.match.in_port = 3 flow_s2_1vlan_id = of.ofp_action_vlan_vid(vlan_vid = 10) flow_s2_queue1 = of.ofp_action_enqueue(port = 1, queue_id = 1) flow_s2_1.actions = [flow_s2_1vlan_id,flow_s2_queue1] flow_s2_2 = of.ofp_flow_mod() flow_s2_2.priority = 32768 # A mayor valor mas prioridad flow_s2_2.match.dl_vlan = 10 flow_s2_2stripvlan = of.ofp_action_strip_vlan() flow_s2_2out = of.ofp_action_output(port = 3) flow_s2_2.actions = [flow_s2_2stripvlan,flow_s2_2out] flow_s2_3 = of.ofp_flow_mod() flow_s2_3.priority = 32768 # A mayor valor mas prioridad flow_s2_3.match.dl_vlan = 20 flow_s2_3stripvlan = of.ofp_action_strip_vlan() flow_s2_3out = of.ofp_action_output(port = 2) flow_s2_3.actions = [flow_s2_3stripvlan,flow_s2_3out] # Instalacion de los flujos previamente definidos core.openflow.sendToDPID(s2_dpid,flow_s2_0) core.openflow.sendToDPID(s2_dpid,flow_s2_1) core.openflow.sendToDPID(s2_dpid,flow_s2_2) core.openflow.sendToDPID(s2_dpid,flow_s2_3)
def reply_request(self, success, request_id, event, title_aggr=None, w=None): # Build the response resp_msg = dts_pb2.ControlResponse() resp_msg.status = resp_msg.SUCCESS if success else resp_msg.FAILURE if request_id != None: resp_msg.request_id = request_id if self.aggr and w: # reply for the second workspace attachment print 'title_aggr', title_aggr, 'flow', self.flow # Send FLOW_MOD to the swith that is ataching an entity title = w.title if title_aggr in workspaces_aggr: w2 = workspaces_aggr[title_aggr] else: log.info('Unknown aggregated workspace title') title_hash = hashlib.sha256(title).digest()[:12] title_hash_aggr = hashlib.sha256(title_aggr).digest()[:12] recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append( of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(event.dpid, recvRule) try: s = w.switches[event.dpid] except KeyError: s = w.WPSwitch(event.dpid) w.switches[s.dpid] = s if event.dpid == w2.path[-1]: s.used_ports.add( graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1]) - 1]]['ports'][w2.path[-1]]) else: s.used_ports.add( graph[w2.path[0]][w2.path[w2.path.index(w2.path[0]) + 1]]['ports'][w2.path[0]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append( of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(event.dpid, sendRule) # Send FLOW_MOD to the switch that created the workspace switch1 = wks[w.title] print 'OZUUUUUU1', switch1.dpid, switch1.port, try: s = w.switches[switch1.dpid] except KeyError: s = w.WPSwitch(switch1.dpid) w.switches[s.dpid] = s if switch1.dpid == w2.path[0]: s.used_ports.add( graph[w2.path[0]][w2.path[w2.path.index(w2.path[0]) + 1]]['ports'][w2.path[0]]) else: s.used_ports.add( graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1]) - 1]]['ports'][w2.path[-1]]) sendRule = of.ofp_flow_mod() sendRule.command = of.OFPFC_MODIFY_STRICT #sendRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches sendRule.match.dl_dst = title_hash[:6] sendRule.match.dl_src = title_hash[6:] sendRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6])) sendRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash_aggr[6:])) sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow)) for p in s.used_ports: sendRule.actions.append( of.ofp_action_enqueue(port=p, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, sendRule) recvRule = of.ofp_flow_mod() recvRule.command = of.OFPFC_MODIFY_STRICT #recvRule.match.dl_type = 0x0880 # Causes conflicts with user-space switches recvRule.match.dl_dst = title_hash_aggr[:6] recvRule.match.dl_src = title_hash_aggr[6:] recvRule.match.dl_vlan = self.flow recvRule.actions.append( of.ofp_action_dl_addr.set_dst(title_hash[:6])) recvRule.actions.append( of.ofp_action_dl_addr.set_src(title_hash[6:])) recvRule.actions.append( of.ofp_action_enqueue(port=event.port, queue_id=1)) core.openflow.sendToDPID(switch1.dpid, recvRule) resp_msg = resp_msg.SerializeToString() # Send response back to the entity resp = of.ofp_packet_out() if not self.wifi: # not wifi resp.data = ''.join( (DTSA.HEADER, struct.pack("<H", len(resp_msg)), resp_msg)) else: resp.data = ''.join( (self.addrResp, struct.pack("<H", len(resp_msg)), resp_msg)) resp.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(resp)
def attach(self, entity, packet=None): if entity.title in self.entities: return False self.entities[entity.title] = entity entity.workspaces[self.title] = self self.switches2 += [entity.switch_dpid] try: s = self.switches[entity.switch_dpid] except KeyError: s = self.WPSwitch(entity.switch_dpid) self.switches[s.dpid] = s s.used_ports.add(entity.port) #print 'self.switches.keys', self.switches.keys() #print graph.nodes() if self.qos: path = nx.shortest_path(graph, self.switches2[-1], self.switches2[0], weight='cost') log.info( ' -> path with minimum QoS cost between {} and {} is: {}'. format(self.switches2[-1], self.switches2[0], path)) else: path = nx.shortest_path(graph, self.switches2[-1], self.switches2[0]) log.info(' -> shortest path between {} and {} is: {}'.format( self.switches2[-1], self.switches2[0], path)) if not self.wifi: msg = of.ofp_flow_mod() #msg.match.dl_type = 0x0880 # Causes conflicts with user-space switchs msg.command = of.OFPFC_MODIFY_STRICT # of.OFPFC_MODIFY || of.OFPFC_ADD msg.match.dl_dst = self.title_hash[:6] msg.match.dl_src = self.title_hash[6:] if path.__len__() > 1: if self.bw and self.cos: log.info( " -> enqueuing in queue 1, corresponding to CoS silver" ) for i in path: if i == path[-1]: self.switches[i].used_ports.add( graph[i][path[path.index(i) - 1]]['ports'][i]) elif i == path[0]: self.switches[i].used_ports.add( graph[i][path[path.index(i) + 1]]['ports'][i]) else: try: s = self.switches[i] except KeyError: s = self.WPSwitch(i) self.switches[i] = s self.switches[i].used_ports.add( graph[i][path[path.index(i) + 1]]['ports'][i]) self.switches[i].used_ports.add( graph[i][path[path.index(i) - 1]]['ports'][i]) if self.bw and self.cos: msg.actions = [ of.ofp_action_enqueue(port=p, queue_id=0) for p in self.switches[i].used_ports ] # ofp_action_enqueue(port=0, queue_id=0) else: msg.actions = [ of.ofp_action_enqueue(port=p, queue_id=1) for p in self.switches[i].used_ports ] core.openflow.sendToDPID(i, msg) else: #print 'output:', s.used_ports, 'dpid:', s.dpid #msg.actions = [of.ofp_action_output(port=p) for p in s.used_ports] if self.bw and self.cos: msg.actions = [ of.ofp_action_enqueue(port=p, queue_id=0) for p in s.used_ports ] else: msg.actions = [ of.ofp_action_enqueue(port=p, queue_id=1) for p in s.used_ports ] core.openflow.sendToDPID(s.dpid, msg) else: # ============================================================================================================================== wifi rule1 = of.ofp_flow_mod() rule1.match.dl_dst = self.title_hash[:6] #rule1.match.dl_type = 0x0880 # Causes conflicts with user-space switch rule1.command = of.OFPFC_MODIFY_STRICT rule1.actions.append( of.ofp_action_dl_addr.set_src(self.title_hash[:6])) rule1.actions.append( of.ofp_action_dl_addr.set_dst(EthAddr("FF:FF:FF:FF:FF:FF"))) rule2 = of.ofp_flow_mod() rule2.match.dl_dst = EthAddr("FF:FF:FF:FF:FF:FF") rule2.match.dl_src = self.title_hash[6:] #rule2.match.dl_type = 0x0880 rule2.command = of.OFPFC_MODIFY_STRICT if path.__len__() > 1: for i in path: if i == path[-1]: self.switches[i].used_ports.add( graph[i][path[path.index(i) - 1]]['ports'][i]) elif i == path[0]: self.switches[i].used_ports.add( graph[i][path[path.index(i) + 1]]['ports'][i]) for p in self.switches[i].used_ports: rule1.actions.append(of.ofp_action_output(port=p)) core.openflow.sendToDPID(i, rule1) else: try: s = self.switches[i] except KeyError: s = self.WPSwitch(i) self.switches[i] = s self.switches[i].used_ports.add( graph[i][path[path.index(i) + 1]]['ports'][i]) self.switches[i].used_ports.add( graph[i][path[path.index(i) - 1]]['ports'][i]) if self.bw and self.cos: # print 'enqueue' rule2.actions = [ of.ofp_action_enqueue(port=p) for p in self.switches[i].used_ports ] # ofp_action_enqueue(port=0, queue_id=0) else: rule2.actions = [ of.ofp_action_output(port=p) for p in self.switches[i].used_ports ] core.openflow.sendToDPID(i, rule2) else: for p in s.used_ports: rule1.actions.append(of.ofp_action_output(port=p)) core.openflow.sendToDPID(s.dpid, rule1) rule2.actions = [ of.ofp_action_output(port=p) for p in s.used_ports ] core.openflow.sendToDPID(s.dpid, rule2) #print 'self.switches', self.switches # for debug return True
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 dnsval = core.DNSSpy.lookup(IPAddr(msg.match.nw_dst)) log.info("resolv is %s " % dnsval ) if dnsval is not None: if 'www.fun.com' in dnsval: log.info("priority 1 " ) msg.actions.append(of.ofp_action_enqueue(port = port, queue_id = 0x01)); if dnsval is not None: if 'www.work.com' in dnsval: log.info("priority 2 " ) msg.actions.append(of.ofp_action_enqueue(port = port, queue_id = 0x02)); msg.actions.append(of.ofp_action_output(port = port)) msg.data = event.ofp # 6a self.connection.send(msg)
def _handle_PacketIn(event): global s1_dpid, s2_dpid print "PacketIn:", dpidToStr(event.connection.dpid) if event.connection.dpid == s1_dpid: msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL)) event.connection.send(msg) # up: q0 for default queue.traffic from h3 to h4 # below:q1 for traffic h1 to h4 msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_enqueue(port=4, queue_id=1)) event.connection.send(msg) # below:q2 for traffic h2 to h4 msg = of.ofp_flow_mod() msg.priority = 100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_enqueue(port=4, queue_id=2)) event.connection.send(msg) # below:ports info msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port=3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port=4)) event.connection.send(msg) elif event.connection.dpid == s2_dpid: msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.actions.append(of.ofp_action_output(port=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.actions.append(of.ofp_action_output(port=1)) event.connection.send(msg)
def _handle_PacketIn (event): global s1_dpid, s2_dpid # print "PacketIn: ", dpidToStr(event.connection.dpid) if event.connection.dpid==s1_dpid: msg = of.ofp_flow_mod() msg.priority =1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0806 msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.1" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_enqueue(port = 4, queue_id=1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_src = "10.0.0.2" msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_enqueue(port = 4, queue_id=2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" msg.actions.append(of.ofp_action_output(port = 3)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg.actions.append(of.ofp_action_output(port = 4)) event.connection.send(msg) elif event.connection.dpid==s2_dpid: msg = of.ofp_flow_mod() msg.priority =1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port =1 msg.actions.append(of.ofp_action_output(port = 2)) event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority =1 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port =2 msg.actions.append(of.ofp_action_output(port = 1)) event.connection.send(msg) def launch (): core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) core.openflow.addListenerByName("PacketIn", _handle_PacketIn)
def _handle_PacketIn (self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.ip_mac_port: self.ip_mac_port[dpid] = {} for fake in self.fakeways: self.ip_mac_port[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid,inport, packet.next.srcip,packet.next.dstip) self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) if packet.next.srcip in self.ip_mac_port[dpid]: if self.ip_mac_port[dpid][packet.next.srcip] != (inport, packet.src): log.debug("%i %i RE-learned %s", dpid,inport,packet.next.srcip) else: #log.info("%i %i learned %s", dpid,inport,str(packet.next.srcip)) log.info("switch %i learned %s from input port %i", dpid,str(packet.next.srcip),inport) self.ip_mac_port[dpid][packet.next.srcip] = Entry(inport, packet.src) dstaddr = packet.next.dstip if dstaddr in self.ip_mac_port[dpid]: prt = self.ip_mac_port[dpid][dstaddr].port mac = self.ip_mac_port[dpid][dstaddr].mac print dstaddr if prt == inport: log.warning("%i %i not sending packet for %s back out of the " + "input port" % (dpid, inport, str(dstaddr))) else: log.debug("%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) if event.ofp.buffer_id==None: bid = None else: bid = event.ofp.buffer_id ip_packet=packet.find("ipv4") if ip_packet!=None: if ip_packet.protocol==1: actions3 = [] actions3.append(of.ofp_action_dl_addr.set_dst(mac)) #actions3.append(of.ofp_action_output(port = prt)) actions3.append(of.ofp_action_enqueue(port = prt,queue_id=1)) match3 = of.ofp_match.from_packet(packet, inport) match3.dl_type=0x800 match3.nw_proto = 1 match3.dl_src = None msg3 = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions3, priority=30, match=match3) event.connection.send(msg3.pack()) print "into queue 1" elif ip_packet.protocol==17 or ip_packet.protocol==6: udp_packet=packet.find("udp") if udp_packet==None: udp_packet=packet.find("tcp") if ip_packet.dstip==IPAddr("172.16.0.3") and udp_packet.dstport==5001: actions5 = [] actions5.append(of.ofp_action_dl_addr.set_dst(mac)) #actions5.append(of.ofp_action_output(port = prt)) actions5.append(of.ofp_action_enqueue(port = prt,queue_id=3)) match5 = of.ofp_match.from_packet(packet, inport) match5.dl_type=0x800 match5.nw_proto = 17 match5.nw_dst = IPAddr("172.16.0.3") match5.tp_dst = 5001 match5.dl_src = None msg5 = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions5, priority=43, match=match5) event.connection.send(msg5.pack()) print "privillaged user into queue 3" elif ip_packet.tos==0: actions2 = [] actions2.append(of.ofp_action_dl_addr.set_dst(mac)) #actions2.append(of.ofp_action_output(port = prt)) actions2.append(of.ofp_action_nw_tos(224)) actions2.append(of.ofp_action_enqueue(port = prt,queue_id=2)) match2 = of.ofp_match.from_packet(packet, inport) match2.dl_type=0x800 if udp_packet!=None: match2.nw_proto = 17 else: match2.nw_proto = 6 match2.dl_src = None msg2 = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions2, priority=42, match=match2) event.connection.send(msg2.pack()) print "into queue 2" else: actions1 = [] actions1.append(of.ofp_action_dl_addr.set_dst(mac)) #actions1.append(of.ofp_action_output(port = prt)) actions1.append(of.ofp_action_enqueue(port = prt,queue_id=2)) match1 = of.ofp_match.from_packet(packet, inport) match1.dl_type=0x800 match1.nw_tos = 224 match1.dl_src = None msg1 = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions1, priority=42, match=match1) event.connection.send(msg1.pack()) print "into queue 2 dscp tagged" else: actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) match4 = of.ofp_match.from_packet(packet, inport) match4.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions, priority=20, match=match4) event.connection.send(msg.pack()) elif self.arp_for_unknowns: if (dpid,dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid,dstaddr)] = [] bucket = self.lost_buffers[(dpid,dstaddr)] entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] self.outstanding_arps = {k:v for k,v in self.outstanding_arps.iteritems() if v > time.time()} if (dpid,dstaddr) in self.outstanding_arps: return self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, str(r.protodst), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.ip_mac_port[dpid]: if self.ip_mac_port[dpid][a.protosrc] != (inport, packet.src): log.debug("%i %i RE-learned %s", dpid,inport,str(a.protosrc)) else: log.info("switch %i learned %s from input port %i", dpid,str(a.protosrc),inport) self.ip_mac_port[dpid][a.protosrc] = Entry(inport, packet.src) # 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.ip_mac_port[dpid]: # We have an answer... if not self.ip_mac_port[dpid][a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves 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.ip_mac_port[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,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) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,'op:%i' % (a.opcode,)), str(a.protosrc), str(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)