def build_of_actions(self,inport,action_list): ### BUILD OF ACTIONS of_actions = [] for actions in action_list: outport = actions['outport'] del actions['outport'] if 'srcmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'srcport' in actions: of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport'])) if 'dstport' in actions: of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError("vlan_id and vlan_pcp must be set together!") pass else: of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) if (not inport is None) and (outport == inport): of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) else: of_actions.append(of.ofp_action_output(port=outport)) return of_actions
def inject_single_match_flow(self,cookie,vlan_id,port_id,forward_port, dl_type = ethernet.IP_TYPE, new_src_ip=None,new_dst_ip=None, nw_proto = ipv4.ICMP_PROTOCOL): ''' inject single vlan_id,port_id with forwarding port''' msg = of.ofp_flow_mod() msg.match.in_port=port_id msg.match.dl_vlan=vlan_id if dl_type: msg.match.dl_type = dl_type msg.match.nw_proto = nw_proto #print vlan_id,port_id #print self.switchVlan_obj.name,forward_port, self.switchVlan_obj.ethPortMap target_forward_port = forward_port if self.switchVlan_obj.multiDstIpMode: if self.dns_enable: # NAT + stripVid msg.actions.append(of.ofp_action_strip_vlan()) target_forward_port,new_srcIP = self.switchVlan_obj.match_edge_dict[(vlan_id,port_id)] msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(new_srcIP))) elif self.vlt_enable: #print self.switchVlan_obj.name+'(vlan_id=%d,port_id=%d)-->forward_port=%d' %(vlan_id,port_id,forward_port) # SRC host --> DST server msg.actions.append(of.ofp_action_strip_vlan()) else: if self.strip_vlan: msg.actions.append(of.ofp_action_strip_vlan()) msg.actions.append(of.ofp_action_output(port = target_forward_port)) msg.cookie = cookie self.connection.send(msg)
def resend_packet (self, packet_in, out_ports): """ Instructs the switch to resend a packet that it had sent to us. "packet_in" is the ofp_packet_in object the switch had sent to the controller due to a table-miss. """ log.debug( "Sending out: %s" % out_ports ) msg = of.ofp_packet_out() msg.data = packet_in # Add actions for each out port for out_port in out_ports: # If port is dot1q put on vlan tag if self.vlan_to_port[out_port] == 1: action = of.ofp_action_vlan_vid(vlan_vid = self.vlan_to_port[packet_in.in_port]) # Else strip vlan tag else: action = of.ofp_action_strip_vlan() msg.actions.append(action) # Send the packet out of the specified port action = of.ofp_action_output(port = out_port) msg.actions.append(action) # Send message to switch self.connection.send(msg) log.debug("Packet sent out: %s" % out_ports )
def build_of_actions(self,inport,action_list): ### BUILD OF ACTIONS of_actions = [] for actions in action_list: outport = actions['port'] del actions['port'] if 'srcmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'srcport' in actions: of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport'])) if 'dstport' in actions: of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError("vlan_id and vlan_pcp must be set together!") pass else: of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) if (not inport is None) and (outport == inport): of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) else: of_actions.append(of.ofp_action_output(port=outport)) return of_actions
def install_pop_rule(self, dpid, mac, label): ''' Install a flow rule on an edge switch to pop a label onto a flow. ''' # message for switch msg = of.ofp_flow_mod() # match on MAC dst and IP dst msg.match.dl_src = None # wildcard source MAC msg.match.dl_dst = None msg.match.dl_type = ethernet.IP_TYPE msg.match.dl_vlan = label # actions - pop label msg.actions.append(of.ofp_action_strip_vlan()) # set output port action port = self.topology_tracker.get_link_port(dpid, str(mac)) if port is None: log.warn("No port connecting {0} --> {1}".format(dpid, mac)) return msg.actions.append(of.ofp_action_output(port=port)) # set a timeout and send msg.idle_timeout = self.idle_timeout self.topology_tracker.graph.node[dpid]['connection'].send(msg)
def _set_path_on_swtiches (self, pid, path): for k, sw in enumerate(path): msg = of.ofp_flow_mod() if USE_VLAN_TAG: msg.match.dl_vlan = pid if USE_ETHERNET_SRC_TAG: msg.match.dl_src = EthAddr( self._int_to_MAC( pid ) ) # match ethernet addr if k < 1: # First one, host continue if k > len(path)-2: # Last one, host continue if k == len(path) - 2: # sw -> host if USE_VLAN_TAG: # strip vlan tag then send to host msg.actions.append( of.ofp_action_strip_vlan() ) if USE_ETHERNET_SRC_TAG: # add back the real src msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr(path[0]) ) ) msg.actions.append( of.ofp_action_output( port = self.hadj[path[k+1]][sw] ) ) core.openflow.sendToDPID(sw, msg) log.warning( "Set rule: %s -> %s via port %i", dpid_to_str(sw), path[k+1], self.hadj[path[k+1]][sw] ) else: # sw -> sw msg.actions.append( of.ofp_action_output( port = self.ports[sw][path[k+1]] ) ) core.openflow.sendToDPID(sw, msg) log.warning( "Set rule: %s -> %s via port %i", dpid_to_str(sw), dpid_to_str(path[k+1]), self.ports[sw][path[k+1]] )
def inject_single_match_flow(self, cookie, vlan_id, port_id, forward_port, dl_type=ethernet.IP_TYPE, new_src_ip=None, new_dst_ip=None, nw_proto=ipv4.ICMP_PROTOCOL): ''' inject single vlan_id,port_id with forwarding port''' msg = of.ofp_flow_mod() msg.match.in_port = port_id msg.match.dl_vlan = vlan_id if dl_type: msg.match.dl_type = dl_type msg.match.nw_proto = nw_proto #print vlan_id,port_id #print self.switchVlan_obj.name,forward_port, self.switchVlan_obj.ethPortMap target_forward_port = forward_port if self.switchVlan_obj.multiDstIpMode: if self.dns_enable: # NAT + stripVid msg.actions.append(of.ofp_action_strip_vlan()) target_forward_port, new_srcIP = self.switchVlan_obj.match_edge_dict[ (vlan_id, port_id)] msg.actions.append( of.ofp_action_nw_addr.set_src(IPAddr(new_srcIP))) elif self.vlt_enable: #print self.switchVlan_obj.name+'(vlan_id=%d,port_id=%d)-->forward_port=%d' %(vlan_id,port_id,forward_port) # SRC host --> DST server msg.actions.append(of.ofp_action_strip_vlan()) else: if self.strip_vlan: msg.actions.append(of.ofp_action_strip_vlan()) msg.actions.append(of.ofp_action_output(port=target_forward_port)) msg.cookie = cookie 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 inject_single_match_flow(self,cookie,vlan_id,port_id,forward_port, dl_type = TYPE_IP, new_src_ip=None,new_dst_ip=None, nw_proto = ipv4.ICMP_PROTOCOL): ''' inject single vlan_id,port_id with forwarding port''' msg = of.ofp_flow_mod() msg.match.in_port=port_id msg.match.dl_vlan=vlan_id if dl_type: msg.match.dl_type = dl_type msg.match.nw_proto = nw_proto #print vlan_id,port_id if self.strip_vlan: msg.actions.append(of.ofp_action_strip_vlan()) msg.actions.append(of.ofp_action_output(port = forward_port)) msg.cookie = cookie self.connection.send(msg)
def _send_rewrite_rule (self, ip, mac): p = ipinfo(ip)[1] for src_p in self.edge_ports: if src_p is p: continue if self.vid_by_port(src_p) == self.vid_by_port(p): msg = of.ofp_flow_mod() msg.priority += 1 msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = "%s/%s" % (dst.network, dst.subnet) msg.match.nw_src = "10.%s.%s.0/255.255.255.0" % (self._id,src_p) msg.match.in_port = src_p msg.match.nw_dst = ip msg.actions.append(of.ofp_action_dl_addr.set_src(self.mac)) msg.actions.append(of.ofp_action_dl_addr.set_dst(mac)) msg.actions.append(of.ofp_action_output(port=p)) self.connection.send(msg) else: msg = of.ofp_flow_mod() msg.priority += 1 msg.match = of.ofp_match() msg.match.dl_type = pkt.ethernet.IP_TYPE #msg.match.nw_dst = "%s/%s" % (dst.network, dst.subnet) msg.match.nw_src = "10.%s.%s.0/255.255.255.0" % (self._id,src_p) msg.match.in_port = src_p msg.match.nw_dst = ip self.connection.send(msg) msg = of.ofp_flow_mod() msg.match = of.ofp_match() msg.match.dl_vlan = self.vid_by_port(p) msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.nw_dst = ip msg.actions.append(of.ofp_action_dl_addr.set_src(self.mac)) msg.actions.append(of.ofp_action_dl_addr.set_dst(mac)) msg.actions.append(of.ofp_action_strip_vlan()) msg.actions.append(of.ofp_action_output(port=p)) self.connection.send(msg)
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)))
flow3msg.match.in_port = 3 flow3msg.match.nw_proto = 6 # ACTIONS--------------------------------- flow3vlan_id = of.ofp_action_vlan_vid (vlan_vid = 10) flow3out = of.ofp_action_output (port = 1) flow3msg.actions = [flow3vlan_id, flow3out] #5: switch4 = 0000000000000005 flow4msg = of.ofp_flow_mod() flow4msg.cookie = 0 flow4msg.priority = 32768 flow4msg.match.dl_vlan = 10 flow4msg.match.nw_proto = 6 # ACTIONS--------------------------------- flow4stripvlan = of.ofp_action_strip_vlan () flow4out = of.ofp_action_output (port = 1) flow4msg.actions = [flow4stripvlan, flow4out] #6: switch5 = 0000000000000005 flow5msg = of.ofp_flow_mod() flow5msg.cookie = 0 flow5msg.priority = 32768 flow5msg.match.dl_vlan = 20 flow5msg.match.nw_proto = 6 # ACTIONS--------------------------------- flow5stripvlan = of.ofp_action_strip_vlan () flow5out = of.ofp_action_output (port = 2) flow5msg.actions = [flow5stripvlan, flow5out] #7:
def install_flowrule(self, id, match, action): """ Install a flowrule in an OpenFlow switch. :param id: ID of the infra element stored in the NFFG :type id: str :param match: match part of the rule (keys: in_port, vlan_id) :type match: dict :param action: action part of the rule (keys: out, vlan_push, vlan_pop) :type action: dict :return: None """ conn = self.openflow.getConnection(dpid=self.infra_to_dpid[id]) if not conn: log.warning( "Missing connection for node element: %s! Skip flowrule " "installation..." % id) return msg = of.ofp_flow_mod() msg.match.in_port = match['in_port'] if 'vlan_id' in match: try: vlan_id = int(match['vlan_id']) except ValueError: log.warning( "VLAN_ID: %s in match field is not a valid number! " "Skip flowrule installation..." % match['vlan_id']) return msg.match.dl_vlan = vlan_id # Append explicit matching parameters to OF flowrule if 'flowclass' in match: for ovs_match_entry in match['flowclass'].split(','): kv = ovs_match_entry.split('=') # kv = [field, value] ~ ['dl_src', '00:0A:E4:25:6B:B6'] # msg.match.dl_src = "00:00:00:00:00:01" if kv[0] in ('dl_src', 'dl_dst'): setattr(msg.match, kv[0], EthAddr(kv[1])) elif kv[0] in ('in_port', 'dl_vlan', 'dl_type', 'ip_proto', 'nw_proto', 'nw_tos', 'nw_ttl', 'tp_src', 'tp_dst'): setattr(msg.match, kv[0], int(kv[1], 0)) elif kv[0] in ('nw_src', 'nw_dst'): setattr(msg.match, kv[0], IPAddr(kv[1])) else: setattr(msg.match, kv[0], kv[1]) if 'vlan_push' in action: try: vlan_push = int(action['vlan_push']) except ValueError: log.warning( "VLAN_PUSH: %s in action field is not a valid number! " "Skip flowrule installation..." % action['vlan_push']) return msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan_push)) # msg.actions.append(of.ofp_action_vlan_vid()) out = action['out'] # If out is in the detected saps --> always remove the VLAN tags if 'vlan_pop' in action: msg.actions.append(of.ofp_action_strip_vlan()) else: try: # If next node is a SAP we need to setup the MAC addresses and # strip VLAN from the frame explicitly if out in self.saps[id]: msg.actions.append(of.ofp_action_strip_vlan()) except KeyError: pass try: if out in self.saps[id]: dl_dst = self.saps[id][str(out)]['dl_dst'] dl_src = self.saps[id][str(out)]['dl_src'] msg.actions.append( of.ofp_action_dl_addr.set_dst(EthAddr(dl_dst))) msg.actions.append( of.ofp_action_dl_addr.set_src(EthAddr(dl_src))) except KeyError: pass try: out_port = int(action['out']) except ValueError: log.warning( "Output port: %s is not a valid port in flowrule action: %s! " "Skip flowrule installation..." % (action['out'], action)) return msg.actions.append(of.ofp_action_output(port=out_port)) log.debug("Install flow entry into INFRA: %s on connection: %s ..." % (id, conn)) conn.send(msg) log.log(VERBOSE, "Sent raw OpenFlow flowrule:\n%s" % msg)
def set_hosts (self, host_data): """ Receive list of hosts This gets called with a list of dictionaries that each contain information about a host. Each time this is called, you get a complete list of all current hosts. Each entry looks something like this: {"ether" : "01:02:03:04:05:06", "ip" : "1.2.3.4", "attached_switch" : dpid, "attached_port" : portno}, In a datacenter, you might get this kind of information from a Cloud Management System. In our case, garnet's sync_hosts() sends us the list of Host entities in the "emulated" network garnet is managing. We receive it via the POX Messenger component and the messenger bot above. """ self.last_host_data = host_data for host in host_data: self.log.info("Got host: %s", " ".join("%s=%s" % kv for kv in sorted(host.items()))) host_e = str(host['ether']) switch_dpid = host['attached_switch'] switch_port = host['attached_port'] switch_name = self.graph.names[switch_dpid] self.hosts[host_e] = switch_dpid self.edge[switch_dpid] = switch_port if host_e in self.graph: self.graph.remove_node(host_e) # alter table info on attached switch # add host to networkX graph attached_switch = self.graph.names[switch_dpid] self.graph.add_edge(host_e, attached_switch) self.graph.add_edge(attached_switch, host_e) port_dict = {'ports': {attached_switch: switch_port}} self.graph.edge[host_e][attached_switch] = port_dict self.graph.edge[attached_switch][host_e] = port_dict core.openflow.sendToDPID(switch_dpid, nx_flow_mod_table_id()) # Enables multiple tables data = [] # construct command to remove VLAN and output to host fm = ofp_flow_mod_table_id( table_id = 0, match = of01.ofp_match(dl_dst=EthAddr(host_e)), command = of01.OFPFC_MODIFY, actions = [ofp_action_strip_vlan(), ofp_action_output(port=switch_port)]) data.append(fm.pack()) for dst_host, dst_switch_dpid in self.hosts.items(): if dst_host == host_e: continue if not self._connection_is_permitted(host_e, dst_host): # If we're not allowed to send to this host (or this host is not allowed to receive), tell our switch # to drop all traffic going to this host. self.log.info("MatchedDenyACE: src=%s dst=%s" % host_e, dst_host) fm = ofp_flow_mod_table_id( table_id = 0, command = of01.OFPFC_MODIFY, match = of01.ofp_match(dl_src=EthAddr(host_e), dl_dst=EthAddr(dst_host)), actions = None) data.append(fm.pack()) continue dst_switch_name = self.graph.names[dst_switch_dpid] #self.log.info(switch_name + ' ' + dst_switch_name) if switch_name == dst_switch_name: continue try: next_hop = nx.shortest_path(self.graph, source=switch_name, target=dst_switch_name)[1] except: continue shortest_path_port = self.graph[switch_name][next_hop]['ports'][switch_name] #self.log.info(str(host_e) + ' ' + str(dst_host)) #self.log.info(str(dst_switch_dpid) + ' ' + str(shortest_path_port)) # inform attached switch where other hosts are fm = ofp_flow_mod_table_id( table_id = 0, command = of01.OFPFC_MODIFY, match = of01.ofp_match(dl_src=EthAddr(host_e), dl_dst=EthAddr(dst_host)), actions = [ofp_action_set_vlan_vid(vlan_vid=dst_switch_dpid), ofp_action_output(port=shortest_path_port)]) data.append(fm.pack()) core.openflow.sendToDPID(dst_switch_dpid, nx_flow_mod_table_id()) # Enables multiple tables try: next_hop = nx.shortest_path(self.graph, source=dst_switch_name, target=switch_name)[1] except: continue shortest_path_port = self.graph[dst_switch_name][next_hop]['ports'][dst_switch_name] # inform other attached switches where this host is fm = ofp_flow_mod_table_id( table_id = 0, command = of01.OFPFC_MODIFY, match = of01.ofp_match(dl_src=EthAddr(dst_host), dl_dst=EthAddr(host_e)), actions = [ofp_action_set_vlan_vid(vlan_vid=switch_dpid), ofp_action_output(port=shortest_path_port)]) core.openflow.sendToDPID(dst_switch_dpid, fm.pack()) core.openflow.sendToDPID(switch_dpid, b''.join(data)) self.broadcast_paths()
def _handle_PacketIn(self, event): packet = event.parsed def getVlan(port, id_): res = None if (id_ != None): res = id_ else: tabla = importData() for i in tabla: for j in i.get('ports'): if (j.get('port') == port): res = i.get('vlan') return res def tagType(portname, vlanname): tabla = importData() for i in tabla: if i.get('vlan') == str(vlanname): for j in i.get('ports'): if (j.get('port') == str(portname)): ttype = j.get('type') return ttype def flood(message=None): srcPort = str(event.port) if (packet.find('vlan') is not None): vlanId = getVlan(srcPort, packet.find('vlan').id) else: vlanId = getVlan(srcPort, None) put = True for i in self.macToPort: if ((i.get('mac') == packet.src) and (i.get('port') == int(srcPort)) and (i.get('vlan') == vlanId)): put = False if (put): self.macToPort.append({ 'mac': packet.src, 'port': int(srcPort), 'vlan': vlanId }) taggedPorts = [] untaggedPorts = [] tabla = importData() for i in tabla: if i.get('vlan') == str(vlanId): for j in i.get('ports'): if (j.get('port') != srcPort and j.get('type') == "tagged"): taggedPorts.append(j.get('port')) if (j.get('port') != srcPort and j.get('type') == "untagged"): untaggedPorts.append(j.get('port')) tag = tagType(srcPort, vlanId) msg = of.ofp_flow_mod() msg.match.in_port = int(srcPort) # Tagged if tag == "tagged": # print ("FLOOD from T-port {0}").format(srcPort) # T a T for i in taggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # T a U if untaggedPorts != []: msg.actions.append(of.ofp_action_strip_vlan()) for i in untaggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # Untagged if tag == "untagged": # print ("FLOOD from U-port {0}").format(srcPort) # U a U for i in untaggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # U a T if taggedPorts != []: msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(vlanId))) for i in taggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) self.connection.send(msg) return 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) 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: vlan = None if (packet.find('vlan') is not None): vlan = packet.find('vlan').id else: vlan = None found = False if vlan != None: for i in self.macToPort: if (i.get('mac') == packet.dst and i.get('vlan') == vlan): port = int(i.get('port')) found = True if vlan == None: tabla = importData() for j in tabla: for k in j.get('ports'): if (str(event.port) == str(k.get('port')) and k.get('type') == "untagged"): # port = k.get('port') vlan = j.get('vlan') if (vlan != None): for i in self.macToPort: if (str(i.get('mac')) == str(packet.dst) and str(i.get('vlan')) == str(vlan)): port = i.get('port') found = True if not found: # 4 flood("Port for %s unknown -- flooding" % (packet.dst, )) # 4a else: vlanId = vlan put = True for i in self.macToPort: if ((i.get('mac') == packet.src) and (i.get('port') == int(event.port)) and (i.get('vlan') == vlanId)): put = False if (put): self.macToPort.append({ 'mac': packet.src, 'port': int(event.port), 'vlan': vlanId }) if port == event.port: # 5 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 tag1 = tagType(str(event.port), str(vlanId)) tag2 = tagType(str(port), str(vlanId)) msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet, event.port) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.data = event.ofp # 6a # Tagged if tag1 == "tagged": if tag2 == "tagged": msg.actions.append( of.ofp_action_output(port=int(port))) if tag2 == "untagged": msg.actions.append(of.ofp_action_strip_vlan()) msg.actions.append( of.ofp_action_output(port=int(port))) # Untagged if tag1 == "untagged": if tag2 == "untagged": msg.actions.append( of.ofp_action_output(port=int(port))) if tag2 == "tagged": msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(vlanId))) msg.actions.append( of.ofp_action_output(port=int(port))) self.connection.send(msg) return
def install_flow(self,pred,action_list): switch = pred['switch'] ### BUILD OF MATCH inport = pred['inport'] match = of.ofp_match() match.in_port = pred['inport'] match.dl_src = pred['srcmac'] match.dl_dst = pred['dstmac'] match.dl_type = pred['ethtype'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] else: match.dl_vlan = 0xffff if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] else: match.dl_vlan_pcp = 0 match.nw_proto = pred['protocol'] if 'srcip' in pred: match.nw_src = pred['srcip'] if 'dstip' in pred: match.nw_dst = pred['dstip'] if 'tos' in pred: match.nw_tos = pred['tos'] if 'srcport' in pred: match.tp_src = pred['srcport'] if 'dstport' in pred: match.tp_dst = pred['dstport'] ### BUILD OF ACTIONS of_actions = [] for actions in action_list: outport = actions['outport'] del actions['outport'] if 'srcmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError("vlan_id and vlan_pcp must be set together!") pass else: of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) if outport == inport: of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) else: of_actions.append(of.ofp_action_output(port=outport)) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=match, actions=of_actions) try: self.switches[switch]['connection'].send(msg) except RuntimeError, e: print "ERROR:install_flow: %s to switch %d" % (str(e),switch)
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 flood(message=None): srcPort = str(event.port) if (packet.find('vlan') is not None): vlanId = getVlan(srcPort, packet.find('vlan').id) else: vlanId = getVlan(srcPort, None) put = True for i in self.macToPort: if ((i.get('mac') == packet.src) and (i.get('port') == int(srcPort)) and (i.get('vlan') == vlanId)): put = False if (put): self.macToPort.append({ 'mac': packet.src, 'port': int(srcPort), 'vlan': vlanId }) taggedPorts = [] untaggedPorts = [] tabla = importData() for i in tabla: if i.get('vlan') == str(vlanId): for j in i.get('ports'): if (j.get('port') != srcPort and j.get('type') == "tagged"): taggedPorts.append(j.get('port')) if (j.get('port') != srcPort and j.get('type') == "untagged"): untaggedPorts.append(j.get('port')) tag = tagType(srcPort, vlanId) msg = of.ofp_flow_mod() msg.match.in_port = int(srcPort) # Tagged if tag == "tagged": # print ("FLOOD from T-port {0}").format(srcPort) # T a T for i in taggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # T a U if untaggedPorts != []: msg.actions.append(of.ofp_action_strip_vlan()) for i in untaggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # Untagged if tag == "untagged": # print ("FLOOD from U-port {0}").format(srcPort) # U a U for i in untaggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) # U a T if taggedPorts != []: msg.actions.append( of.ofp_action_vlan_vid(vlan_vid=int(vlanId))) for i in taggedPorts: msg.actions.append(of.ofp_action_output(port=int(i))) self.connection.send(msg) return
def install_flow(self, pred, action_list): switch = pred['switch'] ### BUILD OF MATCH inport = pred['inport'] match = of.ofp_match() match.in_port = pred['inport'] match.dl_src = pred['srcmac'] match.dl_dst = pred['dstmac'] match.dl_type = pred['ethtype'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] else: match.dl_vlan = 0xffff if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] else: match.dl_vlan_pcp = 0 match.nw_proto = pred['protocol'] if 'srcip' in pred: match.nw_src = pred['srcip'] if 'dstip' in pred: match.nw_dst = pred['dstip'] if 'tos' in pred: match.nw_tos = pred['tos'] if 'srcport' in pred: match.tp_src = pred['srcport'] if 'dstport' in pred: match.tp_dst = pred['dstport'] ### BUILD OF ACTIONS of_actions = [] for actions in action_list: outport = actions['outport'] del actions['outport'] if 'srcmac' in actions: of_actions.append( of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append( of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append( of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append( of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append( of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError( "vlan_id and vlan_pcp must be set together!") pass else: of_actions.append( of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) if outport == inport: of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) else: of_actions.append(of.ofp_action_output(port=outport)) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=match, actions=of_actions) try: self.switches[switch]['connection'].send(msg) except RuntimeError, e: print "ERROR:install_flow: %s to switch %d" % (str(e), switch)
def act_like_switch (self, packet, packet_in): """ Implement switch-like behavior. """ # Here's some psuedocode to start you off implementing a learning # switch. You'll need to rewrite it as real Python code. log.debug("DPID: %s" % self.connection.dpid) # Learn source vlan of the packet if packet.type == ethernet.VLAN_TYPE: src_vlan = packet.find('vlan').id else: src_vlan = self.vlan_to_port[packet_in.in_port] log.debug("Source VLAN: %s" % src_vlan) # Learn the port for the source MAC self.mac_to_port[packet.src] = packet_in.in_port # add or update mac table entry # Ports to send out the packet out_ports = [] #if the port associated with the destination MAC of the packet is known if packet.dst in self.mac_to_port: log.debug("Mac is in table") dst_vlan = self.vlan_to_port[self.mac_to_port[packet.dst]] #if the port is in the same vlan as sending port if src_vlan == dst_vlan or dst_vlan == 1: # Send packet out the associated port out_ports.append(self.mac_to_port[packet.dst]) self.resend_packet(packet_in, out_ports) log.debug("Installing flow. Source port: %s. Destination port: %s.", packet_in.in_port, self.mac_to_port[packet.dst]) # Install the flow table entry msg = of.ofp_flow_mod() ## Set fields to match received packet msg.match = of.ofp_match(dl_dst = packet.dst) #< Set other fields of flow_mod (timeouts? buffer_id?) > msg.idle_timeout = 60 # Add action to add vlan tag or strip it if dst_vlan == 1: action = of.ofp_action_vlan_vid(vlan_vid = src_vlan) else: action = of.ofp_action_strip_vlan() msg.actions.append(action) # Add action to resend packet out of the specified port msg.actions.append(of.ofp_action_output(port = self.mac_to_port[packet.dst])) self.connection.send(msg) else: # Sending to all ports in same vlan as the input port or dot1q port, ignore port connected to controller log.debug("Adress is not in table, flooding: ") for port in self.connection.ports: if port != packet_in.in_port and (self.vlan_to_port[port] == src_vlan or self.vlan_to_port[port] == 1): out_ports.append(port) log.debug(out_ports) if len(out_ports) > 0: self.resend_packet(packet_in, out_ports)
def _install_hybrid_static_flows(self): t = self.t hosts = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_HOST))) edge_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_EDGE))) agg_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_AGG))) core_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_CORE))) # For each host, add entries to that host, from each core switch. sep() #log.info("***adding down entries from each core switch") for host in hosts: host_name = self.t.id_gen(dpid=host).name_str() log.info("for host %i (%s)" % (host, host_name)) for core_sw in core_sws: core_sw_name = self.t.id_gen(dpid=core_sw).name_str() log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) route = self.r.get_route(host_name, core_sw_name, None) assert route[0] == host_name assert route[-1] == core_sw_name # Form OF match match = of.ofp_match() # Highest-order four bits are host index host_id = self.t.id_gen(dpid=host) k = self.t.k host_index = host_id.pod * k + (host_id.sw * k / 2) + (host_id.host - 2) # Lowest-order two bits are core switch ID core_sw_id = self.t.id_gen(dpid=core_sw) log.info("core_sw_id: %s; sw: %i host: %i" % (core_sw, core_sw_id.sw, core_sw_id.host)) core_index = ((core_sw_id.sw - 1) * 2) + (core_sw_id.host - 1) vlan = (host_index << 2) + core_index #log.info("setting vlan to %i" % vlan) match.dl_vlan = vlan #log.info("vlan: %s" % match.dl_vlan) # Add one flow entry for each element on the path pointing down, except host for i, node in enumerate(route): # names if i == 0: pass # Don't install flow entries on hosts :-) else: # Install downward-facing entry node_dpid = self.t.id_gen(name=node).dpid node_below = route[i - 1] src_port, dst_port = self.t.port(node, node_below) log.info( "adding entry from %s to %s via VLAN %i and port %i" % (node, node_below, match.dl_vlan, src_port)) if i == 1: # Strip VLAN too actions = [ of.ofp_action_strip_vlan(), of.ofp_action_output(port=src_port) ] self.switches[node_dpid].install_multiple( actions, match, priority=PRIO_HYBRID_VLAN_DOWN) elif i > 1: self.switches[node_dpid].install( src_port, match, priority=PRIO_HYBRID_VLAN_DOWN) # # Add one flow entry for each edge switch pointing up # sep() # log.info("***adding up entries from each edge switch") # for edge_sw in edge_sws: # DPIDs # edge_sw_name = self.t.id_gen(dpid = edge_sw).name_str() # log.info("for edge sw %i (%s)" % (edge_sw, edge_sw_name)) # for core_sw in core_sws: # DPIDs # core_sw_name = self.t.id_gen(dpid = core_sw).name_str() # log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) # # route = self.r.get_route(edge_sw_name, core_sw_name, None) # assert route[0] == edge_sw_name # assert route[-1] == core_sw_name # # # Form OF match # match = of.ofp_match() # # Highest-order four bits are host index # # # Lowest-order two bits are core switch ID # core_sw_id = self.t.id_gen(dpid = core_sw) # core_index = (core_sw_id.sw - 1) * 2 + (core_sw_id.host - 1) # # agg_sw_name = route[1] # agg_sw = self.t.id_gen(name = agg_sw_name).dpid # # for host_index in range((self.t.k ** 3) / 4): # match.dl_vlan = (host_index << 2) + core_index # #log.info("vlan: %s" % match.dl_vlan) # # edge_port, agg_port = self.t.port(edge_sw_name, agg_sw_name) # log.info("adding entry from %s to %s via VLAN %i and port %i" % # (edge_sw_name, agg_sw_name, match.dl_vlan, edge_port)) # self.switches[edge_sw].install(edge_port, match, # priority = PRIO_HYBRID_VLAN_UP) # Add one flow entry for each agg switch pointing up sep() log.info("***adding up entries from each agg switch") for agg_sw in agg_sws: # DPIDs agg_sw_name = self.t.id_gen(dpid=agg_sw).name_str() log.info("for agg sw %i (%s)" % (agg_sw, agg_sw_name)) for core_sw in core_sws: # DPIDs core_sw_name = self.t.id_gen(dpid=core_sw).name_str() log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) if agg_sw_name in self.t.g[core_sw_name]: # If connected, add entry. agg_port, core_port = self.t.port(agg_sw_name, core_sw_name) # Form OF match match = of.ofp_match() # Highest-order four bits are host index # Lowest-order two bits are core switch ID core_sw_id = self.t.id_gen(dpid=core_sw) core_index = (core_sw_id.sw - 1) * 2 + (core_sw_id.host - 1) for host_index in range((self.t.k**3) / 4): match.dl_vlan = (host_index << 2) + core_index #log.info("vlan: %s" % match.dl_vlan) log.info( "adding entry from %s to %s via VLAN %i and port %i" % (agg_sw_name, core_sw_name, match.dl_vlan, agg_port)) self.switches[agg_sw].install( agg_port, match, priority=PRIO_HYBRID_VLAN_UP)
def _modify_flow(self, command_type): msg = of.ofp_flow_mod() print self.payload if command_type == "MOD_ST": msg.command = of.OFPFC_MODIFY_STRICT elif command_type == "MOD": msg.command = of.OFPFC_MODIFY if self.payload.has_key("wildcards"): msg.match.wildcards = int(self.payload['wildcards']) if self.payload.has_key("dstIP"): msg.match.nw_dst = IPAddr(self.payload['dstIP']) if self.payload.has_key("srcMac"): msg.match.dl_src = EthAddr(self.payload['srcMac']) if self.payload.has_key("srcIP"): msg.match.nw_src = IPAddr(self.payload['srcIP']) if self.payload.has_key("dstMac"): msg.match.dl_dst = EthAddr(self.payload['dstMac']) if self.payload.has_key("hardTimeout"): msg.hard_timeout = int(self.payload['hardTimeout']) if self.payload.has_key("srcPort"): msg.match.tp_src = int(self.payload['srcPort']) if self.payload.has_key("priority"): msg.priority = int(self.payload['priority']) if self.payload.has_key("ingressPort"): msg.match.in_port = int(self.payload['ingressPort']) if self.payload.has_key("vlan"): msg.match.dl_vlan = int(self.payload['vlan']) if self.payload.has_key("ether-type"): msg.match.dl_type = int(self.payload['ether-type']) if self.payload.has_key("duration"): msg.duration_sec = int(self.payload['duration']) if self.payload.has_key("idleTimeout"): msg.idle_timeout = int(self.payload['idleTimeout']) if self.payload.has_key("netProtocol"): msg.match.nw_proto = int(self.payload['netProtocol']) self.dpid = self.payload['switch'].replace(':', '-')[6:] self._parse_actions(self.payload['actions']) for connection in core.openflow._connections.values(): # print dpidToStr(connection.dpid) conn_dpid = str(dpidToStr(connection.dpid)) print conn_dpid if conn_dpid == self.dpid: """match actions""" if (self.actions == "OUTPUT"): msg.actions.append( of.ofp_action_output(port=int(self.actions_argu))) elif (self.actions == "enqueue"): port = self.actions_argu.split(':')[0] queue_id = self.actions_argu.split(':')[1] msg.actions.append( of.ofp_action_enqueue(port=int(port), queue_id=int(queue_id))) elif (self.actions == "strip-vlan"): msg.actions.append(of.ofp_action_strip_vlan()) elif (self.actions == "set-vlan-id"): msg.actions.append( of.ofp_action_vlan_vid( vlan_vid=int(self.actions_argu))) elif (self.actions == "set-vlan-priority"): msg.actions.append( of.ofp_action_vlan_pcp( vlan_pcp=int(self.actions_argu))) elif (self.actions == "SET_DL_SRC"): msg.actions.append( of.ofp_action_dl_addr(type=4, dl_addr=EthAddr( self.actions_argu))) elif (self.actions == "SET_DL_DST"): msg.actions.append( of.ofp_action_dl_addr(type=5, dl_addr=EthAddr( self.actions_argu))) elif (self.actions == "SET_NW_TOS"): msg.actions.append( of.ofp_action_nw_tos(nw_tos=int(self.actions_argu))) elif (self.actions == "SET_NW_SRC"): msg.actions.append( of.ofp_action_nw_addr(type=6, nw_addr=IPAddr( self.actions_argu))) elif (self.actions == "SET_NW_DST"): msg.actions.append( of.ofp_action_nw_addr(type=7, nw_addr=IPAddr( self.actions_argu))) elif (self.actions == "SET_TP_SRC"): msg.actions.append( of.ofp_action_tp_port(type=9, tp_port=int(self.actions_argu))) elif (self.actions == "SET_TP_DST"): msg.actions.append( of.ofp_action_tp_port(type=10, tp_port=int(self.actions_argu))) connection.send(msg)
def _handle_PacketIn(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 build_nx_actions(self,inport,action_list,table_id,pipeline): ### BUILD NX ACTIONS of_actions = [] ctlr_outport = False # there is a controller outport action phys_outports = list() # list of physical outports to forward out of possibly_resubmit_next_table = False # should packet be passed on to next table? atleast_one_action = False for actions in action_list: atleast_one_action = True if 'srcmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac'])) if 'dstmac' in actions: of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac'])) if 'srcip' in actions: of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip'])) if 'dstip' in actions: of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip'])) if 'srcport' in actions: of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport'])) if 'dstport' in actions: of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(of.ofp_action_strip_vlan()) else: of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id'])) if 'vlan_pcp' in actions: if actions['vlan_pcp'] is None: if not actions['vlan_id'] is None: raise RuntimeError("vlan_id and vlan_pcp must be set together!") pass else: of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp'])) assert 'port' in actions outport = actions['port'] if outport == of.OFPP_CONTROLLER: ctlr_outport = True else: """ There is either a physical output action (i.e., on a non-controller port), or a "send to next table" action.""" possibly_resubmit_next_table = True if outport != CUSTOM_NEXT_TABLE_PORT: phys_outports.append(outport) """ Otherwise there are no physical outports; just a possibility of resubmitting to the next table. Pass. """ """In general, actual packet forwarding may have to wait until the final table in the pipeline. This means we must determine if there is a "next" table that processes the packet from here, or if this is the last one. But first, the easy part. There are exactly three cases where a forwarding table *will* in fact "immediately forward" a packet according to the current rule (and all previous table stages that processed the packet), without waiting for any other further processing: (1) if the packet is dropped by the current rule, (2) if the packet is forwarded to the controller port, or (3) if this is the last stage of the pipeline. In the case of (1) and (2), packet forwarding may happen immediately and only depend on the current rule. But in (3), the forwarding decision must take the current rule as well as previous port changes into account, as follows: (a) if the current rule specifies an output port, forward the packet out of that port. (b) if the current rule does not specify an outport, then forward the packet out of the port using the value stored in the dedicated per-packet port register. If neither of (1)-(3) above is true, then we take the following approach: (a) if there is an outport set by this rule, write that value into the dedicated per-packet register that contains the current port the packet is in. (b) if there is no outport set by this rule, and if this is table id 0, move the value of the inport into the dedicated per-packet port register. This denotes that the packet is currently still on its inport. (c) resubmit the packet to the "next" table (according to the pipeline). """ exists_next_table = table_id in pipeline.edges # Decide first on "immediate forwarding" conditions: immediately_fwd = True if not atleast_one_action: # (1) drop of_actions = [] elif ctlr_outport: # (2) controller of_actions = [] of_actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) elif possibly_resubmit_next_table and (not exists_next_table): # (3) last stage of pipeline if len(phys_outports) > 0: # fwd out of latest assigned ports for p in phys_outports: of_actions.append(of.ofp_action_output(port=p)) else: # fwd out of stored port value of_actions.append(nx.nx_output_reg(reg=nx.NXM_NX_REG2, nbits=16)) elif (not exists_next_table) and (not possibly_resubmit_next_table): raise RuntimeError("Unexpected condition in multi-stage processing") else: # must resubmit packet to subsequent tables for processing immediately_fwd = False if immediately_fwd: return of_actions # Act on packet with knowledge that subsequent tables must process it assert (possibly_resubmit_next_table and exists_next_table and (not immediately_fwd)) next_table = pipeline.edges[table_id] if len(phys_outports) > 0: # move port register to latest assigned port values for p in phys_outports: of_actions.append(nx.nx_reg_load(dst=nx.NXM_NX_REG2, value=p, nbits=16)) of_actions.append(nx.nx_action_resubmit.resubmit_table( table=next_table)) elif table_id == 0: # move the inport value to reg2. of_actions.append(nx.nx_reg_move(src=nx.NXM_OF_IN_PORT, dst=nx.NXM_NX_REG2, nbits=16)) of_actions.append(nx.nx_action_resubmit.resubmit_table( table=next_table)) else: of_actions.append(nx.nx_action_resubmit.resubmit_table( table=next_table)) return of_actions
def _install_hybrid_static_flows(self): t = self.t hosts = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_HOST))) edge_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_EDGE))) agg_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_AGG))) core_sws = sorted(self._raw_dpids(t.layer_nodes(t.LAYER_CORE))) # For each host, add entries to that host, from each core switch. sep() #log.info("***adding down entries from each core switch") for host in hosts: host_name = self.t.id_gen(dpid = host).name_str() log.info("for host %i (%s)" % (host, host_name)) for core_sw in core_sws: core_sw_name = self.t.id_gen(dpid = core_sw).name_str() log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) route = self.r.get_route(host_name, core_sw_name, None, False) assert route[0] == host_name assert route[-1] == core_sw_name # Form OF match match = of.ofp_match() # Highest-order four bits are host index host_id = self.t.id_gen(dpid = host) k = self.t.k host_index = host_id.pod * k + (host_id.sw * k / 2) + (host_id.host - 2) # Lowest-order two bits are core switch ID core_sw_id = self.t.id_gen(dpid = core_sw) log.info("core_sw_id: %s; sw: %i host: %i" % (core_sw, core_sw_id.sw, core_sw_id.host)) core_index = ((core_sw_id.sw - 1) * 2) + (core_sw_id.host - 1) vlan = (host_index << 2) + core_index #log.info("setting vlan to %i" % vlan) match.dl_vlan = vlan #log.info("vlan: %s" % match.dl_vlan) # Add one flow entry for each element on the path pointing down, except host for i, node in enumerate(route): # names if i == 0: pass # Don't install flow entries on hosts :-) else: # Install downward-facing entry node_dpid = self.t.id_gen(name = node).dpid node_below = route[i - 1] src_port, dst_port = self.t.port(node, node_below) log.info("adding entry from %s to %s via VLAN %i and port %i" % (node, node_below, match.dl_vlan, src_port)) if i == 1: # Strip VLAN too actions = [of.ofp_action_strip_vlan(), of.ofp_action_output(port = src_port)] self.switches[node_dpid].install_multiple(actions, match, priority = PRIO_HYBRID_VLAN_DOWN) elif i > 1: self.switches[node_dpid].install(src_port, match, priority = PRIO_HYBRID_VLAN_DOWN) # # Add one flow entry for each edge switch pointing up # sep() # log.info("***adding up entries from each edge switch") # for edge_sw in edge_sws: # DPIDs # edge_sw_name = self.t.id_gen(dpid = edge_sw).name_str() # log.info("for edge sw %i (%s)" % (edge_sw, edge_sw_name)) # for core_sw in core_sws: # DPIDs # core_sw_name = self.t.id_gen(dpid = core_sw).name_str() # log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) # # route = self.r.get_route(edge_sw_name, core_sw_name, None) # assert route[0] == edge_sw_name # assert route[-1] == core_sw_name # # # Form OF match # match = of.ofp_match() # # Highest-order four bits are host index # # # Lowest-order two bits are core switch ID # core_sw_id = self.t.id_gen(dpid = core_sw) # core_index = (core_sw_id.sw - 1) * 2 + (core_sw_id.host - 1) # # agg_sw_name = route[1] # agg_sw = self.t.id_gen(name = agg_sw_name).dpid # # for host_index in range((self.t.k ** 3) / 4): # match.dl_vlan = (host_index << 2) + core_index # #log.info("vlan: %s" % match.dl_vlan) # # edge_port, agg_port = self.t.port(edge_sw_name, agg_sw_name) # log.info("adding entry from %s to %s via VLAN %i and port %i" % # (edge_sw_name, agg_sw_name, match.dl_vlan, edge_port)) # self.switches[edge_sw].install(edge_port, match, # priority = PRIO_HYBRID_VLAN_UP) # Add one flow entry for each agg switch pointing up sep() log.info("***adding up entries from each agg switch") for agg_sw in agg_sws: # DPIDs agg_sw_name = self.t.id_gen(dpid = agg_sw).name_str() log.info("for agg sw %i (%s)" % (agg_sw, agg_sw_name)) for core_sw in core_sws: # DPIDs core_sw_name = self.t.id_gen(dpid = core_sw).name_str() log.info("for core switch %i (%s)" % (core_sw, core_sw_name)) if agg_sw_name in self.t.g[core_sw_name]: # If connected, add entry. agg_port, core_port = self.t.port(agg_sw_name, core_sw_name) # Form OF match match = of.ofp_match() # Highest-order four bits are host index # Lowest-order two bits are core switch ID core_sw_id = self.t.id_gen(dpid = core_sw) core_index = (core_sw_id.sw - 1) * 2 + (core_sw_id.host - 1) for host_index in range((self.t.k ** 3) / 4): match.dl_vlan = (host_index << 2) + core_index #log.info("vlan: %s" % match.dl_vlan) log.info("adding entry from %s to %s via VLAN %i and port %i" % (agg_sw_name, core_sw_name, match.dl_vlan, agg_port)) self.switches[agg_sw].install(agg_port, match, priority = PRIO_HYBRID_VLAN_UP)
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)