def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) LOG.info("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = msg.in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: self.add_flow(datapath, msg.in_port, dst, actions) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out)
def match_eth_to_str(value, mask): eth_str = mac.haddr_to_str(value) if mask is not None: eth_str = eth_str + '/' + mac.haddr_to_str(mask) return eth_str
def _forward_to_nw_id(self, msg, src, dst, nw_id, out_port): assert out_port is not None datapath = msg.datapath if not self.nw.same_network(datapath.id, nw_id, out_port, NW_ID_EXTERNAL): self.logger.debug( "packet is blocked src %s dst %s " "from %d to %d on datapath %d", haddr_to_str(src), haddr_to_str(dst), msg.in_port, out_port, datapath.id, ) return self.logger.debug( "learned dpid %s in_port %d out_port " "%d src %s dst %s", datapath.id, msg.in_port, out_port, haddr_to_str(src), haddr_to_str(dst), ) actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] self._modflow_and_send_packet(msg, src, dst, actions)
def switch_configuration(self, ev): print "Packet in: switch configuration" msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id self.mac2port.dpid_add(dpid) LOG.info("Src MAC: %s; Dest MAC: %s", haddr_to_str(src), haddr_to_str(dst)) self.mac2port.port_add(dpid, msg.in_port, src) out_port = self.mac2port.port_get(dpid, dst) if out_port == None: LOG.info("Output port not found") out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] LOG.info("Input port: %s; Output port: %s", msg.in_port, out_port) if out_port != ofproto.OFPP_FLOOD: rule = nx_match.ClsRule() rule.set_in_port(msg.in_port) rule.set_dl_dst(dst) rule.set_dl_src(src) rule.set_nw_dscp(0) datapath.send_flow_mod( rule=rule, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) datapath.send_packet_out(msg.buffer_id, msg.in_port, actions)
def actions_to_str(acts): actions = [] for a in acts: action_type = a.cls_action_type if action_type == ofproto_v1_0.OFPAT_OUTPUT: buf = 'OUTPUT:' + str(a.port) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_VID: buf = 'SET_VLAN_VID:' + str(a.vlan_vid) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_PCP: buf = 'SET_VLAN_PCP:' + str(a.vlan_pcp) elif action_type == ofproto_v1_0.OFPAT_STRIP_VLAN: buf = 'STRIP_VLAN' elif action_type == ofproto_v1_0.OFPAT_SET_DL_SRC: buf = 'SET_DL_SRC:' + haddr_to_str(a.dl_addr) elif action_type == ofproto_v1_0.OFPAT_SET_DL_DST: buf = 'SET_DL_DST:' + haddr_to_str(a.dl_addr) elif action_type==65535: if a.subtype==2: buf = 'set_tunnel:'+str(a.tun_id) else: buf='resubmit:(,'+str(a.table)+')' else: buf='UNKNOWN' actions.append(buf) return actions
def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) match = msg.match.fields #for field in match: #logger.info("FIELDS==> %s ",field.value) logger.info("") logger.info("----------------------------------------") logger.info("*** PacketIn ***") logger.info("in_port=%d, eth_type: %s", in_port, hex(eth_type)) logger.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id) logger.info("packet in datapath_id=%s src=%s dst=%s", msg.datapath.id, haddr_to_str(src), haddr_to_str(dst)) pkt = packet.Packet(msg.data) # get data of packet eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) match = msg.match in_port = 0 #iterate through fields - parser should handle this #packet in dpid 20015998343868 from 08:00:27:15:d4:53 to ff:ff:ff:ff:ff:ff log_port 0 phy_port 0 #Field MTInPort(header=2147483652,length=8,n_bytes=4,value=2) #Field MTEthType(header=2147486210,length=6,n_bytes=2,value=2054) #Field MTArpOp(header=2147494402,length=6,n_bytes=2,value=1) #Field MTMetadata(header=2147484680,length=12,n_bytes=8,value=18446744073709551615L) #Field MTArpSha(header=2147495942,length=10,n_bytes=6,value="\x08\x00'\x15\xd4S") #Field MTEthDst(header=2147485190,length=10,n_bytes=6,value='\xff\xff\xff\xff\xff\xff') #Field MTArpSpa(header=2147494916,length=8,n_bytes=4,value=167772161) #Field MTArpTha(header=2147496454,length=10,n_bytes=6,value='\x00\x00\x00\x00\x00\x00') for o in match.fields: if isinstance(o, ofproto_v1_2_parser.MTInPort): in_port = o.value break self.logger.info("packet in dpid %s from %s to %s log_port %s", dpid, haddr_to_str(src), haddr_to_str(dst), in_port) # do we know the mac? if src not in self.mac_to_port[dpid]: # learn the mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port # set a flow to table 0 to allow packets through to table 1 match = datapath.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_src(src) instructions = [datapath.ofproto_parser.OFPInstructionGotoTable(1)] self.add_flow(datapath, 0, match, instructions) if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] actions = [datapath.ofproto_parser.OFPActionOutput(out_port, 1500)] match = datapath.ofproto_parser.OFPMatch() match.set_dl_dst(dst) instructions = [datapath.ofproto_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] self.add_flow(datapath, 1, match, instructions, buffer_id=msg.buffer_id) else: out_port = ofproto_v1_2.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port, 1500)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions) datapath.send_msg(out)
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id print 'mac_to_port',self.mac_to_port,'\n' self.mac_to_port.setdefault(dpid, {}) print 'mac_to_port',self.mac_to_port,'\n' LOG.info("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = msg.in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] if out_port != ofproto.OFPP_FLOOD: #self.add_flow(datapath, msg.in_port, dst, [datapath.ofproto_parser.OFPActionOutput(datapath.ofproto.OFPP_NORMAL)]) self.add_flow(datapath, msg.in_port, dst, actions) #add a ipv6 flow table: if _eth_type == ether.ETH_TYPE_IPV6: #print _eth_type pkt = Packet(array('B',msg.data)) for packet in pkt: if isinstance(packet,array): pass else: if packet.protocol_name=='ipv6': ipv6_packet=packet else: pass ipv6_src=self._binary_to_ipv6_format(ipv6_packet.src) ipv6_dst=self._binary_to_ipv6_format(ipv6_packet.dst) print ipv6_src,ipv6_dst ''' # judge if src and dst addr is special # eg: src [0,0,0,0] dst begin with 0xff01 or 0x ff02 if ipv6_src == [0,0,0,0] or ipv6_dst[0]&0xff010000 == 0xff010000 or ipv6_dst[0]&0xff020000 == 0xff020000: print 'ipv6 reserved address\n' #elif ipv6_dst[0]&0xfe800000 == 0xfe800000: # print 'ipv6 dst address is Link-Local address' else: ''' rule={'ipv6_src':ipv6_src,'ipv6_dst':ipv6_dst} self.nx_ipv6_add_flow(datapath,rule,actions) print 'add a ipv6 flow entry' out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out)
def packet_in_handler(self, ev): msg = ev.msg dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) in_port = msg.match.fields[0].value LOG.info("----------------------------------------") LOG.info("* PacketIn") LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type)) LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id) LOG.info("packet in datapath_id=%s src=%s dst=%s", msg.datapath.id, haddr_to_str(src), haddr_to_str(dst))
def _flood_to_nw_id(self, msg, src, dst, nw_id): datapath = msg.datapath actions = [] self.logger.debug("dpid %s in_port %d src %s dst %s ports %s", datapath.id, msg.in_port, haddr_to_str(src), haddr_to_str(dst), self.nw.dpids.get(datapath.id, {}).items()) for port_no in self.nw.filter_ports(datapath.id, msg.in_port, nw_id, NW_ID_EXTERNAL): self.logger.debug("port_no %s", port_no) actions.append(datapath.ofproto_parser.OFPActionOutput(port_no)) self._modflow_and_send_packet(msg, src, dst, actions)
def match_to_str(m): return {'dl_dst': haddr_to_str(m.dl_dst), 'dl_src': haddr_to_str(m.dl_src), 'dl_type': m.dl_type, 'dl_vlan': m.dl_vlan, 'dl_vlan_pcp': m.dl_vlan_pcp, 'in_port': m.in_port, 'nw_dst': socket.inet_ntoa(struct.pack('!I', m.nw_dst)), 'nw_proto': m.nw_proto, 'nw_src': socket.inet_ntoa(struct.pack('!I', m.nw_src)), 'tp_src': m.tp_src, 'tp_dst': m.tp_dst}
def match_to_str(m): return {'dl_dst': haddr_to_str(m.dl_dst), 'dl_src': haddr_to_str(m.dl_src), 'dl_type': m.dl_type, 'dl_vlan': m.dl_vlan, 'dl_vlan_pcp': m.dl_vlan_pcp, 'in_port': m.in_port, 'nw_dst': nw_dst_to_str(m.wildcards, m.nw_dst), 'nw_proto': m.nw_proto, 'nw_src': nw_src_to_str(m.wildcards, m.nw_src), 'tp_src': m.tp_src, 'tp_dst': m.tp_dst}
def _decode_bridge_id(bridge_id): priority = (bridge_id << 12) & 0xf000 system_id_extension = (bridge_id >> 4) & 0xfff mac_addr = (bridge_id >> 16) & 0xffffffffffff mac_addr_list = [format((mac_addr >> (8 * i)) & 0xff, '02x') for i in range(0, 6)] mac_address = binascii.a2b_hex(''.join(mac_addr_list)) #TODO: from ryu.lib import mac print mac.haddr_to_str(mac_address) return priority, system_id_extension, mac_address
def equal_match(key, value, cls_name, fields): for field in fields: if cls_name in str(field): if key in ['dl_src', 'dl_dst', 'arp_sha', 'arp_tha', 'eth_src', 'eth_dst']: eth, mask = _to_match_eth(value) str_eth = mac.haddr_to_str(eth) str_mask = mac.haddr_to_str(mask) str_value = mac.haddr_to_str(field.value) for i in range(0, 17): if str_mask[i] == 'f': eq_(str_eth[i], str_value[i]) else: continue eq_(mask, field.mask) return elif key in ['nw_src', 'nw_dst', 'ipv4_src', 'ipv4_dst', 'arp_spa', 'arp_tpa']: ipv4, mask = _to_match_ip(value) eq_(ipv4, field.value) eq_(mask, field.mask) return elif key in ['ipv6_src', 'ipv6_dst']: ipv6, mask = _to_match_ipv6(value) for i in range(0, 8): if mask[i] == 65535: eq_(ipv6[i], field.value[i]) else: continue eq_(list(mask), field.mask) return elif key == 'ipv6_nd_target': ipv6, mask = _to_match_ipv6(value) for i in range(0, 8): if mask[i] == 65535: eq_(ipv6[i], field.value[i]) else: continue return elif key == 'ipv6_nd_sll' or key == 'ipv6_nd_tll': eq_(mac.haddr_to_bin(value), field.value) return elif key == 'metadata': eq_(int(value, 16), field.value) return else: eq_(value, field.value) return assert False
def test_to_string(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) nd = icmpv6.nd_neighbor( self.res, self.dst, self.nd_type, self.nd_length, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, nd) nd_opt_values = {'hw_src': haddr_to_str(self.nd_hw_src), 'data': None} _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_la.__name__, _nd_opt_str) nd_values = {'res': repr(nd.res), 'dst': repr(ipv6_to_str(self.dst)), 'type_': repr(self.nd_type), 'length': repr(self.nd_length), 'data': nd_opt_str} _nd_str = ','.join(['%s=%s' % (k, nd_values[k]) for k, v in inspect.getmembers(nd) if k in nd_values]) nd_str = '%s(%s)' % (icmpv6.nd_neighbor.__name__, _nd_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr('0x%x' % self.csum), 'data': nd_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
def to_dict(self): return { "dpid": dpid_to_str(self.dpid), "port_no": port_no_to_str(self.port_no), "hw_addr": haddr_to_str(self.hw_addr), "name": self.name.rstrip("\0"), }
def match_to_str(ofmatch): keys = { ofproto_v1_3.OXM_OF_IN_PORT: 'in_port', ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src', ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst', ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type', ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan', ofproto_v1_3.OXM_OF_IPV4_SRC: 'nw_src', ofproto_v1_3.OXM_OF_IPV4_DST: 'nw_dst', ofproto_v1_3.OXM_OF_IPV4_SRC_W: 'nw_src', ofproto_v1_3.OXM_OF_IPV4_DST_W: 'nw_dst', ofproto_v1_3.OXM_OF_IP_PROTO: 'nw_proto', ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src', ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst', ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src', ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst' } match = {} for match_field in ofmatch.fields: key = keys[match_field.header] if key == 'dl_src' or key == 'dl_dst': value = mac.haddr_to_str(match_field.value) elif key == 'nw_src' or key == 'nw_dst': value = match_ip_to_str(match_field.value, match_field.mask) else: value = match_field.value match.setdefault(key, value) return match
def to_dict(self): return { 'dpid': dpid_to_str(self.dpid), 'port_no': port_no_to_str(self.port_no), 'hw_addr': haddr_to_str(self.hw_addr), 'name': self.name.rstrip('\0') }
def to_rest(openflow): of_match = openflow[REST_MATCH] mac_dontcare = mac.haddr_to_str(mac.DONTCARE) ip_dontcare = '0.0.0.0' ipv6_dontcare = '::' match = {} for key, value in of_match.items(): if key == REST_SRC_MAC or key == REST_DST_MAC: if value == mac_dontcare: continue elif key == REST_SRC_IP or key == REST_DST_IP: if value == ip_dontcare: continue elif key == REST_SRC_IPV6 or key == REST_DST_IPV6: if value == ipv6_dontcare: continue elif value == 0: continue if key in Match._CONVERT: conv = Match._CONVERT[key] conv = dict((value, key) for key, value in conv.items()) match.setdefault(key, conv[value]) else: match.setdefault(key, value) return match
def to_rest(openflow): of_match = openflow[REST_MATCH] mac_dontcare = mac.haddr_to_str(mac.DONTCARE) ip_dontcare = '0.0.0.0' match = {} for key, value in of_match.items(): if key == REST_SRC_MAC or key == REST_DST_MAC: if value == mac_dontcare: continue elif key == REST_SRC_IP or key == REST_DST_IP: if value == ip_dontcare: continue elif value == 0: continue if key in Match._CONVERT: conv = Match._CONVERT[key] conv = dict((value, key) for key, value in conv.items()) match.setdefault(key, conv[value]) else: match.setdefault(key, value) return match
def block_out_sample_in(self, stats): ofproto = datapath.ofproto #SRC BLOCK FLOW src_mac = stats.match.dl_dst if not src_mac == self.gateway_mac: src_match = datapath.ofproto_parser.OFPMatch(dl_src=src_mac, dl_dst=self.gateway_mac) src_flow = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=src_match, cookie=random_int(), command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=2, priority=0x6000, flags=ofproto.OFPFF_SEND_FLOW_REM) datapath.send_msg(src_flow) eventlet.sleep(0.1) # DST BLOCK FLOW - We only sample this flow for 1 second, # Destination does not receive anything. dst_mac = stats.match.dl_dst if not dst_mac == self.gateway_mac: dst_match = datapath.ofproto_parser.OFPMatch(dl_src=self.gateway_mac, dl_dst=dst_mac) dst_actions = [datapath.ofproto_parser.OFPActionOutput(monitor_port)] dst_flow = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=dst_match, cookie=random_int(), command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=1, priority=0x6000, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=dst_actions) datapath.send_msg(dst_flow) #Notify parser of this source/destination being blocked from this point on. outgoing_block_mode_v1_dict[(haddr_to_str(src_mac))] = int(time.time() * 1000)
def test_mac_haddr_to_str(self): addr = 'aa:aa:aa:aa:aa:aa' val = '\xaa\xaa\xaa\xaa\xaa\xaa' res = mac.haddr_to_str(val) eq_(addr, res)
def test_mac_haddr_to_str(self): addr = "aa:aa:aa:aa:aa:aa" val = b"\xaa\xaa\xaa\xaa\xaa\xaa" res = mac.haddr_to_str(val) eq_(addr, res)
def match_to_str(ofmatch): keys = {ofproto_v1_3.OXM_OF_IN_PORT: 'in_port', ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src', ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst', ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type', ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan', ofproto_v1_3.OXM_OF_IPV4_SRC: 'nw_src', ofproto_v1_3.OXM_OF_IPV4_DST: 'nw_dst', ofproto_v1_3.OXM_OF_IPV4_SRC_W: 'nw_src', ofproto_v1_3.OXM_OF_IPV4_DST_W: 'nw_dst', ofproto_v1_3.OXM_OF_IP_PROTO: 'nw_proto', ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src', ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst', ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src', ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst', ofproto_v1_3.OXM_OF_METADATA: 'metadata', ofproto_v1_3.OXM_OF_METADATA_W: 'metadata'} match = {} for match_field in ofmatch.fields: key = keys[match_field.header] if key == 'dl_src' or key == 'dl_dst': value = mac.haddr_to_str(match_field.value) elif key == 'nw_src' or key == 'nw_dst': value = match_ip_to_str(match_field.value, match_field.mask) elif key == 'metadata': value = ('%d/%d' % (match_field.value, match_field.mask) if match_field.mask else '%d' % match_field.value) else: value = match_field.value match.setdefault(key, value) return match
def test_mac_haddr_to_str_none(self): """ addr is None """ addr = None val = 'None' res = mac.haddr_to_str(addr) eq_(val, res)
def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath port = msg.match['in_port'] pkt = packet.Packet(data=msg.data) ofproto = datapath.ofproto dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.debug("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = msg.in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: self.add_flow(datapath, msg.in_port, dst, actions) if drop_checker[port] == True: self.delete_flow(datapath) out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out) pkt_dhcp = pkt.get_protocols(dhcp.dhcp) if not pkt_dhcp: return else: drop_checker[port] = False self._handle_dhcp(datapath, port, pkt) return
def test_mac_haddr_to_str_none(self): """ addr is None """ addr = None val = "None" res = mac.haddr_to_str(addr) eq_(val, res)
def _forward_to_nw_id(self, msg, src, dst, nw_id, out_port): assert out_port is not None datapath = msg.datapath if not self.nw.same_network(datapath.id, nw_id, out_port, NW_ID_EXTERNAL): LOG.debug( 'packet is blocked src %s dst %s ' 'from %d to %d on datapath %d', haddr_to_str(src), haddr_to_str(dst), msg.in_port, out_port, datapath.id) return LOG.debug("learned dpid %s in_port %d out_port %d src %s dst %s", datapath.id, msg.in_port, out_port, haddr_to_str(src), haddr_to_str(dst)) actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] self._modflow_and_send_packet(msg, src, dst, actions)
def match_to_str(ofmatch): keys = {ofproto_v1_2.OXM_OF_IN_PORT: 'in_port', ofproto_v1_2.OXM_OF_IN_PHY_PORT: 'in_phy_port', ofproto_v1_2.OXM_OF_ETH_SRC: 'dl_src', ofproto_v1_2.OXM_OF_ETH_DST: 'dl_dst', ofproto_v1_2.OXM_OF_ETH_TYPE: 'dl_type', ofproto_v1_2.OXM_OF_VLAN_VID: 'dl_vlan', ofproto_v1_2.OXM_OF_VLAN_PCP: 'vlan_pcp', ofproto_v1_2.OXM_OF_IP_DSCP: 'ip_dscp', ofproto_v1_2.OXM_OF_IP_ECN: 'ip_ecn', ofproto_v1_2.OXM_OF_IPV4_SRC: 'nw_src', ofproto_v1_2.OXM_OF_IPV4_DST: 'nw_dst', ofproto_v1_2.OXM_OF_IPV4_SRC_W: 'nw_src', ofproto_v1_2.OXM_OF_IPV4_DST_W: 'nw_dst', ofproto_v1_2.OXM_OF_IP_PROTO: 'nw_proto', ofproto_v1_2.OXM_OF_TCP_SRC: 'tp_src', ofproto_v1_2.OXM_OF_TCP_DST: 'tp_dst', ofproto_v1_2.OXM_OF_UDP_SRC: 'tp_src', ofproto_v1_2.OXM_OF_UDP_DST: 'tp_dst', ofproto_v1_2.OXM_OF_SCTP_SRC: 'sctp_src', ofproto_v1_2.OXM_OF_SCTP_DST: 'sctp_dst', ofproto_v1_2.OXM_OF_ICMPV4_TYPE: 'icmpv4_type', ofproto_v1_2.OXM_OF_ICMPV4_CODE: 'icmpv4_code', ofproto_v1_2.OXM_OF_MPLS_LABEL: 'mpls_label', ofproto_v1_2.OXM_OF_MPLS_TC: 'mpls_tc', ofproto_v1_2.OXM_OF_ARP_OP: 'arp_op', ofproto_v1_2.OXM_OF_ARP_SPA: 'arp_spa', ofproto_v1_2.OXM_OF_ARP_TPA: 'arp_tpa', ofproto_v1_2.OXM_OF_ARP_SPA_W: 'arp_spa', ofproto_v1_2.OXM_OF_ARP_TPA_W: 'arp_tpa', ofproto_v1_2.OXM_OF_ARP_SHA: 'arp_sha', ofproto_v1_2.OXM_OF_ARP_THA: 'arp_tha', ofproto_v1_2.OXM_OF_IPV6_SRC: 'ipv6_src', ofproto_v1_2.OXM_OF_IPV6_DST: 'ipv6_dst', ofproto_v1_2.OXM_OF_IPV6_SRC_W: 'ipv6_src', ofproto_v1_2.OXM_OF_IPV6_DST_W: 'ipv6_dst', ofproto_v1_2.OXM_OF_IPV6_FLABEL: 'ipv6_flabel', ofproto_v1_2.OXM_OF_ICMPV6_TYPE: 'icmpv6_type', ofproto_v1_2.OXM_OF_ICMPV6_CODE: 'icmpv6_code', ofproto_v1_2.OXM_OF_IPV6_ND_TARGET: 'ipv6_nd_target', ofproto_v1_2.OXM_OF_IPV6_ND_SLL: 'ipv6_nd_sll', ofproto_v1_2.OXM_OF_IPV6_ND_TLL: 'ipv6_nd_tll'} match = {} for match_field in ofmatch.fields: key = keys[match_field.header] if key == 'dl_src' or key == 'dl_dst': value = mac.haddr_to_str(match_field.value) elif key == 'nw_src' or key == 'nw_dst' or \ key == 'arp_spa' or key == 'arp_tpa': value = match_ip_to_str(match_field.value, match_field.mask) elif key == 'ipv6_src' or key == 'ipv6_dst': value = match_ipv6_to_str(match_field.value, match_field.mask) else: value = match_field.value match.setdefault(key, value) return match
def _port_del(self, ev): # free mac addresses associated to this VM port, # and delete related flow entries for later reuse of mac address dps_needs_barrier = set() msg = ev.msg datapath = msg.datapath datapath_id = datapath.id port_no = msg.desc.port_no rule = nx_match.ClsRule() rule.set_in_port(port_no) datapath.send_flow_del(rule=rule, cookie=0) rule = nx_match.ClsRule() datapath.send_flow_del(rule=rule, cookie=0, out_port=port_no) dps_needs_barrier.add(datapath) try: port_nw_id = self.nw.get_network(datapath_id, port_no) except PortUnknown: # race condition between rest api delete port # and openflow port deletion ofp_event pass else: if port_nw_id in (NW_ID_UNKNOWN, NW_ID_EXTERNAL): datapath.send_barrier() return for mac_ in self.mac2port.mac_list(datapath_id, port_no): for (_dpid, dp) in self.dpset.get_all(): if self.mac2port.port_get(dp.id, mac_) is None: continue rule = nx_match.ClsRule() rule.set_dl_src(mac_) dp.send_flow_del(rule=rule, cookie=0) rule = nx_match.ClsRule() rule.set_dl_dst(mac_) dp.send_flow_del(rule=rule, cookie=0) dps_needs_barrier.add(dp) self.mac2port.mac_del(dp.id, mac_) try: self.mac2net.del_mac(mac_) self.api_db.delMAC(haddr_to_str(mac_)) except MacAddressNotFound: # Race condition between del_mac REST API and OF port_del ofp_event # Other possibility is that Ryu has been restarted after a crash pass self.nw.port_deleted(datapath.id, port_no) for dp in dps_needs_barrier: dp.send_barrier()
def __str__(self): return "EventVMPort<dpid %s port_no %d " "network_id %s tunnel_key %s mac %s add_del %s>" % ( dpid_lib.dpid_to_str(self.dpid), self.port_no, self.network_id, self.tunnel_key, mac.haddr_to_str(self.mac_address), self.add_del, )
def lists(self, _req, network_id, dpid, port_id, **_kwargs): dpid = dpid_lib.str_to_dpid(dpid) port_id = int(port_id) try: body = json.dumps([mac_lib.haddr_to_str(mac_addr) for mac_addr in self.nw.list_mac(dpid, port_id)]) except PortNotFound: return Response(status=404) return Response(content_type='application/json', body=body)
def get_eth_src(msg): dp = msg.datapath eth_src = None for f in msg.match.fields: if f.header == dp.ofproto.OXM_OF_ETH_SRC: eth_src = haddr_to_str(f.value) if eth_src is None: eth_src = Ether(str(msg.data)).src return eth_src
def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.debug("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) self.logger.info("===============Message: %d================", self.msg_num) self.logger.info("packet in %s %s %s %s", dpid, eth.src, eth.dst, msg.in_port) self.logger.info("src: %s, out_port: %s", eth.src, msg.in_port) self.logger.info("------------------------------------") # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = msg.in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: self.add_flow(datapath, msg.in_port, dst, actions) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) self.msg_num += 1 self.logger.info("===========================================") datapath.send_msg(out)
def add_mac(self, mac, nw_id, nw_id_external=None): _nw_id = self.mac_to_net.get(mac) if _nw_id == nw_id: return # allow changing from nw_id_external to known nw id if _nw_id is None or _nw_id == nw_id_external: self.mac_to_net[mac] = nw_id LOG.debug("overwrite nw_id: mac %s nw old %s new %s", haddr_to_str(mac), _nw_id, nw_id) return if nw_id == nw_id_external: # this can happens when the packet traverses # VM-> tap-> ovs-> ext-port-> wire-> ext-port-> ovs-> tap-> VM return LOG.warn("duplicated nw_id: mac %s nw old %s new %s", haddr_to_str(mac), _nw_id, nw_id) raise MacAddressDuplicated(mac=mac)
def equal_str(key, value, match_str): if key in ['dl_src', 'dl_dst', 'arp_sha', 'arp_tha']: eth_1, mask_1 = _to_match_eth(value) eth_2, mask_2 = _to_match_eth(match_str[key]) str_eth_1 = mac.haddr_to_str(eth_1) str_mask_1 = mac.haddr_to_str(mask_1) str_eth_2 = mac.haddr_to_str(eth_2) for i in range(0, 17): if str_mask_1[i] == 'f': eq_(str_eth_1[i], str_eth_2[i]) else: continue eq_(mask_1, mask_2) return elif key in['nw_src', 'nw_dst', 'arp_spa', 'arp_tpa']: ipv4_1, ip_mask_1 = _to_match_ip(value) ipv4_2, ip_mask_2 = _to_match_ip(match_str[key]) eq_(ipv4_1, ipv4_2) eq_(ip_mask_1, ip_mask_2) return elif key in ['ipv6_src', 'ipv6_dst']: ipv6_1, netmask_1 = _to_match_ipv6(value) ipv6_2, netmask_2 = _to_match_ipv6(match_str[key]) for i in range(0, 8): if netmask_1[i] == 65535: eq_(ipv6_1[i], ipv6_2[i]) else: continue eq_(netmask_1, netmask_2) return elif key == 'ipv6_nd_target': ipv6_1, netmask_1 = _to_match_ipv6(value) ipv6_2, netmask_2 = _to_match_ipv6(match_str[key]) for i in range(0, 8): if netmask_1[i] == 65535: eq_(ipv6_1[i], ipv6_2[i]) else: continue return elif key == 'metadata': eq_(str(int(value, 16)), match_str[key]) return eq_(value, match_str[key])
def match_to_str(m): match = {} if ~m.wildcards & ofproto_v1_0.OFPFW_IN_PORT: match['in_port'] = m.in_port if ~m.wildcards & ofproto_v1_0.OFPFW_DL_SRC: match['dl_src'] = haddr_to_str(m.dl_src) if ~m.wildcards & ofproto_v1_0.OFPFW_DL_DST: match['dl_dst'] = haddr_to_str(m.dl_dst) if ~m.wildcards & ofproto_v1_0.OFPFW_DL_VLAN: match['dl_vlan'] = m.dl_vlan if ~m.wildcards & ofproto_v1_0.OFPFW_DL_VLAN_PCP: match['dl_vlan_pcp'] = m.dl_vlan_pcp if ~m.wildcards & ofproto_v1_0.OFPFW_DL_TYPE: match['dl_type'] = m.dl_type if ~m.wildcards & ofproto_v1_0.OFPFW_NW_TOS: match['nw_tos'] = m.nw_tos if ~m.wildcards & ofproto_v1_0.OFPFW_NW_PROTO: match['nw_proto'] = m.nw_proto if ~m.wildcards & ofproto_v1_0.OFPFW_NW_SRC_ALL: match['nw_src'] = nw_src_to_str(m.wildcards, m.nw_src) if ~m.wildcards & ofproto_v1_0.OFPFW_NW_DST_ALL: match['nw_dst'] = nw_dst_to_str(m.wildcards, m.nw_dst) if ~m.wildcards & ofproto_v1_0.OFPFW_TP_SRC: match['tp_src'] = m.tp_src if ~m.wildcards & ofproto_v1_0.OFPFW_TP_DST: match['tp_dst'] = m.tp_dst return match
def actions_to_str(acts): actions = [] for a in acts: action_type = a.cls_action_type if action_type == ofproto_v1_0.OFPAT_OUTPUT: port = UTIL.ofp_port_to_user(a.port) buf = 'OUTPUT:' + str(port) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_VID: buf = 'SET_VLAN_VID:' + str(a.vlan_vid) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_PCP: buf = 'SET_VLAN_PCP:' + str(a.vlan_pcp) elif action_type == ofproto_v1_0.OFPAT_STRIP_VLAN: buf = 'STRIP_VLAN' elif action_type == ofproto_v1_0.OFPAT_SET_DL_SRC: buf = 'SET_DL_SRC:' + haddr_to_str(a.dl_addr) elif action_type == ofproto_v1_0.OFPAT_SET_DL_DST: buf = 'SET_DL_DST:' + haddr_to_str(a.dl_addr) elif action_type == ofproto_v1_0.OFPAT_SET_NW_SRC: buf = 'SET_NW_SRC:' + \ socket.inet_ntoa(struct.pack('!I', a.nw_addr)) elif action_type == ofproto_v1_0.OFPAT_SET_NW_DST: buf = 'SET_NW_DST:' + \ socket.inet_ntoa(struct.pack('!I', a.nw_addr)) elif action_type == ofproto_v1_0.OFPAT_SET_NW_TOS: buf = 'SET_NW_TOS:' + str(a.tos) elif action_type == ofproto_v1_0.OFPAT_SET_TP_SRC: buf = 'SET_TP_SRC:' + str(a.tp) elif action_type == ofproto_v1_0.OFPAT_SET_TP_DST: buf = 'SET_TP_DST:' + str(a.tp) elif action_type == ofproto_v1_0.OFPAT_ENQUEUE: port = UTIL.ofp_port_to_user(a.port) queue = UTIL.ofp_queue_to_user(a.queue_id) buf = 'ENQUEUE:' + str(port) + ":" + str(queue) elif action_type == ofproto_v1_0.OFPAT_VENDOR: buf = 'VENDOR' else: buf = 'UNKNOWN' actions.append(buf) return actions
def add_mac(self, mac, nw_id, nw_id_external=None): _nw_id = self.mac_to_net.get(mac) if _nw_id == nw_id: return # allow changing from nw_id_external to known nw id if _nw_id is None or _nw_id == nw_id_external: self.mac_to_net[mac] = nw_id LOG.debug('overwrite nw_id: mac %s nw old %s new %s', haddr_to_str(mac), _nw_id, nw_id) return if nw_id == nw_id_external: # this can happens when the packet traverses # VM-> tap-> ovs-> ext-port-> wire-> ext-port-> ovs-> tap-> VM return LOG.warning('duplicated nw_id: mac %s nw old %s new %s', haddr_to_str(mac), _nw_id, nw_id) raise MacAddressDuplicated(mac=mac)
def packetInHandler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id self.mac2port.dpid_add(dpid) LOG.info("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) self.mac2port.port_add(dpid, msg.in_port, src) out_port = self.mac2port.port_get(dpid, dst) if out_port == None: LOG.info("out_port not found") out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] if out_port != ofproto.OFPP_FLOOD: wildcards = ofproto.OFPFW_ALL wildcards &= ~(ofproto.OFPFW_IN_PORT | ofproto.OFPFW_DL_DST | ofproto.OFPFW_NW_TOS) match = datapath.ofproto_parser.OFPMatch( wildcards, msg.in_port, haddr_to_bin('00:00:00:00:00:00'), dst, 0, 0, 0, 0, 0, 0, 0, 0, 0) datapath.send_flow_mod(match=match, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=32768, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) datapath.send_packet_out(msg.buffer_id, msg.in_port, actions)
def port_add(self, dpid, port, mac): """ :returns: old port if learned. (this may be = port) None otherwise """ old_port = self.mac_to_port[dpid].get(mac, None) self.mac_to_port[dpid][mac] = port if old_port is not None and old_port != port: LOG.debug('port_add: 0x%016x 0x%04x %s', dpid, port, haddr_to_str(mac)) return old_port
def actions_to_str(acts): actions = [] for a in acts: action_type = a.cls_action_type if action_type == ofproto_v1_0.OFPAT_OUTPUT: buf = 'OUTPUT:' + str(a.port) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_VID: buf = 'SET_VLAN_VID:' + str(a.vlan_vid) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_PCP: buf = 'SET_VLAN_PCP:' + str(a.vlan_pcp) elif action_type == ofproto_v1_0.OFPAT_STRIP_VLAN: buf = 'STRIP_VLAN' elif action_type == ofproto_v1_0.OFPAT_SET_DL_SRC: buf = 'SET_DL_SRC:' + haddr_to_str(a.dl_addr) elif action_type == ofproto_v1_0.OFPAT_SET_DL_DST: buf = 'SET_DL_DST:' + haddr_to_str(a.dl_addr) else: buf = 'UNKNOWN' actions.append(buf) return actions
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id self.mac2port.dpid_add(dpid) LOG.info("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) self.mac2port.port_add(dpid, msg.in_port, src) out_port = self.mac2port.port_get(dpid, dst) if out_port == None: LOG.info("out_port not found") out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] if out_port != ofproto.OFPP_FLOOD: rule = nx_match.ClsRule() rule.set_in_port(msg.in_port) rule.set_dl_dst(dst) rule.set_dl_type(nx_match.ETH_TYPE_IP) rule.set_nw_dscp(0) datapath.send_flow_mod(rule=rule, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) datapath.send_packet_out(msg.buffer_id, msg.in_port, actions)
def _packet_in_handler(self, ev): pkt = packet.Packet(array.array('B', ev.msg.data)) eth_pkt = pkt.get_protocol(ethernet.ethernet) arp_pkt = pkt.get_protocol(arp.arp) ip4_pkt = pkt.get_protocol(ipv4.ipv4) if arp_pkt: pak = arp_pkt elif ip4_pkt: pak = ip4_pkt else: pak = eth_pkt self.logger.info(' _packet_in_handler: src_mac -> %s' % eth_pkt.src) self.logger.info(' _packet_in_handler: dst_mac -> %s' % eth_pkt.dst) self.logger.info(' _packet_in_handler: %s' % pak) self.logger.info(' ------') src = eth_pkt.src # Set up the src and dst variables so you can use them dst = eth_pkt.dst ## Mike Pennington's modifications end here msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = msg.in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: self.add_flow(datapath, msg.in_port, dst, actions) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out) if (haddr_to_str(src) == "00:00:00:00:00:01"): print "src" self.counterTraffic +=1
def packet_in_handler(self, ev): print("[DEDALO] Nuevo paquete\n") msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.debug("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = msg.in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] print("[DEDALO] Paquete entrante en " + str(dpid) + " con MAC destino " + haddr_to_str(dst) + " sale por el puerto " + str(out_port)) # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: self.add_flow(datapath, msg.in_port, dst, actions) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out) print("[DEDALO] Tabla CAM: " + str(self.mac_to_port))
def block_out_sample_in(self, stats): ofproto = datapath.ofproto #SRC BLOCK FLOW src_mac = stats.match.dl_dst if not src_mac == self.gateway_mac: src_match = datapath.ofproto_parser.OFPMatch( dl_src=src_mac, dl_dst=self.gateway_mac) src_flow = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=src_match, cookie=random_int(), command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=2, priority=0x6000, flags=ofproto.OFPFF_SEND_FLOW_REM) datapath.send_msg(src_flow) eventlet.sleep(0.1) # DST BLOCK FLOW - We only sample this flow for 1 second, # Destination does not receive anything. dst_mac = stats.match.dl_dst if not dst_mac == self.gateway_mac: dst_match = datapath.ofproto_parser.OFPMatch( dl_src=self.gateway_mac, dl_dst=dst_mac) dst_actions = [ datapath.ofproto_parser.OFPActionOutput(monitor_port) ] dst_flow = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=dst_match, cookie=random_int(), command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=1, priority=0x6000, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=dst_actions) datapath.send_msg(dst_flow) #Notify parser of this source/destination being blocked from this point on. outgoing_block_mode_v1_dict[(haddr_to_str(src_mac))] = int( time.time() * 1000)
def match_to_str(ofmatch): keys = {ofproto_v1_3.OXM_OF_IN_PORT: 'in_port', ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src', ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst', ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type', ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan', ofproto_v1_3.OXM_OF_IPV4_SRC: 'nw_src', ofproto_v1_3.OXM_OF_IPV4_DST: 'nw_dst', ofproto_v1_3.OXM_OF_IPV4_SRC_W: 'nw_src', ofproto_v1_3.OXM_OF_IPV4_DST_W: 'nw_dst', ofproto_v1_3.OXM_OF_IP_PROTO: 'nw_proto', ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src', ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst', ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src', ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst', ofproto_v1_3.OXM_OF_MPLS_LABEL: 'mpls_label', ofproto_v1_3.OXM_OF_METADATA: 'metadata', ofproto_v1_3.OXM_OF_METADATA_W: 'metadata', ofproto_v1_3.OXM_OF_ARP_SPA: 'arp_spa', ofproto_v1_3.OXM_OF_ARP_TPA: 'arp_tpa', ofproto_v1_3.OXM_OF_ARP_SPA_W: 'arp_spa', ofproto_v1_3.OXM_OF_ARP_TPA_W: 'arp_tpa', ofproto_v1_3.OXM_OF_IPV6_SRC: 'ipv6_src', ofproto_v1_3.OXM_OF_IPV6_DST: 'ipv6_dst', ofproto_v1_3.OXM_OF_IPV6_SRC_W: 'ipv6_src', ofproto_v1_3.OXM_OF_IPV6_DST_W: 'ipv6_dst'} match = {} for match_field in ofmatch.fields: key = keys[match_field.header] if key == 'dl_src' or key == 'dl_dst': value = mac.haddr_to_str(match_field.value) elif key == 'nw_src' or key == 'nw_dst' or \ key == 'arp_spa' or key == 'arp_tpa': value = match_ip_to_str(match_field.value, match_field.mask) elif key == 'ipv6_src' or key == 'ipv6_dst': value = match_ipv6_to_str(match_field.value, match_field.mask) elif key == 'metadata': value = ('%d/%d' % (match_field.value, match_field.mask) if match_field.mask else '%d' % match_field.value) else: value = match_field.value match.setdefault(key, value) return match
def to_del_openflow(of_match): mac_dontcare = mac.haddr_to_str(mac.DONTCARE) ip_dontcare = '0.0.0.0' match = {} for key, value in of_match.items(): if key == REST_SRC_MAC or key == REST_DST_MAC: if value == mac_dontcare: continue elif key == REST_SRC_IP or key == REST_DST_IP: if value == ip_dontcare: continue elif value == 0: continue match.setdefault(key, value) return match
def _upstream_collector(self, pkt): (version, msg_type, msg_len, xid) = ofproto_parser.header(pkt) # Switch configuration messages if msg_type == ofproto_v1_0.OFPT_FEATURES_REPLY: # print("Reply xid: " + hex(xid)) msg = ofproto_v1_0_parser.OFPSwitchFeatures.parser(self.datapath, version, msg_type, msg_len, xid, pkt) match = ofproto_v1_0_parser.OFPMatch(dl_type=ETH_TYPE_LLDP, dl_dst=lldp.LLDP_MAC_NEAREST_BRIDGE) cookie = 0 command = ofproto_v1_0.OFPFC_ADD idle_timeout = hard_timeout = 0 priority = 0 buffer_id = ofproto_v1_0.OFP_NO_BUFFER out_port = ofproto_v1_0.OFPP_NONE flags = 0 actions = [ofproto_v1_0_parser.OFPActionOutput(ofproto_v1_0.OFPP_CONTROLLER)] mod = ofproto_v1_0_parser.OFPFlowMod(self.datapath, match, cookie, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, flags, actions) mod.serialize() self.id = msg.datapath_id self.ports = msg.ports # print(str(self.id) + " : Receive Features Reply Message") # print(msg) for port in self.ports.values(): db_message = {"switch_id": hex(self.id), "port_no": port.port_no, "hw_addr": port.hw_addr, "timestamp": datetime.datetime.utcnow()} try: self.db.switch_port.insert_one(db_message) except: if(self.id != None): print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database") else: print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database") pkt_lldp = packet.Packet() dst = BROADCAST_STR src = port.hw_addr ethertype = ETH_TYPE_LLDP eth_pkt = ethernet.ethernet(dst, src, ethertype) pkt_lldp.add_protocol(eth_pkt) tlv_chassis_id = lldp.ChassisID( subtype=lldp.ChassisID.SUB_LOCALLY_ASSIGNED, chassis_id='dpid:%s' % dpid_to_str(self.id)) tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_PORT_COMPONENT, port_id=struct.pack('!I', port.port_no)) tlv_ttl = lldp.TTL(ttl=120) tlv_desc = lldp.PortDescription(port_description="ProxyTopologyMonitorLLDP") tlv_end = lldp.End() tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_desc, tlv_end) lldp_pkt = lldp.lldp(tlvs) pkt_lldp.add_protocol(lldp_pkt) pkt_lldp.serialize() actions = [ofproto_v1_0_parser.OFPActionOutput(port.port_no)] out = ofproto_v1_0_parser.OFPPacketOut( datapath=self.datapath, in_port=ofproto_v1_0.OFPP_CONTROLLER, buffer_id=ofproto_v1_0.OFP_NO_BUFFER, actions=actions, data=pkt_lldp.data) out.serialize() try: self.switch_socket.send(out.buf) except: if(self.id != None): print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Broken Pipe (Downstream : LLDP Message)") else: print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Broken Pipe (Downstream : LLDP Message)") # self._close() pass elif msg_type == ofproto_v1_0.OFPT_STATS_REPLY: msg = ofproto_v1_0_parser.OFPPortStatsReply.parser(self.datapath, version, msg_type, msg_len, xid, pkt) if(type(msg) is ofproto_v1_0_parser.OFPFlowStatsReply): # print(str(self.id) + " : Receive Flow Stats Message") # print(msg.body) for flow in msg.body: db_message = {"switch": hex(self.id), "message": { "header": { "version": msg.version, "type": msg.msg_type, "length": msg.msg_len, "xid": msg.xid }, "match": { "wildcards": flow.match.wildcards, "in_port": flow.match.in_port, "dl_src": mac.haddr_to_str(flow.match.dl_src), "dl_dst": mac.haddr_to_str(flow.match.dl_dst), "dl_vlan": flow.match.dl_vlan, "dl_vlan_pcp": flow.match.dl_vlan_pcp, "dl_type": flow.match.dl_type, "nw_tos": flow.match.nw_tos, "nw_proto": flow.match.nw_proto, "nw_src": ip.ipv4_to_str(flow.match.nw_src), "nw_dst": ip.ipv4_to_str(flow.match.nw_dst), "tp_src": flow.match.tp_src, "tp_dst": flow.match.tp_dst }, "cookie": flow.cookie, "idle_timeout": flow.idle_timeout, "hard_timeout": flow.hard_timeout, "priority": flow.priority, "flags": msg.flags, "actions": [] }, "timestamp": datetime.datetime.utcnow()} for action in flow.actions: db_message["message"]["actions"].append(vars(action)); try: self.db.flow_stats.insert_one(db_message) except: if(self.id != None): print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database") else: print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database") pass if(type(msg) is ofproto_v1_0_parser.OFPPortStatsReply): # print(str(self.id) + " : Receive Port Stats Message") # print(msg.body) for port in msg.body: # print(port) db_message = {"switch": hex(self.id), "port_no": port.port_no, "rx_packets": port.rx_packets, "tx_packets": port.tx_packets, "rx_bytes": port.rx_bytes, "tx_bytes": port.tx_bytes, "rx_dropped": port.rx_dropped, "tx_dropped": port.tx_dropped, "rx_errors": port.rx_errors, "tx_errors": port.tx_errors, "rx_frame_err": port.rx_frame_err, "rx_over_err": port.rx_over_err, "rx_crc_err": port.rx_crc_err, "collisions": port.collisions, "timestamp": datetime.datetime.utcnow()} try: self.db.port_stats.insert_one(db_message) except: if(self.id != None): print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database") else: print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database") pass # Asynchronous messages elif msg_type == ofproto_v1_0.OFPT_PACKET_IN: msg = ofproto_v1_0_parser.OFPPacketIn.parser(self.datapath, version, msg_type, msg_len, xid, pkt) pkt_msg = packet.Packet(msg.data) if pkt_msg.get_protocol(ethernet.ethernet).ethertype == ETH_TYPE_LLDP: lldp_msg = pkt_msg.get_protocol(lldp.lldp) if lldp_msg != None: if lldp_msg.tlvs[3].tlv_info == "ProxyTopologyMonitorLLDP": (port,) = struct.unpack('!I', lldp_msg.tlvs[1].port_id) switch_src = str_to_dpid(lldp_msg.tlvs[0].chassis_id[5:]) # print(str(self.id) + " : Receive Proxy LLDP Packet") # print(lldp_msg) # Write to database try: self.db.topology.insert_one({"switch_dst": hex(self.id), "port_dst": port, "switch_src": hex(switch_src), "port_src": msg.in_port, "timestamp": datetime.datetime.utcnow()}) except: if(self.id != None): print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database") else: print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database") return elif lldp_msg.tlvs[3].tlv_info != "ProxyTopologyMonitorLLDP": # print(lldp_msg) # print("Controller LLDP packet") pass
def _downstream_parse(self, pkt): try: self.switch_socket.send(pkt) except: if(self.id != None): print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Broken Pipe (Downstream)") else: print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Broken Pipe (Downstream)") # self._close() # pass (version, msg_type, msg_len, xid) = ofproto_parser.header(pkt) # Controller command messages if msg_type == ofproto_v1_0.OFPT_FLOW_MOD: msg = ofproto_v1_0_parser.OFPFlowMod.parser(self.datapath, version, msg_type, msg_len, xid, pkt) # print(str(self.id) + " : Receive Flow Mod Message") # Write to database db_message = {"switch": hex(self.id), "message": { "header": { "version": version, "type": msg_type, "length": msg_len, "xid": xid }, "match": { "wildcards": msg.match.wildcards, "in_port": msg.match.in_port, "dl_src": mac.haddr_to_str(msg.match.dl_src), "dl_dst": mac.haddr_to_str(msg.match.dl_dst), "dl_vlan": msg.match.dl_vlan, "dl_vlan_pcp": msg.match.dl_vlan_pcp, "dl_type": msg.match.dl_type, "nw_tos": msg.match.nw_tos, "nw_proto": msg.match.nw_proto, "nw_src": ip.ipv4_to_str(msg.match.nw_src), "nw_dst": ip.ipv4_to_str(msg.match.nw_dst), "tp_src": msg.match.tp_src, "tp_dst": msg.match.tp_dst }, "cookie": msg.cookie, "command": msg.command, "idle_timeout": msg.idle_timeout, "hard_timeout": msg.hard_timeout, "priority": msg.priority, "buffer_id": msg.buffer_id, "out_port": msg.out_port, "flags": msg.flags, "actions": [] }, "timestamp": datetime.datetime.utcnow()} for action in msg.actions: db_message["message"]["actions"].append(vars(action)) # print(db_message) try: self.db.flow_mods.insert_one(db_message) # if(self.id != None): # print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : [" + str(hex(self.id)) + "] --- Received FlowMod message") # else: # print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : [" + str(self.id) + "] --- Received FlowMod message") except: if(self.id != None): print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database") else: print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database") pass
def test_mac_haddr_to_str_assert(self): val = b'\xaa\xaa\xaa\xaa\xaa' res = mac.haddr_to_str(val)
def packet_in_handler(self, ev): # LOG.debug('packet in ev %s msg %s', ev, ev.msg) msg = ev.msg datapath = msg.datapath dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) try: port_nw_id = self.nw.get_network(datapath.id, msg.in_port) except PortUnknown: port_nw_id = NW_ID_UNKNOWN if port_nw_id != NW_ID_UNKNOWN: # Here it is assumed that the # (port <-> network id)/(mac <-> network id) relationship # is stable once the port is created. The port will be destroyed # before assigning new network id to the given port. # This is correct nova-network/nova-compute. try: # allow external -> known nw id change self.mac2net.add_mac(src, port_nw_id, NW_ID_EXTERNAL) except MacAddressDuplicated: LOG.warn( 'mac address %s is already in use.' ' So (dpid %s, port %s) can not use it', haddr_to_str(src), datapath.id, msg.in_port) # # should we install drop action pro-actively for future? # self._drop_packet(msg) return old_port = self.mac2port.port_add(datapath.id, msg.in_port, src) if old_port is not None and old_port != msg.in_port: # We really overwrite already learned mac address. # So discard already installed stale flow entry which conflicts # new port. rule = nx_match.ClsRule() rule.set_dl_dst(src) datapath.send_flow_mod( rule=rule, cookie=0, command=datapath.ofproto.OFPFC_DELETE, idle_timeout=0, hard_timeout=0, priority=datapath.ofproto.OFP_DEFAULT_PRIORITY, out_port=old_port) # to make sure the old flow entries are purged. datapath.send_barrier() src_nw_id = self.mac2net.get_network(src, NW_ID_UNKNOWN) dst_nw_id = self.mac2net.get_network(dst, NW_ID_UNKNOWN) # we handle multicast packet as same as broadcast broadcast = (dst == mac.BROADCAST) or mac.is_multicast(dst) out_port = self.mac2port.port_get(datapath.id, dst) # # there are several combinations: # in_port: known nw_id, external, unknown nw, # src mac: known nw_id, external, unknown nw, # dst mac: known nw_id, external, unknown nw, and broadcast/multicast # where known nw_id: is quantum network id # external: means that these ports are connected to outside # unknown nw: means that we don't know this port is bounded to # specific nw_id or external # broadcast: the destination mac address is broadcast address # (or multicast address) # # Can the following logic be refined/shortened? # # When NW_ID_UNKNOWN is found, registering ports might be delayed. # So just drop only this packet and not install flow entry. # It is expected that when next packet arrives, the port is registers # with some network id if port_nw_id != NW_ID_EXTERNAL and port_nw_id != NW_ID_UNKNOWN: if broadcast: # flood to all ports of external or src_nw_id self._flood_to_nw_id(msg, src, dst, src_nw_id) elif src_nw_id == NW_ID_EXTERNAL: self._modflow_and_drop_packet(msg, src, dst) return elif src_nw_id == NW_ID_UNKNOWN: self._drop_packet(msg) return else: # src_nw_id != NW_ID_EXTERNAL and src_nw_id != NW_ID_UNKNOWN: # # try learned mac check if the port is net_id # or # flood to all ports of external or src_nw_id self._learned_mac_or_flood_to_nw_id(msg, src, dst, src_nw_id, out_port) elif port_nw_id == NW_ID_EXTERNAL: if src_nw_id != NW_ID_EXTERNAL and src_nw_id != NW_ID_UNKNOWN: if broadcast: # flood to all ports of external or src_nw_id self._flood_to_nw_id(msg, src, dst, src_nw_id) elif (dst_nw_id != NW_ID_EXTERNAL and dst_nw_id != NW_ID_UNKNOWN): if src_nw_id == dst_nw_id: # try learned mac # check if the port is external or same net_id # or # flood to all ports of external or src_nw_id self._learned_mac_or_flood_to_nw_id( msg, src, dst, src_nw_id, out_port) else: # should not occur? LOG.debug("should this case happen?") self._drop_packet(msg) elif dst_nw_id == NW_ID_EXTERNAL: # try learned mac # or # flood to all ports of external or src_nw_id self._learned_mac_or_flood_to_nw_id( msg, src, dst, src_nw_id, out_port) else: assert dst_nw_id == NW_ID_UNKNOWN LOG.debug("Unknown dst_nw_id") self._drop_packet(msg) elif src_nw_id == NW_ID_EXTERNAL: self._modflow_and_drop_packet(msg, src, dst) else: # should not occur? assert src_nw_id == NW_ID_UNKNOWN self._drop_packet(msg) else: # drop packets assert port_nw_id == NW_ID_UNKNOWN self._drop_packet(msg)
def haddr_to_str(self, addr): return mac.haddr_to_str(addr)
def __str__(self): return ('EventVMPort<dpid %s port_no %d ' 'network_id %s tunnel_key %s mac %s add_del %s>' % (dpid_lib.dpid_to_str(self.dpid), self.port_no, self.network_id, self.tunnel_key, mac.haddr_to_str(self.mac_address), self.add_del))
def match_to_str(ofmatch): keys = {ofproto_v1_3.OXM_OF_IN_PORT: 'in_port', ofproto_v1_3.OXM_OF_IN_PHY_PORT: 'in_phy_port', ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src', ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst', ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type', ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan', ofproto_v1_3.OXM_OF_VLAN_PCP: 'vlan_pcp', ofproto_v1_3.OXM_OF_IP_DSCP: 'ip_dscp', ofproto_v1_3.OXM_OF_IP_ECN: 'ip_ecn', ofproto_v1_3.OXM_OF_IPV4_SRC: 'nw_src', ofproto_v1_3.OXM_OF_IPV4_DST: 'nw_dst', ofproto_v1_3.OXM_OF_IPV4_SRC_W: 'nw_src', ofproto_v1_3.OXM_OF_IPV4_DST_W: 'nw_dst', ofproto_v1_3.OXM_OF_IP_PROTO: 'nw_proto', ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src', ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst', ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src', ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst', ofproto_v1_3.OXM_OF_SCTP_SRC: 'sctp_src', ofproto_v1_3.OXM_OF_SCTP_DST: 'sctp_dst', ofproto_v1_3.OXM_OF_ICMPV4_TYPE: 'icmpv4_type', ofproto_v1_3.OXM_OF_ICMPV4_CODE: 'icmpv4_code', ofproto_v1_3.OXM_OF_MPLS_LABEL: 'mpls_label', ofproto_v1_3.OXM_OF_MPLS_TC: 'mpls_tc', ofproto_v1_3.OXM_OF_MPLS_BOS: 'mpls_bos', ofproto_v1_3.OXM_OF_METADATA: 'metadata', ofproto_v1_3.OXM_OF_METADATA_W: 'metadata', ofproto_v1_3.OXM_OF_STATE: 'state', ofproto_v1_3.OXM_OF_FLAGS: 'flags', ofproto_v1_3.OXM_OF_FLAGS_W: 'flags', ofproto_v1_3.OXM_OF_ARP_OP: 'arp_op', ofproto_v1_3.OXM_OF_ARP_SPA: 'arp_spa', ofproto_v1_3.OXM_OF_ARP_TPA: 'arp_tpa', ofproto_v1_3.OXM_OF_ARP_SPA_W: 'arp_spa', ofproto_v1_3.OXM_OF_ARP_TPA_W: 'arp_tpa', ofproto_v1_3.OXM_OF_ARP_SHA: 'arp_sha', ofproto_v1_3.OXM_OF_ARP_THA: 'arp_tha', ofproto_v1_3.OXM_OF_IPV6_SRC: 'ipv6_src', ofproto_v1_3.OXM_OF_IPV6_DST: 'ipv6_dst', ofproto_v1_3.OXM_OF_IPV6_SRC_W: 'ipv6_src', ofproto_v1_3.OXM_OF_IPV6_DST_W: 'ipv6_dst', ofproto_v1_3.OXM_OF_IPV6_FLABEL: 'ipv6_flabel', ofproto_v1_3.OXM_OF_ICMPV6_TYPE: 'icmpv6_type', ofproto_v1_3.OXM_OF_ICMPV6_CODE: 'icmpv6_code', ofproto_v1_3.OXM_OF_IPV6_ND_TARGET: 'ipv6_nd_target', ofproto_v1_3.OXM_OF_IPV6_ND_SLL: 'ipv6_nd_sll', ofproto_v1_3.OXM_OF_IPV6_ND_TLL: 'ipv6_nd_tll', ofproto_v1_3.OXM_OF_PBB_ISID: 'pbb_isid', ofproto_v1_3.OXM_OF_TUNNEL_ID: 'tunnel_id', ofproto_v1_3.OXM_OF_IPV6_EXTHDR: 'ipv6_exthdr'} match = {} for match_field in ofmatch.fields: key = keys[match_field.header] if key == 'dl_src' or key == 'dl_dst' or key == 'arp_sha' or \ key == 'arp_tha' or key == 'ipv6_nd_tll' or \ key == 'ipv6_nd_sll': value = mac.haddr_to_str(match_field.value) elif key == 'nw_src' or key == 'nw_dst' or \ key == 'arp_spa' or key == 'arp_tpa': value = match_ip_to_str(match_field.value, match_field.mask) elif key == 'ipv6_src' or key == 'ipv6_dst': value = match_ipv6_to_str(match_field.value, match_field.mask) elif key == 'metadata': value = ('%d/%d' % (match_field.value, match_field.mask) if match_field.mask else '%d' % match_field.value) else: value = match_field.value match.setdefault(key, value) return match
def sample_first_block_later(self, stats): # DST flow with slightly higher priority ofproto = datapath.ofproto dst_mac = stats.match.dl_dst if not dst_mac == self.gateway_mac: dst_match = datapath.ofproto_parser.OFPMatch( dl_src=self.gateway_mac, dl_dst=dst_mac) dst_actions = stats.actions dst_actions.append( datapath.ofproto_parser.OFPActionOutput(monitor_port)) dst_flow = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=dst_match, cookie=random_int(), command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=2, priority=0x6001, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=dst_actions) datapath.send_msg(dst_flow) outgoing_block_mode_v2_dict[(haddr_to_str(dst_mac))] = [] # Time of installing first sample flow. outgoing_block_mode_v2_dict[(haddr_to_str(dst_mac))].append( int(time.time() * 1000)) # Not sampling this flow for now. Could check relation between outgoing requests # and incoming responses if we sampled this. src_mac = stats.match.dl_dst if not src_mac == self.gateway_mac: src_match = datapath.ofproto_parser.OFPMatch( dl_src=src_mac, dl_dst=self.gateway_mac) src_actions = [ datapath.ofproto_parser.OFPActionOutput(self.gateway_port) ] src_flow = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=src_match, cookie=random_int(), command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=2, priority=0x6001, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=src_actions) datapath.send_msg(src_flow) #SRC BLOCK FLOW src_mac = stats.match.dl_dst if not src_mac == self.gateway_mac: src_match = datapath.ofproto_parser.OFPMatch( dl_src=src_mac, dl_dst=self.gateway_mac) src_flow = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=src_match, cookie=random_int(), command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=3, priority=0x6000, flags=ofproto.OFPFF_SEND_FLOW_REM) datapath.send_msg(src_flow) # Time of installing DROP flow. We do not want to count packets after this flow expired # (3 seconds from this moment on) outgoing_block_mode_v2_dict[(haddr_to_str(dst_mac))].append( int(time.time() * 1000)) # DST BLOCK FLOW - We only sample this flow for 1 second, # destination does not receive anything. dst_mac = stats.match.dl_dst if not dst_mac == self.gateway_mac: dst_match = datapath.ofproto_parser.OFPMatch( dl_src=self.gateway_mac, dl_dst=dst_mac) dst_actions = [ datapath.ofproto_parser.OFPActionOutput(monitor_port) ] dst_flow = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=dst_match, cookie=random_int(), command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=3, priority=0x6000, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=dst_actions) datapath.send_msg(dst_flow)