def _add_random_trial_rule(self, dpid): datapath = self.datapaths[dpid] ofproto = datapath.ofproto parser = datapath.ofproto_parser bound_MAC = 5000 bound_Mask = 4 match = parser.OFPMatch(in_port=1) MAC = random.randint(bound_MAC, bound_MAC + 2**bound_Mask - 1) haddr = "00:00:00:00:" + "{:02d}".format( MAC / 100) + ":" + "{:02d}".format(MAC % 100) mask = "ff:ff:ff:ff:ff:f" + hex(0xf << random.randint(0, 4) & 0xf)[2:] self.logger.info("trying... mac: " + haddr + " mask: " + mask) haddr = haddr_to_bin(haddr) mask = haddr_to_bin(mask) match.set_dl_dst_masked(haddr, mask) actions = [parser.OFPActionOutput(2, 65535)] inst = [ parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] mod = parser.OFPFlowMod(datapath=datapath, priority=100, cookie=1, cookie_mask=1, match=match, instructions=inst) return haddr, mask
def add_flow(self, datapath, in_port, eth, ip_v4, actions): ofproto = datapath.ofproto idleTimeout = 2 hardTimeout = 2 if(ip_v4): nw_src = self.ipv4_text_to_int(ip_v4.src) nw_dst = self.ipv4_text_to_int(ip_v4.dst) match = datapath.ofproto_parser.OFPMatch( in_port=in_port, dl_type=eth.ethertype, dl_src=haddr_to_bin(eth.src), dl_dst=haddr_to_bin(eth.dst), nw_proto=ip_v4.proto, nw_src=nw_src, nw_dst=nw_dst, ) else: match = datapath.ofproto_parser.OFPMatch( in_port=in_port, dl_type=eth.ethertype, dl_src=haddr_to_bin(eth.src), dl_dst=haddr_to_bin(eth.dst),) idleTimeout = 2 hardTimeout = 2 mod = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=match, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=idleTimeout, hard_timeout=hardTimeout, priority=ofproto.OFP_DEFAULT_PRIORITY, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) datapath.send_msg(mod)
def __init__(self, flags=0, root_priority=DEFAULT_BRIDGE_PRIORITY, root_system_id_extension=0, root_mac_address=haddr_to_bin('00:00:00:00:00:00'), root_path_cost=0, bridge_priority=DEFAULT_BRIDGE_PRIORITY, bridge_system_id_extension=0, bridge_mac_address=haddr_to_bin('00:00:00:00:00:00'), port_priority=DEFAULT_PORT_PRIORITY, port_number=0, message_age=0, max_age=DEFAULT_MAX_AGE, hello_time=DEFAULT_HELLO_TIME, forward_delay=DEFAULT_FORWARD_DELAY): self.flags = flags self.root_priority = root_priority self.root_system_id_extension = root_system_id_extension self.root_mac_address = root_mac_address self.root_path_cost = root_path_cost self.bridge_priority = bridge_priority self.bridge_system_id_extension = bridge_system_id_extension self.bridge_mac_address = bridge_mac_address self.port_priority = port_priority self.port_number = port_number self.message_age = message_age self.max_age = max_age self.hello_time = hello_time self.forward_delay = forward_delay super(ConfigurationBPDUs, self).__init__()
def rewrite_gw_patch(datapath, port_a, port_g, auth_mac, gw_mac, priority=0): ofproto = datapath.ofproto parser = datapath.ofproto_parser """ GUESTLAN -> AUTHLAN 認証サーバ意外へのパケットは全てMACアドレスを書き換えて、認証サーバへ AUTHLAN -> GUESTLAN 認証サーバ意外へ宛先が向いていたパケットをゲートウェイのMACアドレスに書き換え返す """ """ 1.認証サーバをGWとすり替えるエントリの追加 """ match_a = parser.OFPMatch(in_port=port_a, eth_type=0x800, ip_proto=inet.IPPROTO_TCP, tcp_src=80) match_g = parser.OFPMatch(in_port=port_g, eth_type=0x800, ip_proto=inet.IPPROTO_TCP, tcp_dst=80) action_a = parser.OFPMatchField.make(ofproto.OXM_OF_ETH_SRC, haddr_to_bin(gw_mac)) action_g = parser.OFPMatchField.make(ofproto.OXM_OF_ETH_DST, haddr_to_bin(auth_mac)) actions_a = [parser.OFPActionSetField(action_a), parser.OFPActionOutput(port_g)] actions_g = [parser.OFPActionSetField(action_g), parser.OFPActionOutput(port_a)] inst_a = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions_a)] inst_g = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions_g)] mod_a = parser.OFPFlowMod(datapath=datapath, priority=priority, match=match_a, instructions=inst_a) mod_g = parser.OFPFlowMod(datapath=datapath, priority=priority, match=match_g, instructions=inst_g) datapath.send_msg(mod_a) datapath.send_msg(mod_g)
def _nwtp_forwarding(self, ev): msg = ev.msg datapath = msg.datapath dpid = msg.datapath.id ofproto = datapath.ofproto pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) nw_pkt = pkt.get_protocol(ipv4.ipv4) tp_pkt = pkt.get_protocol(tcp.tcp) dlsrc = eth.src dldst = eth.dst nwsrc = nw_pkt.src nwdst = nw_pkt.dst tpsrc = tp_pkt.src_port tpdst = tp_pkt.dst_port if not dldst in self.mac_to_port[dpid]: return True outport = self.mac_to_port[dpid][dldst] match = datapath.ofproto_parser.OFPMatch(dl_src=haddr_to_bin(dlsrc), dl_dst=haddr_to_bin(dldst), dl_type=self.IP_TYPE, nw_src=ipv4_to_int(nwsrc), nw_dst=ipv4_to_int(nwdst), nw_proto=self.TCP_PROTO, tp_src=tpsrc, tp_dst=tpdst) actions = [datapath.ofproto_parser.OFPActionOutput(outport)] self.add_flow(datapath, self.nwtp_priority, match, actions) return False
def add_flow(self, datapath, in_port, dst, src, actions, out_port): flowtabeltrace = [ datapath.id, src, dst, in_port, out_port, float(time.time() - T0) ] with open('flowtable.trace', 'a') as f: f.write(make_flow_trace(flowtabeltrace)) ofproto = datapath.ofproto match = datapath.ofproto_parser.OFPMatch(in_port=in_port, dl_dst=haddr_to_bin(dst), dl_src=haddr_to_bin(src)) mod = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=match, 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_msg(mod)
def Configure_stateful_FW(self, msg): pkt = packet.Packet(msg.data) datapath = msg.datapath eth = pkt.get_protocol(ethernet.ethernet) hwdst = eth.dst hwsrc = eth.src # Forward all arp if eth.ethertype == ETH_ARP: if msg.in_port == 2: self.forwardPacket(msg, 1) if msg.in_port == 1: self.forwardPacket(msg, 2) # Forward packets from inside to outside and also install the reverse rule with idle_to=5 sec elif msg.in_port == 2: match = datapath.ofproto_parser.OFPMatch( in_port=FW_INPORT, dl_type=ETH_IP, dl_src=haddr_to_bin(hwsrc), dl_dst=haddr_to_bin(hwdst)) actions = [datapath.ofproto_parser.OFPActionOutput(FW_OUTPORT)] self.add_flow(datapath, match, actions, 8, 0) match = datapath.ofproto_parser.OFPMatch( in_port=FW_OUTPORT, dl_type=ETH_IP, dl_src=haddr_to_bin(hwdst), dl_dst=haddr_to_bin(hwsrc)) actions = [datapath.ofproto_parser.OFPActionOutput(FW_INPORT)] self.add_flow(datapath, match, actions, 8, 0) # forward the packet self.forwardPacket(msg, 1)
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(ofproto_v1_0_parser.OFPActionSetDlSrc(haddr_to_bin(actions['srcmac']))) if 'dstmac' in actions: of_actions.append(ofproto_v1_0_parser.OFPActionSetDlDst(haddr_to_bin(actions['dstmac']))) if 'srcip' in actions: of_actions.append(ofproto_v1_0_parser.OFPActionSetNwSrc(self.ipv4_to_int(actions['srcip']))) if 'dstip' in actions: of_actions.append(ofproto_v1_0_parser.OFPActionSetNwDst(self.ipv4_to_int(actions['dstip']))) if 'srcport' in actions: of_actions.append(ofproto_v1_0_parser.OFPActionSetTpSrc(actions['srcport'])) if 'dstport' in actions: of_actions.append(ofproto_v1_0_parser.OFPActionSetTpDst(actions['dstport'])) if 'vlan_id' in actions: if actions['vlan_id'] is None: of_actions.append(ofproto_v1_0_parser.OFPActionStripVlan()) else: of_actions.append(ofproto_v1_0_parser.OFPActionVlanVid(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(ofproto_v1_0_parser.OFPActionVlanPcp(vlan_pcp=actions['vlan_pcp'])) if (not inport is None) and (outport == inport): of_actions.append(ofproto_v1_0_parser.OFPActionOutput(ofproto_v1_0.OFPP_IN_PORT)) else: of_actions.append(ofproto_v1_0_parser.OFPActionOutput(outport)) return of_actions
def add_flow(self, datapath, in_port, actions, dst, src, ipv4_dst=None, ipv4_src=None): ofproto = datapath.ofproto match = datapath.ofproto_parser.OFPMatch(nw_dst=ipv4_dst, nw_src=ipv4_src, in_port=in_port, dl_dst=haddr_to_bin(dst), dl_src=haddr_to_bin(src)) mod = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=match, 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_msg(mod)
def _build_vlan(self): src_mac = mac.haddr_to_bin('00:07:0d:af:f4:54') dst_mac = mac.haddr_to_bin('00:00:00:00:00:00') ethertype = ether.ETH_TYPE_8021Q e = ethernet(dst_mac, src_mac, ethertype) version = 4 header_length = 20 tos = 0 total_length = 24 identification = 0x8a5d flags = 0 offset = 1480 ttl = 64 proto = inet.IPPROTO_ICMP csum = 0xa7f2 src = int(netaddr.IPAddress('131.151.32.21')) dst = int(netaddr.IPAddress('131.151.32.129')) option = 'TEST' ip = ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) p = Packet() p.add_protocol(e) p.add_protocol(self.v) p.add_protocol(ip) p.serialize() return p
def build_of_match(self,datapath,inport,pred): ### BUILD OF MATCH rule = OF10Match() if inport != None: rule.in_port = inport if 'srcmac' in pred: rule.dl_src = haddr_to_bin(pred['srcmac']) if 'dstmac' in pred: rule.dl_dst = haddr_to_bin(pred['dstmac']) if 'ethtype' in pred: rule.dl_type = pred['ethtype'] if 'vlan_id' in pred: rule.dl_vlan = pred['vlan_id'] if 'vlan_pcp' in pred: rule.dl_vlan_pcp = pred['vlan_pcp'] if 'protocol' in pred: rule.nw_proto = pred['protocol'] if 'srcip' in pred: rule.nw_src = self.ipv4_to_int(pred['srcip']) if 'dstip' in pred: rule.nw_dst = self.ipv4_to_int(pred['dstip']) if 'tos' in pred: rule.nw_tos = pred['tos'] if 'srcport' in pred: rule.tp_src = pred['srcport'] if 'dstport' in pred: rule.tp_dst = pred['dstport'] match_tuple = rule.match_tuple() match = datapath.ofproto_parser.OFPMatch(*match_tuple) return match
def _mod_routing_flow(self, command, cookie, priority, out_port, dl_vlan=0, nw_src=0, src_mask=32, nw_dst=0, dst_mask=32, src_mac=0, dst_mac=0, idle_timeout=0, dec_ttl=False, eth_type=ether.ETH_TYPE_IP, in_port=None, out_group=None): ofp_parser = self.dp.ofproto_parser actions = [] if dec_ttl: actions.append(ofp_parser.NXActionDecTtl()) if src_mac: if type(src_mac) == str: src_mac = haddr_to_bin(src_mac) actions.append(ofp_parser.OFPActionSetDlSrc(src_mac)) if dst_mac: if type(dst_mac) == str: dst_mac = haddr_to_bin(dst_mac) actions.append(ofp_parser.OFPActionSetDlDst(dst_mac)) if out_port is not None: actions.append(ofp_parser.OFPActionOutput(out_port)) if out_group is not None: self.logger.warning('Group is not supported in OFP: %d', self.ofp.OFP_VERSION) self._mod_flow(command, cookie, priority, eth_type=eth_type, dl_vlan=dl_vlan, nw_src=nw_src, src_mask=src_mask, nw_dst=nw_dst, dst_mask=dst_mask, idle_timeout=idle_timeout, actions=actions, in_port=in_port)
def to_actions(dp, acts): actions = [] for a in acts: action_type = a.get('type') if action_type == 'OUTPUT': out_port = int(a.get('port', ofproto_v1_0.OFPP_NONE)) max_len = int(a.get('max_len', 65535)) actions.append(dp.ofproto_parser.OFPActionOutput( out_port, max_len=max_len)) elif action_type == 'SET_VLAN_VID': vlan_vid = int(a.get('vlan_vid', 0xffff)) actions.append(dp.ofproto_parser.OFPActionVlanVid(vlan_vid)) elif action_type == 'SET_VLAN_PCP': vlan_pcp = int(a.get('vlan_pcp', 0)) actions.append(dp.ofproto_parser.OFPActionVlanPcp(vlan_pcp)) elif action_type == 'STRIP_VLAN': actions.append(dp.ofproto_parser.OFPActionStripVlan()) elif action_type == 'SET_DL_SRC': dl_src = haddr_to_bin(a.get('dl_src')) actions.append(dp.ofproto_parser.OFPActionSetDlSrc(dl_src)) elif action_type == 'SET_DL_DST': dl_dst = haddr_to_bin(a.get('dl_dst')) actions.append(dp.ofproto_parser.OFPActionSetDlDst(dl_dst)) else: LOG.debug('Unknown action type') return actions
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser msg = ev.msg print 'OFPSwitchFeatures receive: datapath_id=0x%016x n_buffers=%d n_tables=%d auxiliary_id=%d capabilities=0x%08x' % (msg.datapath_id, msg.n_buffers, msg.n_tables,msg.auxiliary_id, msg.capabilities) # install table-miss flow entry # # We specify NO BUFFER to max_len of the output action due to # OVS bug. At this moment, if we specify a lesser number, e.g., # 128, OVS will send Packet-In with invalid buffer_id and # truncated packet data. In that case, we cannot output packets # correctly. match = parser.OFPMatch() actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,max_len=40)] self.add_flow(datapath, 0, match, actions,0) match1 = parser.OFPMatch() mac_src1 = mac.haddr_to_bin('00:00:00:00:00:00') mac_dst1 = mac.haddr_to_bin('00:00:00:00:00:01') mac_mask = mac.haddr_to_bin('ff:ff:ff:ff:ff:ff') match1.set_dl_src_masked(mac_src1,mac_mask) match1.set_dl_dst_masked(mac_dst1,mac_mask) actions1 = [parser.OFPActionOutput(port=2)] self.add_flow(datapath,0,match1,actions1,0) match2 = parser.OFPMatch() mac_src2 = mac.haddr_to_bin('00:00:00:00:00:01') mac_dst2 = mac.haddr_to_bin('00:00:00:00:00:00') match2.set_dl_src_masked(mac_src2,mac_mask) match2.set_dl_dst_masked(mac_dst2,mac_mask) actions2 = [parser.OFPActionOutput(port=1)] self.add_flow(datapath,1,match2,actions2,0)
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto SERVER_MAC = mac.haddr_to_bin('00:00:00:00:00:42') HOST_MAC = mac.haddr_to_bin('00:00:00:00:00:41') SERVER_IP = int(netaddr.IPAddress('192.168.1.2')) HOST_IP = int(netaddr.IPAddress('192.168.1.1')) ip_to_mac= {SERVER_IP:SERVER_MAC, HOST_IP:HOST_MAC} pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return if eth.ethertype == ether_types.ETH_TYPE_ARP: p_arp = self._find_protocol(pkt, "arp") p_ipv4 = self._find_protocol(pkt, "ipv4") if p_arp: src_ip = str(netaddr.IPAddress(p_arp.src_ip)) dst_ip = str(netaddr.IPAddress(p_arp.dst_ip)) if p_arp.opcode == arp.ARP_REQUEST : LOG.debug("--- PacketIn: ARP_Request: %s->%s", src_ip, dst_ip) if p_arp.dst_ip == SERVER_IP) or (p_arp.dst_ip == HOST_IP) : LOG.debug("--- send Pkt: ARP_Reply") data = self._arp_reply(p_arp.src_ip, p_arp.dst_ip) self._send_msg(dp, data) elif p_arp.opcode == arp.ARP_REPLY: LOG.debug("--- PacketIn: ARP_Reply: %s->%s", src_ip, dst_ip) LOG.debug("--- send Pkt: Echo_Request") return
def _make_bum_match(self, metadata): match = self.parser.OFPMatch() match.set_metadata(metadata) encoded_mac = mac_api.haddr_to_bin(mac_api.DONTCARE_STR) encoded_mask = mac_api.haddr_to_bin(mac_api.UNICAST) match.set_dl_dst_masked(encoded_mac, encoded_mask) return match
def _to_match_eth(value): eth_mask = value.split('/') # MAC address eth = mac.haddr_to_bin(eth_mask[0]) # mask mask = mac.haddr_to_bin('ff:ff:ff:ff:ff:ff') if len(eth_mask) == 2: mask = mac.haddr_to_bin(eth_mask[1]) return eth, mask
def block_traffic_by_default(self, dp): ofproto = dp.ofproto parser = dp.ofproto_parser match = parser.OFPMatch(dl_type=ether.ETH_TYPE_IP, dl_src=haddr_to_bin("00:00:00:00:00:02"), dl_dst=haddr_to_bin("00:00:00:00:00:03")) mod = parser.OFPFlowMod(datapath = dp, match = match, cookie=0, command=ofproto.OFPFC_ADD, hard_timeout = 0, priority=ofproto.OFP_DEFAULT_PRIORITY, actions = []) dp.send_msg(mod) secondmatch = parser.OFPMatch(dl_type=ether.ETH_TYPE_IP, dl_dst=haddr_to_bin("00:00:00:00:00:03"), dl_src=haddr_to_bin("00:00:00:00:00:02")) mod = parser.OFPFlowMod(datapath = dp, match = secondmatch, cookie=0, command=ofproto.OFPFC_ADD, hard_timeout = 0, priority=ofproto.OFP_DEFAULT_PRIORITY, actions = []) dp.send_msg(mod)
def to_ofp_match(self): kwargs = self.__dict__.copy() if self.dl_src is not None: kwargs["dl_src"] = haddr_to_bin(self.dl_src) if self.dl_dst is not None: kwargs["dl_dst"] = haddr_to_bin(self.dl_dst) return OFPMatch(**kwargs)
def build_rule(in_port=None, nw_dst=None, nw_src=None, nw_proto=None, dl_dst=None, dl_src=None, registers=None, tun_id=None, dl_type=None): rule = ClsRule() if in_port is not None: rule.set_in_port(in_port) if dl_dst is not None: dl_dst = haddr_to_bin(dl_dst) rule.set_dl_dst(dl_dst) if dl_src is not None: dl_src = haddr_to_bin(dl_src) rule.set_dl_src(dl_src) if dl_type is None and (nw_dst is not None or nw_src is not None): dl_type = ether_types.ETH_TYPE_IP if dl_type is not None: rule.set_dl_type(dl_type) if nw_dst is not None: if isinstance(nw_dst, dict): nw_dst = nw_dst['destination'] if isinstance(nw_dst, six.string_types): nw_dst = ip.ipv4_to_int(nw_dst) if isinstance(nw_dst, tuple): rule.set_nw_dst_masked(nw_dst[0], nw_dst[1]) else: rule.set_nw_dst(nw_dst) if nw_src is not None: if isinstance(nw_src, dict): nw_src = nw_src['destination'] if isinstance(nw_src, six.string_types): nw_src = ip.ipv4_to_int(nw_src) if isinstance(nw_src, tuple): rule.set_nw_src_masked(nw_src[0], nw_src[1]) else: rule.set_nw_src(nw_src) if registers is not None: for k, v in registers.iteritems(): rule.set_reg(k, v) if tun_id is not None: rule.set_tun_id(tun_id) if nw_proto is not None: rule.set_nw_proto(nw_proto) return rule
def add_flow_eth(self, datapath, msg, flow_actions, **kwargs): """ Add an ethernet (non-IP) flow table entry to a switch. Returns 1 for success or 0 for any type of error Required kwargs are: priority (0) buffer_id (None) idle_timeout (5) hard_timeout (0) Uses Ethertype in match to prevent matching against IPv4 or IPv6 flows """ ofproto = datapath.ofproto parser = datapath.ofproto_parser pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) in_port=flow_actions['in_port'] idle_timeout=kwargs['idle_timeout'] hard_timeout=kwargs['hard_timeout'] buffer_id=kwargs['buffer_id'] priority=kwargs['priority'] #*** Build a match that is dependant on the IP and OpenFlow versions: if (eth.ethertype != 0x0800 and ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION): match = self.get_flow_match(datapath, ofproto.OFP_VERSION, in_port=in_port, dl_src=haddr_to_bin(eth.src), dl_dst=haddr_to_bin(eth.dst), dl_type=eth.ethertype) self.logger.debug("event=add_flow ofv=%s match_type=Non-IP " "match=%s", ofproto.OFP_VERSION, match) elif (eth.ethertype != 0x0800 and ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION): match = self.get_flow_match(datapath, ofproto.OFP_VERSION, in_port=in_port, dl_src=eth.src, dl_dst=eth.dst, dl_type=eth.ethertype) self.logger.debug("event=add_flow ofv=%s match_type=Non-IP " "match=%s", ofproto.OFP_VERSION, match) else: #*** Possibly an unsupported OF version. Log and return 0: self.logger.error("event=add_flow error=E1000028 Did not compute. " "ofv=%s pkt=%s", ofproto.OFP_VERSION, pkt) return 0 #*** Get the actions to install for the match: actions = self.get_actions(datapath, ofproto.OFP_VERSION, flow_actions['out_port'], flow_actions['out_queue']) self.logger.debug("actions=%s", actions) #*** Now have a match and actions so call add_flow to instantiate it: _result = self.add_flow(datapath, match, actions, priority=priority, buffer_id=buffer_id, idle_timeout=idle_timeout, hard_timeout=hard_timeout) self.logger.debug("result is %s", _result) return _result
class Test_ethernet(unittest.TestCase): """ Test case for ethernet """ dst = mac.haddr_to_bin('AA:AA:AA:AA:AA:AA') src = mac.haddr_to_bin('BB:BB:BB:BB:BB:BB') ethertype = ether.ETH_TYPE_ARP length = struct.calcsize(ethernet._PACK_STR) buf = pack(ethernet._PACK_STR, dst, src, ethertype) e = ethernet(dst, src, ethertype) def setUp(self): pass def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): eq_(self.dst, self.e.dst) eq_(self.src, self.e.src) eq_(self.ethertype, self.e.ethertype) eq_(self.length, self.e.length) def test_parser(self): res, ptype = self.e.parser(self.buf) LOG.debug((res, ptype)) eq_(res.dst, self.dst) eq_(res.src, self.src) eq_(res.ethertype, self.ethertype) eq_(res.length, self.length) eq_(ptype, arp) def test_serialize(self): data = bytearray() prev = None buf = self.e.serialize(data, prev) fmt = ethernet._PACK_STR res = struct.unpack(fmt, buf) eq_(res[0], self.dst) eq_(res[1], self.src) eq_(res[2], self.ethertype) @raises(Exception) def test_malformed_ethernet(self): m_short_buf = self.buf[1:ethernet._MIN_LEN] ethernet.parser(m_short_buf)
def flowmod(self, fm_type='ADD', src=None, dst=None, in_port=None, match=None, out_port=None, vlan_action=None, vlan_id=None, priority=OFP_LW_PRIORITY): if match is None: match = self._ofproto_parser.OFPMatch(dl_src=haddr_to_bin(src), dl_dst=haddr_to_bin(dst), in_port=in_port) else: match = self._ofproto_parser.OFPMatch(**match) if fm_type == 'ADD': actions = [self._dp.ofproto_parser.OFPActionOutput(out_port)] if vlan_action == 'encap': actions.insert( 0, self._dp.ofproto_parser.OFPActionVlanVid(vlan_id)) if vlan_action == 'decap': actions.insert(0, self._dp.ofproto_parser.OFPActionStripVlan()) mod = self._ofproto_parser.OFPFlowMod( datapath=self._dp, match=match, cookie=0, command=self._ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=priority, flags=self._ofproto.OFPFF_SEND_FLOW_REM, actions=actions) self._dp.send_msg(mod) return mod if fm_type == 'DEL': mod = self._ofproto_parser.OFPFlowMod( datapath=self._dp, match=match, cookie=0, command=self._ofproto.OFPFC_DELETE) self._dp.send_msg(mod) return mod
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) 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, {}) self.logger.info("packet in %s %s %s %s", dpid, src, 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] # install a flow to avoid packet_in next time #ARP Packets...................................................................... if eth.ethertype == ETH_ARP: match = datapath.ofproto_parser.OFPMatch(in_port=msg.in_port, dl_type = ETH_ARP, dl_src=haddr_to_bin(src), dl_dst=haddr_to_bin(dst)) self.add_flow(datapath, match, out_port, 5, 0) self.forwardPacket(msg, out_port) # IP Packets....................................................................... if eth.ethertype == ETH_IP: match = datapath.ofproto_parser.OFPMatch(in_port=msg.in_port, dl_type = ETH_IP, dl_src=haddr_to_bin(src), dl_dst=haddr_to_bin(dst)) if (msg.in_port in FW_INPORTS) or (self.match_in_states(out_port, match, datapath)): if msg.in_port in FW_INPORTS: self.add_match_state(out_port, match) self.add_flow(datapath, match, out_port, 5, 0) self.forwardPacket(msg, out_port) else : #DROP packets #add flow and packet_out with no actions self.add_flow(datapath, match, None, 5, 0) #flood packet if ARP.................................................................. else: out_port = ofproto.OFPP_FLOOD if eth.ethertype == ETH_ARP: #if packet is ARP, foward packet (flood ports) self.forwardPacket(msg, out_port)
def to_match_eth(value): eth_mask = value.split("/") # MAC address eth = mac.haddr_to_bin(eth_mask[0]) # mask mask = mac.haddr_to_bin("ff:ff:ff:ff:ff:ff") if len(eth_mask) == 2: mask = mac.haddr_to_bin(eth_mask[1]) return eth, mask
def isaValidadSubnet(ipdest,ipsrc): if ipdest in self.ip_mac_port.keys(): masc= self.ip_mac_port[ipdest][0] hola = haddr_to_bin(masc) ip1bin = haddr_to_bin(ipdest) ip2bin = haddr_to_bin(ipsrc) for i in hola if(i==1) if ip1bin[i]!=ip2bin[i] return false return true
def add_flow2(self, datapath, in_port, src, dst, actions): ofproto = datapath.ofproto match = datapath.ofproto_parser.OFPMatch( in_port=in_port, dl_src = haddr_to_bin(src), dl_dst=haddr_to_bin(dst)) mod = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=match, 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_msg(mod)
def _add_flow(self, datapath, src, dst, out_port, actions=[]): ofproto = datapath.ofproto match = datapath.ofproto_parser.OFPMatch( dl_src=haddr_to_bin(src), dl_dst=haddr_to_bin(dst)) actions = actions + [datapath.ofproto_parser.OFPActionOutput(out_port)] mod = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=match, 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_msg(mod)
def to_actions(dp, acts): actions = [] for a in acts: action_type = a.get('type') if action_type == 'OUTPUT': port = UTIL.ofp_port_from_user( a.get('port', ofproto_v1_0.OFPP_NONE)) # NOTE: The reason of this magic number (0xffe5) # is because there is no good constant in of1.0. # The same value as OFPCML_MAX of of1.2 and of1.3 is used. max_len = str_to_int(a.get('max_len', 0xffe5)) actions.append(dp.ofproto_parser.OFPActionOutput(port, max_len)) elif action_type == 'SET_VLAN_VID': vlan_vid = str_to_int(a.get('vlan_vid', 0xffff)) actions.append(dp.ofproto_parser.OFPActionVlanVid(vlan_vid)) elif action_type == 'SET_VLAN_PCP': vlan_pcp = str_to_int(a.get('vlan_pcp', 0)) actions.append(dp.ofproto_parser.OFPActionVlanPcp(vlan_pcp)) elif action_type == 'STRIP_VLAN': actions.append(dp.ofproto_parser.OFPActionStripVlan()) elif action_type == 'SET_DL_SRC': dl_src = haddr_to_bin(a.get('dl_src')) actions.append(dp.ofproto_parser.OFPActionSetDlSrc(dl_src)) elif action_type == 'SET_DL_DST': dl_dst = haddr_to_bin(a.get('dl_dst')) actions.append(dp.ofproto_parser.OFPActionSetDlDst(dl_dst)) elif action_type == 'SET_NW_SRC': nw_src = ipv4_to_int(a.get('nw_src')) actions.append(dp.ofproto_parser.OFPActionSetNwSrc(nw_src)) elif action_type == 'SET_NW_DST': nw_dst = ipv4_to_int(a.get('nw_dst')) actions.append(dp.ofproto_parser.OFPActionSetNwDst(nw_dst)) elif action_type == 'SET_NW_TOS': nw_tos = str_to_int(a.get('nw_tos', 0)) actions.append(dp.ofproto_parser.OFPActionSetNwTos(nw_tos)) elif action_type == 'SET_TP_SRC': tp_src = str_to_int(a.get('tp_src', 0)) actions.append(dp.ofproto_parser.OFPActionSetTpSrc(tp_src)) elif action_type == 'SET_TP_DST': tp_dst = str_to_int(a.get('tp_dst', 0)) actions.append(dp.ofproto_parser.OFPActionSetTpDst(tp_dst)) elif action_type == 'ENQUEUE': port = UTIL.ofp_port_from_user( a.get('port', ofproto_v1_0.OFPP_NONE)) queue_id = UTIL.ofp_queue_from_user(a.get('queue_id', 0)) actions.append(dp.ofproto_parser.OFPActionEnqueue(port, queue_id)) else: LOG.error('Unknown action type') return actions
def to_actions(dp, acts): actions = [] for a in acts: action_type = a.get('type') if action_type == 'OUTPUT': port = UTIL.ofp_port_from_user( a.get('port', ofproto_v1_0.OFPP_NONE)) # NOTE: The reason of this magic number (0xffe5) # is because there is no good constant in of1.0. # The same value as OFPCML_MAX of of1.2 and of1.3 is used. max_len = int(a.get('max_len', 0xffe5)) actions.append(dp.ofproto_parser.OFPActionOutput(port, max_len)) elif action_type == 'SET_VLAN_VID': vlan_vid = int(a.get('vlan_vid', 0xffff)) actions.append(dp.ofproto_parser.OFPActionVlanVid(vlan_vid)) elif action_type == 'SET_VLAN_PCP': vlan_pcp = int(a.get('vlan_pcp', 0)) actions.append(dp.ofproto_parser.OFPActionVlanPcp(vlan_pcp)) elif action_type == 'STRIP_VLAN': actions.append(dp.ofproto_parser.OFPActionStripVlan()) elif action_type == 'SET_DL_SRC': dl_src = haddr_to_bin(a.get('dl_src')) actions.append(dp.ofproto_parser.OFPActionSetDlSrc(dl_src)) elif action_type == 'SET_DL_DST': dl_dst = haddr_to_bin(a.get('dl_dst')) actions.append(dp.ofproto_parser.OFPActionSetDlDst(dl_dst)) elif action_type == 'SET_NW_SRC': nw_src = ipv4_to_int(a.get('nw_src')) actions.append(dp.ofproto_parser.OFPActionSetNwSrc(nw_src)) elif action_type == 'SET_NW_DST': nw_dst = ipv4_to_int(a.get('nw_dst')) actions.append(dp.ofproto_parser.OFPActionSetNwDst(nw_dst)) elif action_type == 'SET_NW_TOS': nw_tos = int(a.get('nw_tos', 0)) actions.append(dp.ofproto_parser.OFPActionSetNwTos(nw_tos)) elif action_type == 'SET_TP_SRC': tp_src = int(a.get('tp_src', 0)) actions.append(dp.ofproto_parser.OFPActionSetTpSrc(tp_src)) elif action_type == 'SET_TP_DST': tp_dst = int(a.get('tp_dst', 0)) actions.append(dp.ofproto_parser.OFPActionSetTpDst(tp_dst)) elif action_type == 'ENQUEUE': port = UTIL.ofp_port_from_user( a.get('port', ofproto_v1_0.OFPP_NONE)) queue_id = UTIL.ofp_queue_from_user(a.get('queue_id', 0)) actions.append(dp.ofproto_parser.OFPActionEnqueue(port, queue_id)) else: LOG.error('Unknown action type') return actions
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 = eth.dst src = eth.src inport = msg.in_port dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) #self.logger.info("packet in %s %s %s %s", dpid, src, 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 # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: self.logger.info('flow mod---->src:%s,dst:%s', src, dst) if src in self.qos_list: match = datapath.ofproto_parser.OFPMatch( in_port=inport, dl_src=haddr_to_bin(src), dl_dst=haddr_to_bin(dst)) actions = [ datapath.ofproto_parser.OFPActionEnqueue(out_port, 1) ] self.add_flow(datapath, match, actions) else: match = datapath.ofproto_parser.OFPMatch( in_port=inport, dl_dst=haddr_to_bin(dst)) actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] self.add_flow(datapath, match, actions) action = [datapath.ofproto_parser.OFPActionOutput(out_port)] out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=action) datapath.send_msg(out)
def _install_network_flows_for_flat(self, physical_network, local_network_id): datapath = self.get_datapath() parser = datapath.ofproto_parser ofproto = datapath.ofproto match = parser.OFPMatch() addint = haddr_to_bin('00:00:00:00:00:00') add_mask_int = haddr_to_bin('01:00:00:00:00:00') match.set_dl_dst_masked(addint, add_mask_int) match.set_metadata(local_network_id) inst = [parser.OFPInstructionGotoTable(const.EGRESS_TABLE)] self.mod_flow(datapath=datapath, inst=inst, table_id=const.L2_LOOKUP_TABLE, priority=const.PRIORITY_MEDIUM, match=match) # EGRESS for Remote ports # Table=Egress match = parser.OFPMatch(metadata=local_network_id) goto_inst = parser.OFPInstructionGotoTable(const.EGRESS_EXTERNAL_TABLE) inst = [goto_inst] self.mod_flow(datapath=datapath, inst=inst, table_id=const.EGRESS_TABLE, priority=const.PRIORITY_LOW, match=match) # Add EGRESS port according to physical_network self._install_output_to_physical_patch(physical_network, local_network_id) # Ingress match = parser.OFPMatch(vlan_vid=0) actions = [parser.OFPActionSetField(metadata=local_network_id)] action_inst = parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) goto_inst = parser.OFPInstructionGotoTable( const.INGRESS_DESTINATION_PORT_LOOKUP_TABLE) inst = [action_inst, goto_inst] self.mod_flow(datapath=datapath, inst=inst, table_id=const.INGRESS_CLASSIFICATION_DISPATCH_TABLE, priority=const.PRIORITY_LOW, match=match)
def _packet_in_handler(self, ev): dl_type_ipv4 = 0x0800 msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) dst = eth.dst src = eth.src ipv4_pkt = pkt.get_protocol(ipv4.ipv4) dpid = datapath.id if ipv4_pkt: self.logger.info("packet in %s %s %s %s", dpid, ipv4_pkt.src, ipv4_pkt.dst, msg.in_port) match = parser.OFPMatch(dl_type=dl_type_ipv4, nw_src=self.ipv4_to_int(ipv4_pkt.src)) serverID = 2 #scheduler() actions = [ parser.OFPActionSetNwDst( self.ipv4_to_int(self.servers[serverID][1])), parser.OFPActionSetDlDst( haddr_to_bin(self.servers[serverID][2])), parser.OFPActionOutput(self.servers[serverID][0]) ] self.serverLoad[serverID] += 1 self.add_flow(datapath, match, actions, 1, 10, ofproto.OFPFF_SEND_FLOW_REM, 2) self.logger.info("Flow installed for client %s and serverID %d", ipv4_pkt.src, serverID) actions = [] actions.append( createOFAction(datapath, ofproto.OFPAT_OUTPUT, self.servers[serverID][0])) sendPacketOut(msg=msg, actions=actions, buffer_id=msg.buffer_id)
def __init__(self, hwtype=ARP_HW_TYPE_ETHERNET, proto=ether.ETH_TYPE_IP, hlen=6, plen=4, opcode=ARP_REQUEST, src_mac=mac.haddr_to_bin('ff:ff:ff:ff:ff:ff'), src_ip=ip.ipv4_to_bin('0.0.0.0'), dst_mac=mac.haddr_to_bin('ff:ff:ff:ff:ff:ff'), dst_ip=ip.ipv4_to_bin('0.0.0.0')): super(arp, self).__init__() self.hwtype = hwtype self.proto = proto self.hlen = hlen self.plen = plen self.opcode = opcode self.src_mac = src_mac self.src_ip = src_ip self.dst_mac = dst_mac self.dst_ip = dst_ip
def _del_multicast_broadcast_handling_for_port(self, network_id, lport_id): parser = self.dp.ofproto_parser ofproto = self.dp.ofproto command = self.dp.ofproto.OFPFC_MODIFY network = self.local_networks.get(network_id) if network is None: # TODO(gsagie) add error here return # TODO(gsagie) check if lport in network structure? del network[lport_id] self.local_networks[network_id] = network match = parser.OFPMatch(eth_dst='01:00:00:00:00:00') addint = haddr_to_bin('01:00:00:00:00:00') match.set_dl_dst_masked(addint, addint) match.set_metadata(network_id) actions = [] for tunnel_id in network.values(): actions.append(parser.OFPActionSetField(reg7=tunnel_id)) actions.append(parser.NXActionResubmitTable(OF_IN_PORT, 64)) inst = [self.dp.ofproto_parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)] self.mod_flow( self.dp, inst=inst, table_id=17, command=command, priority=200, match=match)
def remove_remote_port(self, lport_id, mac, network_id, tunnel_key): parser = self.dp.ofproto_parser ofproto = self.dp.ofproto # Remove destination classifier for port match = parser.OFPMatch() match.set_metadata(network_id) match.set_dl_dst(haddr_to_bin(mac)) msg = parser.OFPFlowMod(datapath=self.dp, cookie=0, cookie_mask=0, table_id=17, command=ofproto.OFPFC_DELETE, priority=100, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, match=match) self.dp.send_msg(msg) # Remove egress classifier for port match = parser.OFPMatch(reg7=tunnel_key) msg = parser.OFPFlowMod(datapath=self.dp, cookie=0, cookie_mask=0, table_id=64, command=ofproto.OFPFC_DELETE, priority=100, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, match=match) self.dp.send_msg(msg) self._del_multicast_broadcast_handling_for_port(network_id, lport_id)
def add_flow(self, datapath, in_port, dst, actions): """ Método responsável por adicionar um determinado fluxo em um switch. """ with self.dps_sem: # Adiciona o datapath na cache, caso ele ainda não esteja presente dpid = datapath.id if not dpid in self.dps: self.dps[dpid] = datapath self.logger.info("%s adding entry for switch %s [dst: %s, port %s]", timestamp(), datapath.id, dst, in_port) # Monta a mensagem OpenFlow para adicionar o fluxo no switch, # informando a porta que o pacote deve ser enviado caso o destino # seja igual a 'dst' ofproto = datapath.ofproto match = datapath.ofproto_parser.OFPMatch( in_port=in_port, dl_dst=haddr_to_bin(dst)) mod = datapath.ofproto_parser.OFPFlowMod( datapath=datapath, match=match, 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_msg(mod)
def __init__(self, *args, **kwargs): super(RyuController, self).__init__(*args, **kwargs) self.mac_to_port = {} self.flowstats = {} self.detected_flags = {} self.done = False self.byte_treshold = 500000 self.packet_treshold = 5000 self.detected_flags = {} if socket.gethostname() == 'lt-debian': self.gateway_port = 1 self.map_port_mac = { 3: '52:54:00:12:e9:0b', 1: '52:54:00:34:0d:1f', 65534: '32:32:7c:ac:49:42' } elif socket.gethostname() == 'OVS-Switch': self.gateway_port = 1 self.map_port_mac = { 1: '52:54:00:ee:6e:d7', 2: '52:54:00:2d:0f:99', 65534: '82:c8:6a:fe:33:4f' } else: self.gateway_port = 33 self.map_port_mac = { 32: '00:0c:29:a7:de:cd', 33: '00:0a:f7:1a:a9:34', 34: '00:1b:21:bd:dc:9d' } self.gateway_mac = haddr_to_bin(self.map_port_mac[self.gateway_port]) self.threads.append(hub.spawn(parser.run)) self.threads.append(hub.spawn(counter.run)) self.threads.append(hub.spawn(self.poller))
def _remove_local_port_pipeline_interface(self, lport): parser = self.parser ofproto = self.ofproto local_network_id = lport.lswitch.unique_key # Remove egress classifier for port match = parser.OFPMatch(reg7=lport.unique_key) self.mod_flow( table_id=const.EGRESS_TABLE, command=ofproto.OFPFC_DELETE, priority=const.PRIORITY_MEDIUM, match=match) # Remove ingress destination lookup for port match = parser.OFPMatch() match.set_metadata(local_network_id) match.set_dl_dst(haddr_to_bin(lport.mac)) self.mod_flow( table_id=const.INGRESS_DESTINATION_PORT_LOOKUP_TABLE, command=ofproto.OFPFC_DELETE, priority=const.PRIORITY_HIGH, match=match) # Update multicast and broadcast self._del_multicast_broadcast_handling_for_local( lport.id, lport.topic, local_network_id)
def remove_remote_port(self, lport): lport_id = lport.get_id() mac = lport.get_mac() network_id = lport.get_external_value('local_network_id') tunnel_key = lport.get_tunnel_key() parser = self.get_datapath().ofproto_parser ofproto = self.get_datapath().ofproto # Remove destination classifier for port match = parser.OFPMatch() match.set_metadata(network_id) match.set_dl_dst(haddr_to_bin(mac)) self.mod_flow(datapath=self.get_datapath(), table_id=const.L2_LOOKUP_TABLE, command=ofproto.OFPFC_DELETE, priority=const.PRIORITY_MEDIUM, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, match=match) # Remove egress classifier for port match = parser.OFPMatch(reg7=tunnel_key) self.mod_flow(datapath=self.get_datapath(), table_id=const.EGRESS_TABLE, command=ofproto.OFPFC_DELETE, priority=const.PRIORITY_MEDIUM, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, match=match) self._del_multicast_broadcast_handling_for_port(network_id, lport_id) self._remove_arp_responder(lport)
def _forwarding(self, ev): msg = ev.msg datapath = msg.datapath dpid = datapath.id ofproto = datapath.ofproto pkt = packet.Packet(msg.data) self.logger.debug('dpid:%s, pkt hash:%s', datapath.id, hash(pkt)) eth = pkt.get_protocol(ethernet.ethernet) dst = eth.dst src = eth.src if dst in self.devices: srcSwitchPort = self.devices[src] dstSwitchPort = self.devices[dst] route = self.getRoute(srcSwitchPort, dstSwitchPort) match = datapath.ofproto_parser.OFPMatch(dl_src=haddr_to_bin(src), dl_dst=haddr_to_bin(dst)) self.pushFlow(self, route, match, self.idleTimeout, dst) else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out) return True
def _mpi_packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) dst = eth.dst src = eth.src bin_dst = haddr_to_bin(dst) coll_type = struct.unpack("B", bin_dst[0])[0] >> 2 src_rank = struct.unpack("<h", bin_dst[2:4])[0] dst_rank = struct.unpack("<h", bin_dst[4:6])[0] self.logger.info("SDNMPI communication from rank %s to rank %s", src_rank, dst_rank) self.logger.info("Collective type is: %s", coll_type) # True MAC address of dst, resolved using ProcessManager true_dst = self.send_request(RankResolutionRequest(dst_rank)).mac if not true_dst: return fdb = self.send_request(FindRouteRequest(src, true_dst)).fdb if fdb: # Install rules to all datapaths in path self._add_flows_for_path(fdb, src, dst, true_dst) # Output packet from current switch self._send_packet_out(fdb, datapath, msg.data, msg.buffer_id)
def _get_multicast_broadcast_match(self, network_id): match = self.get_datapath().\ ofproto_parser.OFPMatch(eth_dst='01:00:00:00:00:00') addint = haddr_to_bin('01:00:00:00:00:00') match.set_dl_dst_masked(addint, addint) match.set_metadata(network_id) return match
def add_mac(self, net_id, mac): assert self.mac2net is not None # Must convert MAC address into ASCII char types charMAC = haddr_to_bin(mac) self.mac2net.add_mac(charMAC, net_id, NW_ID_EXTERNAL)
def _add_local_port_dispatch(self, lport): lport_id = lport.id mac = lport.mac port_key = lport.unique_key network_id = lport.lswitch.unique_key topic = lport.topic parser = self.parser ofproto = self.ofproto # Go to dispatch table according to unique metadata & mac match = parser.OFPMatch() match.set_metadata(network_id) match.set_dl_dst(haddr_to_bin(mac)) actions = [parser.OFPActionSetField(reg7=port_key)] action_inst = parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) goto_inst = parser.OFPInstructionGotoTable( const.INGRESS_CONNTRACK_TABLE) inst = [action_inst, goto_inst] self.mod_flow(inst=inst, table_id=const.INGRESS_DESTINATION_PORT_LOOKUP_TABLE, priority=const.PRIORITY_HIGH, match=match) # Egress classifier for port match = parser.OFPMatch(reg7=port_key) inst = [parser.OFPInstructionGotoTable(const.INGRESS_CONNTRACK_TABLE)] self.mod_flow(inst=inst, table_id=const.EGRESS_TABLE, priority=const.PRIORITY_MEDIUM, match=match) self._add_multicast_broadcast_handling_for_local_port( lport_id, port_key, network_id, topic)
def _add_multicast_broadcast_handling_for_port(self, network_id, lport_id, tunnel_key): parser = self.get_datapath().ofproto_parser ofproto = self.get_datapath().ofproto command = self.get_datapath().ofproto.OFPFC_MODIFY network = self.local_networks.get(network_id) if network is None: network = {} self.local_networks[network_id] = network command = self.get_datapath().ofproto.OFPFC_ADD network[lport_id] = tunnel_key match = parser.OFPMatch(eth_dst='01:00:00:00:00:00') addint = haddr_to_bin('01:00:00:00:00:00') match.set_dl_dst_masked(addint, addint) match.set_metadata(network_id) actions = [] for tunnel_id in network.values(): actions.append(parser.OFPActionSetField(reg7=tunnel_id)) actions.append(parser.NXActionResubmitTable(OF_IN_PORT, const.EGRESS_TABLE)) inst = [self.get_datapath().ofproto_parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)] self.mod_flow( self.get_datapath(), inst=inst, table_id=const.L2_LOOKUP_TABLE, command=command, priority=const.PRIORITY_HIGH, match=match)
def _add_multicast_broadcast_handling_for_port(self, network_id, lport_id, tunnel_key): parser = self.dp.ofproto_parser ofproto = self.dp.ofproto command = self.dp.ofproto.OFPFC_MODIFY network = self.local_networks.get(network_id) if network is None: network = {} self.local_networks[network_id] = network command = self.dp.ofproto.OFPFC_ADD network[lport_id] = tunnel_key match = parser.OFPMatch(eth_dst='01:00:00:00:00:00') addint = haddr_to_bin('01:00:00:00:00:00') match.set_dl_dst_masked(addint, addint) match.set_metadata(network_id) actions = [] for tunnel_id in network.values(): actions.append(parser.OFPActionSetField(reg7=tunnel_id)) actions.append( parser.NXActionResubmitTable(OF_IN_PORT, const.EGRESS_TABLE)) inst = [ self.dp.ofproto_parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions) ] self.mod_flow(self.dp, inst=inst, table_id=const.L2_LOOKUP_TABLE, command=command, priority=const.PRIORITY_HIGH, match=match)
def del_mac(self, mac): assert self.mac2net is not None # Must convert MAC address into ASCII char types charMAC = haddr_to_bin(mac) self.mac2net.del_mac(charMAC)
def _forwarding(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.in_port pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] dst = eth.dst dpid = datapath.id 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, dl_dst=haddr_to_bin(dst)) self.add_flow(datapath, self.forward_priority, 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) return True
def _handle_simple_switch(self, datapath, in_port, pkt, buffer_id=None, eth_dst=None): """ Simple learning switch handling for non IPv4 packets. Args: datapath: in_port: pkt: buffer_id: eth_dst: Returns: """ dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser if buffer_id is None: buffer_id = ofproto.OFP_NO_BUFFER eth = pkt.get_protocols(ethernet.ethernet)[0] if eth_dst is None: eth_dst = eth.dst dl_src = eth.src if dpid not in self.mac_to_port: self.mac_to_port[dpid] = {} self.logger.debug("M2P: %s", self.mac_to_port) # learn mac address self.mac_to_port[dpid][dl_src] = in_port self.logger.debug("packet in %s %s %s %s", dpid, in_port, dl_src, eth_dst) if eth_dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][eth_dst] elif eth_dst == 'ff:ff:ff:ff:ff:ff': self.logger.info("Broadcast packet at %s %s %s", dpid, in_port, dl_src) out_port = ofproto.OFPP_FLOOD else: self.logger.debug("OutPort unknown, flooding packet %s %s %s %s", dpid, in_port, dl_src, eth_dst) 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, dl_dst=haddr_to_bin(eth_dst)) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, FLOW_DEFAULT_PRIO_FORWARDING, match, actions, buffer_id, FLOW_DEFAULT_IDLE_TIMEOUT) else: self.add_flow(datapath, FLOW_DEFAULT_PRIO_FORWARDING, match, actions, None, FLOW_DEFAULT_IDLE_TIMEOUT) data = None if buffer_id == ofproto.OFP_NO_BUFFER: data = pkt.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _forwarding(self, ev): msg = ev.msg datapath = msg.datapath dpid = datapath.id ofproto = datapath.ofproto pkt = packet.Packet(msg.data) self.logger.debug('dpid:%s, pkt hash:%s', datapath.id, hash(pkt)) eth = pkt.get_protocol(ethernet.ethernet) dst = eth.dst if dst in self.macToPort[dpid]: out_port = self.macToPort[dpid][dst]['port'] else: out_port = ofproto.OFPP_FLOOD match = datapath.ofproto_parser.OFPMatch(in_port=msg.in_port, dl_dst=haddr_to_bin(dst)) actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: self.addFlow(datapath, match, actions, self.idleTimeout) out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out) return True