def build_of_match(self,switch,inport,pred): ### BUILD OF MATCH if 'ethtype' in pred and pred['ethtype']==0x86dd: match = nx.nx_match() if inport: match.in_port = inport if 'ethtype' in pred: match.eth_type = pred['ethtype'] else: match = of.ofp_match() match.in_port = inport if 'ethtype' in pred: match.dl_type = pred['ethtype'] if 'srcmac' in pred: match.dl_src = pred['srcmac'] if 'dstmac' in pred: match.dl_dst = pred['dstmac'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] if 'protocol' in pred: match.nw_proto = pred['protocol'] if 'srcip' in pred: match.set_nw_src(pred['srcip']) if 'dstip' in pred: match.set_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'] return match
def flow_mod_action(self,pred,priority,action_list,cookie,command,notify): switch = pred['switch'] if 'inport' in pred: inport = pred['inport'] else: inport = None match = self.build_of_match(switch,inport,pred) of_actions = self.build_of_actions(inport,action_list) flags = 0 if notify: flags = of.OFPFF_SEND_FLOW_REM if 'ethtype' in pred and pred['ethtype']==0x86dd: msg = nx.nx_flow_mod(command=command, priority=priority, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=nx.nx_match(match), flags=flags, cookie=cookie, actions=of_actions) else: msg = of.ofp_flow_mod(command=command, priority=priority, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=match, flags=flags, cookie=cookie, actions=of_actions) try: self.switches[switch]['connection'].send(msg) except RuntimeError, e: print "WARNING:install_flow: %s to switch %d" % (str(e),switch)
def flow_mod_action(self, pred, priority, action_list, cookie, command, notify): switch = pred['switch'] if 'inport' in pred: inport = pred['inport'] else: inport = None match = self.build_of_match(switch, inport, pred) of_actions = self.build_of_actions(inport, action_list) flags = 0 if notify: flags = of.OFPFF_SEND_FLOW_REM if 'ethtype' in pred and pred['ethtype'] == 0x86dd: msg = nx.nx_flow_mod(command=command, priority=priority, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=nx.nx_match(match), flags=flags, cookie=cookie, actions=of_actions) else: msg = of.ofp_flow_mod(command=command, priority=priority, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=match, flags=flags, cookie=cookie, actions=of_actions) try: self.switches[switch]['connection'].send(msg) except RuntimeError, e: print "WARNING:install_flow: %s to switch %d" % (str(e), switch)
def build_nx_match(self,switch,inport,pred,table_id): ### BUILD NX MATCH match = nx.nx_match() if inport: if table_id == 0: match.of_in_port = inport else: """NXM_NX_REG2 is the per-packet metadata register where we store the current port value of the packet, including actions from previous tables' forwarding actions. """ match.reg2 = inport if 'srcmac' in pred: match.of_eth_src = packetaddr.EthAddr(pred['srcmac']) if 'dstmac' in pred: match.of_eth_dst = packetaddr.EthAddr(pred['dstmac']) if 'vlan_id' in pred: assert 'vlan_pcp' in pred # Setting the 16-bit TCI: (from highest to least significant bits): # 3 bits vlan_pcp # 1 bit CFI forced to 1 # 12 bits vlan_id # Ref: manpages.ubuntu.com/manpages/trusty/man8/ovs-ofctl.8.html vlan_16bit = ((int(pred['vlan_pcp']) << 13) | 0x1000 | (int(pred['vlan_id']))) match.of_vlan_tci = vlan_16bit if 'ethtype' in pred: match.of_eth_type = pred['ethtype'] if 'srcip' in pred: assert 'ethtype' in pred if pred['ethtype'] == IP_TYPE: match.of_ip_src = packetaddr.IPAddr(pred['srcip']) elif pred['ethtype'] == ARP_TYPE: match.arp_spa = packetaddr.IPAddr(pred['srcip']) else: raise RuntimeError("Unknown ethtype for srcip match!") if 'dstip' in pred: assert 'ethtype' in pred if pred['ethtype'] == IP_TYPE: match.of_ip_dst = packetaddr.IPAddr(pred['dstip']) elif pred['ethtype'] == ARP_TYPE: match.arp_tpa = packetaddr.IPAddr(pred['dstip']) else: raise RuntimeError("Unknown ethtype for dstip match!") if 'tos' in pred: match.of_ip_tos = pred['tos'] if 'protocol' in pred: match.of_ip_proto = pred['protocol'] if 'srcport' in pred: assert 'protocol' in pred match.append(nx.NXM_OF_TCP_SRC(pred['srcport'])) if 'dstport' in pred: assert 'protocol' in pred match.append(nx.NXM_OF_TCP_DST(pred['dstport'])) return match
def flow_mod_action(self,pred,priority,action_list,cookie,command,notify,table_id): switch = pred['switch'] """ Set `inport` from matching predicate """ if 'port' in pred: inport = pred['port'] else: inport = None if self.use_nx: match = self.build_nx_match(switch,inport,pred,table_id) else: match = self.build_of_match(switch,inport,pred) if self.use_nx: debug = False # use for debugging specific rules in build_nx_actions of_actions = self.build_nx_actions(inport, action_list, table_id, self.pipeline, debug=debug) else: debug = False # use for debugging specific rules in build_of_actions of_actions = self.build_of_actions(inport, action_list, debug=debug) flags = 0 if notify: flags = of.OFPFF_SEND_FLOW_REM if 'ethtype' in pred and pred['ethtype']==0x86dd: msg = nx.nx_flow_mod(command=command, priority=priority, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=nx.nx_match(match), flags=flags, cookie=cookie, actions=of_actions) elif self.use_nx: msg = nx.nx_flow_mod(command=command, priority=priority, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=match, flags=flags, cookie=cookie, actions=of_actions, table_id=table_id) else: msg = of.ofp_flow_mod(command=command, priority=priority, idle_timeout=of.OFP_FLOW_PERMANENT, hard_timeout=of.OFP_FLOW_PERMANENT, match=match, flags=flags, cookie=cookie, actions=of_actions) try: self.switches[switch]['connection'].send(msg) except RuntimeError, e: print "WARNING:install_flow: %s to switch %d" % (str(e),switch)
def install_icmp_entry(event, psrc): # first add entries for ICMP # Add to destination table. This is now table 0 msg = nx.nx_flow_mod() msg.match = nx.nx_match() # pld: see pox dox "Using nx_match" msg.table_id = 0 msg.match.append(nx.NXM_OF_ETH_DST(psrc)) msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.IP_TYPE)) msg.match.append(nx.NXM_OF_IP_PROTO(pkt.ipv4.ICMP_PROTOCOL)) msg.actions.append(of.ofp_action_output(port=event.port)) msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1)) event.connection.send(msg) # Now add to source table. This is now table 1 msg = nx.nx_flow_mod() msg.match = nx.nx_match() # pld: see pox dox "Using nx_match" msg.table_id = 1 msg.match.append(nx.NXM_OF_ETH_SRC(psrc)) msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.IP_TYPE)) msg.match.append(nx.NXM_OF_IP_PROTO(pkt.ipv4.ICMP_PROTOCOL)) # empty action list here, meaning no longer send to the controller event.connection.send(msg) # now add similar entries for ARP msg = nx.nx_flow_mod() msg.match = nx.nx_match() # pld: see pox dox "Using nx_match" msg.table_id = 0 msg.match.append(nx.NXM_OF_ETH_DST(psrc)) msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.ARP_TYPE)) msg.actions.append(of.ofp_action_output(port=event.port)) msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1)) event.connection.send(msg) msg = nx.nx_flow_mod() msg.match = nx.nx_match() # pld: see pox dox "Using nx_match" msg.table_id = 1 msg.match.append(nx.NXM_OF_ETH_SRC(psrc)) msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.ARP_TYPE)) # again an empty action list event.connection.send(msg)
def modify_flow_table(self, **kwargs): """ The method will modify flow tables of the openflow switch as per arguments. It takes variable number of named arguments, these names must match with the names defined in static dictionaries of this class. """ match = nx_match() flowmod = nx_flow_mod() prelen = len(kwargs) + 1 while(len(kwargs) < prelen): prelen = len(kwargs) prekey = None for key in kwargs.keys(): value = kwargs[key] if(prekey != None): kwargs.pop(prekey) prekey = None try: if(self.match_attributes.has_key(key)): record = self.match_attributes[key] if((record[0] == None) or self._verify_attributes(match, record[0], record[1])): if(record[2] and (type(value) is str) and (value.find("/") != -1)): fields = value.split("/") match.__setattr__(key, record[-1](fields[0])) match.__setattr__(key + "_mask", record[-1](fields[1])) else: match.__setattr__(key, value) prekey = key elif(self.flowmod_attributes.has_key(key)): flowmod.__setattr__(key, value) prekey = key elif(self.action_attributes.has_key(key)): record = self.action_attributes[key] if(record[1]): flowmod.actions.append(record[0](**value)) else: flowmod.actions.append(record[0]()) prekey = key except Exception as e: return if(len(kwargs) == prelen): break flowmod.match = match print flowmod
def __nx_switch_pipeline_init(self, dpid, p): """ Initialize switch `dpid` according to the input pipeline configuration `p`. """ """ Clear all tables; install default actions. """ for t in range(0, p.num_tables): msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id=t) self.switches[dpid]['connection'].send(msg) msg = nx.nx_flow_mod() msg.table_id = t msg.priority = 1 msg.match = nx.nx_match() if (t+1) < p.num_tables and t in p.edges: """ If not last table in the pipeline, fallthrough to next. """ dst_t = p.edges[t] msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=dst_t)) else: """ If last table in pipeline, or no further edges, send to controller. """ msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER)) self.switches[dpid]['connection'].send(msg)
def addTCPrule(switch, flow, port): assert (port in switch.hmap) or (port in switch.nmap), "{}: unknown port {}".format( switch, port) psrc = flow.ethsrc pdst = flow.ethdst msg = nx.nx_flow_mod() msg.match = nx.nx_match() # pld: see pox dox "Using nx_match" msg.table_id = 0 msg.idle_timeout = TCP_IDLE_TIMEOUT msg.match.append(nx.NXM_OF_ETH_SRC(flow.ethsrc)) msg.match.append(nx.NXM_OF_ETH_DST(flow.ethdst)) msg.match.append(nx.NXM_OF_ETH_TYPE(pkt.ethernet.IP_TYPE)) msg.match.append(nx.NXM_OF_IP_PROTO(pkt.ipv4.TCP_PROTOCOL)) msg.match.append(nx.NXM_OF_IP_SRC(flow.srcip)) msg.match.append(nx.NXM_OF_IP_DST(flow.dstip)) msg.match.append(nx.NXM_OF_TCP_SRC(flow.srcport)) msg.match.append(nx.NXM_OF_TCP_DST(flow.dstport)) msg.actions.append(of.ofp_action_output(port=port)) switch.connection().send(msg)
def build_of_match(self,switch,inport,pred): ### BUILD OF MATCH if 'ethtype' in pred and pred['ethtype']==0x86dd: match = nx.nx_match() if inport: match.in_port = inport if 'ethtype' in pred: match.eth_type = pred['ethtype'] else: match = of.ofp_match() match.in_port = inport if 'ethtype' in pred: match.dl_type = pred['ethtype'] if 'srcmac' in pred: match.dl_src = pred['srcmac'] if 'dstmac' in pred: match.dl_dst = pred['dstmac'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] # Checks to ensure correct use of VLANs with single-stage tables assert 'vlan_total_stages' in pred assert pred['vlan_total_stages'] == 1, ("Cannot use multi-stage " "virtual header fields without enabling the multistage (--nx) " "option.") if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] if 'protocol' in pred: match.nw_proto = pred['protocol'] if 'srcip' in pred: match.set_nw_src(pred['srcip']) if 'dstip' in pred: match.set_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'] return match
def build_of_match(self, switch, inport, pred): ### BUILD OF MATCH if 'ethtype' in pred and pred['ethtype'] == 0x86dd: match = nx.nx_match() if inport: match.in_port = inport if 'ethtype' in pred: match.eth_type = pred['ethtype'] if 'srcmac' in pred: match.eth_src = pred['srcmac'] if 'dstmac' in pred: match.eth_dst = pred['dstmac'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] if 'protocol' in pred: match.ip_proto = pred['protocol'] if 'srcip' in pred: match.ipv6_src = (pred['srcip']) if 'dstip' in pred: match.ipv6_dst = (pred['dstip']) if 'tos' in pred: match.ip_tos = pred['tos'] if 'nxt' in pred: match.nxt = pred['nxt'] if 'icmpv6_type' in pred: match.icmpv6_type = pred['icmpv6_type'] #Add udp_src and udp_dst cases in the future if 'srcport' in pred: match.tcp_src = pred['srcport'] if 'dstport' in pred: match.tcp_dst = pred['dstport'] else: match = of.ofp_match() match.in_port = inport if 'ethtype' in pred: match.dl_type = pred['ethtype'] if 'srcmac' in pred: match.dl_src = pred['srcmac'] if 'dstmac' in pred: match.dl_dst = pred['dstmac'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] if 'protocol' in pred: match.nw_proto = pred['protocol'] #nicira exception to prevent lldp error in ipv6 if 'srcip' in pred: try: match.set_nw_src(pred['srcip']) except: nx.nx_match.ipv6_src = (pred['srcip']) if 'dstip' in pred: try: match.set_nw_dst(pred['dstip']) except: nx.nx_match.ipv6_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'] return match
def build_nx_match(self,switch,inport,pred,table_id): ### BUILD NX MATCH match = nx.nx_match() if inport: if table_id == 0: match.of_in_port = inport else: """NXM_NX_REG2 is the per-packet metadata register where we store the current port value of the packet, including actions from previous tables' forwarding actions. """ match.reg2 = inport if 'srcmac' in pred: match.of_eth_src = packetaddr.EthAddr(pred['srcmac']) if 'dstmac' in pred: match.of_eth_dst = packetaddr.EthAddr(pred['dstmac']) if 'vlan_id' in pred: assert 'vlan_pcp' in pred assert 'vlan_offset' in pred and 'vlan_nbits' in pred assert 'vlan_total_stages' in pred # Setting the 16-bit TCI: (from highest to least significant bits): # 3 bits vlan_pcp # 1 bit CFI forced to 1 # 12 bits vlan_id # Ref: manpages.ubuntu.com/manpages/trusty/man8/ovs-ofctl.8.html if table_id == 0: match.dl_vlan = pred['vlan_id'] match.dl_vlan_pcp = pred['vlan_pcp'] else: """NXM_NX_REG3 is where we store the intermittent value of VLAN. The VLAN ID and PCP are loaded as one contiguous set of 15 bits in the register. See `vlan_load_reg()` for more details. Further, whenever the VLAN is matched, we also check whether the packet has a VLAN in the first place, by checking the VLAN CFI bit, which is now loaded in bit 15 in the register. """ vlan_16bit = ((int(pred['vlan_pcp']) << 12) | 0x8000 | (int(pred['vlan_id']))) vlan_mask = ((((1 << pred['vlan_nbits']) - 1) << pred['vlan_offset']) | 0x8000) # zero out the unmasked value bits # Ref: ~/pox/pox/openflow/nicira.py#L1817 vlan_value = vlan_16bit & vlan_mask match.append(nx.NXM_NX_REG3(value=vlan_value, mask=vlan_mask)) if 'ethtype' in pred: match.of_eth_type = pred['ethtype'] if 'srcip' in pred: assert 'ethtype' in pred if pred['ethtype'] == IP_TYPE: match.NXM_OF_IP_SRC = pred['srcip'] elif pred['ethtype'] == ARP_TYPE: match.arp_spa = packetaddr.IPAddr(pred['srcip']) else: raise RuntimeError("Unknown ethtype for srcip match!") if 'dstip' in pred: assert 'ethtype' in pred if pred['ethtype'] == IP_TYPE: match.NXM_OF_IP_DST = pred['dstip'] elif pred['ethtype'] == ARP_TYPE: match.arp_tpa = packetaddr.IPAddr(pred['dstip']) else: raise RuntimeError("Unknown ethtype for dstip match!") if 'tos' in pred: match.of_ip_tos = pred['tos'] if 'protocol' in pred: match.of_ip_proto = pred['protocol'] if 'srcport' in pred: assert 'protocol' in pred match.append(nx.NXM_OF_TCP_SRC(pred['srcport'])) if 'dstport' in pred: assert 'protocol' in pred match.append(nx.NXM_OF_TCP_DST(pred['dstport'])) return match
def build_of_match(self,switch,inport,pred): ### BUILD OF MATCH if 'ethtype' in pred and pred['ethtype']==0x86dd: match = nx.nx_match() if inport: match.in_port = inport if 'ethtype' in pred: match.eth_type = pred['ethtype'] if 'srcmac' in pred: match.eth_src = pred['srcmac'] if 'dstmac' in pred: match.eth_dst = pred['dstmac'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] if 'protocol' in pred: match.ip_proto = pred['protocol'] if 'srcip' in pred: match.ipv6_src = (pred['srcip']) if 'dstip' in pred: match.ipv6_dst = (pred['dstip']) if 'tos' in pred: match.ip_tos = pred['tos'] if 'nxt' in pred: match.nxt = pred['nxt'] if 'icmpv6_type' in pred: match.icmpv6_type = pred['icmpv6_type'] #Add udp_src and udp_dst cases in the future if 'srcport' in pred: match.tcp_src = pred['srcport'] if 'dstport' in pred: match.tcp_dst = pred['dstport'] else: match = of.ofp_match() match.in_port = inport if 'ethtype' in pred: match.dl_type = pred['ethtype'] if 'srcmac' in pred: match.dl_src = pred['srcmac'] if 'dstmac' in pred: match.dl_dst = pred['dstmac'] if 'vlan_id' in pred: match.dl_vlan = pred['vlan_id'] if 'vlan_pcp' in pred: match.dl_vlan_pcp = pred['vlan_pcp'] if 'protocol' in pred: match.nw_proto = pred['protocol'] #nicira exception to prevent lldp error in ipv6 if 'srcip' in pred: try: match.set_nw_src(pred['srcip']) except: nx.nx_match.ipv6_src = (pred['srcip']) if 'dstip' in pred: try: match.set_nw_dst(pred['dstip']) except: nx.nx_match.ipv6_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'] return match